Tom Butcher 24a3a03c65
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
Enhance Dashboard Functionality and Icon Integration
- Updated DashboardLayout to utilize Electron context for dynamic spacing adjustments.
- Enhanced About and Settings components to include icon keys for improved navigation clarity.
- Refined DashboardOverviewPage to generate dynamic icon keys based on page names.
- Improved DashboardTabs to support sidebar icons, enhancing visual consistency.
- Expanded NavigationTabsContext to manage icon keys for tabs, streamlining tab interactions.
- Updated sidebarIconMap to utilize component references for better performance and maintainability.
2026-09-19 01:57:42 +01:00

195 lines
6.5 KiB
JavaScript

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 { AppUpdateContext } from '../context/AppUpdateContext'
import { useMediaQuery } from 'react-responsive'
import FarmControlAppIcon from '../../Logos/FarmControlAppIcon'
import SoftwareUpdateIcon from '../../Icons/SoftwareUpdateIcon'
import ExternalLink from '../common/ExternalLink'
import { useNavigationTabPage } from '../context/NavigationTabsContext'
const { Title, Text } = Typography
const About = () => {
useNavigationTabPage({ title: 'About', iconKey: 'infoCircle' })
const [collapseState, updateCollapseState] = useCollapseState('About', {
updater: true
})
const { token } = useContext(AuthContext)
const { fetchApiServerVersion, fetchWsServerVersion, connected } =
useContext(ApiServerContext)
const { isElectron, getAppEngine } = useContext(ElectronContext)
const { checkForUpdates } = useContext(AppUpdateContext)
const isMobile = useMediaQuery({ maxWidth: 768 })
const buildNumber = import.meta.env.VITE_BUILD_NUMBER
? 'b' + import.meta.env.VITE_BUILD_NUMBER
: 'dev'
const developmentMode = import.meta.env.MODE === 'development'
const actions = [
{
label: 'Reload Window',
icon: <ReloadIcon />,
onClick: () => {
window.location.reload()
}
}
]
if (isElectron) {
actions.unshift(
{
label: 'Check for Updates',
icon: <SoftwareUpdateIcon />,
onClick: checkForUpdates
},
{ type: 'divider' }
)
}
useEffect(() => {
if (token && connected) {
fetchApiServerVersion().then((version) => {
setApiServerVersion(version)
})
fetchWsServerVersion().then((version) => {
setWsServerVersion(version)
})
}
}, [fetchApiServerVersion, fetchWsServerVersion, token, connected])
useEffect(() => {
if (!isElectron) return
getAppEngine()
.then((engine) => {
setAppEngine(engine === 'chromium' ? 'Chromium' : 'Native')
})
.catch(() => {
setAppEngine('Unknown')
})
}, [getAppEngine, isElectron])
const [apiServerVersion, setApiServerVersion] = useState(null)
const [wsServerVersion, setWsServerVersion] = useState(null)
const [appEngine, setAppEngine] = useState(null)
const apiServerVersionText = apiServerVersion ? (
<Text>
{`v${apiServerVersion.version}-${apiServerVersion.buildNumber == 'dev' ? 'dev' : 'b' + apiServerVersion.buildNumber}`}
</Text>
) : (
<Skeleton.Input active size='small' className='text-skeleton' />
)
const wsServerVersionText = wsServerVersion ? (
<Text>{`v${wsServerVersion.version}-${wsServerVersion.buildNumber == 'dev' ? 'dev' : 'b' + wsServerVersion.buildNumber}`}</Text>
) : (
<Skeleton.Input active size='small' className='text-skeleton' />
)
const appEngineText = appEngine ? (
<Text>{appEngine}</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'>
<FarmControlAppIcon 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'>Engine: {appEngineText}</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>
)}
<ExternalLink href='https://ci.tombutcher.work/job/farmcontrol'>
Jenkins
</ExternalLink>
<Divider type='vertical' style={{ margin: 0 }} />
<ExternalLink href='https://git.tombutcher.work/farmcontrol'>
Git
</ExternalLink>
</Flex>
</Flex>
</Flex>
</InfoCollapse>
</Flex>
</Flex>
</div>
)
}
export default About