Compare commits

..

3 Commits

Author SHA1 Message Date
847e593154 Themed wizard view steps.
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
2026-03-13 20:22:36 +00:00
994f0d7d44 Fixed column visibility bug. 2026-03-13 20:10:39 +00:00
556f8622ee Hosts fixes and improvements. 2026-03-13 20:08:38 +00:00
19 changed files with 111 additions and 85 deletions

View File

@ -37,6 +37,8 @@
.ant-badge,
.ant-select-dropdown,
.ant-splitter,
.ant-steps-item-title,
.ant-steps-icon,
[class*=' ant-radio'] {
font-family: 'DM Sans';
}
@ -46,6 +48,15 @@
font-family: 'DM Mono';
}
.ant-steps .ant-steps-item-icon {
line-height: 30px;
font-weight: 600;
}
.ant-steps .ant-steps-item-icon .anticon.anticon-check.ant-steps-finish-icon {
line-height: 32px;
}
.ant-typography .id-text {
font-family: 'DM Mono';
font-size: 11.9px;

View File

@ -14,7 +14,7 @@ const StockEvents = () => {
const [viewMode, setViewMode] = useViewMode('stockEvents')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockEvents')
useColumnVisibility('stockEvent')
const actionItems = {
items: [

View File

@ -11,7 +11,7 @@ const AuditLogs = () => {
const tableRef = useRef()
const [columnVisibility, updateColumnVisibility] =
useColumnVisibility('auditLogs')
useColumnVisibility('auditLog')
const actionItems = {
items: [

View File

@ -54,8 +54,8 @@ const CourierServices = () => {
<ColumnViewButton
type='courierService'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='courierService' />
</Space>

View File

@ -53,8 +53,8 @@ const Couriers = () => {
<ColumnViewButton
type='courier'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='courier' />
</Space>

View File

@ -54,8 +54,8 @@ const DocumentJobs = () => {
<ColumnViewButton
type='documentJob'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='documentJob' />
</Space>

View File

@ -53,8 +53,8 @@ const DocumentPrinters = () => {
<ColumnViewButton
type='documentPrinter'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='documentPrinter' />
</Space>

View File

@ -54,8 +54,8 @@ const DocumentTemplates = () => {
<ColumnViewButton
type='documentTemplate'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='documentTemplate' />
</Space>

View File

@ -42,8 +42,8 @@ const Files = () => {
<ColumnViewButton
type='file'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='file' />
</Space>

View File

@ -84,6 +84,7 @@ const Hosts = () => {
open={newHostOpen}
footer={null}
width={700}
destroyOnHidden={true}
onCancel={() => {
setNewHostOpen(false)
}}

View File

@ -1,21 +1,14 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useMediaQuery } from 'react-responsive'
import { Typography, Flex, Steps, Divider } from 'antd'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
import WizardView from '../../common/WizardView'
const NewHost = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
const isMobile = useMediaQuery({ maxWidth: 768 })
return (
<NewObjectForm type={'host'}>
<NewObjectForm
type={'host'}
defaultValues={{ active: true, state: { type: 'offline' } }}
>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
const steps = [
{
@ -43,6 +36,20 @@ const NewHost = ({ onOk }) => {
isEditing={true}
required={false}
objectData={objectData}
visibleProperties={{
_id: false,
createdAt: false,
updatedAt: false,
operatingSystem: false,
'deviceInfo.os': false,
'deviceInfo.os.hostname': false,
'deviceInfo.cpu': false,
'deviceInfo.cpu.model': false,
'deviceInfo.user.username': false,
'deviceInfo.user.homedir': false,
'deviceInfo.process.nodeVersion': false,
files: false
}}
/>
)
},
@ -57,7 +64,18 @@ const NewHost = ({ onOk }) => {
visibleProperties={{
_id: false,
createdAt: false,
updatedAt: false
updatedAt: false,
operatingSystem: false,
'deviceInfo.os': false,
'deviceInfo.os.hostname': false,
'deviceInfo.cpu': false,
'deviceInfo.cpu.model': false,
'deviceInfo.user.username': false,
'deviceInfo.user.homedir': false,
'deviceInfo.process.nodeVersion': false,
files: false,
connectedAt: false,
online: false
}}
isEditing={false}
objectData={objectData}
@ -66,45 +84,18 @@ const NewHost = ({ onOk }) => {
}
]
return (
<Flex gap='middle'>
{!isMobile && (
<div style={{ minWidth: '160px' }}>
<Steps
current={currentStep}
items={steps}
direction='vertical'
style={{ width: 'fit-content' }}
/>
</div>
)}
{!isMobile && (
<Divider type='vertical' style={{ height: 'unset' }} />
)}
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
<Title level={2} style={{ margin: 0 }}>
New Host
</Title>
<div style={{ minHeight: '260px', marginBottom: 8 }}>
{steps[currentStep].content}
</div>
<NewObjectButtons
currentStep={currentStep}
totalSteps={steps.length}
onPrevious={() => setCurrentStep((prev) => prev - 1)}
onNext={() => setCurrentStep((prev) => prev + 1)}
<WizardView
steps={steps}
loading={submitLoading}
formValid={formValid}
title='New Host'
onSubmit={async () => {
const result = await handleSubmit()
if (result) {
onOk()
}
}}
formValid={formValid}
submitLoading={submitLoading}
/>
</Flex>
</Flex>
)
}}
</NewObjectForm>

View File

@ -54,8 +54,8 @@ const NoteTypes = () => {
<ColumnViewButton
type='noteType'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='noteType' />
</Space>

View File

@ -58,8 +58,8 @@ const Parts = (filter) => {
<ColumnViewButton
type='part'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='part' />
</Space>

View File

@ -231,7 +231,7 @@ const Products = () => {
]
const [columnVisibility, updateColumnVisibility] = useColumnVisibility(
'Products',
'product',
columns
)

View File

@ -53,8 +53,8 @@ const TaxRates = () => {
<ColumnViewButton
type='taxRate'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='taxRate' />
</Space>

View File

@ -53,8 +53,8 @@ const Vendors = () => {
<ColumnViewButton
type='vendor'
loading={false}
collapseState={columnVisibility}
updateCollapseState={setColumnVisibility}
visibleState={columnVisibility}
updateVisibleState={setColumnVisibility}
/>
<ExportListButton objectType='vendor' />
</Space>

View File

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useMediaQuery } from 'react-responsive'
import CheckIcon from '../../Icons/CheckIcon'
import {
Typography,
Flex,
@ -40,7 +41,17 @@ const WizardView = ({
<div style={{ minWidth: sideBarGrow == true ? '100%' : '160px' }}>
<Steps
current={currentStep}
items={steps}
items={steps.map((step, index) => ({
...step,
icon:
index < currentStep ? (
<div className='ant-steps-item-icon'>
<CheckIcon />
</div>
) : (
step.icon
)
}))}
direction='vertical'
style={{ width: 'fit-content' }}
/>

View File

@ -1,13 +1,22 @@
import { useState, useEffect } from 'react'
import { getModelByName } from '../../../database/ObjectModels'
const useColumnVisibility = (type) => {
const useColumnVisibility = (type, customColumns) => {
const getInitialVisibility = () => {
const stored = sessionStorage.getItem(`${type}_columnVisibility`)
const storageKey = `${type}_columnVisibility`
const stored = sessionStorage.getItem(storageKey)
if (stored) {
return JSON.parse(stored)
}
// Default visibility - all columns visible
if (customColumns && Array.isArray(customColumns)) {
return customColumns.reduce((acc, col) => {
if (col.key) {
acc[col.key] = true
}
return acc
}, {})
}
const model = getModelByName(type)
const columns = model.columns || []
return columns.reduce((acc, columnName) => {

View File

@ -28,13 +28,6 @@ export const Host = {
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=reload`
},
{
name: 'connect',
label: 'Connect',
icon: OTPIcon,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=hostOTP`
},
{
name: 'edit',
label: 'Edit',
@ -65,6 +58,16 @@ export const Host = {
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
type: 'divider'
},
{
name: 'connect',
label: 'Connect',
icon: OTPIcon,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=hostOTP`
}
],
columns: ['name', '_reference', 'state', 'tags', 'connectedAt'],