Skip to content

Commit 7448a88

Browse files
authored
refactor: Replace usage of Column.index with column name (#1126)
resolves #965 BREAKING CHANGE: Removed index property from dh.types Column type. IrisGridUtils.dehydrateSort now returns column name instead of index. TableUtils now expects column name instead of index for functions that don't have access to a columns array.
1 parent 6debb74 commit 7448a88

10 files changed

Lines changed: 163 additions & 73 deletions

File tree

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__mocks__/dh-core.js

packages/dashboard-core-plugins/src/panels/ChartPanel.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
DehydratedSort,
2525
DehydratedAdvancedFilter,
2626
DehydratedQuickFilter,
27+
LegacyDehydratedSort,
2728
} from '@deephaven/iris-grid';
2829
import dh, {
2930
FigureDescriptor,
@@ -107,7 +108,7 @@ export interface ChartPanelTableSettings {
107108
quickFilters?: readonly DehydratedQuickFilter[];
108109
advancedFilters?: readonly DehydratedAdvancedFilter[];
109110
inputFilters?: readonly InputFilter[];
110-
sorts?: readonly DehydratedSort[];
111+
sorts?: readonly (DehydratedSort | LegacyDehydratedSort)[];
111112
partition?: unknown;
112113
partitionColumn?: string;
113114
}

packages/iris-grid/src/IrisGrid.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,7 +2654,8 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
26542654
const { model } = this.props;
26552655
const columnIndex = model.getColumnIndexByName(column.name);
26562656
assertNotNull(columnIndex);
2657-
const oldSort = TableUtils.getSortForColumn(model.sort, columnIndex);
2657+
const columnName = model.columns[columnIndex].name;
2658+
const oldSort = TableUtils.getSortForColumn(model.sort, columnName);
26582659
let newSort = null;
26592660

26602661
if (oldSort == null || oldSort.direction !== direction) {
@@ -2667,7 +2668,7 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
26672668

26682669
const sorts = TableUtils.setSortForColumn(
26692670
model.sort,
2670-
columnIndex,
2671+
columnName,
26712672
newSort,
26722673
addToExisting
26732674
);
@@ -4153,7 +4154,7 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
41534154
const column = model.columns[modelColumn];
41544155
const advancedFilter = advancedFilters.get(modelColumn);
41554156
const { options: advancedFilterOptions } = advancedFilter || {};
4156-
const sort = TableUtils.getSortForColumn(model.sort, modelColumn);
4157+
const sort = TableUtils.getSortForColumn(model.sort, column.name);
41574158
const sortDirection = sort ? sort.direction : null;
41584159
const element = (
41594160
<div

packages/iris-grid/src/IrisGridRenderer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,13 @@ class IrisGridRenderer extends GridRenderer {
450450
return;
451451
}
452452

453-
const sort = TableUtils.getSortForColumn(model.sort, modelColumn);
453+
const columnName = model.columns[modelColumn]?.name;
454+
455+
if (columnName == null) {
456+
return;
457+
}
458+
459+
const sort = TableUtils.getSortForColumn(model.sort, columnName);
454460

455461
if (!sort) {
456462
return;

packages/iris-grid/src/IrisGridUtils.test.ts

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { DateUtils } from '@deephaven/jsapi-utils';
55
import type { AdvancedFilter } from './CommonTypes';
66
import { FilterData } from './IrisGrid';
77
import IrisGridTestUtils from './IrisGridTestUtils';
8-
import IrisGridUtils from './IrisGridUtils';
8+
import IrisGridUtils, {
9+
DehydratedSort,
10+
LegacyDehydratedSort,
11+
} from './IrisGridUtils';
912

1013
function makeFilter() {
1114
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -17,7 +20,7 @@ function makeColumns(count = 30) {
1720

1821
for (let i = 0; i < count; i += 1) {
1922
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20-
const column = new (dh as any).Column({ index: i, name: `${i}` });
23+
const column = new (dh as any).Column({ index: i, name: `name_${i}` });
2124
columns.push(column);
2225
}
2326

@@ -151,30 +154,52 @@ describe('sort exporting/importing', () => {
151154
expect(importedSort).toEqual(sort);
152155
});
153156

154-
it('exports/imports sorts', () => {
157+
it('should export (dehydrate) sorts', () => {
155158
const columns = makeColumns();
156159
const sort = [columns[3].sort(), columns[7].sort().abs().desc()];
157-
const table = makeTable({ columns, sort });
158-
const exportedSort = IrisGridUtils.dehydrateSort(sort);
159-
expect(exportedSort).toEqual([
160-
{ column: 3, isAbs: false, direction: 'ASC' },
161-
{ column: 7, isAbs: true, direction: 'DESC' },
162-
]);
160+
const dehydratedSorts = IrisGridUtils.dehydrateSort(sort);
163161

164-
const importedSort = IrisGridUtils.hydrateSort(table.columns, exportedSort);
165-
expect(importedSort).toEqual([
166-
expect.objectContaining({
167-
column: columns[3],
168-
isAbs: false,
169-
direction: 'ASC',
170-
}),
171-
expect.objectContaining({
172-
column: columns[7],
173-
isAbs: true,
174-
direction: 'DESC',
175-
}),
162+
expect(dehydratedSorts).toEqual<DehydratedSort[]>([
163+
{ column: columns[3].name, isAbs: false, direction: 'ASC' },
164+
{ column: columns[7].name, isAbs: true, direction: 'DESC' },
176165
]);
177166
});
167+
168+
describe('should import (hydrate) sorts', () => {
169+
const columns = makeColumns();
170+
const sort = [columns[3].sort(), columns[7].sort().abs().desc()];
171+
const table = makeTable({ columns, sort });
172+
173+
const dehydratedSorts = IrisGridUtils.dehydrateSort(sort);
174+
175+
// Map `column` to a number to represent our LegacyDehydratedSort
176+
const legacyDehydratedSorts: LegacyDehydratedSort[] = dehydratedSorts.map(
177+
({ column, ...rest }) => ({
178+
column: Number(column.split('_')[1]),
179+
...rest,
180+
})
181+
);
182+
183+
it.each([
184+
['current', dehydratedSorts],
185+
['legacy', legacyDehydratedSorts],
186+
])('%s', (_label, sorts) => {
187+
const importedSort = IrisGridUtils.hydrateSort(table.columns, sorts);
188+
189+
expect(importedSort).toEqual([
190+
expect.objectContaining({
191+
column: columns[3],
192+
isAbs: false,
193+
direction: 'ASC',
194+
}),
195+
expect.objectContaining({
196+
column: columns[7],
197+
isAbs: true,
198+
direction: 'DESC',
199+
}),
200+
]);
201+
});
202+
});
178203
});
179204

180205
describe('pendingDataMap hydration/dehydration', () => {
@@ -222,15 +247,15 @@ describe('pendingDataMap hydration/dehydration', () => {
222247
1,
223248
expect.objectContaining({
224249
data: [
225-
['3', 'Foo'],
226-
['4', 'Bar'],
250+
['name_3', 'Foo'],
251+
['name_4', 'Bar'],
227252
],
228253
}),
229254
],
230255
[
231256
10,
232257
expect.objectContaining({
233-
data: [['7', 'Baz']],
258+
data: [['name_7', 'Baz']],
234259
}),
235260
],
236261
]);
@@ -256,7 +281,7 @@ describe('remove columns in moved columns', () => {
256281
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
257282
table.columns,
258283
movedColumns,
259-
['3']
284+
['name_3']
260285
);
261286
expect(newMovedColumns).toEqual([]);
262287
});
@@ -268,7 +293,7 @@ describe('remove columns in moved columns', () => {
268293
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
269294
table.columns,
270295
movedColumns,
271-
['3']
296+
['name_3']
272297
);
273298
expect(newMovedColumns).toEqual(GridUtils.moveItem(3, 1, [])); // new move should be {from: 3, to: 1}
274299
});
@@ -281,7 +306,7 @@ describe('remove columns in moved columns', () => {
281306
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
282307
table.columns,
283308
movedColumns,
284-
['3']
309+
['name_3']
285310
);
286311
// columns' original state should be [0,1,2,4,5,...] after '3' is removed;
287312
// columns after move should be [4,0,1,2,5,...]; after columns '3' is removed;
@@ -297,7 +322,7 @@ describe('remove columns in moved columns', () => {
297322
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
298323
table.columns,
299324
movedColumns,
300-
['4']
325+
['name_4']
301326
);
302327
// column for is removed, the moved column moved back to it's original place, so delete the move
303328
expect(newMovedColumns).toEqual([]);
@@ -310,7 +335,7 @@ describe('remove columns in moved columns', () => {
310335
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
311336
table.columns,
312337
movedColumns,
313-
['2', '3']
338+
['name_2', 'name_3']
314339
);
315340
// columns' original state should be [0,1,4,5,...] after '2' & '3' are removed;
316341
// columns after move should be [0,1,4,5,...]; after columns '2' & '3' are removed;
@@ -325,7 +350,7 @@ describe('remove columns in moved columns', () => {
325350
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
326351
table.columns,
327352
movedColumns,
328-
['2', '3']
353+
['name_2', 'name_3']
329354
);
330355
// columns' original state should be [0,1,4,5,...] after '2' & '3' are removed;
331356
// columns after move should be [0,4,1,5,...]; after columns '2' & '3' are removed;
@@ -341,7 +366,7 @@ describe('remove columns in moved columns', () => {
341366
const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(
342367
table.columns,
343368
movedColumns,
344-
['2', '3']
369+
['name_2', 'name_3']
345370
);
346371
// columns' original state should be [0,1,4,5,6...] after '2' & '3' are removed;
347372
// columns after moves should be [0,4,1,6,5...]; after columns '2' & '3' are removed;
@@ -461,9 +486,9 @@ describe('changeFilterColumnNamesToIndexes', () => {
461486
const columns = makeColumns(10);
462487
it('Replaces column names with indexes', () => {
463488
const filters = [
464-
{ name: '1', filter: DEFAULT_FILTER },
465-
{ name: '3', filter: DEFAULT_FILTER },
466-
{ name: '5', filter: DEFAULT_FILTER },
489+
{ name: 'name_1', filter: DEFAULT_FILTER },
490+
{ name: 'name_3', filter: DEFAULT_FILTER },
491+
{ name: 'name_5', filter: DEFAULT_FILTER },
467492
];
468493
expect(
469494
IrisGridUtils.changeFilterColumnNamesToIndexes(columns, filters)
@@ -477,7 +502,7 @@ describe('changeFilterColumnNamesToIndexes', () => {
477502
it('Omits missing columns', () => {
478503
const filters = [
479504
{ name: 'missing_1', filter: DEFAULT_FILTER },
480-
{ name: '3', filter: DEFAULT_FILTER },
505+
{ name: 'name_3', filter: DEFAULT_FILTER },
481506
{ name: 'missing_2', filter: DEFAULT_FILTER },
482507
];
483508
expect(

packages/iris-grid/src/IrisGridUtils.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,18 @@ export type DehydratedUserColumnWidth = [ColumnName, number];
9797

9898
export type DehydratedUserRowHeight = [number, number];
9999

100-
export type DehydratedSort = {
100+
/** @deprecated Use `DehydratedSort` instead */
101+
export interface LegacyDehydratedSort {
101102
column: ModelIndex;
102103
isAbs: boolean;
103104
direction: SortDirection;
104-
};
105+
}
106+
107+
export interface DehydratedSort {
108+
column: ColumnName;
109+
isAbs: boolean;
110+
direction: SortDirection;
111+
}
105112

106113
export interface DehydratedIrisGridState {
107114
advancedFilters: readonly DehydratedAdvancedFilter[];
@@ -770,7 +777,7 @@ class IrisGridUtils {
770777
return sorts.map(sort => {
771778
const { column, isAbs, direction } = sort;
772779
return {
773-
column: column.index,
780+
column: column.name,
774781
isAbs,
775782
direction,
776783
};
@@ -785,16 +792,21 @@ class IrisGridUtils {
785792
*/
786793
static hydrateSort(
787794
columns: readonly Column[],
788-
sorts: readonly DehydratedSort[]
795+
sorts: readonly (DehydratedSort | LegacyDehydratedSort)[]
789796
): Sort[] {
790797
return (
791798
sorts
792799
.map(sort => {
793-
const { column: columnIndex, isAbs, direction } = sort;
800+
const { column: columnIndexOrName, isAbs, direction } = sort;
794801
if (direction === TableUtils.sortDirection.reverse) {
795802
return dh.Table.reverse();
796803
}
797-
const column = IrisGridUtils.getColumn(columns, columnIndex);
804+
805+
const column =
806+
typeof columnIndexOrName === 'string'
807+
? IrisGridUtils.getColumnByName(columns, columnIndexOrName)
808+
: IrisGridUtils.getColumn(columns, columnIndexOrName);
809+
798810
if (column != null) {
799811
let columnSort = column.sort();
800812
if (isAbs) {
@@ -868,7 +880,7 @@ class IrisGridUtils {
868880
quickFilters?: readonly DehydratedQuickFilter[];
869881
advancedFilters?: readonly DehydratedAdvancedFilter[];
870882
inputFilters?: readonly InputFilter[];
871-
sorts?: readonly DehydratedSort[];
883+
sorts?: readonly (DehydratedSort | LegacyDehydratedSort)[];
872884
partition?: unknown;
873885
partitionColumn?: ColumnName;
874886
},

packages/iris-grid/src/mousehandlers/IrisGridContextMenuHandler.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ class IrisGridContextMenuHandler extends GridMouseHandler {
229229
} = theme;
230230

231231
const modelSort = model.sort;
232-
const columnSort = TableUtils.getSortForColumn(modelSort, modelIndex);
232+
const columnSort = TableUtils.getSortForColumn(modelSort, column.name);
233233
const hasReverse = reverseType !== TableUtils.REVERSE_TYPE.NONE;
234234
const { userColumnWidths } = metrics;
235235
const isColumnHidden = [...userColumnWidths.values()].some(

packages/jsapi-types/src/dh.types.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,6 @@ export interface OneClick {
524524
}
525525

526526
export interface Column {
527-
/**
528-
* @deprecated
529-
*/
530-
readonly index: number;
531-
532527
readonly type: string;
533528
readonly name: string;
534529
readonly description: string;

0 commit comments

Comments
 (0)