mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	Column min width (#10204)
* Support minimum column width * Adjust DescriptionColumn and StatusColumn * Column refactoring * Refactor PartColumn * Refactor LineItemsProgerssColumn * Tweaks
This commit is contained in:
		| @@ -91,6 +91,7 @@ export type TableState = { | |||||||
|  * @param filter - A custom filter function |  * @param filter - A custom filter function | ||||||
|  * @param filtering - Whether the column is filterable |  * @param filtering - Whether the column is filterable | ||||||
|  * @param width - The width of the column |  * @param width - The width of the column | ||||||
|  |  * @param minWidth - The minimum width of the column | ||||||
|  * @param resizable - Whether the column is resizable (defaults to true) |  * @param resizable - Whether the column is resizable (defaults to true) | ||||||
|  * @param noWrap - Whether the column should wrap |  * @param noWrap - Whether the column should wrap | ||||||
|  * @param ellipsis - Whether the column should be ellipsized |  * @param ellipsis - Whether the column should be ellipsized | ||||||
| @@ -113,6 +114,7 @@ export type TableColumnProps<T = any> = { | |||||||
|   filter?: any; |   filter?: any; | ||||||
|   filtering?: boolean; |   filtering?: boolean; | ||||||
|   width?: number; |   width?: number; | ||||||
|  |   minWidth?: string | number; | ||||||
|   resizable?: boolean; |   resizable?: boolean; | ||||||
|   noWrap?: boolean; |   noWrap?: boolean; | ||||||
|   ellipsis?: boolean; |   ellipsis?: boolean; | ||||||
| @@ -120,6 +122,7 @@ export type TableColumnProps<T = any> = { | |||||||
|   cellsStyle?: any; |   cellsStyle?: any; | ||||||
|   extra?: any; |   extra?: any; | ||||||
|   noContext?: boolean; |   noContext?: boolean; | ||||||
|  |   style?: MantineStyleProp; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ import { useSupplierPartFields } from '../../forms/CompanyForms'; | |||||||
| import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms'; | import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms'; | ||||||
| import { useCreateApiFormModal } from '../../hooks/UseForm'; | import { useCreateApiFormModal } from '../../hooks/UseForm'; | ||||||
| import useWizard from '../../hooks/UseWizard'; | import useWizard from '../../hooks/UseWizard'; | ||||||
| import { PartColumn } from '../../tables/ColumnRenderers'; | import { RenderPartColumn } from '../../tables/ColumnRenderers'; | ||||||
| import RemoveRowButton from '../buttons/RemoveRowButton'; | import RemoveRowButton from '../buttons/RemoveRowButton'; | ||||||
| import { StandaloneField } from '../forms/StandaloneField'; | import { StandaloneField } from '../forms/StandaloneField'; | ||||||
| import Expand from '../items/Expand'; | import Expand from '../items/Expand'; | ||||||
| @@ -133,7 +133,7 @@ function SelectPartsStep({ | |||||||
|         render: (record: PartOrderRecord) => ( |         render: (record: PartOrderRecord) => ( | ||||||
|           <Tooltip label={record.part?.description}> |           <Tooltip label={record.part?.description}> | ||||||
|             <Paper p='xs'> |             <Paper p='xs'> | ||||||
|               <PartColumn part={record.part} /> |               <RenderPartColumn part={record.part} /> | ||||||
|             </Paper> |             </Paper> | ||||||
|           </Tooltip> |           </Tooltip> | ||||||
|         ) |         ) | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ import { | |||||||
|   useSerialNumberGenerator |   useSerialNumberGenerator | ||||||
| } from '../hooks/UseGenerator'; | } from '../hooks/UseGenerator'; | ||||||
| import { useGlobalSettingsState } from '../states/SettingsStates'; | import { useGlobalSettingsState } from '../states/SettingsStates'; | ||||||
| import { PartColumn } from '../tables/ColumnRenderers'; | import { RenderPartColumn } from '../tables/ColumnRenderers'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Field set for BuildOrder forms |  * Field set for BuildOrder forms | ||||||
| @@ -248,7 +248,7 @@ function BuildOutputFormRow({ | |||||||
|     <> |     <> | ||||||
|       <Table.Tr> |       <Table.Tr> | ||||||
|         <Table.Td> |         <Table.Td> | ||||||
|           <PartColumn part={record.part_detail} /> |           <RenderPartColumn part={record.part_detail} /> | ||||||
|         </Table.Td> |         </Table.Td> | ||||||
|         <Table.Td> |         <Table.Td> | ||||||
|           <TableFieldErrorWrapper props={props} errorKey='output'> |           <TableFieldErrorWrapper props={props} errorKey='output'> | ||||||
| @@ -541,7 +541,7 @@ function BuildAllocateLineRow({ | |||||||
|   return ( |   return ( | ||||||
|     <Table.Tr key={`table-row-${record.pk}`}> |     <Table.Tr key={`table-row-${record.pk}`}> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <PartColumn part={record.part_detail} /> |         <RenderPartColumn part={record.part_detail} /> | ||||||
|       </Table.Td> |       </Table.Td> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <ProgressBar |         <ProgressBar | ||||||
| @@ -704,7 +704,7 @@ function BuildConsumeItemRow({ | |||||||
|   return ( |   return ( | ||||||
|     <Table.Tr key={`table-row-${record.pk}`}> |     <Table.Tr key={`table-row-${record.pk}`}> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <PartColumn part={record.part_detail} /> |         <RenderPartColumn part={record.part_detail} /> | ||||||
|       </Table.Td> |       </Table.Td> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <RenderStockItem instance={record.stock_item_detail} /> |         <RenderStockItem instance={record.stock_item_detail} /> | ||||||
| @@ -807,7 +807,7 @@ function BuildConsumeLineRow({ | |||||||
|   return ( |   return ( | ||||||
|     <Table.Tr key={`table-row-${record.pk}`}> |     <Table.Tr key={`table-row-${record.pk}`}> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <PartColumn part={record.part_detail} /> |         <RenderPartColumn part={record.part_detail} /> | ||||||
|       </Table.Td> |       </Table.Td> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         {remaining <= 0 ? ( |         {remaining <= 0 ? ( | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ import type { | |||||||
| import type { TableFieldRowProps } from '../components/forms/fields/TableField'; | import type { TableFieldRowProps } from '../components/forms/fields/TableField'; | ||||||
| import { useCreateApiFormModal } from '../hooks/UseForm'; | import { useCreateApiFormModal } from '../hooks/UseForm'; | ||||||
| import { useGlobalSettingsState } from '../states/SettingsStates'; | import { useGlobalSettingsState } from '../states/SettingsStates'; | ||||||
| import { PartColumn } from '../tables/ColumnRenderers'; | import { RenderPartColumn } from '../tables/ColumnRenderers'; | ||||||
|  |  | ||||||
| export function useSalesOrderFields({ | export function useSalesOrderFields({ | ||||||
|   duplicateOrderId |   duplicateOrderId | ||||||
| @@ -197,7 +197,7 @@ function SalesOrderAllocateLineRow({ | |||||||
|   return ( |   return ( | ||||||
|     <Table.Tr key={`table-row-${props.idx}-${record.pk}`}> |     <Table.Tr key={`table-row-${props.idx}-${record.pk}`}> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <PartColumn part={record.part_detail} /> |         <RenderPartColumn part={record.part_detail} /> | ||||||
|       </Table.Td> |       </Table.Td> | ||||||
|       <Table.Td> |       <Table.Td> | ||||||
|         <ProgressBar |         <ProgressBar | ||||||
|   | |||||||
| @@ -136,13 +136,11 @@ export default function BomPricingPanel({ | |||||||
|  |  | ||||||
|   const columns: TableColumn[] = useMemo(() => { |   const columns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'name', |         accessor: 'name', | ||||||
|         title: t`Component`, |         title: t`Component`, | ||||||
|         sortable: true, |         part: 'sub_part_detail' | ||||||
|         switchable: false, |       }), | ||||||
|         render: (record: any) => PartColumn({ part: record.sub_part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         title: t`Quantity`, |         title: t`Quantity`, | ||||||
|   | |||||||
| @@ -25,13 +25,11 @@ export default function VariantPricingPanel({ | |||||||
|  |  | ||||||
|   const columns: TableColumn[] = useMemo(() => { |   const columns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'name', |  | ||||||
|         title: t`Variant Part`, |         title: t`Variant Part`, | ||||||
|         sortable: true, |         part: '', | ||||||
|         switchable: false, |         full_name: true | ||||||
|         render: (record: any) => PartColumn({ part: record, full_name: true }) |       }), | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'pricing_min', |         accessor: 'pricing_min', | ||||||
|         title: t`Minimum Price`, |         title: t`Minimum Price`, | ||||||
|   | |||||||
| @@ -30,15 +30,24 @@ import { | |||||||
| } from '../states/SettingsStates'; | } from '../states/SettingsStates'; | ||||||
| import { ProjectCodeHoverCard, TableHoverCard } from './TableHoverCard'; | import { ProjectCodeHoverCard, TableHoverCard } from './TableHoverCard'; | ||||||
|  |  | ||||||
| // Render a Part instance within a table | export type PartColumnProps = TableColumnProps & { | ||||||
| export function PartColumn({ |   part?: string; | ||||||
|  |   full_name?: boolean; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Extract rendering function for Part column | ||||||
|  | export function RenderPartColumn({ | ||||||
|   part, |   part, | ||||||
|   full_name |   full_name | ||||||
| }: { | }: { | ||||||
|   part: any; |   part: any; | ||||||
|   full_name?: boolean; |   full_name?: boolean; | ||||||
| }) { | }) { | ||||||
|   return part ? ( |   if (!part) { | ||||||
|  |     return <Skeleton />; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|     <Group justify='space-between' wrap='nowrap'> |     <Group justify='space-between' wrap='nowrap'> | ||||||
|       <Thumbnail |       <Thumbnail | ||||||
|         src={part?.thumbnail ?? part?.image} |         src={part?.thumbnail ?? part?.image} | ||||||
| @@ -63,11 +72,32 @@ export function PartColumn({ | |||||||
|         )} |         )} | ||||||
|       </Group> |       </Group> | ||||||
|     </Group> |     </Group> | ||||||
|   ) : ( |  | ||||||
|     <Skeleton /> |  | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Render a Part instance within a table | ||||||
|  | export function PartColumn(props: PartColumnProps): TableColumn { | ||||||
|  |   return { | ||||||
|  |     accessor: 'part', | ||||||
|  |     title: t`Part`, | ||||||
|  |     sortable: true, | ||||||
|  |     switchable: false, | ||||||
|  |     minWidth: '175px', | ||||||
|  |     render: (record: any) => { | ||||||
|  |       const part = | ||||||
|  |         props.part === '' | ||||||
|  |           ? record | ||||||
|  |           : resolveItem(record, props.part ?? props.accessor ?? 'part_detail'); | ||||||
|  |  | ||||||
|  |       return RenderPartColumn({ | ||||||
|  |         part: part, | ||||||
|  |         full_name: props.full_name ?? false | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     ...props | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
| export function CompanyColumn({ | export function CompanyColumn({ | ||||||
|   company |   company | ||||||
| }: { | }: { | ||||||
| @@ -146,6 +176,7 @@ export function LocationColumn(props: TableColumnProps): TableColumn { | |||||||
|       title: t`Location`, |       title: t`Location`, | ||||||
|       sortable: true, |       sortable: true, | ||||||
|       ordering: 'location', |       ordering: 'location', | ||||||
|  |       minWidth: '150px', | ||||||
|       ...props |       ...props | ||||||
|     }); |     }); | ||||||
|   } else { |   } else { | ||||||
| @@ -154,6 +185,7 @@ export function LocationColumn(props: TableColumnProps): TableColumn { | |||||||
|       title: t`Location`, |       title: t`Location`, | ||||||
|       sortable: true, |       sortable: true, | ||||||
|       ordering: 'location', |       ordering: 'location', | ||||||
|  |       minWidth: '125px', | ||||||
|       ...props |       ...props | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| @@ -192,6 +224,7 @@ export function CategoryColumn(props: TableColumnProps): TableColumn { | |||||||
|       title: t`Category`, |       title: t`Category`, | ||||||
|       sortable: true, |       sortable: true, | ||||||
|       ordering: 'category', |       ordering: 'category', | ||||||
|  |       minWidth: '150px', | ||||||
|       ...props |       ...props | ||||||
|     }); |     }); | ||||||
|   } else { |   } else { | ||||||
| @@ -200,6 +233,7 @@ export function CategoryColumn(props: TableColumnProps): TableColumn { | |||||||
|       title: t`Category`, |       title: t`Category`, | ||||||
|       sortable: true, |       sortable: true, | ||||||
|       ordering: 'category', |       ordering: 'category', | ||||||
|  |       minWidth: '125px', | ||||||
|       ...props |       ...props | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| @@ -209,6 +243,7 @@ export function BooleanColumn(props: TableColumn): TableColumn { | |||||||
|   return { |   return { | ||||||
|     sortable: true, |     sortable: true, | ||||||
|     switchable: true, |     switchable: true, | ||||||
|  |     minWidth: '75px', | ||||||
|     render: (record: any) => ( |     render: (record: any) => ( | ||||||
|       <Center> |       <Center> | ||||||
|         <YesNoButton value={resolveItem(record, props.accessor ?? '')} /> |         <YesNoButton value={resolveItem(record, props.accessor ?? '')} /> | ||||||
| @@ -234,7 +269,7 @@ export function DescriptionColumn(props: TableColumnProps): TableColumn { | |||||||
|     title: t`Description`, |     title: t`Description`, | ||||||
|     sortable: false, |     sortable: false, | ||||||
|     switchable: true, |     switchable: true, | ||||||
|     width: 300, |     minWidth: '200px', | ||||||
|     ...props |     ...props | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -291,17 +326,19 @@ export function NoteColumn(props: TableColumnProps): TableColumn { | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| export function LineItemsProgressColumn(): TableColumn { | export function LineItemsProgressColumn(props: TableColumnProps): TableColumn { | ||||||
|   return { |   return { | ||||||
|     accessor: 'line_items', |     accessor: 'line_items', | ||||||
|     sortable: true, |     sortable: true, | ||||||
|  |     minWidth: 125, | ||||||
|     render: (record: any) => ( |     render: (record: any) => ( | ||||||
|       <ProgressBar |       <ProgressBar | ||||||
|         progressLabel={true} |         progressLabel={true} | ||||||
|         value={record.completed_lines} |         value={record.completed_lines} | ||||||
|         maximum={record.line_items} |         maximum={record.line_items} | ||||||
|       /> |       /> | ||||||
|     ) |     ), | ||||||
|  |     ...props | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -326,31 +363,20 @@ export function ProjectCodeColumn(props: TableColumnProps): TableColumn { | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| export function StatusColumn({ | export type StatusColumnProps = TableColumnProps & { | ||||||
|   model, |  | ||||||
|   sortable, |  | ||||||
|   switchable, |  | ||||||
|   ordering, |  | ||||||
|   accessor, |  | ||||||
|   title, |  | ||||||
|   hidden |  | ||||||
| }: { |  | ||||||
|   model: ModelType; |   model: ModelType; | ||||||
|   sortable?: boolean; | }; | ||||||
|   switchable?: boolean; |  | ||||||
|   accessor?: string; | export function StatusColumn(props: StatusColumnProps): TableColumn { | ||||||
|   ordering?: string; |   const accessor: string = props.accessor ?? 'status'; | ||||||
|   hidden?: boolean; |  | ||||||
|   title?: string; |  | ||||||
| }) { |  | ||||||
|   return { |   return { | ||||||
|     accessor: accessor ?? 'status', |     accessor: 'status', | ||||||
|     sortable: sortable ?? true, |     sortable: true, | ||||||
|     switchable: switchable ?? true, |     switchable: true, | ||||||
|     ordering: ordering, |     minWidth: '50px', | ||||||
|     title: title, |     render: TableStatusRenderer(props.model, accessor ?? 'status_custom_key'), | ||||||
|     hidden: hidden, |     ...props | ||||||
|     render: TableStatusRenderer(model, accessor ?? 'status_custom_key') |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -260,7 +260,12 @@ export function InvenTreeTable<T extends Record<string, any>>({ | |||||||
|         ...col, |         ...col, | ||||||
|         hidden: hidden, |         hidden: hidden, | ||||||
|         resizable: col.resizable ?? true, |         resizable: col.resizable ?? true, | ||||||
|         title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}` |         title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}`, | ||||||
|  |         titleStyle: (record: any, index: number) => { | ||||||
|  |           return { | ||||||
|  |             minWidth: (col as any).minWidth ?? '100px' | ||||||
|  |           }; | ||||||
|  |         } | ||||||
|       }; |       }; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,13 +30,10 @@ export function UsedInTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |  | ||||||
|         switchable: false, |  | ||||||
|         sortable: true, |  | ||||||
|         title: t`Assembly`, |         title: t`Assembly`, | ||||||
|         render: (record: any) => PartColumn({ part: record.part_detail }) |         part: 'part_detail' | ||||||
|       }, |       }), | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: false, |         sortable: false, | ||||||
| @@ -51,12 +48,12 @@ export function UsedInTable({ | |||||||
|       DescriptionColumn({ |       DescriptionColumn({ | ||||||
|         accessor: 'part_detail.description' |         accessor: 'part_detail.description' | ||||||
|       }), |       }), | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'sub_part', |         accessor: 'sub_part', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         title: t`Component`, |         title: t`Component`, | ||||||
|         render: (record: any) => PartColumn({ part: record.sub_part_detail }) |         part: 'sub_part_detail' | ||||||
|       }, |       }), | ||||||
|       { |       { | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         switchable: false, |         switchable: false, | ||||||
|   | |||||||
| @@ -97,14 +97,10 @@ export default function BuildAllocatedStockTable({ | |||||||
|         title: t`Order Status`, |         title: t`Order Status`, | ||||||
|         hidden: showBuildInfo != true |         hidden: showBuildInfo != true | ||||||
|       }), |       }), | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |  | ||||||
|         hidden: !showPartInfo, |         hidden: !showPartInfo, | ||||||
|         title: t`Part`, |         switchable: false | ||||||
|         sortable: true, |       }), | ||||||
|         switchable: false, |  | ||||||
|         render: (record: any) => PartColumn({ part: record.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         ordering: 'IPN', |         ordering: 'IPN', | ||||||
| @@ -136,11 +132,11 @@ export default function BuildAllocatedStockTable({ | |||||||
|       }, |       }, | ||||||
|       DecimalColumn({ |       DecimalColumn({ | ||||||
|         accessor: 'available', |         accessor: 'available', | ||||||
|         title: t`Available Quantity` |         title: t`Available` | ||||||
|       }), |       }), | ||||||
|       DecimalColumn({ |       DecimalColumn({ | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         title: t`Allocated Quantity`, |         title: t`Allocated`, | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         switchable: false |         switchable: false | ||||||
|       }), |       }), | ||||||
|   | |||||||
| @@ -46,7 +46,8 @@ import { | |||||||
|   DecimalColumn, |   DecimalColumn, | ||||||
|   DescriptionColumn, |   DescriptionColumn, | ||||||
|   LocationColumn, |   LocationColumn, | ||||||
|   PartColumn |   PartColumn, | ||||||
|  |   RenderPartColumn | ||||||
| } from '../ColumnRenderers'; | } from '../ColumnRenderers'; | ||||||
| import { InvenTreeTable } from '../InvenTreeTable'; | import { InvenTreeTable } from '../InvenTreeTable'; | ||||||
| import RowExpansionIcon from '../RowExpansionIcon'; | import RowExpansionIcon from '../RowExpansionIcon'; | ||||||
| @@ -75,13 +76,9 @@ export function BuildLineSubTable({ | |||||||
|  |  | ||||||
|   const tableColumns: any[] = useMemo(() => { |   const tableColumns: any[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         part: 'part_detail' | ||||||
|         title: t`Part`, |       }), | ||||||
|         render: (record: any) => { |  | ||||||
|           return <PartColumn part={record.part_detail} />; |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         title: t`Quantity`, |         title: t`Quantity`, | ||||||
| @@ -305,9 +302,9 @@ export default function BuildLineTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'bom_item', |         accessor: 'bom_item', | ||||||
|         title: t`Component`, |         part: 'part_detail', | ||||||
|         ordering: 'part', |         ordering: 'part', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         switchable: false, |         switchable: false, | ||||||
| @@ -320,11 +317,11 @@ export default function BuildLineTable({ | |||||||
|                 enabled={hasAllocatedItems} |                 enabled={hasAllocatedItems} | ||||||
|                 expanded={table.isRowExpanded(record.pk)} |                 expanded={table.isRowExpanded(record.pk)} | ||||||
|               /> |               /> | ||||||
|               <PartColumn part={record.part_detail} /> |               <RenderPartColumn part={record.part_detail} /> | ||||||
|             </Group> |             </Group> | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
|       }, |       }), | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: false, |         sortable: false, | ||||||
| @@ -471,6 +468,7 @@ export default function BuildLineTable({ | |||||||
|         switchable: false, |         switchable: false, | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         hidden: !isActive, |         hidden: !isActive, | ||||||
|  |         minWidth: 125, | ||||||
|         render: (record: any) => { |         render: (record: any) => { | ||||||
|           if (record?.bom_item_detail?.consumable) { |           if (record?.bom_item_detail?.consumable) { | ||||||
|             return ( |             return ( | ||||||
| @@ -514,6 +512,7 @@ export default function BuildLineTable({ | |||||||
|         accessor: 'consumed', |         accessor: 'consumed', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         hidden: !!output?.pk, |         hidden: !!output?.pk, | ||||||
|  |         minWidth: 125, | ||||||
|         render: (record: any) => { |         render: (record: any) => { | ||||||
|           return record?.bom_item_detail?.consumable ? ( |           return record?.bom_item_detail?.consumable ? ( | ||||||
|             <Text style={{ fontStyle: 'italic' }}>{t`Consumable item`}</Text> |             <Text style={{ fontStyle: 'italic' }}>{t`Consumable item`}</Text> | ||||||
|   | |||||||
| @@ -68,12 +68,9 @@ export function BuildOrderTable({ | |||||||
|   const tableColumns = useMemo(() => { |   const tableColumns = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       ReferenceColumn({}), |       ReferenceColumn({}), | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         switchable: false | ||||||
|         sortable: true, |       }), | ||||||
|         switchable: false, |  | ||||||
|         render: (record: any) => PartColumn({ part: record.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: true, |         sortable: true, | ||||||
| @@ -92,6 +89,8 @@ export function BuildOrderTable({ | |||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         accessor: 'completed', |         accessor: 'completed', | ||||||
|  |         title: t`Completed`, | ||||||
|  |         minWidth: 125, | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         switchable: false, |         switchable: false, | ||||||
|         render: (record: any) => ( |         render: (record: any) => ( | ||||||
|   | |||||||
| @@ -56,7 +56,12 @@ import useStatusCodes from '../../hooks/UseStatusCodes'; | |||||||
| import { useStockAdjustActions } from '../../hooks/UseStockAdjustActions'; | import { useStockAdjustActions } from '../../hooks/UseStockAdjustActions'; | ||||||
| import { useTable } from '../../hooks/UseTable'; | import { useTable } from '../../hooks/UseTable'; | ||||||
| import { useUserState } from '../../states/UserState'; | import { useUserState } from '../../states/UserState'; | ||||||
| import { LocationColumn, PartColumn, StatusColumn } from '../ColumnRenderers'; | import { | ||||||
|  |   LocationColumn, | ||||||
|  |   PartColumn, | ||||||
|  |   RenderPartColumn, | ||||||
|  |   StatusColumn | ||||||
|  | } from '../ColumnRenderers'; | ||||||
| import { | import { | ||||||
|   BatchFilter, |   BatchFilter, | ||||||
|   HasBatchCodeFilter, |   HasBatchCodeFilter, | ||||||
| @@ -100,7 +105,7 @@ function OutputAllocationDrawer({ | |||||||
|           <Space h='lg' /> |           <Space h='lg' /> | ||||||
|           <Paper withBorder p='sm'> |           <Paper withBorder p='sm'> | ||||||
|             <Group gap='xs'> |             <Group gap='xs'> | ||||||
|               <PartColumn part={build.part_detail} /> |               <RenderPartColumn part={build.part_detail} /> | ||||||
|               {output?.serial && ( |               {output?.serial && ( | ||||||
|                 <Text size='sm'> |                 <Text size='sm'> | ||||||
|                   {t`Serial Number`}: {output.serial} |                   {t`Serial Number`}: {output.serial} | ||||||
| @@ -578,11 +583,7 @@ export default function BuildOutputTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({}), | ||||||
|         accessor: 'part', |  | ||||||
|         sortable: true, |  | ||||||
|         render: (record: any) => PartColumn({ part: record?.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         ordering: 'stock', |         ordering: 'stock', | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ export function CompanyTable({ | |||||||
|     return [ |     return [ | ||||||
|       { |       { | ||||||
|         accessor: 'name', |         accessor: 'name', | ||||||
|  |         title: t`Company`, | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         switchable: false, |         switchable: false, | ||||||
|         render: (record: any) => { |         render: (record: any) => { | ||||||
|   | |||||||
| @@ -365,14 +365,10 @@ export default function ParametricPartTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     const partColumns: TableColumn[] = [ |     const partColumns: TableColumn[] = [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'name', |         part: '', | ||||||
|         title: t`Part`, |         switchable: false | ||||||
|         sortable: true, |       }), | ||||||
|         switchable: false, |  | ||||||
|         noWrap: true, |  | ||||||
|         render: (record: any) => PartColumn({ part: record }) |  | ||||||
|       }, |  | ||||||
|       DescriptionColumn({ |       DescriptionColumn({ | ||||||
|         defaultVisible: false |         defaultVisible: false | ||||||
|       }), |       }), | ||||||
|   | |||||||
| @@ -55,22 +55,18 @@ export default function PartBuildAllocationsTable({ | |||||||
|           </Group> |           </Group> | ||||||
|         ) |         ) | ||||||
|       }, |       }, | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'assembly_detail', |         part: 'assembly_detail', | ||||||
|         title: t`Assembly`, |         title: t`Assembly` | ||||||
|         switchable: false, |       }), | ||||||
|         render: (record: any) => <PartColumn part={record.assembly_detail} /> |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'assembly_detail.IPN', |         accessor: 'assembly_detail.IPN', | ||||||
|         title: t`Assembly IPN` |         title: t`Assembly IPN` | ||||||
|       }, |       }, | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part_detail', |         part: 'part_detail', | ||||||
|         title: t`Part`, |         defaultVisible: false | ||||||
|         defaultVisible: false, |       }), | ||||||
|         render: (record: any) => <PartColumn part={record.part_detail} /> |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         defaultVisible: false, |         defaultVisible: false, | ||||||
|   | |||||||
| @@ -52,11 +52,9 @@ export function PartParameterTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         part: 'part_detail' | ||||||
|         sortable: true, |       }), | ||||||
|         render: (record: any) => PartColumn({ part: record?.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: false, |         sortable: false, | ||||||
|   | |||||||
| @@ -53,11 +53,9 @@ export default function PartSalesAllocationsTable({ | |||||||
|       DescriptionColumn({ |       DescriptionColumn({ | ||||||
|         accessor: 'order_detail.description' |         accessor: 'order_detail.description' | ||||||
|       }), |       }), | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part_detail', |         part: 'part_detail' | ||||||
|         title: t`Part`, |       }), | ||||||
|         render: (record: any) => <PartColumn part={record.part_detail} /> |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         title: t`IPN` |         title: t`IPN` | ||||||
|   | |||||||
| @@ -39,14 +39,10 @@ import { TableHoverCard } from '../TableHoverCard'; | |||||||
|  */ |  */ | ||||||
| function partTableColumns(): TableColumn[] { | function partTableColumns(): TableColumn[] { | ||||||
|   return [ |   return [ | ||||||
|     { |     PartColumn({ | ||||||
|       accessor: 'name', |       part: '', | ||||||
|       title: t`Part`, |       accessor: 'name' | ||||||
|       sortable: true, |     }), | ||||||
|       noWrap: true, |  | ||||||
|       switchable: false, |  | ||||||
|       render: (record: any) => PartColumn({ part: record }) |  | ||||||
|     }, |  | ||||||
|     { |     { | ||||||
|       accessor: 'IPN', |       accessor: 'IPN', | ||||||
|       sortable: true |       sortable: true | ||||||
|   | |||||||
| @@ -41,12 +41,9 @@ export function ManufacturerPartTable({ | |||||||
|   // Construct table columns for this table |   // Construct table columns for this table | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         switchable: 'part' in params | ||||||
|         switchable: 'part' in params, |       }), | ||||||
|         sortable: true, |  | ||||||
|         render: (record: any) => PartColumn({ part: record?.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'manufacturer', |         accessor: 'manufacturer', | ||||||
|         sortable: true, |         sortable: true, | ||||||
| @@ -56,7 +53,7 @@ export function ManufacturerPartTable({ | |||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         accessor: 'MPN', |         accessor: 'MPN', | ||||||
|         title: t`Manufacturer Part Number`, |         title: t`MPN`, | ||||||
|         sortable: true |         sortable: true | ||||||
|       }, |       }, | ||||||
|       DescriptionColumn({}), |       DescriptionColumn({}), | ||||||
|   | |||||||
| @@ -132,14 +132,10 @@ export function PurchaseOrderLineItemTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         part: 'part_detail', | ||||||
|         title: t`Part`, |         ordering: 'part_name' | ||||||
|         sortable: true, |       }), | ||||||
|         ordering: 'part_name', |  | ||||||
|         switchable: false, |  | ||||||
|         render: (record: any) => PartColumn({ part: record.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ export function PurchaseOrderTable({ | |||||||
|       { |       { | ||||||
|         accessor: 'supplier_reference' |         accessor: 'supplier_reference' | ||||||
|       }, |       }, | ||||||
|       LineItemsProgressColumn(), |       LineItemsProgressColumn({}), | ||||||
|       StatusColumn({ model: ModelType.purchaseorder }), |       StatusColumn({ model: ModelType.purchaseorder }), | ||||||
|       ProjectCodeColumn({ |       ProjectCodeColumn({ | ||||||
|         defaultVisible: false |         defaultVisible: false | ||||||
|   | |||||||
| @@ -48,13 +48,10 @@ export function SupplierPartTable({ | |||||||
|   // Construct table columns for this table |   // Construct table columns for this table | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |  | ||||||
|         switchable: 'part' in params, |         switchable: 'part' in params, | ||||||
|         sortable: true, |         part: 'part_detail' | ||||||
|         render: (record: any) => |       }), | ||||||
|           PartColumn({ part: record?.part_detail, full_name: true }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'supplier', |         accessor: 'supplier', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|   | |||||||
| @@ -106,12 +106,9 @@ export default function ReturnOrderLineItemTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         part: 'part_detail' | ||||||
|         title: t`Part`, |       }), | ||||||
|         switchable: false, |  | ||||||
|         render: (record: any) => PartColumn({ part: record?.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'part_detail.IPN', |         accessor: 'part_detail.IPN', | ||||||
|         sortable: false |         sortable: false | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ export function ReturnOrderTable({ | |||||||
|         accessor: 'customer_reference' |         accessor: 'customer_reference' | ||||||
|       }, |       }, | ||||||
|       DescriptionColumn({}), |       DescriptionColumn({}), | ||||||
|       LineItemsProgressColumn(), |       LineItemsProgressColumn({}), | ||||||
|       StatusColumn({ model: ModelType.returnorder }), |       StatusColumn({ model: ModelType.returnorder }), | ||||||
|       ProjectCodeColumn({ |       ProjectCodeColumn({ | ||||||
|         defaultVisible: false |         defaultVisible: false | ||||||
|   | |||||||
| @@ -119,14 +119,10 @@ export default function SalesOrderAllocationTable({ | |||||||
|         title: t`Order Status`, |         title: t`Order Status`, | ||||||
|         hidden: showOrderInfo != true |         hidden: showOrderInfo != true | ||||||
|       }), |       }), | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |  | ||||||
|         hidden: showPartInfo != true, |         hidden: showPartInfo != true, | ||||||
|         title: t`Part`, |         part: 'part_detail' | ||||||
|         sortable: true, |       }), | ||||||
|         switchable: false, |  | ||||||
|         render: (record: any) => PartColumn({ part: record.part_detail }) |  | ||||||
|       }, |  | ||||||
|       DescriptionColumn({ |       DescriptionColumn({ | ||||||
|         accessor: 'part_detail.description', |         accessor: 'part_detail.description', | ||||||
|         hidden: showPartInfo != true |         hidden: showPartInfo != true | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ import { | |||||||
|   DecimalColumn, |   DecimalColumn, | ||||||
|   DescriptionColumn, |   DescriptionColumn, | ||||||
|   LinkColumn, |   LinkColumn, | ||||||
|   PartColumn |   RenderPartColumn | ||||||
| } from '../ColumnRenderers'; | } from '../ColumnRenderers'; | ||||||
| import { InvenTreeTable } from '../InvenTreeTable'; | import { InvenTreeTable } from '../InvenTreeTable'; | ||||||
| import RowExpansionIcon from '../RowExpansionIcon'; | import RowExpansionIcon from '../RowExpansionIcon'; | ||||||
| @@ -78,6 +78,7 @@ export default function SalesOrderLineItemTable({ | |||||||
|         accessor: 'part', |         accessor: 'part', | ||||||
|         sortable: true, |         sortable: true, | ||||||
|         switchable: false, |         switchable: false, | ||||||
|  |         minWidth: 175, | ||||||
|         render: (record: any) => { |         render: (record: any) => { | ||||||
|           return ( |           return ( | ||||||
|             <Group wrap='nowrap'> |             <Group wrap='nowrap'> | ||||||
| @@ -85,7 +86,7 @@ export default function SalesOrderLineItemTable({ | |||||||
|                 enabled={record.allocated} |                 enabled={record.allocated} | ||||||
|                 expanded={table.isRowExpanded(record.pk)} |                 expanded={table.isRowExpanded(record.pk)} | ||||||
|               /> |               /> | ||||||
|               <PartColumn part={record.part_detail} /> |               <RenderPartColumn part={record.part_detail} /> | ||||||
|             </Group> |             </Group> | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -141,10 +141,11 @@ export function SalesOrderTable({ | |||||||
|         title: t`Customer Reference` |         title: t`Customer Reference` | ||||||
|       }, |       }, | ||||||
|       DescriptionColumn({}), |       DescriptionColumn({}), | ||||||
|       LineItemsProgressColumn(), |       LineItemsProgressColumn({}), | ||||||
|       { |       { | ||||||
|         accessor: 'shipments_count', |         accessor: 'shipments_count', | ||||||
|         title: t`Shipments`, |         title: t`Shipments`, | ||||||
|  |         minWidth: 125, | ||||||
|         render: (record: any) => ( |         render: (record: any) => ( | ||||||
|           <ProgressBar |           <ProgressBar | ||||||
|             progressLabel |             progressLabel | ||||||
|   | |||||||
| @@ -58,11 +58,9 @@ export default function InstalledItemsTable({ | |||||||
|  |  | ||||||
|   const tableColumns: TableColumn[] = useMemo(() => { |   const tableColumns: TableColumn[] = useMemo(() => { | ||||||
|     return [ |     return [ | ||||||
|       { |       PartColumn({ | ||||||
|         accessor: 'part', |         part: 'part' | ||||||
|         switchable: false, |       }), | ||||||
|         render: (record: any) => PartColumn({ part: record?.part_detail }) |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         accessor: 'quantity', |         accessor: 'quantity', | ||||||
|         switchable: false, |         switchable: false, | ||||||
|   | |||||||
| @@ -61,11 +61,10 @@ function stockItemTableColumns({ | |||||||
|   showPricing: boolean; |   showPricing: boolean; | ||||||
| }): TableColumn[] { | }): TableColumn[] { | ||||||
|   return [ |   return [ | ||||||
|     { |     PartColumn({ | ||||||
|       accessor: 'part', |       accessor: 'part', | ||||||
|       sortable: true, |       part: 'part_detail' | ||||||
|       render: (record: any) => PartColumn({ part: record?.part_detail }) |     }), | ||||||
|     }, |  | ||||||
|     { |     { | ||||||
|       accessor: 'part_detail.IPN', |       accessor: 'part_detail.IPN', | ||||||
|       title: t`IPN`, |       title: t`IPN`, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user