@onehat/ui 0.3.313 → 0.3.314
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -48,6 +48,8 @@ import getIconButtonFromConfig from '../../Functions/getIconButtonFromConfig.js'
|
|
|
48
48
|
import nbToRgb from '../../Functions/nbToRgb.js';
|
|
49
49
|
import testProps from '../../Functions/testProps.js';
|
|
50
50
|
import Loading from '../Messages/Loading.js';
|
|
51
|
+
import isSerializable from '../../Functions/isSerializable.js';
|
|
52
|
+
import inArray from '../../Functions/inArray.js';
|
|
51
53
|
import ReloadPageButton from '../Buttons/ReloadPageButton.js';
|
|
52
54
|
import GridHeaderRow from './GridHeaderRow.js';
|
|
53
55
|
import GridRow, { DragSourceDropTargetGridRow, DragSourceGridRow, DropTargetGridRow } from './GridRow.js';
|
|
@@ -191,17 +193,9 @@ function GridComponent(props) {
|
|
|
191
193
|
styles = UiGlobals.styles,
|
|
192
194
|
id = props.id || props.self?.path,
|
|
193
195
|
localColumnsConfigKey = id && id + '-localColumnsConfig',
|
|
194
|
-
[
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
_.each(columnsConfig, (column) => {
|
|
198
|
-
if (column.renderer || _.isFunction(column)) {
|
|
199
|
-
ret = true;
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
return ret;
|
|
204
|
-
})()),
|
|
196
|
+
[hasUnserializableColumns] = useState(() => {
|
|
197
|
+
return !isSerializable(columnsConfig); // (runs only once, when the component is first created)
|
|
198
|
+
}),
|
|
205
199
|
forceUpdate = useForceUpdate(),
|
|
206
200
|
containerRef = useRef(),
|
|
207
201
|
gridRef = useRef(),
|
|
@@ -224,8 +218,23 @@ function GridComponent(props) {
|
|
|
224
218
|
forceUpdate();
|
|
225
219
|
},
|
|
226
220
|
setLocalColumnsConfig = (config) => {
|
|
227
|
-
if (localColumnsConfigKey
|
|
228
|
-
|
|
221
|
+
if (localColumnsConfigKey) {
|
|
222
|
+
const localConfig = _.clone(config); // clone it so we don't alter the original
|
|
223
|
+
if (hasUnserializableColumns) {
|
|
224
|
+
// just save the data needed to later reconstruct the columns
|
|
225
|
+
const usedIds = [];
|
|
226
|
+
_.each(localConfig, (column, ix) => {
|
|
227
|
+
if (!column.id || inArray(column.id, usedIds)) {
|
|
228
|
+
throw Error('When using unserializable columns, each column must have a unique id');
|
|
229
|
+
}
|
|
230
|
+
usedIds.push(column.id);
|
|
231
|
+
localConfig[ix] = {
|
|
232
|
+
id: column.id,
|
|
233
|
+
isHidden: !!column.isHidden,
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
setSaved(localColumnsConfigKey, localConfig);
|
|
229
238
|
}
|
|
230
239
|
|
|
231
240
|
setLocalColumnsConfigRaw(config);
|
|
@@ -791,19 +800,18 @@ function GridComponent(props) {
|
|
|
791
800
|
|
|
792
801
|
// second call -- do other necessary setup
|
|
793
802
|
|
|
794
|
-
|
|
795
|
-
let localColumnsConfig = []
|
|
796
|
-
|
|
797
|
-
|
|
803
|
+
|
|
804
|
+
let localColumnsConfig = [],
|
|
805
|
+
savedLocalColumnsConfig,
|
|
806
|
+
calculateLocalColumnsConfig = false;
|
|
807
|
+
if (localColumnsConfigKey && !UiGlobals.disableSavedColumnsConfig) {
|
|
798
808
|
savedLocalColumnsConfig = await getSaved(localColumnsConfigKey);
|
|
799
809
|
}
|
|
800
|
-
if (savedLocalColumnsConfig) {
|
|
801
|
-
// use saved
|
|
802
|
-
localColumnsConfig = savedLocalColumnsConfig;
|
|
803
|
-
} else {
|
|
804
|
-
// calculate new
|
|
805
810
|
|
|
806
|
-
|
|
811
|
+
if (!savedLocalColumnsConfig || hasUnserializableColumns) {
|
|
812
|
+
calculateLocalColumnsConfig = true;
|
|
813
|
+
}
|
|
814
|
+
if (calculateLocalColumnsConfig) {
|
|
807
815
|
if (_.isEmpty(columnsConfig)) {
|
|
808
816
|
if (Repository) {
|
|
809
817
|
// create a column for the displayProperty
|
|
@@ -821,10 +829,9 @@ function GridComponent(props) {
|
|
|
821
829
|
localColumnsConfig.push(columnConfig);
|
|
822
830
|
return;
|
|
823
831
|
}
|
|
824
|
-
|
|
832
|
+
|
|
825
833
|
const
|
|
826
834
|
defaults = {
|
|
827
|
-
columnId: uuid(),
|
|
828
835
|
isEditable: false,
|
|
829
836
|
reorderable: true,
|
|
830
837
|
resizable: true,
|
|
@@ -841,11 +848,29 @@ function GridComponent(props) {
|
|
|
841
848
|
// Both are set. Width overrules flex.
|
|
842
849
|
delete config.flex;
|
|
843
850
|
}
|
|
844
|
-
|
|
851
|
+
|
|
845
852
|
localColumnsConfig.push(config);
|
|
846
853
|
});
|
|
847
854
|
}
|
|
848
855
|
}
|
|
856
|
+
|
|
857
|
+
if (savedLocalColumnsConfig) {
|
|
858
|
+
if (!hasUnserializableColumns) {
|
|
859
|
+
// just use the saved config without any further processing
|
|
860
|
+
localColumnsConfig = savedLocalColumnsConfig;
|
|
861
|
+
|
|
862
|
+
} else {
|
|
863
|
+
// Conform the calculated localColumnsConfig to the saved config.
|
|
864
|
+
// This should allow us to continue using non-serializable configurations after a refresh
|
|
865
|
+
const reconstructedLocalColumnsConfig = savedLocalColumnsConfig.map((savedConfig) => { // foreach saved column, in the order it was saved...
|
|
866
|
+
const columnConfig = localColumnsConfig.find(localConfig => localConfig.id === savedConfig.id); // find the corresponding column in localColumnsConfig
|
|
867
|
+
columnConfig.isHidden = savedConfig.isHidden;
|
|
868
|
+
return columnConfig;
|
|
869
|
+
});
|
|
870
|
+
localColumnsConfig = reconstructedLocalColumnsConfig;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
849
874
|
setLocalColumnsConfig(localColumnsConfig);
|
|
850
875
|
|
|
851
876
|
setIsReady(true);
|
|
@@ -294,7 +294,6 @@ export default function GridHeaderRow(props) {
|
|
|
294
294
|
// so we can drag/drop them to control the columns.
|
|
295
295
|
const headerColumns = _.map(localColumnsConfig, (config, ix, all) => {
|
|
296
296
|
let {
|
|
297
|
-
columnId,
|
|
298
297
|
fieldName,
|
|
299
298
|
header = _.upperFirst(fieldName),
|
|
300
299
|
reorderable,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default function isSerializable(value, seen = new WeakSet()) {
|
|
2
|
+
// Handle primitive types that are serializable or explicitly unserializable
|
|
3
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'string' || typeof value === 'number') {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === 'undefined' || typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Handle objects (including arrays)
|
|
11
|
+
if (typeof value === 'object') {
|
|
12
|
+
// Check for circular references
|
|
13
|
+
if (seen.has(value)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
seen.add(value);
|
|
17
|
+
|
|
18
|
+
for (const key in value) {
|
|
19
|
+
if (!isSerializable(value[key], seen)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return true;
|
|
26
|
+
}
|