@xh/hoist 67.0.0-SNAPSHOT.1725048431197 → 67.0.0-SNAPSHOT.1725049253748
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
|
@@ -21,10 +21,12 @@
|
|
|
21
21
|
* New property `FetchOptions.asJson` to instruct `FetchService` to decode an HTTP response as JSON.
|
|
22
22
|
Note that `FetchService` methods suffixed with `Json` will set this property automatically.
|
|
23
23
|
* `GridModel` will now accept `contextMenu: false` to omit context menus.
|
|
24
|
-
* New bindable `AppContainerModel.intializingLoadMaskMessage`
|
|
24
|
+
* New bindable property `AppContainerModel.intializingLoadMaskMessage` to allow apps to customize
|
|
25
25
|
the loading mask message shown during app initialization.
|
|
26
26
|
* Enhanced `select` component with new `emptyValue` prop, allowing for a custom value to be returned
|
|
27
27
|
when the control is empty (vs default of `null`). Expected usage is `[]` when `enableMulti:true`.
|
|
28
|
+
* New `GroupingChooserModel.setDimensions()` API, to support updating available dimensions on an
|
|
29
|
+
already constructed `GroupingChooserModel`.
|
|
28
30
|
|
|
29
31
|
### 🐞 Bug Fixes
|
|
30
32
|
|
|
@@ -42,8 +42,6 @@ export interface GroupingChooserPersistOptions extends PersistOptions {
|
|
|
42
42
|
export declare class GroupingChooserModel extends HoistModel {
|
|
43
43
|
value: string[];
|
|
44
44
|
favorites: string[][];
|
|
45
|
-
dimensions: Record<string, DimensionSpec>;
|
|
46
|
-
dimensionNames: string[];
|
|
47
45
|
allowEmpty: boolean;
|
|
48
46
|
maxDepth: number;
|
|
49
47
|
commitOnChange: boolean;
|
|
@@ -54,10 +52,14 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
54
52
|
editorIsOpen: boolean;
|
|
55
53
|
favoritesIsOpen: boolean;
|
|
56
54
|
popoverRef: import("react").RefObject<HTMLElement> & import("react").RefCallback<HTMLElement>;
|
|
55
|
+
private dimensions;
|
|
56
|
+
private dimensionNames;
|
|
57
57
|
get availableDims(): string[];
|
|
58
|
+
get dimensionSpecs(): DimensionSpec[];
|
|
58
59
|
get isValid(): boolean;
|
|
59
60
|
get isAddEnabled(): boolean;
|
|
60
61
|
constructor({ dimensions, initialValue, initialFavorites, persistWith, allowEmpty, maxDepth, commitOnChange }: GroupingChooserConfig);
|
|
62
|
+
setDimensions(dimensions: Array<DimensionSpec | string>): void;
|
|
61
63
|
setValue(value: string[]): void;
|
|
62
64
|
toggleEditor(): void;
|
|
63
65
|
toggleFavoritesMenu(): void;
|
|
@@ -67,13 +69,7 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
67
69
|
removePendingDimAtIdx(idx: number): void;
|
|
68
70
|
movePendingDimToIndex(dimName: string, toIdx: number): void;
|
|
69
71
|
commitPendingValueAndClose(): void;
|
|
70
|
-
validateValue(value:
|
|
71
|
-
normalizeDimensions(dims: Array<DimensionSpec | string>): Record<string, DimensionSpec>;
|
|
72
|
-
createDimension(src: DimensionSpec | string): {
|
|
73
|
-
/** Shortname or code (almost always a `CubeField.name`). */
|
|
74
|
-
name: string;
|
|
75
|
-
displayName: string;
|
|
76
|
-
};
|
|
72
|
+
validateValue(value: string[]): boolean;
|
|
77
73
|
getValueLabel(value: string[]): string;
|
|
78
74
|
getDimDisplayName(dimName: string): string;
|
|
79
75
|
onDragEnd(result: any): void;
|
|
@@ -86,4 +82,7 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
86
82
|
removeFavorite(value: string[]): void;
|
|
87
83
|
isFavorite(value: string[]): boolean;
|
|
88
84
|
get persistState(): PlainObject;
|
|
85
|
+
private normalizeDimensions;
|
|
86
|
+
private createDimension;
|
|
87
|
+
private removeUnknownDimsFromValue;
|
|
89
88
|
}
|
|
@@ -13,21 +13,11 @@ import {
|
|
|
13
13
|
PlainObject,
|
|
14
14
|
XH
|
|
15
15
|
} from '@xh/hoist/core';
|
|
16
|
-
import {action, computed, observable, makeObservable} from '@xh/hoist/mobx';
|
|
17
16
|
import {genDisplayName} from '@xh/hoist/data';
|
|
18
|
-
import {
|
|
17
|
+
import {action, computed, makeObservable, observable} from '@xh/hoist/mobx';
|
|
18
|
+
import {executeIfFunction, throwIf} from '@xh/hoist/utils/js';
|
|
19
19
|
import {createObservableRef} from '@xh/hoist/utils/react';
|
|
20
|
-
import {
|
|
21
|
-
cloneDeep,
|
|
22
|
-
difference,
|
|
23
|
-
isFunction,
|
|
24
|
-
isArray,
|
|
25
|
-
isEmpty,
|
|
26
|
-
isEqual,
|
|
27
|
-
isString,
|
|
28
|
-
keys,
|
|
29
|
-
sortBy
|
|
30
|
-
} from 'lodash';
|
|
20
|
+
import {cloneDeep, difference, isArray, isEmpty, isEqual, isString, keys, sortBy} from 'lodash';
|
|
31
21
|
|
|
32
22
|
export interface GroupingChooserConfig {
|
|
33
23
|
/**
|
|
@@ -81,11 +71,8 @@ export interface GroupingChooserPersistOptions extends PersistOptions {
|
|
|
81
71
|
|
|
82
72
|
export class GroupingChooserModel extends HoistModel {
|
|
83
73
|
@observable.ref value: string[];
|
|
84
|
-
|
|
85
74
|
@observable.ref favorites: string[][] = [];
|
|
86
75
|
|
|
87
|
-
dimensions: Record<string, DimensionSpec>;
|
|
88
|
-
dimensionNames: string[];
|
|
89
76
|
allowEmpty: boolean;
|
|
90
77
|
maxDepth: number;
|
|
91
78
|
commitOnChange: boolean;
|
|
@@ -98,14 +85,22 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
98
85
|
@observable.ref pendingValue: string[] = [];
|
|
99
86
|
@observable editorIsOpen: boolean = false;
|
|
100
87
|
@observable favoritesIsOpen: boolean = false;
|
|
101
|
-
|
|
102
88
|
popoverRef = createObservableRef<HTMLElement>();
|
|
103
89
|
|
|
90
|
+
// Internal state
|
|
91
|
+
@observable.ref private dimensions: Record<string, DimensionSpec>;
|
|
92
|
+
@observable.ref private dimensionNames: string[];
|
|
93
|
+
|
|
104
94
|
@computed
|
|
105
95
|
get availableDims(): string[] {
|
|
106
96
|
return difference(this.dimensionNames, this.pendingValue);
|
|
107
97
|
}
|
|
108
98
|
|
|
99
|
+
@computed
|
|
100
|
+
get dimensionSpecs(): DimensionSpec[] {
|
|
101
|
+
return Object.values(this.dimensions);
|
|
102
|
+
}
|
|
103
|
+
|
|
109
104
|
@computed
|
|
110
105
|
get isValid(): boolean {
|
|
111
106
|
return this.validateValue(this.pendingValue);
|
|
@@ -132,17 +127,15 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
132
127
|
super();
|
|
133
128
|
makeObservable(this);
|
|
134
129
|
|
|
135
|
-
this.dimensions = this.normalizeDimensions(dimensions);
|
|
136
|
-
this.dimensionNames = keys(this.dimensions);
|
|
137
130
|
this.allowEmpty = allowEmpty;
|
|
138
131
|
this.maxDepth = maxDepth;
|
|
139
132
|
this.commitOnChange = commitOnChange;
|
|
140
133
|
|
|
141
|
-
|
|
134
|
+
this.setDimensions(dimensions);
|
|
142
135
|
|
|
143
136
|
// Read and validate value and favorites
|
|
144
|
-
let value =
|
|
145
|
-
favorites =
|
|
137
|
+
let value = executeIfFunction(initialValue),
|
|
138
|
+
favorites = executeIfFunction(initialFavorites);
|
|
146
139
|
|
|
147
140
|
throwIf(isEmpty(value) && !this.allowEmpty, 'Initial value cannot be empty.');
|
|
148
141
|
throwIf(!this.validateValue(value), 'Initial value is invalid.');
|
|
@@ -187,6 +180,18 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
187
180
|
this.setFavorites(favorites);
|
|
188
181
|
}
|
|
189
182
|
|
|
183
|
+
@action
|
|
184
|
+
setDimensions(dimensions: Array<DimensionSpec | string>) {
|
|
185
|
+
throwIf(
|
|
186
|
+
isEmpty(dimensions) && !this.allowEmpty,
|
|
187
|
+
'Must provide valid dimensions available for selection.'
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
this.dimensions = this.normalizeDimensions(dimensions);
|
|
191
|
+
this.dimensionNames = keys(this.dimensions);
|
|
192
|
+
this.removeUnknownDimsFromValue();
|
|
193
|
+
}
|
|
194
|
+
|
|
190
195
|
@action
|
|
191
196
|
setValue(value: string[]) {
|
|
192
197
|
if (!this.validateValue(value)) {
|
|
@@ -259,37 +264,18 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
259
264
|
this.closePopover();
|
|
260
265
|
}
|
|
261
266
|
|
|
262
|
-
validateValue(value) {
|
|
267
|
+
validateValue(value: string[]) {
|
|
263
268
|
if (!isArray(value)) return false;
|
|
264
269
|
if (isEmpty(value) && !this.allowEmpty) return false;
|
|
265
270
|
return value.every(dim => this.dimensionNames.includes(dim));
|
|
266
271
|
}
|
|
267
272
|
|
|
268
|
-
|
|
269
|
-
dims = dims ?? [];
|
|
270
|
-
const ret = {};
|
|
271
|
-
dims.forEach(it => {
|
|
272
|
-
const dim = this.createDimension(it);
|
|
273
|
-
ret[dim.name] = dim;
|
|
274
|
-
});
|
|
275
|
-
return ret;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
createDimension(src: DimensionSpec | string) {
|
|
279
|
-
src = isString(src) ? {name: src} : src;
|
|
280
|
-
throwIf(
|
|
281
|
-
!src.hasOwnProperty('name'),
|
|
282
|
-
"Dimensions provided as Objects must define a 'name' property."
|
|
283
|
-
);
|
|
284
|
-
return {displayName: genDisplayName(src.name), ...src};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
getValueLabel(value: string[]) {
|
|
273
|
+
getValueLabel(value: string[]): string {
|
|
288
274
|
return value.map(dimName => this.getDimDisplayName(dimName)).join(' › ');
|
|
289
275
|
}
|
|
290
276
|
|
|
291
277
|
getDimDisplayName(dimName: string) {
|
|
292
|
-
return this.dimensions[dimName]
|
|
278
|
+
return this.dimensions[dimName]?.displayName ?? dimName;
|
|
293
279
|
}
|
|
294
280
|
|
|
295
281
|
//--------------------
|
|
@@ -343,4 +329,41 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
343
329
|
if (this.persistFavorites) ret.favorites = this.favorites;
|
|
344
330
|
return ret;
|
|
345
331
|
}
|
|
332
|
+
|
|
333
|
+
//------------------------
|
|
334
|
+
// Implementation
|
|
335
|
+
//------------------------
|
|
336
|
+
private normalizeDimensions(
|
|
337
|
+
dims: Array<DimensionSpec | string>
|
|
338
|
+
): Record<string, DimensionSpec> {
|
|
339
|
+
dims = dims ?? [];
|
|
340
|
+
const ret = {};
|
|
341
|
+
dims.forEach(it => {
|
|
342
|
+
const dim = this.createDimension(it);
|
|
343
|
+
ret[dim.name] = dim;
|
|
344
|
+
});
|
|
345
|
+
return ret;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private createDimension(src: DimensionSpec | string) {
|
|
349
|
+
src = isString(src) ? {name: src} : src;
|
|
350
|
+
throwIf(
|
|
351
|
+
!src.hasOwnProperty('name'),
|
|
352
|
+
"Dimensions provided as Objects must define a 'name' property."
|
|
353
|
+
);
|
|
354
|
+
return {displayName: genDisplayName(src.name), ...src};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private removeUnknownDimsFromValue() {
|
|
358
|
+
const {value, dimensionNames, allowEmpty} = this,
|
|
359
|
+
cleanValue = value?.filter(dim => dimensionNames.includes(dim));
|
|
360
|
+
|
|
361
|
+
if (isEqual(value, cleanValue)) return;
|
|
362
|
+
|
|
363
|
+
if (isEmpty(cleanValue) && !allowEmpty) {
|
|
364
|
+
cleanValue.push(dimensionNames[0]);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
this.setValue(cleanValue);
|
|
368
|
+
}
|
|
346
369
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "67.0.0-SNAPSHOT.
|
|
3
|
+
"version": "67.0.0-SNAPSHOT.1725049253748",
|
|
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",
|