ag-grid-url-sync 0.4.1 → 0.5.1

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.
Files changed (58) hide show
  1. package/README.md +143 -50
  2. package/dist/core/ag-grid-url-sync.d.ts +19 -5
  3. package/dist/core/ag-grid-url-sync.js +28 -17
  4. package/dist/core/ag-grid-url-sync.js.map +1 -1
  5. package/dist/core/grid-integration.d.ts +27 -1
  6. package/dist/core/grid-integration.js +161 -129
  7. package/dist/core/grid-integration.js.map +1 -1
  8. package/dist/core/index.d.ts +2 -1
  9. package/dist/core/index.js +2 -1
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/individual-params.d.ts +26 -0
  12. package/dist/core/individual-params.js +236 -0
  13. package/dist/core/individual-params.js.map +1 -0
  14. package/dist/core/issue-columns.d.ts +2 -0
  15. package/dist/core/issue-columns.js +11 -0
  16. package/dist/core/issue-columns.js.map +1 -0
  17. package/dist/core/issues.d.ts +34 -0
  18. package/dist/core/issues.js +58 -0
  19. package/dist/core/issues.js.map +1 -0
  20. package/dist/core/operators.d.ts +189 -0
  21. package/dist/core/operators.js +60 -0
  22. package/dist/core/operators.js.map +1 -0
  23. package/dist/core/options.d.ts +21 -0
  24. package/dist/core/options.js +21 -0
  25. package/dist/core/options.js.map +1 -0
  26. package/dist/core/schemas.d.ts +51 -0
  27. package/dist/core/schemas.js +59 -0
  28. package/dist/core/schemas.js.map +1 -0
  29. package/dist/core/serialization/formats.d.ts +8 -9
  30. package/dist/core/serialization/formats.js +70 -47
  31. package/dist/core/serialization/formats.js.map +1 -1
  32. package/dist/core/serialization/grouped.d.ts +13 -11
  33. package/dist/core/serialization/grouped.js +24 -17
  34. package/dist/core/serialization/grouped.js.map +1 -1
  35. package/dist/core/to-error.d.ts +5 -0
  36. package/dist/core/to-error.js +4 -0
  37. package/dist/core/to-error.js.map +1 -0
  38. package/dist/core/types.d.ts +172 -33
  39. package/dist/core/types.js +35 -108
  40. package/dist/core/types.js.map +1 -1
  41. package/dist/core/url-generator.d.ts +10 -7
  42. package/dist/core/url-generator.js +29 -121
  43. package/dist/core/url-generator.js.map +1 -1
  44. package/dist/core/url-parser.d.ts +19 -7
  45. package/dist/core/url-parser.js +31 -239
  46. package/dist/core/url-parser.js.map +1 -1
  47. package/dist/core/validation.d.ts +21 -14
  48. package/dist/core/validation.js +58 -54
  49. package/dist/core/validation.js.map +1 -1
  50. package/dist/core/view-storage.js +21 -19
  51. package/dist/core/view-storage.js.map +1 -1
  52. package/dist/index.d.ts +2 -1
  53. package/dist/index.js +2 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/react/types.d.ts +36 -11
  56. package/dist/react/use-ag-grid-url-sync.js +151 -97
  57. package/dist/react/use-ag-grid-url-sync.js.map +1 -1
  58. package/package.json +35 -16
package/README.md CHANGED
@@ -195,38 +195,56 @@ import type {
195
195
 
196
196
  ```typescript
197
197
  import { parseUrlFilters } from 'ag-grid-url-sync/url-parser'
198
- import { DEFAULT_CONFIG } from 'ag-grid-url-sync/validation'
199
198
  import type { FilterState } from 'ag-grid-url-sync/types'
200
199
 
201
200
  function getFiltersFromUrl(url: string): FilterState {
202
- const config = {
203
- gridApi: null, // Not needed for parsing
204
- ...DEFAULT_CONFIG,
201
+ // Options that you leave out get their defaults. No grid is needed.
202
+ return parseUrlFilters(url, {
205
203
  onParseError: error => console.error('Parse error:', error)
206
- }
207
-
208
- return parseUrlFilters(url, config)
204
+ })
209
205
  }
210
206
  ```
211
207
 
208
+ `parseUrlFilters` reads the input with these rules, in this order:
209
+
210
+ | # | Input | Result | Example |
211
+ | --- | --------------------------- | ------------------------ | ----------------------------------------- |
212
+ | 1 | A host with no scheme | Throws `InvalidURLError` | `example.com?…`, `localhost:3000?…` |
213
+ | 2 | Starts with a scheme | Absolute URL | `https://example.com/users?f_name_eq=bob` |
214
+ | 3 | Starts with `/`, `?` or `#` | Relative URL | `/users?f_name_eq=bob`, `?f_name_eq=bob` |
215
+ | 4 | Anything else | Raw query string | `f_name_eq=bob` |
216
+
217
+ - A relative path must start with `/`. `users?f_name_eq=bob` matches rule 4, so it gives no filters.
218
+ - A bare `localhost?…` with no port cannot be told apart from a raw query, so it matches rule 4.
219
+ - In a raw query string, a `?` or `#` is part of a param name or value.
220
+
221
+ `InvalidURLError` is thrown for rule 1, and for any input that the `URL` constructor rejects under rules 2 and 3 (for example `http://` or `//[`). A param that is not valid is skipped and sent to `onParseError`.
222
+
212
223
  #### Example: Custom URL Generator
213
224
 
214
225
  ```typescript
215
- import { generateUrl, serializeFilters } from 'ag-grid-url-sync/url-generator'
226
+ import { generateUrl } from 'ag-grid-url-sync/url-generator'
216
227
  import type { FilterState } from 'ag-grid-url-sync/types'
217
228
 
218
229
  function createShareableUrl(filters: FilterState, baseUrl: string): string {
219
- const config = {
220
- gridApi: null, // Not needed for generation
221
- paramPrefix: 'f_',
222
- maxValueLength: 200,
223
- onParseError: () => {}
224
- }
225
-
226
- return generateUrl(baseUrl, filters, config)
230
+ return generateUrl(baseUrl, filters, { maxValueLength: 500 })
227
231
  }
228
232
  ```
229
233
 
234
+ #### Example: Read and Write the Grid Filters
235
+
236
+ ```typescript
237
+ import {
238
+ getFilterModel,
239
+ applyFilterModel
240
+ } from 'ag-grid-url-sync/grid-integration'
241
+
242
+ const filters = getFilterModel(gridApi, { onParseError: console.warn })
243
+ applyFilterModel(filters, otherGridApi)
244
+ ```
245
+
246
+ The config form (`getFilterModel({ ...DEFAULT_CONFIG, gridApi })`) still works, but it is deprecated.
247
+
230
248
  **💡 Pro Tip**: Use granular imports in libraries and applications where bundle size matters. All existing import patterns remain fully supported for backward compatibility.
231
249
 
232
250
  ### Basic Example
@@ -300,6 +318,10 @@ interface AGGridUrlSyncConfig {
300
318
  }
301
319
  ```
302
320
 
321
+ When the library reads a URL, it reads only the `groupedParam` name and decodes it with the configured `format`. It does not guess the format. This works in both modes, so a grouped link opens in an app in individual mode when the name and format match. If the param is present and not empty, the prefixed params are not read.
322
+
323
+ > **Note:** A URL written with a different `groupedParam` or `format` does not decode. If you change either option, links that were shared before the change stop working.
324
+
303
325
  ### Format Options
304
326
 
305
327
  #### QueryString Format (Default)
@@ -418,28 +440,82 @@ import {
418
440
 
419
441
  ---
420
442
 
421
- ### Error Handling for Grouped Serialization
443
+ ### Error Handling
422
444
 
423
- You can provide a custom error handler to gracefully handle malformed grouped parameters or serialization errors. The library will throw an `InvalidSerializationError` for invalid formats:
445
+ The library never writes to the console. Each problem goes to one callback, and each error that the library makes has a `code` that you can switch on:
446
+
447
+ | Code | Meaning | Callback |
448
+ | ------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
449
+ | `INVALID_PARAM` | A param name that is not valid, or an unknown operation | `onParseError` |
450
+ | `INVALID_NUMBER` | A value that is not a number, or that would be rounded | `onParseError` |
451
+ | `INVALID_DATE` | A date that does not exist, or a date range in the wrong order | `onParseError` |
452
+ | `VALUE_TOO_LONG` | A text value over `maxValueLength` | `onParseError` |
453
+ | `INVALID_GROUPED` | A grouped value that does not decode (bad JSON or base64) | `onParseError` |
454
+ | `TYPE_MISMATCH` | A number or date filter on a column of another type | `onParseError` |
455
+ | `INVALID_URL` | A URL that the parser cannot read | Thrown by `parseUrlFilters` and `applyFromUrl`. The React hook catches it and sends it to `onParseError` |
456
+ | `GRID_ERROR` | The AG Grid API threw | `onParseError` in the core, `onError` in the React hook |
457
+ | `NOT_READY` | A hook operation called before the grid is ready | `onError` (React) |
458
+ | `VIEW_NOT_FOUND`, `VIEW_NAME_REQUIRED` | A saved view operation that cannot run | `onError` (React) |
459
+ | `STORAGE_UNAVAILABLE`, `STORAGE_FULL`, `STORAGE_WRITE_FAILED` | Browser storage for saved views failed | `onError` (React) |
460
+
461
+ The codes in the first seven rows are data issues: a filter that is dropped or is not valid. The library skips that filter and keeps the others. When the library knows the column, it is in `error.column`. `onParseError` is typed with `Error`, so check `instanceof URLSyncError` before you read `code` or `column`.
462
+
463
+ Every error is a `URLSyncError`. The classes from earlier versions (`InvalidFilterError`, `InvalidDateError`, `InvalidURLError`, `InvalidSerializationError`) are subclasses of it, so an `instanceof` check still works.
424
464
 
425
465
  ```typescript
426
- import { InvalidSerializationError } from 'ag-grid-url-sync/types'
466
+ import { createUrlSync, URLSyncError } from 'ag-grid-url-sync'
427
467
 
428
468
  const urlSync = createUrlSync(gridApi, {
429
- serialization: 'grouped',
430
- format: 'json',
431
469
  onParseError: error => {
432
- if (error instanceof InvalidSerializationError) {
433
- // Handle grouped serialization error
434
- alert('Invalid filter data in URL!')
435
- } else {
436
- // Handle other errors
437
- console.error(error)
470
+ if (error instanceof URLSyncError && error.code === 'VALUE_TOO_LONG') {
471
+ showToast(`The link leaves out the filter on ${error.column}`)
438
472
  }
439
473
  }
440
474
  })
441
475
  ```
442
476
 
477
+ In grouped mode, an error that comes from the grouped URL value is an `InvalidSerializationError`, and the original error is in `error.cause`. When the original error is an issue with one filter (for example a value over `maxValueLength`), the wrapper has the same `code` and `column`. So a check on `error.code` works the same in both modes. `INVALID_GROUPED` means that the grouped value itself does not decode.
478
+
479
+ In every grouped format (`querystring`, `json`, `base64`), a text value over `maxValueLength` (default 200) is dropped and reported through `onParseError`, both when the URL is generated and when it is parsed.
480
+
481
+ #### Dropped Filters in the Result
482
+
483
+ A caller does not need a callback to see dropped filters. `getUrlState()` and the apply methods return the issues of each call. They are the same objects that `onParseError` gets.
484
+
485
+ ```typescript
486
+ const { url, hasFilters, issues } = urlSync.getUrlState()
487
+
488
+ if (issues.length > 0) {
489
+ // The link leaves out these filters, so the recipient sees other rows
490
+ showToast(`The link leaves out ${issues.length} filter(s)`)
491
+ }
492
+
493
+ const { issues: urlIssues } = urlSync.applyFromUrl()
494
+ ```
495
+
496
+ In React, the hook returns `issues`: the issues of the latest URL apply (`applyUrlFilters`, `applyFilters`, auto-apply), followed by the issues of the latest URL write. The apply issues stay until the next apply, `clearFilters` or `loadView`. Operation failures (`onError`) are not in the list:
497
+
498
+ ```tsx
499
+ const { shareUrl, issues } = useAGGridUrlSync(gridApi)
500
+
501
+ return issues.length > 0 ? (
502
+ <Warning>The link leaves out a filter</Warning>
503
+ ) : null
504
+ ```
505
+
506
+ #### `throwOnError`
507
+
508
+ Like TanStack Query, the library can throw an issue instead of reporting it. Set `throwOnError: true` to throw every issue, or give a function that picks issues. In the core, a thrown issue does not go to `onParseError`, and the first one stops the call. In React, the hook keeps reporting each issue to `onParseError` one time, and then throws the picked issue during render, so an error boundary catches it. The default is `false`.
509
+
510
+ The library does not change the address bar. Before an error boundary resets, remove the bad param from the URL (or the filter from the grid), or the same issue is thrown again.
511
+
512
+ ```tsx
513
+ useAGGridUrlSync(gridApi, {
514
+ // Throw only when a link would leave out a filter
515
+ throwOnError: issue => issue.code === 'VALUE_TOO_LONG'
516
+ })
517
+ ```
518
+
443
519
  ### Exports
444
520
 
445
521
  The package supports granular subpath exports for advanced usage and optimal bundle size:
@@ -558,6 +634,7 @@ const {
558
634
  isReady,
559
635
  currentUrl,
560
636
  hasFilters,
637
+ issues,
561
638
  parseUrlFilters,
562
639
  applyFilters,
563
640
  getFiltersAsFormat,
@@ -573,11 +650,12 @@ interface UseAGGridUrlSyncOptions {
573
650
  paramPrefix?: string // Default: 'f_'
574
651
  maxValueLength?: number // Default: 200
575
652
  onParseError?: (error: Error) => void
653
+ throwOnError?: boolean | ((issue: URLSyncError) => boolean) // Default: false
576
654
 
577
655
  // React-specific options
578
656
  autoApplyOnMount?: boolean // Default: false
579
657
  enabledWhenReady?: boolean // Default: true
580
- onError?: (error: Error, context: string) => void // Advanced error handling
658
+ onError?: (error: Error, context: string) => void // Operation failures (see Error Handling)
581
659
 
582
660
  // Saved views: setting a key enables the feature and namespaces its storage
583
661
  storageKey?: string // Default: undefined (saved views disabled)
@@ -586,19 +664,20 @@ interface UseAGGridUrlSyncOptions {
586
664
 
587
665
  #### Hook Return Values
588
666
 
589
- | Property | Type | Description |
590
- | -------------------- | -------------------------------- | ----------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- |
591
- | `shareUrl` | `(baseUrl?: string) => string` | Generate shareable URL with current filters |
592
- | `getQueryParams` | `() => string` | Get filter state as query parameters |
593
- | `applyUrlFilters` | `(url?: string) => void` | Apply filters from URL to grid |
594
- | `clearFilters` | `() => void` | Clear all text filters |
595
- | `isReady` | `boolean` | Whether grid API is available and hook is ready |
596
- | `currentUrl` | `string` | Current URL with filters applied |
597
- | `hasFilters` | `boolean` | Whether grid has any active text filters |
598
- | `parseUrlFilters` | `(url: string) => FilterState` | Parse filters from URL without applying |
599
- | `applyFilters` | `(filters: FilterState) => void` | Apply filter state object to grid |
600
- | `getFiltersAsFormat` | `(format: 'querystring' | 'json' | 'base64') => string` | Serialize filters to any supported format (for sharing/export) |
601
- | `getCurrentFormat` | `() => 'individual' | 'grouped'` | Get the current serialization mode (individual or grouped) |
667
+ | Property | Type | Description |
668
+ | -------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------- |
669
+ | `shareUrl` | `(baseUrl?: string) => string` | Generate shareable URL with current filters |
670
+ | `getQueryParams` | `() => string` | Get filter state as query parameters |
671
+ | `applyUrlFilters` | `(url?: string) => void` | Apply filters from URL to grid |
672
+ | `clearFilters` | `() => void` | Clear all text filters |
673
+ | `isReady` | `boolean` | Whether grid API is available and hook is ready |
674
+ | `currentUrl` | `string` | Current URL with filters applied |
675
+ | `hasFilters` | `boolean` | Whether the grid has supported filters |
676
+ | `issues` | `readonly URLSyncError[]` | Filters that the latest URL apply or URL write dropped (see Error Handling) |
677
+ | `parseUrlFilters` | `(url: string) => FilterState` | Parse filters from URL without applying |
678
+ | `applyFilters` | `(filters: FilterState) => void` | Apply filter state object to grid |
679
+ | `getFiltersAsFormat` | `(format: 'querystring' \| 'json' \| 'base64') => string` | Serialize filters to any supported format (for sharing/export) |
680
+ | `getCurrentFormat` | `() => 'individual' \| 'grouped'` | Get the current serialization mode (individual or grouped) |
602
681
 
603
682
  Saved views (inert unless `storageKey` is set):
604
683
 
@@ -692,8 +771,9 @@ store.saveView('Engineering', gridApi.getFilterModel())
692
771
  - **🔄 Automatic State Management**: Tracks grid state and filter changes automatically
693
772
  - **⚡ Ready State**: `isReady` indicates when the grid API is available
694
773
  - **🎯 Auto-Apply**: `autoApplyOnMount` applies URL filters when component mounts.
695
- It is attempted once per grid: a failure is reported through `onError` and
696
- `onParseError` and is not retried on later renders
774
+ It is attempted once per grid: a failure is reported one time (a bad filter
775
+ through `onParseError`, any other failure through `onError`) and is not
776
+ retried on later renders
697
777
  - **🧹 Cleanup**: Automatically cleans up resources when component unmounts
698
778
  - **🛡️ Error Boundaries**: Graceful error handling with configurable callbacks
699
779
  - **📊 Filter Status**: `hasFilters` tracks whether any filters are active
@@ -889,6 +969,17 @@ const url = urlSync.generateUrl('https://app.com/page')
889
969
  // https://app.com/page?f_name_contains=john
890
970
  ```
891
971
 
972
+ ##### `getUrlState(baseUrl?: string): { url: string; hasFilters: boolean; issues: readonly URLSyncError[] }`
973
+
974
+ Generates the same URL as `generateUrl`, and tells if the grid has filters that the library supports. It reads the grid one time for both values. `hasFilters` comes from the filter state, not from the URL, because the URL also keeps the page's own params.
975
+
976
+ ```typescript
977
+ const { url, hasFilters } = urlSync.getUrlState('https://app.com/page?tab=1')
978
+ // url: https://app.com/page?tab=1 (no filters), hasFilters: false
979
+ ```
980
+
981
+ `issues` holds the filters that this call dropped, for example a text value over `maxValueLength`.
982
+
892
983
  ##### `getQueryParams(): string`
893
984
 
894
985
  Gets the current filter state as URL query parameters.
@@ -898,17 +989,17 @@ const params = urlSync.getQueryParams()
898
989
  // ?f_name_contains=john
899
990
  ```
900
991
 
901
- ##### `applyFromUrl(url?: string): void`
992
+ ##### `applyFromUrl(url?: string): { issues: readonly URLSyncError[] }`
902
993
 
903
- Applies filters from a URL to the grid.
994
+ Applies filters from a URL to the grid, and returns the filters in the URL that were dropped.
904
995
 
905
996
  ```typescript
906
997
  urlSync.applyFromUrl('https://app.com/page?f_name_contains=john')
907
998
  ```
908
999
 
909
- ##### `applyFilters(filterState: FilterState): void`
1000
+ ##### `applyFilters(filterState: FilterState): { issues: readonly URLSyncError[] }`
910
1001
 
911
- Applies a filter state object to the grid.
1002
+ Applies a filter state object to the grid, and returns the filters that were dropped (for example a number filter on a text column).
912
1003
 
913
1004
  ```typescript
914
1005
  urlSync.applyFilters({
@@ -920,7 +1011,7 @@ urlSync.applyFilters({
920
1011
  })
921
1012
  ```
922
1013
 
923
- ##### `clearFilters(): void`
1014
+ ##### `clearFilters(): { issues: readonly URLSyncError[] }`
924
1015
 
925
1016
  Clears all text filters from the grid.
926
1017
 
@@ -954,8 +1045,10 @@ interface AGGridUrlSyncConfig {
954
1045
  // Parameter name for grouped mode (default: 'grid_filters')
955
1046
  groupedParam?: string
956
1047
 
957
- // Prefix for URL parameters (default: 'f_')
958
- // In grouped mode, this affects individual parameter names within the group
1048
+ // Prefix for URL parameters in individual mode (default: 'f_')
1049
+ // A prefix without a trailing '_' gets one ('filter' -> 'filter_name_contains').
1050
+ // An empty prefix means the default. Grouped mode always uses 'f_' inside the
1051
+ // grouped value, so grouped URLs do not change with this option.
959
1052
  paramPrefix?: string
960
1053
 
961
1054
  // Maximum length for filter values (default: 200)
@@ -1,10 +1,11 @@
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
5
  */
6
6
  export declare class AGGridUrlSync {
7
- private config;
7
+ private readonly gridApi;
8
+ private readonly options;
8
9
  /**
9
10
  * Creates a new instance of AGGridUrlSync
10
11
  * @param gridApi - AG Grid API instance
@@ -17,6 +18,16 @@ export declare class AGGridUrlSync {
17
18
  * @returns URL string with filter parameters
18
19
  */
19
20
  generateUrl(baseUrl?: string): string;
21
+ /**
22
+ * Generates a URL with the current filter state, and tells if the grid has
23
+ * filters that the library supports.
24
+ *
25
+ * Reads the grid filter model one time, so an error in it is reported one
26
+ * time. `hasFilters` comes from the filter state, not from the URL: the URL
27
+ * also keeps the page's own params (#215).
28
+ * @param baseUrl - Optional base URL (defaults to current URL)
29
+ */
30
+ getUrlState(baseUrl?: string): UrlState;
20
31
  /**
21
32
  * Gets the current filter state as URL query parameters
22
33
  * @returns Query parameter string
@@ -25,17 +36,20 @@ export declare class AGGridUrlSync {
25
36
  /**
26
37
  * Applies filters from a URL to the grid
27
38
  * @param url - Optional URL to parse (defaults to current URL)
39
+ * @returns The issues of this call: filters in the URL that were dropped
28
40
  */
29
- applyFromUrl(url?: string): void;
41
+ applyFromUrl(url?: string): ApplyResult;
30
42
  /**
31
43
  * Applies a filter state object to the grid
32
44
  * @param filterState - Filter state to apply
45
+ * @returns The issues of this call: filters that were dropped
33
46
  */
34
- applyFilters(filterState: FilterState): void;
47
+ applyFilters(filterState: FilterState): ApplyResult;
35
48
  /**
36
49
  * Clears all text filters from the grid
50
+ * @returns The issues of this call
37
51
  */
38
- clearFilters(): void;
52
+ clearFilters(): ApplyResult;
39
53
  /**
40
54
  * Cleans up any resources or event listeners
41
55
  */
@@ -1,21 +1,28 @@
1
- import { DEFAULT_CONFIG } from './validation.js';
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
- config;
8
+ gridApi;
9
+ options;
8
10
  constructor(gridApi, config = {}) {
9
- this.config = {
10
- gridApi,
11
- ...DEFAULT_CONFIG,
12
- ...config
13
- };
11
+ this.gridApi = gridApi;
12
+ this.options = resolveOptions(config);
14
13
  }
15
14
  generateUrl(baseUrl) {
16
- const filterState = getFilterModel(this.config);
15
+ return this.getUrlState(baseUrl).url;
16
+ }
17
+ getUrlState(baseUrl) {
18
+ const { options, issues } = collectIssues(this.options);
19
+ const filterState = getFilterModel(this.gridApi, options);
17
20
  const url = baseUrl ?? window.location.href;
18
- return generateUrl(url, filterState, this.config);
21
+ return {
22
+ url: generateUrl(url, filterState, options),
23
+ hasFilters: Object.keys(filterState).length > 0,
24
+ issues
25
+ };
19
26
  }
20
27
  getQueryParams() {
21
28
  const url = this.generateUrl();
@@ -23,28 +30,32 @@ export class AGGridUrlSync {
23
30
  return urlObj.search;
24
31
  }
25
32
  applyFromUrl(url) {
33
+ const { options, issues } = collectIssues(this.options);
26
34
  const urlToParse = url ?? window.location.href;
27
- const filterState = parseUrlFilters(urlToParse, this.config);
28
- this.applyFilters(filterState);
35
+ const filterState = parseUrlFilters(urlToParse, options);
36
+ const applied = this.applyFilters(filterState);
37
+ return { issues: [...issues, ...(applied?.issues ?? [])] };
29
38
  }
30
39
  applyFilters(filterState) {
31
- applyFilterModel(filterState, this.config);
40
+ const { options, issues } = collectIssues(this.options);
41
+ applyFilterModel(filterState, this.gridApi, options);
42
+ return { issues };
32
43
  }
33
44
  clearFilters() {
34
- this.applyFilters({});
45
+ return this.applyFilters({});
35
46
  }
36
47
  destroy() {
37
48
  }
38
49
  getSerializationMode() {
39
- return this.config.serialization;
50
+ return this.options.serialization;
40
51
  }
41
52
  getCurrentFormat() {
42
- return this.config.format;
53
+ return this.options.format;
43
54
  }
44
55
  getFiltersAsFormat(format) {
45
- const filterState = getFilterModel(this.config);
56
+ const filterState = getFilterModel(this.gridApi, this.options);
46
57
  const tempConfig = {
47
- ...this.config,
58
+ ...this.options,
48
59
  format,
49
60
  serialization: 'grouped'
50
61
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ag-grid-url-sync.js","sourceRoot":"","sources":["../../src/core/ag-grid-url-sync.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAK7D,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgB;IAO9B,YAAY,OAAgB,EAAE,MAAM,GAAwB,EAAE;QAC5D,IAAI,CAAC,MAAM,GAAG;YACZ,OAAO;YACP,GAAG,cAAc;YACjB,GAAG,MAAM;SACV,CAAA;IACH,CAAC;IAOD,WAAW,CAAC,OAAgB;QAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/C,MAAM,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAA;QAC3C,OAAO,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACnD,CAAC;IAMD,cAAc;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,OAAO,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;IAMD,YAAY,CAAC,GAAY;QACvB,MAAM,UAAU,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAA;QAC9C,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5D,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC;IAMD,YAAY,CAAC,WAAwB;QACnC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;IAKD,YAAY;QACV,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IACvB,CAAC;IAKD,OAAO;IAEP,CAAC;IAMD,oBAAoB;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAA;IAClC,CAAC;IAMD,gBAAgB;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAA;IAC3B,CAAC;IAKD,kBAAkB,CAAC,MAA2B;QAC5C,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAG/C,MAAM,UAAU,GAAG;YACjB,GAAG,IAAI,CAAC,MAAM;YACd,MAAM;YACN,aAAa,EAAE,SAAkB;SAClC,CAAA;QAGD,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;QAExD,OAAO,MAAM,CAAC,KAAK,CAAA;IACrB,CAAC;CACF;AAQD,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,MAA4B;IAE5B,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC3C,CAAC"}
1
+ {"version":3,"file":"ag-grid-url-sync.js","sourceRoot":"","sources":["../../src/core/ag-grid-url-sync.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,40 @@
1
- import type { FilterState, InternalConfig } from './types.js';
1
+ import type { AGGridUrlSyncConfig, FilterState, InternalConfig } from './types.js';
2
2
  import type { 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
+ * Applies a filter state to AG Grid. A filter whose type does not match the
25
+ * column is skipped with a warning. An error from the grid is reported
26
+ * through `options.onParseError`.
27
+ *
28
+ * @param filterState - Filter state to apply
29
+ * @param gridApi - AG Grid API instance
30
+ * @param options - Optional options. Only `onParseError` is read.
31
+ */
32
+ export declare function applyFilterModel(filterState: FilterState, gridApi: GridApi, options?: AGGridUrlSyncConfig): void;
11
33
  /**
12
34
  * Applies a filter state to AG Grid
35
+ *
36
+ * @deprecated Give the grid API as an argument:
37
+ * `applyFilterModel(filterState, gridApi, options)`. This form will be
38
+ * removed in 0.6.0.
13
39
  */
14
40
  export declare function applyFilterModel(filterState: FilterState, config: InternalConfig): void;