Skip to content

Commit 2ed7053

Browse files
authored
AdvancedTable - Dynamic columns fix (#3266)
1 parent ea23bde commit 2ed7053

File tree

6 files changed

+419
-57
lines changed

6 files changed

+419
-57
lines changed

packages/components/src/components/hds/advanced-table/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ export default class HdsAdvancedTable extends Component<HdsAdvancedTableSignatur
231231
columns,
232232
columnOrder,
233233
childrenKey,
234+
hasReorderableColumns,
234235
hasResizableColumns,
235236
sortBy,
236237
sortOrder,
@@ -243,6 +244,7 @@ export default class HdsAdvancedTable extends Component<HdsAdvancedTableSignatur
243244
columns,
244245
columnOrder,
245246
childrenKey,
247+
hasReorderableColumns,
246248
hasResizableColumns,
247249
sortBy,
248250
sortOrder,

packages/components/src/components/hds/advanced-table/models/row.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import { action } from '@ember/object';
88
import { guidFor } from '@ember/object/internals';
99

1010
import type { HdsAdvancedTableColumn, HdsAdvancedTableCell } from '../types';
11+
import type HdsAdvancedTableTableModel from './table';
1112

1213
interface HdsAdvancedTableRowArgs {
1314
[key: string]: unknown;
1415
columns: HdsAdvancedTableColumn[];
16+
table: HdsAdvancedTableTableModel;
1517
id?: string;
1618
childrenKey?: string;
17-
columnOrder?: string[];
1819
}
1920

2021
export default class HdsAdvancedTableRow {
@@ -25,10 +26,10 @@ export default class HdsAdvancedTableRow {
2526

2627
@tracked isOpen: boolean = false;
2728
@tracked cells: HdsAdvancedTableCell[] = [];
28-
@tracked columnOrder: string[] = [];
2929

3030
children: HdsAdvancedTableRow[] = [];
3131
childrenKey: string;
32+
table: HdsAdvancedTableTableModel;
3233

3334
get hasChildren(): boolean {
3435
return this.children.length > 0;
@@ -39,21 +40,27 @@ export default class HdsAdvancedTableRow {
3940
}
4041

4142
get orderedCells(): HdsAdvancedTableCell[] {
42-
return this.columnOrder.map((key) => {
43-
const cell = this.cells.find((cell) => cell.columnKey === key);
43+
const { columnOrder, hasReorderableColumns } = this.table;
4444

45-
if (cell === undefined) {
46-
throw new Error(
47-
`Cell in the column with key ${key} not found for the row.`
48-
);
49-
}
45+
if (hasReorderableColumns) {
46+
return columnOrder.reduce<HdsAdvancedTableCell[]>((acc, key) => {
47+
const cell = this.cells.find((cell) => cell.columnKey === key);
5048

51-
return cell;
52-
});
49+
if (cell !== undefined) {
50+
acc.push(cell);
51+
}
52+
53+
return acc;
54+
}, []);
55+
} else {
56+
return this.cells;
57+
}
5358
}
5459

5560
constructor(args: HdsAdvancedTableRowArgs) {
56-
const { columns } = args;
61+
const { columns, table } = args;
62+
63+
this.table = table;
5764

5865
this.cells = columns.map((column) => {
5966
const cell = args[column.key ?? ''];
@@ -64,9 +71,6 @@ export default class HdsAdvancedTableRow {
6471
};
6572
});
6673

67-
this.columnOrder =
68-
args.columnOrder ?? this.cells.map((cell) => cell.columnKey);
69-
7074
// set row data
7175
Object.assign(this, args);
7276

packages/components/src/components/hds/advanced-table/models/table.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type HdsAdvancedTableTableArgs = Pick<
2828
| 'columns'
2929
| 'columnOrder'
3030
| 'childrenKey'
31+
| 'hasReorderableColumns'
3132
| 'hasResizableColumns'
3233
| 'sortBy'
3334
| 'sortOrder'
@@ -67,6 +68,7 @@ export default class HdsAdvancedTableTableModel {
6768
@tracked gridElement?: HTMLDivElement = undefined;
6869

6970
childrenKey?: HdsAdvancedTableTableArgs['childrenKey'];
71+
hasReorderableColumns?: HdsAdvancedTableTableArgs['hasReorderableColumns'];
7072
hasResizableColumns?: HdsAdvancedTableTableArgs['hasResizableColumns'];
7173
onColumnReorder?: HdsAdvancedTableColumnReorderCallback;
7274
onSort?: HdsAdvancedTableSignature['Args']['onSort'];
@@ -77,6 +79,7 @@ export default class HdsAdvancedTableTableModel {
7779
columns,
7880
columnOrder,
7981
childrenKey,
82+
hasReorderableColumns,
8083
hasResizableColumns,
8184
sortBy,
8285
sortOrder,
@@ -85,17 +88,20 @@ export default class HdsAdvancedTableTableModel {
8588
} = args;
8689

8790
this.childrenKey = childrenKey;
91+
this.hasReorderableColumns = hasReorderableColumns;
8892
this.hasResizableColumns = hasResizableColumns;
8993
this.onSort = onSort;
9094

9195
this.setupData({ model, columns, sortBy, sortOrder });
9296

9397
// set initial column order
94-
this.columnOrder = isEmpty(columnOrder)
95-
? this.columns.map((column) => column.key)
96-
: columnOrder!; // ensured non-empty
98+
if (this.hasReorderableColumns) {
99+
this.columnOrder = isEmpty(columnOrder)
100+
? this.columns.map((column) => column.key)
101+
: columnOrder!; // ensured non-empty
97102

98-
this.onColumnReorder = onColumnReorder;
103+
this.onColumnReorder = onColumnReorder;
104+
}
99105
}
100106

101107
get hasColumnBeingDragged(): boolean {
@@ -117,15 +123,19 @@ export default class HdsAdvancedTableTableModel {
117123
}
118124

119125
get orderedColumns(): HdsAdvancedTableColumn[] {
120-
return this.columnOrder.map((key) => {
121-
const column = this.columns.find((column) => column.key === key);
126+
if (this.hasReorderableColumns) {
127+
return this.columnOrder.reduce<HdsAdvancedTableColumn[]>((acc, key) => {
128+
const column = this.columns.find((column) => column.key === key);
122129

123-
if (!column) {
124-
throw new Error(`Column with key ${key} not found`);
125-
}
130+
if (column !== undefined) {
131+
acc.push(column);
132+
}
126133

127-
return column;
128-
});
134+
return acc;
135+
}, []);
136+
} else {
137+
return this.columns;
138+
}
129139
}
130140

131141
get sortCriteria(): string | HdsAdvancedTableSortingFunction<unknown> {
@@ -254,6 +264,7 @@ export default class HdsAdvancedTableTableModel {
254264
...row,
255265
childrenKey: this.childrenKey,
256266
columns,
267+
table: this,
257268
});
258269
});
259270
}
@@ -367,8 +378,11 @@ export default class HdsAdvancedTableTableModel {
367378
targetColumn: HdsAdvancedTableColumn,
368379
side: HdsAdvancedTableColumnReorderSide
369380
): void {
370-
const oldIndex = this.orderedColumns.indexOf(sourceColumn);
371-
const newIndex = this.orderedColumns.indexOf(targetColumn);
381+
const sourceKey = sourceColumn.key;
382+
const targetKey = targetColumn.key;
383+
384+
const oldIndex = this.columnOrder.indexOf(sourceKey);
385+
const newIndex = this.columnOrder.indexOf(targetKey);
372386

373387
if (oldIndex !== -1 && newIndex !== -1) {
374388
const updated = [...this.columnOrder];
@@ -392,10 +406,6 @@ export default class HdsAdvancedTableTableModel {
392406

393407
this.columnOrder = updated;
394408

395-
for (const row of this.rows) {
396-
row.columnOrder = updated;
397-
}
398-
399409
// we need to wait until the reposition has finished
400410
requestAnimationFrame(() => {
401411
sourceColumn.thElement?.scrollIntoView({

showcase/app/components/page-components/advanced-table/code-fragments/with-simple-data.gts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@
44
*/
55

66
import Component from '@glimmer/component';
7+
import { get } from '@ember/helper';
78

89
import USERS from 'showcase/mocks/user-data';
910

1011
import { HdsAdvancedTable } from '@hashicorp/design-system-components/components';
12+
1113
import type { HdsAdvancedTableSignature } from '@hashicorp/design-system-components/components/hds/advanced-table/index';
1214

15+
export const DEFAULT_COLUMNS = [
16+
{ key: 'id', label: 'ID' },
17+
{ key: 'name', label: 'Name' },
18+
{ key: 'email', label: 'Email' },
19+
{ key: 'role', label: 'Role' },
20+
];
21+
1322
export interface CodeFragmentWithSimpleDataSignature {
1423
Args: {
1524
isSelectable?: HdsAdvancedTableSignature['Args']['isSelectable'];
25+
columns?: HdsAdvancedTableSignature['Args']['columns'];
1626
density?: HdsAdvancedTableSignature['Args']['density'];
1727
isStriped?: HdsAdvancedTableSignature['Args']['isStriped'];
1828
hasTooltips?: boolean;
@@ -21,14 +31,11 @@ export interface CodeFragmentWithSimpleDataSignature {
2131
}
2232

2333
export default class CodeFragmentWithSimpleData extends Component<CodeFragmentWithSimpleDataSignature> {
24-
model = USERS.slice(0, 4);
34+
get columns(): HdsAdvancedTableSignature['Args']['columns'] {
35+
return this.args.columns ?? DEFAULT_COLUMNS;
36+
}
2537

26-
columns = [
27-
{ key: 'id', label: 'ID' },
28-
{ key: 'name', label: 'Name' },
29-
{ key: 'email', label: 'Email' },
30-
{ key: 'role', label: 'Role' },
31-
];
38+
model = USERS.slice(0, 4);
3239

3340
columnsWithTooltips = [
3441
{
@@ -54,14 +61,10 @@ export default class CodeFragmentWithSimpleData extends Component<CodeFragmentWi
5461
<:body as |B|>
5562
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
5663
<B.Tr @selectionKey="{{B.data.id}}">
57-
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
58-
<B.Td>{{B.data.id}}</B.Td>
59-
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
60-
<B.Td>{{B.data.name}}</B.Td>
61-
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
62-
<B.Td>{{B.data.email}}</B.Td>
63-
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
64-
<B.Td>{{B.data.role}}</B.Td>
64+
{{#each this.columns as |column|}}
65+
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
66+
<B.Td>{{get B.data column.key}}</B.Td>
67+
{{/each}}
6568
</B.Tr>
6669
</:body>
6770
</HdsAdvancedTable>

0 commit comments

Comments
 (0)