@xh/hoist 80.0.0-SNAPSHOT.1767973504648 → 80.0.0-SNAPSHOT.1767982629403
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 +10 -9
- package/build/types/cmp/filter/FilterChooserFieldSpec.d.ts +1 -1
- package/build/types/cmp/filter/FilterChooserModel.d.ts +19 -10
- package/build/types/cmp/grid/GridModel.d.ts +2 -2
- package/build/types/cmp/grid/filter/GridFilterFieldSpec.d.ts +4 -3
- package/build/types/cmp/grid/filter/GridFilterModel.d.ts +1 -1
- package/build/types/cmp/layout/Tags.d.ts +0 -2
- package/build/types/cmp/tab/TabContainerModel.d.ts +1 -1
- package/build/types/data/Store.d.ts +5 -6
- package/build/types/data/cube/View.d.ts +5 -3
- package/build/types/data/filter/BaseFilterFieldSpec.d.ts +3 -3
- package/build/types/data/filter/CompoundFilter.d.ts +1 -1
- package/build/types/data/filter/FieldFilter.d.ts +1 -1
- package/build/types/data/filter/Filter.d.ts +3 -3
- package/build/types/data/filter/FunctionFilter.d.ts +1 -1
- package/build/types/data/filter/Types.d.ts +39 -13
- package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +6 -46
- package/build/types/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTabModel.d.ts +2 -2
- package/build/types/svc/InspectorService.d.ts +2 -2
- package/cmp/filter/FilterChooserFieldSpec.ts +5 -22
- package/cmp/filter/FilterChooserModel.ts +27 -12
- package/cmp/grid/GridModel.ts +2 -2
- package/cmp/grid/filter/GridFilterFieldSpec.ts +52 -51
- package/cmp/grid/filter/GridFilterModel.ts +6 -7
- package/cmp/layout/Tags.ts +0 -2
- package/cmp/tab/TabContainerModel.ts +1 -1
- package/data/Store.ts +47 -13
- package/data/cube/View.ts +14 -3
- package/data/filter/BaseFilterFieldSpec.ts +3 -3
- package/data/filter/CompoundFilter.ts +3 -3
- package/data/filter/FieldFilter.ts +2 -2
- package/data/filter/Filter.ts +4 -4
- package/data/filter/FunctionFilter.ts +2 -2
- package/data/filter/Types.ts +53 -20
- package/desktop/cmp/dash/canvas/DashCanvas.ts +4 -21
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +24 -140
- package/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTabModel.ts +9 -9
- package/package.json +3 -3
- package/svc/InspectorService.ts +6 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/build/types/desktop/cmp/button/FieldsetCollapseButton.d.ts +0 -10
- package/build/types/desktop/cmp/dash/canvas/widgetwell/DashCanvasWidgetWell.d.ts +0 -17
- package/build/types/desktop/cmp/dash/canvas/widgetwell/DashCanvasWidgetWellModel.d.ts +0 -11
- package/build/types/desktop/cmp/form/CollapsibleFieldset.d.ts +0 -11
- package/desktop/cmp/button/FieldsetCollapseButton.ts +0 -44
- package/desktop/cmp/dash/canvas/widgetwell/DashCanvasWidgetWell.scss +0 -26
- package/desktop/cmp/dash/canvas/widgetwell/DashCanvasWidgetWell.ts +0 -126
- package/desktop/cmp/dash/canvas/widgetwell/DashCanvasWidgetWellModel.ts +0 -65
- package/desktop/cmp/form/CollapsibleFieldset.scss +0 -14
- package/desktop/cmp/form/CollapsibleFieldset.ts +0 -65
package/CHANGELOG.md
CHANGED
|
@@ -10,17 +10,18 @@
|
|
|
10
10
|
* Renamed `AppContainerModel.loadModel` to `loadObserver`. This is primarily an internal model,
|
|
11
11
|
so there is no deprecated alias. Any app usages should swap to `XH.appLoadObserver`.
|
|
12
12
|
* Removed additional references to deprecated `loadModel` within Hoist itself.
|
|
13
|
+
* Removed the following instance getters - use new static typeguards instead:
|
|
14
|
+
* `Store.isStore`
|
|
15
|
+
* `View.isView`
|
|
16
|
+
* `Filter.isFilter`
|
|
13
17
|
|
|
14
|
-
###
|
|
15
|
-
|
|
16
|
-
* DashCanvas:
|
|
17
|
-
* supports dragging and dropping widgets in from an external container.
|
|
18
|
-
* supports new compacting strategy: 'wrap'
|
|
19
|
-
* new elementFactory tags: `fieldset`, `legend`
|
|
20
|
-
|
|
21
|
-
### 📚 Libraries
|
|
18
|
+
### ⚙️ Typescript API Adjustments
|
|
22
19
|
|
|
23
|
-
*
|
|
20
|
+
* Introduced new `FilterBindTarget` and `FilterValueSource` interfaces to generalize the data
|
|
21
|
+
sources that could be used with `FilterChooserModel` and `GridFilterModel`. Both `Store` and
|
|
22
|
+
`View` implement these interfaces, meaning no changes are required for apps, but it is now
|
|
23
|
+
possible to use these models with other, alternate implementations if needed.
|
|
24
|
+
* Added new static typeguard methods on `Store`, `View`, and `Filter` + subclasses.
|
|
24
25
|
|
|
25
26
|
## 79.0.0 - 2026-01-05
|
|
26
27
|
|
|
@@ -31,7 +31,7 @@ export declare class FilterChooserFieldSpec extends BaseFilterFieldSpec {
|
|
|
31
31
|
renderValue(value: any, op: FieldFilterOperator): string;
|
|
32
32
|
parseValue(value: any, op: FieldFilterOperator): any;
|
|
33
33
|
parseExample(example: any): any;
|
|
34
|
-
parseValueParser(valueParser:
|
|
34
|
+
parseValueParser(valueParser: FilterChooserValueParser): FilterChooserValueParser;
|
|
35
35
|
loadValuesFromSource(): void;
|
|
36
36
|
}
|
|
37
37
|
type FilterChooserValueRenderer = (value: any, op: FieldFilterOperator) => ReactNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HoistModel, PersistOptions, TaskObserver, Thunkable } from '@xh/hoist/core';
|
|
2
|
-
import { CompoundFilter, FieldFilter, Filter,
|
|
2
|
+
import { CompoundFilter, FieldFilter, Filter, FilterBindTarget, FilterValueSource } from '@xh/hoist/data';
|
|
3
3
|
import { CompoundFilterSpec, FieldFilterSpec, FilterLike } from '@xh/hoist/data/filter/Types';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
import { FilterChooserFieldSpec, FilterChooserFieldSpecConfig } from './FilterChooserFieldSpec';
|
|
@@ -15,16 +15,25 @@ export interface FilterChooserConfig {
|
|
|
15
15
|
/** Default properties to be assigned to all FilterChooserFieldSpecs created by this model. */
|
|
16
16
|
fieldSpecDefaults?: Partial<FilterChooserFieldSpecConfig>;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Target (typically a {@link Store} or Cube {@link View}) to which this model's filter should
|
|
19
|
+
* be automatically applied as it changes.
|
|
20
|
+
*
|
|
21
|
+
* Note this binding is bi-directional - the target's filter will also be *set onto* this model
|
|
22
|
+
* if it changes on the target, to support e.g. sync'd filtering between a FilterChooser and
|
|
23
|
+
* Grid filtering bound to the same target Store.
|
|
24
|
+
*
|
|
25
|
+
* Leave undefined if you wish to combine this model's values with other filters, send it to
|
|
26
|
+
* the server, or otherwise observe and handle value changes manually.
|
|
21
27
|
*/
|
|
22
|
-
bind?:
|
|
28
|
+
bind?: FilterBindTarget;
|
|
23
29
|
/**
|
|
24
|
-
*
|
|
25
|
-
* provide suggested data values (if so
|
|
30
|
+
* Source (typically a {@link Store} or Cube {@link View}) from which this model can lookup
|
|
31
|
+
* matching Field-level defaults for `fieldSpecs` and provide suggested data values (if so
|
|
32
|
+
* configured) from user input.
|
|
33
|
+
*
|
|
34
|
+
* Defaults to {@link bind} if the a bind target is provided and is a valid source.
|
|
26
35
|
*/
|
|
27
|
-
valueSource?:
|
|
36
|
+
valueSource?: FilterValueSource;
|
|
28
37
|
/**
|
|
29
38
|
* Configuration for a filter appropriate to be rendered and managed by FilterChooser, or a function
|
|
30
39
|
* to produce the same. Note that FilterChooser currently can only edit and create a flat collection
|
|
@@ -62,8 +71,8 @@ export interface FilterChooserConfig {
|
|
|
62
71
|
export declare class FilterChooserModel extends HoistModel {
|
|
63
72
|
value: FilterChooserFilter;
|
|
64
73
|
favorites: FilterChooserFilter[];
|
|
65
|
-
bind:
|
|
66
|
-
valueSource:
|
|
74
|
+
bind: FilterBindTarget;
|
|
75
|
+
valueSource: FilterValueSource;
|
|
67
76
|
fieldSpecs: FilterChooserFieldSpec[];
|
|
68
77
|
suggestFieldsWhenEmpty: boolean;
|
|
69
78
|
sortFieldSuggestions: boolean;
|
|
@@ -553,9 +553,9 @@ export declare class GridModel extends HoistModel {
|
|
|
553
553
|
autosizeAsync(overrideOpts?: Omit<GridAutosizeOptions, 'mode'>): Promise<void>;
|
|
554
554
|
/**
|
|
555
555
|
* Begin an inline editing session.
|
|
556
|
-
* @param
|
|
556
|
+
* @param record - StoreRecord/ID to edit. If unspecified, the first selected StoreRecord
|
|
557
557
|
* will be used, if any, or the first overall StoreRecord in the grid.
|
|
558
|
-
* @param
|
|
558
|
+
* @param colId - ID of column on which to start editing. If unspecified, the first
|
|
559
559
|
* editable column will be used.
|
|
560
560
|
*/
|
|
561
561
|
beginEditAsync(opts?: {
|
|
@@ -22,17 +22,18 @@ export interface GridFilterFieldSpecConfig extends BaseFilterFieldSpecConfig {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Apps should NOT instantiate this class directly.
|
|
25
|
-
* Instead, provide a config for this object
|
|
25
|
+
* Instead, provide a config for this object via {@link GridConfig.filterModel} config.
|
|
26
26
|
*/
|
|
27
27
|
export declare class GridFilterFieldSpec extends BaseFilterFieldSpec {
|
|
28
28
|
filterModel: GridFilterModel;
|
|
29
29
|
renderer: ColumnRenderer;
|
|
30
30
|
inputProps: PlainObject;
|
|
31
31
|
defaultOp: FieldFilterOperator;
|
|
32
|
-
|
|
32
|
+
/** Total number of unique values for this field in the source, regardless of other filters. */
|
|
33
|
+
allValuesCount: number;
|
|
33
34
|
constructor({ filterModel, renderer, inputProps, defaultOp, ...rest }: GridFilterFieldSpecConfig);
|
|
34
35
|
getUniqueValue(value: unknown): unknown;
|
|
35
36
|
loadValuesFromSource(): void;
|
|
36
37
|
private cleanFilter;
|
|
37
|
-
private
|
|
38
|
+
private toDisplayValue;
|
|
38
39
|
}
|
|
@@ -38,7 +38,7 @@ export declare class GridFilterModel extends HoistModel {
|
|
|
38
38
|
fromDisplayValue(value: any): any;
|
|
39
39
|
openDialog(): void;
|
|
40
40
|
closeDialog(): void;
|
|
41
|
-
setFilter(filter:
|
|
41
|
+
setFilter(filter: Filter): void;
|
|
42
42
|
private parseFieldSpecs;
|
|
43
43
|
private getOuterCompoundFilter;
|
|
44
44
|
}
|
|
@@ -10,7 +10,6 @@ export declare const a: import("@xh/hoist/core").ElementFactory<import("react").
|
|
|
10
10
|
export declare const br: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLBRElement>, HTMLBRElement>>;
|
|
11
11
|
export declare const code: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>>;
|
|
12
12
|
export declare const div: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>>;
|
|
13
|
-
export declare const fieldset: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>>;
|
|
14
13
|
export declare const form: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>>;
|
|
15
14
|
export declare const hr: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHRElement>, HTMLHRElement>>;
|
|
16
15
|
export declare const h1: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>>;
|
|
@@ -18,7 +17,6 @@ export declare const h2: import("@xh/hoist/core").ElementFactory<import("react")
|
|
|
18
17
|
export declare const h3: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>>;
|
|
19
18
|
export declare const h4: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>>;
|
|
20
19
|
export declare const label: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>>;
|
|
21
|
-
export declare const legend: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>>;
|
|
22
20
|
export declare const li: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>>;
|
|
23
21
|
export declare const nav: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>>;
|
|
24
22
|
export declare const ol: import("@xh/hoist/core").ElementFactory<import("react").DetailedHTMLProps<import("react").OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>>;
|
|
@@ -70,7 +70,7 @@ export declare class TabContainerModel extends HoistModel {
|
|
|
70
70
|
protected lastActiveTabId: string;
|
|
71
71
|
/**
|
|
72
72
|
* @param config - TabContainer configuration.
|
|
73
|
-
* @param depth - Depth in hierarchy of nested TabContainerModels. Not for application use.
|
|
73
|
+
* @param [depth] - Depth in hierarchy of nested TabContainerModels. Not for application use.
|
|
74
74
|
*/
|
|
75
75
|
constructor({ tabs, defaultTabId, route, track, renderMode, refreshMode, persistWith, emptyText, xhImpl, switcher }: TabContainerConfig, depth?: number);
|
|
76
76
|
/** Set/replace all tabs within the container. */
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { HoistBase, PlainObject, Some } from '@xh/hoist/core';
|
|
2
|
-
import { Field, FieldSpec } from '
|
|
2
|
+
import { Field, FieldSpec, Filter, FilterBindTarget, FilterLike, FilterValueSource, StoreRecord, StoreRecordId, StoreRecordOrId } from '@xh/hoist/data';
|
|
3
3
|
import { RecordSet } from './impl/RecordSet';
|
|
4
4
|
import { StoreErrorMap, StoreValidator } from './impl/StoreValidator';
|
|
5
|
-
import { StoreRecord, StoreRecordId, StoreRecordOrId } from './StoreRecord';
|
|
6
|
-
import { Filter } from './filter/Filter';
|
|
7
|
-
import { FilterLike } from './filter/Types';
|
|
8
5
|
export interface StoreConfig {
|
|
9
6
|
/** Field names, configs, or instances. */
|
|
10
7
|
fields?: Array<string | FieldSpec | Field>;
|
|
@@ -127,8 +124,9 @@ export type StoreRecordIdSpec = string | ((data: PlainObject) => StoreRecordId);
|
|
|
127
124
|
/**
|
|
128
125
|
* A managed and observable set of local, in-memory Records.
|
|
129
126
|
*/
|
|
130
|
-
export declare class Store extends HoistBase {
|
|
131
|
-
|
|
127
|
+
export declare class Store extends HoistBase implements FilterBindTarget, FilterValueSource {
|
|
128
|
+
static isStore(obj: unknown): obj is Store;
|
|
129
|
+
readonly isFilterValueSource = true;
|
|
132
130
|
fields: Field[];
|
|
133
131
|
idSpec: (data: PlainObject) => StoreRecordId;
|
|
134
132
|
processRawData: (raw: any) => any;
|
|
@@ -323,6 +321,7 @@ export declare class Store extends HoistBase {
|
|
|
323
321
|
* false if the record is either not in the Store at all or not filtered out.
|
|
324
322
|
*/
|
|
325
323
|
recordIsFiltered(recOrId: StoreRecordOrId): boolean;
|
|
324
|
+
getValuesForFieldFilter(fieldName: string, filter?: Filter): any[];
|
|
326
325
|
/**
|
|
327
326
|
* Set whether the root should be loaded as summary data in loadData().
|
|
328
327
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HoistBase, PlainObject, Some } from '@xh/hoist/core';
|
|
2
|
-
import { Cube, CubeField, Filter, FilterLike, Query, QueryConfig, Store, StoreChangeLog, StoreRecordId } from '@xh/hoist/data';
|
|
2
|
+
import { Cube, CubeField, Filter, FilterBindTarget, FilterLike, FilterValueSource, Query, QueryConfig, Store, StoreChangeLog, StoreRecordId } from '@xh/hoist/data';
|
|
3
3
|
import { ViewRowData } from '@xh/hoist/data/cube/ViewRowData';
|
|
4
4
|
import { AggregationContext } from './aggregate/AggregationContext';
|
|
5
5
|
import { BaseRow } from './row/BaseRow';
|
|
@@ -33,8 +33,9 @@ export interface DimensionValue {
|
|
|
33
33
|
* Primary interface for consuming grouped and aggregated data from the cube.
|
|
34
34
|
* Applications should create via the {@link Cube.createView} factory.
|
|
35
35
|
*/
|
|
36
|
-
export declare class View extends HoistBase {
|
|
37
|
-
|
|
36
|
+
export declare class View extends HoistBase implements FilterBindTarget, FilterValueSource {
|
|
37
|
+
static isView(obj: unknown): obj is View;
|
|
38
|
+
readonly isFilterValueSource = true;
|
|
38
39
|
/** Query defining this View. Update via {@link updateQuery}. */
|
|
39
40
|
query: Query;
|
|
40
41
|
/**
|
|
@@ -81,6 +82,7 @@ export declare class View extends HoistBase {
|
|
|
81
82
|
setFilter(filter: FilterLike): void;
|
|
82
83
|
noteCubeLoaded(): void;
|
|
83
84
|
noteCubeUpdated(changeLog: StoreChangeLog): void;
|
|
85
|
+
getValuesForFieldFilter(fieldName: string, filter?: Filter): any[];
|
|
84
86
|
private fullUpdate;
|
|
85
87
|
private dataOnlyUpdate;
|
|
86
88
|
private loadStores;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HoistBase } from '@xh/hoist/core';
|
|
2
|
-
import { Field,
|
|
2
|
+
import { Field, FieldType, FilterValueSource } from '@xh/hoist/data';
|
|
3
3
|
import { FieldFilterOperator } from './Types';
|
|
4
4
|
export interface BaseFilterFieldSpecConfig {
|
|
5
5
|
/** Identifying field name to filter on. */
|
|
@@ -11,7 +11,7 @@ export interface BaseFilterFieldSpecConfig {
|
|
|
11
11
|
/** Operators available for filtering, will default to a supported set based on type.*/
|
|
12
12
|
ops?: FieldFilterOperator[];
|
|
13
13
|
/** Used to source matching data `Field` and extract values if configured. */
|
|
14
|
-
source?:
|
|
14
|
+
source?: FilterValueSource;
|
|
15
15
|
/**
|
|
16
16
|
* True to provide interfaces and auto-complete options
|
|
17
17
|
* with enumerated matches for creating '=' or '!=' filters. Defaults to true for
|
|
@@ -38,7 +38,7 @@ export declare abstract class BaseFilterFieldSpec extends HoistBase {
|
|
|
38
38
|
fieldType: FieldType;
|
|
39
39
|
displayName: string;
|
|
40
40
|
ops: FieldFilterOperator[];
|
|
41
|
-
source:
|
|
41
|
+
source: FilterValueSource;
|
|
42
42
|
enableValues: boolean;
|
|
43
43
|
forceSelection: boolean;
|
|
44
44
|
values: any[];
|
|
@@ -6,7 +6,7 @@ import { CompoundFilterSpec, CompoundFilterOperator, FilterTestFn } from './Type
|
|
|
6
6
|
* Immutable.
|
|
7
7
|
*/
|
|
8
8
|
export declare class CompoundFilter extends Filter {
|
|
9
|
-
|
|
9
|
+
static isCompoundFilter(obj: unknown): obj is CompoundFilter;
|
|
10
10
|
readonly filters: Filter[];
|
|
11
11
|
readonly op: CompoundFilterOperator;
|
|
12
12
|
/** @returns the singular field this filter operates on, if consistent across all clauses. */
|
|
@@ -11,7 +11,7 @@ import { FieldFilterOperator, FieldFilterSpec, FilterTestFn } from './Types';
|
|
|
11
11
|
* Immutable.
|
|
12
12
|
*/
|
|
13
13
|
export declare class FieldFilter extends Filter {
|
|
14
|
-
|
|
14
|
+
static isFieldFilter(obj: unknown): obj is FieldFilter;
|
|
15
15
|
readonly field: string;
|
|
16
16
|
readonly op: FieldFilterOperator;
|
|
17
17
|
readonly value: any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Store } from '
|
|
2
|
-
import { FilterSpec, FilterTestFn } from './Types';
|
|
1
|
+
import { Store } from '@xh/hoist/data';
|
|
2
|
+
import type { FilterSpec, FilterTestFn } from './Types';
|
|
3
3
|
/**
|
|
4
4
|
* Base class for Hoist data package Filters.
|
|
5
5
|
*
|
|
@@ -12,7 +12,7 @@ import { FilterSpec, FilterTestFn } from './Types';
|
|
|
12
12
|
* via an `AND` or `OR` operator.
|
|
13
13
|
*/
|
|
14
14
|
export declare abstract class Filter {
|
|
15
|
-
|
|
15
|
+
static isFilter(obj: unknown): obj is Filter;
|
|
16
16
|
/**
|
|
17
17
|
* @returns a function that can be used to test a record or object.
|
|
18
18
|
* @param store - if provided, return will be appropriate for testing records of this store.
|
|
@@ -8,7 +8,7 @@ import { FunctionFilterSpec, FilterTestFn } from './Types';
|
|
|
8
8
|
* Immutable.
|
|
9
9
|
*/
|
|
10
10
|
export declare class FunctionFilter extends Filter {
|
|
11
|
-
|
|
11
|
+
static isFunctionFilter(obj: unknown): obj is FunctionFilter;
|
|
12
12
|
readonly key: string;
|
|
13
13
|
readonly testFn: FilterTestFn;
|
|
14
14
|
/**
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { PlainObject } from '@xh/hoist/core';
|
|
2
|
-
import { Filter } from './Filter';
|
|
3
|
-
import { StoreRecord, Field, FieldType } from '../';
|
|
4
|
-
export type
|
|
5
|
-
export
|
|
6
|
-
/** Collection of Filters or configs to create. */
|
|
7
|
-
filters: FilterLike[];
|
|
8
|
-
/** logical operator 'AND' (default) or 'OR'. */
|
|
9
|
-
op?: CompoundFilterOperator;
|
|
10
|
-
}
|
|
11
|
-
export type FieldFilterOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'like' | 'not like' | 'begins' | 'not begins' | 'ends' | 'not ends' | 'includes' | 'excludes';
|
|
1
|
+
import type { PlainObject } from '@xh/hoist/core';
|
|
2
|
+
import type { Filter } from './Filter';
|
|
3
|
+
import type { StoreRecord, Field, FieldType } from '../';
|
|
4
|
+
export type FilterLike = Filter | FilterSpec | FilterTestFn | FilterLike[];
|
|
5
|
+
export type FilterSpec = FieldFilterSpec | FunctionFilterSpec | CompoundFilterSpec;
|
|
12
6
|
export interface FieldFilterSpec {
|
|
13
7
|
/** Name of Field to filter or Field instance. */
|
|
14
8
|
field: string | Field;
|
|
@@ -18,6 +12,14 @@ export interface FieldFilterSpec {
|
|
|
18
12
|
/** For internal serialization only. */
|
|
19
13
|
valueType?: FieldType;
|
|
20
14
|
}
|
|
15
|
+
export type FieldFilterOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'like' | 'not like' | 'begins' | 'not begins' | 'ends' | 'not ends' | 'includes' | 'excludes';
|
|
16
|
+
export interface CompoundFilterSpec {
|
|
17
|
+
/** Collection of Filters or configs to create. */
|
|
18
|
+
filters: FilterLike[];
|
|
19
|
+
/** logical operator 'AND' (default) or 'OR'. */
|
|
20
|
+
op?: CompoundFilterOperator;
|
|
21
|
+
}
|
|
22
|
+
export type CompoundFilterOperator = 'AND' | 'OR' | 'and' | 'or';
|
|
21
23
|
export interface FunctionFilterSpec {
|
|
22
24
|
/** Key used to identify this FunctionFilter.*/
|
|
23
25
|
key: string;
|
|
@@ -30,5 +32,29 @@ export interface FunctionFilterSpec {
|
|
|
30
32
|
* @returns true if the candidate passes and should be included in filtered results.
|
|
31
33
|
*/
|
|
32
34
|
export type FilterTestFn = (candidate: PlainObject | StoreRecord) => boolean;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Target (typically a {@link Store} or Cube {@link View}) that can be used by filtering models
|
|
37
|
+
* such as {@link FilterChooserModel} and {@link GridFilterModel} to get and set filters.
|
|
38
|
+
*/
|
|
39
|
+
export interface FilterBindTarget {
|
|
40
|
+
filter: Filter;
|
|
41
|
+
setFilter(filter: FilterLike): unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Data provider (typically a {@link Store} or Cube {@link View}) that can be used by filtering
|
|
45
|
+
* models such as {@link FilterChooserModel} and {@link GridFilterModel} to source available
|
|
46
|
+
* values from within a dataset for display / suggestion to users.
|
|
47
|
+
*/
|
|
48
|
+
export interface FilterValueSource {
|
|
49
|
+
/** Names of all fields available in the source. */
|
|
50
|
+
fieldNames: string[];
|
|
51
|
+
/** @returns the Field instance for the given field name. */
|
|
52
|
+
getField(fieldName: string): Field;
|
|
53
|
+
/** @returns unique values for the given field, applying the given filter if provided. */
|
|
54
|
+
getValuesForFieldFilter(fieldName: string, filter?: Filter): any[];
|
|
55
|
+
/** Observable timestamp for the source's data, to trigger consumers to re-query values. */
|
|
56
|
+
lastUpdated: number;
|
|
57
|
+
/** For the {@link isFilterValueSource} typeguard. */
|
|
58
|
+
isFilterValueSource: true;
|
|
59
|
+
}
|
|
60
|
+
export declare function isFilterValueSource(v: unknown): v is FilterValueSource;
|
|
@@ -14,12 +14,11 @@ export interface DashCanvasConfig extends DashConfig<DashCanvasViewSpec, DashCan
|
|
|
14
14
|
*/
|
|
15
15
|
rowHeight?: number;
|
|
16
16
|
/**
|
|
17
|
-
* Whether views should "compact" vertically
|
|
17
|
+
* Whether views should "compact" vertically or horizontally
|
|
18
18
|
* to condense space. Default `true` defaults to vertical compaction.
|
|
19
|
-
* Use `wrap` with caution. It only works well if all items are 1 row high.
|
|
20
19
|
* See react-grid-layout docs for more information.
|
|
21
|
-
*/
|
|
22
|
-
compact?: boolean | 'vertical' | 'horizontal'
|
|
20
|
+
* */
|
|
21
|
+
compact?: boolean | 'vertical' | 'horizontal';
|
|
23
22
|
/** Between items [x,y] in pixels. Default `[10, 10]`. */
|
|
24
23
|
margin?: [number, number];
|
|
25
24
|
/** Padding inside the container [x, y] in pixels. Defaults to same as `margin`. */
|
|
@@ -30,31 +29,6 @@ export interface DashCanvasConfig extends DashConfig<DashCanvasViewSpec, DashCan
|
|
|
30
29
|
* Whether a grid background should be shown. Default false.
|
|
31
30
|
*/
|
|
32
31
|
showGridBackground?: boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Whether the canvas should accept drag-and-drop of views from outside
|
|
35
|
-
* the canvas. Default false.
|
|
36
|
-
*/
|
|
37
|
-
allowsDrop?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Optional callback to invoke after a view is successfully dropped onto the canvas.
|
|
40
|
-
*/
|
|
41
|
-
onDropDone?: (viewModel: DashCanvasViewModel) => void;
|
|
42
|
-
/**
|
|
43
|
-
* Optional callback to invoke when an item is dragged over the canvas. This may be used to
|
|
44
|
-
* customize how the size of the dropping placeholder is calculated. The callback should
|
|
45
|
-
* return an object with optional properties indicating the desired width, height (in grid units),
|
|
46
|
-
* and offset (in pixels) of the dropping placeholder. The method's signature is the same as
|
|
47
|
-
* the `onDropDragOver` prop of ReactGridLayout.
|
|
48
|
-
* Returning `false` will prevent the dropping placeholder from being shown, and prevents a drop.
|
|
49
|
-
* Returning `void` will use the default behavior, which is to size the placeholder as per the
|
|
50
|
-
* `dropConfig.defaultItem` specification.
|
|
51
|
-
*/
|
|
52
|
-
onDropDragOver?: (e: DragEvent) => OnDropDragOverResult;
|
|
53
|
-
/**
|
|
54
|
-
* Whether an overlay with an Add View button should be rendered
|
|
55
|
-
* when the canvas is empty. Default true.
|
|
56
|
-
*/
|
|
57
|
-
showAddViewButtonWhenEmpty?: boolean;
|
|
58
32
|
}
|
|
59
33
|
export interface DashCanvasItemState {
|
|
60
34
|
layout: DashCanvasItemLayout;
|
|
@@ -68,12 +42,6 @@ export interface DashCanvasItemLayout {
|
|
|
68
42
|
w: number;
|
|
69
43
|
h: number;
|
|
70
44
|
}
|
|
71
|
-
export type OnDropDragOverResult = {
|
|
72
|
-
w?: number;
|
|
73
|
-
h?: number;
|
|
74
|
-
dragOffsetX?: number;
|
|
75
|
-
dragOffsetY?: number;
|
|
76
|
-
} | false | void;
|
|
77
45
|
/**
|
|
78
46
|
* Model for {@link DashCanvas}, managing all configurable options for the component and publishing
|
|
79
47
|
* the observable state of its current widgets and their layout.
|
|
@@ -83,17 +51,12 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
|
|
|
83
51
|
}> {
|
|
84
52
|
columns: number;
|
|
85
53
|
rowHeight: number;
|
|
86
|
-
compact: 'vertical' | 'horizontal'
|
|
54
|
+
compact: 'vertical' | 'horizontal';
|
|
87
55
|
margin: [number, number];
|
|
88
56
|
containerPadding: [number, number];
|
|
89
57
|
showGridBackground: boolean;
|
|
90
58
|
rglHeight: number;
|
|
91
|
-
showAddViewButtonWhenEmpty: boolean;
|
|
92
|
-
DROPPING_ELEM_ID: string;
|
|
93
59
|
maxRows: number;
|
|
94
|
-
allowsDrop: boolean;
|
|
95
|
-
onDropDone: (viewModel: DashCanvasViewModel) => void;
|
|
96
|
-
draggedInView: DashCanvasItemState;
|
|
97
60
|
/** Current number of rows in canvas */
|
|
98
61
|
get rows(): number;
|
|
99
62
|
get isEmpty(): boolean;
|
|
@@ -102,7 +65,7 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
|
|
|
102
65
|
isResizing: boolean;
|
|
103
66
|
private isLoadingState;
|
|
104
67
|
get rglLayout(): any[];
|
|
105
|
-
constructor({ viewSpecs, viewSpecDefaults, initialState, layoutLocked, contentLocked, renameLocked, persistWith, emptyText, addViewButtonText, columns, rowHeight, compact, margin, maxRows, containerPadding, extraMenuItems, showGridBackground
|
|
68
|
+
constructor({ viewSpecs, viewSpecDefaults, initialState, layoutLocked, contentLocked, renameLocked, persistWith, emptyText, addViewButtonText, columns, rowHeight, compact, margin, maxRows, containerPadding, extraMenuItems, showGridBackground }: DashCanvasConfig);
|
|
106
69
|
/** Removes all views from the canvas */
|
|
107
70
|
clear(): void;
|
|
108
71
|
/**
|
|
@@ -140,10 +103,6 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
|
|
|
140
103
|
renameView(id: string): void;
|
|
141
104
|
/** Scrolls a DashCanvasView into view. */
|
|
142
105
|
ensureViewVisible(id: string): void;
|
|
143
|
-
onDrop(rglLayout: LayoutItem[], layoutItem: LayoutItem, evt: Event): void;
|
|
144
|
-
setDraggedInView(view?: DashCanvasItemState): void;
|
|
145
|
-
onDropDragOver(evt: DragEvent): OnDropDragOverResult;
|
|
146
|
-
getViewsBySpecId(id: any): DashCanvasViewModel[];
|
|
147
106
|
getPersistableState(): PersistableState<{
|
|
148
107
|
state: DashCanvasItemState[];
|
|
149
108
|
}>;
|
|
@@ -164,5 +123,6 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
|
|
|
164
123
|
private setViewLayout;
|
|
165
124
|
private getSpec;
|
|
166
125
|
private hasSpec;
|
|
126
|
+
private getViewsBySpecId;
|
|
167
127
|
private getNextAvailablePosition;
|
|
168
128
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GridFilterModel, GridModel } from '@xh/hoist/cmp/grid';
|
|
2
2
|
import { HoistModel } from '@xh/hoist/core';
|
|
3
|
-
import { FieldFilterSpec } from '@xh/hoist/data';
|
|
3
|
+
import type { FieldFilterSpec } from '@xh/hoist/data';
|
|
4
4
|
import { HeaderFilterModel } from '../HeaderFilterModel';
|
|
5
5
|
export declare class ValuesTabModel extends HoistModel {
|
|
6
6
|
xhImpl: boolean;
|
|
@@ -24,7 +24,7 @@ export declare class ValuesTabModel extends HoistModel {
|
|
|
24
24
|
get columnFilters(): import("@xh/hoist/data").FieldFilter[];
|
|
25
25
|
get gridFilterModel(): GridFilterModel;
|
|
26
26
|
get values(): any[];
|
|
27
|
-
get
|
|
27
|
+
get allValuesCount(): number;
|
|
28
28
|
get hasHiddenValues(): boolean;
|
|
29
29
|
get sortIcon(): any;
|
|
30
30
|
constructor(headerFilterModel: HeaderFilterModel);
|
|
@@ -45,13 +45,13 @@ export declare class InspectorService extends HoistService {
|
|
|
45
45
|
clearStats(): void;
|
|
46
46
|
restoreDefaultsAsync(): Promise<void>;
|
|
47
47
|
private sync;
|
|
48
|
-
setActiveInstances(ai:
|
|
48
|
+
setActiveInstances(ai: InspectorInstanceData[]): void;
|
|
49
49
|
_prevModelCount: number;
|
|
50
50
|
get conf(): any;
|
|
51
51
|
}
|
|
52
52
|
interface InspectorInstanceData {
|
|
53
53
|
className: string;
|
|
54
|
-
created:
|
|
54
|
+
created: number;
|
|
55
55
|
isHoistModel: boolean;
|
|
56
56
|
isHoistService: boolean;
|
|
57
57
|
isStore: boolean;
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2026 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {parseFieldValue} from '@xh/hoist/data';
|
|
7
8
|
import {
|
|
8
9
|
BaseFilterFieldSpec,
|
|
9
10
|
BaseFilterFieldSpecConfig
|
|
10
11
|
} from '@xh/hoist/data/filter/BaseFilterFieldSpec';
|
|
11
12
|
import {FieldFilterOperator} from '@xh/hoist/data/filter/Types';
|
|
12
|
-
import {parseFieldValue, View} from '@xh/hoist/data';
|
|
13
13
|
import {fmtDate, parseNumber} from '@xh/hoist/format';
|
|
14
14
|
import {stripTags, throwIf} from '@xh/hoist/utils/js';
|
|
15
|
-
import {isFunction, isNil} from 'lodash';
|
|
16
|
-
import {isValidElement, ReactNode} from 'react';
|
|
17
15
|
import {renderToStaticMarkup} from '@xh/hoist/utils/react';
|
|
16
|
+
import {isFunction} from 'lodash';
|
|
17
|
+
import {isValidElement, ReactNode} from 'react';
|
|
18
18
|
|
|
19
19
|
export interface FilterChooserFieldSpecConfig extends BaseFilterFieldSpecConfig {
|
|
20
20
|
/**
|
|
@@ -120,7 +120,7 @@ export class FilterChooserFieldSpec extends BaseFilterFieldSpec {
|
|
|
120
120
|
return 'value';
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
parseValueParser(valueParser) {
|
|
123
|
+
parseValueParser(valueParser: FilterChooserValueParser): FilterChooserValueParser {
|
|
124
124
|
// Default numeric parser
|
|
125
125
|
if (!valueParser && (this.fieldType === 'int' || this.fieldType === 'number')) {
|
|
126
126
|
return input => parseNumber(input);
|
|
@@ -129,24 +129,7 @@ export class FilterChooserFieldSpec extends BaseFilterFieldSpec {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
loadValuesFromSource() {
|
|
132
|
-
|
|
133
|
-
values = new Set();
|
|
134
|
-
|
|
135
|
-
// Note use of unfiltered recordset here to source suggest values. This allows chooser to
|
|
136
|
-
// suggest values from already-filtered fields that will expand the results when selected.
|
|
137
|
-
const sourceStore = source instanceof View ? source.cube.store : source;
|
|
138
|
-
sourceStore.allRecords.forEach(rec => {
|
|
139
|
-
const val = rec.get(field);
|
|
140
|
-
if (!isNil(val)) {
|
|
141
|
-
if (sourceStore.getField(field).type === 'tags') {
|
|
142
|
-
val.forEach(it => values.add(it));
|
|
143
|
-
} else {
|
|
144
|
-
values.add(val);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
this.values = Array.from(values);
|
|
132
|
+
this.values = this.source.getValuesForFieldFilter(this.field);
|
|
150
133
|
}
|
|
151
134
|
}
|
|
152
135
|
|
|
@@ -18,9 +18,10 @@ import {
|
|
|
18
18
|
CompoundFilter,
|
|
19
19
|
FieldFilter,
|
|
20
20
|
Filter,
|
|
21
|
+
FilterBindTarget,
|
|
22
|
+
FilterValueSource,
|
|
23
|
+
isFilterValueSource,
|
|
21
24
|
parseFilter,
|
|
22
|
-
Store,
|
|
23
|
-
View,
|
|
24
25
|
withFilterByTypes
|
|
25
26
|
} from '@xh/hoist/data';
|
|
26
27
|
import {CompoundFilterSpec, FieldFilterSpec, FilterLike} from '@xh/hoist/data/filter/Types';
|
|
@@ -66,17 +67,26 @@ export interface FilterChooserConfig {
|
|
|
66
67
|
fieldSpecDefaults?: Partial<FilterChooserFieldSpecConfig>;
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
70
|
+
* Target (typically a {@link Store} or Cube {@link View}) to which this model's filter should
|
|
71
|
+
* be automatically applied as it changes.
|
|
72
|
+
*
|
|
73
|
+
* Note this binding is bi-directional - the target's filter will also be *set onto* this model
|
|
74
|
+
* if it changes on the target, to support e.g. sync'd filtering between a FilterChooser and
|
|
75
|
+
* Grid filtering bound to the same target Store.
|
|
76
|
+
*
|
|
77
|
+
* Leave undefined if you wish to combine this model's values with other filters, send it to
|
|
78
|
+
* the server, or otherwise observe and handle value changes manually.
|
|
72
79
|
*/
|
|
73
|
-
bind?:
|
|
80
|
+
bind?: FilterBindTarget;
|
|
74
81
|
|
|
75
82
|
/**
|
|
76
|
-
*
|
|
77
|
-
* provide suggested data values (if so
|
|
83
|
+
* Source (typically a {@link Store} or Cube {@link View}) from which this model can lookup
|
|
84
|
+
* matching Field-level defaults for `fieldSpecs` and provide suggested data values (if so
|
|
85
|
+
* configured) from user input.
|
|
86
|
+
*
|
|
87
|
+
* Defaults to {@link bind} if the a bind target is provided and is a valid source.
|
|
78
88
|
*/
|
|
79
|
-
valueSource?:
|
|
89
|
+
valueSource?: FilterValueSource;
|
|
80
90
|
|
|
81
91
|
/**
|
|
82
92
|
* Configuration for a filter appropriate to be rendered and managed by FilterChooser, or a function
|
|
@@ -124,8 +134,8 @@ export interface FilterChooserConfig {
|
|
|
124
134
|
export class FilterChooserModel extends HoistModel {
|
|
125
135
|
@observable.ref value: FilterChooserFilter = null;
|
|
126
136
|
@observable.ref favorites: FilterChooserFilter[] = [];
|
|
127
|
-
bind:
|
|
128
|
-
valueSource:
|
|
137
|
+
bind: FilterBindTarget;
|
|
138
|
+
valueSource: FilterValueSource;
|
|
129
139
|
|
|
130
140
|
@managed fieldSpecs: FilterChooserFieldSpec[] = [];
|
|
131
141
|
|
|
@@ -155,7 +165,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
155
165
|
fieldSpecs,
|
|
156
166
|
fieldSpecDefaults,
|
|
157
167
|
bind = null,
|
|
158
|
-
valueSource
|
|
168
|
+
valueSource,
|
|
159
169
|
initialValue = null,
|
|
160
170
|
initialFavorites = [],
|
|
161
171
|
suggestFieldsWhenEmpty = true,
|
|
@@ -169,7 +179,12 @@ export class FilterChooserModel extends HoistModel {
|
|
|
169
179
|
makeObservable(this);
|
|
170
180
|
|
|
171
181
|
this.bind = bind;
|
|
182
|
+
|
|
172
183
|
this.valueSource = valueSource;
|
|
184
|
+
if (!this.valueSource && isFilterValueSource(bind)) {
|
|
185
|
+
this.valueSource = bind;
|
|
186
|
+
}
|
|
187
|
+
|
|
173
188
|
this.fieldSpecs = this.parseFieldSpecs(fieldSpecs, fieldSpecDefaults);
|
|
174
189
|
this.suggestFieldsWhenEmpty = !!suggestFieldsWhenEmpty;
|
|
175
190
|
this.sortFieldSuggestions = sortFieldSuggestions;
|