Compare commits

..

No commits in common. "24a3a03c653c2bb9ff4d3758f530d1ecab2d89a4" and "999c960339f74bafebca268cf2538206f367a357" have entirely different histories.

9 changed files with 136 additions and 274 deletions

View File

@ -4027,13 +4027,13 @@ body.objectKanbanColumnResizing * {
.dashboard-tab-pane { .dashboard-tab-pane {
position: absolute; position: absolute;
top: 10px; top: 0;
left: 0; left: 0;
right: 0;
bottom: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
box-sizing: border-box; box-sizing: border-box;
width: 100%;
height: 100%;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
} }

View File

@ -1,7 +1,6 @@
// DashboardLayout.js // DashboardLayout.js
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Layout, Flex } from 'antd' import { Layout, Flex } from 'antd'
import { useContext } from 'react'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import ProductionSidebar from './Production/ProductionSidebar' import ProductionSidebar from './Production/ProductionSidebar'
import InventorySidebar from './Inventory/InventorySidebar' import InventorySidebar from './Inventory/InventorySidebar'
@ -17,14 +16,12 @@ import { useThemeContext } from './context/ThemeContext'
import { MessageProvider } from './context/MessageContext' import { MessageProvider } from './context/MessageContext'
import { useDashboardObjectToolsContext } from './context/DashboardObjectToolsContext' import { useDashboardObjectToolsContext } from './context/DashboardObjectToolsContext'
import { useMediaQuery } from 'react-responsive' import { useMediaQuery } from 'react-responsive'
import { ElectronContext } from './context/ElectronContext'
const { Content } = Layout const { Content } = Layout
const DashboardLayout = ({ children }) => { const DashboardLayout = ({ children }) => {
const location = useLocation() const location = useLocation()
const isMobile = useMediaQuery({ maxWidth: 768 }) const isMobile = useMediaQuery({ maxWidth: 768 })
const { isElectron } = useContext(ElectronContext)
const isProduction = location.pathname.startsWith('/dashboard/production') const isProduction = location.pathname.startsWith('/dashboard/production')
const isInventory = location.pathname.startsWith('/dashboard/inventory') const isInventory = location.pathname.startsWith('/dashboard/inventory')
const isFinance = location.pathname.startsWith('/dashboard/finance') const isFinance = location.pathname.startsWith('/dashboard/finance')
@ -64,11 +61,7 @@ const DashboardLayout = ({ children }) => {
className='main-content-layout' className='main-content-layout'
> >
<Content> <Content>
<Flex <Flex vertical style={{ height: '100%' }} gap='20px'>
vertical
style={{ height: '100%' }}
gap={isElectron ? '10px' : '20px'}
>
<Flex justify='space-between' align='center'> <Flex justify='space-between' align='center'>
<DashboardBreadcrumb style={{ margin: '16px 0' }} /> <DashboardBreadcrumb style={{ margin: '16px 0' }} />
{currentObjectTools} {currentObjectTools}

View File

@ -26,7 +26,7 @@ import { useNavigationTabPage } from '../context/NavigationTabsContext'
const { Title, Text } = Typography const { Title, Text } = Typography
const About = () => { const About = () => {
useNavigationTabPage({ title: 'About', iconKey: 'infoCircle' }) useNavigationTabPage({ title: 'About' })
const [collapseState, updateCollapseState] = useCollapseState('About', { const [collapseState, updateCollapseState] = useCollapseState('About', {
updater: true updater: true
}) })

View File

@ -36,7 +36,7 @@ const LEGACY_ELECTRON_USER_KEYS = [
] ]
const Settings = () => { const Settings = () => {
useNavigationTabPage({ title: 'Settings', iconKey: 'settings' }) useNavigationTabPage({ title: 'Settings' })
const { const {
isDarkMode, isDarkMode,
isCompact, isCompact,

View File

@ -125,16 +125,10 @@ const DashboardOverviewPage = ({
onOpenActionsModal, onOpenActionsModal,
sections = [] sections = []
}) => { }) => {
const overviewSection = pageName.endsWith('Overview') const overviewTitle = pageName.endsWith('Overview')
? pageName.slice(0, -'Overview'.length) ? `Overview - ${pageName.slice(0, -'Overview'.length)}`
: ''
const overviewTitle = overviewSection
? `Overview - ${overviewSection}`
: pageName : pageName
const overviewIconKey = overviewSection useNavigationTabPage({ title: overviewTitle })
? `${overviewSection.charAt(0).toLowerCase()}${overviewSection.slice(1)}`
: undefined
useNavigationTabPage({ title: overviewTitle, iconKey: overviewIconKey })
const [savedCollapseState, updateCollapseState] = useCollapseState( const [savedCollapseState, updateCollapseState] = useCollapseState(
pageName, pageName,
collapseDefaults collapseDefaults

View File

@ -8,7 +8,6 @@ import PlusIcon from '../../Icons/PlusIcon'
import XMarkIcon from '../../Icons/XMarkIcon' import XMarkIcon from '../../Icons/XMarkIcon'
import HomeIcon from '../../Icons/HomeIcon' import HomeIcon from '../../Icons/HomeIcon'
import { getModelByName } from '../../../database/ObjectModels' import { getModelByName } from '../../../database/ObjectModels'
import { getSidebarIconComponent } from '../../Icons/sidebarIconMap'
import { useNavigationTabs, useTabPreview } from '../context/NavigationTabsContext' import { useNavigationTabs, useTabPreview } from '../context/NavigationTabsContext'
import { getDesktopWindowId } from '../../../electrobun-bridge.js' import { getDesktopWindowId } from '../../../electrobun-bridge.js'
import { hasExternalTabDrag, writeTabDragData } from './tabDrag' import { hasExternalTabDrag, writeTabDragData } from './tabDrag'
@ -89,8 +88,7 @@ const DashboardTabItem = ({
const [previewOpen, setPreviewOpen] = useState(false) const [previewOpen, setPreviewOpen] = useState(false)
const previewTargetRef = useRef(null) const previewTargetRef = useRef(null)
const model = tab.modelName ? getModelByName(tab.modelName) : null const model = tab.modelName ? getModelByName(tab.modelName) : null
const SidebarIcon = getSidebarIconComponent(tab.iconKey) const Icon = model?.icon || HomeIcon
const Icon = model?.icon || SidebarIcon || HomeIcon
const handlePreviewOpenChange = useCallback( const handlePreviewOpenChange = useCallback(
(nextOpen) => { (nextOpen) => {
@ -156,7 +154,7 @@ const DashboardTabItem = ({
trigger='hover' trigger='hover'
placement='bottom' placement='bottom'
arrow={false} arrow={false}
mouseEnterDelay={1} mouseEnterDelay={0}
mouseLeaveDelay={0} mouseLeaveDelay={0}
destroyOnHidden destroyOnHidden
open={isDragging ? false : previewOpen} open={isDragging ? false : previewOpen}
@ -180,8 +178,7 @@ DashboardTabItem.propTypes = {
tab: PropTypes.shape({ tab: PropTypes.shape({
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
title: PropTypes.string, title: PropTypes.string,
modelName: PropTypes.string, modelName: PropTypes.string
iconKey: PropTypes.string
}).isRequired, }).isRequired,
tabIndex: PropTypes.number.isRequired, tabIndex: PropTypes.number.isRequired,
isSelected: PropTypes.bool, isSelected: PropTypes.bool,

View File

@ -72,7 +72,6 @@ const createTabFromLocation = (location, extras = {}) => ({
id: createTabId(), id: createTabId(),
title: extras.title || 'Farm Control', title: extras.title || 'Farm Control',
modelName: extras.modelName || null, modelName: extras.modelName || null,
iconKey: extras.iconKey || null,
history: [locationToEntry(location)], history: [locationToEntry(location)],
historyIndex: 0 historyIndex: 0
}) })
@ -81,7 +80,6 @@ const cloneCurrentPageTab = (tab, location) => ({
id: createTabId(), id: createTabId(),
title: tab?.title || 'Farm Control', title: tab?.title || 'Farm Control',
modelName: tab?.modelName || null, modelName: tab?.modelName || null,
iconKey: tab?.iconKey || null,
history: [locationToEntry(location)], history: [locationToEntry(location)],
historyIndex: 0 historyIndex: 0
}) })
@ -89,73 +87,6 @@ const cloneCurrentPageTab = (tab, location) => ({
const getTabCurrentEntry = (tab) => const getTabCurrentEntry = (tab) =>
tab?.history?.[tab.historyIndex] || tab?.history?.[tab.history.length - 1] tab?.history?.[tab.historyIndex] || tab?.history?.[tab.history.length - 1]
const normalizeHistory = (history, fallbackEntry) => {
if (Array.isArray(history) && history.length > 0) {
return history.map((item) => locationToEntry(item))
}
return [fallbackEntry || { pathname: '/', search: '', hash: '' }]
}
const normalizeTab = (tab, fallbackLocation) => {
const fallbackEntry = locationToEntry(fallbackLocation)
const history = normalizeHistory(tab?.history, fallbackEntry)
const rawIndex = Number.isInteger(tab?.historyIndex)
? tab.historyIndex
: history.length - 1
return {
id: tab?.id || createTabId(),
title: tab?.title || 'Farm Control',
modelName: tab?.modelName || null,
iconKey: tab?.iconKey || null,
history,
historyIndex: Math.min(Math.max(rawIndex, 0), history.length - 1)
}
}
const applyLocationToTab = (tab, entry) => {
if (!tab || !entry) return tab
const currentEntry = getTabCurrentEntry(tab)
if (entriesEqual(currentEntry, entry)) return tab
if (!tab.history?.length) {
return { ...tab, history: [entry], historyIndex: 0 }
}
const truncated = tab.history.slice(0, tab.historyIndex + 1)
return {
...tab,
history: [...truncated, entry],
historyIndex: truncated.length
}
}
const applyPageMetaToTab = (tab, { title, modelName, iconKey } = {}) => {
const nextModelName =
modelName === undefined
? iconKey !== undefined
? null
: tab.modelName
: modelName || null
const nextIconKey =
iconKey === undefined
? modelName !== undefined
? null
: tab.iconKey
: iconKey || null
const nextTitle = title || tab.title
if (
nextTitle === tab.title &&
nextModelName === tab.modelName &&
nextIconKey === tab.iconKey
) {
return tab
}
return {
...tab,
title: nextTitle,
modelName: nextModelName,
iconKey: nextIconKey
}
}
export const NavigationTabsProvider = ({ children }) => { export const NavigationTabsProvider = ({ children }) => {
const navigate = useNavigate() const navigate = useNavigate()
const location = useLocation() const location = useLocation()
@ -182,53 +113,20 @@ export const NavigationTabsProvider = ({ children }) => {
const [tabPreviewCapturing, setTabPreviewCapturing] = useState({}) const [tabPreviewCapturing, setTabPreviewCapturing] = useState({})
const tabsRef = useRef(tabs) const tabsRef = useRef(tabs)
const activeTabIdRef = useRef(activeTabId) const activeTabIdRef = useRef(activeTabId)
const locationRef = useRef(location)
const previousActiveTabIdRef = useRef(null) const previousActiveTabIdRef = useRef(null)
const isRestoringRef = useRef(null) const isRestoringRef = useRef(false)
const tabPaneElsRef = useRef(new Map()) const tabPaneElsRef = useRef(new Map())
const captureQueueRef = useRef(Promise.resolve()) const captureQueueRef = useRef(Promise.resolve())
const captureInFlightRef = useRef(new Map()) const captureInFlightRef = useRef(new Map())
const previewThemeRef = useRef(isDarkMode ? 'dark' : 'light') const previewThemeRef = useRef(isDarkMode ? 'dark' : 'light')
tabsRef.current = tabs tabsRef.current = tabs
activeTabIdRef.current = activeTabId activeTabIdRef.current = activeTabId
locationRef.current = location
previewThemeRef.current = isDarkMode ? 'dark' : 'light' previewThemeRef.current = isDarkMode ? 'dark' : 'light'
const isRestoreLocation = useCallback((entry) => {
const restoring = isRestoringRef.current
if (!restoring) return false
if (restoring === true) return true
return (
entriesEqual(restoring.target, entry) ||
entriesEqual(restoring.from, entry)
)
}, [])
const shouldIgnoreRestoredLocation = useCallback((entry) => {
const restoring = isRestoringRef.current
if (!restoring) return false
if (restoring === true) {
isRestoringRef.current = null
return true
}
if (entriesEqual(restoring.target, entry)) {
isRestoringRef.current = null
return true
}
if (entriesEqual(restoring.from, entry)) {
return true
}
isRestoringRef.current = null
return false
}, [])
const restoreToEntry = useCallback( const restoreToEntry = useCallback(
(entry) => { (entry) => {
if (!entry) return if (!entry) return
isRestoringRef.current = { isRestoringRef.current = true
target: locationToEntry(entry),
from: locationToEntry(locationRef.current)
}
navigate(entryToPath(entry), { replace: true }) navigate(entryToPath(entry), { replace: true })
}, },
[navigate] [navigate]
@ -243,13 +141,13 @@ export const NavigationTabsProvider = ({ children }) => {
const nextEntry = getTabCurrentEntry(nextTab) const nextEntry = getTabCurrentEntry(nextTab)
setActiveTabId(tabId) setActiveTabId(tabId)
if (entriesEqual(nextEntry, locationRef.current)) { if (entriesEqual(nextEntry, location)) {
return return
} }
restoreToEntry(nextEntry) restoreToEntry(nextEntry)
}, },
[restoreToEntry] [location, restoreToEntry]
) )
const addTab = useCallback(() => { const addTab = useCallback(() => {
@ -296,13 +194,13 @@ export const NavigationTabsProvider = ({ children }) => {
if (nextActive) { if (nextActive) {
setActiveTabId(nextActive.id) setActiveTabId(nextActive.id)
const nextEntry = getTabCurrentEntry(nextActive) const nextEntry = getTabCurrentEntry(nextActive)
if (!entriesEqual(nextEntry, locationRef.current)) { if (!entriesEqual(nextEntry, location)) {
restoreToEntry(nextEntry) restoreToEntry(nextEntry)
} }
} }
return true return true
}, },
[handleWindowControl, restoreToEntry] [handleWindowControl, location, restoreToEntry]
) )
const closeTab = useCallback( const closeTab = useCallback(
@ -315,30 +213,29 @@ export const NavigationTabsProvider = ({ children }) => {
const acceptIncomingTab = useCallback( const acceptIncomingTab = useCallback(
(incomingTab, targetId, insertBefore = false) => { (incomingTab, targetId, insertBefore = false) => {
if (!incomingTab?.id) return if (!incomingTab?.id) return
const tab = normalizeTab(incomingTab, locationRef.current)
setTabs((current) => { setTabs((current) => {
if (current.some((item) => item.id === tab.id)) { if (current.some((tab) => tab.id === incomingTab.id)) {
return current return current
} }
const next = [...current] const next = [...current]
const targetIndex = next.findIndex((item) => item.id === targetId) const targetIndex = next.findIndex((tab) => tab.id === targetId)
if (targetIndex === -1) { if (targetIndex === -1) {
next.push(tab) next.push(incomingTab)
return next return next
} }
next.splice(insertBefore ? targetIndex : targetIndex + 1, 0, tab) next.splice(insertBefore ? targetIndex : targetIndex + 1, 0, incomingTab)
return next return next
}) })
setActiveTabId(tab.id) setActiveTabId(incomingTab.id)
const nextEntry = getTabCurrentEntry(tab) const nextEntry = getTabCurrentEntry(incomingTab)
if (!entriesEqual(nextEntry, locationRef.current)) { if (!entriesEqual(nextEntry, location)) {
restoreToEntry(nextEntry) restoreToEntry(nextEntry)
} }
}, },
[restoreToEntry] [location, restoreToEntry]
) )
const handleTabDragStart = useCallback( const handleTabDragStart = useCallback(
@ -481,31 +378,22 @@ export const NavigationTabsProvider = ({ children }) => {
void captureTabPreview(previousId) void captureTabPreview(previousId)
}, [activeTabId, captureTabPreview, hydrated]) }, [activeTabId, captureTabPreview, hydrated])
const setTabPage = useCallback( const setTabPage = useCallback(({ title, modelName } = {}) => {
({ title, modelName, iconKey, location: pageLocation } = {}) => { const activeId = activeTabIdRef.current
const activeId = activeTabIdRef.current if (!activeId) return
if (!activeId) return
const pageEntry = pageLocation ? locationToEntry(pageLocation) : null setTabs((current) =>
current.map((tab) => {
setTabs((current) => { if (tab.id !== activeId) return tab
if (current.length === 0) return current return {
...tab,
let changed = false title: title || tab.title,
const next = current.map((tab) => { modelName:
if (tab.id !== activeId) return tab modelName === undefined ? tab.modelName : modelName || null
let updated = applyPageMetaToTab(tab, { title, modelName, iconKey }) }
if (pageEntry && !isRestoreLocation(pageEntry)) {
updated = applyLocationToTab(updated, pageEntry)
}
if (updated !== tab) changed = true
return updated
})
return changed ? next : current
}) })
}, )
[isRestoreLocation] }, [])
)
const goBack = useCallback(() => { const goBack = useCallback(() => {
const currentTab = tabsRef.current.find( const currentTab = tabsRef.current.find(
@ -569,24 +457,22 @@ export const NavigationTabsProvider = ({ children }) => {
if (cancelled) return if (cancelled) return
if (session?.tabs?.length) { if (session?.tabs?.length) {
const restoredTabs = session.tabs.map((tab) => isRestoringRef.current = true
normalizeTab(tab, location) setTabs(session.tabs)
)
setTabs(restoredTabs)
const nextActiveId = const nextActiveId =
session.activeTabId && session.activeTabId &&
restoredTabs.some((tab) => tab.id === session.activeTabId) session.tabs.some((tab) => tab.id === session.activeTabId)
? session.activeTabId ? session.activeTabId
: restoredTabs[0].id : session.tabs[0].id
setActiveTabId(nextActiveId) setActiveTabId(nextActiveId)
const activeTab = const activeTab =
restoredTabs.find((tab) => tab.id === nextActiveId) || session.tabs.find((tab) => tab.id === nextActiveId) ||
restoredTabs[0] session.tabs[0]
const entry = getTabCurrentEntry(activeTab) const entry = getTabCurrentEntry(activeTab)
if (!entriesEqual(entry, location)) { if (!entriesEqual(entry, location)) {
restoreToEntry(entry) restoreToEntry(entry)
} else { } else {
isRestoringRef.current = null isRestoringRef.current = false
} }
} else { } else {
const initialTab = createTabFromLocation(location) const initialTab = createTabFromLocation(location)
@ -607,10 +493,12 @@ export const NavigationTabsProvider = ({ children }) => {
useEffect(() => { useEffect(() => {
if (!isElectron || !hydrated) return if (!isElectron || !hydrated) return
if (isRestoringRef.current) {
isRestoringRef.current = false
return
}
const entry = locationToEntry(location) const entry = locationToEntry(location)
if (shouldIgnoreRestoredLocation(entry)) return
setTabs((current) => { setTabs((current) => {
if (current.length === 0) { if (current.length === 0) {
const initialTab = createTabFromLocation(location) const initialTab = createTabFromLocation(location)
@ -618,16 +506,20 @@ export const NavigationTabsProvider = ({ children }) => {
return [initialTab] return [initialTab]
} }
let changed = false return current.map((tab) => {
const next = current.map((tab) => {
if (tab.id !== activeTabIdRef.current) return tab if (tab.id !== activeTabIdRef.current) return tab
const updated = applyLocationToTab(tab, entry) const currentEntry = getTabCurrentEntry(tab)
if (updated !== tab) changed = true if (entriesEqual(currentEntry, entry)) return tab
return updated
const truncated = tab.history.slice(0, tab.historyIndex + 1)
return {
...tab,
history: [...truncated, entry],
historyIndex: truncated.length
}
}) })
return changed ? next : current
}) })
}, [hydrated, isElectron, location, shouldIgnoreRestoredLocation]) }, [hydrated, isElectron, location])
useEffect(() => { useEffect(() => {
if (!isElectron || !hydrated || !syncWindowTabs) return undefined if (!isElectron || !hydrated || !syncWindowTabs) return undefined
@ -778,22 +670,21 @@ export const useTabPreview = (tabId) => {
} }
// eslint-disable-next-line react-refresh/only-export-components // eslint-disable-next-line react-refresh/only-export-components
export const useNavigationTabPage = ({ title, modelName, iconKey } = {}) => { export const useNavigationTabPage = ({ title, modelName } = {}) => {
const { setTabPage, isElectron } = useContext(NavigationTabMetaContext) const { setTabPage, isElectron } = useContext(NavigationTabMetaContext)
const store = useContext(NavigationTabActiveContext) const store = useContext(NavigationTabActiveContext)
const pageLocation = useLocation()
useEffect(() => { useEffect(() => {
if (!isElectron || !title) return undefined if (!isElectron || !title) return undefined
const sync = () => { const sync = () => {
if (!store.getSnapshot()) return if (!store.getSnapshot()) return
setTabPage({ title, modelName, iconKey, location: pageLocation }) setTabPage({ title, modelName })
} }
sync() sync()
return store.subscribe(sync) return store.subscribe(sync)
}, [iconKey, isElectron, modelName, pageLocation, setTabPage, store, title]) }, [isElectron, modelName, setTabPage, store, title])
} }
// eslint-disable-next-line react-refresh/only-export-components // eslint-disable-next-line react-refresh/only-export-components

View File

@ -62,91 +62,79 @@ import MailIcon from './MailIcon'
import EmailAccountIcon from './EmailAccountIcon' import EmailAccountIcon from './EmailAccountIcon'
import EmailTemplateIcon from './EmailTemplateIcon' import EmailTemplateIcon from './EmailTemplateIcon'
const makeEmojiIcon = (emoji) => { const toEmoji = (emoji) => <span aria-hidden>{emoji}</span>
const EmojiIcon = (props) => (
<span aria-hidden {...props}>
{emoji}
</span>
)
return EmojiIcon
}
const sidebarIconComponents = { const sidebarIconMap = {
production: ProductionIcon, production: <ProductionIcon />,
printer: PrinterIcon, printer: <PrinterIcon />,
printerProfile: PrinterProfileIcon, printerProfile: <PrinterProfileIcon />,
filamentProfile: FilamentProfileIcon, filamentProfile: <FilamentProfileIcon />,
job: JobIcon, job: <JobIcon />,
subJob: SubJobIcon, subJob: <SubJobIcon />,
gcodeFile: GCodeFileIcon, gcodeFile: <GCodeFileIcon />,
inventory: InventoryIcon, inventory: <InventoryIcon />,
filamentStock: FilamentStockIcon, filamentStock: <FilamentStockIcon />,
partStock: PartStockIcon, partStock: <PartStockIcon />,
productStock: ProductStockIcon, productStock: <ProductStockIcon />,
stockEvent: StockEventIcon, stockEvent: <StockEventIcon />,
stockAudit: StockAuditIcon, stockAudit: <StockAuditIcon />,
stockAuditLevel: StockAuditLevelIcon, stockAuditLevel: <StockAuditLevelIcon />,
purchaseOrder: PurchaseOrderIcon, purchaseOrder: <PurchaseOrderIcon />,
orderItem: OrderItemIcon, orderItem: <OrderItemIcon />,
shipment: ShipmentIcon, shipment: <ShipmentIcon />,
stockLocation: StockLocationIcon, stockLocation: <StockLocationIcon />,
stockTransfer: StockTransferIcon, stockTransfer: <StockTransferIcon />,
sales: SalesIcon, sales: <SalesIcon />,
client: ClientIcon, client: <ClientIcon />,
salesOrder: SalesOrderIcon, salesOrder: <SalesOrderIcon />,
marketplace: MarketplaceIcon, marketplace: <MarketplaceIcon />,
listing: ListingIcon, listing: <ListingIcon />,
listingVarient: ListingVarientIcon, listingVarient: <ListingVarientIcon />,
fulfillmentPolicy: FulfillmentPolicyIcon, fulfillmentPolicy: <FulfillmentPolicyIcon />,
returnPolicy: ReturnPolicyIcon, returnPolicy: <ReturnPolicyIcon />,
paymentPolicy: PaymentPolicyIcon, paymentPolicy: <PaymentPolicyIcon />,
finance: FinanceIcon, finance: <FinanceIcon />,
invoice: InvoiceIcon, invoice: <InvoiceIcon />,
payment: PaymentIcon, payment: <PaymentIcon />,
filament: FilamentIcon, filament: <FilamentIcon />,
filamentSku: FilamentSkuIcon, filamentSku: <FilamentSkuIcon />,
part: PartIcon, part: <PartIcon />,
partSku: PartSkuIcon, partSku: <PartSkuIcon />,
product: ProductIcon, product: <ProductIcon />,
productCategory: ProductCategoryIcon, productCategory: <ProductCategoryIcon />,
productSku: ProductSkuIcon, productSku: <ProductSkuIcon />,
vendor: VendorIcon, vendor: <VendorIcon />,
material: MaterialIcon, material: <MaterialIcon />,
noteType: NoteTypeIcon, noteType: <NoteTypeIcon />,
settings: SettingsIcon, settings: <SettingsIcon />,
auditLog: AuditLogIcon, auditLog: <AuditLogIcon />,
developer: DeveloperIcon, developer: <DeveloperIcon />,
person: PersonIcon, person: <PersonIcon />,
userGroup: PersonGroupIcon, userGroup: <PersonGroupIcon />,
permissionSetting: PermissionSettingIcon, permissionSetting: <PermissionSettingIcon />,
host: HostIcon, host: <HostIcon />,
documentPrinter: DocumentPrinterIcon, documentPrinter: <DocumentPrinterIcon />,
documentTemplate: DocumentTemplateIcon, documentTemplate: <DocumentTemplateIcon />,
document: DocumentIcon, document: <DocumentIcon />,
documentSize: DocumentSizeIcon, documentSize: <DocumentSizeIcon />,
documentJob: DocumentJobIcon, documentJob: <DocumentJobIcon />,
file: FileIcon, file: <FileIcon />,
courier: CourierIcon, courier: <CourierIcon />,
courierService: CourierServiceIcon, courierService: <CourierServiceIcon />,
taxRate: TaxRateIcon, taxRate: <TaxRateIcon />,
taxRecord: TaxRecordIcon, taxRecord: <TaxRecordIcon />,
appPassword: AppPasswordIcon, appPassword: <AppPasswordIcon />,
email: MailIcon, email: <MailIcon />,
emailAccount: EmailAccountIcon, emailAccount: <EmailAccountIcon />,
emailTemplate: EmailTemplateIcon, emailTemplate: <EmailTemplateIcon />,
emailMessage: MailIcon, emailMessage: <MailIcon />,
infoCircle: InfoCircleIcon, infoCircle: <InfoCircleIcon />,
sessionStorage: makeEmojiIcon('🗃️'), sessionStorage: toEmoji('🗃️'),
authDebug: makeEmojiIcon('🔐'), authDebug: toEmoji('🔐'),
apiDebug: makeEmojiIcon('🌐') apiDebug: toEmoji('🌐')
}
export const getSidebarIconComponent = (iconKey) => {
if (!iconKey) return null
return sidebarIconComponents[iconKey] || null
} }
export const getSidebarIconNode = (iconKey) => { export const getSidebarIconNode = (iconKey) => {
const Icon = getSidebarIconComponent(iconKey) if (!iconKey) return null
return Icon ? <Icon /> : null return sidebarIconMap[iconKey] || null
} }

View File

@ -471,7 +471,6 @@ function createDefaultTab() {
id, id,
title: 'Overview - Production', title: 'Overview - Production',
modelName: null, modelName: null,
iconKey: 'production',
history: [ history: [
{ {
pathname: DEFAULT_DASHBOARD_PATH, pathname: DEFAULT_DASHBOARD_PATH,