Refactor Dashboard Components to Remove Unused State Management
- Removed unnecessary useState hooks for view state management in multiple dashboard components (Invoices, PaymentPolicies, Payments, TaxRecords, FilamentStocks, OrderItems, PartStocks, ProductStocks, PurchaseOrders, Shipments, StockAudits, StockEvents, StockLocations, StockTransfers, AppPasswords, AuditLogs, Couriers, CourierServices, DocumentJobs, DocumentPrinters, DocumentSizes, DocumentTemplates, Filaments, FilamentSkus). - Updated ObjectListViewProvider integration to streamline component functionality and improve maintainability. - Adjusted CSS variables in App.css for enhanced styling consistency across components.
This commit is contained in:
parent
444e694593
commit
9d1a032e10
@ -47,6 +47,12 @@
|
||||
font-family: 'DM Sans';
|
||||
}
|
||||
|
||||
:root {
|
||||
--color-list-view-tabs-border: #8282822e;
|
||||
--color-button-border: #8282822e;
|
||||
--color-button-background: #8282822e;
|
||||
}
|
||||
|
||||
.ant-dropdown {
|
||||
z-index: 999;
|
||||
}
|
||||
@ -2754,7 +2760,7 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
||||
}
|
||||
|
||||
.list-view-tabs-options-dropdown-privacy {
|
||||
margin: 3px 12px 8px;
|
||||
margin: 3px 12px 14px 16px;
|
||||
}
|
||||
|
||||
.segmented-nav-drag-handle {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Invoices = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('invoices')
|
||||
|
||||
@ -36,13 +31,11 @@ const Invoices = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='invoice'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='invoice'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const Invoices = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const Invoices = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const PaymentPolicies = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('paymentPolicy')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -31,12 +27,11 @@ const PaymentPolicies = () => {
|
||||
useSortSidebarVisibility('PaymentPolicies')
|
||||
|
||||
return (
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='paymentPolicy'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='paymentPolicy'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -69,7 +64,7 @@ const PaymentPolicies = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -86,10 +81,9 @@ const PaymentPolicies = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Payments = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('payments')
|
||||
|
||||
@ -36,13 +31,11 @@ const Payments = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='payment'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='payment'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const Payments = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const Payments = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const TaxRecords = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('taxRecord')
|
||||
|
||||
@ -36,13 +31,11 @@ const TaxRecords = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='taxRecord'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='taxRecord'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const TaxRecords = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const TaxRecords = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/filamentStocks.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -21,12 +21,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const FilamentStocks = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('filamentStocks')
|
||||
|
||||
@ -41,13 +35,11 @@ const FilamentStocks = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentStock'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentStock'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -80,8 +72,6 @@ const FilamentStocks = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -98,11 +88,10 @@ const FilamentStocks = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const OrderItems = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('orderItems')
|
||||
|
||||
@ -36,13 +31,11 @@ const OrderItems = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='orderItem'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='orderItem'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const OrderItems = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const OrderItems = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/partStocks.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -21,12 +21,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const PartStocks = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('partStocks')
|
||||
|
||||
@ -41,13 +35,11 @@ const PartStocks = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='partStock'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='partStock'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -80,8 +72,6 @@ const PartStocks = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -98,11 +88,10 @@ const PartStocks = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// src/components/Dashboard/Inventory/ProductStocks.jsx
|
||||
// ProductStocks - tracks assembled products consisting of part stocks
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -22,12 +22,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const ProductStocks = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('productStocks')
|
||||
|
||||
@ -42,13 +36,11 @@ const ProductStocks = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='productStock'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='productStock'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -81,8 +73,6 @@ const ProductStocks = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -99,11 +89,10 @@ const ProductStocks = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const PurchaseOrders = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('purchaseOrders')
|
||||
|
||||
@ -36,13 +31,11 @@ const PurchaseOrders = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='purchaseOrder'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='purchaseOrder'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const PurchaseOrders = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const PurchaseOrders = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Shipments = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('shipments')
|
||||
|
||||
@ -36,13 +31,11 @@ const Shipments = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='shipment'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='shipment'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const Shipments = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const Shipments = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/stockAudits.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -21,12 +21,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const StockAudits = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('stockAudits')
|
||||
|
||||
@ -41,13 +35,11 @@ const StockAudits = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockAudit'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockAudit'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -80,8 +72,6 @@ const StockAudits = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -98,11 +88,10 @@ const StockAudits = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const StockEvents = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('stockEvents')
|
||||
|
||||
@ -35,13 +31,11 @@ const StockEvents = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockEvent'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockEvent'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,8 +68,6 @@ const StockEvents = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +84,10 @@ const StockEvents = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -19,12 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const StockLocations = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('stockLocations')
|
||||
|
||||
@ -39,13 +33,11 @@ const StockLocations = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockLocation'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockLocation'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -78,8 +70,6 @@ const StockLocations = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -96,11 +86,10 @@ const StockLocations = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -19,12 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const StockTransfers = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('stockTransfers')
|
||||
|
||||
@ -39,13 +33,11 @@ const StockTransfers = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockTransfer'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockTransfer'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -78,8 +70,6 @@ const StockTransfers = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -96,11 +86,10 @@ const StockTransfers = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||
import ColumnViewButton from '../common/ColumnViewButton'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const AppPasswords = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('appPassword')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -35,13 +30,11 @@ const AppPasswords = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='appPassword'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='appPassword'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -74,8 +67,6 @@ const AppPasswords = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='appPassword'
|
||||
@ -92,12 +83,10 @@ const AppPasswords = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||
@ -16,11 +16,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const AuditLogs = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [columnVisibility, updateColumnVisibility] =
|
||||
useColumnVisibility('auditLog')
|
||||
@ -33,13 +28,11 @@ const AuditLogs = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='auditLog'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='auditLog'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -68,8 +61,6 @@ const AuditLogs = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -85,11 +76,10 @@ const AuditLogs = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const CourierServices = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('courierService')
|
||||
|
||||
@ -36,13 +31,11 @@ const CourierServices = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='courierService'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='courierService'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const CourierServices = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const CourierServices = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Couriers = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('courier')
|
||||
|
||||
@ -35,13 +30,11 @@ const Couriers = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='courier'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='courier'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,7 +67,7 @@ const Couriers = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +84,9 @@ const Couriers = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const DocumentJobs = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('documentJob')
|
||||
|
||||
@ -36,13 +31,11 @@ const DocumentJobs = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentJob'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentJob'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const DocumentJobs = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const DocumentJobs = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const DocumentPrinters = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('documentPrinter')
|
||||
|
||||
@ -35,13 +31,11 @@ const DocumentPrinters = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentPrinter'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentPrinter'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,7 +68,7 @@ const DocumentPrinters = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +85,9 @@ const DocumentPrinters = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const DocumentSizes = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('documentSize')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -34,13 +30,11 @@ const DocumentSizes = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentSize'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentSize'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -73,7 +67,7 @@ const DocumentSizes = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -90,11 +84,9 @@ const DocumentSizes = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const DocumentTemplates = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('documentTemplate')
|
||||
|
||||
@ -36,13 +31,11 @@ const DocumentTemplates = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentTemplate'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='documentTemplate'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const DocumentTemplates = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const DocumentTemplates = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -19,12 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const FilamentSkus = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('filamentSkus')
|
||||
|
||||
@ -39,13 +33,11 @@ const FilamentSkus = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentSku'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentSku'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -78,8 +70,6 @@ const FilamentSkus = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -96,11 +86,10 @@ const FilamentSkus = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/filaments.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
|
||||
@ -21,11 +21,6 @@ import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
||||
|
||||
const Filaments = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
// View mode state (cards/list), persisted in sessionStorage via custom hook
|
||||
const [viewMode, setViewMode] = useViewMode('filament')
|
||||
@ -41,13 +36,11 @@ const Filaments = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='filament'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='filament'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -80,8 +73,6 @@ const Filaments = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='filament'
|
||||
@ -98,12 +89,10 @@ const Filaments = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Files = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('file')
|
||||
|
||||
@ -33,17 +28,11 @@ const Files = () => {
|
||||
const [showSortSidebar, setShowSortSidebar] =
|
||||
useSortSidebarVisibility('Files')
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ObjectListViewProvider objectType='file' tableRef={tableRef}>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='file'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
type='file'
|
||||
pageName='list'
|
||||
@ -57,8 +46,8 @@ const Files = () => {
|
||||
/>
|
||||
<ExportListButton objectType='file' />
|
||||
</Space>
|
||||
<ListViewTabs />
|
||||
<Space>
|
||||
<ListViewTabs />
|
||||
<Space>
|
||||
<SortSidebarButton
|
||||
active={showSortSidebar}
|
||||
onClick={() => setShowSortSidebar(!showSortSidebar)}
|
||||
@ -73,8 +62,7 @@ const Files = () => {
|
||||
/>
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
</Flex>
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +79,9 @@ const Files = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/hosts.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
|
||||
@ -21,11 +21,6 @@ import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
||||
|
||||
const Hosts = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
// View mode state (cards/list), persisted in sessionStorage via custom hook
|
||||
const [viewMode, setViewMode] = useViewMode('host')
|
||||
@ -40,13 +35,11 @@ const Hosts = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='host'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='host'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -79,8 +72,6 @@ const Hosts = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='host'
|
||||
@ -97,12 +88,10 @@ const Hosts = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
|
||||
@ -19,11 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Materials = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('material')
|
||||
|
||||
@ -38,13 +33,11 @@ const Materials = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='material'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='material'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -77,8 +70,6 @@ const Materials = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='material'
|
||||
@ -95,12 +86,10 @@ const Materials = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const NoteTypes = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('noteType')
|
||||
|
||||
@ -36,13 +31,11 @@ const NoteTypes = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='noteType'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='noteType'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const NoteTypes = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const NoteTypes = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -19,12 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const PartSkus = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('partSkus')
|
||||
|
||||
@ -38,13 +32,11 @@ const PartSkus = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='partSku'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='partSku'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -77,8 +69,6 @@ const PartSkus = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -95,11 +85,10 @@ const PartSkus = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/gcodefiles.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
@ -24,10 +24,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Parts = (filter) => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('part')
|
||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('part')
|
||||
@ -40,13 +36,11 @@ const Parts = (filter) => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='part'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='part'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -79,7 +73,7 @@ const Parts = (filter) => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -97,11 +91,9 @@ const Parts = (filter) => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const PermissionSettingsList = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('permissionSetting')
|
||||
|
||||
@ -36,13 +31,11 @@ const PermissionSettingsList = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='permissionSetting'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='permissionSetting'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const PermissionSettingsList = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const PermissionSettingsList = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
|
||||
@ -19,11 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const ProductCategories = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('productCategory')
|
||||
|
||||
@ -38,13 +33,11 @@ const ProductCategories = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='productCategory'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='productCategory'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -77,8 +70,6 @@ const ProductCategories = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='productCategory'
|
||||
@ -95,12 +86,10 @@ const ProductCategories = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
import { Flex, Space } from 'antd'
|
||||
|
||||
@ -19,12 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const ProductSkus = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('productSkus')
|
||||
|
||||
@ -39,13 +33,11 @@ const ProductSkus = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='productSku'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='productSku'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -78,8 +70,6 @@ const ProductSkus = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -96,11 +86,10 @@ const ProductSkus = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/gcodefiles.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import {
|
||||
Button,
|
||||
@ -36,11 +36,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
const Products = () => {
|
||||
const navigate = useNavigate()
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('Products')
|
||||
|
||||
@ -310,13 +305,11 @@ const Products = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='product'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='product'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -350,7 +343,7 @@ const Products = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type={'product'}
|
||||
@ -366,11 +359,9 @@ const Products = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const StockAuditLevels = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('stockAuditLevel')
|
||||
|
||||
@ -35,12 +30,11 @@ const StockAuditLevels = () => {
|
||||
useSortSidebarVisibility('StockAuditLevels')
|
||||
|
||||
return (
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockAuditLevel'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='stockAuditLevel'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -73,7 +67,7 @@ const StockAuditLevels = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -90,10 +84,9 @@ const StockAuditLevels = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const TaxRates = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('taxRate')
|
||||
|
||||
@ -35,13 +30,11 @@ const TaxRates = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='taxRate'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='taxRate'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,7 +67,7 @@ const TaxRates = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +84,9 @@ const TaxRates = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const UserGroups = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('userGroup')
|
||||
|
||||
@ -35,13 +30,11 @@ const UserGroups = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='userGroup'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='userGroup'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,7 +67,7 @@ const UserGroups = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +84,9 @@ const UserGroups = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Users = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('user')
|
||||
|
||||
@ -35,12 +30,11 @@ const Users = () => {
|
||||
|
||||
|
||||
return (
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='user'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='user'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -73,7 +67,7 @@ const Users = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type={'user'}
|
||||
@ -90,10 +84,9 @@ const Users = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Vendors = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('vendor')
|
||||
|
||||
@ -33,46 +29,40 @@ const Vendors = () => {
|
||||
useSortSidebarVisibility('Vendors')
|
||||
|
||||
return (
|
||||
<>
|
||||
<ObjectListViewProvider objectType='vendor' tableRef={tableRef}>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='vendor'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
type='vendor'
|
||||
pageName='list'
|
||||
onReload={() => tableRef.current?.reload()}
|
||||
/>
|
||||
<ColumnViewButton
|
||||
type='vendor'
|
||||
loading={false}
|
||||
visibleState={columnVisibility}
|
||||
updateVisibleState={setColumnVisibility}
|
||||
/>
|
||||
<ExportListButton objectType='vendor' />
|
||||
</Space>
|
||||
<ListViewTabs />
|
||||
<Space>
|
||||
<SortSidebarButton
|
||||
active={showSortSidebar}
|
||||
onClick={() => setShowSortSidebar(!showSortSidebar)}
|
||||
/>
|
||||
<FilterSidebarButton
|
||||
active={showFilterSidebar}
|
||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
||||
/>
|
||||
<ObjectTableViewButton
|
||||
viewMode={viewMode}
|
||||
setViewMode={setViewMode}
|
||||
/>
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
type='vendor'
|
||||
pageName='list'
|
||||
onReload={() => tableRef.current?.reload()}
|
||||
/>
|
||||
<ColumnViewButton
|
||||
type='vendor'
|
||||
loading={false}
|
||||
visibleState={columnVisibility}
|
||||
updateVisibleState={setColumnVisibility}
|
||||
/>
|
||||
<ExportListButton objectType='vendor' />
|
||||
</Space>
|
||||
<ListViewTabs />
|
||||
<Space>
|
||||
<SortSidebarButton
|
||||
active={showSortSidebar}
|
||||
onClick={() => setShowSortSidebar(!showSortSidebar)}
|
||||
/>
|
||||
<FilterSidebarButton
|
||||
active={showFilterSidebar}
|
||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
||||
/>
|
||||
<ObjectTableViewButton
|
||||
viewMode={viewMode}
|
||||
setViewMode={setViewMode}
|
||||
/>
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -89,11 +79,9 @@ const Vendors = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ColumnViewButton from '../common/ColumnViewButton'
|
||||
import ExportListButton from '../common/ExportListButton'
|
||||
@ -17,10 +17,6 @@ import useViewMode from '../hooks/useViewMode'
|
||||
|
||||
const FilamentProfiles = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('FilamentProfiles')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -33,13 +29,11 @@ const FilamentProfiles = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentProfile'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='filamentProfile'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -71,8 +65,6 @@ const FilamentProfiles = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='filamentProfile'
|
||||
@ -89,11 +81,10 @@ const FilamentProfiles = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/gcodefiles.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
@ -20,10 +20,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const GCodeFiles = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('gcodeFile')
|
||||
|
||||
@ -38,13 +34,11 @@ const GCodeFiles = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='gcodeFile'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='gcodeFile'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -77,7 +71,7 @@ const GCodeFiles = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='gcodeFile'
|
||||
@ -94,11 +88,9 @@ const GCodeFiles = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/Jobs.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
|
||||
import ObjectTable from '../common/ObjectTable.jsx'
|
||||
@ -19,10 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Jobs = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('job')
|
||||
|
||||
@ -36,13 +32,11 @@ const Jobs = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='job'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='job'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,8 +69,6 @@ const Jobs = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type={'job'}
|
||||
@ -93,11 +85,10 @@ const Jobs = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ColumnViewButton from '../common/ColumnViewButton'
|
||||
import ExportListButton from '../common/ExportListButton'
|
||||
@ -16,10 +16,6 @@ import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
||||
import useViewMode from '../hooks/useViewMode'
|
||||
const PrinterProfiles = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('PrinterProfiles')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -32,13 +28,11 @@ const PrinterProfiles = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='printerProfile'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='printerProfile'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -70,8 +64,6 @@ const PrinterProfiles = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='printerProfile'
|
||||
@ -88,11 +80,10 @@ const PrinterProfiles = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/Printers.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Space, Flex } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -20,11 +20,6 @@ import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
||||
|
||||
const Printers = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
// View mode state (cards/list), persisted in sessionStorage via custom hook
|
||||
const [viewMode, setViewMode] = useViewMode('Printers')
|
||||
@ -41,13 +36,11 @@ const Printers = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='printer'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='printer'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space>
|
||||
<ObjectActions
|
||||
@ -80,8 +73,6 @@ const Printers = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type='printer'
|
||||
@ -98,12 +89,10 @@ const Printers = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
</>
|
||||
/>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// src/SubJobs.js
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
|
||||
import ObjectTable from '../common/ObjectTable.jsx'
|
||||
@ -19,10 +19,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const SubJobs = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('subJob')
|
||||
|
||||
@ -36,13 +32,11 @@ const SubJobs = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='subJob'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='subJob'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,8 +69,6 @@ const SubJobs = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
type={'subJob'}
|
||||
@ -93,11 +85,10 @@ const SubJobs = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Clients = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('client')
|
||||
|
||||
@ -35,13 +30,11 @@ const Clients = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='client'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='client'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -74,7 +67,7 @@ const Clients = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -91,11 +84,9 @@ const Clients = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const FulfillmentPolicies = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('fulfillmentPolicy')
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
@ -31,12 +27,11 @@ const FulfillmentPolicies = () => {
|
||||
useSortSidebarVisibility('FulfillmentPolicies')
|
||||
|
||||
return (
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='fulfillmentPolicy'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='fulfillmentPolicy'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -69,7 +64,7 @@ const FulfillmentPolicies = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -86,10 +81,9 @@ const FulfillmentPolicies = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const ListingVarients = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('listingVarients')
|
||||
|
||||
@ -36,13 +31,11 @@ const ListingVarients = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='listingVarient'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='listingVarient'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const ListingVarients = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const ListingVarients = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Listings = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('listings')
|
||||
|
||||
@ -36,13 +31,11 @@ const Listings = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='listing'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='listing'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const Listings = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const Listings = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const Marketplaces = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('marketplaces')
|
||||
|
||||
@ -36,13 +31,11 @@ const Marketplaces = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='marketplace'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='marketplace'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const Marketplaces = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const Marketplaces = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,10 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const ReturnPolicies = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('returnPolicy')
|
||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('returnPolicy')
|
||||
@ -30,12 +26,11 @@ const ReturnPolicies = () => {
|
||||
useSortSidebarVisibility('ReturnPolicies')
|
||||
|
||||
return (
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='returnPolicy'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='returnPolicy'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -68,7 +63,7 @@ const ReturnPolicies = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -85,10 +80,9 @@ const ReturnPolicies = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Flex, Space } from 'antd'
|
||||
import ObjectTable from '../common/ObjectTable'
|
||||
import ObjectActions from '../common/ObjectActions'
|
||||
@ -17,11 +17,6 @@ import { ObjectListViewProvider } from '../context/ObjectListViewContext'
|
||||
|
||||
const SalesOrders = () => {
|
||||
const tableRef = useRef()
|
||||
const [viewState, setViewState] = useState({
|
||||
activeView: null,
|
||||
handleFilterSortChange: null
|
||||
})
|
||||
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('salesOrders')
|
||||
|
||||
@ -36,13 +31,11 @@ const SalesOrders = () => {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<ObjectListViewProvider
|
||||
objectType='salesOrder'
|
||||
tableRef={tableRef}
|
||||
onViewStateChange={setViewState}
|
||||
>
|
||||
<ObjectListViewProvider
|
||||
objectType='salesOrder'
|
||||
tableRef={tableRef}
|
||||
>
|
||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
|
||||
<Space size='small'>
|
||||
<ObjectActions
|
||||
@ -75,7 +68,7 @@ const SalesOrders = () => {
|
||||
<ListViewEditButtons showStartingDivider={true} />
|
||||
</Space>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
|
||||
<ObjectTable
|
||||
ref={tableRef}
|
||||
visibleColumns={columnVisibility}
|
||||
@ -92,11 +85,9 @@ const SalesOrders = () => {
|
||||
saveSortInUrl={true}
|
||||
useSortInSession={true}
|
||||
useSortInUrl={true}
|
||||
activeObjectView={viewState.activeView}
|
||||
onObjectViewFilterSortChange={viewState.handleFilterSortChange}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
</Flex>
|
||||
</ObjectListViewProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React, { useMemo } from 'react'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import {
|
||||
Input,
|
||||
Dropdown,
|
||||
@ -46,7 +46,8 @@ const ViewOptionsDropdown = ({ view, isEditing, onChange, onDelete }) => {
|
||||
domEvent.stopPropagation()
|
||||
onDelete?.()
|
||||
}
|
||||
}
|
||||
},
|
||||
{ type: 'divider' }
|
||||
]
|
||||
}
|
||||
|
||||
@ -203,6 +204,18 @@ const ListViewTabs = () => {
|
||||
viewTabSignatures
|
||||
} = useObjectListView()
|
||||
|
||||
const [animated, setAnimated] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (initialLoading) {
|
||||
setAnimated(false)
|
||||
return undefined
|
||||
}
|
||||
|
||||
const timeoutId = setTimeout(() => setAnimated(true), 10)
|
||||
return () => clearTimeout(timeoutId)
|
||||
}, [initialLoading])
|
||||
|
||||
const model = getModelByName(objectType)
|
||||
|
||||
const options = useMemo(() => {
|
||||
@ -286,6 +299,7 @@ const ListViewTabs = () => {
|
||||
options={options}
|
||||
onChange={selectTab}
|
||||
onReorder={isEditing ? reorderDraftViews : undefined}
|
||||
animated={animated}
|
||||
/>
|
||||
{isEditing && (
|
||||
<Button
|
||||
|
||||
@ -52,11 +52,13 @@ import QuickPropertyFilters from './QuickPropertyFilters'
|
||||
import FilterInput from './FilterInput'
|
||||
import {
|
||||
getActiveFilterValues,
|
||||
useTableState,
|
||||
useTableStatePersistence
|
||||
} from '../context/TableStateContext'
|
||||
import { hasActionPermission } from '../../../database/permissions'
|
||||
import Tooltip from './Tooltip'
|
||||
import { ObjectTableFilterContext } from './ObjectTableFilterContext'
|
||||
import ObjectListViewContext from '../context/ObjectListViewContext'
|
||||
|
||||
const logger = loglevel.getLogger('DasboardTable')
|
||||
logger.setLevel(config.logLevel)
|
||||
@ -91,6 +93,37 @@ const fromFilterExpression = (expr) => {
|
||||
return [expr]
|
||||
}
|
||||
|
||||
const areValuesEqual = (v1, v2) => {
|
||||
const id1 = v1 && typeof v1 === 'object' && v1._id ? v1._id : v1
|
||||
const id2 = v2 && typeof v2 === 'object' && v2._id ? v2._id : v2
|
||||
return String(id1) === String(id2)
|
||||
}
|
||||
|
||||
const getChangedKeys = (existing, updated) => {
|
||||
if (!updated || typeof updated !== 'object') return []
|
||||
return Object.keys(updated).filter((key) => {
|
||||
if (key === '_id' || key === 'objectType') return false
|
||||
if (!existing) return true
|
||||
return !areValuesEqual(existing[key], updated[key])
|
||||
})
|
||||
}
|
||||
|
||||
const updateAffectsFilterOrSort = (
|
||||
changedKeys,
|
||||
filter,
|
||||
masterFilter,
|
||||
sorter
|
||||
) => {
|
||||
if (!changedKeys.length) return false
|
||||
const filterKeys = new Set([
|
||||
...Object.keys(filter || {}),
|
||||
...Object.keys(masterFilter || {})
|
||||
])
|
||||
if (changedKeys.some((key) => filterKeys.has(key))) return true
|
||||
if (sorter?.field && changedKeys.includes(sorter.field)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
const ColumnFilterDropdown = ({
|
||||
setSelectedKeys,
|
||||
selectedKeys,
|
||||
@ -255,8 +288,6 @@ const ObjectTable = forwardRef(
|
||||
saveSortInUrl = false,
|
||||
useSortInSession = false,
|
||||
useSortInUrl = false,
|
||||
activeObjectView = null,
|
||||
onObjectViewFilterSortChange,
|
||||
onRowAction
|
||||
},
|
||||
ref
|
||||
@ -264,6 +295,14 @@ const ObjectTable = forwardRef(
|
||||
const { token, userProfile } = useContext(AuthContext)
|
||||
const { isElectron } = useContext(ElectronContext)
|
||||
const { callAction } = useActions()
|
||||
const objectListView = useContext(ObjectListViewContext)
|
||||
const listViewId = objectListView?.listViewId ?? null
|
||||
const listViewFilter = objectListView?.listViewFilter ?? null
|
||||
const listViewSort = objectListView?.listViewSort ?? null
|
||||
const activeObjectView = objectListView?.activeObjectView ?? null
|
||||
const onObjectViewFilterSortChange = objectListView?.isEditing
|
||||
? objectListView.handleFilterSortChange
|
||||
: null
|
||||
const onStateChangeRef = useRef(onStateChange)
|
||||
useEffect(() => {
|
||||
onStateChangeRef.current = onStateChange
|
||||
@ -271,7 +310,7 @@ const ObjectTable = forwardRef(
|
||||
const {
|
||||
fetchObjects,
|
||||
connected,
|
||||
subscribeToObjectUpdates,
|
||||
subscribeToAllObjectUpdates,
|
||||
subscribeToObjectTypeUpdates,
|
||||
updateMultipleObjects,
|
||||
setObjectActivity,
|
||||
@ -282,13 +321,19 @@ const ObjectTable = forwardRef(
|
||||
const {
|
||||
getPersistedFilter,
|
||||
getPersistedSorter,
|
||||
getAllTabPersistedFilter,
|
||||
getAllTabPersistedSorter,
|
||||
persistFilter,
|
||||
persistSort,
|
||||
persistTableState,
|
||||
persistAllTabTableState,
|
||||
registerPageFilter,
|
||||
registerPageSorter
|
||||
registerPageSorter,
|
||||
registerObjectListFilter,
|
||||
registerObjectListSorter
|
||||
} = useTableStatePersistence({
|
||||
scope: type,
|
||||
viewId: listViewId,
|
||||
pagePath: location.pathname,
|
||||
saveFilterInSession,
|
||||
saveFilterInUrl,
|
||||
@ -299,6 +344,7 @@ const ObjectTable = forwardRef(
|
||||
useSortInSession,
|
||||
useSortInUrl
|
||||
})
|
||||
const { getViewFromUrl } = useTableState()
|
||||
var adjustedScrollHeight = scrollHeight
|
||||
if (isMobile) {
|
||||
adjustedScrollHeight = 'calc(var(--unit-100vh) - 298px)'
|
||||
@ -319,6 +365,8 @@ const ObjectTable = forwardRef(
|
||||
const model = getModelByName(type)
|
||||
const activeFilterRef = useRef({})
|
||||
const tableSorterRef = useRef({})
|
||||
const listViewIdRef = useRef(listViewId)
|
||||
const listViewFilterRef = useRef(listViewFilter)
|
||||
const activeObjectViewRef = useRef(activeObjectView)
|
||||
activeObjectViewRef.current = activeObjectView
|
||||
const onObjectViewFilterSortChangeRef = useRef(onObjectViewFilterSortChange)
|
||||
@ -327,6 +375,25 @@ const ObjectTable = forwardRef(
|
||||
const [tableSorter, setTableSorter] = useState({})
|
||||
const [initialized, setInitialized] = useState(false)
|
||||
|
||||
// Keep refs in sync with props. applyViewState may update them earlier in
|
||||
// the same tick; props remain the source of truth after commit.
|
||||
useEffect(() => {
|
||||
listViewIdRef.current = listViewId
|
||||
listViewFilterRef.current = listViewFilter || {}
|
||||
}, [listViewId, listViewFilter])
|
||||
|
||||
const lastAppliedViewKeyRef = useRef(null)
|
||||
|
||||
const buildEffectiveFilter = useCallback((userFilter, viewFilter = listViewFilterRef.current) => {
|
||||
const active = getActiveFilterValues(userFilter)
|
||||
const viewId = listViewIdRef.current
|
||||
if (!viewId) return active
|
||||
return {
|
||||
...getActiveFilterValues(viewFilter || {}),
|
||||
...active
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Table state
|
||||
const [pages, setPages] = useState([])
|
||||
const pagesRef = useRef(pages)
|
||||
@ -362,14 +429,15 @@ const ObjectTable = forwardRef(
|
||||
onStateChangeRef.current?.({ isEditing, editLoading })
|
||||
}, [isEditing, editLoading])
|
||||
|
||||
const subscribedIdsRef = useRef([])
|
||||
// const [typeSubscribed, setTypeSubscribed] = useState(false)
|
||||
const unsubscribesRef = useRef([])
|
||||
const updateEventHandlerRef = useRef()
|
||||
const subscribeToObjectTypeUpdatesRef = useRef(null)
|
||||
const subscribedTypeRef = useRef(null)
|
||||
const subscribeToAllObjectUpdatesRef = useRef(null)
|
||||
const newEventHandlerRef = useRef()
|
||||
const subscriptionFilterRef = useRef()
|
||||
const effectiveSorterRef = useRef({})
|
||||
const reloadRef = useRef(null)
|
||||
const silentReloadRef = useRef(null)
|
||||
const subscribeToObjectTypeUpdatesFnRef = useRef(
|
||||
subscribeToObjectTypeUpdates
|
||||
)
|
||||
@ -412,16 +480,36 @@ const ObjectTable = forwardRef(
|
||||
const pendingScrollAnchorRef = useRef(null)
|
||||
const dataLoadGenerationRef = useRef(0)
|
||||
const [tableListKey, setTableListKey] = useState(0)
|
||||
const isInternalSortUpdateRef = useRef(false)
|
||||
// Suppress Ant Design Table onChange while we remount / set filter+sort
|
||||
// programmatically. Remounting with controlled filteredValue often fires
|
||||
// onChange with all-null filters (sorter intact) and would wipe the view.
|
||||
const isInternalTableChangeRef = useRef(false)
|
||||
const internalTableChangeClearRafRef = useRef(null)
|
||||
|
||||
const suppressTableChange = useCallback(() => {
|
||||
isInternalTableChangeRef.current = true
|
||||
if (internalTableChangeClearRafRef.current != null) {
|
||||
cancelAnimationFrame(internalTableChangeClearRafRef.current)
|
||||
}
|
||||
// Double rAF: wait until after the remounted Table commits and any
|
||||
// synchronous/mount onChange from Ant Design has run.
|
||||
internalTableChangeClearRafRef.current = requestAnimationFrame(() => {
|
||||
internalTableChangeClearRafRef.current = requestAnimationFrame(() => {
|
||||
internalTableChangeClearRafRef.current = null
|
||||
isInternalTableChangeRef.current = false
|
||||
})
|
||||
})
|
||||
}, [])
|
||||
|
||||
const beginDataReload = useCallback(() => {
|
||||
dataLoadGenerationRef.current += 1
|
||||
loadingPagesRef.current.clear()
|
||||
pendingScrollAnchorRef.current = null
|
||||
pagesRef.current = []
|
||||
suppressTableChange()
|
||||
setTableListKey((key) => key + 1)
|
||||
return dataLoadGenerationRef.current
|
||||
}, [])
|
||||
}, [suppressTableChange])
|
||||
|
||||
const isStaleDataLoad = useCallback((generation) => {
|
||||
return generation !== dataLoadGenerationRef.current
|
||||
@ -799,19 +887,35 @@ const ObjectTable = forwardRef(
|
||||
[loadNextPage, loadPreviousPage, skeletonsHeight]
|
||||
)
|
||||
|
||||
const reload = useCallback(async () => {
|
||||
setLazyLoading(true)
|
||||
try {
|
||||
const loadedPages = pagesRef.current.filter(
|
||||
(page) => !page.isSkeletonPage
|
||||
)
|
||||
for (let i = 0; i < loadedPages.length; i++) {
|
||||
await fetchData(loadedPages[i].pageNum)
|
||||
const reloadLoadedPages = useCallback(
|
||||
async ({ silent = false } = {}) => {
|
||||
if (!silent) {
|
||||
setLazyLoading(true)
|
||||
}
|
||||
} finally {
|
||||
setLazyLoading(false)
|
||||
}
|
||||
}, [fetchData])
|
||||
try {
|
||||
const loadedPages = pagesRef.current.filter(
|
||||
(page) => !page.isSkeletonPage
|
||||
)
|
||||
for (let i = 0; i < loadedPages.length; i++) {
|
||||
await fetchData(loadedPages[i].pageNum)
|
||||
}
|
||||
} finally {
|
||||
if (!silent) {
|
||||
setLazyLoading(false)
|
||||
}
|
||||
}
|
||||
},
|
||||
[fetchData]
|
||||
)
|
||||
|
||||
const reload = useCallback(() => reloadLoadedPages(), [reloadLoadedPages])
|
||||
const silentReload = useCallback(
|
||||
() => reloadLoadedPages({ silent: true }),
|
||||
[reloadLoadedPages]
|
||||
)
|
||||
|
||||
reloadRef.current = reload
|
||||
silentReloadRef.current = silentReload
|
||||
|
||||
const startEditing = useCallback(() => {
|
||||
setIsEditing(true)
|
||||
@ -855,138 +959,139 @@ const ObjectTable = forwardRef(
|
||||
}
|
||||
}, [type, updateMultipleObjects, reload, tableData, clearObjectActivity])
|
||||
|
||||
// Update event handler for real-time updates
|
||||
const updateEventHandler = useCallback((id, updatedData) => {
|
||||
setPages((prevPages) =>
|
||||
prevPages.map((page) => {
|
||||
const updatedItems = page.items.map((item) => {
|
||||
if (item._id === id) {
|
||||
return { ...item, ...updatedData }
|
||||
}
|
||||
return item
|
||||
})
|
||||
return {
|
||||
...page,
|
||||
items: updatedItems
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
if (rowFormsRef.current[id]) {
|
||||
rowFormsRef.current[id].setFieldsValue(updatedData)
|
||||
const findTableItem = useCallback((id) => {
|
||||
for (const page of pagesRef.current) {
|
||||
const item = page.items?.find(
|
||||
(entry) => String(entry._id) === String(id) && !entry.isSkeleton
|
||||
)
|
||||
if (item) return item
|
||||
}
|
||||
return null
|
||||
}, [])
|
||||
|
||||
// Update event handler for real-time updates
|
||||
const updateEventHandler = useCallback(
|
||||
(id, updatedData) => {
|
||||
const existingItem = findTableItem(id)
|
||||
const changedKeys = getChangedKeys(existingItem, updatedData)
|
||||
|
||||
if (
|
||||
updateAffectsFilterOrSort(
|
||||
changedKeys,
|
||||
subscriptionFilterRef.current,
|
||||
{},
|
||||
effectiveSorterRef.current
|
||||
)
|
||||
) {
|
||||
silentReloadRef.current?.()
|
||||
return
|
||||
}
|
||||
|
||||
if (!existingItem) return
|
||||
|
||||
setPages((prevPages) =>
|
||||
prevPages.map((page) => {
|
||||
const updatedItems = page.items.map((item) => {
|
||||
if (String(item._id) === String(id)) {
|
||||
return { ...item, ...updatedData }
|
||||
}
|
||||
return item
|
||||
})
|
||||
return {
|
||||
...page,
|
||||
items: updatedItems
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
if (rowFormsRef.current[id]) {
|
||||
rowFormsRef.current[id].setFieldsValue(updatedData)
|
||||
}
|
||||
},
|
||||
[findTableItem]
|
||||
)
|
||||
|
||||
// Store the latest updateEventHandler in a ref
|
||||
updateEventHandlerRef.current = updateEventHandler
|
||||
|
||||
const newEventHandler = useCallback(
|
||||
(params) => {
|
||||
logger.debug('New event handler:', params)
|
||||
reload()
|
||||
},
|
||||
[reload]
|
||||
)
|
||||
const newEventHandler = useCallback((params) => {
|
||||
logger.debug('New event handler:', params)
|
||||
silentReloadRef.current?.()
|
||||
}, [])
|
||||
|
||||
const subscriptionFilter = useMemo(() => {
|
||||
const active = {}
|
||||
Object.entries(sidebarFilter).forEach(([k, v]) => {
|
||||
if (v !== '' && v !== undefined) active[k] = v
|
||||
})
|
||||
return { ...masterFilter, ...active }
|
||||
}, [sidebarFilter, masterFilter])
|
||||
// Effective filter for ObjectTableFilterContext, breadcrumb, and neighbors:
|
||||
// view definition + any user-entered sidebar filters.
|
||||
const effectiveFilter = useMemo(() => {
|
||||
const userFilter = getActiveFilterValues(sidebarFilter)
|
||||
if (!listViewId) return userFilter
|
||||
return {
|
||||
...getActiveFilterValues(listViewFilter || {}),
|
||||
...userFilter
|
||||
}
|
||||
}, [listViewId, listViewFilter, sidebarFilter])
|
||||
|
||||
const effectiveSorter = useMemo(() => {
|
||||
if (tableSorter?.field && tableSorter?.order) {
|
||||
return { field: tableSorter.field, order: tableSorter.order }
|
||||
}
|
||||
if (listViewId && listViewSort?.field && listViewSort?.order) {
|
||||
return { field: listViewSort.field, order: listViewSort.order }
|
||||
}
|
||||
return {}
|
||||
}, [listViewId, listViewSort, tableSorter])
|
||||
|
||||
const subscriptionFilter = useMemo(
|
||||
() => ({ ...masterFilter, ...effectiveFilter }),
|
||||
[effectiveFilter, masterFilter]
|
||||
)
|
||||
|
||||
const tableFilterContextValue = useMemo(
|
||||
() => ({
|
||||
filter: getActiveFilterValues(sidebarFilter),
|
||||
filter: effectiveFilter,
|
||||
masterFilter
|
||||
}),
|
||||
[sidebarFilter, masterFilter]
|
||||
[effectiveFilter, masterFilter]
|
||||
)
|
||||
|
||||
newEventHandlerRef.current = newEventHandler
|
||||
subscriptionFilterRef.current = subscriptionFilter
|
||||
effectiveSorterRef.current = effectiveSorter
|
||||
subscribeToObjectTypeUpdatesFnRef.current = subscribeToObjectTypeUpdates
|
||||
|
||||
// Subscribe to real-time updates for all items
|
||||
useEffect(() => {
|
||||
if (pages.length > 0 && connected == true) {
|
||||
// Get all non-skeleton item IDs from all pages
|
||||
const allItemIds = pages
|
||||
.flatMap((page) => page.items || [])
|
||||
.filter((item) => !item.isSkeleton)
|
||||
.map((item) => item._id)
|
||||
.filter(Boolean)
|
||||
|
||||
// Find new items that need subscription
|
||||
const newItemIds = allItemIds.filter(
|
||||
(id) => !subscribedIdsRef.current.includes(id)
|
||||
)
|
||||
|
||||
// Subscribe to new items only
|
||||
newItemIds.forEach((itemId) => {
|
||||
const unsubscribe = subscribeToObjectUpdates(
|
||||
itemId?.toLowerCase(),
|
||||
type,
|
||||
(updateData) => {
|
||||
updateEventHandlerRef.current(itemId, updateData)
|
||||
}
|
||||
)
|
||||
subscribedIdsRef.current.push(itemId)
|
||||
if (unsubscribe) {
|
||||
unsubscribesRef.current.push(unsubscribe)
|
||||
}
|
||||
})
|
||||
|
||||
// Clean up subscriptions for items that are no longer in the pages
|
||||
const currentSubscribedIds = subscribedIdsRef.current
|
||||
const itemsToUnsubscribe = currentSubscribedIds.filter(
|
||||
(id) => !allItemIds.includes(id)
|
||||
)
|
||||
|
||||
itemsToUnsubscribe.forEach((itemId) => {
|
||||
const index = subscribedIdsRef.current.indexOf(itemId)
|
||||
if (index > -1) {
|
||||
subscribedIdsRef.current.splice(index, 1)
|
||||
const unsubscribe = unsubscribesRef.current[index]
|
||||
if (unsubscribe) {
|
||||
unsubscribe()
|
||||
}
|
||||
unsubscribesRef.current.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [pages, type, subscribeToObjectUpdates, connected])
|
||||
|
||||
// Cleanup effect for component unmount
|
||||
// Cleanup subscriptions on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (connected == true && unsubscribesRef.current) {
|
||||
// Clean up all subscriptions when component unmounts
|
||||
unsubscribesRef.current.forEach((unsubscribe) => {
|
||||
if (unsubscribe) unsubscribe()
|
||||
})
|
||||
unsubscribesRef.current = []
|
||||
subscribedIdsRef.current = []
|
||||
|
||||
// Clean up type subscription
|
||||
}
|
||||
if (connected == true && subscribeToObjectTypeUpdatesRef.current) {
|
||||
subscribeToObjectTypeUpdatesRef.current()
|
||||
subscribeToObjectTypeUpdatesRef.current = null
|
||||
}
|
||||
if (connected == true && subscribeToAllObjectUpdatesRef.current) {
|
||||
subscribeToAllObjectUpdatesRef.current()
|
||||
subscribeToAllObjectUpdatesRef.current = null
|
||||
}
|
||||
}
|
||||
}, [connected])
|
||||
|
||||
// Subscribe to all object updates for this type
|
||||
useEffect(() => {
|
||||
if (connected !== true || !type) return
|
||||
|
||||
const unsubscribe = subscribeToAllObjectUpdates(type, (id, updateData) => {
|
||||
updateEventHandlerRef.current(id, updateData)
|
||||
})
|
||||
subscribeToAllObjectUpdatesRef.current = unsubscribe
|
||||
return () => {
|
||||
if (unsubscribe) unsubscribe()
|
||||
if (subscribeToAllObjectUpdatesRef.current === unsubscribe) {
|
||||
subscribeToAllObjectUpdatesRef.current = null
|
||||
}
|
||||
}
|
||||
}, [type, connected, subscribeToAllObjectUpdates])
|
||||
|
||||
useEffect(() => {
|
||||
if (connected !== true) return
|
||||
if (subscribedTypeRef.current === type) return
|
||||
|
||||
console.log(
|
||||
'subscribing to object type updates',
|
||||
type,
|
||||
subscriptionFilterRef.current
|
||||
)
|
||||
const unsubscribe = subscribeToObjectTypeUpdatesFnRef.current(
|
||||
type,
|
||||
subscriptionFilterRef.current,
|
||||
@ -1047,6 +1152,8 @@ const ObjectTable = forwardRef(
|
||||
} finally {
|
||||
if (!isStaleDataLoad(generation)) {
|
||||
setLoading(false)
|
||||
// Data/column swap can also trigger a spurious Table onChange.
|
||||
suppressTableChange()
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1057,11 +1164,18 @@ const ObjectTable = forwardRef(
|
||||
createSkeletonPage,
|
||||
fetchPage,
|
||||
isStaleDataLoad,
|
||||
setTablePages
|
||||
setTablePages,
|
||||
suppressTableChange
|
||||
]
|
||||
)
|
||||
|
||||
const loadInitialPage = useCallback(async () => {
|
||||
// A selected view applies its own filter/sort via applyViewState.
|
||||
// Do not load (or clear) filters here — that races and wipes the view.
|
||||
if (getViewFromUrl() || listViewIdRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
const filter = getPersistedFilter()
|
||||
const sorter = getPersistedSorter()
|
||||
const activeFilter = getActiveFilterValues(filter)
|
||||
@ -1083,22 +1197,85 @@ const ObjectTable = forwardRef(
|
||||
}, [
|
||||
getPersistedFilter,
|
||||
getPersistedSorter,
|
||||
getViewFromUrl,
|
||||
initialPage,
|
||||
loadPage,
|
||||
resolveSorter
|
||||
])
|
||||
|
||||
// When a view becomes available, apply its definition once. Skip empty
|
||||
// prop-lag updates so we never clear an already-applied view filter.
|
||||
useEffect(() => {
|
||||
if (!listViewId || activeObjectView) {
|
||||
if (!listViewId) lastAppliedViewKeyRef.current = null
|
||||
return
|
||||
}
|
||||
|
||||
const viewFilter = getActiveFilterValues(listViewFilter || {})
|
||||
const viewSort =
|
||||
listViewSort?.field && listViewSort?.order
|
||||
? { field: listViewSort.field, order: listViewSort.order }
|
||||
: {}
|
||||
const viewKey = `${listViewId}:${JSON.stringify(viewFilter)}:${JSON.stringify(viewSort)}`
|
||||
|
||||
if (lastAppliedViewKeyRef.current === viewKey) return
|
||||
|
||||
// Prop lag: listViewId is set but filter/sort props are still empty.
|
||||
// Never overwrite a non-empty sidebar/query with {}.
|
||||
const hasViewState =
|
||||
Object.keys(viewFilter).length > 0 || Boolean(viewSort.field)
|
||||
if (!hasViewState) return
|
||||
|
||||
lastAppliedViewKeyRef.current = viewKey
|
||||
|
||||
setSidebarFilter(viewFilter)
|
||||
setTableSorter(viewSort)
|
||||
tableSorterRef.current = viewSort
|
||||
activeFilterRef.current = viewFilter
|
||||
loadPage(
|
||||
initialPage,
|
||||
viewFilter,
|
||||
viewSort.field ? viewSort : null
|
||||
)
|
||||
}, [
|
||||
activeObjectView,
|
||||
initialPage,
|
||||
listViewFilter,
|
||||
listViewId,
|
||||
listViewSort,
|
||||
loadPage
|
||||
])
|
||||
|
||||
const applyViewState = useCallback(
|
||||
(filterState, sorterState) => {
|
||||
(filterState, sorterState, options = {}) => {
|
||||
let filter
|
||||
let sorter
|
||||
|
||||
if (filterState == null && sorterState == null) {
|
||||
const filter = getPersistedFilter()
|
||||
const sorter = getPersistedSorter()
|
||||
const activeFilter = getActiveFilterValues(filter)
|
||||
// Ignore accidental All restores while a view is still selected
|
||||
// (e.g. load race). Explicit All tab switches pass forceAll.
|
||||
if (
|
||||
!options.forceAll &&
|
||||
(listViewIdRef.current || getViewFromUrl())
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
listViewIdRef.current = null
|
||||
listViewFilterRef.current = {}
|
||||
lastAppliedViewKeyRef.current = null
|
||||
filter = getAllTabPersistedFilter()
|
||||
sorter = getAllTabPersistedSorter()
|
||||
|
||||
const resolvedSorter = resolveSorter(sorter)
|
||||
const nextSorter = sorter?.field ? sorter : {}
|
||||
const activeFilter = getActiveFilterValues(filter)
|
||||
|
||||
setSidebarFilter(filter)
|
||||
tableSorterRef.current = sorter?.field ? sorter : {}
|
||||
setTableSorter(sorter?.field ? sorter : {})
|
||||
tableSorterRef.current = nextSorter
|
||||
setTableSorter(nextSorter)
|
||||
activeFilterRef.current = activeFilter
|
||||
persistAllTabTableState(filter, nextSorter)
|
||||
loadPage(
|
||||
initialPage,
|
||||
activeFilter,
|
||||
@ -1107,14 +1284,39 @@ const ObjectTable = forwardRef(
|
||||
return
|
||||
}
|
||||
|
||||
const filter = filterState || {}
|
||||
const sorter = sorterState?.field ? sorterState : {}
|
||||
const activeFilter = getActiveFilterValues(filter)
|
||||
// View tab: apply the view definition. Sidebar starts as the view
|
||||
// filter so the UI matches; All-tab user settings must not leak in.
|
||||
const viewId =
|
||||
options.viewId !== undefined
|
||||
? options.viewId
|
||||
: listViewIdRef.current
|
||||
const viewFilter =
|
||||
options.viewFilter !== undefined
|
||||
? options.viewFilter || {}
|
||||
: filterState || {}
|
||||
|
||||
listViewIdRef.current = viewId
|
||||
listViewFilterRef.current = viewFilter
|
||||
|
||||
filter = viewFilter
|
||||
sorter =
|
||||
options.viewSort?.field
|
||||
? options.viewSort
|
||||
: sorterState?.field
|
||||
? sorterState
|
||||
: {}
|
||||
|
||||
const resolvedSorter = resolveSorter(sorter)
|
||||
const nextSorter = sorter?.field ? sorter : {}
|
||||
const activeFilter = getActiveFilterValues(filter)
|
||||
|
||||
lastAppliedViewKeyRef.current = `${viewId || ''}:${JSON.stringify(activeFilter)}:${JSON.stringify(nextSorter)}`
|
||||
|
||||
setSidebarFilter(filter)
|
||||
tableSorterRef.current = sorter
|
||||
setTableSorter(sorter)
|
||||
tableSorterRef.current = nextSorter
|
||||
setTableSorter(nextSorter)
|
||||
activeFilterRef.current = activeFilter
|
||||
|
||||
loadPage(
|
||||
initialPage,
|
||||
activeFilter,
|
||||
@ -1122,10 +1324,12 @@ const ObjectTable = forwardRef(
|
||||
)
|
||||
},
|
||||
[
|
||||
getPersistedFilter,
|
||||
getPersistedSorter,
|
||||
getAllTabPersistedFilter,
|
||||
getAllTabPersistedSorter,
|
||||
getViewFromUrl,
|
||||
initialPage,
|
||||
loadPage,
|
||||
persistAllTabTableState,
|
||||
resolveSorter
|
||||
]
|
||||
)
|
||||
@ -1180,14 +1384,16 @@ const ObjectTable = forwardRef(
|
||||
}, [type, masterFilter, beginDataReload])
|
||||
|
||||
useEffect(() => {
|
||||
registerPageFilter(sidebarFilter)
|
||||
registerPageFilter(effectiveFilter)
|
||||
registerObjectListFilter(effectiveFilter)
|
||||
return () => registerPageFilter({})
|
||||
}, [sidebarFilter, registerPageFilter])
|
||||
}, [effectiveFilter, registerPageFilter, registerObjectListFilter])
|
||||
|
||||
useEffect(() => {
|
||||
registerPageSorter(tableSorter)
|
||||
registerPageSorter(effectiveSorter)
|
||||
registerObjectListSorter(effectiveSorter)
|
||||
return () => registerPageSorter({})
|
||||
}, [tableSorter, registerPageSorter])
|
||||
}, [effectiveSorter, registerPageSorter, registerObjectListSorter])
|
||||
|
||||
const getFilterDropdown = ({
|
||||
setSelectedKeys,
|
||||
@ -1207,13 +1413,13 @@ const ObjectTable = forwardRef(
|
||||
propertyName={propertyName}
|
||||
propertyLabel={propertyLabel}
|
||||
modelType={type}
|
||||
filter={sidebarFilter}
|
||||
filter={effectiveFilter}
|
||||
masterFilter={masterFilter}
|
||||
/>
|
||||
)
|
||||
|
||||
const handleTableChange = (pagination, filters, sorter) => {
|
||||
if (isInternalSortUpdateRef.current) return
|
||||
if (isInternalTableChangeRef.current) return
|
||||
|
||||
const next = { ...sidebarFilter }
|
||||
|
||||
@ -1233,29 +1439,42 @@ const ObjectTable = forwardRef(
|
||||
|
||||
setSidebarFilter(next)
|
||||
setTableSorter(nextSorter)
|
||||
const effective = buildEffectiveFilter(next)
|
||||
activeFilterRef.current = effective
|
||||
if (activeObjectViewRef.current) {
|
||||
// Editing a view: keep filter/sort on the draft view only
|
||||
onObjectViewFilterSortChangeRef.current?.(next, nextSorter)
|
||||
} else {
|
||||
} else if (!listViewIdRef.current) {
|
||||
// All tab: persist personal filter/sort to URL/session
|
||||
persistTableState(next, nextSorter)
|
||||
}
|
||||
loadPage(initialPage, getActiveFilterValues(next), resolveSorter(nextSorter))
|
||||
loadPage(initialPage, effective, resolveSorter(nextSorter))
|
||||
}
|
||||
|
||||
const handleSidebarFilterChange = useCallback(
|
||||
(newSidebarFilter) => {
|
||||
setSidebarFilter(newSidebarFilter)
|
||||
const effective = buildEffectiveFilter(newSidebarFilter)
|
||||
activeFilterRef.current = effective
|
||||
if (activeObjectViewRef.current) {
|
||||
onObjectViewFilterSortChangeRef.current?.(newSidebarFilter, tableSorter)
|
||||
} else {
|
||||
} else if (!listViewIdRef.current) {
|
||||
persistFilter(newSidebarFilter)
|
||||
}
|
||||
loadPage(
|
||||
initialPage,
|
||||
getActiveFilterValues(newSidebarFilter),
|
||||
effective,
|
||||
resolveSorter(tableSorter)
|
||||
)
|
||||
},
|
||||
[initialPage, loadPage, persistFilter, resolveSorter, tableSorter]
|
||||
[
|
||||
buildEffectiveFilter,
|
||||
initialPage,
|
||||
loadPage,
|
||||
persistFilter,
|
||||
resolveSorter,
|
||||
tableSorter
|
||||
]
|
||||
)
|
||||
|
||||
const handleSidebarSortChange = useCallback(
|
||||
@ -1263,24 +1482,29 @@ const ObjectTable = forwardRef(
|
||||
const nextSorter = newSorter?.field
|
||||
? { field: newSorter.field, order: newSorter.order }
|
||||
: {}
|
||||
isInternalSortUpdateRef.current = true
|
||||
suppressTableChange()
|
||||
setTableSorter(nextSorter)
|
||||
tableSorterRef.current = nextSorter
|
||||
if (activeObjectViewRef.current) {
|
||||
onObjectViewFilterSortChangeRef.current?.(sidebarFilter, nextSorter)
|
||||
} else {
|
||||
} else if (!listViewIdRef.current) {
|
||||
persistSort(nextSorter)
|
||||
}
|
||||
loadPage(
|
||||
initialPage,
|
||||
getActiveFilterValues(sidebarFilter),
|
||||
buildEffectiveFilter(sidebarFilter),
|
||||
resolveSorter(nextSorter)
|
||||
)
|
||||
requestAnimationFrame(() => {
|
||||
isInternalSortUpdateRef.current = false
|
||||
})
|
||||
},
|
||||
[initialPage, loadPage, persistSort, resolveSorter, sidebarFilter]
|
||||
[
|
||||
buildEffectiveFilter,
|
||||
initialPage,
|
||||
loadPage,
|
||||
persistSort,
|
||||
resolveSorter,
|
||||
sidebarFilter,
|
||||
suppressTableChange
|
||||
]
|
||||
)
|
||||
|
||||
const modelProperties = getModelProperties(type)
|
||||
@ -1420,7 +1644,7 @@ const ObjectTable = forwardRef(
|
||||
propertyLabel: prop.label
|
||||
})
|
||||
columnConfig.filteredValue = fromFilterExpression(
|
||||
sidebarFilter[prop.name]
|
||||
effectiveFilter[prop.name]
|
||||
)
|
||||
}
|
||||
|
||||
@ -1670,7 +1894,7 @@ const ObjectTable = forwardRef(
|
||||
{showSortSidebar && (
|
||||
<SortSidebar
|
||||
type={type}
|
||||
sorter={tableSorter}
|
||||
sorter={effectiveSorter}
|
||||
onSortChange={handleSidebarSortChange}
|
||||
stretchHeight={showSortSidebar && !showFilterSidebar}
|
||||
/>
|
||||
@ -1679,7 +1903,7 @@ const ObjectTable = forwardRef(
|
||||
<Flex style={{ flex: 1, minHeight: 0 }}>
|
||||
<FilterSidebar
|
||||
type={type}
|
||||
filter={sidebarFilter}
|
||||
filter={effectiveFilter}
|
||||
onFilterChange={handleSidebarFilterChange}
|
||||
masterFilter={masterFilter}
|
||||
/>
|
||||
@ -1726,8 +1950,6 @@ ObjectTable.propTypes = {
|
||||
saveSortInUrl: PropTypes.bool,
|
||||
useSortInSession: PropTypes.bool,
|
||||
useSortInUrl: PropTypes.bool,
|
||||
activeObjectView: PropTypes.object,
|
||||
onObjectViewFilterSortChange: PropTypes.func,
|
||||
onRowAction: PropTypes.func
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import { ApiServerContext } from '../context/ApiServerContext'
|
||||
import { AuthContext } from '../context/AuthContext'
|
||||
import {
|
||||
getActiveFilterValues,
|
||||
useTableState,
|
||||
useTableStatePersistence
|
||||
} from '../context/TableStateContext'
|
||||
import KeyboardShortcut from './KeyboardShortcut.jsx'
|
||||
@ -25,6 +26,7 @@ const ObjectTableNavigationButtons = ({
|
||||
const [neighbors, setNeighbors] = useState({ next: null, previous: null })
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const { getObjectListFilter, getObjectListSorter } = useTableState()
|
||||
const { getPersistedFilter, getPersistedSorter } = useTableStatePersistence({
|
||||
scope: objectType,
|
||||
useFilterInSession: true,
|
||||
@ -34,6 +36,12 @@ const ObjectTableNavigationButtons = ({
|
||||
const getObjectNeighborsRef = useRef(getObjectNeighbors)
|
||||
getObjectNeighborsRef.current = getObjectNeighbors
|
||||
|
||||
const getObjectListFilterRef = useRef(getObjectListFilter)
|
||||
getObjectListFilterRef.current = getObjectListFilter
|
||||
|
||||
const getObjectListSorterRef = useRef(getObjectListSorter)
|
||||
getObjectListSorterRef.current = getObjectListSorter
|
||||
|
||||
const getPersistedFilterRef = useRef(getPersistedFilter)
|
||||
getPersistedFilterRef.current = getPersistedFilter
|
||||
|
||||
@ -51,8 +59,21 @@ const ObjectTableNavigationButtons = ({
|
||||
|
||||
const loadNeighbors = async () => {
|
||||
setLoading(true)
|
||||
const filter = getActiveFilterValues(getPersistedFilterRef.current())
|
||||
const sorter = getPersistedSorterRef.current()
|
||||
// Prefer the effective list filter (view + user filters) when available
|
||||
const listFilter = getActiveFilterValues(
|
||||
getObjectListFilterRef.current(objectType)
|
||||
)
|
||||
const persistedFilter = getActiveFilterValues(
|
||||
getPersistedFilterRef.current()
|
||||
)
|
||||
const filter =
|
||||
Object.keys(listFilter).length > 0 ? listFilter : persistedFilter
|
||||
|
||||
const listSorter = getObjectListSorterRef.current(objectType)
|
||||
const persistedSorter = getPersistedSorterRef.current()
|
||||
const sorter =
|
||||
listSorter?.field && listSorter?.order ? listSorter : persistedSorter
|
||||
|
||||
const result = await getObjectNeighborsRef.current(objectType, {
|
||||
id: _id,
|
||||
filter,
|
||||
|
||||
@ -60,7 +60,8 @@ const SegmentedNav = ({
|
||||
onChange,
|
||||
onReorder,
|
||||
className,
|
||||
disabled = false
|
||||
disabled = false,
|
||||
animated = true
|
||||
}) => {
|
||||
const groupRef = useRef(null)
|
||||
const thumbRef = useRef(null)
|
||||
@ -95,6 +96,12 @@ const SegmentedNav = ({
|
||||
const toMetrics = getItemMetrics(itemRefs.current.get(value))
|
||||
prevValueRef.current = value
|
||||
|
||||
if (!animated) {
|
||||
setIsAnimating(false)
|
||||
setThumbRect(null)
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (!fromMetrics || !toMetrics) {
|
||||
return undefined
|
||||
}
|
||||
@ -119,7 +126,7 @@ const SegmentedNav = ({
|
||||
cancelAnimationFrame(startFrame)
|
||||
cancelAnimationFrame(endFrame)
|
||||
}
|
||||
}, [value])
|
||||
}, [value, animated])
|
||||
|
||||
const finishAnimation = useCallback(() => {
|
||||
setIsAnimating(false)
|
||||
@ -425,7 +432,8 @@ SegmentedNav.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
onReorder: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool
|
||||
disabled: PropTypes.bool,
|
||||
animated: PropTypes.bool
|
||||
}
|
||||
|
||||
export default SegmentedNav
|
||||
|
||||
@ -17,6 +17,56 @@ const ObjectListViewContext = createContext()
|
||||
|
||||
const ALL_TAB_KEY = 'all'
|
||||
|
||||
const getLastViewStorageKey = (objectType) =>
|
||||
`objectListView:${objectType}:lastViewId`
|
||||
|
||||
const getViewsCacheKey = (objectType) =>
|
||||
`objectListView:${objectType}:views`
|
||||
|
||||
const readLastViewId = (objectType) => {
|
||||
if (!objectType) return null
|
||||
try {
|
||||
return sessionStorage.getItem(getLastViewStorageKey(objectType)) || null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const writeLastViewId = (objectType, viewId) => {
|
||||
if (!objectType) return
|
||||
try {
|
||||
const key = getLastViewStorageKey(objectType)
|
||||
if (viewId) {
|
||||
sessionStorage.setItem(key, String(viewId))
|
||||
} else {
|
||||
sessionStorage.removeItem(key)
|
||||
}
|
||||
} catch {
|
||||
// Ignore sessionStorage failures (private mode, quota, etc.)
|
||||
}
|
||||
}
|
||||
|
||||
const readCachedViews = (objectType) => {
|
||||
if (!objectType) return null
|
||||
try {
|
||||
const raw = sessionStorage.getItem(getViewsCacheKey(objectType))
|
||||
if (raw == null) return null
|
||||
const parsed = JSON.parse(raw)
|
||||
return Array.isArray(parsed) ? parsed : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const writeCachedViews = (objectType, views) => {
|
||||
if (!objectType) return
|
||||
try {
|
||||
sessionStorage.setItem(getViewsCacheKey(objectType), JSON.stringify(views))
|
||||
} catch {
|
||||
// Ignore sessionStorage failures (private mode, quota, etc.)
|
||||
}
|
||||
}
|
||||
|
||||
const getPreviousTabKey = (viewList, deletedKey) => {
|
||||
const index = viewList.findIndex(
|
||||
(view) => String(view._id) === String(deletedKey)
|
||||
@ -35,6 +85,9 @@ const DEFAULT_VIEW = {
|
||||
sort: {}
|
||||
}
|
||||
|
||||
const EMPTY_FILTER = {}
|
||||
const EMPTY_SORT = {}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const getObjectViewKey = (view) =>
|
||||
view?._id != null ? String(view._id) : null
|
||||
@ -62,8 +115,7 @@ const viewStateEqual = (left, right) =>
|
||||
export const ObjectListViewProvider = ({
|
||||
children,
|
||||
objectType,
|
||||
tableRef,
|
||||
onViewStateChange
|
||||
tableRef
|
||||
}) => {
|
||||
const {
|
||||
fetchObjectViews,
|
||||
@ -77,12 +129,21 @@ export const ObjectListViewProvider = ({
|
||||
const { token, authInitialized } = useContext(AuthContext)
|
||||
const { getViewFromUrl, persistView } = useTableState()
|
||||
|
||||
const [views, setViews] = useState([])
|
||||
const [draftViews, setDraftViews] = useState([])
|
||||
const [initialLoading, setInitialLoading] = useState(true)
|
||||
const [views, setViews] = useState(
|
||||
() => readCachedViews(objectType) || []
|
||||
)
|
||||
const [draftViews, setDraftViews] = useState(() => {
|
||||
const cached = readCachedViews(objectType)
|
||||
return cached ? cloneViews(cached) : []
|
||||
})
|
||||
const [initialLoading, setInitialLoading] = useState(
|
||||
() => readCachedViews(objectType) == null
|
||||
)
|
||||
const [viewsFetched, setViewsFetched] = useState(false)
|
||||
const [saving, setSaving] = useState(false)
|
||||
const [activeTabKey, setActiveTabKey] = useState(ALL_TAB_KEY)
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [viewSyncReady, setViewSyncReady] = useState(false)
|
||||
|
||||
const editSnapshotRef = useRef([])
|
||||
const wasEditingRef = useRef(false)
|
||||
@ -140,15 +201,22 @@ export const ObjectListViewProvider = ({
|
||||
|
||||
if (tabKey !== ALL_TAB_KEY && !view) return
|
||||
|
||||
// "All" outside edit mode restores the user's persisted filter/sort
|
||||
// "All" restores the user's personal filter/sort from URL/session
|
||||
if (tabKey === ALL_TAB_KEY && !editing) {
|
||||
tableRef.current.applyViewState(null, null)
|
||||
tableRef.current.applyViewState(null, null, { forceAll: true })
|
||||
return
|
||||
}
|
||||
|
||||
// Views apply their own filter/sort into the table (and filter context).
|
||||
// They are never written to the filter/sort URL params.
|
||||
tableRef.current.applyViewState(
|
||||
view?.filter || {},
|
||||
view?.sort?.field ? view.sort : {}
|
||||
view?.sort?.field ? view.sort : {},
|
||||
{
|
||||
viewId: view?._id != null ? String(view._id) : null,
|
||||
viewFilter: view?.filter || {},
|
||||
viewSort: view?.sort?.field ? view.sort : {}
|
||||
}
|
||||
)
|
||||
},
|
||||
[tableRef]
|
||||
@ -157,18 +225,23 @@ export const ObjectListViewProvider = ({
|
||||
const loadViews = useCallback(
|
||||
async (silent = false) => {
|
||||
if (!authReady || !objectType) return
|
||||
if (!silent) setInitialLoading(true)
|
||||
const hasCache = readCachedViews(objectType) != null
|
||||
// Keep showing cached tabs while refreshing; only spin when nothing to show
|
||||
if (!silent && !hasCache) setInitialLoading(true)
|
||||
try {
|
||||
const { data } = await apiRef.current.fetchObjectViews(objectType)
|
||||
const nextViews = data || []
|
||||
setViews(nextViews)
|
||||
writeCachedViews(objectType, nextViews)
|
||||
if (!isEditingRef.current) {
|
||||
setDraftViews(cloneViews(nextViews))
|
||||
}
|
||||
setViewsFetched(true)
|
||||
return nextViews
|
||||
} catch (error) {
|
||||
console.error('Error fetching object views:', error)
|
||||
return []
|
||||
setViewsFetched(true)
|
||||
return hasCache ? readCachedViews(objectType) || [] : []
|
||||
} finally {
|
||||
if (!silent) setInitialLoading(false)
|
||||
}
|
||||
@ -179,54 +252,109 @@ export const ObjectListViewProvider = ({
|
||||
const loadViewsRef = useRef(loadViews)
|
||||
loadViewsRef.current = loadViews
|
||||
|
||||
const rememberActiveView = useCallback(
|
||||
(viewId) => {
|
||||
const key = viewId ? String(viewId) : null
|
||||
persistView(key)
|
||||
writeLastViewId(objectType, key)
|
||||
},
|
||||
[objectType, persistView]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
urlSyncedRef.current = false
|
||||
setViewSyncReady(false)
|
||||
setViewsFetched(false)
|
||||
setActiveTabKey(ALL_TAB_KEY)
|
||||
|
||||
const cached = readCachedViews(objectType)
|
||||
if (cached) {
|
||||
setViews(cached)
|
||||
if (!isEditingRef.current) {
|
||||
setDraftViews(cloneViews(cached))
|
||||
}
|
||||
setInitialLoading(false)
|
||||
} else {
|
||||
setViews([])
|
||||
setDraftViews([])
|
||||
setInitialLoading(true)
|
||||
}
|
||||
}, [objectType])
|
||||
|
||||
useEffect(() => {
|
||||
loadViews()
|
||||
}, [loadViews])
|
||||
|
||||
// Keep the local cache in sync with authoritative (non-draft) views
|
||||
useEffect(() => {
|
||||
if (initialLoading) return
|
||||
if (!objectType || initialLoading) return
|
||||
writeCachedViews(objectType, views)
|
||||
}, [objectType, views, initialLoading])
|
||||
|
||||
useEffect(() => {
|
||||
if (initialLoading || !viewSyncReady) return
|
||||
applyViewToTable(activeTabKey)
|
||||
}, [activeTabKey, applyViewToTable, initialLoading, isEditing])
|
||||
}, [
|
||||
activeTabKey,
|
||||
applyViewToTable,
|
||||
initialLoading,
|
||||
isEditing,
|
||||
viewSyncReady,
|
||||
viewsFetched
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (initialLoading || urlSyncedRef.current) return
|
||||
if (urlSyncedRef.current) return
|
||||
|
||||
const viewId = getViewFromUrl()
|
||||
if (!viewId) {
|
||||
// Allow early restore from cache; only block when we have nothing to match against yet
|
||||
if (initialLoading && views.length === 0) return
|
||||
|
||||
const urlViewId = getViewFromUrl()
|
||||
const rememberedViewId = readLastViewId(objectType)
|
||||
const candidateViewId = urlViewId || rememberedViewId
|
||||
|
||||
if (!candidateViewId) {
|
||||
urlSyncedRef.current = true
|
||||
setViewSyncReady(true)
|
||||
return
|
||||
}
|
||||
|
||||
const matched =
|
||||
resolveViewFromId(views, viewId) ||
|
||||
resolveViewFromId(draftViews, viewId)
|
||||
resolveViewFromId(views, candidateViewId) ||
|
||||
resolveViewFromId(draftViews, candidateViewId)
|
||||
|
||||
if (matched) {
|
||||
setActiveTabKey(String(matched._id))
|
||||
const matchedId = String(matched._id)
|
||||
setActiveTabKey(matchedId)
|
||||
writeLastViewId(objectType, matchedId)
|
||||
if (!matched._isDraft) {
|
||||
// Keep viewId in the URL and strip any leftover filter/sort params
|
||||
persistView(matchedId)
|
||||
}
|
||||
urlSyncedRef.current = true
|
||||
setViewSyncReady(true)
|
||||
return
|
||||
}
|
||||
|
||||
// Wait until views have loaded before deciding the URL viewId is invalid
|
||||
if (views.length === 0) return
|
||||
// Wait until views have loaded from the network before deciding the candidate is invalid
|
||||
if (!viewsFetched) return
|
||||
|
||||
if (!isEditing) {
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
}
|
||||
|
||||
urlSyncedRef.current = true
|
||||
setViewSyncReady(true)
|
||||
}, [
|
||||
initialLoading,
|
||||
viewsFetched,
|
||||
views,
|
||||
draftViews,
|
||||
isEditing,
|
||||
objectType,
|
||||
getViewFromUrl,
|
||||
persistView
|
||||
persistView,
|
||||
rememberActiveView
|
||||
])
|
||||
|
||||
const selectTab = useCallback(
|
||||
@ -236,7 +364,7 @@ export const ObjectListViewProvider = ({
|
||||
setActiveTabKey(tabKey)
|
||||
|
||||
if (tabKey === ALL_TAB_KEY) {
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
return
|
||||
}
|
||||
|
||||
@ -245,9 +373,9 @@ export const ObjectListViewProvider = ({
|
||||
)
|
||||
if (!view || view._isDraft) return
|
||||
|
||||
persistView(getObjectViewKey(view))
|
||||
rememberActiveView(getObjectViewKey(view))
|
||||
},
|
||||
[activeTabKey, draftViews, isEditing, persistView, views]
|
||||
[activeTabKey, draftViews, isEditing, rememberActiveView, views]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
@ -278,13 +406,13 @@ export const ObjectListViewProvider = ({
|
||||
)
|
||||
if (!stillExists) {
|
||||
setActiveTabKey(ALL_TAB_KEY)
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
applyViewToTable(ALL_TAB_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
await loadViewsRef.current(true)
|
||||
}, [activeTabKey, applyViewToTable, persistView])
|
||||
}, [activeTabKey, applyViewToTable, rememberActiveView])
|
||||
|
||||
const saveEdits = useCallback(async () => {
|
||||
setSaving(true)
|
||||
@ -355,11 +483,11 @@ export const ObjectListViewProvider = ({
|
||||
|
||||
if (resolvedTabKey !== ALL_TAB_KEY && savedView && !savedView._isDraft) {
|
||||
setActiveTabKey(resolvedTabKey)
|
||||
persistView(getObjectViewKey(savedView))
|
||||
rememberActiveView(getObjectViewKey(savedView))
|
||||
} else if (resolvedTabKey !== ALL_TAB_KEY && !savedView) {
|
||||
resolvedTabKey = ALL_TAB_KEY
|
||||
setActiveTabKey(ALL_TAB_KEY)
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
}
|
||||
|
||||
message.success('Views saved')
|
||||
@ -373,7 +501,7 @@ export const ObjectListViewProvider = ({
|
||||
activeTabKey,
|
||||
draftViews,
|
||||
objectType,
|
||||
persistView,
|
||||
rememberActiveView,
|
||||
views
|
||||
])
|
||||
|
||||
@ -407,7 +535,7 @@ export const ObjectListViewProvider = ({
|
||||
const newKey = String(created._id)
|
||||
setActiveTabKey(newKey)
|
||||
applyViewToTable(newKey)
|
||||
persistView(getObjectViewKey(created))
|
||||
rememberActiveView(getObjectViewKey(created))
|
||||
} else {
|
||||
message.error('Failed to create view')
|
||||
}
|
||||
@ -437,13 +565,13 @@ export const ObjectListViewProvider = ({
|
||||
if (isActiveDeleted) {
|
||||
setActiveTabKey(previousKey)
|
||||
if (previousKey === ALL_TAB_KEY) {
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
} else {
|
||||
const view = draftViews.find(
|
||||
(item) => String(item._id) === String(previousKey)
|
||||
)
|
||||
if (view && !view._isDraft) {
|
||||
persistView(getObjectViewKey(view))
|
||||
rememberActiveView(getObjectViewKey(view))
|
||||
}
|
||||
}
|
||||
applyViewToTable(previousKey)
|
||||
@ -456,7 +584,7 @@ export const ObjectListViewProvider = ({
|
||||
draftViews,
|
||||
isEditing,
|
||||
objectType,
|
||||
persistView,
|
||||
rememberActiveView,
|
||||
views
|
||||
]
|
||||
)
|
||||
@ -531,19 +659,19 @@ export const ObjectListViewProvider = ({
|
||||
if (isActiveDeleted) {
|
||||
setActiveTabKey(previousKey)
|
||||
if (previousKey === ALL_TAB_KEY) {
|
||||
persistView(null)
|
||||
rememberActiveView(null)
|
||||
} else {
|
||||
const view = list.find(
|
||||
(item) => String(item._id) === String(previousKey)
|
||||
)
|
||||
if (view && !view._isDraft) {
|
||||
persistView(getObjectViewKey(view))
|
||||
rememberActiveView(getObjectViewKey(view))
|
||||
}
|
||||
}
|
||||
applyViewToTable(previousKey)
|
||||
}
|
||||
},
|
||||
[activeTabKey, applyViewToTable, draftViews, isEditing, persistView, views]
|
||||
[activeTabKey, applyViewToTable, draftViews, isEditing, rememberActiveView, views]
|
||||
)
|
||||
|
||||
const handleFilterSortChange = useCallback((filter, sorter) => {
|
||||
@ -682,40 +810,17 @@ export const ObjectListViewProvider = ({
|
||||
[]
|
||||
)
|
||||
|
||||
const handleFilterSortChangeRef = useRef(handleFilterSortChange)
|
||||
handleFilterSortChangeRef.current = handleFilterSortChange
|
||||
|
||||
const stableFilterSortHandlerRef = useRef((filter, sorter) => {
|
||||
handleFilterSortChangeRef.current?.(filter, sorter)
|
||||
})
|
||||
|
||||
const lastSyncedViewKeyRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
const viewKey = isEditing
|
||||
? `edit:${activeView?._id ?? activeTabKey}`
|
||||
: activeView?._id != null
|
||||
? String(activeView._id)
|
||||
: activeTabKey === ALL_TAB_KEY
|
||||
? 'all'
|
||||
: null
|
||||
|
||||
if (viewKey === lastSyncedViewKeyRef.current) return
|
||||
lastSyncedViewKeyRef.current = viewKey
|
||||
|
||||
onViewStateChange?.({
|
||||
activeView: isEditing ? activeViewRef.current : null,
|
||||
isEditing,
|
||||
handleFilterSortChange: isEditing
|
||||
? stableFilterSortHandlerRef.current
|
||||
: null
|
||||
})
|
||||
}, [
|
||||
activeTabKey,
|
||||
activeView?._id,
|
||||
isEditing,
|
||||
onViewStateChange
|
||||
])
|
||||
const listViewId =
|
||||
activeTabKey !== ALL_TAB_KEY && activeTabKey != null
|
||||
? String(activeTabKey)
|
||||
: null
|
||||
const listViewFilter = activeView?.filter || EMPTY_FILTER
|
||||
const listViewSort = activeView?.sort?.field
|
||||
? activeView.sort
|
||||
: EMPTY_SORT
|
||||
// Only expose the editable view while editing — ObjectTable uses this to
|
||||
// route filter/sort changes into the draft instead of URL/session persistence.
|
||||
const activeObjectView = isEditing ? activeView : null
|
||||
|
||||
const viewTabSignatures = useMemo(
|
||||
() => displayedViews.map(getViewTabSignature).join('|'),
|
||||
@ -728,7 +833,11 @@ export const ObjectListViewProvider = ({
|
||||
ALL_TAB_KEY,
|
||||
views: displayedViews,
|
||||
activeView,
|
||||
activeObjectView,
|
||||
activeTabKey,
|
||||
listViewId,
|
||||
listViewFilter,
|
||||
listViewSort,
|
||||
initialLoading,
|
||||
saving,
|
||||
isEditing,
|
||||
@ -749,7 +858,11 @@ export const ObjectListViewProvider = ({
|
||||
objectType,
|
||||
displayedViews,
|
||||
activeView,
|
||||
activeObjectView,
|
||||
activeTabKey,
|
||||
listViewId,
|
||||
listViewFilter,
|
||||
listViewSort,
|
||||
initialLoading,
|
||||
saving,
|
||||
isEditing,
|
||||
@ -788,8 +901,7 @@ export const useObjectListView = () => {
|
||||
ObjectListViewProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
objectType: PropTypes.string.isRequired,
|
||||
tableRef: PropTypes.object,
|
||||
onViewStateChange: PropTypes.func
|
||||
tableRef: PropTypes.object
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
|
||||
@ -3,6 +3,7 @@ import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
@ -16,6 +17,8 @@ export const VIEW_URL_PARAM = 'viewId'
|
||||
|
||||
const getSessionFilterKey = (scope) => `tableState:${scope}:filter`
|
||||
const getSessionSortKey = (scope) => `tableState:${scope}:sort`
|
||||
const getSessionListFilterKey = (scope) => `tableState:${scope}:listFilter`
|
||||
const getSessionListSortKey = (scope) => `tableState:${scope}:listSort`
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const getActiveFilterValues = (filterState) => {
|
||||
@ -89,6 +92,42 @@ const writeSortToSession = (scope, sorter) => {
|
||||
}
|
||||
}
|
||||
|
||||
const readListFilterFromSession = (scope) => {
|
||||
try {
|
||||
return parseJsonParam(sessionStorage.getItem(getSessionListFilterKey(scope)))
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const readListSortFromSession = (scope) => {
|
||||
try {
|
||||
const parsed = parseJsonParam(sessionStorage.getItem(getSessionListSortKey(scope)))
|
||||
if (!parsed?.field || !parsed?.order) return null
|
||||
return { field: parsed.field, order: parsed.order }
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const writeListFilterToSession = (scope, filter) => {
|
||||
const key = getSessionListFilterKey(scope)
|
||||
if (Object.keys(filter).length > 0) {
|
||||
sessionStorage.setItem(key, JSON.stringify(filter))
|
||||
} else {
|
||||
sessionStorage.removeItem(key)
|
||||
}
|
||||
}
|
||||
|
||||
const writeListSortToSession = (scope, sorter) => {
|
||||
const key = getSessionListSortKey(scope)
|
||||
if (sorter?.field && sorter?.order) {
|
||||
sessionStorage.setItem(key, JSON.stringify(sorter))
|
||||
} else {
|
||||
sessionStorage.removeItem(key)
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeSorter = (sorter) => {
|
||||
if (sorter?.field && sorter?.order) {
|
||||
return { field: sorter.field, order: sorter.order }
|
||||
@ -100,6 +139,24 @@ export const TableStateProvider = ({ children }) => {
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const [pageFilters, setPageFilters] = useState({})
|
||||
const [pageSorters, setPageSorters] = useState({})
|
||||
// Effective list filters (view filter + user filters). Survives navigating
|
||||
// from the list page to an info page so breadcrumb/neighbors keep working.
|
||||
const [objectListFilters, setObjectListFilters] = useState({})
|
||||
const [objectListSorters, setObjectListSorters] = useState({})
|
||||
const searchParamsRef = useRef(searchParams)
|
||||
searchParamsRef.current = searchParams
|
||||
|
||||
// Keep sequential URL writes in the same tick from clobbering each other
|
||||
// (e.g. persistView then persistTableState both calling setSearchParams).
|
||||
const updateSearchParams = useCallback(
|
||||
(mutator) => {
|
||||
const next = new URLSearchParams(searchParamsRef.current)
|
||||
mutator(next)
|
||||
searchParamsRef.current = next
|
||||
setSearchParams(next, { replace: true })
|
||||
},
|
||||
[setSearchParams]
|
||||
)
|
||||
|
||||
const getPersistedFilter = useCallback(
|
||||
(scope, { useFilterInUrl = false, useFilterInSession = false } = {}) => {
|
||||
@ -137,18 +194,23 @@ export const TableStateProvider = ({ children }) => {
|
||||
)
|
||||
|
||||
const persistView = useCallback(
|
||||
(viewId) => {
|
||||
const next = new URLSearchParams(searchParams)
|
||||
// Drop legacy `view` param that previously stored `_reference`
|
||||
next.delete('view')
|
||||
if (viewId) {
|
||||
next.set(VIEW_URL_PARAM, String(viewId))
|
||||
} else {
|
||||
next.delete(VIEW_URL_PARAM)
|
||||
}
|
||||
setSearchParams(next, { replace: true })
|
||||
(viewId, { clearFilterSort = Boolean(viewId) } = {}) => {
|
||||
updateSearchParams((next) => {
|
||||
// Drop legacy `view` param that previously stored `_reference`
|
||||
next.delete('view')
|
||||
if (viewId) {
|
||||
next.set(VIEW_URL_PARAM, String(viewId))
|
||||
} else {
|
||||
next.delete(VIEW_URL_PARAM)
|
||||
}
|
||||
// View filter/sort live on the view object — never in the URL
|
||||
if (clearFilterSort) {
|
||||
next.delete(FILTER_URL_PARAM)
|
||||
next.delete(SORT_URL_PARAM)
|
||||
}
|
||||
})
|
||||
},
|
||||
[searchParams, setSearchParams]
|
||||
[updateSearchParams]
|
||||
)
|
||||
|
||||
const persistFilter = useCallback(
|
||||
@ -162,16 +224,16 @@ export const TableStateProvider = ({ children }) => {
|
||||
writeFilterToSession(scope, active)
|
||||
}
|
||||
if (saveFilterInUrl) {
|
||||
const next = new URLSearchParams(searchParams)
|
||||
if (Object.keys(active).length > 0) {
|
||||
next.set(FILTER_URL_PARAM, JSON.stringify(active))
|
||||
} else {
|
||||
next.delete(FILTER_URL_PARAM)
|
||||
}
|
||||
setSearchParams(next, { replace: true })
|
||||
updateSearchParams((next) => {
|
||||
if (Object.keys(active).length > 0) {
|
||||
next.set(FILTER_URL_PARAM, JSON.stringify(active))
|
||||
} else {
|
||||
next.delete(FILTER_URL_PARAM)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
[searchParams, setSearchParams]
|
||||
[updateSearchParams]
|
||||
)
|
||||
|
||||
const persistSort = useCallback(
|
||||
@ -185,16 +247,16 @@ export const TableStateProvider = ({ children }) => {
|
||||
writeSortToSession(scope, nextSorter)
|
||||
}
|
||||
if (saveSortInUrl) {
|
||||
const next = new URLSearchParams(searchParams)
|
||||
if (nextSorter.field && nextSorter.order) {
|
||||
next.set(SORT_URL_PARAM, JSON.stringify(nextSorter))
|
||||
} else {
|
||||
next.delete(SORT_URL_PARAM)
|
||||
}
|
||||
setSearchParams(next, { replace: true })
|
||||
updateSearchParams((next) => {
|
||||
if (nextSorter.field && nextSorter.order) {
|
||||
next.set(SORT_URL_PARAM, JSON.stringify(nextSorter))
|
||||
} else {
|
||||
next.delete(SORT_URL_PARAM)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
[searchParams, setSearchParams]
|
||||
[updateSearchParams]
|
||||
)
|
||||
|
||||
const persistTableState = useCallback(
|
||||
@ -220,25 +282,25 @@ export const TableStateProvider = ({ children }) => {
|
||||
}
|
||||
|
||||
if (saveFilterInUrl || saveSortInUrl) {
|
||||
const next = new URLSearchParams(searchParams)
|
||||
if (saveFilterInUrl) {
|
||||
if (Object.keys(active).length > 0) {
|
||||
next.set(FILTER_URL_PARAM, JSON.stringify(active))
|
||||
} else {
|
||||
next.delete(FILTER_URL_PARAM)
|
||||
updateSearchParams((next) => {
|
||||
if (saveFilterInUrl) {
|
||||
if (Object.keys(active).length > 0) {
|
||||
next.set(FILTER_URL_PARAM, JSON.stringify(active))
|
||||
} else {
|
||||
next.delete(FILTER_URL_PARAM)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (saveSortInUrl) {
|
||||
if (nextSorter.field && nextSorter.order) {
|
||||
next.set(SORT_URL_PARAM, JSON.stringify(nextSorter))
|
||||
} else {
|
||||
next.delete(SORT_URL_PARAM)
|
||||
if (saveSortInUrl) {
|
||||
if (nextSorter.field && nextSorter.order) {
|
||||
next.set(SORT_URL_PARAM, JSON.stringify(nextSorter))
|
||||
} else {
|
||||
next.delete(SORT_URL_PARAM)
|
||||
}
|
||||
}
|
||||
}
|
||||
setSearchParams(next, { replace: true })
|
||||
})
|
||||
}
|
||||
},
|
||||
[searchParams, setSearchParams]
|
||||
[updateSearchParams]
|
||||
)
|
||||
|
||||
const setPageFilter = useCallback((path, filter) => {
|
||||
@ -268,12 +330,71 @@ export const TableStateProvider = ({ children }) => {
|
||||
})
|
||||
}, [])
|
||||
|
||||
const setObjectListFilter = useCallback((objectType, filter) => {
|
||||
if (!objectType) return
|
||||
const active = getActiveFilterValues(filter)
|
||||
writeListFilterToSession(objectType, active)
|
||||
setObjectListFilters((prev) => {
|
||||
const hasActive = Object.keys(active).length > 0
|
||||
if (!hasActive) {
|
||||
if (!(objectType in prev)) return prev
|
||||
const next = { ...prev }
|
||||
delete next[objectType]
|
||||
return next
|
||||
}
|
||||
return { ...prev, [objectType]: active }
|
||||
})
|
||||
}, [])
|
||||
|
||||
const setObjectListSorter = useCallback((objectType, sorter) => {
|
||||
if (!objectType) return
|
||||
const nextSorter = normalizeSorter(sorter)
|
||||
writeListSortToSession(objectType, nextSorter)
|
||||
setObjectListSorters((prev) => {
|
||||
const hasSort = nextSorter?.field && nextSorter?.order
|
||||
if (!hasSort) {
|
||||
if (!(objectType in prev)) return prev
|
||||
const next = { ...prev }
|
||||
delete next[objectType]
|
||||
return next
|
||||
}
|
||||
return { ...prev, [objectType]: nextSorter }
|
||||
})
|
||||
}, [])
|
||||
|
||||
const getObjectListFilter = useCallback(
|
||||
(objectType) => {
|
||||
if (!objectType) return {}
|
||||
if (objectListFilters[objectType]) {
|
||||
return objectListFilters[objectType]
|
||||
}
|
||||
return getActiveFilterValues(readListFilterFromSession(objectType) || {})
|
||||
},
|
||||
[objectListFilters]
|
||||
)
|
||||
|
||||
const getObjectListSorter = useCallback(
|
||||
(objectType) => {
|
||||
if (!objectType) return {}
|
||||
if (objectListSorters[objectType]) {
|
||||
return objectListSorters[objectType]
|
||||
}
|
||||
return readListSortFromSession(objectType) || {}
|
||||
},
|
||||
[objectListSorters]
|
||||
)
|
||||
|
||||
const hasPageFilter = useCallback(
|
||||
(path) => Object.keys(pageFilters[path] || {}).length > 0,
|
||||
[pageFilters]
|
||||
)
|
||||
|
||||
const hasStoredFilter = useCallback((scope) => hasStoredSessionFilter(scope), [])
|
||||
const hasStoredFilter = useCallback((scope) => {
|
||||
if (!scope) return false
|
||||
if (hasStoredSessionFilter(scope)) return true
|
||||
if (Object.keys(objectListFilters[scope] || {}).length > 0) return true
|
||||
return Object.keys(getActiveFilterValues(readListFilterFromSession(scope) || {})).length > 0
|
||||
}, [objectListFilters])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
@ -286,10 +407,16 @@ export const TableStateProvider = ({ children }) => {
|
||||
persistTableState,
|
||||
setPageFilter,
|
||||
setPageSorter,
|
||||
setObjectListFilter,
|
||||
setObjectListSorter,
|
||||
getObjectListFilter,
|
||||
getObjectListSorter,
|
||||
hasPageFilter,
|
||||
hasStoredFilter,
|
||||
pageFilters,
|
||||
pageSorters
|
||||
pageSorters,
|
||||
objectListFilters,
|
||||
objectListSorters
|
||||
}),
|
||||
[
|
||||
getPersistedFilter,
|
||||
@ -301,10 +428,16 @@ export const TableStateProvider = ({ children }) => {
|
||||
persistTableState,
|
||||
setPageFilter,
|
||||
setPageSorter,
|
||||
setObjectListFilter,
|
||||
setObjectListSorter,
|
||||
getObjectListFilter,
|
||||
getObjectListSorter,
|
||||
hasPageFilter,
|
||||
hasStoredFilter,
|
||||
pageFilters,
|
||||
pageSorters
|
||||
pageSorters,
|
||||
objectListFilters,
|
||||
objectListSorters
|
||||
]
|
||||
)
|
||||
|
||||
@ -327,6 +460,7 @@ export const useTableState = () => {
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const useTableStatePersistence = ({
|
||||
scope,
|
||||
viewId = null,
|
||||
pagePath,
|
||||
saveFilterInSession = false,
|
||||
saveFilterInUrl = false,
|
||||
@ -344,15 +478,58 @@ export const useTableStatePersistence = ({
|
||||
persistSort: persistSortCtx,
|
||||
persistTableState: persistTableStateCtx,
|
||||
setPageFilter,
|
||||
setPageSorter
|
||||
setPageSorter,
|
||||
setObjectListFilter,
|
||||
setObjectListSorter
|
||||
} = useTableState()
|
||||
|
||||
// View filter/sort belong to the view object — never read/write them via
|
||||
// the shared filter/sort URL or session keys used by the "All" tab.
|
||||
const isViewScope = Boolean(viewId)
|
||||
|
||||
const readOptions = useMemo(
|
||||
() => ({ useFilterInUrl, useFilterInSession, useSortInUrl, useSortInSession }),
|
||||
[useFilterInUrl, useFilterInSession, useSortInUrl, useSortInSession]
|
||||
() => ({
|
||||
useFilterInUrl: isViewScope ? false : useFilterInUrl,
|
||||
useFilterInSession: isViewScope ? false : useFilterInSession,
|
||||
useSortInUrl: isViewScope ? false : useSortInUrl,
|
||||
useSortInSession: isViewScope ? false : useSortInSession
|
||||
}),
|
||||
[
|
||||
isViewScope,
|
||||
useFilterInUrl,
|
||||
useFilterInSession,
|
||||
useSortInUrl,
|
||||
useSortInSession
|
||||
]
|
||||
)
|
||||
|
||||
const saveOptions = useMemo(
|
||||
() => ({
|
||||
saveFilterInSession: isViewScope ? false : saveFilterInSession,
|
||||
saveFilterInUrl: isViewScope ? false : saveFilterInUrl,
|
||||
saveSortInSession: isViewScope ? false : saveSortInSession,
|
||||
saveSortInUrl: isViewScope ? false : saveSortInUrl
|
||||
}),
|
||||
[
|
||||
isViewScope,
|
||||
saveFilterInSession,
|
||||
saveFilterInUrl,
|
||||
saveSortInSession,
|
||||
saveSortInUrl
|
||||
]
|
||||
)
|
||||
|
||||
const allTabReadOptions = useMemo(
|
||||
() => ({
|
||||
useFilterInUrl,
|
||||
useFilterInSession,
|
||||
useSortInUrl,
|
||||
useSortInSession
|
||||
}),
|
||||
[useFilterInUrl, useFilterInSession, useSortInUrl, useSortInSession]
|
||||
)
|
||||
|
||||
const allTabSaveOptions = useMemo(
|
||||
() => ({
|
||||
saveFilterInSession,
|
||||
saveFilterInUrl,
|
||||
@ -372,6 +549,18 @@ export const useTableStatePersistence = ({
|
||||
[getPersistedSorterCtx, scope, readOptions]
|
||||
)
|
||||
|
||||
// Always reads the All-tab filter/sort, even while a view is still selected
|
||||
// (used when switching back to All before listViewId has cleared).
|
||||
const getAllTabPersistedFilter = useCallback(
|
||||
() => getPersistedFilterCtx(scope, allTabReadOptions),
|
||||
[getPersistedFilterCtx, scope, allTabReadOptions]
|
||||
)
|
||||
|
||||
const getAllTabPersistedSorter = useCallback(
|
||||
() => getPersistedSorterCtx(scope, allTabReadOptions),
|
||||
[getPersistedSorterCtx, scope, allTabReadOptions]
|
||||
)
|
||||
|
||||
const persistFilter = useCallback(
|
||||
(filterState) => persistFilterCtx(scope, filterState, saveOptions),
|
||||
[persistFilterCtx, scope, saveOptions]
|
||||
@ -388,6 +577,12 @@ export const useTableStatePersistence = ({
|
||||
[persistTableStateCtx, scope, saveOptions]
|
||||
)
|
||||
|
||||
const persistAllTabTableState = useCallback(
|
||||
(filterState, sorter) =>
|
||||
persistTableStateCtx(scope, filterState, sorter, allTabSaveOptions),
|
||||
[persistTableStateCtx, scope, allTabSaveOptions]
|
||||
)
|
||||
|
||||
const registerPageFilter = useCallback(
|
||||
(filterState) => {
|
||||
if (pagePath) {
|
||||
@ -406,14 +601,38 @@ export const useTableStatePersistence = ({
|
||||
[pagePath, setPageSorter]
|
||||
)
|
||||
|
||||
const registerObjectListFilter = useCallback(
|
||||
(filterState) => {
|
||||
if (scope) {
|
||||
setObjectListFilter(scope, filterState)
|
||||
}
|
||||
},
|
||||
[scope, setObjectListFilter]
|
||||
)
|
||||
|
||||
const registerObjectListSorter = useCallback(
|
||||
(sorter) => {
|
||||
if (scope) {
|
||||
setObjectListSorter(scope, sorter)
|
||||
}
|
||||
},
|
||||
[scope, setObjectListSorter]
|
||||
)
|
||||
|
||||
return {
|
||||
persistenceScope: scope,
|
||||
getPersistedFilter,
|
||||
getPersistedSorter,
|
||||
getAllTabPersistedFilter,
|
||||
getAllTabPersistedSorter,
|
||||
persistFilter,
|
||||
persistSort,
|
||||
persistTableState,
|
||||
persistAllTabTableState,
|
||||
registerPageFilter,
|
||||
registerPageSorter,
|
||||
registerObjectListFilter,
|
||||
registerObjectListSorter,
|
||||
getActiveFilterValues
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user