Compare commits

..

No commits in common. "62805b0d6a2bd6b5a9daadacb5d9192fc9b55520" and "a896cdf223b111228d3190c1bc031db710b723e5" have entirely different histories.

4 changed files with 22 additions and 150 deletions

View File

@ -196,7 +196,6 @@ code {
/* --- Start of src/index.css --- */ /* --- Start of src/index.css --- */
body { body {
margin: 0; margin: 0;
overflow: hidden;
} }
.ant-modal-mask { .ant-modal-mask {
@ -603,32 +602,3 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
min-width: 0; min-width: 0;
height: 20px; height: 20px;
} }
.sidebar-scroll .simplebar-track.simplebar-vertical {
right: -1px;
width: 0px !important;
transition:
width 0.15s ease-in-out,
right 0.15s ease-in-out;
}
.sidebar-scroll.dark .simplebar-track.simplebar-vertical {
background-color: #141414;
border-inline-end: 1px solid rgba(253, 253, 253, 0.12);
border-bottom: 1px solid rgba(253, 253, 253, 0.12);
border-radius: 0 0 5px 0;
}
.sidebar-scroll.simplebar-scrolling .simplebar-track.simplebar-vertical {
width: 10px !important;
right: -11px;
}
.sidebar-scroll
.simplebar-track.simplebar-vertical
.simplebar-scrollbar:before {
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
}

View File

@ -8,8 +8,6 @@ import { useNavigate } from 'react-router-dom'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { ElectronContext } from '../context/ElectronContext' import { ElectronContext } from '../context/ElectronContext'
import { getSidebarIconNode } from '../../Icons/sidebarIconMap' import { getSidebarIconNode } from '../../Icons/sidebarIconMap'
import SimpleBar from 'simplebar-react'
import { useThemeContext } from '../context/ThemeContext'
const { Sider } = Layout const { Sider } = Layout
const DashboardSidebar = ({ const DashboardSidebar = ({
@ -26,7 +24,7 @@ const DashboardSidebar = ({
}) })
const isMobile = useMediaQuery({ maxWidth: 768 }) const isMobile = useMediaQuery({ maxWidth: 768 })
const navigate = useNavigate() const navigate = useNavigate()
const { isDarkMode } = useThemeContext()
const { isElectron } = useContext(ElectronContext) const { isElectron } = useContext(ElectronContext)
useEffect(() => { useEffect(() => {
@ -92,14 +90,11 @@ const DashboardSidebar = ({
className={isElectron ? 'electron-sider' : ''} className={isElectron ? 'electron-sider' : ''}
> >
<Flex <Flex
style={{ height: '100%', minHeight: 0 }} style={{ height: '100%' }}
vertical vertical
className='ant-menu-root ant-menu-inline ant-menu-light' className='ant-menu-root ant-menu-inline ant-menu-light'
> >
<SimpleBar <div style={{ maxHeight: '100%', overflowY: 'auto', height: '100%' }}>
style={{ flexGrow: 1, minHeight: 0 }}
className={`sidebar-scroll ${isDarkMode ? 'dark' : 'light'}`}
>
<Menu <Menu
mode='inline' mode='inline'
selectedKeys={[selectedKey]} selectedKeys={[selectedKey]}
@ -108,7 +103,7 @@ const DashboardSidebar = ({
style={{ flexGrow: 1, border: 'none' }} style={{ flexGrow: 1, border: 'none' }}
_internalDisableMenuItemTitleTooltip _internalDisableMenuItemTitleTooltip
/> />
</SimpleBar> </div>
<Flex style={{ padding: '4px', width: '100%' }}> <Flex style={{ padding: '4px', width: '100%' }}>
<Button <Button
size={isElectron ? 'middle' : 'large'} size={isElectron ? 'middle' : 'large'}

View File

@ -26,19 +26,9 @@ const areValuesEqual = (v1, v2) => {
return String(id1) === String(id2) return String(id1) === String(id2)
} }
const getFirstSelectableLeaf = (nodes) => {
if (!Array.isArray(nodes)) return null
for (const node of nodes) {
if (node.isLeaf && node.selectable !== false) return node
const found = getFirstSelectableLeaf(node.children)
if (found) return found
}
return null
}
const ObjectSelect = ({ const ObjectSelect = ({
type = 'unknown', type = 'unknown',
showSearch = true, showSearch = false,
multiple = false, multiple = false,
treeSelectProps = EMPTY_OBJECT, treeSelectProps = EMPTY_OBJECT,
filter = EMPTY_OBJECT, filter = EMPTY_OBJECT,
@ -48,7 +38,7 @@ const ObjectSelect = ({
disabled = false, disabled = false,
...rest ...rest
}) => { }) => {
const { fetchObjectsByProperty, fetchObject, connected, searchObjects } = const { fetchObjectsByProperty, fetchObject, connected } =
useContext(ApiServerContext) useContext(ApiServerContext)
const { token } = useContext(AuthContext) const { token } = useContext(AuthContext)
// --- State --- // --- State ---
@ -62,9 +52,6 @@ const ObjectSelect = ({
const [initialLoading, setInitialLoading] = useState(true) const [initialLoading, setInitialLoading] = useState(true)
const [expandedKeys, setExpandedKeys] = useState([]) const [expandedKeys, setExpandedKeys] = useState([])
const [treeVersion, setTreeVersion] = useState(0) const [treeVersion, setTreeVersion] = useState(0)
const [isSearching, setIsSearching] = useState(false)
const [searchValue, setSearchValue] = useState('')
const searchRequestIdRef = useRef(0)
const valueRef = useRef(null) const valueRef = useRef(null)
// Refs to track value changes // Refs to track value changes
@ -358,7 +345,6 @@ const ObjectSelect = ({
const onTreeSelectChange = useCallback( const onTreeSelectChange = useCallback(
(value) => { (value) => {
// Mark this as an internal change // Mark this as an internal change
setIsSearching(false)
isInternalChangeRef.current = true isInternalChangeRef.current = true
// value can be a string (single) or array (multiple) // value can be a string (single) or array (multiple)
@ -382,55 +368,8 @@ const ObjectSelect = ({
[multiple, objectList, onChange] [multiple, objectList, onChange]
) )
const onSearch = useCallback(
async (search) => {
setSearchValue(search)
const trimmed = search?.trim() ?? ''
if (!trimmed) {
searchRequestIdRef.current += 1
setIsSearching(false)
setTreeData(buildTreeData(objectPropertiesTree))
return
}
const requestId = ++searchRequestIdRef.current
setIsSearching(true)
const data = await searchObjects(type, trimmed)
if (requestId !== searchRequestIdRef.current) return
if (!Array.isArray(data)) return
setTreeData(buildTreeData(data, properties.length))
},
[
searchObjects,
type,
buildTreeData,
objectPropertiesTree,
properties.length
]
)
const onInputKeyDown = useCallback(
(e) => {
treeSelectProps.onInputKeyDown?.(e)
if (e.defaultPrevented || e.key !== 'Enter' || !isSearching) return
const firstLeaf = getFirstSelectableLeaf(treeData)
if (!firstLeaf?.value) return
e.preventDefault()
e.stopPropagation()
onTreeSelectChange(
multiple ? [firstLeaf.value] : firstLeaf.value
)
setSearchValue('')
onSearch('')
},
[treeSelectProps, isSearching, treeData, multiple, onTreeSelectChange, onSearch]
)
// Update treeData when objectPropertiesTree changes // Update treeData when objectPropertiesTree changes
useEffect(() => { useEffect(() => {
if (isSearching) return
if (objectPropertiesTree && Object.keys(objectPropertiesTree).length > 0) { if (objectPropertiesTree && Object.keys(objectPropertiesTree).length > 0) {
const newTreeData = buildTreeData(objectPropertiesTree) const newTreeData = buildTreeData(objectPropertiesTree)
setTreeData((prev) => { setTreeData((prev) => {
@ -440,7 +379,7 @@ const ObjectSelect = ({
return prev return prev
}) })
} }
}, [objectPropertiesTree, properties, buildTreeData, isSearching]) }, [objectPropertiesTree, properties, buildTreeData])
useEffect(() => { useEffect(() => {
const handleValue = async () => { const handleValue = async () => {
@ -541,9 +480,6 @@ const ObjectSelect = ({
JSON.stringify(prevValues.masterFilter) !== JSON.stringify(masterFilter) JSON.stringify(prevValues.masterFilter) !== JSON.stringify(masterFilter)
if (hasChanged) { if (hasChanged) {
searchRequestIdRef.current += 1
setIsSearching(false)
setSearchValue('')
setObjectPropertiesTree({}) setObjectPropertiesTree({})
setObjectList([]) setObjectList([])
setTreeData([]) setTreeData([])
@ -623,18 +559,14 @@ const ObjectSelect = ({
onTreeExpand={setExpandedKeys} onTreeExpand={setExpandedKeys}
treeData={treeData} treeData={treeData}
showSearch={showSearch} showSearch={showSearch}
filterTreeNode={() => true}
multiple={multiple} multiple={multiple}
loadData={isSearching ? undefined : loadData} loadData={loadData}
showCheckedStrategy={SHOW_CHILD} showCheckedStrategy={SHOW_CHILD}
placeholder={placeholder} placeholder={placeholder}
{...treeSelectProps} {...treeSelectProps}
{...rest} {...rest}
value={treeSelectValue} value={treeSelectValue}
onChange={onTreeSelectChange} onChange={onTreeSelectChange}
onSearch={onSearch}
onInputKeyDown={onInputKeyDown}
searchValue={searchValue}
disabled={disabled || type == 'unknown' || type == undefined} disabled={disabled || type == 'unknown' || type == undefined}
/> />
) )

View File

@ -744,8 +744,7 @@ const ApiServerProvider = ({ children }) => {
[offLockEvent] [offLockEvent]
) )
const showError = useCallback( const showError = useCallback((error, callback = null) => {
(error, callback = null) => {
const code = error.response.data.code || 'UNKNOWN' const code = error.response.data.code || 'UNKNOWN'
if (code == 'UNAUTHORIZED') { if (code == 'UNAUTHORIZED') {
setUnauthenticated() setUnauthenticated()
@ -758,9 +757,7 @@ const ApiServerProvider = ({ children }) => {
setErrorModalContent(content) setErrorModalContent(content)
setRetryCallback(() => callback) setRetryCallback(() => callback)
setShowErrorModal(true) setShowErrorModal(true)
}, }, [setUnauthenticated])
[setUnauthenticated]
)
const handleRetry = () => { const handleRetry = () => {
setShowErrorModal(false) setShowErrorModal(false)
@ -914,27 +911,6 @@ const ApiServerProvider = ({ children }) => {
} }
} }
const searchObjects = async (type, search) => {
const searchUrl = `${config.backendUrl}/${getObjectEndpoint(type)}/search`
logger.debug('Searching objects for ' + type, { search })
try {
const response = await axios.get(searchUrl, {
params: { search },
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`
}
})
return response.data
} catch (err) {
console.error(err)
showError(err, () => {
searchObjects(type, search)
})
return []
}
}
// Update filament information // Update filament information
const updateObject = async (id, type, value) => { const updateObject = async (id, type, value) => {
const updateUrl = `${config.backendUrl}/${getObjectEndpoint(type)}/${id}` const updateUrl = `${config.backendUrl}/${getObjectEndpoint(type)}/${id}`
@ -1848,7 +1824,6 @@ const ApiServerProvider = ({ children }) => {
fetchObject, fetchObject,
fetchObjects, fetchObjects,
fetchObjectsByProperty, fetchObjectsByProperty,
searchObjects,
fetchSpotlightData, fetchSpotlightData,
getModelStats, getModelStats,
getModelHistory, getModelHistory,