[PUI] Column Refactoring (#7242)

* Refactor column helpers

* Make reference column switchable in BomTable

* Make 'accessor' a required field againt

* Update props

* Fix c0d3
This commit is contained in:
Oliver 2024-05-17 11:38:55 +10:00 committed by GitHub
parent 2a83c19208
commit acb1ec4c83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 102 additions and 135 deletions

View File

@ -1,8 +1,5 @@
/** export type TableColumnProps<T = any> = {
* Interface for the table column definition accessor?: string; // The key in the record to access
*/
export type TableColumn<T = any> = {
accessor: string; // The key in the record to access
title?: string; // The title of the column - Note: this may be supplied by the API, and is not required, but it can be overridden if required title?: string; // The title of the column - Note: this may be supplied by the API, and is not required, but it can be overridden if required
ordering?: string; // The key in the record to sort by (defaults to accessor) ordering?: string; // The key in the record to sort by (defaults to accessor)
sortable?: boolean; // Whether the column is sortable sortable?: boolean; // Whether the column is sortable
@ -18,3 +15,10 @@ export type TableColumn<T = any> = {
cellsStyle?: any; // The style of the cells in the column cellsStyle?: any; // The style of the cells in the column
extra?: any; // Extra data to pass to the render function extra?: any; // Extra data to pass to the render function
}; };
/**
* Interface for the table column definition
*/
export type TableColumn<T = any> = {
accessor: string; // The key in the record to access
} & TableColumnProps<T>;

View File

@ -13,7 +13,7 @@ import { formatCurrency, renderDate } from '../defaults/formatters';
import { ModelType } from '../enums/ModelType'; import { ModelType } from '../enums/ModelType';
import { resolveItem } from '../functions/conversion'; import { resolveItem } from '../functions/conversion';
import { cancelEvent } from '../functions/events'; import { cancelEvent } from '../functions/events';
import { TableColumn } from './Column'; import { TableColumn, TableColumnProps } from './Column';
import { ProjectCodeHoverCard } from './TableHoverCard'; import { ProjectCodeHoverCard } from './TableHoverCard';
// Render a Part instance within a table // Render a Part instance within a table
@ -26,24 +26,14 @@ export function PartColumn(part: any, full_name?: boolean) {
); );
} }
export function LocationColumn({ export function LocationColumn(props: TableColumnProps): TableColumn {
accessor,
title,
sortable,
ordering
}: {
accessor: string;
title?: string;
sortable?: boolean;
ordering?: string;
}): TableColumn {
return { return {
accessor: accessor, accessor: 'location',
title: title ?? t`Location`, title: t`Location`,
sortable: sortable ?? true, sortable: true,
ordering: ordering ?? 'location', ordering: 'location',
render: (record: any) => { render: (record: any) => {
let location = resolveItem(record, accessor); let location = resolveItem(record, props.accessor ?? '');
if (!location) { if (!location) {
return ( return (
@ -52,62 +42,38 @@ export function LocationColumn({
} }
return <Text>{location.name}</Text>; return <Text>{location.name}</Text>;
} },
...props
}; };
} }
export function BooleanColumn({ export function BooleanColumn(props: TableColumn): TableColumn {
accessor,
title,
sortable,
switchable,
ordering
}: {
accessor: string;
title?: string;
ordering?: string;
sortable?: boolean;
switchable?: boolean;
}): TableColumn {
return { return {
accessor: accessor, sortable: true,
title: title, switchable: true,
ordering: ordering,
sortable: sortable ?? true,
switchable: switchable ?? true,
render: (record: any) => ( render: (record: any) => (
<YesNoButton value={resolveItem(record, accessor)} /> <YesNoButton value={resolveItem(record, props.accessor ?? '')} />
) ),
...props
}; };
} }
export function DescriptionColumn({ export function DescriptionColumn(props: TableColumnProps): TableColumn {
accessor,
sortable,
switchable
}: {
accessor?: string;
sortable?: boolean;
switchable?: boolean;
}): TableColumn {
return { return {
accessor: accessor ?? 'description', accessor: 'description',
title: t`Description`, title: t`Description`,
sortable: sortable ?? false, sortable: false,
switchable: switchable ?? true switchable: true,
...props
}; };
} }
export function LinkColumn({ export function LinkColumn(props: TableColumnProps): TableColumn {
accessor = 'link'
}: {
accessor?: string;
}): TableColumn {
return { return {
accessor: accessor, accessor: 'link',
sortable: false, sortable: false,
render: (record: any) => { render: (record: any) => {
let url = resolveItem(record, accessor); let url = resolveItem(record, props.accessor ?? 'link');
if (!url) { if (!url) {
return '-'; return '-';
@ -127,24 +93,28 @@ export function LinkColumn({
{url} {url}
</Anchor> </Anchor>
); );
} },
...props
}; };
} }
export function ReferenceColumn(): TableColumn { export function ReferenceColumn(props: TableColumnProps): TableColumn {
return { return {
accessor: 'reference', accessor: 'reference',
title: t`Reference`,
sortable: true, sortable: true,
switchable: false switchable: true,
...props
}; };
} }
export function NoteColumn(): TableColumn { export function NoteColumn(props: TableColumnProps): TableColumn {
return { return {
accessor: 'note', accessor: 'note',
sortable: false, sortable: false,
title: t`Note`, title: t`Note`,
render: (record: any) => record.note ?? record.notes render: (record: any) => record.note ?? record.notes,
...props
}; };
} }
@ -162,13 +132,14 @@ export function LineItemsProgressColumn(): TableColumn {
}; };
} }
export function ProjectCodeColumn(): TableColumn { export function ProjectCodeColumn(props: TableColumnProps): TableColumn {
return { return {
accessor: 'project_code', accessor: 'project_code',
sortable: true, sortable: true,
render: (record: any) => ( render: (record: any) => (
<ProjectCodeHoverCard projectCode={record.project_code_detail} /> <ProjectCodeHoverCard projectCode={record.project_code_detail} />
) ),
...props
}; };
} }
@ -188,62 +159,52 @@ export function StatusColumn({
}; };
} }
export function ResponsibleColumn(): TableColumn { export function ResponsibleColumn(props: TableColumnProps): TableColumn {
return { return {
accessor: 'responsible', accessor: 'responsible',
sortable: true, sortable: true,
switchable: true,
render: (record: any) => render: (record: any) =>
record.responsible && RenderOwner({ instance: record.responsible_detail }) record.responsible &&
RenderOwner({ instance: record.responsible_detail }),
...props
}; };
} }
export function DateColumn({ export function DateColumn(props: TableColumnProps): TableColumn {
accessor,
sortable,
switchable,
ordering,
title
}: {
accessor?: string;
ordering?: string;
sortable?: boolean;
switchable?: boolean;
title?: string;
}): TableColumn {
return { return {
accessor: accessor ?? 'date', accessor: 'date',
sortable: sortable ?? true, sortable: true,
ordering: ordering, title: t`Date`,
title: title ?? t`Date`, switchable: true,
switchable: switchable, render: (record: any) =>
render: (record: any) => renderDate(resolveItem(record, accessor ?? 'date')) renderDate(resolveItem(record, props.accessor ?? 'date')),
...props
}; };
} }
export function TargetDateColumn(): TableColumn { export function TargetDateColumn(props: TableColumnProps): TableColumn {
return { return DateColumn({
accessor: 'target_date', accessor: 'target_date',
sortable: true,
title: t`Target Date`, title: t`Target Date`,
// TODO: custom renderer which alerts user if target date is overdue ...props
render: (record: any) => renderDate(record.target_date) });
};
} }
export function CreationDateColumn(): TableColumn { export function CreationDateColumn(props: TableColumnProps): TableColumn {
return { return DateColumn({
accessor: 'creation_date', accessor: 'creation_date',
sortable: true, title: t`Creation Date`,
render: (record: any) => renderDate(record.creation_date) ...props
}; });
} }
export function ShipmentDateColumn(): TableColumn { export function ShipmentDateColumn(props: TableColumnProps): TableColumn {
return { return DateColumn({
accessor: 'shipment_date', accessor: 'shipment_date',
sortable: true, title: t`Shipment Date`,
render: (record: any) => renderDate(record.shipment_date) ...props
}; });
} }
export function CurrencyColumn({ export function CurrencyColumn({

View File

@ -99,7 +99,9 @@ export function BomTable({
DescriptionColumn({ DescriptionColumn({
accessor: 'sub_part_detail.description' accessor: 'sub_part_detail.description'
}), }),
ReferenceColumn(), ReferenceColumn({
switchable: true
}),
{ {
accessor: 'quantity', accessor: 'quantity',
switchable: false, switchable: false,
@ -248,7 +250,7 @@ export function BomTable({
); );
} }
}, },
NoteColumn() NoteColumn({})
]; ];
}, [partId, params]); }, [partId, params]);

View File

@ -52,7 +52,7 @@ export function UsedInTable({
); );
} }
}, },
ReferenceColumn() ReferenceColumn({})
]; ];
}, [partId]); }, [partId]);

View File

@ -36,7 +36,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
*/ */
function buildOrderTableColumns(): TableColumn[] { function buildOrderTableColumns(): TableColumn[] {
return [ return [
ReferenceColumn(), ReferenceColumn({}),
{ {
accessor: 'part', accessor: 'part',
sortable: true, sortable: true,
@ -60,13 +60,13 @@ function buildOrderTableColumns(): TableColumn[] {
) )
}, },
StatusColumn({ model: ModelType.build }), StatusColumn({ model: ModelType.build }),
ProjectCodeColumn(), ProjectCodeColumn({}),
{ {
accessor: 'priority', accessor: 'priority',
sortable: true sortable: true
}, },
CreationDateColumn(), CreationDateColumn({}),
TargetDateColumn(), TargetDateColumn({}),
DateColumn({ DateColumn({
accessor: 'completion_date', accessor: 'completion_date',
sortable: true sortable: true
@ -78,7 +78,7 @@ function buildOrderTableColumns(): TableColumn[] {
<RenderUser instance={record?.issued_by_detail} /> <RenderUser instance={record?.issued_by_detail} />
) )
}, },
ResponsibleColumn() ResponsibleColumn({})
]; ];
} }

View File

@ -88,7 +88,7 @@ export function PurchaseOrderLineItemTable({
sortable: false, sortable: false,
render: (record: any) => record?.part_detail?.description render: (record: any) => record?.part_detail?.description
}, },
ReferenceColumn(), ReferenceColumn({}),
{ {
accessor: 'quantity', accessor: 'quantity',
title: t`Quantity`, title: t`Quantity`,
@ -170,7 +170,7 @@ export function PurchaseOrderLineItemTable({
title: t`Unit Price` title: t`Unit Price`
}), }),
TotalPriceColumn(), TotalPriceColumn(),
TargetDateColumn(), TargetDateColumn({}),
{ {
accessor: 'destination', accessor: 'destination',
title: t`Destination`, title: t`Destination`,
@ -180,7 +180,7 @@ export function PurchaseOrderLineItemTable({
? RenderStockLocation({ instance: record.destination_detail }) ? RenderStockLocation({ instance: record.destination_detail })
: '-' : '-'
}, },
NoteColumn(), NoteColumn({}),
LinkColumn({}) LinkColumn({})
]; ];
}, [orderId, user]); }, [orderId, user]);

View File

@ -81,7 +81,7 @@ export function PurchaseOrderTable({
const tableColumns = useMemo(() => { const tableColumns = useMemo(() => {
return [ return [
ReferenceColumn(), ReferenceColumn({}),
DescriptionColumn({}), DescriptionColumn({}),
{ {
accessor: 'supplier__name', accessor: 'supplier__name',
@ -104,9 +104,9 @@ export function PurchaseOrderTable({
}, },
LineItemsProgressColumn(), LineItemsProgressColumn(),
StatusColumn({ model: ModelType.purchaseorder }), StatusColumn({ model: ModelType.purchaseorder }),
ProjectCodeColumn(), ProjectCodeColumn({}),
CreationDateColumn(), CreationDateColumn({}),
TargetDateColumn(), TargetDateColumn({}),
{ {
accessor: 'total_price', accessor: 'total_price',
title: t`Total Price`, title: t`Total Price`,
@ -117,7 +117,7 @@ export function PurchaseOrderTable({
}); });
} }
}, },
ResponsibleColumn() ResponsibleColumn({})
]; ];
}, []); }, []);

View File

@ -134,7 +134,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
} }
}, },
LinkColumn({}), LinkColumn({}),
NoteColumn(), NoteColumn({}),
{ {
accessor: 'available', accessor: 'available',
sortable: true, sortable: true,

View File

@ -72,7 +72,7 @@ export function ReturnOrderTable({ params }: { params?: any }) {
const tableColumns = useMemo(() => { const tableColumns = useMemo(() => {
return [ return [
ReferenceColumn(), ReferenceColumn({}),
{ {
accessor: 'customer__name', accessor: 'customer__name',
title: t`Customer`, title: t`Customer`,
@ -95,10 +95,10 @@ export function ReturnOrderTable({ params }: { params?: any }) {
DescriptionColumn({}), DescriptionColumn({}),
LineItemsProgressColumn(), LineItemsProgressColumn(),
StatusColumn({ model: ModelType.returnorder }), StatusColumn({ model: ModelType.returnorder }),
ProjectCodeColumn(), ProjectCodeColumn({}),
CreationDateColumn(), CreationDateColumn({}),
TargetDateColumn(), TargetDateColumn({}),
ResponsibleColumn(), ResponsibleColumn({}),
{ {
accessor: 'total_price', accessor: 'total_price',
title: t`Total Price`, title: t`Total Price`,

View File

@ -101,7 +101,7 @@ export function SalesOrderTable({
const tableColumns = useMemo(() => { const tableColumns = useMemo(() => {
return [ return [
ReferenceColumn(), ReferenceColumn({}),
{ {
accessor: 'customer__name', accessor: 'customer__name',
title: t`Customer`, title: t`Customer`,
@ -125,10 +125,10 @@ export function SalesOrderTable({
DescriptionColumn({}), DescriptionColumn({}),
LineItemsProgressColumn(), LineItemsProgressColumn(),
StatusColumn({ model: ModelType.salesorder }), StatusColumn({ model: ModelType.salesorder }),
ProjectCodeColumn(), ProjectCodeColumn({}),
CreationDateColumn(), CreationDateColumn({}),
TargetDateColumn(), TargetDateColumn({}),
ShipmentDateColumn(), ShipmentDateColumn({}),
{ {
accessor: 'total_price', accessor: 'total_price',
title: t`Total Price`, title: t`Total Price`,

View File

@ -33,7 +33,7 @@ export default function ProjectCodeTable() {
sortable: true sortable: true
}, },
DescriptionColumn({}), DescriptionColumn({}),
ResponsibleColumn() ResponsibleColumn({})
]; ];
}, []); }, []);

View File

@ -187,7 +187,7 @@ export default function StockItemTestResultTable({
render: (record: any) => render: (record: any) =>
record.attachment && <AttachmentLink attachment={record.attachment} /> record.attachment && <AttachmentLink attachment={record.attachment} />
}, },
NoteColumn(), NoteColumn({}),
DateColumn({}), DateColumn({}),
{ {
accessor: 'user', accessor: 'user',