ag-grid-url-sync 0.5.0 → 0.5.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/README.md +339 -66
- package/dist/core/ag-grid-url-sync.d.ts +16 -9
- package/dist/core/ag-grid-url-sync.js +23 -19
- package/dist/core/ag-grid-url-sync.js.map +1 -1
- package/dist/core/codecs.d.ts +28 -0
- package/dist/core/codecs.js +39 -0
- package/dist/core/codecs.js.map +1 -0
- package/dist/core/data-issue-codes.d.ts +3 -0
- package/dist/core/data-issue-codes.js +10 -0
- package/dist/core/data-issue-codes.js.map +1 -0
- package/dist/core/grid-integration.d.ts +38 -2
- package/dist/core/grid-integration.js +169 -128
- package/dist/core/grid-integration.js.map +1 -1
- package/dist/core/grid-url-sync.d.ts +62 -0
- package/dist/core/grid-url-sync.js +738 -0
- package/dist/core/grid-url-sync.js.map +1 -0
- package/dist/core/index.d.ts +4 -1
- package/dist/core/index.js +4 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/individual-params.d.ts +12 -5
- package/dist/core/individual-params.js +38 -62
- package/dist/core/individual-params.js.map +1 -1
- package/dist/core/issue-columns.d.ts +2 -0
- package/dist/core/issue-columns.js +11 -0
- package/dist/core/issue-columns.js.map +1 -0
- package/dist/core/issues.d.ts +34 -0
- package/dist/core/issues.js +51 -0
- package/dist/core/issues.js.map +1 -0
- package/dist/core/operators.d.ts +189 -0
- package/dist/core/operators.js +60 -0
- package/dist/core/operators.js.map +1 -0
- package/dist/core/options.d.ts +21 -0
- package/dist/core/options.js +21 -0
- package/dist/core/options.js.map +1 -0
- package/dist/core/own-write.d.ts +138 -0
- package/dist/core/own-write.js +133 -0
- package/dist/core/own-write.js.map +1 -0
- package/dist/core/schemas.d.ts +51 -0
- package/dist/core/schemas.js +59 -0
- package/dist/core/schemas.js.map +1 -0
- package/dist/core/serialization/formats.d.ts +7 -7
- package/dist/core/serialization/formats.js +34 -28
- package/dist/core/serialization/formats.js.map +1 -1
- package/dist/core/serialization/grouped.d.ts +9 -12
- package/dist/core/serialization/grouped.js +24 -17
- package/dist/core/serialization/grouped.js.map +1 -1
- package/dist/core/to-error.d.ts +5 -0
- package/dist/core/to-error.js +4 -0
- package/dist/core/to-error.js.map +1 -0
- package/dist/core/types.d.ts +296 -43
- package/dist/core/types.js +39 -108
- package/dist/core/types.js.map +1 -1
- package/dist/core/url-generator.d.ts +4 -4
- package/dist/core/url-generator.js +9 -7
- package/dist/core/url-generator.js.map +1 -1
- package/dist/core/url-parser.d.ts +4 -4
- package/dist/core/url-parser.js +6 -4
- package/dist/core/url-parser.js.map +1 -1
- package/dist/core/validation.d.ts +21 -14
- package/dist/core/validation.js +58 -54
- package/dist/core/validation.js.map +1 -1
- package/dist/core/view-storage.js +21 -19
- package/dist/core/view-storage.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/sync-holder.d.ts +22 -0
- package/dist/react/sync-holder.js +68 -0
- package/dist/react/sync-holder.js.map +1 -0
- package/dist/react/sync-options.d.ts +17 -0
- package/dist/react/sync-options.js +22 -0
- package/dist/react/sync-options.js.map +1 -0
- package/dist/react/types.d.ts +101 -14
- package/dist/react/use-ag-grid-url-sync.d.ts +3 -0
- package/dist/react/use-ag-grid-url-sync.js +344 -499
- package/dist/react/use-ag-grid-url-sync.js.map +1 -1
- package/dist/react/use-grid-url-sync.d.ts +14 -0
- package/dist/react/use-grid-url-sync.js +206 -0
- package/dist/react/use-grid-url-sync.js.map +1 -0
- package/package.json +35 -15
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { GridApi } from 'ag-grid-community';
|
|
2
|
-
import type { AGGridUrlSyncConfig, FilterState, SerializationFormat, SerializationMode } from './types.js';
|
|
2
|
+
import type { AGGridUrlSyncConfig, FilterState, ApplyResult, SerializationFormat, SerializationMode, UrlState } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* AGGridUrlSync class for synchronizing AG Grid text filters with URL parameters
|
|
5
|
+
*
|
|
6
|
+
* @deprecated Use `createGridUrlSync({ api })`: it also listens to the grid
|
|
7
|
+
* and can write the address bar (#221). `AGGridUrlSync` and `createUrlSync`
|
|
8
|
+
* will be removed in 0.6.0.
|
|
5
9
|
*/
|
|
6
10
|
export declare class AGGridUrlSync {
|
|
7
|
-
private
|
|
11
|
+
private readonly gridApi;
|
|
12
|
+
private readonly options;
|
|
8
13
|
/**
|
|
9
14
|
* Creates a new instance of AGGridUrlSync
|
|
10
15
|
* @param gridApi - AG Grid API instance
|
|
@@ -26,10 +31,7 @@ export declare class AGGridUrlSync {
|
|
|
26
31
|
* also keeps the page's own params (#215).
|
|
27
32
|
* @param baseUrl - Optional base URL (defaults to current URL)
|
|
28
33
|
*/
|
|
29
|
-
getUrlState(baseUrl?: string):
|
|
30
|
-
url: string;
|
|
31
|
-
hasFilters: boolean;
|
|
32
|
-
};
|
|
34
|
+
getUrlState(baseUrl?: string): UrlState;
|
|
33
35
|
/**
|
|
34
36
|
* Gets the current filter state as URL query parameters
|
|
35
37
|
* @returns Query parameter string
|
|
@@ -38,17 +40,20 @@ export declare class AGGridUrlSync {
|
|
|
38
40
|
/**
|
|
39
41
|
* Applies filters from a URL to the grid
|
|
40
42
|
* @param url - Optional URL to parse (defaults to current URL)
|
|
43
|
+
* @returns The issues of this call: filters in the URL that were dropped
|
|
41
44
|
*/
|
|
42
|
-
applyFromUrl(url?: string):
|
|
45
|
+
applyFromUrl(url?: string): ApplyResult;
|
|
43
46
|
/**
|
|
44
47
|
* Applies a filter state object to the grid
|
|
45
48
|
* @param filterState - Filter state to apply
|
|
49
|
+
* @returns The issues of this call: filters that were dropped
|
|
46
50
|
*/
|
|
47
|
-
applyFilters(filterState: FilterState):
|
|
51
|
+
applyFilters(filterState: FilterState): ApplyResult;
|
|
48
52
|
/**
|
|
49
53
|
* Clears all text filters from the grid
|
|
54
|
+
* @returns The issues of this call
|
|
50
55
|
*/
|
|
51
|
-
clearFilters():
|
|
56
|
+
clearFilters(): ApplyResult;
|
|
52
57
|
/**
|
|
53
58
|
* Cleans up any resources or event listeners
|
|
54
59
|
*/
|
|
@@ -74,5 +79,7 @@ export declare class AGGridUrlSync {
|
|
|
74
79
|
* @param gridApi - AG Grid API instance
|
|
75
80
|
* @param config - Optional configuration options
|
|
76
81
|
* @returns AGGridUrlSync instance
|
|
82
|
+
* @deprecated Use `createGridUrlSync({ api })` (#221). This function will be
|
|
83
|
+
* removed in 0.6.0.
|
|
77
84
|
*/
|
|
78
85
|
export declare function createUrlSync(gridApi: GridApi, config?: AGGridUrlSyncConfig): AGGridUrlSync;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOptions } from './options.js';
|
|
2
|
+
import { collectIssues } from './issues.js';
|
|
2
3
|
import { parseUrlFilters } from './url-parser.js';
|
|
3
4
|
import { generateUrl } from './url-generator.js';
|
|
4
5
|
import { getFilterModel, applyFilterModel } from './grid-integration.js';
|
|
5
6
|
import { serializeGrouped } from './serialization/grouped.js';
|
|
6
7
|
export class AGGridUrlSync {
|
|
7
|
-
|
|
8
|
+
gridApi;
|
|
9
|
+
options;
|
|
8
10
|
constructor(gridApi, config = {}) {
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
gridApi,
|
|
12
|
-
...DEFAULT_CONFIG,
|
|
13
|
-
...definedConfig
|
|
14
|
-
};
|
|
11
|
+
this.gridApi = gridApi;
|
|
12
|
+
this.options = resolveOptions(config);
|
|
15
13
|
}
|
|
16
14
|
generateUrl(baseUrl) {
|
|
17
15
|
return this.getUrlState(baseUrl).url;
|
|
18
16
|
}
|
|
19
17
|
getUrlState(baseUrl) {
|
|
20
|
-
const
|
|
18
|
+
const { options, issues } = collectIssues(this.options);
|
|
19
|
+
const filterState = getFilterModel(this.gridApi, options);
|
|
21
20
|
const url = baseUrl ?? window.location.href;
|
|
22
21
|
return {
|
|
23
|
-
url: generateUrl(url, filterState,
|
|
24
|
-
hasFilters: Object.keys(filterState).length > 0
|
|
22
|
+
url: generateUrl(url, filterState, options),
|
|
23
|
+
hasFilters: Object.keys(filterState).length > 0,
|
|
24
|
+
issues
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
getQueryParams() {
|
|
@@ -30,28 +30,32 @@ export class AGGridUrlSync {
|
|
|
30
30
|
return urlObj.search;
|
|
31
31
|
}
|
|
32
32
|
applyFromUrl(url) {
|
|
33
|
+
const { options, issues } = collectIssues(this.options);
|
|
33
34
|
const urlToParse = url ?? window.location.href;
|
|
34
|
-
const filterState = parseUrlFilters(urlToParse,
|
|
35
|
-
this.applyFilters(filterState);
|
|
35
|
+
const filterState = parseUrlFilters(urlToParse, options);
|
|
36
|
+
const applied = this.applyFilters(filterState);
|
|
37
|
+
return { issues: [...issues, ...(applied?.issues ?? [])] };
|
|
36
38
|
}
|
|
37
39
|
applyFilters(filterState) {
|
|
38
|
-
|
|
40
|
+
const { options, issues } = collectIssues(this.options);
|
|
41
|
+
applyFilterModel(filterState, this.gridApi, options);
|
|
42
|
+
return { issues };
|
|
39
43
|
}
|
|
40
44
|
clearFilters() {
|
|
41
|
-
this.applyFilters({});
|
|
45
|
+
return this.applyFilters({});
|
|
42
46
|
}
|
|
43
47
|
destroy() {
|
|
44
48
|
}
|
|
45
49
|
getSerializationMode() {
|
|
46
|
-
return this.
|
|
50
|
+
return this.options.serialization;
|
|
47
51
|
}
|
|
48
52
|
getCurrentFormat() {
|
|
49
|
-
return this.
|
|
53
|
+
return this.options.format;
|
|
50
54
|
}
|
|
51
55
|
getFiltersAsFormat(format) {
|
|
52
|
-
const filterState = getFilterModel(this.
|
|
56
|
+
const filterState = getFilterModel(this.gridApi, this.options);
|
|
53
57
|
const tempConfig = {
|
|
54
|
-
...this.
|
|
58
|
+
...this.options,
|
|
55
59
|
format,
|
|
56
60
|
serialization: 'grouped'
|
|
57
61
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ag-grid-url-sync.js","sourceRoot":"","sources":["../../src/core/ag-grid-url-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ag-grid-url-sync.js","sourceRoot":"","sources":["../../src/core/ag-grid-url-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Codec, ResolvedOptions, SerializationFormat } from './types.js';
|
|
2
|
+
/** The options that a codec sets */
|
|
3
|
+
export type CodecOptions = Pick<ResolvedOptions, 'serialization' | 'paramPrefix' | 'groupedParam' | 'format'>;
|
|
4
|
+
/**
|
|
5
|
+
* One URL param for each filter, for example `?f_name_contains=jo`
|
|
6
|
+
* @param options.prefix - The start of each param name. Default `'f_'`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function individual(options?: {
|
|
9
|
+
prefix?: string | undefined;
|
|
10
|
+
}): Codec;
|
|
11
|
+
/**
|
|
12
|
+
* All the filters in one URL param
|
|
13
|
+
* @param options.param - The param name. Default `'grid_filters'`.
|
|
14
|
+
* @param options.format - `'querystring'` (default), `'json'` or `'base64'`
|
|
15
|
+
*/
|
|
16
|
+
export declare function grouped(options?: {
|
|
17
|
+
param?: string | undefined;
|
|
18
|
+
format?: SerializationFormat | undefined;
|
|
19
|
+
}): Codec;
|
|
20
|
+
/** The options of a codec. Throws for an object that no factory made. */
|
|
21
|
+
export declare function codecOptions(codec: Codec): CodecOptions;
|
|
22
|
+
/**
|
|
23
|
+
* A codec with all four settings, for the React hook (#222). Internal: the
|
|
24
|
+
* hook's old options name the params of both modes, and the URL must strip
|
|
25
|
+
* the names that the app set, as the class does. Not exported from the
|
|
26
|
+
* package.
|
|
27
|
+
*/
|
|
28
|
+
export declare function codecFromOptions(options: CodecOptions): Codec;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DEFAULT_CONFIG } from './options.js';
|
|
2
|
+
const settings = new WeakMap();
|
|
3
|
+
function makeCodec(options) {
|
|
4
|
+
const codec = Object.freeze({});
|
|
5
|
+
settings.set(codec, options);
|
|
6
|
+
return codec;
|
|
7
|
+
}
|
|
8
|
+
export function individual(options = {}) {
|
|
9
|
+
return makeCodec({
|
|
10
|
+
serialization: 'individual',
|
|
11
|
+
paramPrefix: options.prefix ?? DEFAULT_CONFIG.paramPrefix,
|
|
12
|
+
groupedParam: DEFAULT_CONFIG.groupedParam,
|
|
13
|
+
format: DEFAULT_CONFIG.format
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export function grouped(options = {}) {
|
|
17
|
+
return makeCodec({
|
|
18
|
+
serialization: 'grouped',
|
|
19
|
+
paramPrefix: DEFAULT_CONFIG.paramPrefix,
|
|
20
|
+
groupedParam: options.param ?? DEFAULT_CONFIG.groupedParam,
|
|
21
|
+
format: options.format ?? DEFAULT_CONFIG.format
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function codecOptions(codec) {
|
|
25
|
+
const options = settings.get(codec);
|
|
26
|
+
if (!options) {
|
|
27
|
+
throw new TypeError('codec must come from individual() or grouped()');
|
|
28
|
+
}
|
|
29
|
+
return options;
|
|
30
|
+
}
|
|
31
|
+
export function codecFromOptions(options) {
|
|
32
|
+
return makeCodec({
|
|
33
|
+
serialization: options.serialization,
|
|
34
|
+
paramPrefix: options.paramPrefix,
|
|
35
|
+
groupedParam: options.groupedParam,
|
|
36
|
+
format: options.format
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=codecs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../src/core/codecs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAY7C,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAuB,CAAA;AAEnD,SAAS,SAAS,CAAC,OAAqB;IAGtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAU,CAAA;IACxC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAE5B,OAAO,KAAK,CAAA;AACd,CAAC;AAMD,MAAM,UAAU,UAAU,CACxB,OAAO,GAAoC,EAAE;IAE7C,OAAO,SAAS,CAAC;QACf,aAAa,EAAE,YAAY;QAC3B,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,WAAW;QACzD,YAAY,EAAE,cAAc,CAAC,YAAY;QACzC,MAAM,EAAE,cAAc,CAAC,MAAM;KAC9B,CAAC,CAAA;AACJ,CAAC;AAOD,MAAM,UAAU,OAAO,CACrB,OAAO,GAGH,EAAE;IAEN,OAAO,SAAS,CAAC;QACf,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,cAAc,CAAC,WAAW;QACvC,YAAY,EAAE,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,YAAY;QAC1D,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM;KAChD,CAAC,CAAA;AACJ,CAAC;AAGD,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAA;IACvE,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAQD,MAAM,UAAU,gBAAgB,CAAC,OAAqB;IACpD,OAAO,SAAS,CAAC;QACf,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-issue-codes.js","sourceRoot":"","sources":["../../src/core/data-issue-codes.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,gBAAgB,GAA2B,IAAI,GAAG,CAAY;IACzE,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,aAAa;CACd,CAAC,CAAA"}
|
|
@@ -1,14 +1,50 @@
|
|
|
1
|
-
import type { FilterState, InternalConfig } from './types.js';
|
|
2
|
-
import type { GridApi } from 'ag-grid-community';
|
|
1
|
+
import type { AGGridUrlSyncConfig, FilterState, InternalConfig } from './types.js';
|
|
2
|
+
import type { FilterModel, GridApi } from 'ag-grid-community';
|
|
3
3
|
/**
|
|
4
4
|
* Detects the expected filter type for a column based on AG Grid configuration
|
|
5
5
|
*/
|
|
6
6
|
export declare function detectColumnFilterType(gridApi: GridApi, columnId: string): 'text' | 'number' | 'date';
|
|
7
|
+
/**
|
|
8
|
+
* Gets the current filter model from AG Grid as a filter state. Filter types
|
|
9
|
+
* that the library does not support are skipped, and a filter that is not
|
|
10
|
+
* valid is reported through `options.onParseError`.
|
|
11
|
+
*
|
|
12
|
+
* @param gridApi - AG Grid API instance
|
|
13
|
+
* @param options - Optional options. Only `onParseError` is read.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getFilterModel(gridApi: GridApi, options?: AGGridUrlSyncConfig): FilterState;
|
|
7
16
|
/**
|
|
8
17
|
* Gets the current filter model from AG Grid
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Give the grid API as an argument:
|
|
20
|
+
* `getFilterModel(gridApi, options)`. This form will be removed in 0.6.0.
|
|
9
21
|
*/
|
|
10
22
|
export declare function getFilterModel(config: InternalConfig): FilterState;
|
|
23
|
+
/**
|
|
24
|
+
* Converts an AG Grid filter model to URL filters. It does not call the grid.
|
|
25
|
+
* Filter types that the library does not support (set, multi) are skipped.
|
|
26
|
+
*/
|
|
27
|
+
export declare function fromGridModel(model: FilterModel | null | undefined, options?: AGGridUrlSyncConfig): FilterState;
|
|
28
|
+
/**
|
|
29
|
+
* Applies a filter state to AG Grid. A filter whose type does not match the
|
|
30
|
+
* column is skipped with a warning. An error from the grid is reported
|
|
31
|
+
* through `options.onParseError`.
|
|
32
|
+
*
|
|
33
|
+
* @param filterState - Filter state to apply
|
|
34
|
+
* @param gridApi - AG Grid API instance
|
|
35
|
+
* @param options - Optional options. Only `onParseError` is read.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyFilterModel(filterState: FilterState, gridApi: GridApi, options?: AGGridUrlSyncConfig): void;
|
|
11
38
|
/**
|
|
12
39
|
* Applies a filter state to AG Grid
|
|
40
|
+
*
|
|
41
|
+
* @deprecated Give the grid API as an argument:
|
|
42
|
+
* `applyFilterModel(filterState, gridApi, options)`. This form will be
|
|
43
|
+
* removed in 0.6.0.
|
|
13
44
|
*/
|
|
14
45
|
export declare function applyFilterModel(filterState: FilterState, config: InternalConfig): void;
|
|
46
|
+
/**
|
|
47
|
+
* Converts URL filters to the AG Grid filter model that `applyFilterModel`
|
|
48
|
+
* would write. It does not call `setFilterModel`.
|
|
49
|
+
*/
|
|
50
|
+
export declare function toGridModel(filterState: FilterState, gridApi: GridApi, options?: AGGridUrlSyncConfig): FilterModel;
|
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { InvalidFilterError, NUMBER_FILTER_OPERATIONS, isDateFilterOperation, isNumberFilterOperation, isTextFilterOperation } from './types.js';
|
|
3
|
+
import { operatorById, operatorFromAgGrid } from './operators.js';
|
|
4
|
+
import { AgGridFilterSchema, JsonObjectSchema } from './schemas.js';
|
|
5
|
+
import { reportIssue, toIssue } from './issues.js';
|
|
6
|
+
import { readNumber } from './validation.js';
|
|
7
|
+
import { resolveOptions } from './options.js';
|
|
8
|
+
function toAgGridOperation(operation) {
|
|
9
|
+
return operatorById(operation)?.agGrid ?? null;
|
|
10
|
+
}
|
|
11
|
+
function hasGridValue(value) {
|
|
12
|
+
return value !== undefined && value !== null && String(value).trim() !== '';
|
|
13
|
+
}
|
|
14
|
+
function gridNumber(value, column) {
|
|
15
|
+
if (!v.is(v.string(), value))
|
|
16
|
+
return Number(value);
|
|
17
|
+
const number = readNumber(value);
|
|
18
|
+
return number instanceof InvalidFilterError
|
|
19
|
+
? new InvalidFilterError(`${number.message} (column '${column}')`, undefined, {
|
|
20
|
+
code: 'INVALID_NUMBER',
|
|
21
|
+
column
|
|
22
|
+
})
|
|
23
|
+
: number;
|
|
15
24
|
}
|
|
16
25
|
function toIsoDateString(val) {
|
|
17
26
|
if (!val)
|
|
@@ -19,15 +28,6 @@ function toIsoDateString(val) {
|
|
|
19
28
|
const match = val.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
20
29
|
return match?.[1] ? match[1] : val || '';
|
|
21
30
|
}
|
|
22
|
-
function isTextFilterOperation(operation) {
|
|
23
|
-
return TEXT_FILTER_OPERATIONS.includes(operation);
|
|
24
|
-
}
|
|
25
|
-
function isNumberFilterOperation(operation) {
|
|
26
|
-
return NUMBER_FILTER_OPERATIONS.includes(operation);
|
|
27
|
-
}
|
|
28
|
-
function isDateFilterOperation(operation) {
|
|
29
|
-
return DATE_FILTER_OPERATIONS.includes(operation);
|
|
30
|
-
}
|
|
31
31
|
export function detectColumnFilterType(gridApi, columnId) {
|
|
32
32
|
try {
|
|
33
33
|
const column = gridApi.getColumn(columnId);
|
|
@@ -52,90 +52,126 @@ export function detectColumnFilterType(gridApi, columnId) {
|
|
|
52
52
|
return 'text';
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
export function getFilterModel(
|
|
55
|
+
export function getFilterModel(source, options) {
|
|
56
|
+
if ('gridApi' in source) {
|
|
57
|
+
return readGridFilters(source.gridApi, resolveOptions(source));
|
|
58
|
+
}
|
|
59
|
+
return readGridFilters(source, resolveOptions(options));
|
|
60
|
+
}
|
|
61
|
+
function readGridFilters(gridApi, options) {
|
|
62
|
+
let model;
|
|
56
63
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
model = gridApi.getFilterModel();
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
reportIssue(options, toIssue(error, 'GRID_ERROR'));
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
return fromGridModel(model, options);
|
|
71
|
+
}
|
|
72
|
+
export function fromGridModel(model, options) {
|
|
73
|
+
const resolved = resolveOptions(options);
|
|
74
|
+
const filters = new Map();
|
|
75
|
+
if (!v.is(JsonObjectSchema, model)) {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
for (const [column, entry] of Object.entries(model)) {
|
|
79
|
+
const parsed = v.safeParse(AgGridFilterSchema, entry);
|
|
80
|
+
if (!parsed.success)
|
|
81
|
+
continue;
|
|
82
|
+
const filter = parsed.output;
|
|
83
|
+
if (filter.filterType === 'text') {
|
|
84
|
+
const operator = operatorFromAgGrid('text', filter.type);
|
|
85
|
+
if (operator && isTextFilterOperation(operator.id)) {
|
|
86
|
+
filters.set(column, {
|
|
87
|
+
filterType: 'text',
|
|
88
|
+
type: operator.id,
|
|
89
|
+
filter: String(filter.filter || '')
|
|
90
|
+
});
|
|
91
|
+
}
|
|
61
92
|
}
|
|
62
|
-
|
|
63
|
-
|
|
93
|
+
else if (filter.filterType === 'number') {
|
|
94
|
+
const operator = operatorFromAgGrid('number', filter.type);
|
|
95
|
+
const internalOperation = operator?.id;
|
|
96
|
+
if (!operator ||
|
|
97
|
+
!internalOperation ||
|
|
98
|
+
!isNumberFilterOperation(internalOperation)) {
|
|
99
|
+
reportIssue(resolved, new InvalidFilterError(`Unknown number filter operation '${filter.type}' for column '${column}'. ` +
|
|
100
|
+
`Supported operations: ${NUMBER_FILTER_OPERATIONS.map(toAgGridOperation).join(', ')}`, undefined, { code: 'INVALID_PARAM', column }));
|
|
64
101
|
continue;
|
|
65
|
-
const { filterType, type, filter: value, filterTo, dateFrom, dateTo } = filter;
|
|
66
|
-
if (filterType === 'text') {
|
|
67
|
-
const internalOperation = REVERSE_AG_GRID_OPERATION_NAMES[type];
|
|
68
|
-
if (internalOperation && isTextFilterOperation(internalOperation)) {
|
|
69
|
-
filterState[column] = {
|
|
70
|
-
filterType: 'text',
|
|
71
|
-
type: internalOperation,
|
|
72
|
-
filter: String(value || '')
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
102
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
if (operator.arity === 0) {
|
|
104
|
+
filters.set(column, {
|
|
105
|
+
filterType: 'number',
|
|
106
|
+
type: internalOperation,
|
|
107
|
+
filter: 0
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (!hasGridValue(filter.filter) ||
|
|
112
|
+
(operator.arity === 2 && !hasGridValue(filter.filterTo))) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const numericValue = gridNumber(filter.filter, column);
|
|
116
|
+
const numericTo = operator.arity === 2 && hasGridValue(filter.filterTo)
|
|
117
|
+
? gridNumber(filter.filterTo, column)
|
|
118
|
+
: undefined;
|
|
119
|
+
if (numericValue instanceof InvalidFilterError) {
|
|
120
|
+
reportIssue(resolved, numericValue);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (numericTo instanceof InvalidFilterError) {
|
|
124
|
+
reportIssue(resolved, numericTo);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (isNaN(numericValue)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
filters.set(column, internalOperation === 'inRange' && numericTo !== undefined
|
|
131
|
+
? {
|
|
132
|
+
filterType: 'number',
|
|
133
|
+
type: internalOperation,
|
|
134
|
+
filter: numericValue,
|
|
135
|
+
filterTo: numericTo
|
|
86
136
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
137
|
+
: {
|
|
138
|
+
filterType: 'number',
|
|
139
|
+
type: internalOperation,
|
|
140
|
+
filter: numericValue
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const operator = operatorFromAgGrid('date', filter.type);
|
|
145
|
+
const mappedOperation = operator?.id;
|
|
146
|
+
if (operator &&
|
|
147
|
+
mappedOperation &&
|
|
148
|
+
isDateFilterOperation(mappedOperation)) {
|
|
149
|
+
if (operator.arity === 0) {
|
|
150
|
+
filters.set(column, {
|
|
151
|
+
filterType: 'date',
|
|
152
|
+
type: mappedOperation,
|
|
153
|
+
filter: ''
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
102
156
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
greaterThanOrEqual: 'dateAfterOrEqual',
|
|
112
|
-
inRange: 'dateRange'
|
|
113
|
-
};
|
|
114
|
-
mappedOperation = type
|
|
115
|
-
? AG_GRID_TO_DATE_OPERATION_MAP[type] || internalOperation
|
|
116
|
-
: internalOperation;
|
|
117
|
-
if (mappedOperation && isDateFilterOperation(mappedOperation)) {
|
|
118
|
-
const dateFilter = {
|
|
157
|
+
const from = toIsoDateString(filter.dateFrom || String(filter.filter || ''));
|
|
158
|
+
const to = operator.arity === 2
|
|
159
|
+
? toIsoDateString(filter.dateTo ?? undefined)
|
|
160
|
+
: '';
|
|
161
|
+
if (!from || (operator.arity === 2 && !to))
|
|
162
|
+
continue;
|
|
163
|
+
filters.set(column, operator.arity === 2
|
|
164
|
+
? {
|
|
119
165
|
filterType: 'date',
|
|
120
166
|
type: mappedOperation,
|
|
121
|
-
filter:
|
|
122
|
-
|
|
123
|
-
if (mappedOperation === 'dateRange' && dateTo) {
|
|
124
|
-
;
|
|
125
|
-
dateFilter.filterTo = toIsoDateString(dateTo);
|
|
167
|
+
filter: from,
|
|
168
|
+
filterTo: to
|
|
126
169
|
}
|
|
127
|
-
|
|
128
|
-
}
|
|
170
|
+
: { filterType: 'date', type: mappedOperation, filter: from });
|
|
129
171
|
}
|
|
130
172
|
}
|
|
131
|
-
return filterState;
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
if (config.onParseError) {
|
|
135
|
-
config.onParseError(error);
|
|
136
|
-
}
|
|
137
|
-
return {};
|
|
138
173
|
}
|
|
174
|
+
return Object.fromEntries(filters);
|
|
139
175
|
}
|
|
140
176
|
function convertToAGGridFilter(filter) {
|
|
141
177
|
if (filter.filterType === 'date') {
|
|
@@ -155,23 +191,18 @@ function convertToAGGridFilter(filter) {
|
|
|
155
191
|
dateTo: null
|
|
156
192
|
};
|
|
157
193
|
}
|
|
158
|
-
const dateOperationMapping = {
|
|
159
|
-
dateBefore: 'lessThan',
|
|
160
|
-
dateBeforeOrEqual: 'lessThanOrEqual',
|
|
161
|
-
dateAfter: 'greaterThan',
|
|
162
|
-
dateAfterOrEqual: 'greaterThanOrEqual'
|
|
163
|
-
};
|
|
164
|
-
const agOperation = dateOperationMapping[filter.type] ||
|
|
165
|
-
AG_GRID_OPERATION_NAMES[filter.type];
|
|
166
194
|
return {
|
|
167
195
|
filterType: 'date',
|
|
168
|
-
type:
|
|
196
|
+
type: toAgGridOperation(filter.type),
|
|
169
197
|
dateFrom: filter.filter,
|
|
170
198
|
dateTo: null
|
|
171
199
|
};
|
|
172
200
|
}
|
|
173
201
|
if (filter.filterType === 'number') {
|
|
174
|
-
const agGridOperation =
|
|
202
|
+
const agGridOperation = toAgGridOperation(filter.type);
|
|
203
|
+
if (filter.type === 'blank' || filter.type === 'notBlank') {
|
|
204
|
+
return { filterType: 'number', type: agGridOperation, filter: null };
|
|
205
|
+
}
|
|
175
206
|
if (filter.type === 'inRange') {
|
|
176
207
|
const baseFilter = {
|
|
177
208
|
filterType: 'number',
|
|
@@ -188,39 +219,49 @@ function convertToAGGridFilter(filter) {
|
|
|
188
219
|
filter: filter.filter
|
|
189
220
|
};
|
|
190
221
|
}
|
|
191
|
-
const agGridOperation =
|
|
222
|
+
const agGridOperation = toAgGridOperation(filter.type);
|
|
192
223
|
return {
|
|
193
224
|
filterType: 'text',
|
|
194
225
|
type: agGridOperation,
|
|
195
226
|
filter: filter.filter
|
|
196
227
|
};
|
|
197
228
|
}
|
|
198
|
-
export function applyFilterModel(filterState,
|
|
229
|
+
export function applyFilterModel(filterState, target, options) {
|
|
230
|
+
if ('gridApi' in target) {
|
|
231
|
+
writeGridFilters(filterState, target.gridApi, resolveOptions(target));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
writeGridFilters(filterState, target, resolveOptions(options));
|
|
235
|
+
}
|
|
236
|
+
function writeGridFilters(filterState, gridApi, options) {
|
|
237
|
+
const model = toGridModel(filterState, gridApi, options);
|
|
199
238
|
try {
|
|
200
|
-
|
|
201
|
-
for (const [column, filter] of Object.entries(filterState)) {
|
|
202
|
-
if (!filter || typeof filter !== 'object')
|
|
203
|
-
continue;
|
|
204
|
-
const expectedType = detectColumnFilterType(config.gridApi, column);
|
|
205
|
-
if (filter.filterType === 'date' && expectedType !== 'date') {
|
|
206
|
-
console.warn(`Column '${column}' expects a ${expectedType} filter but received a date filter. This may indicate a configuration mismatch in the column definition or filter application.`);
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
if (filter.filterType === 'number' && expectedType !== 'number') {
|
|
210
|
-
console.warn(`Column '${column}' expects a ${expectedType} filter but received a number filter. This may indicate a configuration mismatch in the column definition or filter application.`);
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
const agGridFilter = convertToAGGridFilter(filter);
|
|
214
|
-
if (agGridFilter) {
|
|
215
|
-
model[column] = agGridFilter;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
config.gridApi.setFilterModel(model);
|
|
239
|
+
gridApi.setFilterModel(model);
|
|
219
240
|
}
|
|
220
241
|
catch (error) {
|
|
221
|
-
|
|
222
|
-
|
|
242
|
+
reportIssue(options, toIssue(error, 'GRID_ERROR'));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
export function toGridModel(filterState, gridApi, options) {
|
|
246
|
+
const resolved = resolveOptions(options);
|
|
247
|
+
const model = new Map();
|
|
248
|
+
for (const [column, filter] of Object.entries(filterState)) {
|
|
249
|
+
if (!v.is(JsonObjectSchema, filter))
|
|
250
|
+
continue;
|
|
251
|
+
const expectedType = detectColumnFilterType(gridApi, column);
|
|
252
|
+
if (filter.filterType === 'date' && expectedType !== 'date') {
|
|
253
|
+
reportIssue(resolved, new InvalidFilterError(`Column '${column}' expects a ${expectedType} filter but received a date filter. This may indicate a configuration mismatch in the column definition or filter application.`, undefined, { code: 'TYPE_MISMATCH', column }));
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (filter.filterType === 'number' && expectedType !== 'number') {
|
|
257
|
+
reportIssue(resolved, new InvalidFilterError(`Column '${column}' expects a ${expectedType} filter but received a number filter. This may indicate a configuration mismatch in the column definition or filter application.`, undefined, { code: 'TYPE_MISMATCH', column }));
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const agGridFilter = convertToAGGridFilter(filter);
|
|
261
|
+
if (agGridFilter) {
|
|
262
|
+
model.set(column, agGridFilter);
|
|
223
263
|
}
|
|
224
264
|
}
|
|
265
|
+
return Object.fromEntries(model);
|
|
225
266
|
}
|
|
226
267
|
//# sourceMappingURL=grid-integration.js.map
|