Skip to content

Commit ed31503

Browse files
Column min width (#10204)
* Support minimum column width * Adjust DescriptionColumn and StatusColumn * Column refactoring * Refactor PartColumn * Refactor LineItemsProgerssColumn * Tweaks
1 parent 76dfd62 commit ed31503

30 files changed

+170
-181
lines changed

src/frontend/lib/types/Tables.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export type TableState = {
9191
* @param filter - A custom filter function
9292
* @param filtering - Whether the column is filterable
9393
* @param width - The width of the column
94+
* @param minWidth - The minimum width of the column
9495
* @param resizable - Whether the column is resizable (defaults to true)
9596
* @param noWrap - Whether the column should wrap
9697
* @param ellipsis - Whether the column should be ellipsized
@@ -113,13 +114,15 @@ export type TableColumnProps<T = any> = {
113114
filter?: any;
114115
filtering?: boolean;
115116
width?: number;
117+
minWidth?: string | number;
116118
resizable?: boolean;
117119
noWrap?: boolean;
118120
ellipsis?: boolean;
119121
textAlign?: 'left' | 'center' | 'right';
120122
cellsStyle?: any;
121123
extra?: any;
122124
noContext?: boolean;
125+
style?: MantineStyleProp;
123126
};
124127

125128
/**

src/frontend/src/components/wizards/OrderPartsWizard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useSupplierPartFields } from '../../forms/CompanyForms';
1414
import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms';
1515
import { useCreateApiFormModal } from '../../hooks/UseForm';
1616
import useWizard from '../../hooks/UseWizard';
17-
import { PartColumn } from '../../tables/ColumnRenderers';
17+
import { RenderPartColumn } from '../../tables/ColumnRenderers';
1818
import RemoveRowButton from '../buttons/RemoveRowButton';
1919
import { StandaloneField } from '../forms/StandaloneField';
2020
import Expand from '../items/Expand';
@@ -133,7 +133,7 @@ function SelectPartsStep({
133133
render: (record: PartOrderRecord) => (
134134
<Tooltip label={record.part?.description}>
135135
<Paper p='xs'>
136-
<PartColumn part={record.part} />
136+
<RenderPartColumn part={record.part} />
137137
</Paper>
138138
</Tooltip>
139139
)

src/frontend/src/forms/BuildForms.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
useSerialNumberGenerator
3737
} from '../hooks/UseGenerator';
3838
import { useGlobalSettingsState } from '../states/SettingsStates';
39-
import { PartColumn } from '../tables/ColumnRenderers';
39+
import { RenderPartColumn } from '../tables/ColumnRenderers';
4040

4141
/**
4242
* Field set for BuildOrder forms
@@ -248,7 +248,7 @@ function BuildOutputFormRow({
248248
<>
249249
<Table.Tr>
250250
<Table.Td>
251-
<PartColumn part={record.part_detail} />
251+
<RenderPartColumn part={record.part_detail} />
252252
</Table.Td>
253253
<Table.Td>
254254
<TableFieldErrorWrapper props={props} errorKey='output'>
@@ -541,7 +541,7 @@ function BuildAllocateLineRow({
541541
return (
542542
<Table.Tr key={`table-row-${record.pk}`}>
543543
<Table.Td>
544-
<PartColumn part={record.part_detail} />
544+
<RenderPartColumn part={record.part_detail} />
545545
</Table.Td>
546546
<Table.Td>
547547
<ProgressBar
@@ -704,7 +704,7 @@ function BuildConsumeItemRow({
704704
return (
705705
<Table.Tr key={`table-row-${record.pk}`}>
706706
<Table.Td>
707-
<PartColumn part={record.part_detail} />
707+
<RenderPartColumn part={record.part_detail} />
708708
</Table.Td>
709709
<Table.Td>
710710
<RenderStockItem instance={record.stock_item_detail} />
@@ -807,7 +807,7 @@ function BuildConsumeLineRow({
807807
return (
808808
<Table.Tr key={`table-row-${record.pk}`}>
809809
<Table.Td>
810-
<PartColumn part={record.part_detail} />
810+
<RenderPartColumn part={record.part_detail} />
811811
</Table.Td>
812812
<Table.Td>
813813
{remaining <= 0 ? (

src/frontend/src/forms/SalesOrderForms.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323
import type { TableFieldRowProps } from '../components/forms/fields/TableField';
2424
import { useCreateApiFormModal } from '../hooks/UseForm';
2525
import { useGlobalSettingsState } from '../states/SettingsStates';
26-
import { PartColumn } from '../tables/ColumnRenderers';
26+
import { RenderPartColumn } from '../tables/ColumnRenderers';
2727

2828
export function useSalesOrderFields({
2929
duplicateOrderId
@@ -197,7 +197,7 @@ function SalesOrderAllocateLineRow({
197197
return (
198198
<Table.Tr key={`table-row-${props.idx}-${record.pk}`}>
199199
<Table.Td>
200-
<PartColumn part={record.part_detail} />
200+
<RenderPartColumn part={record.part_detail} />
201201
</Table.Td>
202202
<Table.Td>
203203
<ProgressBar

src/frontend/src/pages/part/pricing/BomPricingPanel.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,11 @@ export default function BomPricingPanel({
136136

137137
const columns: TableColumn[] = useMemo(() => {
138138
return [
139-
{
139+
PartColumn({
140140
accessor: 'name',
141141
title: t`Component`,
142-
sortable: true,
143-
switchable: false,
144-
render: (record: any) => PartColumn({ part: record.sub_part_detail })
145-
},
142+
part: 'sub_part_detail'
143+
}),
146144
{
147145
accessor: 'quantity',
148146
title: t`Quantity`,

src/frontend/src/pages/part/pricing/VariantPricingPanel.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ export default function VariantPricingPanel({
2525

2626
const columns: TableColumn[] = useMemo(() => {
2727
return [
28-
{
29-
accessor: 'name',
28+
PartColumn({
3029
title: t`Variant Part`,
31-
sortable: true,
32-
switchable: false,
33-
render: (record: any) => PartColumn({ part: record, full_name: true })
34-
},
30+
part: '',
31+
full_name: true
32+
}),
3533
{
3634
accessor: 'pricing_min',
3735
title: t`Minimum Price`,

src/frontend/src/tables/ColumnRenderers.tsx

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,24 @@ import {
3030
} from '../states/SettingsStates';
3131
import { ProjectCodeHoverCard, TableHoverCard } from './TableHoverCard';
3232

33-
// Render a Part instance within a table
34-
export function PartColumn({
33+
export type PartColumnProps = TableColumnProps & {
34+
part?: string;
35+
full_name?: boolean;
36+
};
37+
38+
// Extract rendering function for Part column
39+
export function RenderPartColumn({
3540
part,
3641
full_name
3742
}: {
3843
part: any;
3944
full_name?: boolean;
4045
}) {
41-
return part ? (
46+
if (!part) {
47+
return <Skeleton />;
48+
}
49+
50+
return (
4251
<Group justify='space-between' wrap='nowrap'>
4352
<Thumbnail
4453
src={part?.thumbnail ?? part?.image}
@@ -63,11 +72,32 @@ export function PartColumn({
6372
)}
6473
</Group>
6574
</Group>
66-
) : (
67-
<Skeleton />
6875
);
6976
}
7077

78+
// Render a Part instance within a table
79+
export function PartColumn(props: PartColumnProps): TableColumn {
80+
return {
81+
accessor: 'part',
82+
title: t`Part`,
83+
sortable: true,
84+
switchable: false,
85+
minWidth: '175px',
86+
render: (record: any) => {
87+
const part =
88+
props.part === ''
89+
? record
90+
: resolveItem(record, props.part ?? props.accessor ?? 'part_detail');
91+
92+
return RenderPartColumn({
93+
part: part,
94+
full_name: props.full_name ?? false
95+
});
96+
},
97+
...props
98+
};
99+
}
100+
71101
export function CompanyColumn({
72102
company
73103
}: {
@@ -146,6 +176,7 @@ export function LocationColumn(props: TableColumnProps): TableColumn {
146176
title: t`Location`,
147177
sortable: true,
148178
ordering: 'location',
179+
minWidth: '150px',
149180
...props
150181
});
151182
} else {
@@ -154,6 +185,7 @@ export function LocationColumn(props: TableColumnProps): TableColumn {
154185
title: t`Location`,
155186
sortable: true,
156187
ordering: 'location',
188+
minWidth: '125px',
157189
...props
158190
});
159191
}
@@ -192,6 +224,7 @@ export function CategoryColumn(props: TableColumnProps): TableColumn {
192224
title: t`Category`,
193225
sortable: true,
194226
ordering: 'category',
227+
minWidth: '150px',
195228
...props
196229
});
197230
} else {
@@ -200,6 +233,7 @@ export function CategoryColumn(props: TableColumnProps): TableColumn {
200233
title: t`Category`,
201234
sortable: true,
202235
ordering: 'category',
236+
minWidth: '125px',
203237
...props
204238
});
205239
}
@@ -209,6 +243,7 @@ export function BooleanColumn(props: TableColumn): TableColumn {
209243
return {
210244
sortable: true,
211245
switchable: true,
246+
minWidth: '75px',
212247
render: (record: any) => (
213248
<Center>
214249
<YesNoButton value={resolveItem(record, props.accessor ?? '')} />
@@ -234,7 +269,7 @@ export function DescriptionColumn(props: TableColumnProps): TableColumn {
234269
title: t`Description`,
235270
sortable: false,
236271
switchable: true,
237-
width: 300,
272+
minWidth: '200px',
238273
...props
239274
};
240275
}
@@ -291,17 +326,19 @@ export function NoteColumn(props: TableColumnProps): TableColumn {
291326
};
292327
}
293328

294-
export function LineItemsProgressColumn(): TableColumn {
329+
export function LineItemsProgressColumn(props: TableColumnProps): TableColumn {
295330
return {
296331
accessor: 'line_items',
297332
sortable: true,
333+
minWidth: 125,
298334
render: (record: any) => (
299335
<ProgressBar
300336
progressLabel={true}
301337
value={record.completed_lines}
302338
maximum={record.line_items}
303339
/>
304-
)
340+
),
341+
...props
305342
};
306343
}
307344

@@ -326,31 +363,20 @@ export function ProjectCodeColumn(props: TableColumnProps): TableColumn {
326363
};
327364
}
328365

329-
export function StatusColumn({
330-
model,
331-
sortable,
332-
switchable,
333-
ordering,
334-
accessor,
335-
title,
336-
hidden
337-
}: {
366+
export type StatusColumnProps = TableColumnProps & {
338367
model: ModelType;
339-
sortable?: boolean;
340-
switchable?: boolean;
341-
accessor?: string;
342-
ordering?: string;
343-
hidden?: boolean;
344-
title?: string;
345-
}) {
368+
};
369+
370+
export function StatusColumn(props: StatusColumnProps): TableColumn {
371+
const accessor: string = props.accessor ?? 'status';
372+
346373
return {
347-
accessor: accessor ?? 'status',
348-
sortable: sortable ?? true,
349-
switchable: switchable ?? true,
350-
ordering: ordering,
351-
title: title,
352-
hidden: hidden,
353-
render: TableStatusRenderer(model, accessor ?? 'status_custom_key')
374+
accessor: 'status',
375+
sortable: true,
376+
switchable: true,
377+
minWidth: '50px',
378+
render: TableStatusRenderer(props.model, accessor ?? 'status_custom_key'),
379+
...props
354380
};
355381
}
356382

src/frontend/src/tables/InvenTreeTable.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,12 @@ export function InvenTreeTable<T extends Record<string, any>>({
260260
...col,
261261
hidden: hidden,
262262
resizable: col.resizable ?? true,
263-
title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}`
263+
title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}`,
264+
titleStyle: (record: any, index: number) => {
265+
return {
266+
minWidth: (col as any).minWidth ?? '100px'
267+
};
268+
}
264269
};
265270
});
266271

src/frontend/src/tables/bom/UsedInTable.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@ export function UsedInTable({
3030

3131
const tableColumns: TableColumn[] = useMemo(() => {
3232
return [
33-
{
34-
accessor: 'part',
35-
switchable: false,
36-
sortable: true,
33+
PartColumn({
3734
title: t`Assembly`,
38-
render: (record: any) => PartColumn({ part: record.part_detail })
39-
},
35+
part: 'part_detail'
36+
}),
4037
{
4138
accessor: 'part_detail.IPN',
4239
sortable: false,
@@ -51,12 +48,12 @@ export function UsedInTable({
5148
DescriptionColumn({
5249
accessor: 'part_detail.description'
5350
}),
54-
{
51+
PartColumn({
5552
accessor: 'sub_part',
5653
sortable: true,
5754
title: t`Component`,
58-
render: (record: any) => PartColumn({ part: record.sub_part_detail })
59-
},
55+
part: 'sub_part_detail'
56+
}),
6057
{
6158
accessor: 'quantity',
6259
switchable: false,

src/frontend/src/tables/build/BuildAllocatedStockTable.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,10 @@ export default function BuildAllocatedStockTable({
9797
title: t`Order Status`,
9898
hidden: showBuildInfo != true
9999
}),
100-
{
101-
accessor: 'part',
100+
PartColumn({
102101
hidden: !showPartInfo,
103-
title: t`Part`,
104-
sortable: true,
105-
switchable: false,
106-
render: (record: any) => PartColumn({ part: record.part_detail })
107-
},
102+
switchable: false
103+
}),
108104
{
109105
accessor: 'part_detail.IPN',
110106
ordering: 'IPN',
@@ -136,11 +132,11 @@ export default function BuildAllocatedStockTable({
136132
},
137133
DecimalColumn({
138134
accessor: 'available',
139-
title: t`Available Quantity`
135+
title: t`Available`
140136
}),
141137
DecimalColumn({
142138
accessor: 'quantity',
143-
title: t`Allocated Quantity`,
139+
title: t`Allocated`,
144140
sortable: true,
145141
switchable: false
146142
}),

0 commit comments

Comments
 (0)