Enhance layout and styling across various components

- Added min-height: 0 to Flex components in multiple files to improve layout consistency.
- Updated App.css with new styles for .farmcontrol-splitter and .objectTableCards to enhance visual structure and overflow handling.
- Refactored ObjectTable component to utilize ScrollBox for better scrolling behavior and layout management.
This commit is contained in:
Tom Butcher 2026-07-31 23:41:49 +01:00
parent 95e02dcd63
commit c6ad465ad6
49 changed files with 188 additions and 133 deletions

View File

@ -640,6 +640,7 @@ 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 {
@ -804,6 +805,14 @@ 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%;
}
.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
@ -812,3 +821,22 @@ 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%;
}
.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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<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'}> <Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'> <Space size='small'>
<Dropdown menu={actionItems}> <Dropdown menu={actionItems}>
<Button>Actions</Button> <Button>Actions</Button>

View File

@ -36,6 +36,8 @@ 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...'} />
} }
@ -44,13 +46,11 @@ const FilePreview = ({ file, style = {} }) => {
return <div style={{ color: 'red' }}>{error}</div> return <div style={{ color: 'red' }}>{error}</div>
} }
const isGcode = ['.g', '.gcode'].includes( const isGcode =
(file?.extension || '').toLowerCase() ['.g', '.gcode'].includes((file?.extension || '').toLowerCase()) || false
)
const is3DModel = ['.stl', '.3mf'].includes( const is3DModel =
(file?.extension || '').toLowerCase() ['.stl', '.3mf'].includes((file?.extension || '').toLowerCase()) || false
)
const isImage = file?.type.startsWith('image/') const isImage = file?.type.startsWith('image/')

View File

@ -45,6 +45,7 @@ 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)
@ -132,7 +133,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) - 316px)' adjustedScrollHeight = 'calc(var(--unit-100vh) - 298px)'
} }
if (cards) { if (cards) {
adjustedScrollHeight = 'calc(var(--unit-100vh) - 210px)' adjustedScrollHeight = 'calc(var(--unit-100vh) - 210px)'
@ -1071,52 +1072,53 @@ const ObjectTable = forwardRef(
const renderCards = () => { const renderCards = () => {
return ( return (
<Row <ScrollBox
gutter={[16, 16]}
style={{ style={{
overflowY: 'auto', maxHeight: `100%`
maxHeight: adjustedScrollHeight
}} }}
ref={cardsContainerRef}
> >
{tableData.map((record) => { <div className='objectTableCards'>
if (record?._id == undefined) { <Row gutter={[16, 16]} ref={cardsContainerRef}>
return null {tableData.map((record) => {
} if (record?._id == undefined) {
return ( return null
<Col }
xs={24} return (
sm={24} <Col
md={24} xs={24}
lg={12} sm={24}
xl={12} md={24}
xxl={8} lg={12}
xxxl={6} xl={12}
key={record._id} xxl={8}
> xxxl={6}
<div style={{ width: '100%', overflow: 'hidden' }}> key={record._id}
<RowForm
record={record}
isEditing={isEditing}
onRegister={registerForm}
> >
<Flex align={'center'} vertical gap={'middle'}> <div style={{ width: '100%', overflow: 'hidden' }}>
<ObjectCard <RowForm
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
record={record} record={record}
isEditing={isEditing} isEditing={isEditing}
rowActions={rowActions} onRegister={registerForm}
renderActions={renderActions} >
/> <Flex align={'center'} vertical gap={'middle'}>
</Flex> <ObjectCard
</RowForm> model={model}
</div> modelProperties={modelProperties}
</Col> visibleColumns={visibleColumns}
) record={record}
})} isEditing={isEditing}
</Row> rowActions={rowActions}
renderActions={renderActions}
/>
</Flex>
</RowForm>
</div>
</Col>
)
})}
</Row>
</div>
</ScrollBox>
) )
} }
@ -1143,9 +1145,15 @@ const ObjectTable = forwardRef(
<Splitter className={'farmcontrol-splitter'}> <Splitter className={'farmcontrol-splitter'}>
<Splitter.Panel> <Splitter.Panel>
{cards ? ( {cards ? (
<Spin indicator={<LoadingOutlined />} spinning={loading}> <div className='objectTableCardsContainer'>
{renderCards()} <Spin
</Spin> indicator={<LoadingOutlined />}
spinning={loading}
style={{ height: '100%' }}
>
{renderCards()}
</Spin>
</div>
) : ( ) : (
<Table <Table
ref={tableRef} ref={tableRef}

View File

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