ag-grid-url-sync 0.5.2 → 0.5.4
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 +139 -48
- package/dist/core/grid-integration.d.ts +7 -1
- package/dist/core/grid-integration.js +7 -3
- package/dist/core/grid-integration.js.map +1 -1
- package/dist/core/grid-url-sync.d.ts +29 -0
- package/dist/core/grid-url-sync.js +115 -35
- package/dist/core/grid-url-sync.js.map +1 -1
- package/dist/core/own-write.d.ts +20 -1
- package/dist/core/own-write.js +37 -18
- package/dist/core/own-write.js.map +1 -1
- package/dist/core/types.d.ts +30 -5
- package/dist/core/types.js.map +1 -1
- package/dist/core/url-generator.d.ts +4 -2
- package/dist/core/url-generator.js +23 -22
- package/dist/core/url-generator.js.map +1 -1
- package/dist/core/view-storage.d.ts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/sync-holder.d.ts +4 -1
- package/dist/react/sync-holder.js +27 -17
- package/dist/react/sync-holder.js.map +1 -1
- package/dist/react/types.d.ts +3 -3
- package/dist/react/use-ag-grid-url-sync.js +5 -5
- package/dist/react/use-ag-grid-url-sync.js.map +1 -1
- package/dist/react/use-grid-url-sync.js +10 -9
- package/dist/react/use-grid-url-sync.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -63,10 +63,31 @@ Supports **all AG Grid text, number, and date filter operations** (26 total) wit
|
|
|
63
63
|
| **Date** | Before or Equal | `f_column_beforeEq=YYYY-MM-DD` | `f_archived_beforeEq=2024-12-31` | Date is before or equal to value |
|
|
64
64
|
| **Date** | After | `f_column_after=YYYY-MM-DD` | `f_created_after=2024-01-01` | Date is after value |
|
|
65
65
|
| **Date** | After or Equal | `f_column_afterEq=YYYY-MM-DD` | `f_updated_afterEq=2024-06-01` | Date is after or equal to value |
|
|
66
|
-
| **Date** | In Range | `f_column_daterange=start,end` | `f_period_daterange=2024-01-01,2024-12-31` | Date is between start and end (
|
|
66
|
+
| **Date** | In Range | `f_column_daterange=start,end` | `f_period_daterange=2024-01-01,2024-12-31` | Date is between start and end (see below) |
|
|
67
67
|
| **Date** | Blank | `f_column_blank=true` | `f_deadline_blank=true` | Date field is empty/null |
|
|
68
68
|
| **Date** | Not Blank | `f_column_notBlank=true` | `f_created_notBlank=true` | Date field has any value |
|
|
69
69
|
|
|
70
|
+
Two date operations depend on the settings of the AG Grid column:
|
|
71
|
+
|
|
72
|
+
- **`daterange`:** AG Grid's `inRange` leaves out the start and end dates. To keep them, set `filterParams: { inRangeInclusive: true }` on the column.
|
|
73
|
+
- **`beforeEq` and `afterEq`:** they need the AG Grid filter options `lessThanOrEqual` and `greaterThanOrEqual`. AG Grid's default date filter does not have these options, so it uses `equals` in their place. The grid then shows other rows, and the sync reports no issue. Add the options to the column:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
filterParams: {
|
|
77
|
+
filterOptions: [
|
|
78
|
+
'equals',
|
|
79
|
+
'notEqual',
|
|
80
|
+
'lessThan',
|
|
81
|
+
'lessThanOrEqual',
|
|
82
|
+
'greaterThan',
|
|
83
|
+
'greaterThanOrEqual',
|
|
84
|
+
'inRange',
|
|
85
|
+
'blank',
|
|
86
|
+
'notBlank'
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
70
91
|
> **🗓️ Date Format Note**: Date filters require strict ISO format (`YYYY-MM-DD`). All date values are validated for real calendar dates, including leap years and month boundaries. Invalid or non-ISO dates will be rejected.
|
|
71
92
|
|
|
72
93
|
### Filter Detection
|
|
@@ -231,6 +252,8 @@ function createShareableUrl(filters: FilterState, baseUrl: string): string {
|
|
|
231
252
|
}
|
|
232
253
|
```
|
|
233
254
|
|
|
255
|
+
`generateUrl` keeps the page's own params as they are in `baseUrl`: the same text and the same order. For example, `?debug` stays `?debug`, and `%20` stays `%20`. It removes the old filter params and puts the new ones after the page's params, in both modes. With no filters, it writes no filter param. The sync, `getUrl` and the deprecated APIs write the URL in the same way.
|
|
256
|
+
|
|
234
257
|
#### Example: Read and Write the Grid Filters
|
|
235
258
|
|
|
236
259
|
```typescript
|
|
@@ -249,7 +272,7 @@ The config form (`getFilterModel({ ...DEFAULT_CONFIG, gridApi })`) still works,
|
|
|
249
272
|
|
|
250
273
|
### Vanilla JS: `createGridUrlSync`
|
|
251
274
|
|
|
252
|
-
One call gives full sync. `createGridUrlSync` applies the address bar's filters to the grid, follows the grid's filter changes, can write them to the address bar, and removes its listeners when the grid is destroyed.
|
|
275
|
+
One call gives full sync. `createGridUrlSync` applies the address bar's filters to the grid, follows the grid's filter changes, can write them to the address bar, and removes its listeners when the grid is destroyed (on AG Grid 28 and 29, see the note under the options).
|
|
253
276
|
|
|
254
277
|
```typescript
|
|
255
278
|
import { createGridUrlSync, individual, grouped } from 'ag-grid-url-sync'
|
|
@@ -257,7 +280,7 @@ import { createGridUrlSync, individual, grouped } from 'ag-grid-url-sync'
|
|
|
257
280
|
const sync = createGridUrlSync({
|
|
258
281
|
api: gridApi,
|
|
259
282
|
codec: individual({ prefix: 'f_' }), // or grouped({ param: 'gf', format: 'json' })
|
|
260
|
-
history: 'replace', // 'none' (default) | 'replace' | 'push' | (url) =>
|
|
283
|
+
history: 'replace', // 'none' (default) | 'replace' | 'push' | (url, { replace }) => ...
|
|
261
284
|
onIssue: ({ issue, source }) => {
|
|
262
285
|
if (issue.severity === 'warning') showToast(issue.message)
|
|
263
286
|
}
|
|
@@ -279,19 +302,75 @@ sync.destroy()
|
|
|
279
302
|
|
|
280
303
|
`applyFilters` writes filters to the grid as the app's own write. When they land, the sync writes the URL in the `history` mode, as it does for a user edit. `applyUrl` writes no history, because the URL already holds those filters.
|
|
281
304
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
|
287
|
-
|
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
| `
|
|
292
|
-
| `
|
|
305
|
+
A URL write keeps the text and the order of the page's other params, and puts the filter params after them. With no filters, the URL has no filter param.
|
|
306
|
+
|
|
307
|
+
Two grids on one page must use different URL params. A URL write removes every param with the codec's prefix and the codec's grouped param. `grouped()` has no prefix, so it always removes the `f_` params too. Give each grid its own prefix, for example `individual({ prefix: 'a' })` and `individual({ prefix: 'b' })`.
|
|
308
|
+
|
|
309
|
+
| Option | Default | Meaning |
|
|
310
|
+
| ------------------ | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
311
|
+
| `api` | (required) | The AG Grid API |
|
|
312
|
+
| `codec` | `individual()` | How the filters are written in the URL. `individual({ prefix })` writes one param for each filter; `grouped({ param, format })` writes all filters in one param |
|
|
313
|
+
| `maxValueLength` | `200` | The longest text value that is kept |
|
|
314
|
+
| `history` | `'none'` | How a filter change goes to the address bar. `'replace'` and `'push'` use `window.history`; a function gets the absolute URL and `{ replace }`. The page's other params, `#hash` and `history.state` stay |
|
|
315
|
+
| `popstate` | `true` only with `'push'` | Apply the URL when the back or forward button changes it |
|
|
316
|
+
| `applyUrlOnCreate` | `true` | Apply the address bar's filters on create. A URL with no filter params keeps the grid's filters (for example from `initialState`), and with `history` they are written to the URL with replace. AG Grid 31 applies `initialState` filters when the first rows come: the sync writes them at that time |
|
|
317
|
+
| `views` | none | The saved views. Give `createViewStore(key)` from `ag-grid-url-sync/view-storage`. See [Saved Views](#saved-views) |
|
|
318
|
+
| `throwOnError` | `false` | Throw an issue instead of reporting it, in the methods that the app calls (`applyUrl`, `getUrl`, `applyFilters`, `saveView`, `loadView`, `deleteView`). `createGridUrlSync` and its listeners never throw |
|
|
319
|
+
| `onIssue` | none | Gets each issue one time, as `{ issue, source }`. `source` is `'url'` (the sync read the address bar), `'grid'` (it read the grid) or `'api'` (a method that the app called) |
|
|
320
|
+
|
|
321
|
+
The snapshot `status` is `'active'` from create, and `'destroyed'` after `destroy()` or after the grid is destroyed. A grid that cannot take the sync's listeners also gives `'destroyed'`: `createGridUrlSync` does not throw, and sends a `GRID_ERROR` to `onIssue`. After that, `applyUrl`, `applyFilters`, `saveView` and `loadView` report `NOT_READY` to `onIssue`. `deleteView` needs only storage, so it still works. `IDLE_SNAPSHOT` (`status: 'idle'`) is the snapshot for a time when there is no sync yet. `getSnapshot()` returns the same object until something changes, so it works with React's `useSyncExternalStore`. The sync writes no history for an `applyUrl` apply, because the URL holds those filters already. `applyFilters` and `loadView` write the URL as a user edit does. Nothing reads `window` when the module loads, and a sync made with no `window` does nothing to the address bar.
|
|
322
|
+
|
|
323
|
+
**AG Grid 28 and 29:** the sync does not see a grid destroy. These versions have no `gridPreDestroyed` event and no `api.isDestroyed()`. So `status` stays `'active'`, the listeners stay, and a later `applyFilters` writes to the destroyed grid and to the URL. Call `sync.destroy()` before `api.destroy()`. In React, set the hook's `api` to `null` when you remove the grid.
|
|
324
|
+
|
|
325
|
+
An issue has the source of the work that found it. A method that the app calls gives `'api'` to each issue of its work: also the grid read after its write, a later landing of that write, and the write of the stored view pointer. A back-button apply and the restore on create give `'url'`. A filter change in the grid, and the read of the grid's own filters on create, give `'grid'`.
|
|
326
|
+
|
|
327
|
+
#### History with a router
|
|
328
|
+
|
|
329
|
+
A `history` function gets two arguments: the absolute URL (`https://host/path?...`) and `{ replace }`. `replace` tells the function what to do with the history entry:
|
|
330
|
+
|
|
331
|
+
- `true`: replace the entry. This is for a write that must not add a back-button step: the create-time write of the grid's own filters, and the restore of a stored view (on create, or for a new `storageKey`).
|
|
332
|
+
- `false`: add an entry. This is for a user edit, `applyFilters` and `loadView`.
|
|
333
|
+
|
|
334
|
+
For a router that can push, use the two arguments. Then the history is the same as with `'push'`:
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
createGridUrlSync({
|
|
338
|
+
api: gridApi,
|
|
339
|
+
history: (url, { replace }) =>
|
|
340
|
+
replace ? router.replace(url) : router.push(url)
|
|
341
|
+
})
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
A function with one argument also works. It does not use `replace`, so it does the same for each write. `url => router.replace(url)` is correct. Do not use `url => router.push(url)`: it adds a back-button step on page load.
|
|
345
|
+
|
|
346
|
+
The Next.js router takes the absolute URL. React Router's `navigate` takes a path: it reads an absolute URL as a relative path, so the route does not match. Give it the path, the search and the hash:
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
createGridUrlSync({
|
|
350
|
+
api: gridApi,
|
|
351
|
+
history: (url, { replace }) => {
|
|
352
|
+
const { pathname, search, hash } = new URL(url)
|
|
353
|
+
navigate(pathname + search + hash, { replace })
|
|
354
|
+
}
|
|
355
|
+
})
|
|
356
|
+
```
|
|
293
357
|
|
|
294
|
-
The
|
|
358
|
+
The sync reads the address bar only on create and on `popstate`. A router navigation that keeps the page mounted (for example a Next.js `<Link>` to the same page with other params) does not fire `popstate`, so the sync does not apply its filters. The next user edit then writes the grid's filters over them. Call `applyUrl()` when the search params change. With a `history` function, `popstate` is `false` by default, so set `popstate: true` to apply the URL on back and forward:
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
const query = useSearchParams().toString()
|
|
362
|
+
const { status, applyUrl } = useGridUrlSync({
|
|
363
|
+
api,
|
|
364
|
+
history: url => router.replace(url),
|
|
365
|
+
popstate: true
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
if (status === 'active') applyUrl()
|
|
370
|
+
}, [query, status, applyUrl])
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
`'replace'` and `'push'` keep `history.state`, but they remove the Next.js keys `__NA` and `_N` from it. Next.js skips its router update for a write with these keys. With them removed, the Next.js router (`useSearchParams`) gets the new URL. A state that is not a plain object stays as it is.
|
|
295
374
|
|
|
296
375
|
### Basic Example (deprecated `createUrlSync`)
|
|
297
376
|
|
|
@@ -305,7 +384,7 @@ const urlSync = createUrlSync(gridApi)
|
|
|
305
384
|
|
|
306
385
|
// Generate shareable URL with current filters (text and number)
|
|
307
386
|
const shareableUrl = urlSync.generateUrl()
|
|
308
|
-
// Result: https://app.com/data?f_name_contains=john&f_salary_gte=80000&f_age_range=25
|
|
387
|
+
// Result: https://app.com/data?f_name_contains=john&f_salary_gte=80000&f_age_range=25%2C45
|
|
309
388
|
|
|
310
389
|
// Apply filters from URL (automatically detects text vs number columns)
|
|
311
390
|
urlSync.applyFromUrl(
|
|
@@ -368,6 +447,8 @@ interface AGGridUrlSyncConfig {
|
|
|
368
447
|
|
|
369
448
|
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.
|
|
370
449
|
|
|
450
|
+
With no filters, the URL has no grouped param, in each format. A link with an empty value, such as `?grid_filters=%7B%7D` (json) or `?grid_filters=e30%3D` (base64), still opens with no filters and no issue. `getFiltersAsFormat` and `serializeGrouped` do not change: with no filters, they give `'{}'` for json, `'e30='` for base64 and `''` for querystring.
|
|
451
|
+
|
|
371
452
|
> **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.
|
|
372
453
|
|
|
373
454
|
### Format Options
|
|
@@ -640,24 +721,25 @@ The options are the [`createGridUrlSync` options](#vanilla-js-creategridurlsync)
|
|
|
640
721
|
| `api` | none | The AG Grid API, or `null` while the grid starts |
|
|
641
722
|
| `storageKey` | none | Enables saved views, kept in `localStorage` under this key (in place of the core's `views` store). With no key, the view methods do nothing |
|
|
642
723
|
| `enabled` | `true` | With `false`, the hook makes no sync: `status` is `'idle'`, and a method reports `NOT_READY`. `views` still shows what is in storage. Back to `true` starts again, as a new sync does: the URL is applied again |
|
|
643
|
-
| `throwOnError` | `false` | As in TanStack Query: the hook throws a picked issue during render, so an error boundary catches it. The methods do not throw
|
|
724
|
+
| `throwOnError` | `false` | As in TanStack Query: the hook throws a picked issue of `issues` during render, so an error boundary catches it. Failures other than `HISTORY_WRITE_FAILED` go to `onIssue` only. The methods do not throw |
|
|
644
725
|
|
|
645
726
|
The hook returns the snapshot and the methods of the sync:
|
|
646
727
|
|
|
647
|
-
| Property | Description
|
|
648
|
-
| ------------------------------------ |
|
|
649
|
-
| `status` | `'idle'` (no grid, no sync yet, or a server render), `'active'` or `'destroyed'`
|
|
650
|
-
| `url`, `hasFilters`, `issues` | The URL with the grid's filters, whether
|
|
651
|
-
| `views`, `activeViewId` | The saved views and the active one
|
|
652
|
-
| `applyUrl(url?)`, `applyFilters(f)` | Apply a URL or filters. They return `{ issues }`
|
|
653
|
-
| `getUrl(baseUrl?)` | The URL with the grid's filters, for example to share
|
|
654
|
-
| `saveView`, `loadView`, `deleteView` | The saved view methods of the sync
|
|
728
|
+
| Property | Description |
|
|
729
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------------- |
|
|
730
|
+
| `status` | `'idle'` (no grid, no sync yet, or a server render), `'active'` or `'destroyed'` |
|
|
731
|
+
| `url`, `hasFilters`, `issues` | The URL with the grid's filters, whether the URL holds filters (see below), the latest issues |
|
|
732
|
+
| `views`, `activeViewId` | The saved views and the active one |
|
|
733
|
+
| `applyUrl(url?)`, `applyFilters(f)` | Apply a URL or filters. They return `{ issues }` |
|
|
734
|
+
| `getUrl(baseUrl?)` | The URL with the grid's filters, for example to share |
|
|
735
|
+
| `saveView`, `loadView`, `deleteView` | The saved view methods of the sync |
|
|
655
736
|
|
|
656
737
|
- **The core's rules hold.** On mount, a URL with filters wins over the stored view, a URL with no filters keeps the grid's filters, and a URL apply writes no history.
|
|
657
738
|
- **Options can change after mount.** A new codec, `maxValueLength`, history mode, `popstate` or `storageKey` makes a new sync on the same grid. It does not apply the URL again, and it keeps the active view. A new `storageKey` restores that store's view. A new codec object with the same settings, a new `onIssue` or a new `history` function makes no new sync.
|
|
658
739
|
- **The result is stable.** It is the same object until a snapshot value changes, and the methods never change.
|
|
740
|
+
- **`hasFilters` counts only the filters that the URL holds.** With `individual()`, a combined (AND/OR) filter or a set filter is not in the URL (`UNSUPPORTED_FILTER`). So `hasFilters` is `false` while the grid shows such a filter, and a "Clear" button with `disabled={!hasFilters}` stays disabled. To clear any filter, keep the button enabled.
|
|
659
741
|
- **A method with no sync** (no grid yet, `enabled: false`): `applyUrl` and `applyFilters` report `NOT_READY` to `onIssue`, and so do `saveView` and `loadView` with a `storageKey`. `getUrl` returns the base URL. `deleteView` still works with storage only.
|
|
660
|
-
- **Issues stay across a new sync.** After an option change or a `StrictMode` remount, `issues` still shows the latest apply's issues until the next apply. `onIssue` gets each issue one time.
|
|
742
|
+
- **Issues stay across a new sync.** After an option change or a `StrictMode` remount, `issues` still shows the latest apply's issues until the next apply. A new `storageKey` that restores its stored view clears them, as `loadView` does. `onIssue` gets each issue one time.
|
|
661
743
|
- `StrictMode`, React's `<Activity>` and server rendering are supported.
|
|
662
744
|
|
|
663
745
|
### Migrating from `useAGGridUrlSync`
|
|
@@ -793,7 +875,11 @@ The hook takes the `history` and `popstate` options of [`createGridUrlSync`](#va
|
|
|
793
875
|
useAGGridUrlSync(gridApi, { autoApplyOnMount: true, history: 'push' })
|
|
794
876
|
|
|
795
877
|
// Or give the URL to a router. A new function on each render is fine.
|
|
796
|
-
|
|
878
|
+
// `replace` is true for a write that must not add an entry (see History with a router).
|
|
879
|
+
useAGGridUrlSync(gridApi, {
|
|
880
|
+
history: (url, { replace }) =>
|
|
881
|
+
replace ? router.replace(url) : router.push(url)
|
|
882
|
+
})
|
|
797
883
|
```
|
|
798
884
|
|
|
799
885
|
- A user edit, `applyFilters`, `clearFilters` and `loadView` write the URL. `'push'` adds one entry for each of them.
|
|
@@ -812,7 +898,11 @@ interface UseAGGridUrlSyncOptions {
|
|
|
812
898
|
throwOnError?: boolean | ((issue: URLSyncError) => boolean) // Default: false
|
|
813
899
|
|
|
814
900
|
// Address bar (see Address bar above)
|
|
815
|
-
history?:
|
|
901
|
+
history?:
|
|
902
|
+
| 'none'
|
|
903
|
+
| 'replace'
|
|
904
|
+
| 'push'
|
|
905
|
+
| ((url: string, write: { replace: boolean }) => void) // Default: 'none'
|
|
816
906
|
popstate?: boolean // Default: true with 'push', else false
|
|
817
907
|
|
|
818
908
|
// React-specific options
|
|
@@ -827,21 +917,21 @@ interface UseAGGridUrlSyncOptions {
|
|
|
827
917
|
|
|
828
918
|
#### Hook Return Values
|
|
829
919
|
|
|
830
|
-
| Property | Type | Description
|
|
831
|
-
| ---------------------- | --------------------------------------------------------- |
|
|
832
|
-
| `shareUrl` | `(baseUrl?: string) => string` | Generate shareable URL with current filters
|
|
833
|
-
| `getQueryParams` | `() => string` | Get filter state as query parameters
|
|
834
|
-
| `applyUrlFilters` | `(url?: string) => void` | Apply filters from URL to grid
|
|
835
|
-
| `clearFilters` | `() => void` | Clear all text filters
|
|
836
|
-
| `isReady` | `boolean` | Whether the grid API is available and the hook is ready. `false` after AG Grid destroys the grid. |
|
|
837
|
-
| `currentUrl` | `string` | Current URL with filters applied
|
|
838
|
-
| `hasFilters` | `boolean` | Whether the grid has supported filters
|
|
839
|
-
| `issues` | `readonly URLSyncError[]` | Filters that the latest URL apply or URL write dropped (see Error Handling)
|
|
840
|
-
| `parseUrlFilters` | `(url: string) => FilterState` | Parse filters from URL without applying
|
|
841
|
-
| `applyFilters` | `(filters: FilterState) => void` | Apply filter state object to grid
|
|
842
|
-
| `getFiltersAsFormat` | `(format: 'querystring' \| 'json' \| 'base64') => string` | Serialize filters to any supported format (for sharing/export)
|
|
843
|
-
| `getSerializationMode` | `() => 'individual' \| 'grouped'` | Get the current serialization mode (individual or grouped)
|
|
844
|
-
| `getCurrentFormat` | `() => 'individual' \| 'grouped'` | **Deprecated** (removed in 0.6.0): use `getSerializationMode`
|
|
920
|
+
| Property | Type | Description |
|
|
921
|
+
| ---------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
922
|
+
| `shareUrl` | `(baseUrl?: string) => string` | Generate shareable URL with current filters |
|
|
923
|
+
| `getQueryParams` | `() => string` | Get filter state as query parameters |
|
|
924
|
+
| `applyUrlFilters` | `(url?: string) => void` | Apply filters from URL to grid |
|
|
925
|
+
| `clearFilters` | `() => void` | Clear all text filters |
|
|
926
|
+
| `isReady` | `boolean` | Whether the grid API is available and the hook is ready. `false` after AG Grid destroys the grid (AG Grid 30 and later). |
|
|
927
|
+
| `currentUrl` | `string` | Current URL with filters applied |
|
|
928
|
+
| `hasFilters` | `boolean` | Whether the grid has supported filters |
|
|
929
|
+
| `issues` | `readonly URLSyncError[]` | Filters that the latest URL apply or URL write dropped (see Error Handling) |
|
|
930
|
+
| `parseUrlFilters` | `(url: string) => FilterState` | Parse filters from URL without applying |
|
|
931
|
+
| `applyFilters` | `(filters: FilterState) => void` | Apply filter state object to grid |
|
|
932
|
+
| `getFiltersAsFormat` | `(format: 'querystring' \| 'json' \| 'base64') => string` | Serialize filters to any supported format (for sharing/export) |
|
|
933
|
+
| `getSerializationMode` | `() => 'individual' \| 'grouped'` | Get the current serialization mode (individual or grouped) |
|
|
934
|
+
| `getCurrentFormat` | `() => 'individual' \| 'grouped'` | **Deprecated** (removed in 0.6.0): use `getSerializationMode` |
|
|
845
935
|
|
|
846
936
|
Saved views (inert unless `storageKey` is set):
|
|
847
937
|
|
|
@@ -897,7 +987,7 @@ Rules for the vanilla API:
|
|
|
897
987
|
On create (when `applyUrlOnCreate` is not `false`), the sync picks the starting filters in this order:
|
|
898
988
|
|
|
899
989
|
1. The URL holds the filters of the stored view (compared in URL form). The sync restores the view with its full model, and keeps `activeViewId` and the pointer. This is how a reload keeps a view that was loaded with `history` on.
|
|
900
|
-
2. The URL has at least one filter. The URL wins. `activeViewId` is `null` and the pointer is cleared. A URL with only bad params does not win.
|
|
990
|
+
2. The URL has at least one filter. The URL wins. `activeViewId` is `null` and the pointer is cleared. A URL with only bad params does not win, and its bad params are not reported: `onIssue` gets nothing, and `issues` stays empty. With no `views`, the sync reports them.
|
|
901
991
|
3. A stored view exists. The sync restores it. With `history` on, the URL is written with replace, so page load adds no back-button step.
|
|
902
992
|
4. Else, the grid keeps its filters.
|
|
903
993
|
|
|
@@ -907,7 +997,8 @@ A stored pointer that names a missing view is ignored.
|
|
|
907
997
|
|
|
908
998
|
Pass a `storageKey` to let users name and revisit filter sets. The key both enables
|
|
909
999
|
the feature and namespaces its storage, so two grids on the same origin must use
|
|
910
|
-
different keys
|
|
1000
|
+
different keys. They must also use different URL params (see
|
|
1001
|
+
[Vanilla JS: `createGridUrlSync`](#vanilla-js-creategridurlsync)):
|
|
911
1002
|
|
|
912
1003
|
```tsx
|
|
913
1004
|
const { views, activeViewId, saveView, loadView, deleteView } =
|
|
@@ -988,7 +1079,7 @@ store.saveView('Engineering', gridApi.getFilterModel())
|
|
|
988
1079
|
retried on later renders
|
|
989
1080
|
- **🧹 Cleanup**: Automatically cleans up resources when component unmounts
|
|
990
1081
|
- **🛡️ Error Boundaries**: Graceful error handling with configurable callbacks
|
|
991
|
-
- **📊 Filter Status**: `hasFilters` tracks whether
|
|
1082
|
+
- **📊 Filter Status**: `hasFilters` tracks whether the grid has supported filters
|
|
992
1083
|
- **💾 Saved Views**: `storageKey` enables naming and revisiting filter sets
|
|
993
1084
|
|
|
994
1085
|
### React with Grouped Serialization
|
|
@@ -1131,7 +1222,7 @@ The library generates clean, human-readable URLs:
|
|
|
1131
1222
|
```
|
|
1132
1223
|
Base URL: https://app.com/page
|
|
1133
1224
|
With text filters: https://app.com/page?f_name_contains=john&f_status_eq=active
|
|
1134
|
-
With number filters: https://app.com/page?f_salary_gte=75000&f_age_range=25
|
|
1225
|
+
With number filters: https://app.com/page?f_salary_gte=75000&f_age_range=25%2C45
|
|
1135
1226
|
Mixed filters: https://app.com/page?f_name_contains=john&f_salary_gte=75000&f_age_lt=50
|
|
1136
1227
|
```
|
|
1137
1228
|
|
|
@@ -1142,7 +1233,7 @@ Parameter structure:
|
|
|
1142
1233
|
- **Text Operations**: `contains`, `eq`, `neq`, `startsWith`, `endsWith`, `notContains`, `blank`, `notBlank`
|
|
1143
1234
|
- **Number Operations**: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `range`, `blank`, `notBlank`
|
|
1144
1235
|
- **Date Operations**: `eq`, `neq`, `before`, `beforeEq`, `after`, `afterEq`, `daterange`, `blank`, `notBlank`
|
|
1145
|
-
- **Range Format**: `f_column_range=min,max` (comma-separated values)
|
|
1236
|
+
- **Range Format**: `f_column_range=min,max` (comma-separated values). The library writes the comma as `%2C`. A link with a raw comma (`f_age_range=25,45`) also works.
|
|
1146
1237
|
- Standard URL encoding for special characters
|
|
1147
1238
|
- Supports column names with underscores (e.g., `user_id`, `salary_base`, `created_date`)
|
|
1148
1239
|
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { AGGridUrlSyncConfig, FilterState, InternalConfig } from './types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { GridApi } from 'ag-grid-community';
|
|
3
|
+
/**
|
|
4
|
+
* The grid's filter model, as `api.getFilterModel()` gives it. This is AG
|
|
5
|
+
* Grid's `FilterModel`, which AG Grid 28 to 30 do not export (#300). The
|
|
6
|
+
* package does not export this type.
|
|
7
|
+
*/
|
|
8
|
+
export type FilterModel = ReturnType<GridApi['getFilterModel']>;
|
|
3
9
|
/**
|
|
4
10
|
* Detects the expected filter type for a column based on AG Grid configuration
|
|
5
11
|
*/
|
|
@@ -28,12 +28,16 @@ function toIsoDateString(val) {
|
|
|
28
28
|
const match = val.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
29
29
|
return match?.[1] ? match[1] : val || '';
|
|
30
30
|
}
|
|
31
|
+
function findColumnDef(gridApi, columnId) {
|
|
32
|
+
if (gridApi.getColumn === undefined)
|
|
33
|
+
return gridApi.getColumnDef(columnId);
|
|
34
|
+
return gridApi.getColumn(columnId)?.getColDef() ?? null;
|
|
35
|
+
}
|
|
31
36
|
export function detectColumnFilterType(gridApi, columnId) {
|
|
32
37
|
try {
|
|
33
|
-
const
|
|
34
|
-
if (!
|
|
38
|
+
const colDef = findColumnDef(gridApi, columnId);
|
|
39
|
+
if (!colDef)
|
|
35
40
|
return 'text';
|
|
36
|
-
const colDef = column.getColDef();
|
|
37
41
|
if (colDef.filter === 'agDateColumnFilter')
|
|
38
42
|
return 'date';
|
|
39
43
|
if (colDef.filter === 'agNumberColumnFilter')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-integration.js","sourceRoot":"","sources":["../../src/core/grid-integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAU5B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"grid-integration.js","sourceRoot":"","sources":["../../src/core/grid-integration.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,11 @@ import { URLSyncError } from './types.js';
|
|
|
3
3
|
import type { OwnWrite } from './own-write.js';
|
|
4
4
|
/** The snapshot when there is no sync yet, for the React hook (#222) */
|
|
5
5
|
export declare const IDLE_SNAPSHOT: GridUrlSyncSnapshot;
|
|
6
|
+
/**
|
|
7
|
+
* Two issue lists with the same code, column and message in each place. Not
|
|
8
|
+
* public: the React hook's holder uses it too (#311).
|
|
9
|
+
*/
|
|
10
|
+
export declare function sameIssues(a: readonly URLSyncError[], b: readonly URLSyncError[]): boolean;
|
|
6
11
|
/**
|
|
7
12
|
* Makes a sync between one grid and the URL. It applies the address bar's
|
|
8
13
|
* filters to the grid (a URL with no filters keeps the grid's filters), then
|
|
@@ -26,6 +31,17 @@ export interface Handover {
|
|
|
26
31
|
readonly keys: string;
|
|
27
32
|
/** The issues of the latest apply (#271 review) */
|
|
28
33
|
readonly applyIssues: readonly URLSyncError[];
|
|
34
|
+
/**
|
|
35
|
+
* The issues of the latest grid read, which onIssue got (#305). The next
|
|
36
|
+
* sync does not report the same ones again. It reports a new one.
|
|
37
|
+
*/
|
|
38
|
+
readonly readIssues: readonly URLSyncError[];
|
|
39
|
+
/**
|
|
40
|
+
* The key of the GRID_ERROR that onIssue got when the grid could not take
|
|
41
|
+
* the old sync's listeners, or null (#286). The next sync does not report
|
|
42
|
+
* the same failure again. A different failure is reported.
|
|
43
|
+
*/
|
|
44
|
+
readonly listenerFailure: string | null;
|
|
29
45
|
}
|
|
30
46
|
/**
|
|
31
47
|
* Not public: the state of a sync that the next sync on the same grid can
|
|
@@ -54,6 +70,19 @@ export interface SyncStart {
|
|
|
54
70
|
* replaces them.
|
|
55
71
|
*/
|
|
56
72
|
readonly keepApplyIssues?: boolean | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The kept view comes from a new view store (a new storageKey in the
|
|
75
|
+
* hook). Its restore replaces what the grid showed, so it clears the
|
|
76
|
+
* apply issues, as loadView does (#285). The same store's kept view
|
|
77
|
+
* keeps them: the grid shows what it showed.
|
|
78
|
+
*/
|
|
79
|
+
readonly newStore?: boolean | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* The deprecated hook: a grid read and a pointer clear report with source
|
|
82
|
+
* 'grid', whatever started the work, as before #313. The hook gives them
|
|
83
|
+
* the 0.5.1 contexts by that source.
|
|
84
|
+
*/
|
|
85
|
+
readonly gridSourceForGridWork?: boolean | undefined;
|
|
57
86
|
}
|
|
58
87
|
/**
|
|
59
88
|
* Not public: createGridUrlSync, and the React hook's sync (#270), which
|