Compare commits

..

No commits in common. "1466fe0f62961f0d36b5808f4dc8145f0912a4ba" and "b2e35c965c07c874fb968c4ef13e2d74be1d5be7" have entirely different histories.

82 changed files with 1054 additions and 5821 deletions

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.779032,0,0,0.779032,3.073021,9.025537)">
<path d="M22.587,55.452L29.317,55.452L29.317,3.541L22.587,3.541L22.587,55.452ZM44.947,55.452L51.677,55.452L51.677,3.541L44.947,3.541L44.947,55.452ZM10.588,58.962L63.676,58.962C70.606,58.962 74.264,55.326 74.264,48.481L74.264,10.522C74.264,3.667 70.606,0.02 63.676,0.02L10.588,0.02C3.679,0.02 0,3.667 0,10.522L0,48.481C0,55.326 3.679,58.962 10.588,58.962ZM11.167,52.003C8.429,52.003 6.959,50.615 6.959,47.743L6.959,11.251C6.959,8.378 8.429,6.979 11.167,6.979L63.097,6.979C65.813,6.979 67.305,8.378 67.305,11.251L67.305,47.743C67.305,50.615 65.813,52.003 63.097,52.003L11.167,52.003Z" style="fill-rule:nonzero;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg
width="100%"
height="100%"
viewBox="0 0 64 64"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
class="th-icon"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"
>
<g>
<path
d="M32,5.131C46.829,5.131 58.869,17.171 58.869,32"
style="fill:none;"
/>
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 32 32"
to="360 32 32"
dur="1s"
repeatCount="indefinite"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 774 B

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0,-0.777065,0.777065,0,9.038886,69.94022)">
<path d="M75.315,48.595C75.315,55.44 71.658,59.097 64.728,59.097L21.503,59.097C14.606,59.097 10.906,55.461 10.906,48.595L10.906,36.765L17.865,36.765L17.865,48.26C17.865,50.888 19.229,52.138 21.722,52.138L64.499,52.138C66.981,52.138 68.356,50.888 68.356,48.26L68.356,36.765L75.315,36.765L75.315,48.595ZM75.315,10.657L75.315,22.436L68.356,22.436L68.356,10.982C68.356,8.354 66.981,7.114 64.499,7.114L21.722,7.114C19.229,7.114 17.865,8.354 17.865,10.982L17.865,22.436L10.906,22.436L10.906,10.657C10.906,3.781 14.606,0.155 21.503,0.155L64.728,0.155C71.658,0.155 75.315,3.802 75.315,10.657Z" style="fill-rule:nonzero;"/>
<path d="M88.562,55.043C88.562,57.276 86.765,59.094 84.532,59.094C82.3,59.094 80.481,57.276 80.481,55.043C80.481,52.81 82.3,51.013 84.532,51.013C86.765,51.013 88.562,52.81 88.562,55.043Z" style="fill-rule:nonzero;"/>
<path d="M88.562,42.32C88.562,44.553 86.765,46.34 84.532,46.34C82.3,46.34 80.481,44.553 80.481,42.32C80.481,40.066 82.3,38.269 84.532,38.269C86.765,38.269 88.562,40.066 88.562,42.32Z" style="fill-rule:nonzero;"/>
<path d="M88.562,16.774C88.562,19.007 86.765,20.825 84.532,20.825C82.3,20.825 80.481,19.007 80.481,16.774C80.481,14.541 82.3,12.744 84.532,12.744C86.765,12.744 88.562,14.541 88.562,16.774Z" style="fill-rule:nonzero;"/>
<path d="M88.562,4.02C88.562,6.284 86.765,8.071 84.532,8.071C82.3,8.071 80.481,6.284 80.481,4.02C80.481,1.787 82.3,0 84.532,0C86.765,0 88.562,1.787 88.562,4.02Z" style="fill-rule:nonzero;"/>
<path d="M84.582,34.107C87.085,34.107 89.11,32.082 89.11,29.579C89.11,27.076 87.085,25.041 84.582,25.041C82.961,25.041 81.507,25.903 80.707,27.224L10.916,27.224C9.558,27.224 8.54,28.242 8.54,29.6C8.54,30.958 9.558,31.998 10.916,31.998L80.75,31.998C81.55,33.276 82.961,34.107 84.582,34.107Z" style="fill-rule:nonzero;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -22,7 +22,7 @@
.ant-form-item-control-input,
.ant-input,
.ant-input-number .ant-input-number-input,
.segmented-nav-item-label,
.ant-segmented-item-label,
.ant-badge-status-text,
.ant-tree-title,
.ant-select,
@ -47,12 +47,6 @@
font-family: 'DM Sans';
}
:root {
--color-list-view-tabs-border: #8282822e;
--color-button-border: #8282822e;
--color-button-background: #8282822e;
}
.ant-dropdown {
z-index: 999;
}
@ -671,11 +665,6 @@ body {
bottom: 8px;
}
.scrollbox-horizontal > [data-simplebar],
.scrollbox-horizontal .simplebar-wrapper {
width: 100%;
}
.simplebar-scrollbar:before {
background: #78787854 !important;
}
@ -1372,193 +1361,16 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
}
.objectTableCardsContainer > .ant-spin-nested-loading,
.objectTableCardsContainer > .ant-spin-nested-loading > .ant-spin-container,
.objectTableCardsContainer .ant-spin-nested-loading {
width: 100%;
height: 100%;
min-height: 0;
flex: 1;
display: flex;
flex-direction: column;
}
.objectTableCardsContainer .ant-spin-container {
width: 100%;
height: 100%;
min-height: 0;
flex: 1;
display: flex;
flex-direction: column;
}
.objectKanbanContainerWrapper {
position: relative;
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
}
.objectKanbanContainerWrapper > .ant-spin-nested-loading,
.objectKanbanContainerWrapper > .ant-spin-nested-loading > .ant-spin-container {
height: 100%;
min-height: 0;
flex: 1;
display: flex;
flex-direction: column;
}
.objectKanbanContainerSkeletons {
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
min-height: 0;
}
.objectKanbanKanbanBody {
position: relative;
flex: 1;
min-width: 0;
min-height: 0;
}
.objectKanbanContainer {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
z-index: 1;
pointer-events: auto;
}
.objectKanbanWrap {
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
}
.objectKanbanWrap > .ant-spin-nested-loading,
.objectKanbanWrap > .ant-spin-nested-loading > .ant-spin-container {
height: 100%;
min-height: 0;
}
.objectKanbanScroll {
flex: 1;
width: 100%;
min-width: 0;
min-height: 0;
}
.objectKanbanScroll .simplebar-content-wrapper {
height: 100%;
}
.objectKanbanScroll .simplebar-content {
min-height: 100%;
}
.objectKanbanHeader {
flex-shrink: 0;
width: 100%;
min-width: 0;
overflow: hidden;
}
.objectKanbanHeaderTrack {
width: max-content;
min-width: 100%;
will-change: transform;
}
.objectKanbanHeaderRow {
width: max-content;
min-width: 100%;
align-items: flex-start;
}
.objectKanbanHeaderCell {
flex: 0 0 360px;
min-width: 360px;
flex-shrink: 0;
padding: 8px 8px;
border: 1px solid var(--ant-color-border-secondary);
border-bottom: 1px solid var(--color-descriptions-border);
border-radius: 12px 12px 0 0;
background-color: var(--layout-header-bg);
}
.objectKanban {
width: max-content;
min-width: 100%;
height: 100%;
min-height: 100%;
align-items: stretch;
padding-bottom: 4px;
}
.objectKanbanSkeletonColumns {
position: absolute;
inset: 0;
z-index: 0;
overflow: hidden;
pointer-events: none;
}
.objectKanbanSkeletonTrack {
width: max-content;
min-width: 100%;
height: 100%;
will-change: transform;
}
.objectKanbanSkeletonRow {
width: max-content;
min-width: 100%;
height: 100%;
align-items: stretch;
}
.objectKanbanColumn,
.objectKanbanColumnSkeleton {
flex: 0 0 360px;
min-width: 360px;
min-height: 0;
border-top: none;
border-radius: 0 0 12px 12px;
}
.objectKanbanColumnSkeleton {
border-radius: 0 0 12px 12px;
overflow: hidden;
}
.objectKanbanColumnCards {
flex: 1;
border-radius: 0 0 12px 12px;
height: 100%;
}
.objectKanbanColumnSkeleton .objectKanbanColumnCards {
background-color: var(--layout-header-bg);
}
.objectKanbanColumnCardsInner {
padding: 16px;
}
.electron-body .ant-modal-wrap,
@ -2732,253 +2544,3 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
height: 0;
pointer-events: none;
}
.list-view-tabs {
flex: 1;
min-width: 0;
}
.list-view-tabs .ant-input-sm {
border-radius: 0;
}
.list-view-tabs-spin {
flex: 1;
min-width: 0;
}
.list-view-tabs-spin > .ant-spin-container {
display: flex;
flex: 1;
min-width: 0;
}
.list-view-tabs-segmented-wrap {
flex: 1;
min-width: 0;
}
.list-view-tabs-segmented-wrap .simplebar-track.simplebar-vertical {
display: none;
}
.list-view-tabs-segmented-inner {
width: max-content;
}
.segmented-nav {
display: inline-flex;
width: max-content;
flex-shrink: 0;
padding: 0;
}
.segmented-nav-group {
position: relative;
display: flex;
align-items: center;
gap: 8px;
}
.segmented-nav-thumb {
position: absolute;
top: 0;
left: 0;
z-index: 0;
border-radius: 12px;
background: var(--color-button-background);
pointer-events: none;
will-change: transform, width;
transition:
transform 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.segmented-nav-item {
position: relative;
z-index: 1;
display: inline-flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 0;
border: 1px solid var(--color-list-view-tabs-border);
border-radius: 12px;
background: transparent;
cursor: pointer;
font-family: inherit;
font-size: inherit;
line-height: inherit;
color: inherit;
box-shadow: none;
outline: none;
transition:
background 0.2s ease,
border 0.2s ease;
}
.segmented-nav-item-label {
position: relative;
z-index: 1;
display: flex;
align-items: center;
min-height: 30px;
line-height: 30px;
padding-inline: 12px;
}
.segmented-nav-item-icon {
padding-inline: 8px;
min-width: 32px;
}
.segmented-nav-item-icon-contents {
position: relative;
z-index: 1;
display: flex;
align-items: center;
min-height: 30px;
line-height: 30px;
}
.segmented-nav-item:focus-visible {
outline: 2px solid
color-mix(in srgb, var(--color-primary, #1677ff) 45%, transparent);
outline-offset: 2px;
}
.segmented-nav-item-selected,
.segmented-nav-item:not(.segmented-nav-item-disabled):hover {
background: var(--color-button-background);
border: 1px solid
color-mix(
in srgb,
var(--color-button-border) 40%,
var(--color-button-background)
);
}
.segmented-nav-item-disabled {
cursor: not-allowed;
opacity: 0.45;
}
.segmented-nav-disabled .segmented-nav-item {
cursor: not-allowed;
}
.list-view-tabs-label {
height: 30px;
}
.list-view-tabs-label-editing .ant-input {
font-size: inherit;
}
.list-view-tabs-label-editing {
margin: 0px -8px;
max-width: none;
min-width: 0;
}
.list-view-tabs-label-editing .list-view-tabs-name-input-wrap {
flex: 0 0 auto;
width: auto;
}
.list-view-tabs-name-input-wrap {
display: inline-block;
position: relative;
vertical-align: top;
min-width: 0;
}
.list-view-tabs-name-input-sizer {
visibility: hidden;
white-space: pre;
font-size: inherit;
line-height: inherit;
font-family: inherit;
min-height: 1em;
}
.list-view-tabs-label-editing .list-view-tabs-name-input {
position: absolute;
inset: 0;
width: 100%;
min-width: 0;
padding-inline: 0;
}
.list-view-tabs-color-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.list-view-tabs-editing
.segmented-nav-item
.ant-color-picker-trigger.ant-color-picker-sm {
border-radius: 8px;
}
.list-view-tabs-privacy-button,
.list-view-tabs-options-button {
padding-inline: 4px;
min-width: 20px;
}
.list-view-tabs-options-dropdown {
display: flex;
flex-direction: column;
}
.list-view-tabs-options-dropdown-privacy {
margin: 3px 12px 14px 16px;
}
.segmented-nav-drag-handle {
flex-shrink: 0;
}
.segmented-nav-item-dragging {
opacity: 0.4;
}
.segmented-nav-item-drop-before::before,
.segmented-nav-item-drop-after::after {
content: '';
position: absolute;
top: 4px;
bottom: 4px;
width: 2px;
border-radius: 1px;
background: var(--color-primary, #1677ff);
pointer-events: none;
}
.segmented-nav-item-drop-before::before {
left: -5px;
}
.segmented-nav-item-drop-after::after {
right: -5px;
}
.segmented-nav-reordering
.segmented-nav-item:not(.segmented-nav-item-dragging) {
cursor: default;
}
.list-view-tabs-add-button {
padding-inline: 4px;
min-width: 20px;
}
.state-tag-loading svg path {
stroke: currentColor;
stroke-width: 12px;
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Invoices = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('invoices')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('invoices')
@ -28,13 +28,10 @@ const Invoices = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='invoice'
pageName='list'
@ -48,8 +45,7 @@ const Invoices = () => {
/>
<ExportListButton objectType='invoice' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const Invoices = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='invoice'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='invoice'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const Invoices = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const PaymentPolicies = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('paymentPolicy')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('paymentPolicy')
const [showFilterSidebar, setShowFilterSidebar] =
@ -24,13 +23,9 @@ const PaymentPolicies = () => {
useSortSidebarVisibility('PaymentPolicies')
return (
<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'>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='paymentPolicy'
pageName='list'
@ -44,8 +39,7 @@ const PaymentPolicies = () => {
/>
<ExportListButton objectType='paymentPolicy' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -55,16 +49,17 @@ const PaymentPolicies = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='paymentPolicy'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='paymentPolicy'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -77,8 +72,7 @@ const PaymentPolicies = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Payments = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('payments')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('payments')
@ -28,13 +28,10 @@ const Payments = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='payment'
pageName='list'
@ -48,8 +45,7 @@ const Payments = () => {
/>
<ExportListButton objectType='payment' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const Payments = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='payment'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='payment'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const Payments = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const TaxRecords = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('taxRecord')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('taxRecord')
@ -28,13 +28,10 @@ const TaxRecords = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='taxRecord'
pageName='list'
@ -48,8 +45,7 @@ const TaxRecords = () => {
/>
<ExportListButton objectType='taxRecord' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const TaxRecords = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='taxRecord'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='taxRecord'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const TaxRecords = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -10,17 +10,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const FilamentStocks = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('filamentStocks')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('filamentStocks')
@ -32,13 +33,10 @@ const FilamentStocks = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='filamentStock'
pageName='list'
@ -52,8 +50,7 @@ const FilamentStocks = () => {
/>
<ExportListButton objectType='filamentStock' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -63,15 +60,18 @@ const FilamentStocks = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='filamentStock'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='filamentStock'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -83,10 +83,9 @@ const FilamentStocks = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const OrderItems = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('orderItems')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('orderItems')
@ -28,13 +28,10 @@ const OrderItems = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='orderItem'
pageName='list'
@ -48,8 +45,7 @@ const OrderItems = () => {
/>
<ExportListButton objectType='orderItem' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const OrderItems = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='orderItem'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='orderItem'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const OrderItems = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -10,17 +10,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const PartStocks = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('partStocks')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('partStocks')
@ -32,13 +33,10 @@ const PartStocks = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='partStock'
pageName='list'
@ -52,8 +50,7 @@ const PartStocks = () => {
/>
<ExportListButton objectType='partStock' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -63,15 +60,18 @@ const PartStocks = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='partStock'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='partStock'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -83,10 +83,9 @@ const PartStocks = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -11,17 +11,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const ProductStocks = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('productStocks')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('productStock')
@ -33,13 +34,10 @@ const ProductStocks = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='productStock'
pageName='list'
@ -53,8 +51,7 @@ const ProductStocks = () => {
/>
<ExportListButton objectType='productStock' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -64,15 +61,18 @@ const ProductStocks = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='productStock'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='productStock'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -84,10 +84,9 @@ const ProductStocks = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const PurchaseOrders = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('purchaseOrders')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('purchaseOrders')
@ -28,13 +28,10 @@ const PurchaseOrders = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='purchaseOrder'
pageName='list'
@ -48,8 +45,7 @@ const PurchaseOrders = () => {
/>
<ExportListButton objectType='purchaseOrder' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const PurchaseOrders = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='purchaseOrder'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='purchaseOrder'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const PurchaseOrders = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Shipments = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('shipments')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('shipments')
@ -28,13 +28,10 @@ const Shipments = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='shipment'
pageName='list'
@ -48,8 +45,7 @@ const Shipments = () => {
/>
<ExportListButton objectType='shipment' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const Shipments = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='shipment'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='shipment'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const Shipments = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -10,17 +10,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const StockAudits = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('stockAudits')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockAudits')
@ -32,13 +33,10 @@ const StockAudits = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='stockAudit'
pageName='list'
@ -52,8 +50,7 @@ const StockAudits = () => {
/>
<ExportListButton objectType='stockAudit' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -63,15 +60,18 @@ const StockAudits = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='stockAudit'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='stockAudit'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -83,10 +83,9 @@ const StockAudits = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const StockEvents = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('stockEvents')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockEvent')
@ -28,13 +27,10 @@ const StockEvents = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='stockEvent'
pageName='list'
@ -48,8 +44,7 @@ const StockEvents = () => {
/>
<ExportListButton objectType='stockEvent' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,15 +54,18 @@ const StockEvents = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='stockEvent'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='stockEvent'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -79,10 +77,9 @@ const StockEvents = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const StockLocations = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('stockLocations')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockLocation')
@ -30,13 +31,10 @@ const StockLocations = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='stockLocation'
pageName='list'
@ -50,8 +48,7 @@ const StockLocations = () => {
/>
<ExportListButton objectType='stockLocation' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,15 +58,18 @@ const StockLocations = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='stockLocation'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='stockLocation'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,10 +81,9 @@ const StockLocations = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const StockTransfers = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('stockTransfers')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockTransfer')
@ -30,13 +31,10 @@ const StockTransfers = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='stockTransfer'
pageName='list'
@ -50,8 +48,7 @@ const StockTransfers = () => {
/>
<ExportListButton objectType='stockTransfer' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,15 +58,18 @@ const StockTransfers = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='stockTransfer'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='stockTransfer'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,10 +81,9 @@ const StockTransfers = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -7,15 +7,15 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const AppPasswords = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('appPassword')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('appPassword')
@ -27,13 +27,10 @@ const AppPasswords = () => {
return (
<ObjectListViewProvider
objectType='appPassword'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='appPassword'
pageName='list'
@ -47,8 +44,7 @@ const AppPasswords = () => {
/>
<ExportListButton objectType='appPassword' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,14 +54,17 @@ const AppPasswords = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='appPassword'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='appPassword'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -78,10 +77,10 @@ const AppPasswords = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -10,9 +10,6 @@ import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const AuditLogs = () => {
const tableRef = useRef()
@ -28,13 +25,10 @@ const AuditLogs = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='auditLog'
pageName='list'
@ -48,8 +42,7 @@ const AuditLogs = () => {
/>
<ExportListButton objectType='auditLog' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,9 +51,9 @@ const AuditLogs = () => {
active={showFilterSidebar}
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
@ -76,10 +69,9 @@ const AuditLogs = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const CourierServices = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('courierService')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('courierService')
@ -28,13 +28,10 @@ const CourierServices = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='courierService'
pageName='list'
@ -48,8 +45,7 @@ const CourierServices = () => {
/>
<ExportListButton objectType='courierService' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const CourierServices = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='courierService'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='courierService'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const CourierServices = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Couriers = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('courier')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('courier')
const [showFilterSidebar, setShowFilterSidebar] =
@ -27,13 +27,10 @@ const Couriers = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='courier'
pageName='list'
@ -47,8 +44,7 @@ const Couriers = () => {
/>
<ExportListButton objectType='courier' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +54,17 @@ const Couriers = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='courier'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='courier'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +77,8 @@ const Couriers = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const DocumentJobs = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('documentJob')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('documentJob')
@ -28,13 +28,10 @@ const DocumentJobs = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='documentJob'
pageName='list'
@ -48,8 +45,7 @@ const DocumentJobs = () => {
/>
<ExportListButton objectType='documentJob' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const DocumentJobs = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='documentJob'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='documentJob'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const DocumentJobs = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const DocumentPrinters = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('documentPrinter')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('documentPrinter')
@ -28,13 +27,10 @@ const DocumentPrinters = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='documentPrinter'
pageName='list'
@ -48,8 +44,7 @@ const DocumentPrinters = () => {
/>
<ExportListButton objectType='documentPrinter' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +54,17 @@ const DocumentPrinters = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='documentPrinter'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='documentPrinter'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +77,8 @@ const DocumentPrinters = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const DocumentSizes = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('documentSize')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('documentSize')
@ -27,13 +26,10 @@ const DocumentSizes = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='documentSize'
pageName='list'
@ -47,8 +43,7 @@ const DocumentSizes = () => {
/>
<ExportListButton objectType='documentSize' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +53,17 @@ const DocumentSizes = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='documentSize'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='documentSize'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +76,8 @@ const DocumentSizes = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const DocumentTemplates = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('documentTemplate')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('documentTemplate')
@ -28,13 +28,10 @@ const DocumentTemplates = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='documentTemplate'
pageName='list'
@ -48,8 +45,7 @@ const DocumentTemplates = () => {
/>
<ExportListButton objectType='documentTemplate' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const DocumentTemplates = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='documentTemplate'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='documentTemplate'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const DocumentTemplates = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const FilamentSkus = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('filamentSkus')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('filamentSku')
@ -30,13 +31,10 @@ const FilamentSkus = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='filamentSku'
pageName='list'
@ -50,8 +48,7 @@ const FilamentSkus = () => {
/>
<ExportListButton objectType='filamentSku' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,15 +58,18 @@ const FilamentSkus = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='filamentSku'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='filamentSku'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,10 +81,9 @@ const FilamentSkus = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,13 +8,11 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ObjectTable from '../common/ObjectTable'
import ObjectActions from '../common/ObjectActions'
import useViewMode from '../hooks/useViewMode'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
@ -22,6 +20,7 @@ const Filaments = () => {
const tableRef = useRef()
// View mode state (cards/list), persisted in sessionStorage via custom hook
const [viewMode, setViewMode] = useViewMode('filament')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('filament')
@ -34,13 +33,10 @@ const Filaments = () => {
return (
<ObjectListViewProvider
objectType='filament'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='filament'
pageName='list'
@ -54,8 +50,7 @@ const Filaments = () => {
/>
<ExportListButton objectType='filament' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -65,14 +60,17 @@ const Filaments = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='filament'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='filament'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -85,10 +83,10 @@ const Filaments = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Files = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('file')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('file')
const [showFilterSidebar, setShowFilterSidebar] =
@ -25,13 +25,11 @@ const Files = () => {
const [showSortSidebar, setShowSortSidebar] =
useSortSidebarVisibility('Files')
return (
<ObjectListViewProvider
objectType='file'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='file'
@ -46,7 +44,6 @@ const Files = () => {
/>
<ExportListButton objectType='file' />
</Space>
<ListViewTabs />
<Space>
<SortSidebarButton
active={showSortSidebar}
@ -57,15 +54,17 @@ const Files = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='file'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='file'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -79,7 +78,7 @@ const Files = () => {
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</>
)
}

View File

@ -7,11 +7,9 @@ import { Flex, Space } from 'antd'
import useColumnVisibility from '../hooks/useColumnVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
import ObjectTable from '../common/ObjectTable'
import ObjectActions from '../common/ObjectActions'
import useViewMode from '../hooks/useViewMode'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
@ -22,6 +20,7 @@ const Hosts = () => {
const tableRef = useRef()
// View mode state (cards/list), persisted in sessionStorage via custom hook
const [viewMode, setViewMode] = useViewMode('host')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('host')
@ -33,13 +32,10 @@ const Hosts = () => {
return (
<ObjectListViewProvider
objectType='host'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='host'
pageName='list'
@ -53,8 +49,7 @@ const Hosts = () => {
/>
<ExportListButton objectType='host' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -64,14 +59,17 @@ const Hosts = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='host'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='host'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -84,10 +82,10 @@ const Hosts = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -9,16 +9,16 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Materials = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('material')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('material')
@ -30,13 +30,10 @@ const Materials = () => {
return (
<ObjectListViewProvider
objectType='material'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='material'
pageName='list'
@ -50,8 +47,7 @@ const Materials = () => {
/>
<ExportListButton objectType='material' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,14 +57,17 @@ const Materials = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='material'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='material'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -81,10 +80,10 @@ const Materials = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const NoteTypes = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('noteType')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('noteType')
@ -28,13 +28,10 @@ const NoteTypes = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='noteType'
pageName='list'
@ -48,8 +45,7 @@ const NoteTypes = () => {
/>
<ExportListButton objectType='noteType' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const NoteTypes = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='noteType'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='noteType'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const NoteTypes = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const PartSkus = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('partSkus')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('partSku')
const [showFilterSidebar, setShowFilterSidebar] =
@ -29,13 +30,10 @@ const PartSkus = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='partSku'
pageName='list'
@ -49,8 +47,7 @@ const PartSkus = () => {
/>
<ExportListButton objectType='partSku' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -60,15 +57,18 @@ const PartSkus = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='partSku'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='partSku'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,10 +80,9 @@ const PartSkus = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -9,6 +9,7 @@ import ObjectActions from '../common/ObjectActions'
import useColumnVisibility from '../hooks/useColumnVisibility'
import useViewMode from '../hooks/useViewMode'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
@ -17,12 +18,10 @@ import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Parts = (filter) => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('part')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('part')
const [showFilterSidebar, setShowFilterSidebar] =
@ -33,13 +32,10 @@ const Parts = (filter) => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='part'
pageName='list'
@ -53,8 +49,7 @@ const Parts = (filter) => {
/>
<ExportListButton objectType='part' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -64,16 +59,17 @@ const Parts = (filter) => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='part'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='part'
cards={viewMode === 'cards'}
filter={filter}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -87,8 +83,8 @@ const Parts = (filter) => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const PermissionSettingsList = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('permissionSetting')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('permissionSetting')
@ -28,13 +28,10 @@ const PermissionSettingsList = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='permissionSetting'
pageName='list'
@ -48,8 +45,7 @@ const PermissionSettingsList = () => {
/>
<ExportListButton objectType='permissionSetting' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const PermissionSettingsList = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='permissionSetting'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='permissionSetting'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const PermissionSettingsList = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -9,16 +9,16 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const ProductCategories = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('productCategory')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('productCategory')
@ -30,13 +30,10 @@ const ProductCategories = () => {
return (
<ObjectListViewProvider
objectType='productCategory'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='productCategory'
pageName='list'
@ -50,8 +47,7 @@ const ProductCategories = () => {
/>
<ExportListButton objectType='productCategory' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,14 +57,17 @@ const ProductCategories = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='productCategory'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='productCategory'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -81,10 +80,10 @@ const ProductCategories = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,18 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const ProductSkus = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('productSkus')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('productSku')
@ -30,13 +31,10 @@ const ProductSkus = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='productSku'
pageName='list'
@ -50,8 +48,7 @@ const ProductSkus = () => {
/>
<ExportListButton objectType='productSku' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -61,15 +58,18 @@ const ProductSkus = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='productSku'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='productSku'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,10 +81,9 @@ const ProductSkus = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -25,17 +25,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Products = () => {
const navigate = useNavigate()
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('Products')
const getProductActionItems = (id) => {
return {
items: [
@ -302,13 +302,10 @@ const Products = () => {
}
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='product'
pageName='list'
@ -323,8 +320,7 @@ const Products = () => {
<Button>View</Button>
</Popover>
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -334,15 +330,16 @@ const Products = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='product'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type={'product'}
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -355,8 +352,8 @@ const Products = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const StockAuditLevels = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('stockAuditLevel')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('stockAuditLevel')
@ -27,13 +27,9 @@ const StockAuditLevels = () => {
useSortSidebarVisibility('StockAuditLevels')
return (
<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'>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='stockAuditLevel'
pageName='list'
@ -47,8 +43,7 @@ const StockAuditLevels = () => {
/>
<ExportListButton objectType='stockAuditLevel' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +53,17 @@ const StockAuditLevels = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='stockAuditLevel'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='stockAuditLevel'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +76,7 @@ const StockAuditLevels = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const TaxRates = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('taxRate')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('taxRate')
const [showFilterSidebar, setShowFilterSidebar] =
@ -27,13 +27,10 @@ const TaxRates = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='taxRate'
pageName='list'
@ -47,8 +44,7 @@ const TaxRates = () => {
/>
<ExportListButton objectType='taxRate' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +54,17 @@ const TaxRates = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='taxRate'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='taxRate'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +77,8 @@ const TaxRates = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const UserGroups = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('userGroup')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('userGroup')
const [showFilterSidebar, setShowFilterSidebar] =
@ -27,13 +27,10 @@ const UserGroups = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='userGroup'
pageName='list'
@ -47,8 +44,7 @@ const UserGroups = () => {
/>
<ExportListButton objectType='userGroup' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +54,17 @@ const UserGroups = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='userGroup'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='userGroup'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +77,8 @@ const UserGroups = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Users = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('user')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('user')
const [showFilterSidebar, setShowFilterSidebar] =
@ -27,13 +27,9 @@ const Users = () => {
return (
<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'>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='user'
pageName='list'
@ -47,8 +43,7 @@ const Users = () => {
/>
<ExportListButton objectType='user' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +53,16 @@ const Users = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='user'
viewMode={viewMode}
setViewMode={setViewMode}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type={'user'}
visibleColumns={columnVisibility}
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +75,7 @@ const Users = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Vendors = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('vendor')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('vendor')
const [showFilterSidebar, setShowFilterSidebar] =
@ -25,13 +25,11 @@ const Vendors = () => {
const [showSortSidebar, setShowSortSidebar] =
useSortSidebarVisibility('Vendors')
return (
<ObjectListViewProvider
objectType='vendor'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='vendor'
@ -46,7 +44,6 @@ const Vendors = () => {
/>
<ExportListButton objectType='vendor' />
</Space>
<ListViewTabs />
<Space>
<SortSidebarButton
active={showSortSidebar}
@ -57,15 +54,17 @@ const Vendors = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='vendor'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='vendor'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -79,7 +78,7 @@ const Vendors = () => {
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</>
)
}

View File

@ -2,9 +2,6 @@ import { useRef } from 'react'
import { Flex, Space } from 'antd'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import ObjectTable from '../common/ObjectTable'
@ -13,9 +10,11 @@ import ObjectTableViewButton from '../common/ObjectTableViewButton'
import useColumnVisibility from '../hooks/useColumnVisibility'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import useViewMode from '../hooks/useViewMode'
const FilamentProfiles = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('FilamentProfiles')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('filamentProfile')
const [showFilterSidebar, setShowFilterSidebar] =
@ -26,13 +25,10 @@ const FilamentProfiles = () => {
return (
<ObjectListViewProvider
objectType='filamentProfile'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='filamentProfile'
pageName='list'
@ -45,8 +41,7 @@ const FilamentProfiles = () => {
/>
<ExportListButton objectType='filamentProfile' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -56,14 +51,17 @@ const FilamentProfiles = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='filamentProfile'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='filamentProfile'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -76,10 +74,9 @@ const FilamentProfiles = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -8,17 +8,16 @@ import ObjectActions from '../common/ObjectActions'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const GCodeFiles = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('gcodeFile')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('gcodeFile')
@ -31,13 +30,10 @@ const GCodeFiles = () => {
return (
<ObjectListViewProvider
objectType='gcodeFile'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='gcodeFile'
pageName='list'
@ -51,8 +47,7 @@ const GCodeFiles = () => {
/>
<ExportListButton objectType='gcodeFile' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -62,15 +57,16 @@ const GCodeFiles = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='gcodeFile'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='gcodeFile'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -84,8 +80,8 @@ const GCodeFiles = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -5,6 +5,7 @@ import { Flex, Space } from 'antd'
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
import ObjectTable from '../common/ObjectTable.jsx'
import ObjectActions from '../common/ObjectActions'
import useViewMode from '../hooks/useViewMode.jsx'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
@ -12,12 +13,10 @@ import ColumnViewButton from '../common/ColumnViewButton.jsx'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility.jsx'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton.jsx'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Jobs = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('job')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('job')
@ -29,13 +28,10 @@ const Jobs = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='job'
pageName='list'
@ -49,8 +45,8 @@ const Jobs = () => {
/>
<ExportListButton objectType='job' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -60,15 +56,18 @@ const Jobs = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='job'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type={'job'}
visibleColumns={columnVisibility}
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,10 +79,9 @@ const Jobs = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -2,9 +2,6 @@ import { useRef } from 'react'
import { Flex, Space } from 'antd'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import ObjectTable from '../common/ObjectTable'
@ -13,8 +10,10 @@ import ObjectTableViewButton from '../common/ObjectTableViewButton'
import useColumnVisibility from '../hooks/useColumnVisibility'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import useViewMode from '../hooks/useViewMode'
const PrinterProfiles = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('PrinterProfiles')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('printerProfile')
const [showFilterSidebar, setShowFilterSidebar] =
@ -25,13 +24,10 @@ const PrinterProfiles = () => {
return (
<ObjectListViewProvider
objectType='printerProfile'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='printerProfile'
pageName='list'
@ -44,8 +40,7 @@ const PrinterProfiles = () => {
/>
<ExportListButton objectType='printerProfile' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -55,14 +50,17 @@ const PrinterProfiles = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='printerProfile'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='printerProfile'
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
@ -75,10 +73,9 @@ const PrinterProfiles = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,13 +6,11 @@ import ObjectTable from '../common/ObjectTable'
import ObjectActions from '../common/ObjectActions'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useColumnVisibility from '../hooks/useColumnVisibility'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
@ -21,6 +19,7 @@ const Printers = () => {
const tableRef = useRef()
// View mode state (cards/list), persisted in sessionStorage via custom hook
const [viewMode, setViewMode] = useViewMode('Printers')
// Column visibility state, persisted in sessionStorage via custom hook
const [columnVisibility, setColumnVisibility] = useColumnVisibility('printer')
@ -34,13 +33,10 @@ const Printers = () => {
return (
<ObjectListViewProvider
objectType='printer'
tableRef={tableRef}
>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify='space-between' style={{ minHeight: 0 }} gap='small'>
<Space>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space>
<ObjectActions
type='printer'
pageName='list'
@ -54,8 +50,7 @@ const Printers = () => {
/>
<ExportListButton objectType='printer' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -65,16 +60,19 @@ const Printers = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='printer'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type='printer'
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
cards={viewMode === 'cards'}
visibleColumns={columnVisibility}
expandHeight={true}
saveFilterInSession={true}
@ -85,10 +83,10 @@ const Printers = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -5,6 +5,7 @@ import { Flex, Space } from 'antd'
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
import ObjectTable from '../common/ObjectTable.jsx'
import ObjectActions from '../common/ObjectActions'
import useViewMode from '../hooks/useViewMode.jsx'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
@ -12,12 +13,10 @@ import ColumnViewButton from '../common/ColumnViewButton.jsx'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility.jsx'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ExportListButton from '../common/ExportListButton.jsx'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const SubJobs = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('subJob')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('subJob')
@ -29,13 +28,10 @@ const SubJobs = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='subJob'
pageName='list'
@ -49,8 +45,8 @@ const SubJobs = () => {
/>
<ExportListButton objectType='subJob' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -60,15 +56,18 @@ const SubJobs = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='subJob'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
type={'subJob'}
visibleColumns={columnVisibility}
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,10 +79,9 @@ const SubJobs = () => {
saveSortInUrl={true}
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Clients = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('client')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('client')
const [showFilterSidebar, setShowFilterSidebar] =
@ -27,13 +27,10 @@ const Clients = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='client'
pageName='list'
@ -47,8 +44,7 @@ const Clients = () => {
/>
<ExportListButton objectType='client' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -58,16 +54,17 @@ const Clients = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='client'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='client'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -80,8 +77,8 @@ const Clients = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const FulfillmentPolicies = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('fulfillmentPolicy')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('fulfillmentPolicy')
const [showFilterSidebar, setShowFilterSidebar] =
@ -24,13 +23,9 @@ const FulfillmentPolicies = () => {
useSortSidebarVisibility('FulfillmentPolicies')
return (
<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'>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='fulfillmentPolicy'
pageName='list'
@ -44,8 +39,7 @@ const FulfillmentPolicies = () => {
/>
<ExportListButton objectType='fulfillmentPolicy' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -55,16 +49,17 @@ const FulfillmentPolicies = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='fulfillmentPolicy'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='fulfillmentPolicy'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -77,8 +72,7 @@ const FulfillmentPolicies = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const ListingVarients = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('listingVarients')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('listingVarients')
@ -28,13 +28,10 @@ const ListingVarients = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='listingVarient'
pageName='list'
@ -48,8 +45,7 @@ const ListingVarients = () => {
/>
<ExportListButton objectType='listingVarient' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const ListingVarients = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='listingVarient'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='listingVarient'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const ListingVarients = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Listings = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('listings')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('listings')
@ -28,13 +28,10 @@ const Listings = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='listing'
pageName='list'
@ -48,8 +45,7 @@ const Listings = () => {
/>
<ExportListButton objectType='listing' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const Listings = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='listing'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='listing'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const Listings = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const Marketplaces = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('marketplaces')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('marketplaces')
@ -28,13 +28,10 @@ const Marketplaces = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='marketplace'
pageName='list'
@ -48,8 +45,7 @@ const Marketplaces = () => {
/>
<ExportListButton objectType='marketplace' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const Marketplaces = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='marketplace'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='marketplace'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const Marketplaces = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -6,16 +6,15 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const ReturnPolicies = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('returnPolicy')
const [columnVisibility, setColumnVisibility] = useColumnVisibility('returnPolicy')
const [showFilterSidebar, setShowFilterSidebar] =
useFilterSidebarVisibility('ReturnPolicies')
@ -23,13 +22,9 @@ const ReturnPolicies = () => {
useSortSidebarVisibility('ReturnPolicies')
return (
<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'>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='returnPolicy'
pageName='list'
@ -43,8 +38,7 @@ const ReturnPolicies = () => {
/>
<ExportListButton objectType='returnPolicy' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -54,16 +48,17 @@ const ReturnPolicies = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='returnPolicy'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='returnPolicy'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -76,8 +71,7 @@ const ReturnPolicies = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
)
}

View File

@ -6,17 +6,17 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTableViewButton from '../common/ObjectTableViewButton'
import FilterSidebarButton from '../common/FilterSidebarButton'
import SortSidebarButton from '../common/SortSidebarButton'
import useViewMode from '../hooks/useViewMode'
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
import ColumnViewButton from '../common/ColumnViewButton'
import ExportListButton from '../common/ExportListButton'
import ListViewTabs from '../common/ListViewTabs'
import ListViewEditButtons from '../common/ListViewEditButtons'
import { ObjectListViewProvider } from '../context/ObjectListViewContext'
const SalesOrders = () => {
const tableRef = useRef()
const [viewMode, setViewMode] = useViewMode('salesOrders')
const [columnVisibility, setColumnVisibility] =
useColumnVisibility('salesOrders')
@ -28,13 +28,10 @@ const SalesOrders = () => {
return (
<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'>
<>
<Flex vertical={'true'} gap='large' className='h-100'>
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
<Space size='small'>
<ObjectActions
type='salesOrder'
pageName='list'
@ -48,8 +45,7 @@ const SalesOrders = () => {
/>
<ExportListButton objectType='salesOrder' />
</Space>
<ListViewTabs />
<Space>
<Space>
<SortSidebarButton
active={showSortSidebar}
onClick={() => setShowSortSidebar(!showSortSidebar)}
@ -59,16 +55,17 @@ const SalesOrders = () => {
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
/>
<ObjectTableViewButton
objectType='salesOrder'
viewMode={viewMode}
setViewMode={setViewMode}
showEndingDivider={true}
/>
<ListViewEditButtons showStartingDivider={true} />
</Space>
</Flex>
</Flex>
<ObjectTable
ref={tableRef}
visibleColumns={columnVisibility}
type='salesOrder'
cards={viewMode === 'cards'}
showFilterSidebar={showFilterSidebar}
showSortSidebar={showSortSidebar}
expandHeight={true}
@ -81,8 +78,8 @@ const SalesOrders = () => {
useSortInSession={true}
useSortInUrl={true}
/>
</Flex>
</ObjectListViewProvider>
</Flex>
</>
)
}

View File

@ -2,16 +2,7 @@ import { useState, useEffect } from 'react'
import { ColorPicker, Checkbox, Flex, Row, Col, Divider } from 'antd'
import PropTypes from 'prop-types'
const ColorSelector = ({
value,
onChange,
disabled,
required = false,
size,
showText = true,
className,
onClick
}) => {
const ColorSelector = ({ value, onChange, disabled, required = false }) => {
// Determine initial enabled state based on value
const [colorEnabled, setColorEnabled] = useState(!!value)
@ -106,24 +97,18 @@ const ColorSelector = ({
]
return (
<Flex gap={showText ? 'middle' : 0} align='center'>
<Flex gap={'middle'}>
<ColorPicker
size={size}
showText={showText}
showText
disabledAlpha
style={
showText
? { width: '100%', justifyContent: 'start' }
: undefined
}
style={{ width: '100%', justifyContent: 'start' }}
disabled={(!colorEnabled && !required) || disabled}
value={value || '#000000'}
onChange={handleColorChange}
onClick={onClick}
presets={presets}
panelRender={customPanelRender}
arrow={false}
className={className ?? (showText ? 'ant-input-outlined' : undefined)}
className='ant-input-outlined'
/>
{!required && (
<Checkbox
@ -140,11 +125,7 @@ ColorSelector.propTypes = {
value: PropTypes.string,
onChange: PropTypes.func,
disabled: PropTypes.bool,
required: PropTypes.bool,
size: PropTypes.string,
showText: PropTypes.bool,
className: PropTypes.string,
onClick: PropTypes.func
required: PropTypes.bool
}
export default ColorSelector

View File

@ -28,7 +28,7 @@ const mainSections = ['production', 'inventory', 'management', 'developer']
const DashboardBreadcrumb = () => {
const location = useLocation()
const navigate = useNavigate()
const { hasPageFilter, hasStoredFilter, getObjectListView } = useTableState()
const { hasPageFilter, hasStoredFilter } = useTableState()
const pathSnippets = location.pathname.split('/').filter((i) => i)
function segmentToModel(segment) {
@ -45,15 +45,7 @@ const DashboardBreadcrumb = () => {
const isMainSection = mainSections.includes(segment)
const model = segmentToModel(segment)
const modelLabelPlural = model?.labelPlural ? model.labelPlural : null
const viewName =
modelLabelPlural && model?.name && model.name !== 'unknown'
? getObjectListView(model.name)?.name
: null
const name = breadcrumbNameMap[segment] || modelLabelPlural || segment
const displayName =
modelLabelPlural && viewName
? `${modelLabelPlural} - ${viewName}`
: name
const showFilterIcon =
hasPageFilter(url) ||
(model?.name && model.name !== 'unknown' && hasStoredFilter(model.name))
@ -61,7 +53,7 @@ const DashboardBreadcrumb = () => {
return {
title: (
<span style={{ padding: '0 12px' }} key={segment}>
{displayName}
{name}
</span>
),
key: segment
@ -79,7 +71,7 @@ const DashboardBreadcrumb = () => {
gap: 6
}}
>
{displayName}
{name}
{showFilterIcon && <FilterIcon style={{ fontSize: 12 }} />}
</Link>
),

View File

@ -1027,7 +1027,7 @@ const FilterInput = ({
}
}, [])
const showPlaceholder = Boolean(placeholder) && !internalValue
const showPlaceholder = !internalValue && !focused
const showClear = allowClear && !!internalValue && !disabled
const affixCls = `${prefixCls}-affix-wrapper`
@ -1076,7 +1076,6 @@ const FilterInput = ({
className={classNames(prefixCls, 'filter-input-editor')}
role='textbox'
aria-multiline='false'
aria-placeholder={showPlaceholder ? placeholder : undefined}
aria-disabled={disabled || undefined}
contentEditable={!disabled}
suppressContentEditableWarning

View File

@ -1,41 +0,0 @@
import PropTypes from 'prop-types'
import { Divider, Flex } from 'antd'
import EditButtons from './EditButtons'
import { useObjectListView } from '../context/ObjectListViewContext'
const ListViewEditButtons = ({ showStartingDivider = false }) => {
const {
isEditing,
initialLoading,
saving,
saveEdits,
cancelEdits,
startEditing
} = useObjectListView()
return (
<Flex align='center' gap='small'>
{showStartingDivider && (
<Divider type='vertical' style={{ margin: '0 4px', height: '18px' }} />
)}
<EditButtons
isEditing={isEditing}
handleUpdate={async () => {
await saveEdits()
}}
cancelEditing={cancelEdits}
startEditing={startEditing}
formValid={true}
disabled={initialLoading}
loading={saving}
requirePermission={false}
/>
</Flex>
)
}
ListViewEditButtons.propTypes = {
showStartingDivider: PropTypes.bool
}
export default ListViewEditButtons

View File

@ -1,320 +0,0 @@
import PropTypes from 'prop-types'
import React, { useEffect, useMemo, useState } from 'react'
import {
Input,
Dropdown,
Checkbox,
Button,
Flex,
Typography,
Divider,
theme
} from 'antd'
const { useToken } = theme
import SegmentedNav, { SegmentedNavDragHandle } from './SegmentedNav'
import { CaretDownFilled, LoadingOutlined } from '@ant-design/icons'
import { getModelByName } from '../../../database/ObjectModels'
import { useObjectListView } from '../context/ObjectListViewContext'
import classNames from 'classnames'
import PlusIcon from '../../Icons/PlusIcon'
import BinIcon from '../../Icons/BinIcon'
import ScrollBox from './ScrollBox'
import ColorSelector from './ColorSelector'
const { Text } = Typography
const ViewColorDot = ({ color }) => (
<span
className='list-view-tabs-color-dot'
style={{ backgroundColor: color || '#3498DB' }}
/>
)
ViewColorDot.propTypes = {
color: PropTypes.string
}
const ViewOptionsDropdown = ({ view, isEditing, onChange, onDelete }) => {
const menu = {
items: [
{
key: 'delete',
label: 'Delete',
icon: <BinIcon />,
danger: true,
onClick: ({ domEvent }) => {
domEvent.stopPropagation()
onDelete?.()
}
},
{ type: 'divider' }
]
}
const menuStyle = {
boxShadow: 'none'
}
const { token } = useToken()
const contentStyle = {
backgroundColor: token.colorBgElevated,
borderRadius: token.borderRadiusLG,
boxShadow: token.boxShadowSecondary
}
return (
<Dropdown
menu={menu}
trigger={['hover']}
placement='bottomLeft'
popupRender={(menu) => (
<div className='list-view-tabs-options-dropdown' style={contentStyle}>
{React.cloneElement(menu, { style: menuStyle })}
<Flex
vertical
gap='middle'
className='list-view-tabs-options-dropdown-privacy'
>
<Checkbox
checked={view.private !== false}
disabled={!isEditing}
onChange={(event) => onChange({ private: event.target.checked })}
onClick={(event) => event.stopPropagation()}
>
Private
</Checkbox>
</Flex>
</div>
)}
>
<Button
type='text'
size='small'
className='list-view-tabs-options-button'
icon={<CaretDownFilled style={{ fontSize: 14, marginTop: 4 }} />}
disabled={!isEditing}
onClick={(event) => event.stopPropagation()}
/>
</Dropdown>
)
}
ViewOptionsDropdown.propTypes = {
view: PropTypes.object.isRequired,
isEditing: PropTypes.bool.isRequired,
onChange: PropTypes.func.isRequired,
onDelete: PropTypes.func
}
const ViewTabNameInput = ({ value, onClick, onChange }) => (
<span className='list-view-tabs-name-input-wrap'>
<span aria-hidden className='list-view-tabs-name-input-sizer'>
{value}
</span>
<Input
size='small'
variant='borderless'
className='list-view-tabs-name-input'
value={value}
onClick={onClick}
onChange={onChange}
/>
</span>
)
ViewTabNameInput.propTypes = {
value: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired
}
const ViewTabLabel = ({
view,
isEditing,
onDraftChange,
onRemove,
onSelect
}) => {
if (!isEditing) {
return (
<Flex align='center' gap={8} className='list-view-tabs-label'>
<ViewColorDot color={view.color} />
<Text ellipsis style={{ maxWidth: 160 }}>
{view.name}
</Text>
</Flex>
)
}
return (
<Flex
align='center'
gap={6}
className='list-view-tabs-label list-view-tabs-label-editing'
onFocusCapture={() => onSelect?.()}
>
<div style={{ marginRight: 2 }}>
<ColorSelector
size='small'
showText={false}
required
value={view.color || '#3498DB'}
onChange={(color) => onDraftChange({ color })}
onClick={(event) => event.stopPropagation()}
/>
</div>
<ViewTabNameInput
value={view.name}
onClick={(event) => event.stopPropagation()}
onChange={(event) => onDraftChange({ name: event.target.value })}
/>
<Flex align='center' gap={2}>
<ViewOptionsDropdown
view={view}
isEditing={isEditing}
onChange={onDraftChange}
onDelete={onRemove}
/>
<SegmentedNavDragHandle value={String(view._id)} />
</Flex>
</Flex>
)
}
ViewTabLabel.propTypes = {
view: PropTypes.object.isRequired,
isEditing: PropTypes.bool.isRequired,
onDraftChange: PropTypes.func.isRequired,
onRemove: PropTypes.func,
onSelect: PropTypes.func
}
const ListViewTabs = () => {
const {
objectType,
ALL_TAB_KEY,
views,
activeTabKey,
initialLoading,
isEditing,
selectTab,
handleTabEdit,
updateDraftView,
reorderDraftViews,
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(() => {
const Icon = initialLoading ? LoadingOutlined : model?.icon
const styles = initialLoading
? { fontSize: 12, color: 'var(--color-button-border)' }
: { fontSize: 14 }
const allOption = {
value: ALL_TAB_KEY,
icon: Icon ? (
<Icon
style={styles}
color={'secondary'}
spin={initialLoading || undefined}
/>
) : null
}
const viewOptions = views.map((view) => ({
value: String(view._id),
reorderable: isEditing,
label: (
<ViewTabLabel
view={view}
isEditing={isEditing}
onDraftChange={(changes) => updateDraftView(view._id, changes)}
onRemove={
isEditing
? () => handleTabEdit(String(view._id), 'remove')
: undefined
}
onSelect={() => {
const tabKey = String(view._id)
if (activeTabKey !== tabKey) {
selectTab(tabKey)
}
}}
/>
)
}))
return [allOption, ...viewOptions]
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
ALL_TAB_KEY,
activeTabKey,
handleTabEdit,
initialLoading,
isEditing,
model?.icon,
selectTab,
updateDraftView,
viewTabSignatures
])
return (
<Flex
align='center'
gap='small'
style={{ minHeight: 0, width: '100%', minWidth: 0 }}
>
<Divider type='vertical' style={{ margin: '0 4px', height: '18px' }} />
<Flex
align='center'
gap={4}
className={classNames('list-view-tabs', {
'list-view-tabs-editing': isEditing
})}
style={{ flex: 1, minWidth: 0 }}
>
<ScrollBox className='list-view-tabs-segmented-wrap' horizontal>
<Flex
align='center'
gap={8}
className='list-view-tabs-segmented-inner'
>
<SegmentedNav
className='list-view-tabs-segmented'
value={activeTabKey}
options={options}
onChange={selectTab}
onReorder={isEditing ? reorderDraftViews : undefined}
animated={animated}
/>
{isEditing && (
<Button
type='text'
size='small'
className='list-view-tabs-add-button'
onClick={() => handleTabEdit(null, 'add')}
icon={<PlusIcon style={{ fontSize: 14, marginTop: 3 }} />}
/>
)}
</Flex>
</ScrollBox>
</Flex>
</Flex>
)
}
export default ListViewTabs

View File

@ -1,426 +0,0 @@
import {
forwardRef,
useCallback,
useContext,
useImperativeHandle,
useLayoutEffect,
useMemo,
useRef,
useState
} from 'react'
import { Empty, Flex, Spin } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import ObjectCard from './ObjectCard'
import ObjectKanbanColumn from './ObjectKanbanColumn'
import ObjectKanbanHeader from './ObjectKanbanHeader'
import ScrollBox from './ScrollBox'
import { getCategoryValueKey } from './viewModeUtils'
const KANBAN_COLUMN_WIDTH = 360
const KANBAN_GAP = 16
const KANBAN_CARD_MIN_HEIGHT = 136
const getKanbanSkeletonLayout = (width, height) => {
const columnCount =
Math.max(
1,
Math.floor((width + KANBAN_GAP) / (KANBAN_COLUMN_WIDTH + KANBAN_GAP))
) + 1
const cardCount = Math.max(
1,
Math.floor((height - 32) / KANBAN_CARD_MIN_HEIGHT)
)
return { columnCount, cardCount }
}
const ObjectKanbanSkeletonColumns = ({
columnCount,
cardCount = 0,
trackRef,
model,
modelProperties,
visibleColumns,
keyPrefix = 'skeleton'
}) => (
<div className='objectKanbanSkeletonColumns objectKanbanSkeletonColumns--loading'>
<div className='objectKanbanSkeletonTrack' ref={trackRef}>
<Flex gap='middle' className='objectKanbanSkeletonRow'>
{Array.from({ length: columnCount }).map((_, columnIndex) => (
<div
key={`${keyPrefix}-${columnIndex}`}
className='objectKanbanColumnSkeleton'
>
<div className='objectKanbanColumnCards'>
{cardCount > 0 && (
<Flex
vertical
gap='middle'
className='objectKanbanColumnCardsInner'
>
{Array.from({ length: cardCount }).map((_, cardIndex) => (
<ObjectCard
key={cardIndex}
isSkeleton
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
record={{
_id: `${keyPrefix}-${columnIndex}-${cardIndex}`
}}
cardStyle='bordered'
/>
))}
</Flex>
)}
</div>
</div>
))}
</Flex>
</div>
</div>
)
ObjectKanbanSkeletonColumns.propTypes = {
columnCount: PropTypes.number.isRequired,
cardCount: PropTypes.number,
trackRef: PropTypes.object,
model: PropTypes.object.isRequired,
modelProperties: PropTypes.array.isRequired,
visibleColumns: PropTypes.object,
keyPrefix: PropTypes.string
}
const ObjectKanban = forwardRef(
(
{
type,
categoryProperty,
baseFilter = {},
masterFilter = {},
sorter = {},
pageSize = 25,
model,
modelProperties,
visibleColumns = {},
isEditing = false,
rowActions = [],
renderActions
},
ref
) => {
const { getModelPropertyValues } = useContext(ApiServerContext)
const columnRefs = useRef({})
const headerTrackRef = useRef(null)
const skeletonTrackRef = useRef(null)
const kanbanBodyRef = useRef(null)
const [scrollElement, setScrollElement] = useState(null)
const [categoryValues, setCategoryValues] = useState([])
const [hasLoaded, setHasLoaded] = useState(false)
const [loadedFilter, setLoadedFilter] = useState(baseFilter)
const [loadedSorter, setLoadedSorter] = useState(sorter)
const [skeletonLayout, setSkeletonLayout] = useState({
columnCount: 3,
cardCount: 3
})
const baseFilterRef = useRef(baseFilter)
const masterFilterRef = useRef(masterFilter)
const sorterRef = useRef(sorter)
const getModelPropertyValuesRef = useRef(getModelPropertyValues)
const lastCategoryQueryKeyRef = useRef(null)
const hasLoadedRef = useRef(false)
const loadGenerationRef = useRef(0)
baseFilterRef.current = baseFilter
masterFilterRef.current = masterFilter
sorterRef.current = sorter
getModelPropertyValuesRef.current = getModelPropertyValues
const setScrollContainerRef = useCallback((node) => {
setScrollElement(node)
}, [])
useLayoutEffect(() => {
const kanbanBody = kanbanBodyRef.current
if (!kanbanBody) return undefined
const updateLayout = () => {
const { width, height } = kanbanBody.getBoundingClientRect()
setSkeletonLayout(getKanbanSkeletonLayout(width, height))
}
updateLayout()
const observer = new ResizeObserver(updateLayout)
observer.observe(kanbanBody)
return () => observer.disconnect()
}, [categoryProperty])
useLayoutEffect(() => {
const mainScroll = scrollElement
const headerTrack = headerTrackRef.current
const skeletonTrack = skeletonTrackRef.current
if (!mainScroll || !headerTrack) return undefined
const handleMainScroll = () => {
const offset = `translate3d(-${mainScroll.scrollLeft}px, 0, 0)`
headerTrack.style.transform = offset
if (skeletonTrack) {
skeletonTrack.style.transform = offset
}
}
handleMainScroll()
mainScroll.addEventListener('scroll', handleMainScroll, { passive: true })
return () => {
mainScroll.removeEventListener('scroll', handleMainScroll)
}
}, [scrollElement, categoryValues])
const categoryPropertyDef = useMemo(
() =>
model?.properties?.find(
(property) => property.name === categoryProperty
),
[categoryProperty, model]
)
const buildCategoryQueryKey = useCallback(
(filter, activeSorter) =>
JSON.stringify({
type,
categoryProperty,
filter,
masterFilter: masterFilterRef.current,
sorter: activeSorter
}),
[categoryProperty, type]
)
const reloadColumns = useCallback(async () => {
await Promise.all(
Object.values(columnRefs.current)
.filter(Boolean)
.map((columnRef) => columnRef.reload?.())
)
}, [])
const load = useCallback(
async (filter = null, sorterArg = null, options = {}) => {
const silent = options.silent === true
const generation = ++loadGenerationRef.current
if (!categoryProperty) {
lastCategoryQueryKeyRef.current = null
hasLoadedRef.current = true
setCategoryValues([])
setHasLoaded(true)
return
}
const activeFilter = filter ?? baseFilterRef.current
const activeSorter = sorterArg ?? sorterRef.current
const activeMasterFilter = masterFilterRef.current
const queryKey = buildCategoryQueryKey(activeFilter, activeSorter)
const canReuseColumns =
lastCategoryQueryKeyRef.current === queryKey && hasLoadedRef.current
if (canReuseColumns) {
await reloadColumns()
if (generation !== loadGenerationRef.current) return
hasLoadedRef.current = true
setHasLoaded(true)
return
}
// Filter/sort changes keep current columns visible; objectView /
// initial loads clear to skeleton + Spin.
if (!silent || !hasLoadedRef.current) {
hasLoadedRef.current = false
setHasLoaded(false)
}
try {
const values = await getModelPropertyValuesRef.current(
type,
categoryProperty,
{
filter: activeFilter,
masterFilter: activeMasterFilter
}
)
if (generation !== loadGenerationRef.current) return
const nextValues = Array.isArray(values) ? values : []
lastCategoryQueryKeyRef.current = queryKey
hasLoadedRef.current = true
setLoadedFilter(activeFilter)
setLoadedSorter(activeSorter)
setCategoryValues(nextValues)
setHasLoaded(true)
} catch (error) {
if (generation !== loadGenerationRef.current) return
console.error('Error fetching kanban category values:', error)
lastCategoryQueryKeyRef.current = null
hasLoadedRef.current = true
setCategoryValues([])
setHasLoaded(true)
throw error
}
},
[buildCategoryQueryKey, categoryProperty, reloadColumns, type]
)
const reload = useCallback(async () => {
lastCategoryQueryKeyRef.current = null
hasLoadedRef.current = false
await load(baseFilterRef.current, sorterRef.current)
}, [load])
useImperativeHandle(
ref,
() => ({
load,
reload
}),
[load, reload]
)
if (!categoryProperty) {
return (
<Flex align='center' justify='center' style={{ height: '100%' }}>
<Empty description='Select a category property for kanban view' />
</Flex>
)
}
if (hasLoaded && categoryValues.length === 0) {
return (
<Flex align='center' justify='center' style={{ height: '100%' }}>
<Empty description='No category values found' />
</Flex>
)
}
const showSkeleton = !hasLoaded
return (
<div className='objectKanbanContainerWrapper'>
<Spin
indicator={<LoadingOutlined />}
spinning={showSkeleton}
style={{ height: '100%', flex: 1, minHeight: 0 }}
>
<div className='objectKanbanContainerSkeletons'>
<ObjectKanbanHeader
categoryValues={categoryValues}
categoryProperty={categoryProperty}
categoryPropertyDef={categoryPropertyDef}
trackRef={headerTrackRef}
skeletonColumnCount={
showSkeleton ? skeletonLayout.columnCount : 0
}
/>
<div className='objectKanbanKanbanBody' ref={kanbanBodyRef}>
{!showSkeleton && (
<div className='objectKanbanContainer'>
<ScrollBox
className='objectKanbanScroll'
scrollableNodeProps={{ ref: setScrollContainerRef }}
>
<Flex gap='middle' className='objectKanban'>
{categoryValues.map((categoryValue) => {
const columnKey = getCategoryValueKey(categoryValue)
return (
<ObjectKanbanColumn
key={columnKey}
ref={(node) => {
if (node) {
columnRefs.current[columnKey] = node
} else {
delete columnRefs.current[columnKey]
}
}}
scrollElement={scrollElement}
type={type}
categoryProperty={categoryProperty}
categoryValue={categoryValue}
baseFilter={loadedFilter}
masterFilter={masterFilter}
sorter={loadedSorter}
pageSize={pageSize}
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
isEditing={isEditing}
rowActions={rowActions}
renderActions={renderActions}
/>
)
})}
</Flex>
</ScrollBox>
</div>
)}
{showSkeleton ? (
<ObjectKanbanSkeletonColumns
columnCount={skeletonLayout.columnCount}
cardCount={skeletonLayout.cardCount}
trackRef={skeletonTrackRef}
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
/>
) : (
<div className='objectKanbanSkeletonColumns'>
<div
className='objectKanbanSkeletonTrack'
ref={skeletonTrackRef}
>
<Flex gap='middle' className='objectKanbanSkeletonRow'>
{categoryValues.map((categoryValue) => {
const columnKey = getCategoryValueKey(categoryValue)
return (
<div
key={columnKey}
className='objectKanbanColumnSkeleton'
>
<div className='objectKanbanColumnCards' />
</div>
)
})}
</Flex>
</div>
</div>
)}
</div>
</div>
</Spin>
</div>
)
}
)
ObjectKanban.displayName = 'ObjectKanban'
ObjectKanban.propTypes = {
type: PropTypes.string.isRequired,
categoryProperty: PropTypes.string,
baseFilter: PropTypes.object,
masterFilter: PropTypes.object,
sorter: PropTypes.object,
pageSize: PropTypes.number,
model: PropTypes.object.isRequired,
modelProperties: PropTypes.array.isRequired,
visibleColumns: PropTypes.object,
isEditing: PropTypes.bool,
rowActions: PropTypes.array,
renderActions: PropTypes.func
}
export default ObjectKanban

View File

@ -1,567 +0,0 @@
import {
forwardRef,
useCallback,
useContext,
useEffect,
useImperativeHandle,
useLayoutEffect,
useMemo,
useRef,
useState
} from 'react'
import { Flex, Spin } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import ObjectCard from './ObjectCard'
import { toCategoryFilterValue } from './viewModeUtils'
const SCROLL_THRESHOLD = 50
const ObjectKanbanColumn = forwardRef(
(
{
type,
categoryProperty,
categoryValue,
baseFilter = {},
masterFilter = {},
sorter = {},
pageSize = 25,
model,
modelProperties,
visibleColumns = {},
isEditing = false,
rowActions = [],
renderActions,
scrollElement = null
},
ref
) => {
const { fetchObjects } = useContext(ApiServerContext)
const containerRef = useRef(null)
const pagesRef = useRef([])
const loadingPagesRef = useRef(new Set())
const dataLoadGenerationRef = useRef(0)
const pendingScrollAnchorRef = useRef(null)
const lastColumnQueryKeyRef = useRef(null)
const baseFilterRef = useRef(baseFilter)
const masterFilterRef = useRef(masterFilter)
const sorterRef = useRef(sorter)
const fetchObjectsRef = useRef(fetchObjects)
baseFilterRef.current = baseFilter
masterFilterRef.current = masterFilter
sorterRef.current = sorter
fetchObjectsRef.current = fetchObjects
const [pages, setPages] = useState([])
const [loading, setLoading] = useState(true)
const columnFilter = useMemo(
() => ({
...baseFilter,
[categoryProperty]: toCategoryFilterValue(categoryValue)
}),
[baseFilter, categoryProperty, categoryValue]
)
const columnQueryKey = useMemo(
() =>
JSON.stringify({
type,
categoryProperty,
categoryValue: toCategoryFilterValue(categoryValue),
filter: columnFilter,
sorter
}),
[columnFilter, categoryProperty, categoryValue, sorter, type]
)
const tableData = useMemo(() => {
const items = pages.flatMap((page) => page.items)
const seen = new Set()
return items.filter((item) => {
const id = item?._id
if (id == null) return true
if (seen.has(id)) return false
seen.add(id)
return true
})
}, [pages])
const createSkeletonData = useCallback(
(pageNum) =>
Array(pageSize)
.fill(null)
.map((_, index) => ({
_id: `skeleton-${categoryProperty}-${pageNum}-${index}`,
isSkeleton: true
})),
[categoryProperty, pageSize]
)
const createSkeletonPage = useCallback(
(pageNum) => ({
pageNum,
items: createSkeletonData(pageNum),
isSkeletonPage: true
}),
[createSkeletonData]
)
const createPageWindow = useCallback(
(loadedPages, direction) => {
const dedupedByPageNum = new Map()
loadedPages.forEach((page) => {
dedupedByPageNum.set(page.pageNum, page)
})
const sortedPages = [...dedupedByPageNum.values()].sort(
(a, b) => a.pageNum - b.pageNum
)
const visiblePages =
direction === 'previous'
? sortedPages.slice(0, 2)
: sortedPages.slice(-2)
const firstPage = visiblePages[0]
const lastPage = visiblePages[visiblePages.length - 1]
const nextPages = []
if (firstPage?.pageNum > 1) {
nextPages.push(createSkeletonPage(firstPage.pageNum - 1))
}
nextPages.push(...visiblePages)
if (lastPage?.hasMore) {
nextPages.push(createSkeletonPage(lastPage.pageNum + 1))
}
return nextPages
},
[createSkeletonPage]
)
const mergeLoadedPage = useCallback((currentPages, loadedPage) => {
const withoutSkeletons = currentPages.filter(
(page) => !page.isSkeletonPage
)
const withoutDuplicate = withoutSkeletons.filter(
(page) => page.pageNum !== loadedPage.pageNum
)
return [...withoutDuplicate, loadedPage].sort(
(a, b) => a.pageNum - b.pageNum
)
}, [])
const setTablePages = useCallback((nextPages) => {
pagesRef.current = nextPages
setPages(nextPages)
}, [])
const isStaleDataLoad = useCallback(
(generation) => generation !== dataLoadGenerationRef.current,
[]
)
const fetchPage = useCallback(
async (pageNum, overrides = {}) => {
const filter = overrides.filter ?? {
...masterFilterRef.current,
...baseFilterRef.current,
[categoryProperty]: toCategoryFilterValue(categoryValue)
}
const sorter = overrides.sorter ?? sorterRef.current
return fetchObjectsRef.current(type, {
page: pageNum,
limit: pageSize,
filter,
sorter
})
},
[categoryProperty, categoryValue, pageSize, type]
)
const fetchData = useCallback(
async (pageNum) => {
const generation = dataLoadGenerationRef.current
try {
const result = await fetchPage(pageNum)
if (isStaleDataLoad(generation)) return []
const loadedPage = {
pageNum,
items: result.data || [],
hasMore: result.hasMore
}
setPages((prev) =>
prev.map((page) => (page.pageNum === pageNum ? loadedPage : page))
)
return result.data || []
} catch (error) {
console.error(`Error loading kanban page ${pageNum}:`, error)
return []
}
},
[fetchPage, isStaleDataLoad]
)
const findRenderedCard = useCallback((scrollTarget, id) => {
if (!scrollTarget || id == null) return null
return scrollTarget.querySelector(`[data-kanban-card-id="${String(id)}"]`)
}, [])
const captureScrollAnchor = useCallback(
(scrollTarget, placeholderPage, direction, currentPages) => {
if (!scrollTarget) return null
const targetTop = scrollTarget.getBoundingClientRect().top
const closestCard = (items) =>
items
.map((item, index) => {
const element = findRenderedCard(scrollTarget, item._id)
return element
? {
index,
id: item._id,
top: element.getBoundingClientRect().top
}
: null
})
.filter(Boolean)
.sort(
(a, b) =>
Math.abs(a.top - targetTop) - Math.abs(b.top - targetTop)
)[0]
const placeholderAnchor = closestCard(placeholderPage.items)
const loadedPages = currentPages.filter((page) => !page.isSkeletonPage)
const retainedPage =
direction === 'previous'
? loadedPages[0]
: loadedPages[loadedPages.length - 1]
const fallbackAnchor = retainedPage
? closestCard(retainedPage.items)
: null
return { placeholderAnchor, fallbackAnchor }
},
[findRenderedCard]
)
const restoreScrollAnchor = useCallback(
(scrollTarget, anchor, loadedPage) => {
if (!scrollTarget || !anchor) return
const loadedItem = loadedPage.items[anchor.placeholderAnchor?.index]
const anchorId = loadedItem?._id ?? anchor.fallbackAnchor?.id
const previousTop = loadedItem
? anchor.placeholderAnchor?.top
: anchor.fallbackAnchor?.top
if (anchorId == null || previousTop == null) return
const element = findRenderedCard(scrollTarget, anchorId)
if (!element) return
const renderedTop = element.getBoundingClientRect().top
scrollTarget.scrollTop += renderedTop - previousTop
},
[findRenderedCard]
)
useLayoutEffect(() => {
const pendingAnchor = pendingScrollAnchorRef.current
if (!pendingAnchor) return
pendingScrollAnchorRef.current = null
restoreScrollAnchor(
pendingAnchor.scrollTarget,
pendingAnchor.anchor,
pendingAnchor.loadedPage
)
}, [pages, restoreScrollAnchor])
const loadBoundaryPage = useCallback(
async (pageNum, direction, scrollTarget) => {
if (loadingPagesRef.current.size > 0) return
const currentPages = pagesRef.current
const placeholderPage = currentPages.find(
(page) => page.pageNum === pageNum && page.isSkeletonPage
)
if (!placeholderPage) return
const scrollAnchor = captureScrollAnchor(
scrollTarget,
placeholderPage,
direction,
currentPages
)
const generation = dataLoadGenerationRef.current
loadingPagesRef.current.add(pageNum)
try {
const result = await fetchPage(pageNum)
if (isStaleDataLoad(generation)) return
const loadedPage = {
pageNum,
items: result.data || [],
hasMore: result.hasMore
}
pendingScrollAnchorRef.current = {
scrollTarget,
anchor: scrollAnchor,
loadedPage
}
setPages((prev) => {
if (
!prev.some(
(page) => page.pageNum === pageNum && page.isSkeletonPage
)
) {
return prev
}
const loadedPages = mergeLoadedPage(prev, loadedPage)
return createPageWindow(loadedPages, direction)
})
} catch (error) {
console.error(`Error loading kanban page ${pageNum}:`, error)
} finally {
loadingPagesRef.current.delete(pageNum)
}
},
[
captureScrollAnchor,
createPageWindow,
fetchPage,
isStaleDataLoad,
mergeLoadedPage
]
)
const loadNextPage = useCallback(
(scrollTarget) => {
const nextPage = pagesRef.current[pagesRef.current.length - 1]
if (nextPage?.isSkeletonPage) {
loadBoundaryPage(nextPage.pageNum, 'next', scrollTarget)
}
},
[loadBoundaryPage]
)
const loadPreviousPage = useCallback(
(scrollTarget) => {
const previousPage = pagesRef.current[0]
if (previousPage?.isSkeletonPage) {
loadBoundaryPage(previousPage.pageNum, 'previous', scrollTarget)
}
},
[loadBoundaryPage]
)
const loadInitialPage = useCallback(async ({ silent = false } = {}) => {
dataLoadGenerationRef.current += 1
loadingPagesRef.current.clear()
pendingScrollAnchorRef.current = null
const generation = dataLoadGenerationRef.current
const filter = {
...masterFilterRef.current,
...baseFilterRef.current,
[categoryProperty]: toCategoryFilterValue(categoryValue)
}
const sorter = sorterRef.current
if (!silent) {
pagesRef.current = []
setPages([])
setLoading(true)
const skeletonPage = createSkeletonPage(1)
setTablePages([skeletonPage])
} else {
setLoading(false)
}
try {
const firstResult = await fetchPage(1, { filter, sorter })
if (isStaleDataLoad(generation)) return
const loadedPages = [
{
pageNum: 1,
items: firstResult.data || [],
hasMore: firstResult.hasMore
}
]
if (!isStaleDataLoad(generation)) {
setTablePages(createPageWindow(loadedPages, 'next'))
}
} catch {
if (!silent && !isStaleDataLoad(generation)) {
setTablePages([])
}
} finally {
if (!silent && !isStaleDataLoad(generation)) {
setLoading(false)
}
}
}, [
categoryProperty,
categoryValue,
createPageWindow,
createSkeletonPage,
fetchPage,
isStaleDataLoad,
setTablePages
])
const reloadLoadedPages = useCallback(async () => {
const loadedPages = pagesRef.current.filter(
(page) => !page.isSkeletonPage
)
for (let i = 0; i < loadedPages.length; i++) {
await fetchData(loadedPages[i].pageNum)
}
}, [fetchData])
useImperativeHandle(ref, () => ({
reload: reloadLoadedPages
}))
useEffect(() => {
if (lastColumnQueryKeyRef.current === columnQueryKey) return
// First mount shows skeleton; later filter/sort updates load silently.
const silent = lastColumnQueryKeyRef.current != null
let cancelled = false
const runLoad = async () => {
await loadInitialPage({ silent })
if (!cancelled) {
lastColumnQueryKeyRef.current = columnQueryKey
}
}
runLoad()
return () => {
cancelled = true
}
}, [columnQueryKey, loadInitialPage])
const skeletonBoundaryIds = useMemo(() => {
const firstPage = pages[0]
const lastPage = pages[pages.length - 1]
return {
previous:
firstPage?.isSkeletonPage && firstPage.items.length > 0
? firstPage.items[firstPage.items.length - 1]._id
: null,
next:
lastPage?.isSkeletonPage && lastPage.items[0]
? lastPage.items[0]._id
: null
}
}, [pages])
useLayoutEffect(() => {
const container = containerRef.current
if (!container || !scrollElement) return
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
if (!entry.isIntersecting) continue
const boundary = entry.target.dataset.skeletonBoundary
if (boundary === 'next') {
loadNextPage(scrollElement)
} else if (boundary === 'previous') {
loadPreviousPage(scrollElement)
}
}
},
{
root: scrollElement,
rootMargin: `${SCROLL_THRESHOLD}px`,
threshold: 0
}
)
container
.querySelectorAll('[data-skeleton-boundary]')
.forEach((el) => observer.observe(el))
return () => observer.disconnect()
}, [
scrollElement,
skeletonBoundaryIds,
loadNextPage,
loadPreviousPage,
tableData
])
return (
<Flex vertical className='objectKanbanColumn'>
<div className='objectKanbanColumnCards' ref={containerRef}>
<Spin indicator={<LoadingOutlined />} spinning={loading}>
<Flex
vertical
gap='middle'
className='objectKanbanColumnCardsInner'
>
{tableData.map((record) => {
if (record?._id == undefined) return null
const skeletonBoundary =
record._id === skeletonBoundaryIds.next
? 'next'
: record._id === skeletonBoundaryIds.previous
? 'previous'
: undefined
return (
<div
key={record._id}
data-kanban-card-id={record._id}
data-skeleton-boundary={skeletonBoundary}
>
<ObjectCard
isSkeleton={record?.isSkeleton || false}
model={model}
modelProperties={modelProperties}
visibleColumns={visibleColumns}
record={record}
isEditing={isEditing}
rowActions={rowActions}
renderActions={renderActions}
cardStyle='bordered'
/>
</div>
)
})}
</Flex>
</Spin>
</div>
</Flex>
)
}
)
ObjectKanbanColumn.displayName = 'ObjectKanbanColumn'
ObjectKanbanColumn.propTypes = {
type: PropTypes.string.isRequired,
categoryProperty: PropTypes.string.isRequired,
categoryValue: PropTypes.any,
baseFilter: PropTypes.object,
masterFilter: PropTypes.object,
sorter: PropTypes.object,
pageSize: PropTypes.number,
model: PropTypes.object.isRequired,
modelProperties: PropTypes.array.isRequired,
visibleColumns: PropTypes.object,
isEditing: PropTypes.bool,
rowActions: PropTypes.array,
renderActions: PropTypes.func,
scrollElement: PropTypes.object
}
export default ObjectKanbanColumn

View File

@ -1,63 +0,0 @@
import { Flex, Skeleton } from 'antd'
import PropTypes from 'prop-types'
import ObjectProperty from './ObjectProperty'
import { getCategoryValueKey } from './viewModeUtils'
const ObjectKanbanHeader = ({
categoryValues,
categoryProperty,
categoryPropertyDef,
trackRef,
skeletonColumnCount = 0
}) => {
const showSkeleton = skeletonColumnCount > 0
return (
<div className='objectKanbanHeader'>
<div className='objectKanbanHeaderTrack' ref={trackRef}>
<Flex gap='middle' className='objectKanbanHeaderRow'>
{showSkeleton
? Array.from({ length: skeletonColumnCount }).map((_, index) => (
<div
key={`skeleton-header-${index}`}
className='objectKanbanHeaderCell'
>
<Skeleton.Input
active
size='small'
style={{ width: '60%', height: 24 }}
/>
</div>
))
: categoryValues.map((categoryValue) => {
const columnKey = getCategoryValueKey(categoryValue)
return (
<div key={columnKey} className='objectKanbanHeaderCell'>
{categoryPropertyDef ? (
<ObjectProperty
{...categoryPropertyDef}
value={categoryValue}
objectData={{ [categoryProperty]: categoryValue }}
name={categoryProperty}
/>
) : null}
</div>
)
})}
</Flex>
</div>
</div>
)
}
ObjectKanbanHeader.displayName = 'ObjectKanbanHeader'
ObjectKanbanHeader.propTypes = {
categoryValues: PropTypes.array.isRequired,
categoryProperty: PropTypes.string.isRequired,
categoryPropertyDef: PropTypes.object,
trackRef: PropTypes.object,
skeletonColumnCount: PropTypes.number
}
export default ObjectKanbanHeader

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,6 @@ import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import {
getActiveFilterValues,
useTableState,
useTableStatePersistence
} from '../context/TableStateContext'
import KeyboardShortcut from './KeyboardShortcut.jsx'
@ -26,7 +25,6 @@ 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,
@ -36,12 +34,6 @@ 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
@ -59,21 +51,8 @@ const ObjectTableNavigationButtons = ({
const loadNeighbors = async () => {
setLoading(true)
// 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 filter = getActiveFilterValues(getPersistedFilterRef.current())
const sorter = getPersistedSorterRef.current()
const result = await getObjectNeighborsRef.current(objectType, {
id: _id,
filter,

View File

@ -1,188 +1,24 @@
import PropTypes from 'prop-types'
import { useContext, useMemo, useState } from 'react'
import ObjectListViewContext from '../context/ObjectListViewContext'
import {
Button,
Divider,
Flex,
Modal,
Popover,
Radio,
Select,
Typography
} from 'antd'
import { Button, Divider, Flex } from 'antd'
import GridIcon from '../../Icons/GridIcon'
import ListIcon from '../../Icons/ListIcon'
import KanbanIcon from '../../Icons/KanbanIcon'
import SettingsIcon from '../../Icons/SettingsIcon'
import { getModelByName } from '../../../database/ObjectModels'
import { getViewModeType, normalizeViewMode } from './viewModeUtils'
const VIEW_MODE_OPTIONS = [
{ type: 'list', label: 'List' },
{ type: 'cards', label: 'Cards' },
{ type: 'kanban', label: 'Kanban' }
]
const { Text } = Typography
const ObjectTableViewButton = ({
objectType,
viewMode: viewModeProp,
setViewMode: setViewModeProp,
viewMode,
setViewMode,
showEndingDivider = false,
...buttonProps
}) => {
const objectListView = useContext(ObjectListViewContext)
const viewMode = viewModeProp ?? objectListView?.viewMode
const setViewMode = setViewModeProp ?? objectListView?.setViewMode
const [settingsOpen, setSettingsOpen] = useState(false)
const normalizedViewMode = normalizeViewMode(viewMode)
const model = getModelByName(objectType)
const stateProperties = useMemo(
() =>
model?.properties?.filter((property) => property.type === 'state') || [],
[model]
)
const hasKanbanOption = stateProperties.length > 0
const defaultCategoryProperty = stateProperties[0]?.name
const availableViewModes = useMemo(
() =>
VIEW_MODE_OPTIONS.filter(
(option) => option.type !== 'kanban' || hasKanbanOption
).map((option) => option.type),
[hasKanbanOption]
)
const handleTypeChange = (nextType) => {
if (nextType === 'kanban') {
setViewMode({
type: 'kanban',
settings: {
categoryProperty:
normalizedViewMode.type === 'kanban'
? normalizedViewMode.settings?.categoryProperty ||
defaultCategoryProperty
: defaultCategoryProperty
}
})
return
}
setViewMode({ type: nextType })
}
const handleCategoryPropertyChange = (categoryProperty) => {
setViewMode({
type: 'kanban',
settings: { categoryProperty }
})
}
const { onClick: buttonOnClick, ...restButtonProps } = buttonProps
const handleCycleView = (event) => {
buttonOnClick?.(event)
const currentType = getViewModeType(normalizedViewMode)
const currentIndex = availableViewModes.indexOf(currentType)
const nextIndex =
currentIndex === -1 ? 0 : (currentIndex + 1) % availableViewModes.length
handleTypeChange(availableViewModes[nextIndex])
}
const activeIcon =
normalizedViewMode.type === 'cards' ? (
<GridIcon />
) : normalizedViewMode.type === 'kanban' ? (
<KanbanIcon />
) : (
<ListIcon />
)
const content = (
<>
<Popover
content={
<Flex vertical>
<Radio.Group
value={getViewModeType(normalizedViewMode)}
onChange={(e) => handleTypeChange(e.target.value)}
>
<Flex vertical gap='middle' style={{ margin: '4px 8px' }}>
{VIEW_MODE_OPTIONS.filter(
(option) => option.type !== 'kanban' || hasKanbanOption
).map((option) => (
<Radio key={option.type} value={option.type}>
<Flex
gap='8px'
align='center'
style={{ marginLeft: '4px' }}
>
<Text>{option.label}</Text>
{option.type === 'kanban' && (
<Button
type='text'
size='small'
icon={
<SettingsIcon
style={{ fontSize: '14px', marginTop: '2.5px' }}
/>
}
disabled={normalizedViewMode.type !== 'kanban'}
onClick={(event) => {
event.preventDefault()
event.stopPropagation()
setSettingsOpen(true)
}}
/>
)}
</Flex>
</Radio>
))}
</Flex>
</Radio.Group>
</Flex>
}
placement='bottomLeft'
arrow={false}
trigger='hover'
>
<Button
icon={activeIcon}
title='View mode'
onClick={handleCycleView}
{...restButtonProps}
/>
</Popover>
<Modal
title='Kanban settings'
open={settingsOpen}
onCancel={() => setSettingsOpen(false)}
onOk={() => setSettingsOpen(false)}
destroyOnClose
>
<Select
style={{ width: '100%' }}
placeholder='Select category property'
value={
normalizedViewMode.settings?.categoryProperty ||
defaultCategoryProperty
}
onChange={handleCategoryPropertyChange}
options={stateProperties.map((property) => ({
value: property.name,
label: property.label || property.name
}))}
/>
</Modal>
</>
<Button
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
onClick={() => setViewMode(viewMode === 'cards' ? 'list' : 'cards')}
title={
viewMode === 'cards' ? 'Switch to list view' : 'Switch to card view'
}
{...buttonProps}
/>
)
if (showEndingDivider) {
return (
<Flex gap='small' align='center'>
@ -195,9 +31,8 @@ const ObjectTableViewButton = ({
}
ObjectTableViewButton.propTypes = {
objectType: PropTypes.string.isRequired,
viewMode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
setViewMode: PropTypes.func,
viewMode: PropTypes.oneOf(['list', 'cards']).isRequired,
setViewMode: PropTypes.func.isRequired,
showEndingDivider: PropTypes.bool
}

View File

@ -87,7 +87,6 @@ const PropertyChanges = ({ type, value }) => {
longId={false}
minimal={true}
showPreview={false}
showProgress={false}
objectData={value?.old}
maxWidth='200px'
/>
@ -103,7 +102,6 @@ const PropertyChanges = ({ type, value }) => {
longId={false}
minimal={true}
showPreview={false}
showProgress={false}
objectData={value?.new}
maxWidth='200px'
/>

View File

@ -8,30 +8,21 @@ const ScrollBox = ({
horizontalBottomPadding = 16,
verticalRightPadding = 16,
inner = false,
horizontal = false,
smallPadding = false,
className = '',
...rest
}) => {
const outerStyle = {
minHeight: '0',
minWidth: horizontal ? 0 : undefined,
'--scrollbox-vertical-right-padding': `${verticalRightPadding}px`,
'--scrollbox-horizontal-bottom-padding': `${horizontalBottomPadding}px`,
...(horizontal ? { width: '100%', height: 'auto' } : { height: '100%' })
}
const simpleBarStyle = {
...(horizontal ? { width: '100%', height: 'auto' } : { height: '100%' }),
...style
}
return (
<div
style={outerStyle}
className={`${inner ? 'scrollbox-inner' : ''} ${smallPadding ? 'scrollbox-inner-small-padding' : ''} ${horizontal ? 'scrollbox-horizontal' : ''} ${className}`}
style={{
height: '100%',
minHeight: '0',
'--scrollbox-vertical-right-padding': `${verticalRightPadding}px`,
'--scrollbox-horizontal-bottom-padding': `${horizontalBottomPadding}px`
}}
className={`${inner ? 'scrollbox-inner' : ''} ${smallPadding ? 'scrollbox-inner-small-padding' : ''} ${className}`}
>
<SimpleBar style={simpleBarStyle} {...rest}>
<SimpleBar style={{ height: '100%', ...style }} {...rest}>
{children}
</SimpleBar>
</div>
@ -44,7 +35,6 @@ ScrollBox.propTypes = {
horizontalBottomPadding: PropTypes.number,
verticalRightPadding: PropTypes.number,
inner: PropTypes.bool,
horizontal: PropTypes.bool,
smallPadding: PropTypes.bool,
className: PropTypes.string
}

View File

@ -1,439 +0,0 @@
import PropTypes from 'prop-types'
import {
createContext,
useCallback,
useContext,
useLayoutEffect,
useRef,
useState
} from 'react'
import { HolderOutlined } from '@ant-design/icons'
import classNames from 'classnames'
const SegmentedNavReorderContext = createContext(null)
const getEnabledOptions = (options, disabled) =>
options.filter((option) => !disabled && !option.disabled)
const getItemMetrics = (element) => {
if (!element) {
return null
}
return {
left: element.offsetLeft,
top: element.offsetTop,
width: element.offsetWidth,
height: element.offsetHeight
}
}
export const SegmentedNavDragHandle = ({ value }) => {
const reorder = useContext(SegmentedNavReorderContext)
const dragProps = reorder?.getDragHandleProps?.(value)
if (!dragProps) {
return null
}
return (
<span
className='segmented-nav-drag-handle overview-drag-handle'
draggable
onClick={(event) => event.stopPropagation()}
onMouseDown={(event) => event.stopPropagation()}
onDragStart={(event) => dragProps.onDragStart(event)}
onDragEnd={dragProps.onDragEnd}
>
<HolderOutlined />
</span>
)
}
SegmentedNavDragHandle.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
}
const SegmentedNav = ({
value,
options = [],
onChange,
onReorder,
className,
disabled = false,
animated = true
}) => {
const groupRef = useRef(null)
const thumbRef = useRef(null)
const itemRefs = useRef(new Map())
const prevValueRef = useRef(value)
const transitionGenRef = useRef(0)
const finishGenRef = useRef(0)
const [isAnimating, setIsAnimating] = useState(false)
const [thumbRect, setThumbRect] = useState(null)
const [draggedValue, setDraggedValue] = useState(null)
const [dropTarget, setDropTarget] = useState(null)
const enabledOptions = getEnabledOptions(options, disabled)
const isReordering = Boolean(onReorder && draggedValue != null)
const setItemRef = useCallback((optionValue, element) => {
if (element) {
itemRefs.current.set(optionValue, element)
} else {
itemRefs.current.delete(optionValue)
}
}, [])
useLayoutEffect(() => {
if (prevValueRef.current === value) {
return undefined
}
const fromMetrics = getItemMetrics(
itemRefs.current.get(prevValueRef.current)
)
const toMetrics = getItemMetrics(itemRefs.current.get(value))
prevValueRef.current = value
if (!animated) {
setIsAnimating(false)
setThumbRect(null)
return undefined
}
if (!fromMetrics || !toMetrics) {
return undefined
}
const transitionGen = transitionGenRef.current + 1
transitionGenRef.current = transitionGen
setIsAnimating(true)
setThumbRect(fromMetrics)
let endFrame = 0
const startFrame = requestAnimationFrame(() => {
endFrame = requestAnimationFrame(() => {
if (transitionGenRef.current === transitionGen) {
finishGenRef.current = transitionGen
setThumbRect(toMetrics)
}
})
})
return () => {
cancelAnimationFrame(startFrame)
cancelAnimationFrame(endFrame)
}
}, [value, animated])
const finishAnimation = useCallback(() => {
setIsAnimating(false)
setThumbRect(null)
}, [])
const handleThumbTransitionEnd = useCallback(
(event) => {
if (event.target !== thumbRef.current) {
return
}
if (
(event.propertyName === 'transform' ||
event.propertyName === 'width') &&
finishGenRef.current === transitionGenRef.current
) {
finishAnimation()
}
},
[finishAnimation]
)
const clearDragState = useCallback(() => {
setDraggedValue(null)
setDropTarget(null)
}, [])
const handleDragStart = useCallback(
(event, optionValue) => {
if (!onReorder) return
event.stopPropagation()
const item = event.currentTarget.closest('.segmented-nav-item')
if (item) {
const rect = item.getBoundingClientRect()
event.dataTransfer.setDragImage(
item,
event.clientX - rect.left,
event.clientY - rect.top
)
}
setDraggedValue(optionValue)
event.dataTransfer.effectAllowed = 'move'
event.dataTransfer.setData('text/plain', String(optionValue))
},
[onReorder]
)
const handleDragEnd = useCallback(() => {
clearDragState()
}, [clearDragState])
const handleItemDragOver = useCallback(
(event, option) => {
if (!onReorder || draggedValue == null || !option.reorderable) {
return
}
if (String(option.value) === String(draggedValue)) {
return
}
event.preventDefault()
event.stopPropagation()
event.dataTransfer.dropEffect = 'move'
const rect = event.currentTarget.getBoundingClientRect()
setDropTarget({
value: option.value,
insertBefore: event.clientX < rect.left + rect.width / 2
})
},
[draggedValue, onReorder]
)
const handleItemDrop = useCallback(
(event, option) => {
if (!onReorder || draggedValue == null || !option.reorderable) {
return
}
event.preventDefault()
event.stopPropagation()
const target = dropTarget || {
value: option.value,
insertBefore: true
}
if (String(draggedValue) !== String(target.value)) {
onReorder(draggedValue, target.value, target.insertBefore)
}
clearDragState()
},
[clearDragState, draggedValue, dropTarget, onReorder]
)
const handleGroupDragOver = useCallback(
(event) => {
if (!onReorder || draggedValue == null) {
return
}
const reorderableOptions = options.filter((option) => option.reorderable)
if (reorderableOptions.length === 0) {
return
}
if (
event.target instanceof Element &&
event.target.closest('.segmented-nav-item')
) {
return
}
event.preventDefault()
event.dataTransfer.dropEffect = 'move'
const lastOption = reorderableOptions[reorderableOptions.length - 1]
setDropTarget({
value: lastOption.value,
insertBefore: false
})
},
[draggedValue, onReorder, options]
)
const handleGroupDrop = useCallback(
(event) => {
if (!onReorder || draggedValue == null) {
return
}
if (
event.target instanceof Element &&
event.target.closest('.segmented-nav-item')
) {
return
}
event.preventDefault()
event.stopPropagation()
const reorderableOptions = options.filter((option) => option.reorderable)
const lastOption = reorderableOptions[reorderableOptions.length - 1]
if (lastOption && String(draggedValue) !== String(lastOption.value)) {
onReorder(draggedValue, lastOption.value, false)
}
clearDragState()
},
[clearDragState, draggedValue, onReorder, options]
)
const getDragHandleProps = useCallback(
(optionValue) => {
const option = options.find(
(item) => String(item.value) === String(optionValue)
)
if (!onReorder || !option?.reorderable) {
return null
}
return {
onDragStart: (event) => handleDragStart(event, optionValue),
onDragEnd: handleDragEnd
}
},
[handleDragEnd, handleDragStart, onReorder, options]
)
const handleKeyDown = (event, optionIndex) => {
if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') {
return
}
event.preventDefault()
const direction = event.key === 'ArrowRight' ? 1 : -1
const currentEnabledIndex = enabledOptions.findIndex(
(option) => option.value === value
)
const startIndex =
currentEnabledIndex === -1 ? optionIndex : currentEnabledIndex
const nextIndex =
(startIndex + direction + enabledOptions.length) % enabledOptions.length
onChange?.(enabledOptions[nextIndex].value)
}
const reorderContextValue = onReorder ? { getDragHandleProps } : null
return (
<SegmentedNavReorderContext.Provider value={reorderContextValue}>
<div
className={classNames('segmented-nav', className, {
'segmented-nav-disabled': disabled,
'segmented-nav-reordering': isReordering
})}
role='radiogroup'
>
<div
className={classNames('segmented-nav-group', {
'segmented-nav-animating': isAnimating
})}
ref={groupRef}
onDragOver={handleGroupDragOver}
onDrop={handleGroupDrop}
>
{isAnimating && thumbRect && (
<div
ref={thumbRef}
className='segmented-nav-thumb'
style={{
width: thumbRect.width,
height: thumbRect.height,
transform: `translate3d(${thumbRect.left}px, ${thumbRect.top}px, 0)`
}}
onTransitionEnd={handleThumbTransitionEnd}
aria-hidden='true'
/>
)}
{options.map((option, index) => {
const isSelected = value === option.value
const isDisabled = disabled || option.disabled
const isDragging =
draggedValue != null &&
String(draggedValue) === String(option.value)
const isDropTarget =
dropTarget != null &&
String(dropTarget.value) === String(option.value) &&
String(draggedValue) !== String(option.value)
return (
<button
key={option.value}
ref={(element) => setItemRef(option.value, element)}
type='button'
role='radio'
aria-checked={isSelected}
disabled={isDisabled}
tabIndex={isSelected ? 0 : -1}
className={classNames('segmented-nav-item', option.className, {
'segmented-nav-item-selected': isSelected,
'segmented-nav-item-disabled': isDisabled,
'segmented-nav-item-dragging': isDragging,
'segmented-nav-item-drop-before':
isDropTarget && dropTarget.insertBefore,
'segmented-nav-item-drop-after':
isDropTarget && !dropTarget.insertBefore,
'segmented-nav-item-icon': option.icon
})}
onClick={() => {
if (!isDisabled) {
onChange?.(option.value)
}
}}
onKeyDown={(event) => handleKeyDown(event, index)}
onDragOver={
option.reorderable
? (event) => handleItemDragOver(event, option)
: undefined
}
onDrop={
option.reorderable
? (event) => handleItemDrop(event, option)
: undefined
}
>
{option.icon && (
<span className='segmented-nav-item-icon-contents'>
{option.icon}
</span>
)}
{option.label && (
<span className='segmented-nav-item-label'>
{option.label}
</span>
)}
</button>
)
})}
</div>
</div>
</SegmentedNavReorderContext.Provider>
)
}
SegmentedNav.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
.isRequired,
label: PropTypes.node,
disabled: PropTypes.bool,
reorderable: PropTypes.bool,
className: PropTypes.string
})
),
onChange: PropTypes.func,
onReorder: PropTypes.func,
className: PropTypes.string,
disabled: PropTypes.bool,
animated: PropTypes.bool
}
export default SegmentedNav

View File

@ -34,27 +34,20 @@ const StateDisplay = ({
'syncing'
]
const circularLoadingTypes = ['loading', 'processing', 'initializing']
const currentState = state || {
type: 'unknown',
progress: 0
}
const [showMessageModal, setShowMessageModal] = useState(false)
const progressValue = Math.round(currentState.progress * 1000) / 10
const isCircularLoading = circularLoadingTypes.includes(currentState.type)
const showCircularLoading = isCircularLoading && showProgress
return (
<>
<Flex gap='small' align={'center'}>
{showState && (
<Space>
<StateTag state={currentState.type} loading={showCircularLoading} />
<StateTag state={currentState.type} />
</Space>
)}
{showProgress &&
loadingProgressTypes.includes(currentState.type) &&
currentState?.progress &&

View File

@ -1,15 +1,8 @@
import PropTypes from 'prop-types'
import { Badge, Flex, Tag } from 'antd'
import { useMemo } from 'react'
import LoadingIcon from '../../Icons/LoadingIcon'
const StateTag = ({
state,
showBadge = true,
showTag = true,
loading = false,
style = {}
}) => {
const StateTag = ({ state, showBadge = true, showTag = true, style = {} }) => {
const { badgeStatus, badgeText } = useMemo(() => {
let status = 'default'
let text = 'Unknown'
@ -223,17 +216,10 @@ const StateTag = ({
return <Badge {...badgeProps} style={{ ...style }} />
}
const showLoading = loading && showBadge
const padding = showLoading ? '0 6px' : '0 8px'
return (
<Tag color={badgeStatus} style={{ marginRight: 0, ...style, padding }}>
<Tag color={badgeStatus} style={{ marginRight: 0, ...style }}>
<Flex gap={6}>
{showBadge && !loading && <Badge {...badgeProps} />}
{showLoading && (
<LoadingIcon style={{ fontSize: 8 }} className='state-tag-loading' />
)}
{showBadge && <Badge {...badgeProps} />}
{badgeText}
</Flex>
</Tag>
@ -244,8 +230,7 @@ StateTag.propTypes = {
state: PropTypes.string,
showBadge: PropTypes.bool,
style: PropTypes.object,
showTag: PropTypes.bool,
loading: PropTypes.bool
showTag: PropTypes.bool
}
export default StateTag

View File

@ -1,31 +0,0 @@
export const DEFAULT_VIEW_MODE = { type: 'list' }
export const normalizeViewMode = (value) => {
if (!value) return DEFAULT_VIEW_MODE
if (typeof value === 'string') {
return {
type: value === 'cards' ? 'cards' : value === 'kanban' ? 'kanban' : 'list'
}
}
if (value?.type) return value
return DEFAULT_VIEW_MODE
}
export const isCardsView = (vm) => normalizeViewMode(vm).type === 'cards'
export const isKanbanView = (vm) => normalizeViewMode(vm).type === 'kanban'
export const getViewModeType = (vm) => normalizeViewMode(vm).type
export const toCategoryFilterValue = (value) => {
if (value && typeof value === 'object') {
return value.type ?? value._id ?? JSON.stringify(value)
}
return String(value)
}
export const getCategoryValueKey = (value) => {
if (value && typeof value === 'object' && value.type != null) {
return String(value.type)
}
if (value != null) return String(value)
return 'null'
}

View File

@ -2532,51 +2532,6 @@ const ApiServerProvider = ({ children }) => {
}
}
const fetchObjectViews = async (objectType) => {
if (!objectType) return { data: [] }
try {
const result = await fetchObjects('objectView', {
filter: { objectType },
limit: 100
})
return result || { data: [] }
} catch (err) {
console.error(err)
showError(err, () => fetchObjectViews(objectType))
return { data: [] }
}
}
const createObjectView = async (values) => {
try {
return await createObject('objectView', values)
} catch (err) {
console.error(err)
showError(err, () => createObjectView(values))
return null
}
}
const updateObjectView = async (objectViewId, updates) => {
try {
return await updateObject(objectViewId, 'objectView', updates)
} catch (err) {
console.error(err)
showError(err, () => updateObjectView(objectViewId, updates))
return null
}
}
const deleteObjectView = async (objectViewId) => {
try {
return await deleteObject(objectViewId, 'objectView')
} catch (err) {
console.error(err)
showError(err, () => deleteObjectView(objectViewId))
return null
}
}
const fetchNotificationsApi = useCallback(async () => {
const response = await axios.get(`${config.backendUrl}/notifications`, {
params: { limit: 100, sortProperty: 'createdAt', sortOrder: 'descend' },
@ -2893,10 +2848,6 @@ const ApiServerProvider = ({ children }) => {
fetchAllUserNotifiersForObject,
toggleUserNotifier,
editUserNotifier,
fetchObjectViews,
createObjectView,
updateObjectView,
deleteObjectView,
fetchNotificationsApi,
markNotificationAsReadApi,
markAllNotificationsAsReadApi,

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,7 @@ import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState
} from 'react'
import { useSearchParams } from 'react-router-dom'
@ -14,13 +12,9 @@ const TableStateContext = createContext()
export const FILTER_URL_PARAM = 'filter'
export const SORT_URL_PARAM = 'sort'
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`
const getSessionListViewKey = (scope) => `tableState:${scope}:listView`
// eslint-disable-next-line react-refresh/only-export-components
export const getActiveFilterValues = (filterState) => {
@ -50,8 +44,6 @@ const readSortFromUrl = (searchParams) => {
return { field: parsed.field, order: parsed.order }
}
const readViewFromUrl = (searchParams) => searchParams.get(VIEW_URL_PARAM) || null
const readFilterFromSession = (scope) => {
try {
return parseJsonParam(sessionStorage.getItem(getSessionFilterKey(scope)))
@ -94,67 +86,6 @@ 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 readListViewFromSession = (scope) => {
try {
const parsed = parseJsonParam(sessionStorage.getItem(getSessionListViewKey(scope)))
if (!parsed?.id) return null
return {
id: String(parsed.id),
name: parsed.name || null
}
} catch {
return null
}
}
const writeListViewToSession = (scope, view) => {
const key = getSessionListViewKey(scope)
if (view?.id) {
sessionStorage.setItem(
key,
JSON.stringify({ id: String(view.id), name: view.name || null })
)
} else {
sessionStorage.removeItem(key)
}
}
const normalizeSorter = (sorter) => {
if (sorter?.field && sorter?.order) {
return { field: sorter.field, order: sorter.order }
@ -166,50 +97,6 @@ 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({})
// Active list view (id + name) per object type — same survival pattern as filters.
const [objectListViews, setObjectListViews] = useState({})
const searchParamsRef = useRef(searchParams)
// Tracks an in-flight optimistic URL write so a render with stale router
// searchParams cannot clobber searchParamsRef and resurrect deleted params
// (e.g. viewId briefly cleared on All, then written back by persistTableState).
const pendingSearchParamsRef = useRef(null)
const previousSearchParamsRef = useRef(searchParams.toString())
useEffect(() => {
const current = searchParams.toString()
if (pendingSearchParamsRef.current != null) {
if (current === pendingSearchParamsRef.current) {
pendingSearchParamsRef.current = null
} else if (current === previousSearchParamsRef.current) {
// Stale snapshot from before our write — keep the optimistic ref.
return
} else {
// External navigation while a write was pending — accept it.
pendingSearchParamsRef.current = null
}
}
previousSearchParamsRef.current = current
searchParamsRef.current = searchParams
}, [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 previous = searchParamsRef.current.toString()
const next = new URLSearchParams(searchParamsRef.current)
mutator(next)
previousSearchParamsRef.current = previous
searchParamsRef.current = next
pendingSearchParamsRef.current = next.toString()
setSearchParams(next, { replace: true })
},
[setSearchParams]
)
const getPersistedFilter = useCallback(
(scope, { useFilterInUrl = false, useFilterInSession = false } = {}) => {
@ -241,31 +128,6 @@ export const TableStateProvider = ({ children }) => {
[searchParams]
)
const getViewFromUrl = useCallback(
() => readViewFromUrl(searchParams),
[searchParams]
)
const persistView = useCallback(
(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)
}
})
},
[updateSearchParams]
)
const persistFilter = useCallback(
(
scope,
@ -277,16 +139,16 @@ export const TableStateProvider = ({ children }) => {
writeFilterToSession(scope, active)
}
if (saveFilterInUrl) {
updateSearchParams((next) => {
if (Object.keys(active).length > 0) {
next.set(FILTER_URL_PARAM, JSON.stringify(active))
} else {
next.delete(FILTER_URL_PARAM)
}
})
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]
[searchParams, setSearchParams]
)
const persistSort = useCallback(
@ -300,16 +162,16 @@ export const TableStateProvider = ({ children }) => {
writeSortToSession(scope, nextSorter)
}
if (saveSortInUrl) {
updateSearchParams((next) => {
if (nextSorter.field && nextSorter.order) {
next.set(SORT_URL_PARAM, JSON.stringify(nextSorter))
} else {
next.delete(SORT_URL_PARAM)
}
})
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]
[searchParams, setSearchParams]
)
const persistTableState = useCallback(
@ -335,25 +197,25 @@ export const TableStateProvider = ({ children }) => {
}
if (saveFilterInUrl || saveSortInUrl) {
updateSearchParams((next) => {
if (saveFilterInUrl) {
if (Object.keys(active).length > 0) {
next.set(FILTER_URL_PARAM, JSON.stringify(active))
} else {
next.delete(FILTER_URL_PARAM)
}
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)
}
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 })
}
},
[updateSearchParams]
[searchParams, setSearchParams]
)
const setPageFilter = useCallback((path, filter) => {
@ -383,157 +245,39 @@ 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 setObjectListView = useCallback((objectType, view) => {
if (!objectType) return
const nextView =
view?.id != null
? { id: String(view.id), name: view.name || null }
: null
writeListViewToSession(objectType, nextView)
setObjectListViews((prev) => {
if (!nextView) {
if (!(objectType in prev)) return prev
const next = { ...prev }
delete next[objectType]
return next
}
const existing = prev[objectType]
if (
existing &&
existing.id === nextView.id &&
existing.name === nextView.name
) {
return prev
}
return { ...prev, [objectType]: nextView }
})
}, [])
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 getObjectListView = useCallback(
(objectType) => {
if (!objectType) return null
if (objectListViews[objectType]) {
return objectListViews[objectType]
}
return readListViewFromSession(objectType)
},
[objectListViews]
)
const hasPageFilter = useCallback(
(path) => Object.keys(pageFilters[path] || {}).length > 0,
[pageFilters]
)
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 hasStoredFilter = useCallback((scope) => hasStoredSessionFilter(scope), [])
const value = useMemo(
() => ({
getPersistedFilter,
getPersistedSorter,
getViewFromUrl,
persistView,
persistFilter,
persistSort,
persistTableState,
setPageFilter,
setPageSorter,
setObjectListFilter,
setObjectListSorter,
setObjectListView,
getObjectListFilter,
getObjectListSorter,
getObjectListView,
hasPageFilter,
hasStoredFilter,
pageFilters,
pageSorters,
objectListFilters,
objectListSorters,
objectListViews
pageSorters
}),
[
getPersistedFilter,
getPersistedSorter,
getViewFromUrl,
persistView,
persistFilter,
persistSort,
persistTableState,
setPageFilter,
setPageSorter,
setObjectListFilter,
setObjectListSorter,
setObjectListView,
getObjectListFilter,
getObjectListSorter,
getObjectListView,
hasPageFilter,
hasStoredFilter,
pageFilters,
pageSorters,
objectListFilters,
objectListSorters,
objectListViews
pageSorters
]
)
@ -556,7 +300,6 @@ export const useTableState = () => {
// eslint-disable-next-line react-refresh/only-export-components
export const useTableStatePersistence = ({
scope,
viewId = null,
pagePath,
saveFilterInSession = false,
saveFilterInUrl = false,
@ -574,58 +317,15 @@ export const useTableStatePersistence = ({
persistSort: persistSortCtx,
persistTableState: persistTableStateCtx,
setPageFilter,
setPageSorter,
setObjectListFilter,
setObjectListSorter
setPageSorter
} = 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: 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 }),
[useFilterInUrl, useFilterInSession, useSortInUrl, useSortInSession]
)
const allTabSaveOptions = useMemo(
const saveOptions = useMemo(
() => ({
saveFilterInSession,
saveFilterInUrl,
@ -645,18 +345,6 @@ 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]
@ -673,12 +361,6 @@ 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) {
@ -697,38 +379,14 @@ 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
}
}

View File

@ -171,27 +171,11 @@ export const ThemeProvider = ({ children }) => {
'--layout-modal-bg',
isDarkMode ? '#1f1f1f' : '#ffffff'
)
root.style.setProperty(
'--color-background',
isDarkMode ? '#000000' : '#ffffff'
)
root.style.setProperty('--color-text', isDarkMode ? '#ffffff' : '#000000')
root.style.setProperty(
'--color-descriptions-border',
isDarkMode ? 'rgba(253,253,253,0.12)' : 'rgba(5,5,5,0.06)'
)
root.style.setProperty(
'--color-list-view-tabs-border',
isDarkMode ? '#1f1f1f' : '#E7E7E7'
)
root.style.setProperty(
'--color-button-background',
isDarkMode ? '#141414' : '#FFFFFF'
)
root.style.setProperty(
'--color-button-border',
isDarkMode ? '#424242' : '#d9d9d9'
)
}, [isDarkMode, primaryColorOverride])
const themeConfig = {

View File

@ -1,21 +1,14 @@
import { useCallback, useContext } from 'react'
import { ApiServerContext } from '../context/ApiServerContext'
import {
DEFAULT_VIEW_MODE,
normalizeViewMode
} from '../common/viewModeUtils'
const useViewMode = (componentName, defaultMode = DEFAULT_VIEW_MODE) => {
const useViewMode = (componentName, defaultMode = 'list') => {
const { userSettings, updateUserSettings } = useContext(ApiServerContext)
const viewMode = normalizeViewMode(
userSettings.viewMode[componentName] ?? defaultMode
)
const viewMode = userSettings.viewMode[componentName] ?? defaultMode
const setViewMode = useCallback(
(nextMode) => {
const mode = normalizeViewMode(
const mode =
typeof nextMode === 'function' ? nextMode(viewMode) : nextMode
)
updateUserSettings('viewMode', componentName, mode)
},
[componentName, updateUserSettings, viewMode]

View File

@ -1,6 +0,0 @@
import Icon from '@ant-design/icons'
import CustomIconSvg from '../../../assets/icons/kanbanicon.svg?react'
const KanbanIcon = (props) => <Icon component={CustomIconSvg} {...props} />
export default KanbanIcon

View File

@ -1,6 +0,0 @@
import Icon from '@ant-design/icons'
import CustomIconSvg from '../../../assets/icons/loadingicon.svg?react'
const LoadingIcon = (props) => <Icon component={CustomIconSvg} {...props} />
export default LoadingIcon

View File

@ -194,7 +194,7 @@ export function getModelByName(name, ignoreCase = false) {
export function getModelByPluralName(pluralName, ignoreCase = false) {
function formatName(formattedName) {
if (ignoreCase == true) {
formattedName = formattedName.toUpperCase().replaceAll(' ', '')
formattedName = formattedName.toUpperCase().replace(' ', '')
}
return formattedName
}

View File

@ -110,7 +110,7 @@ export const DocumentPrinter = {
],
sorters: [
'name',
'currentDocumentSize',
'documentSize',
'connectedAt',
'connection.port',
'updatedAt',
@ -261,47 +261,15 @@ export const DocumentPrinter = {
},
columnWidth: 85
},
{
name: 'connection.username',
label: 'Username',
type: 'text',
required: false,
visible: (objectData) => objectData?.connection?.interface === 'cups',
columnWidth: 150
},
{
name: 'connection.password',
label: 'Password',
type: 'secret',
required: false,
visible: (objectData) => objectData?.connection?.interface === 'cups',
columnWidth: 150
},
{
name: 'currentDocumentSize',
label: 'Current Document Size',
label: 'Document Size',
required: false,
type: 'object',
objectType: 'documentSize',
showHyperlink: true,
columnWidth: 200
},
{
name: 'rotateOrientation',
label: 'Rotate Orientation',
required: false,
type: 'bool',
columnWidth: 150
},
{
name: 'supportedDocumentSizes',
label: 'Supported Document Sizes',
required: false,
type: 'objectList',
objectType: 'documentSize',
showHyperlink: true,
columnWidth: 260
},
{
name: 'tags',
label: 'Tags',