Compare commits

..

No commits in common. "3c634a90d0b381a5de864f34ef6d47c4b7c09538" and "95e02dcd6342d7e4601271e66002224bc05d212e" have entirely different histories.

51 changed files with 172 additions and 301 deletions

View File

@ -640,7 +640,6 @@ body {
.h-100 { .h-100 {
height: 100%; height: 100%;
min-height: 0;
} }
.ant-table.ant-table-middle .ant-table-filter-trigger { .ant-table.ant-table-middle .ant-table-filter-trigger {
@ -805,15 +804,6 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
margin-left: 4px; margin-left: 4px;
} }
.farmcontrol-splitter .ant-splitter-panel {
overflow: visible;
}
.farmcontrol-splitter.ant-splitter-horizontal .ant-splitter-panel {
width: 100%;
min-width: 0;
}
.farmcontrol-splitter .farmcontrol-splitter
.ant-splitter-panel:has(~ .ant-splitter-panel) .ant-splitter-panel:has(~ .ant-splitter-panel)
.info-collapse.ant-collapse.ant-collapse-icon-position-end .info-collapse.ant-collapse.ant-collapse-icon-position-end
@ -822,23 +812,3 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
.ant-collapse-expand-icon { .ant-collapse-expand-icon {
padding-inline-end: 2px; padding-inline-end: 2px;
} }
.objectTableCards {
overflow: hidden;
}
.objectTableCardsContainer {
width: 100%;
height: 100%;
min-width: 0;
}
.objectTableCardsContainer .ant-spin-nested-loading {
width: 100%;
height: 100%;
}
.objectTableCardsContainer .ant-spin-container {
width: 100%;
height: 100%;
}

View File

@ -50,7 +50,7 @@ const Invoices = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const Payments = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const TaxRecords = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -55,7 +55,7 @@ const FilamentStocks = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const OrderItems = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -55,7 +55,7 @@ const PartStocks = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -56,7 +56,7 @@ const ProductStocks = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const PurchaseOrders = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const Shipments = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -55,7 +55,7 @@ const StockAudits = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -38,7 +38,7 @@ const StockEvents = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -53,7 +53,7 @@ const StockLocations = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -53,7 +53,7 @@ const StockTransfers = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const AppPasswords = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -36,7 +36,7 @@ const AuditLogs = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const CourierServices = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const Couriers = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const DocumentJobs = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const DocumentPrinters = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -48,7 +48,7 @@ const DocumentSizes = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const DocumentTemplates = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -53,7 +53,7 @@ const FilamentSkus = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -55,7 +55,7 @@ const Filaments = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -38,7 +38,7 @@ const Files = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -54,7 +54,7 @@ const Hosts = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -52,7 +52,7 @@ const Materials = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const NoteTypes = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -52,7 +52,7 @@ const PartSkus = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -54,7 +54,7 @@ const Parts = (filter) => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -52,7 +52,7 @@ const ProductCategories = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -53,7 +53,7 @@ const ProductSkus = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -325,7 +325,7 @@ const Products = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const TaxRates = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -37,7 +37,7 @@ const Users = () => {
return ( return (
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const Vendors = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -77,7 +77,7 @@ const FilamentProfiles = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -52,7 +52,7 @@ const GCodeFiles = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -54,7 +54,7 @@ const Jobs = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -66,7 +66,7 @@ const PrinterProfiles = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -55,7 +55,7 @@ const Printers = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space> <Space>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -39,7 +39,7 @@ const SubJobs = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -49,7 +49,7 @@ const Clients = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const Listings = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const Marketplaces = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -50,7 +50,7 @@ const SalesOrders = () => {
return ( return (
<> <>
<Flex vertical={'true'} gap='large' className='h-100'> <Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}> <Flex justify={'space-between'}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -36,8 +36,6 @@ const FilePreview = ({ file, style = {} }) => {
} }
}, [file._id, file?.type, fetchPreview, token]) }, [file._id, file?.type, fetchPreview, token])
console.log(file)
if (loading == true || !file?.type) { if (loading == true || !file?.type) {
return <LoadingPlaceholder message={'Loading file preview...'} /> return <LoadingPlaceholder message={'Loading file preview...'} />
} }
@ -46,11 +44,13 @@ const FilePreview = ({ file, style = {} }) => {
return <div style={{ color: 'red' }}>{error}</div> return <div style={{ color: 'red' }}>{error}</div>
} }
const isGcode = const isGcode = ['.g', '.gcode'].includes(
['.g', '.gcode'].includes((file?.extension || '').toLowerCase()) || false (file?.extension || '').toLowerCase()
)
const is3DModel = const is3DModel = ['.stl', '.3mf'].includes(
['.stl', '.3mf'].includes((file?.extension || '').toLowerCase()) || false (file?.extension || '').toLowerCase()
)
const isImage = file?.type.startsWith('image/') const isImage = file?.type.startsWith('image/')

View File

@ -66,31 +66,6 @@ const ObjectCard = ({
? descriptionItems.slice(2) ? descriptionItems.slice(2)
: descriptionItems : descriptionItems
const nameContent = (
<>
<Flex align='center' gap={12} style={{ minWidth: 0 }}>
{modelIcon}
<ObjectProperty
{...model.properties.find((p) => p.name === 'name')}
objectData={record}
isEditing={isEditing}
style={{
fontSize: 20,
fontWeight: '600',
lineHeight: 1.2,
minWidth: 0
}}
/>
{visibleColumns?.state == true && (
<ObjectProperty
{...model.properties.find((p) => p.name === 'state')}
objectData={record}
/>
)}
</Flex>
</>
)
return ( return (
<Card <Card
styles={{ body: { padding: 18 } }} styles={{ body: { padding: 18 } }}
@ -113,7 +88,28 @@ const ObjectCard = ({
size={128} size={128}
/> />
<Flex vertical gap={10} style={{ minWidth: 0 }}> <Flex vertical gap={10} style={{ minWidth: 0 }}>
{visibleColumns?.name == true && nameContent} {visibleColumns?.name == true && (
<Flex align='center' gap={12} style={{ minWidth: 0 }}>
{modelIcon}
<ObjectProperty
{...model.properties.find((p) => p.name === 'name')}
objectData={record}
isEditing={isEditing}
style={{
fontSize: 20,
fontWeight: '600',
lineHeight: 1.2,
minWidth: 0
}}
/>
{visibleColumns?.state == true && (
<ObjectProperty
{...model.properties.find((p) => p.name === 'state')}
objectData={record}
/>
)}
</Flex>
)}
{primaryDescriptionItems.length > 0 && ( {primaryDescriptionItems.length > 0 && (
<Descriptions <Descriptions
column={1} column={1}
@ -127,7 +123,6 @@ const ObjectCard = ({
</Flex> </Flex>
)} )}
<Flex vertical gap={8}> <Flex vertical gap={8}>
{visibleColumns?.name == true && !thumbnailPresent && nameContent}
{remainingDescriptionItems.length > 0 && ( {remainingDescriptionItems.length > 0 && (
<Descriptions <Descriptions
column={1} column={1}

View File

@ -45,7 +45,6 @@ import { AuthContext } from '../context/AuthContext'
import { ElectronContext } from '../context/ElectronContext' import { ElectronContext } from '../context/ElectronContext'
import ActionsIcon from '../../Icons/ActionsIcon' import ActionsIcon from '../../Icons/ActionsIcon'
import FilterIcon from '../../Icons/FilterIcon' import FilterIcon from '../../Icons/FilterIcon'
import ScrollBox from './ScrollBox'
const logger = loglevel.getLogger('DasboardTable') const logger = loglevel.getLogger('DasboardTable')
logger.setLevel(config.logLevel) logger.setLevel(config.logLevel)
@ -53,14 +52,6 @@ logger.setLevel(config.logLevel)
const SCROLL_THRESHOLD = 50 const SCROLL_THRESHOLD = 50
const SKELETON_HEIGHT = 49.5 const SKELETON_HEIGHT = 49.5
const getCardColSpan = (containerWidth) => {
if (containerWidth >= 2980) return 2
if (containerWidth >= 1780) return 4
if (containerWidth >= 1080) return 8
if (containerWidth >= 680) return 12
return 24
}
const RowForm = ({ record, isEditing, onRegister, children }) => { const RowForm = ({ record, isEditing, onRegister, children }) => {
const [form] = Form.useForm() const [form] = Form.useForm()
useEffect(() => { useEffect(() => {
@ -141,7 +132,7 @@ const ObjectTable = forwardRef(
const navigate = useNavigate() const navigate = useNavigate()
var adjustedScrollHeight = scrollHeight var adjustedScrollHeight = scrollHeight
if (isMobile) { if (isMobile) {
adjustedScrollHeight = 'calc(var(--unit-100vh) - 298px)' adjustedScrollHeight = 'calc(var(--unit-100vh) - 316px)'
} }
if (cards) { if (cards) {
adjustedScrollHeight = 'calc(var(--unit-100vh) - 210px)' adjustedScrollHeight = 'calc(var(--unit-100vh) - 210px)'
@ -1046,68 +1037,13 @@ const ObjectTable = forwardRef(
} }
// Card view rendering // Card view rendering
const [cardColSpan, setCardColSpan] = useState(24) const cardsContainerRef = useRef(null)
const cardsContainerNodeRef = useRef(null)
const cardsResizeObserverRef = useRef(null)
const measureCardColSpan = useCallback(() => {
const node = cardsContainerNodeRef.current
if (!node) return
const panel = node.closest('.ant-splitter-panel')
const width = (panel ?? node).getBoundingClientRect().width
if (width <= 0) return
const nextSpan = getCardColSpan(width)
setCardColSpan((prev) => (prev === nextSpan ? prev : nextSpan))
}, [])
const objectTableCardsContainerRef = useCallback(
(node) => {
cardsResizeObserverRef.current?.disconnect()
cardsResizeObserverRef.current = null
cardsContainerNodeRef.current = node
if (!node) return
let rafId = null
const scheduleMeasure = () => {
if (rafId != null) cancelAnimationFrame(rafId)
rafId = requestAnimationFrame(() => {
rafId = null
measureCardColSpan()
})
}
scheduleMeasure()
const observer = new ResizeObserver(scheduleMeasure)
const panel = node.closest('.ant-splitter-panel')
if (panel) {
observer.observe(panel)
} else {
observer.observe(node)
}
cardsResizeObserverRef.current = observer
},
[measureCardColSpan]
)
useLayoutEffect(() => {
if (!cards) return
measureCardColSpan()
}, [cards, showFilterSidebar, measureCardColSpan])
useEffect(() => {
return () => cardsResizeObserverRef.current?.disconnect()
}, [])
// Card view scroll handler // Card view scroll handler
useEffect(() => { useEffect(() => {
if (!cards) return if (!cards) return
const container = cardsContainerNodeRef.current const container = cardsContainerRef.current
if (!container) return if (!container) return
const scrollEl = container.querySelector('.simplebar-content-wrapper')
if (!scrollEl) return
const handleCardsScroll = (e) => { const handleCardsScroll = (e) => {
const { scrollTop, scrollHeight, clientHeight } = e.target const { scrollTop, scrollHeight, clientHeight } = e.target
@ -1119,60 +1055,68 @@ const ObjectTable = forwardRef(
scrollHeight - scrollTop - clientHeight < 100 && scrollHeight - scrollTop - clientHeight < 100 &&
!lazyLoading !lazyLoading
) { ) {
loadNextPage(scrollEl) loadNextPage()
} else if ( } else if (
firstPage?.isSkeletonPage && firstPage?.isSkeletonPage &&
scrollTop < 100 && scrollTop < 100 &&
!lazyLoading !lazyLoading
) { ) {
loadPreviousPage(scrollEl) loadPreviousPage()
} }
} }
scrollEl.addEventListener('scroll', handleCardsScroll) container.addEventListener('scroll', handleCardsScroll)
return () => scrollEl.removeEventListener('scroll', handleCardsScroll) return () => container.removeEventListener('scroll', handleCardsScroll)
}, [cards, pages, lazyLoading, loadNextPage, loadPreviousPage]) }, [cards, pages, lazyLoading, loadNextPage, loadPreviousPage])
const renderCards = () => { const renderCards = () => {
return ( return (
<ScrollBox <Row
gutter={[16, 16]}
style={{ style={{
maxHeight: `100%` overflowY: 'auto',
maxHeight: adjustedScrollHeight
}} }}
ref={cardsContainerRef}
> >
<div className='objectTableCards'> {tableData.map((record) => {
<Row gutter={[16, 16]} key={cardColSpan}> if (record?._id == undefined) {
{tableData.map((record) => { return null
if (record?._id == undefined) { }
return null return (
} <Col
return ( xs={24}
<Col span={cardColSpan} key={record._id}> sm={24}
<div style={{ width: '100%', overflow: 'hidden' }}> md={24}
<RowForm lg={12}
xl={12}
xxl={8}
xxxl={6}
key={record._id}
>
<div style={{ width: '100%', overflow: 'hidden' }}>
<RowForm
record={record}
isEditing={isEditing}
onRegister={registerForm}
>
<Flex align={'center'} vertical gap={'middle'}>
<ObjectCard
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
record={record} record={record}
isEditing={isEditing} isEditing={isEditing}
onRegister={registerForm} rowActions={rowActions}
> renderActions={renderActions}
<Flex align={'center'} vertical gap={'middle'}> />
<ObjectCard </Flex>
model={model} </RowForm>
modelProperties={modelProperties} </div>
visibleColumns={visibleColumns} </Col>
record={record} )
isEditing={isEditing} })}
rowActions={rowActions} </Row>
renderActions={renderActions}
/>
</Flex>
</RowForm>
</div>
</Col>
)
})}
</Row>
</div>
</ScrollBox>
) )
} }
@ -1195,30 +1139,13 @@ const ObjectTable = forwardRef(
) )
const tableContent = ( const tableContent = (
<Flex <Flex gap={'middle'} vertical style={{ flex: 1, minWidth: 0 }}>
gap={'middle'} <Splitter className={'farmcontrol-splitter'}>
vertical
style={{ flex: 1, minWidth: 0, minHeight: 0 }}
>
<Splitter
className={'farmcontrol-splitter'}
onResize={measureCardColSpan}
onResizeEnd={measureCardColSpan}
>
<Splitter.Panel> <Splitter.Panel>
{cards ? ( {cards ? (
<div <Spin indicator={<LoadingOutlined />} spinning={loading}>
className='objectTableCardsContainer' {renderCards()}
ref={objectTableCardsContainerRef} </Spin>
>
<Spin
indicator={<LoadingOutlined />}
spinning={loading}
style={{ height: '100%' }}
>
{renderCards()}
</Spin>
</div>
) : ( ) : (
<Table <Table
ref={tableRef} ref={tableRef}

View File

@ -145,62 +145,48 @@ const ApiServerProvider = ({ children }) => {
notificationListenersRef.current.clear() notificationListenersRef.current.clear()
}, []) }, [])
const resubscribeActivityListeners = useCallback( const resubscribeActivityListeners = useCallback((socket = socketRef.current) => {
(socket = socketRef.current) => { if (!socket?.connected) {
if (!socket?.connected) { return
}
subscribedActivityCallbacksRef.current.forEach((callbacks, callbacksRefKey) => {
if (!callbacks?.length) {
return return
} }
subscribedActivityCallbacksRef.current.forEach( if (subscribedActivityServerSubscriptionsRef.current.has(callbacksRefKey)) {
(callbacks, callbacksRefKey) => { return
if (!callbacks?.length) { }
return
}
if ( const colonIndex = callbacksRefKey.indexOf(':')
subscribedActivityServerSubscriptionsRef.current.has( if (colonIndex === -1) {
callbacksRefKey return
) }
) {
return
}
const colonIndex = callbacksRefKey.indexOf(':') const objectType = callbacksRefKey.slice(0, colonIndex)
if (colonIndex === -1) { const objectId = callbacksRefKey.slice(colonIndex + 1)
return
}
const objectType = callbacksRefKey.slice(0, colonIndex) socket.emit(
const objectId = callbacksRefKey.slice(colonIndex + 1) 'subscribeToObjectActivity',
{ _id: objectId, objectType },
socket.emit( (result) => {
'subscribeToObjectActivity', if (result?.success) {
{ _id: objectId, objectType }, subscribedActivityServerSubscriptionsRef.current.add(callbacksRefKey)
(result) => { if (Array.isArray(result.activities)) {
if (result?.success) { callbacks.forEach((callback) => {
subscribedActivityServerSubscriptionsRef.current.add( try {
callbacksRefKey callback(null, result.activities)
) } catch (error) {
if (Array.isArray(result.activities)) { logger.error('Error in activity resubscribe callback:', error)
callbacks.forEach((callback) => {
try {
callback(null, result.activities)
} catch (error) {
logger.error(
'Error in activity resubscribe callback:',
error
)
}
})
} }
} })
} }
) }
} }
) )
}, })
[] }, [])
)
const registerNotificationListener = useCallback((callback) => { const registerNotificationListener = useCallback((callback) => {
notificationListenersRef.current.add(callback) notificationListenersRef.current.add(callback)
@ -980,9 +966,7 @@ const ApiServerProvider = ({ children }) => {
{ _id: id, objectType: type }, { _id: id, objectType: type },
(result) => { (result) => {
if (result?.success) { if (result?.success) {
subscribedActivityServerSubscriptionsRef.current.add( subscribedActivityServerSubscriptionsRef.current.add(callbacksRefKey)
callbacksRefKey
)
if (Array.isArray(result.activities)) { if (Array.isArray(result.activities)) {
subscribedActivityCallbacksRef.current subscribedActivityCallbacksRef.current
.get(callbacksRefKey) .get(callbacksRefKey)
@ -990,10 +974,7 @@ const ApiServerProvider = ({ children }) => {
try { try {
activityCallback(null, result.activities) activityCallback(null, result.activities)
} catch (error) { } catch (error) {
logger.error( logger.error('Error in activity subscribe callback:', error)
'Error in activity subscribe callback:',
error
)
} }
}) })
} }

View File

@ -68,13 +68,6 @@ export const User = {
readOnly: true, readOnly: true,
columnWidth: 180 columnWidth: 180
}, },
{
name: 'updatedAt',
label: 'Updated At',
type: 'dateTime',
readOnly: true,
columnWidth: 175
},
{ {
name: 'name', name: 'name',
label: 'Name', label: 'Name',
@ -83,13 +76,12 @@ export const User = {
type: 'text', type: 'text',
columnWidth: 200 columnWidth: 200
}, },
{ {
name: 'username', name: 'updatedAt',
label: 'Username', label: 'Updated At',
required: true, type: 'dateTime',
type: 'text', readOnly: true,
columnWidth: 150 columnWidth: 175
}, },
{ {
@ -98,7 +90,13 @@ export const User = {
type: 'text', type: 'text',
columnWidth: 130 columnWidth: 130
}, },
{
name: 'username',
label: 'Username',
required: true,
type: 'text',
columnWidth: 150
},
{ {
name: 'lastName', name: 'lastName',
label: 'Last Name', label: 'Last Name',