forked from deephaven/web-client-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIrisGridCacheUtils.ts
More file actions
156 lines (149 loc) · 5.16 KB
/
IrisGridCacheUtils.ts
File metadata and controls
156 lines (149 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* eslint-disable import/prefer-default-export */
import { type GridState } from '@deephaven/grid';
import memoizeOne from 'memoize-one';
import type IrisGridModel from './IrisGridModel';
import IrisGridUtils, {
type DehydratedGridState,
type DehydratedIrisGridState,
type HydratedGridState,
type HydratedIrisGridState,
} from './IrisGridUtils';
/**
* Checks if 2 grid states are equivalent.
* Checks values and does not require referential equality of the entire state, just the values we care about.
* @param gridStateA First grid state
* @param gridStateB Second grid state
* @returns True if the states are equivalent
*/
function areGridStatesEqual(
gridStateA: HydratedGridState,
gridStateB: HydratedGridState
): boolean {
const compareKeys = [
'isStuckToBottom',
'isStuckToRight',
'movedColumns',
'movedRows',
] satisfies Array<keyof GridState>;
return (
gridStateA === gridStateB ||
compareKeys.every(key => gridStateA[key] === gridStateB[key])
);
}
/**
* Checks if 2 iris grid states are equivalent.
* Checks values and does not require referential equality of the entire state, just the values we care about.
* @param irisGridStateA First iris grid state
* @param irisGridStateB Second iris grid state
* @returns True if the states are equivalent
*/
function areIrisGridStatesEqual(
irisGridStateA: HydratedIrisGridState,
irisGridStateB: HydratedIrisGridState
): boolean {
// Top level keys we want to check for referential equality
const compareStateKeys = [
'advancedFilters',
'aggregationSettings',
'customColumnFormatMap',
'columnAlignmentMap',
'isFilterBarShown',
'quickFilters',
'customColumns',
'reverse',
'rollupConfig',
'showSearchBar',
'searchValue',
'selectDistinctColumns',
'selectedSearchColumns',
'sorts',
'invertSearchColumns',
'pendingDataMap',
'frozenColumns',
'conditionalFormats',
'columnHeaderGroups',
'partitionConfig',
] satisfies Array<keyof HydratedIrisGridState>;
return (
irisGridStateA === irisGridStateB ||
(irisGridStateA.metrics?.userColumnWidths ===
irisGridStateB.metrics?.userColumnWidths &&
irisGridStateA.metrics?.userRowHeights ===
irisGridStateB.metrics?.userRowHeights &&
compareStateKeys.every(
key => irisGridStateA[key] === irisGridStateB[key]
))
);
}
/**
* Creates a dehydrator function for grid state that is memoized on the last call.
* Only tracks 1 state at a time. If the model and input states are equal, returns the same dehydrated state object reference.
* @returns A dehydrator function memoized on the last call
*/
function makeMemoizedGridStateDehydrator(): (
model: IrisGridModel,
gridState: HydratedGridState
) => DehydratedGridState {
return memoizeOne(
(model: IrisGridModel, gridState: HydratedGridState) =>
IrisGridUtils.dehydrateGridState(model, gridState),
([modelA, gridStateA], [modelB, gridStateB]) =>
modelA === modelB && areGridStatesEqual(gridStateA, gridStateB)
);
}
/**
* Creates a dehydrator function for iris grid state that is memoized on the last call.
* Only tracks 1 state at a time. If the model and input states are equal, returns the same dehydrated state object reference.
* @returns A dehydrator function memoized on the last call
*/
function makeMemoizedIrisGridStateDehydrator(): (
model: IrisGridModel,
irisGridState: HydratedIrisGridState
) => DehydratedIrisGridState {
return memoizeOne(
(model: IrisGridModel, irisGridState: HydratedIrisGridState) => {
const irisGridUtils = new IrisGridUtils(model.dh);
return irisGridUtils.dehydrateIrisGridState(model, irisGridState);
},
([modelA, irisGridStateA], [modelB, irisGridStateB]) =>
modelA === modelB &&
areIrisGridStatesEqual(irisGridStateA, irisGridStateB)
);
}
/**
* Creates a dehydrator function for grid and iris grid state that is memoized on the last call.
* Only tracks 1 state at a time. If the model and input states are equal, returns the same dehydrated state object reference.
* Combines the dehydrated grid and iris grid states into a single object.
* @returns A dehydrator function memoized on the last call
*/
function makeMemoizedCombinedGridStateDehydrator(): (
model: IrisGridModel,
irisGridState: HydratedIrisGridState,
gridState: HydratedGridState
) => DehydratedIrisGridState & DehydratedGridState {
return memoizeOne(
(
model: IrisGridModel,
irisGridState: HydratedIrisGridState,
gridState: HydratedGridState
): DehydratedIrisGridState & DehydratedGridState => {
const irisGridUtils = new IrisGridUtils(model.dh);
return {
...irisGridUtils.dehydrateIrisGridState(model, irisGridState),
...IrisGridUtils.dehydrateGridState(model, gridState),
};
},
(
[modelA, irisGridStateA, gridStateA],
[modelB, irisGridStateB, gridStateB]
) =>
modelA === modelB &&
areIrisGridStatesEqual(irisGridStateA, irisGridStateB) &&
areGridStatesEqual(gridStateA, gridStateB)
);
}
export const IrisGridCacheUtils = {
makeMemoizedGridStateDehydrator,
makeMemoizedIrisGridStateDehydrator,
makeMemoizedCombinedGridStateDehydrator,
};