Implemented about page.
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
This commit is contained in:
parent
8901cdbc98
commit
4363f08f50
6
Jenkinsfile
vendored
6
Jenkinsfile
vendored
@ -20,7 +20,7 @@ def deploy() {
|
|||||||
|
|
||||||
stage('Build (Ubuntu)') {
|
stage('Build (Ubuntu)') {
|
||||||
nodejs(nodeJSInstallationName: 'Node23') {
|
nodejs(nodeJSInstallationName: 'Node23') {
|
||||||
sh 'NODE_ENV=production pnpm build:cloudflare'
|
sh "VITE_BUILD_NUMBER=${env.BUILD_NUMBER} NODE_ENV=production pnpm build:cloudflare"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,9 +70,9 @@ def buildOnLabel(label, buildCommand) {
|
|||||||
stage("Build (${label})") {
|
stage("Build (${label})") {
|
||||||
nodejs(nodeJSInstallationName: 'Node23') {
|
nodejs(nodeJSInstallationName: 'Node23') {
|
||||||
if (isUnix()) {
|
if (isUnix()) {
|
||||||
sh "NODE_ENV=production ${buildCommand}"
|
sh "VITE_BUILD_NUMBER=${env.BUILD_NUMBER} NODE_ENV=production ${buildCommand}"
|
||||||
} else {
|
} else {
|
||||||
bat "set NODE_ENV=production && ${buildCommand}"
|
bat "set VITE_BUILD_NUMBER=${env.BUILD_NUMBER} && set NODE_ENV=production && ${buildCommand}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -596,3 +596,9 @@ body {
|
|||||||
.ant-table-wrapper .ant-table-filter-column {
|
.ant-table-wrapper .ant-table-filter-column {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
||||||
|
width: 50px;
|
||||||
|
min-width: 0;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|||||||
0
public/appupdate.js
Normal file
0
public/appupdate.js
Normal file
@ -206,6 +206,10 @@ export function getWindow() {
|
|||||||
return win
|
return win
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getElectronVersion() {
|
||||||
|
return process.versions.electron
|
||||||
|
}
|
||||||
|
|
||||||
export function setupMainWindowIPC() {
|
export function setupMainWindowIPC() {
|
||||||
// IPC handler to get window state
|
// IPC handler to get window state
|
||||||
ipcMain.handle('window-state', () => {
|
ipcMain.handle('window-state', () => {
|
||||||
@ -267,6 +271,8 @@ export function setupMainWindowIPC() {
|
|||||||
applyApplicationMenu()
|
applyApplicationMenu()
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('electron-version', () => getElectronVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupMainWindowAppEvents(app) {
|
export function setupMainWindowAppEvents(app) {
|
||||||
|
|||||||
180
src/components/Dashboard/Management/About.jsx
Normal file
180
src/components/Dashboard/Management/About.jsx
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
import {
|
||||||
|
Flex,
|
||||||
|
Typography,
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
Skeleton,
|
||||||
|
Tag,
|
||||||
|
Divider
|
||||||
|
} from 'antd'
|
||||||
|
import useCollapseState from '../hooks/useCollapseState'
|
||||||
|
import InfoCollapse from '../common/InfoCollapse'
|
||||||
|
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
|
||||||
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
|
import DeveloperIcon from '../../Icons/DeveloperIcon'
|
||||||
|
import { version as appVersion } from '../../../../package.json'
|
||||||
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
|
import { AuthContext } from '../context/AuthContext'
|
||||||
|
import { ElectronContext } from '../context/ElectronContext'
|
||||||
|
import { useMediaQuery } from 'react-responsive'
|
||||||
|
const { Title, Text, Link } = Typography
|
||||||
|
|
||||||
|
const About = () => {
|
||||||
|
const [collapseState, updateCollapseState] = useCollapseState('About', {
|
||||||
|
updater: true
|
||||||
|
})
|
||||||
|
const { token } = useContext(AuthContext)
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
label: 'Check for Updates',
|
||||||
|
icon: <ReloadIcon />,
|
||||||
|
onClick: () => {
|
||||||
|
console.log('Check for Updates')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const buildNumber = import.meta.env.VITE_BUILD_NUMBER
|
||||||
|
? 'b' + import.meta.env.VITE_BUILD_NUMBER
|
||||||
|
: 'dev'
|
||||||
|
const developmentMode = import.meta.env.MODE === 'development'
|
||||||
|
|
||||||
|
const { fetchApiServerVersion, fetchWsServerVersion } =
|
||||||
|
useContext(ApiServerContext)
|
||||||
|
const { isElectron, getElectronVersion } = useContext(ElectronContext)
|
||||||
|
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (token) {
|
||||||
|
fetchApiServerVersion().then((version) => {
|
||||||
|
setApiServerVersion(version)
|
||||||
|
})
|
||||||
|
fetchWsServerVersion().then((version) => {
|
||||||
|
setWsServerVersion(version)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [fetchApiServerVersion, fetchWsServerVersion, token])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isElectron) return
|
||||||
|
|
||||||
|
getElectronVersion()
|
||||||
|
.then((version) => {
|
||||||
|
setElectronVersion(version || 'unknown')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setElectronVersion('unknown')
|
||||||
|
})
|
||||||
|
}, [getElectronVersion, isElectron])
|
||||||
|
|
||||||
|
const [apiServerVersion, setApiServerVersion] = useState(null)
|
||||||
|
const [wsServerVersion, setWsServerVersion] = useState(null)
|
||||||
|
const [electronVersion, setElectronVersion] = useState(null)
|
||||||
|
|
||||||
|
const apiServerVersionText = apiServerVersion ? (
|
||||||
|
<Text>
|
||||||
|
{`v${apiServerVersion.version}-${apiServerVersion.buildNumber}`}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Skeleton.Input active size='small' className='text-skeleton' />
|
||||||
|
)
|
||||||
|
const wsServerVersionText = wsServerVersion ? (
|
||||||
|
<Text>{`v${wsServerVersion.version}-${wsServerVersion.buildNumber}`}</Text>
|
||||||
|
) : (
|
||||||
|
<Skeleton.Input active size='small' className='text-skeleton' />
|
||||||
|
)
|
||||||
|
const electronVersionText = electronVersion ? (
|
||||||
|
<Text>{`v${electronVersion}`}</Text>
|
||||||
|
) : (
|
||||||
|
<Skeleton.Input active size='small' className='text-skeleton' />
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100%', minHeight: 0, overflowY: 'auto' }}>
|
||||||
|
<Flex vertical gap='large'>
|
||||||
|
<Flex vertical gap='middle' align='start'>
|
||||||
|
<Dropdown menu={{ items: actions }}>
|
||||||
|
<Button>Actions</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical gap='large'>
|
||||||
|
<InfoCollapse
|
||||||
|
title='About Farm Control'
|
||||||
|
icon={<InfoCircleIcon />}
|
||||||
|
canCollapse={false}
|
||||||
|
active={collapseState.purchaseOrderStats}
|
||||||
|
onToggle={(isActive) =>
|
||||||
|
updateCollapseState('purchaseOrderStats', isActive)
|
||||||
|
}
|
||||||
|
className='no-t-padding-collapse'
|
||||||
|
collapseKey='purchaseOrderStats'
|
||||||
|
>
|
||||||
|
<Flex gap='large'>
|
||||||
|
<img
|
||||||
|
src={'/logo512.png'}
|
||||||
|
alt='Farm Control Logo'
|
||||||
|
style={{ width: '200px', height: '200px' }}
|
||||||
|
/>
|
||||||
|
<Flex vertical gap='small' justify='center'>
|
||||||
|
<Flex gap='middle' align='center'>
|
||||||
|
<Title level={2} style={{ margin: 0 }}>
|
||||||
|
Farm Control
|
||||||
|
</Title>
|
||||||
|
{developmentMode && !isMobile && (
|
||||||
|
<Tag
|
||||||
|
color='yellow'
|
||||||
|
style={{ marginRight: 0 }}
|
||||||
|
icon={<DeveloperIcon />}
|
||||||
|
>
|
||||||
|
Development
|
||||||
|
</Tag>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
<Text type='secondary'>
|
||||||
|
3D Printer ERP and Control Software.
|
||||||
|
</Text>
|
||||||
|
<Flex style={{ columnGap: '15px', rowGap: '8px' }} wrap='wrap'>
|
||||||
|
<Text type='secondary'>
|
||||||
|
User Interface:{' '}
|
||||||
|
<Text>
|
||||||
|
v{appVersion}-{buildNumber}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
{isElectron && (
|
||||||
|
<Text type='secondary'>
|
||||||
|
Electron: {electronVersionText}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Text type='secondary'>REST API: {apiServerVersionText}</Text>
|
||||||
|
<Text type='secondary'>
|
||||||
|
Web Socket: {wsServerVersionText}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex gap='middle' align='center'>
|
||||||
|
{developmentMode && isMobile && (
|
||||||
|
<Tag
|
||||||
|
color='yellow'
|
||||||
|
style={{ marginRight: 0 }}
|
||||||
|
icon={<DeveloperIcon />}
|
||||||
|
>
|
||||||
|
Development
|
||||||
|
</Tag>
|
||||||
|
)}
|
||||||
|
<Link href='https://ci.tombutcher.work/job/farmcontrol'>
|
||||||
|
Jenkins
|
||||||
|
</Link>
|
||||||
|
<Divider type='vertical' style={{ margin: 0 }} />
|
||||||
|
<Link href='https://github.com/farmcontrol'>GitHub</Link>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</InfoCollapse>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default About
|
||||||
@ -17,7 +17,8 @@ const breadcrumbNameMap = {
|
|||||||
info: 'Info',
|
info: 'Info',
|
||||||
design: 'Design',
|
design: 'Design',
|
||||||
control: 'Control',
|
control: 'Control',
|
||||||
preview: 'Preview'
|
preview: 'Preview',
|
||||||
|
about: 'About'
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainSections = ['production', 'inventory', 'management', 'developer']
|
const mainSections = ['production', 'inventory', 'management', 'developer']
|
||||||
|
|||||||
@ -744,7 +744,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
[offLockEvent]
|
[offLockEvent]
|
||||||
)
|
)
|
||||||
|
|
||||||
const showError = (error, callback = null) => {
|
const showError = useCallback((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()
|
||||||
@ -757,7 +757,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
setErrorModalContent(content)
|
setErrorModalContent(content)
|
||||||
setRetryCallback(() => callback)
|
setRetryCallback(() => callback)
|
||||||
setShowErrorModal(true)
|
setShowErrorModal(true)
|
||||||
}
|
}, [setUnauthenticated])
|
||||||
|
|
||||||
const handleRetry = () => {
|
const handleRetry = () => {
|
||||||
setShowErrorModal(false)
|
setShowErrorModal(false)
|
||||||
@ -1678,35 +1678,78 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
return response.data
|
return response.data
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const fetchAppUpdateBranches = useCallback(async () => {
|
const fetchApiServerVersion = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.backendUrl}/appupdate/branches`, {
|
const response = await axios.get(`${config.backendUrl}/server/version`, {
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return Array.isArray(response.data?.branches) ? response.data.branches : []
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
showError(err, () => {
|
|
||||||
fetchAppUpdateBranches()
|
|
||||||
})
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}, [token])
|
|
||||||
|
|
||||||
const fetchAppUpdateCurrent = useCallback(
|
|
||||||
async (branch) => {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`${config.backendUrl}/appupdate/current`, {
|
|
||||||
params: { branch },
|
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
Authorization: `Bearer ${token}`
|
Authorization: `Bearer ${token}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return response.data
|
return response.data
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
showError(err, () => {
|
||||||
|
fetchApiServerVersion()
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}, [token, showError])
|
||||||
|
|
||||||
|
const fetchWsServerVersion = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (socketRef.current && socketRef.current.connected) {
|
||||||
|
return await new Promise((resolve) => {
|
||||||
|
socketRef.current.emit('getServerVersion', {}, resolve)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
showError(err, () => {
|
||||||
|
fetchWsServerVersion()
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}, [showError])
|
||||||
|
|
||||||
|
const fetchAppUpdateBranches = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
`${config.backendUrl}/appupdate/branches`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return Array.isArray(response.data?.branches)
|
||||||
|
? response.data.branches
|
||||||
|
: []
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
showError(err, () => {
|
||||||
|
fetchAppUpdateBranches()
|
||||||
|
})
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}, [token, showError])
|
||||||
|
|
||||||
|
const fetchAppUpdateCurrent = useCallback(
|
||||||
|
async (branch) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
`${config.backendUrl}/appupdate/current`,
|
||||||
|
{
|
||||||
|
params: { branch },
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.data
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
showError(err, () => {
|
showError(err, () => {
|
||||||
@ -1715,7 +1758,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[token]
|
[token, showError]
|
||||||
)
|
)
|
||||||
|
|
||||||
const flushFile = async (id) => {
|
const flushFile = async (id) => {
|
||||||
@ -1816,7 +1859,9 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
completeAppLaunchSession,
|
completeAppLaunchSession,
|
||||||
getAppLaunchSession,
|
getAppLaunchSession,
|
||||||
fetchAppUpdateBranches,
|
fetchAppUpdateBranches,
|
||||||
fetchAppUpdateCurrent
|
fetchAppUpdateCurrent,
|
||||||
|
fetchWsServerVersion,
|
||||||
|
fetchApiServerVersion
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
|
|||||||
@ -152,6 +152,11 @@ const ElectronProvider = ({ children }) => {
|
|||||||
[electronAvailable]
|
[electronAvailable]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getElectronVersion = useCallback(async () => {
|
||||||
|
if (!electronAvailable || !ipcRenderer) return null
|
||||||
|
return await ipcRenderer.invoke('electron-version')
|
||||||
|
}, [electronAvailable])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ElectronContext.Provider
|
<ElectronContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@ -168,7 +173,8 @@ const ElectronProvider = ({ children }) => {
|
|||||||
getToken,
|
getToken,
|
||||||
setToken,
|
setToken,
|
||||||
resizeSpotlightWindow,
|
resizeSpotlightWindow,
|
||||||
setSidebarViewMenu
|
setSidebarViewMenu,
|
||||||
|
getElectronVersion
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import CourierServiceIcon from './CourierServiceIcon'
|
|||||||
import TaxRateIcon from './TaxRateIcon'
|
import TaxRateIcon from './TaxRateIcon'
|
||||||
import TaxRecordIcon from './TaxRecordIcon'
|
import TaxRecordIcon from './TaxRecordIcon'
|
||||||
import AppPasswordIcon from './AppPasswordIcon'
|
import AppPasswordIcon from './AppPasswordIcon'
|
||||||
|
import InfoCircleIcon from './InfoCircleIcon'
|
||||||
|
|
||||||
const toEmoji = (emoji) => <span aria-hidden>{emoji}</span>
|
const toEmoji = (emoji) => <span aria-hidden>{emoji}</span>
|
||||||
|
|
||||||
@ -102,6 +103,7 @@ const sidebarIconMap = {
|
|||||||
taxRate: <TaxRateIcon />,
|
taxRate: <TaxRateIcon />,
|
||||||
taxRecord: <TaxRecordIcon />,
|
taxRecord: <TaxRecordIcon />,
|
||||||
appPassword: <AppPasswordIcon />,
|
appPassword: <AppPasswordIcon />,
|
||||||
|
infoCircle: <InfoCircleIcon />,
|
||||||
sessionStorage: toEmoji('🗃️'),
|
sessionStorage: toEmoji('🗃️'),
|
||||||
authDebug: toEmoji('🔐'),
|
authDebug: toEmoji('🔐'),
|
||||||
apiDebug: toEmoji('🌐')
|
apiDebug: toEmoji('🌐')
|
||||||
|
|||||||
@ -168,6 +168,12 @@ const managementSidebarItems = [
|
|||||||
label: 'Developer',
|
label: 'Developer',
|
||||||
path: '/dashboard/developer/sessionstorage',
|
path: '/dashboard/developer/sessionstorage',
|
||||||
devOnly: true
|
devOnly: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'about',
|
||||||
|
iconKey: 'infoCircle',
|
||||||
|
label: 'About',
|
||||||
|
path: '/dashboard/management/about'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -1,55 +1,155 @@
|
|||||||
import { lazy } from 'react'
|
import { lazy } from 'react'
|
||||||
import { Route } from 'react-router-dom'
|
import { Route } from 'react-router-dom'
|
||||||
|
|
||||||
const Filaments = lazy(() => import('../components/Dashboard/Management/Filaments'))
|
const Filaments = lazy(
|
||||||
const FilamentInfo = lazy(() => import('../components/Dashboard/Management/Filaments/FilamentInfo.jsx'))
|
() => import('../components/Dashboard/Management/Filaments')
|
||||||
const FilamentSkus = lazy(() => import('../components/Dashboard/Management/FilamentSkus.jsx'))
|
)
|
||||||
const FilamentSkuInfo = lazy(() => import('../components/Dashboard/Management/FilamentSkus/FilamentSkuInfo.jsx'))
|
const FilamentInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Filaments/FilamentInfo.jsx')
|
||||||
|
)
|
||||||
|
const FilamentSkus = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/FilamentSkus.jsx')
|
||||||
|
)
|
||||||
|
const FilamentSkuInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/FilamentSkus/FilamentSkuInfo.jsx')
|
||||||
|
)
|
||||||
const Parts = lazy(() => import('../components/Dashboard/Management/Parts.jsx'))
|
const Parts = lazy(() => import('../components/Dashboard/Management/Parts.jsx'))
|
||||||
const PartInfo = lazy(() => import('../components/Dashboard/Management/Parts/PartInfo.jsx'))
|
const PartInfo = lazy(
|
||||||
const PartSkus = lazy(() => import('../components/Dashboard/Management/PartSkus.jsx'))
|
() => import('../components/Dashboard/Management/Parts/PartInfo.jsx')
|
||||||
const PartSkuInfo = lazy(() => import('../components/Dashboard/Management/PartSkus/PartSkuInfo.jsx'))
|
)
|
||||||
const Products = lazy(() => import('../components/Dashboard/Management/Products.jsx'))
|
const PartSkus = lazy(
|
||||||
const ProductInfo = lazy(() => import('../components/Dashboard/Management/Products/ProductInfo.jsx'))
|
() => import('../components/Dashboard/Management/PartSkus.jsx')
|
||||||
const ProductCategories = lazy(() => import('../components/Dashboard/Management/ProductCategories.jsx'))
|
)
|
||||||
const ProductCategoryInfo = lazy(() => import('../components/Dashboard/Management/ProductCategories/ProductCategoryInfo.jsx'))
|
const PartSkuInfo = lazy(
|
||||||
const ProductSkus = lazy(() => import('../components/Dashboard/Management/ProductSkus.jsx'))
|
() => import('../components/Dashboard/Management/PartSkus/PartSkuInfo.jsx')
|
||||||
const ProductSkuInfo = lazy(() => import('../components/Dashboard/Management/ProductSkus/ProductSkuInfo.jsx'))
|
)
|
||||||
|
const Products = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Products.jsx')
|
||||||
|
)
|
||||||
|
const ProductInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Products/ProductInfo.jsx')
|
||||||
|
)
|
||||||
|
const ProductCategories = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/ProductCategories.jsx')
|
||||||
|
)
|
||||||
|
const ProductCategoryInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/ProductCategories/ProductCategoryInfo.jsx')
|
||||||
|
)
|
||||||
|
const ProductSkus = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/ProductSkus.jsx')
|
||||||
|
)
|
||||||
|
const ProductSkuInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/ProductSkus/ProductSkuInfo.jsx')
|
||||||
|
)
|
||||||
const Vendors = lazy(() => import('../components/Dashboard/Management/Vendors'))
|
const Vendors = lazy(() => import('../components/Dashboard/Management/Vendors'))
|
||||||
const VendorInfo = lazy(() => import('../components/Dashboard/Management/Vendors/VendorInfo'))
|
const VendorInfo = lazy(
|
||||||
const Materials = lazy(() => import('../components/Dashboard/Management/Materials'))
|
() => import('../components/Dashboard/Management/Vendors/VendorInfo')
|
||||||
const MaterialInfo = lazy(() => import('../components/Dashboard/Management/Materials/MaterialInfo.jsx'))
|
)
|
||||||
const Couriers = lazy(() => import('../components/Dashboard/Management/Couriers'))
|
const Materials = lazy(
|
||||||
const CourierInfo = lazy(() => import('../components/Dashboard/Management/Couriers/CourierInfo.jsx'))
|
() => import('../components/Dashboard/Management/Materials')
|
||||||
const CourierServices = lazy(() => import('../components/Dashboard/Management/CourierServices'))
|
)
|
||||||
const CourierServiceInfo = lazy(() => import('../components/Dashboard/Management/CourierServices/CourierServiceInfo.jsx'))
|
const MaterialInfo = lazy(
|
||||||
const Settings = lazy(() => import('../components/Dashboard/Management/Settings'))
|
() => import('../components/Dashboard/Management/Materials/MaterialInfo.jsx')
|
||||||
const AppUpdate = lazy(() => import('../components/Dashboard/Management/AppUpdate'))
|
)
|
||||||
const AuditLogs = lazy(() => import('../components/Dashboard/Management/AuditLogs.jsx'))
|
const Couriers = lazy(
|
||||||
const NoteTypes = lazy(() => import('../components/Dashboard/Management/NoteTypes.jsx'))
|
() => import('../components/Dashboard/Management/Couriers')
|
||||||
const NoteTypeInfo = lazy(() => import('../components/Dashboard/Management/NoteTypes/NoteTypeInfo.jsx'))
|
)
|
||||||
const NoteInfo = lazy(() => import('../components/Dashboard/Management/Notes/NoteInfo.jsx'))
|
const CourierInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Couriers/CourierInfo.jsx')
|
||||||
|
)
|
||||||
|
const CourierServices = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/CourierServices')
|
||||||
|
)
|
||||||
|
const CourierServiceInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/CourierServices/CourierServiceInfo.jsx')
|
||||||
|
)
|
||||||
|
const Settings = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Settings')
|
||||||
|
)
|
||||||
|
const AppUpdate = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/AppUpdate')
|
||||||
|
)
|
||||||
|
const AuditLogs = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/AuditLogs.jsx')
|
||||||
|
)
|
||||||
|
const NoteTypes = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/NoteTypes.jsx')
|
||||||
|
)
|
||||||
|
const NoteTypeInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/NoteTypes/NoteTypeInfo.jsx')
|
||||||
|
)
|
||||||
|
const NoteInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/Notes/NoteInfo.jsx')
|
||||||
|
)
|
||||||
const Users = lazy(() => import('../components/Dashboard/Management/Users.jsx'))
|
const Users = lazy(() => import('../components/Dashboard/Management/Users.jsx'))
|
||||||
const UserInfo = lazy(() => import('../components/Dashboard/Management/Users/UserInfo.jsx'))
|
const UserInfo = lazy(
|
||||||
const AppPasswords = lazy(() => import('../components/Dashboard/Management/AppPasswords.jsx'))
|
() => import('../components/Dashboard/Management/Users/UserInfo.jsx')
|
||||||
const AppPasswordInfo = lazy(() => import('../components/Dashboard/Management/AppPasswords/AppPasswordInfo.jsx'))
|
)
|
||||||
|
const AppPasswords = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/AppPasswords.jsx')
|
||||||
|
)
|
||||||
|
const AppPasswordInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/AppPasswords/AppPasswordInfo.jsx')
|
||||||
|
)
|
||||||
const Hosts = lazy(() => import('../components/Dashboard/Management/Hosts.jsx'))
|
const Hosts = lazy(() => import('../components/Dashboard/Management/Hosts.jsx'))
|
||||||
const HostInfo = lazy(() => import('../components/Dashboard/Management/Hosts/HostInfo.jsx'))
|
const HostInfo = lazy(
|
||||||
const DocumentSizes = lazy(() => import('../components/Dashboard/Management/DocumentSizes.jsx'))
|
() => import('../components/Dashboard/Management/Hosts/HostInfo.jsx')
|
||||||
const DocumentSizeInfo = lazy(() => import('../components/Dashboard/Management/DocumentSizes/DocumentSizeInfo.jsx'))
|
)
|
||||||
const DocumentTemplates = lazy(() => import('../components/Dashboard/Management/DocumentTemplates.jsx'))
|
const DocumentSizes = lazy(
|
||||||
const DocumentTemplateInfo = lazy(() => import('../components/Dashboard/Management/DocumentTemplates/DocumentTemplateInfo.jsx'))
|
() => import('../components/Dashboard/Management/DocumentSizes.jsx')
|
||||||
const DocumentPrinters = lazy(() => import('../components/Dashboard/Management/DocumentPrinters.jsx'))
|
)
|
||||||
const DocumentPrinterInfo = lazy(() => import('../components/Dashboard/Management/DocumentPrinters/DocumentPrinterInfo.jsx'))
|
const DocumentSizeInfo = lazy(
|
||||||
const DocumentJobs = lazy(() => import('../components/Dashboard/Management/DocumentJobs.jsx'))
|
() =>
|
||||||
const DocumentJobInfo = lazy(() => import('../components/Dashboard/Management/DocumentJobs/DocumentJobInfo.jsx'))
|
import('../components/Dashboard/Management/DocumentSizes/DocumentSizeInfo.jsx')
|
||||||
const DocumentTemplateDesign = lazy(() => import('../components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx'))
|
)
|
||||||
|
const DocumentTemplates = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/DocumentTemplates.jsx')
|
||||||
|
)
|
||||||
|
const DocumentTemplateInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/DocumentTemplates/DocumentTemplateInfo.jsx')
|
||||||
|
)
|
||||||
|
const DocumentPrinters = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/DocumentPrinters.jsx')
|
||||||
|
)
|
||||||
|
const DocumentPrinterInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/DocumentPrinters/DocumentPrinterInfo.jsx')
|
||||||
|
)
|
||||||
|
const DocumentJobs = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/DocumentJobs.jsx')
|
||||||
|
)
|
||||||
|
const DocumentJobInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/DocumentJobs/DocumentJobInfo.jsx')
|
||||||
|
)
|
||||||
|
const DocumentTemplateDesign = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx')
|
||||||
|
)
|
||||||
const Files = lazy(() => import('../components/Dashboard/Management/Files.jsx'))
|
const Files = lazy(() => import('../components/Dashboard/Management/Files.jsx'))
|
||||||
const FileInfo = lazy(() => import('../components/Dashboard/Management/Files/FileInfo.jsx'))
|
const FileInfo = lazy(
|
||||||
const TaxRates = lazy(() => import('../components/Dashboard/Management/TaxRates.jsx'))
|
() => import('../components/Dashboard/Management/Files/FileInfo.jsx')
|
||||||
const TaxRateInfo = lazy(() => import('../components/Dashboard/Management/TaxRates/TaxRateInfo.jsx'))
|
)
|
||||||
const TaxRecords = lazy(() => import('../components/Dashboard/Management/TaxRecords.jsx'))
|
const TaxRates = lazy(
|
||||||
const TaxRecordInfo = lazy(() => import('../components/Dashboard/Management/TaxRecords/TaxRecordInfo.jsx'))
|
() => import('../components/Dashboard/Management/TaxRates.jsx')
|
||||||
|
)
|
||||||
|
const TaxRateInfo = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/TaxRates/TaxRateInfo.jsx')
|
||||||
|
)
|
||||||
|
const TaxRecords = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/TaxRecords.jsx')
|
||||||
|
)
|
||||||
|
const TaxRecordInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../components/Dashboard/Management/TaxRecords/TaxRecordInfo.jsx')
|
||||||
|
)
|
||||||
|
const About = lazy(() => import('../components/Dashboard/Management/About.jsx'))
|
||||||
|
|
||||||
const ManagementRoutes = [
|
const ManagementRoutes = [
|
||||||
<Route key='filaments' path='management/filaments' element={<Filaments />} />,
|
<Route key='filaments' path='management/filaments' element={<Filaments />} />,
|
||||||
@ -58,7 +158,11 @@ const ManagementRoutes = [
|
|||||||
path='management/filaments/info'
|
path='management/filaments/info'
|
||||||
element={<FilamentInfo />}
|
element={<FilamentInfo />}
|
||||||
/>,
|
/>,
|
||||||
<Route key='filamentskus' path='management/filamentskus' element={<FilamentSkus />} />,
|
<Route
|
||||||
|
key='filamentskus'
|
||||||
|
path='management/filamentskus'
|
||||||
|
element={<FilamentSkus />}
|
||||||
|
/>,
|
||||||
<Route
|
<Route
|
||||||
key='filamentskus-info'
|
key='filamentskus-info'
|
||||||
path='management/filamentskus/info'
|
path='management/filamentskus/info'
|
||||||
@ -92,7 +196,11 @@ const ManagementRoutes = [
|
|||||||
path='management/productcategories/info'
|
path='management/productcategories/info'
|
||||||
element={<ProductCategoryInfo />}
|
element={<ProductCategoryInfo />}
|
||||||
/>,
|
/>,
|
||||||
<Route key='productskus' path='management/productskus' element={<ProductSkus />} />,
|
<Route
|
||||||
|
key='productskus'
|
||||||
|
path='management/productskus'
|
||||||
|
element={<ProductSkus />}
|
||||||
|
/>,
|
||||||
<Route
|
<Route
|
||||||
key='productskus-info'
|
key='productskus-info'
|
||||||
path='management/productskus/info'
|
path='management/productskus/info'
|
||||||
@ -208,6 +316,7 @@ const ManagementRoutes = [
|
|||||||
/>,
|
/>,
|
||||||
<Route key='settings' path='management/settings' element={<Settings />} />,
|
<Route key='settings' path='management/settings' element={<Settings />} />,
|
||||||
<Route key='appupdate' path='management/appupdate' element={<AppUpdate />} />,
|
<Route key='appupdate' path='management/appupdate' element={<AppUpdate />} />,
|
||||||
|
<Route key='about' path='management/about' element={<About />} />,
|
||||||
<Route key='auditlogs' path='management/auditlogs' element={<AuditLogs />} />,
|
<Route key='auditlogs' path='management/auditlogs' element={<AuditLogs />} />,
|
||||||
<Route key='taxrates' path='management/taxrates' element={<TaxRates />} />,
|
<Route key='taxrates' path='management/taxrates' element={<TaxRates />} />,
|
||||||
<Route
|
<Route
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user