@xh/hoist 55.3.0 → 55.3.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v55.3.2 - 2023-03-22
4
+
5
+ ### 🐞 Bug Fixes
6
+ * Fix grid bug whereby LocalDate filter entered via FilterChooser was causing column filtering
7
+ to fail.
8
+
9
+
10
+ ## v55.3.1 - 2023-03-14
11
+
12
+ ### 🐞 Bug Fixes
13
+ * Revert `structuredClone` to lodash `deepClone` throughout toolkit.
14
+
3
15
  ## v55.3.0 - 2023-03-03
4
16
 
5
17
  ### 🐞 Bug Fixes
@@ -13,7 +13,7 @@ import {Icon} from '@xh/hoist/icon';
13
13
  import {bindable, makeObservable, observable, action} from '@xh/hoist/mobx';
14
14
  import {pluralize} from '@xh/hoist/utils/js';
15
15
  import {hbox} from '@xh/hoist/cmp/layout';
16
- import {isEqual, isString, isNil, omit, remove, trimEnd} from 'lodash';
16
+ import {cloneDeep, isEqual, isString, isNil, omit, remove, trimEnd} from 'lodash';
17
17
  import {hspacer} from '../../cmp/layout';
18
18
 
19
19
  import {DifferDetailModel} from './DifferDetailModel';
@@ -151,7 +151,7 @@ export class DifferModel extends HoistModel {
151
151
  const resp = await Promise.all([
152
152
  XH.fetchJson({url: `${url}/${entityName}s`, loadSpec}),
153
153
  this.clipboardContent ?
154
- Promise.resolve(structuredClone(this.clipboardContent)) :
154
+ Promise.resolve(cloneDeep(this.clipboardContent)) :
155
155
  XH.fetchJson({url: `${remoteBaseUrl}${url}/${entityName}s`, loadSpec})
156
156
  ]);
157
157
  this.processResponse(resp);
@@ -250,8 +250,8 @@ export class DifferModel extends HoistModel {
250
250
 
251
251
  rawRecordsAreEqual(local, remote) {
252
252
  // cloning to avoid disturbing the source data.
253
- local = structuredClone(local);
254
- remote = structuredClone(remote);
253
+ local = cloneDeep(local);
254
+ remote = cloneDeep(remote);
255
255
 
256
256
  // For JSON records, parse JSON to do an accurate value compare,
257
257
  if (local?.valueType === 'json' && remote?.valueType === 'json') {
@@ -9,6 +9,7 @@ import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/
9
9
  import {throwIf} from '@xh/hoist/utils/js';
10
10
  import {
11
11
  castArray,
12
+ cloneDeep,
12
13
  concat,
13
14
  find,
14
15
  has,
@@ -305,7 +306,7 @@ export class AgGridModel extends HoistModel {
305
306
  setSortState(sortState: AgGridColumnSortState[]) {
306
307
  this.throwIfNotReady();
307
308
 
308
- const sortedColumnState = structuredClone(sortState),
309
+ const sortedColumnState = cloneDeep(sortState),
309
310
  [primaryColumnState, secondaryColumnState] = partition(sortedColumnState, it => !isArray(it.colId)),
310
311
  {agColumnApi: colApi, agApi} = this,
311
312
  isPivot = colApi.isPivotMode(),
@@ -355,7 +355,7 @@ class ChartLocalModel extends HoistModel {
355
355
  }
356
356
 
357
357
  getThemeConfig() {
358
- return XH.darkTheme ? structuredClone(DarkTheme) : structuredClone(LightTheme);
358
+ return XH.darkTheme ? cloneDeep(DarkTheme) : cloneDeep(LightTheme);
359
359
  }
360
360
 
361
361
  getModelConfig() {
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import {HoistModel, PlainObject, Some} from '@xh/hoist/core';
8
8
  import {action, makeObservable, observable} from '@xh/hoist/mobx';
9
- import {castArray, merge} from 'lodash';
9
+ import {castArray, cloneDeep, merge} from 'lodash';
10
10
 
11
11
  interface ChartConfig {
12
12
 
@@ -84,7 +84,7 @@ export class ChartModel extends HoistModel {
84
84
  */
85
85
  @action
86
86
  updateHighchartsConfig(update: any) {
87
- this.highchartsConfig = merge(structuredClone(this.highchartsConfig), update);
87
+ this.highchartsConfig = merge(cloneDeep(this.highchartsConfig), update);
88
88
  }
89
89
 
90
90
  /** @param series - one or more data series to be charted. */
@@ -29,6 +29,7 @@ import {throwIf, withDefault} from '@xh/hoist/utils/js';
29
29
  import {createObservableRef} from '@xh/hoist/utils/react';
30
30
  import {ReactNode} from 'react';
31
31
  import {
32
+ cloneDeep,
32
33
  compact,
33
34
  flatMap,
34
35
  flatten,
@@ -373,7 +374,7 @@ export class FilterChooserModel extends HoistModel {
373
374
  // it's internal `value`. Force synchronise its `value` to our bound `selectValue`
374
375
  // to get it back inline. Note we're intentionally not using `setSelectValue()`,
375
376
  // which returns early if the actual filter value hasn't changed.
376
- this.selectValue = structuredClone(this.selectValue);
377
+ this.selectValue = cloneDeep(this.selectValue);
377
378
  });
378
379
  }
379
380
 
@@ -60,6 +60,7 @@ import equal from 'fast-deep-equal';
60
60
  import {
61
61
  castArray,
62
62
  clone,
63
+ cloneDeep,
63
64
  compact,
64
65
  defaults,
65
66
  defaultsDeep,
@@ -1060,7 +1061,7 @@ export class GridModel extends HoistModel {
1060
1061
  applyColumnStateChanges(colStateChanges: Partial<ColumnState>[]) {
1061
1062
  if (isEmpty(colStateChanges)) return;
1062
1063
 
1063
- let columnState = structuredClone(this.columnState);
1064
+ let columnState = cloneDeep(this.columnState);
1064
1065
 
1065
1066
  throwIf(colStateChanges.some(({colId}) => !find(columnState, {colId})),
1066
1067
  'Invalid columns detected in column changes!');
@@ -66,7 +66,7 @@ export class GridFilterFieldSpec extends BaseFilterFieldSpec {
66
66
  // Implementation
67
67
  //------------------------
68
68
  loadValuesFromSource() {
69
- const {filterModel, field, source} = this,
69
+ const {filterModel, field, source, sourceField} = this,
70
70
  columnFilters = filterModel.getColumnFilters(field),
71
71
  sourceStore = source instanceof View ? source.cube.store : source,
72
72
  allRecords = sourceStore.allRecords;
@@ -83,7 +83,10 @@ export class GridFilterFieldSpec extends BaseFilterFieldSpec {
83
83
  // Get values from current column filter
84
84
  const filterValues = [];
85
85
  columnFilters.forEach(filter => {
86
- const newValues = castArray(filter.value).map(value => filterModel.toDisplayValue(value));
86
+ const newValues = castArray(filter.value).map(value => {
87
+ value = sourceField.parseVal(value);
88
+ return filterModel.toDisplayValue(value);
89
+ });
87
90
  filterValues.push(...newValues);
88
91
  });
89
92
 
@@ -10,7 +10,7 @@ import {action, computed, observable, makeObservable} from '@xh/hoist/mobx';
10
10
  import {genDisplayName} from '@xh/hoist/data';
11
11
  import {throwIf} from '@xh/hoist/utils/js';
12
12
  import {createObservableRef} from '@xh/hoist/utils/react';
13
- import {difference, isFunction, isArray, isEmpty, isEqual, isString, keys, sortBy} from 'lodash';
13
+ import {cloneDeep, difference, isFunction, isArray, isEmpty, isEqual, isString, keys, sortBy} from 'lodash';
14
14
 
15
15
  export interface GroupingChooserConfig {
16
16
  /**
@@ -128,7 +128,7 @@ export class GroupingChooserModel extends HoistModel {
128
128
  this.persistValue = persistWith.persistValue ?? true;
129
129
  this.persistFavorites = persistWith.persistFavorites ?? true;
130
130
 
131
- const state = structuredClone(this.provider.read());
131
+ const state = cloneDeep(this.provider.read());
132
132
  if (this.persistValue && state?.value && this.validateValue(state?.value)) {
133
133
  value = state.value;
134
134
  }
package/core/HoistBase.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  import {XH, PersistenceProvider, PersistOptions, DebounceSpec} from './';
8
8
  import {throwIf, getOrCreate} from '@xh/hoist/utils/js';
9
9
  import {
10
+ cloneDeep,
10
11
  debounce as lodashDebounce,
11
12
  isFunction,
12
13
  isNil,
@@ -219,7 +220,7 @@ export abstract class HoistBase {
219
220
  provider = this.markManaged(PersistenceProvider.create(persistWith)),
220
221
  providerState = provider.read();
221
222
  if (!isUndefined(providerState)) {
222
- runInAction(() => this[property] = structuredClone(providerState));
223
+ runInAction(() => this[property] = cloneDeep(providerState));
223
224
  }
224
225
  this.addReaction({
225
226
  track: () => this[property],
@@ -9,6 +9,7 @@ import {PersistenceProvider, PersistOptions, HoistBaseClass} from './';
9
9
  import {isUndefined} from 'lodash';
10
10
  import {wait} from '../promise';
11
11
  import {throwIf} from '../utils/js';
12
+ import {cloneDeep} from 'lodash';
12
13
 
13
14
  /**
14
15
  * Decorator to make a property "managed". Managed properties are designed to hold objects that
@@ -75,7 +76,7 @@ function createPersistDescriptor(target: HoistBaseClass, property: string, descr
75
76
  try {
76
77
  const persistWith = {path: property, ...this.persistWith, ...options},
77
78
  provider = this.markManaged(PersistenceProvider.create(persistWith));
78
- providerState = structuredClone(provider.read());
79
+ providerState = cloneDeep(provider.read());
79
80
  wait().then(() => {
80
81
  this.addReaction({
81
82
  track: () => this[property],
@@ -8,6 +8,7 @@
8
8
  import {DebounceSpec, XH} from '../';
9
9
  import {LocalStorageProvider, PrefProvider, DashViewProvider, CustomProvider, PersistOptions} from './';
10
10
  import {
11
+ cloneDeep,
11
12
  isUndefined,
12
13
  get,
13
14
  set,
@@ -95,7 +96,7 @@ export class PersistenceProvider {
95
96
  * Clear any state saved by this object at a path
96
97
  */
97
98
  clear(path: string = this.path) {
98
- const obj = structuredClone(this.readRaw());
99
+ const obj = cloneDeep(this.readRaw());
99
100
  unset(obj, this.path);
100
101
  this.writeRaw(obj);
101
102
  }
@@ -111,7 +112,7 @@ export class PersistenceProvider {
111
112
  // Implementation
112
113
  //----------------
113
114
  protected writeInternal(data: object) {
114
- const obj = structuredClone(this.readRaw());
115
+ const obj = cloneDeep(this.readRaw());
115
116
  set(obj, this.path, data);
116
117
  this.writeRaw(obj);
117
118
  }
@@ -22,6 +22,7 @@ import {debounced, ensureUniqueBy, throwIf} from '@xh/hoist/utils/js';
22
22
  import {createObservableRef} from '@xh/hoist/utils/react';
23
23
  import {isOmitted} from '@xh/hoist/utils/impl';
24
24
  import {
25
+ cloneDeep,
25
26
  defaultsDeep,
26
27
  find,
27
28
  isFinite,
@@ -539,7 +540,7 @@ export class DashContainerModel extends DashModel<DashContainerViewSpec, DashVie
539
540
  private createGoldenLayout(containerEl: HTMLElement, state: any): GoldenLayout {
540
541
  const {viewSpecs} = this,
541
542
  ret = new GoldenLayout({
542
- content: convertStateToGL(structuredClone(state), this),
543
+ content: convertStateToGL(cloneDeep(state), this),
543
544
  settings: {
544
545
  // Remove icons by default
545
546
  showPopoutIcon: false,
@@ -142,7 +142,7 @@ export class ValuesTabModel extends HoistModel {
142
142
 
143
143
  @action
144
144
  private doSyncWithFilter() {
145
- const {values, columnFilters, gridFilterModel} = this,
145
+ const {values, columnFilters, gridFilterModel, fieldSpec} = this,
146
146
  {fieldType} = this.headerFilterModel;
147
147
 
148
148
  if (isEmpty(columnFilters)) {
@@ -157,7 +157,10 @@ export class ValuesTabModel extends HoistModel {
157
157
  filterValues = [];
158
158
 
159
159
  arr.forEach(filter => {
160
- const newValues = castArray(filter.value).map(value => gridFilterModel.toDisplayValue(value));
160
+ const newValues = castArray(filter.value).map(value => {
161
+ value = fieldSpec.sourceField.parseVal(value);
162
+ return gridFilterModel.toDisplayValue(value);
163
+ });
161
164
  filterValues.push(...newValues); // Todo: Is this safe?
162
165
  });
163
166
 
@@ -12,6 +12,7 @@ import {chooserToolbar} from './impl/ChooserToolbar';
12
12
  import {description} from './impl/Description';
13
13
  import './LeftRightChooser.scss';
14
14
  import {LeftRightChooserModel} from './LeftRightChooserModel';
15
+ import {cloneDeep} from 'lodash';
15
16
 
16
17
  export interface LeftRightChooserProps extends HoistProps<LeftRightChooserModel>, BoxProps {}
17
18
 
@@ -36,8 +37,8 @@ export const [LeftRightChooser, leftRightChooser] = hoistCmp.withFactory<LeftRig
36
37
  }
37
38
  }
38
39
  },
39
- leftGridOptions = structuredClone(gridOptions),
40
- rightGridOptions = structuredClone(gridOptions);
40
+ leftGridOptions = cloneDeep(gridOptions),
41
+ rightGridOptions = cloneDeep(gridOptions);
41
42
 
42
43
  if (!leftGroupingExpanded) leftGridOptions.agOptions.groupDefaultExpanded = 0;
43
44
  if (!rightGroupingExpanded) rightGridOptions.agOptions.groupDefaultExpanded = 0;
@@ -13,7 +13,7 @@ import {numberRenderer} from '@xh/hoist/format';
13
13
  import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx';
14
14
  import {throwIf, withDefault} from '@xh/hoist/utils/js';
15
15
  import {ReactNode} from 'react';
16
- import {get, isEmpty, isFinite, max, set, sortBy, sumBy, unset} from 'lodash';
16
+ import {cloneDeep, get, isEmpty, isFinite, max, set, sortBy, sumBy, unset} from 'lodash';
17
17
 
18
18
  /**
19
19
  * Core Model for a TreeMap.
@@ -442,7 +442,7 @@ export class TreeMapModel extends HoistModel {
442
442
 
443
443
  toggleNodeExpanded(treePath) {
444
444
  const {gridModel} = this,
445
- expandState = structuredClone(gridModel.expandState);
445
+ expandState = cloneDeep(gridModel.expandState);
446
446
 
447
447
  if (get(expandState, treePath)) {
448
448
  unset(expandState, treePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "55.3.0",
3
+ "version": "55.3.2",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": "github:xh/hoist-react",
6
6
  "homepage": "https://xh.io",
@@ -7,7 +7,7 @@
7
7
  import {HoistService, XH} from '@xh/hoist/core';
8
8
  import {SECONDS} from '@xh/hoist/utils/datetime';
9
9
  import {deepFreeze, throwIf} from '@xh/hoist/utils/js';
10
- import {debounce, forEach, isEmpty, isEqual, isNil, pickBy} from 'lodash';
10
+ import {cloneDeep, debounce, forEach, isEmpty, isEqual, isNil, pickBy} from 'lodash';
11
11
 
12
12
  /**
13
13
  * Service to read and set user-specific preference values.
@@ -92,7 +92,7 @@ export class PrefService extends HoistService {
92
92
  if (isEqual(oldValue, value)) return;
93
93
 
94
94
  // Change local value to sanitized copy and fire.
95
- value = deepFreeze(structuredClone(value));
95
+ value = deepFreeze(cloneDeep(value));
96
96
  this._data[key].value = value;
97
97
 
98
98
  // Schedule serialization to storage
@@ -198,7 +198,7 @@ export class PrefService extends HoistService {
198
198
  for (let key in data) {
199
199
  if (data[key].local) {
200
200
  data[key].value = !isNil(localPrefs[key]) ?
201
- deepFreeze(structuredClone(localPrefs[key])) :
201
+ deepFreeze(cloneDeep(localPrefs[key])) :
202
202
  data[key].defaultValue;
203
203
  }
204
204
  }