ag-grid-url-sync 0.3.0 → 0.5.0

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 (42) hide show
  1. package/README.md +144 -14
  2. package/dist/core/ag-grid-url-sync.d.ts +13 -0
  3. package/dist/core/ag-grid-url-sync.js +10 -55
  4. package/dist/core/ag-grid-url-sync.js.map +1 -1
  5. package/dist/core/grid-integration.js +5 -67
  6. package/dist/core/grid-integration.js.map +1 -1
  7. package/dist/core/index.js +0 -5
  8. package/dist/core/index.js.map +1 -1
  9. package/dist/core/individual-params.d.ts +19 -0
  10. package/dist/core/individual-params.js +260 -0
  11. package/dist/core/individual-params.js.map +1 -0
  12. package/dist/core/serialization/formats.d.ts +8 -9
  13. package/dist/core/serialization/formats.js +63 -65
  14. package/dist/core/serialization/formats.js.map +1 -1
  15. package/dist/core/serialization/grouped.d.ts +10 -5
  16. package/dist/core/serialization/grouped.js +4 -51
  17. package/dist/core/serialization/grouped.js.map +1 -1
  18. package/dist/core/serialization/index.js +0 -4
  19. package/dist/core/serialization/index.js.map +1 -1
  20. package/dist/core/types.d.ts +42 -9
  21. package/dist/core/types.js +0 -118
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/core/url-generator.d.ts +10 -7
  24. package/dist/core/url-generator.js +25 -165
  25. package/dist/core/url-generator.js.map +1 -1
  26. package/dist/core/url-parser.d.ts +19 -7
  27. package/dist/core/url-parser.js +28 -294
  28. package/dist/core/url-parser.js.map +1 -1
  29. package/dist/core/validation.d.ts +6 -6
  30. package/dist/core/validation.js +1 -78
  31. package/dist/core/validation.js.map +1 -1
  32. package/dist/core/view-storage.d.ts +63 -0
  33. package/dist/core/view-storage.js +112 -0
  34. package/dist/core/view-storage.js.map +1 -0
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.js +0 -6
  37. package/dist/index.js.map +1 -1
  38. package/dist/react/index.d.ts +1 -0
  39. package/dist/react/types.d.ts +103 -1
  40. package/dist/react/use-ag-grid-url-sync.js +406 -46
  41. package/dist/react/use-ag-grid-url-sync.js.map +1 -1
  42. package/package.json +98 -31
@@ -1,7 +1,4 @@
1
1
  import { InvalidFilterError, InvalidDateError, TEXT_FILTER_OPERATIONS, NUMBER_FILTER_OPERATIONS, DATE_FILTER_OPERATIONS } from './types.js';
2
- /**
3
- * Default configuration values
4
- */
5
2
  export const DEFAULT_CONFIG = {
6
3
  paramPrefix: 'f_',
7
4
  maxValueLength: 200,
@@ -10,17 +7,7 @@ export const DEFAULT_CONFIG = {
10
7
  format: 'querystring',
11
8
  onParseError: () => { }
12
9
  };
13
- /**
14
- * Validates a text filter value against configuration constraints
15
- *
16
- * @param value - The filter value to validate
17
- * @param config - Internal configuration with validation rules
18
- * @param operation - Optional filter operation type. Blank operations (blank/notBlank) bypass value validation
19
- * @returns The validated filter value (empty string for blank operations)
20
- * @throws InvalidFilterError if value exceeds maximum length
21
- */
22
10
  export function validateFilterValue(value, config, operation) {
23
- // Blank operations don't require value validation
24
11
  if (operation === 'blank' || operation === 'notBlank') {
25
12
  return '';
26
13
  }
@@ -29,30 +16,15 @@ export function validateFilterValue(value, config, operation) {
29
16
  }
30
17
  return value;
31
18
  }
32
- /**
33
- * Validates a number filter value
34
- *
35
- * @param value - The number value to validate
36
- * @returns Validation result
37
- */
38
19
  export function validateNumberFilter(value) {
39
- // Basic number validation
40
20
  if (!Number.isFinite(value)) {
41
21
  return { valid: false, error: 'Filter value must be a finite number' };
42
22
  }
43
- // Range validation for precision
44
23
  if (Math.abs(value) > Number.MAX_SAFE_INTEGER) {
45
24
  return { valid: false, error: 'Number value exceeds safe integer range' };
46
25
  }
47
26
  return { valid: true };
48
27
  }
49
- /**
50
- * Validates a number range filter
51
- *
52
- * @param min - The minimum value
53
- * @param max - The maximum value
54
- * @returns Validation result
55
- */
56
28
  export function validateNumberRange(min, max) {
57
29
  const minResult = validateNumberFilter(min);
58
30
  if (!minResult.valid)
@@ -68,19 +40,11 @@ export function validateNumberRange(min, max) {
68
40
  }
69
41
  return { valid: true };
70
42
  }
71
- /**
72
- * Validates a parsed number from string input
73
- *
74
- * @param value - String representation of number
75
- * @returns Parsed number or throws InvalidFilterError
76
- */
77
43
  export function validateAndParseNumber(value) {
78
44
  const trimmedValue = value?.trim();
79
45
  if (!trimmedValue) {
80
46
  throw new InvalidFilterError('Number filter value cannot be empty');
81
47
  }
82
- // Use a regex to validate proper number format before parsing
83
- // This prevents parseFloat from accepting partial numbers like "42abc" -> 42
84
48
  const numberRegex = /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;
85
49
  if (!numberRegex.test(trimmedValue)) {
86
50
  throw new InvalidFilterError(`Invalid number format: ${value}`);
@@ -95,30 +59,19 @@ export function validateAndParseNumber(value) {
95
59
  }
96
60
  return numValue;
97
61
  }
98
- /**
99
- * Validates and parses a date string in ISO format (YYYY-MM-DD)
100
- *
101
- * @param value - String representation of date in ISO format
102
- * @returns Validated ISO date string
103
- * @throws InvalidDateError if date format is invalid or date doesn't exist
104
- */
105
62
  export function validateAndParseDate(value) {
106
63
  const trimmedValue = value?.trim();
107
64
  if (!trimmedValue) {
108
65
  throw new InvalidDateError('Date filter value cannot be empty');
109
66
  }
110
- // Validate ISO date format (YYYY-MM-DD)
111
67
  const isoDateRegex = /^\d{4}-\d{2}-\d{2}$/;
112
68
  if (!isoDateRegex.test(trimmedValue)) {
113
69
  throw new InvalidDateError(`Invalid date format '${value}'. Expected ISO format YYYY-MM-DD (e.g., 2024-01-15)`);
114
70
  }
115
- // Validate that it's a real date by parsing
116
- const date = new Date(trimmedValue + 'T00:00:00.000Z'); // Force UTC to avoid timezone issues
71
+ const date = new Date(trimmedValue + 'T00:00:00.000Z');
117
72
  if (isNaN(date.getTime())) {
118
73
  throw new InvalidDateError(`Invalid date '${value}'. Date does not exist in the calendar`);
119
74
  }
120
- // Additional validation: ensure the parsed date matches the input
121
- // This catches edge cases like February 30th that might parse differently
122
75
  const [year, month, day] = trimmedValue.split('-').map(Number);
123
76
  if (date.getUTCFullYear() !== year ||
124
77
  date.getUTCMonth() + 1 !== month ||
@@ -127,15 +80,7 @@ export function validateAndParseDate(value) {
127
80
  }
128
81
  return trimmedValue;
129
82
  }
130
- /**
131
- * Validates a date filter value
132
- *
133
- * @param value - The date value to validate
134
- * @param operation - The date filter operation
135
- * @returns Validation result
136
- */
137
83
  export function validateDateFilter(value, operation) {
138
- // Blank operations don't require date validation
139
84
  if (operation === 'blank' || operation === 'notBlank') {
140
85
  return { valid: true };
141
86
  }
@@ -150,18 +95,10 @@ export function validateDateFilter(value, operation) {
150
95
  };
151
96
  }
152
97
  }
153
- /**
154
- * Validates a date range filter
155
- *
156
- * @param startDate - The start date (ISO format)
157
- * @param endDate - The end date (ISO format)
158
- * @returns Validation result
159
- */
160
98
  export function validateDateRange(startDate, endDate) {
161
99
  try {
162
100
  const validStartDate = validateAndParseDate(startDate);
163
101
  const validEndDate = validateAndParseDate(endDate);
164
- // Check that start date <= end date
165
102
  if (validStartDate > validEndDate) {
166
103
  return {
167
104
  valid: false,
@@ -177,12 +114,6 @@ export function validateDateRange(startDate, endDate) {
177
114
  };
178
115
  }
179
116
  }
180
- /**
181
- * Validates a date range from comma-separated string input
182
- *
183
- * @param rangeValue - Comma-separated date range (e.g., "2024-01-01,2024-12-31")
184
- * @returns Tuple of [startDate, endDate] or throws InvalidDateError
185
- */
186
117
  export function validateAndParseDateRange(rangeValue) {
187
118
  const trimmedValue = rangeValue?.trim();
188
119
  if (!trimmedValue) {
@@ -200,25 +131,17 @@ export function validateAndParseDateRange(rangeValue) {
200
131
  }
201
132
  return [startDate, endDate];
202
133
  }
203
- /**
204
- * Validates if an object is a valid column filter
205
- *
206
- * @param obj - The object to validate
207
- * @returns Type guard that narrows the type to ColumnFilter
208
- */
209
134
  export function isValidColumnFilter(obj) {
210
135
  if (!obj || typeof obj !== 'object') {
211
136
  return false;
212
137
  }
213
138
  const filter = obj;
214
- // Check for required properties
215
139
  if (!filter.filterType ||
216
140
  !filter.type ||
217
141
  typeof filter.filterType !== 'string' ||
218
142
  typeof filter.type !== 'string') {
219
143
  return false;
220
144
  }
221
- // Validate based on filter type
222
145
  if (filter.filterType === 'text') {
223
146
  return (typeof filter.filter === 'string' &&
224
147
  TEXT_FILTER_OPERATIONS.includes(filter.type));
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { FilterModel } from 'ag-grid-community';
2
+ /**
3
+ * A saved snapshot of a grid's filters.
4
+ */
5
+ export interface GridView {
6
+ /** Stable generated id */
7
+ id: string;
8
+ /** User-supplied display name */
9
+ name: string;
10
+ /** Epoch millis of the last write */
11
+ updatedAt: number;
12
+ /** AG Grid's native filter model, stored as-is */
13
+ filterModel: FilterModel;
14
+ }
15
+ /**
16
+ * Read/write access to one grid's saved views.
17
+ */
18
+ export interface ViewStore {
19
+ /** All saved views, in save order */
20
+ listViews(): GridView[];
21
+ /** Id of the active view, or null */
22
+ getActiveViewId(): string | null;
23
+ /**
24
+ * Records which view is active.
25
+ *
26
+ * Named `persist…` rather than `set…` so it cannot be mistaken for a React
27
+ * state setter: this writes storage and triggers no re-render.
28
+ *
29
+ * Writing the value the pointer already holds is a no-op, so callers need not
30
+ * check first and a redundant call cannot fail on blocked storage.
31
+ */
32
+ persistActiveViewId(id: string | null): void;
33
+ /**
34
+ * Saves a filter model under a name and makes it active.
35
+ *
36
+ * Names are unique and matched exactly after trimming, so saving over an
37
+ * existing name updates that view in place, keeping its id and its position
38
+ * in the list, rather than adding a duplicate label. That is what gives
39
+ * "load, adjust, re-save" its update semantics without a separate method.
40
+ *
41
+ * A null or undefined filterModel is stored as an empty model, since that is
42
+ * what AG Grid means by it and what getFilterModel returns in practice.
43
+ *
44
+ * @throws when the name is empty, or when the write fails: storage full,
45
+ * blocked by policy, or no DOM present
46
+ */
47
+ saveView(name: string, filterModel: FilterModel): GridView;
48
+ /**
49
+ * Deletes a view, clearing the active id if it pointed at that view.
50
+ *
51
+ * Deleting an id that is not stored is a no-op, so it cannot fail on blocked
52
+ * storage.
53
+ */
54
+ deleteView(id: string): void;
55
+ }
56
+ /**
57
+ * Creates a store bound to one storage key.
58
+ *
59
+ * All reads degrade to an empty store rather than throwing: storage may be
60
+ * absent (SSR), blocked by policy, or hold a corrupt or foreign blob. Writes do
61
+ * throw, so callers can tell the user a view wasn't saved.
62
+ */
63
+ export declare function createViewStore(storageKey: string): ViewStore;
@@ -0,0 +1,112 @@
1
+ const SCHEMA_VERSION = 'v1';
2
+ const keyFor = (storageKey) => `ag-grid-url-sync:views:${SCHEMA_VERSION}:${storageKey}`;
3
+ const empty = () => ({ views: [], activeId: null });
4
+ function isGridView(value) {
5
+ if (typeof value !== 'object' || value === null)
6
+ return false;
7
+ const candidate = value;
8
+ return (typeof candidate.id === 'string' &&
9
+ typeof candidate.name === 'string' &&
10
+ typeof candidate.updatedAt === 'number' &&
11
+ typeof candidate.filterModel === 'object' &&
12
+ candidate.filterModel !== null);
13
+ }
14
+ function createId() {
15
+ if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {
16
+ return crypto.randomUUID();
17
+ }
18
+ return `view-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
19
+ }
20
+ export function createViewStore(storageKey) {
21
+ const key = keyFor(storageKey);
22
+ const read = () => {
23
+ if (typeof window === 'undefined')
24
+ return empty();
25
+ let raw = null;
26
+ try {
27
+ raw = window.localStorage.getItem(key);
28
+ }
29
+ catch {
30
+ return empty();
31
+ }
32
+ if (!raw)
33
+ return empty();
34
+ try {
35
+ const parsed = JSON.parse(raw);
36
+ if (typeof parsed !== 'object' || parsed === null)
37
+ return empty();
38
+ const { views, activeId } = parsed;
39
+ const validViews = Array.isArray(views) ? views.filter(isGridView) : [];
40
+ return {
41
+ views: validViews,
42
+ activeId: typeof activeId === 'string' &&
43
+ validViews.some(view => view.id === activeId)
44
+ ? activeId
45
+ : null
46
+ };
47
+ }
48
+ catch {
49
+ return empty();
50
+ }
51
+ };
52
+ const write = (next) => {
53
+ if (typeof window === 'undefined') {
54
+ throw new Error('Browser storage is unavailable.');
55
+ }
56
+ try {
57
+ window.localStorage.setItem(key, JSON.stringify(next));
58
+ }
59
+ catch (error) {
60
+ const isQuota = typeof DOMException !== 'undefined' &&
61
+ error instanceof DOMException &&
62
+ (error.name === 'QuotaExceededError' ||
63
+ error.name === 'NS_ERROR_DOM_QUOTA_REACHED');
64
+ throw new Error(isQuota
65
+ ? 'Browser storage is full. Delete a saved view and try again.'
66
+ : 'Error writing to storage.', { cause: error });
67
+ }
68
+ };
69
+ return {
70
+ listViews: () => read().views,
71
+ getActiveViewId: () => read().activeId,
72
+ persistActiveViewId: (id) => {
73
+ const current = read();
74
+ if (current.activeId === id)
75
+ return;
76
+ write({ ...current, activeId: id });
77
+ },
78
+ saveView: (name, filterModel) => {
79
+ const trimmedName = name.trim();
80
+ if (!trimmedName) {
81
+ throw new Error('A view name is required.');
82
+ }
83
+ const current = read();
84
+ const existing = current.views.find(view => view.name === trimmedName);
85
+ const view = {
86
+ id: existing?.id ?? createId(),
87
+ name: trimmedName,
88
+ updatedAt: Date.now(),
89
+ filterModel: structuredClone(filterModel ?? {})
90
+ };
91
+ write({
92
+ views: existing
93
+ ? current.views.map(candidate => candidate.id === existing.id ? view : candidate)
94
+ : [...current.views, view],
95
+ activeId: view.id
96
+ });
97
+ return view;
98
+ },
99
+ deleteView: (id) => {
100
+ const current = read();
101
+ const views = current.views.filter(view => view.id !== id);
102
+ if (views.length === current.views.length && current.activeId !== id) {
103
+ return;
104
+ }
105
+ write({
106
+ views,
107
+ activeId: current.activeId === id ? null : current.activeId
108
+ });
109
+ }
110
+ };
111
+ }
112
+ //# sourceMappingURL=view-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-storage.js","sourceRoot":"","sources":["../../src/core/view-storage.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,5 +4,6 @@ export { validateFilterValue, DEFAULT_CONFIG } from './core/validation.js';
4
4
  export { parseUrlFilters, parseFilterParam } from './core/url-parser.js';
5
5
  export { serializeFilters, generateUrl } from './core/url-generator.js';
6
6
  export { getFilterModel, applyFilterModel } from './core/grid-integration.js';
7
+ export type { GridView, ViewStore } from './core/view-storage.js';
7
8
  export { serializeGrouped, deserializeGrouped, detectGroupedSerialization, getAvailableFormats, getFormatSerializer } from './core/serialization/grouped.js';
8
9
  export { QueryStringSerializer, JsonSerializer, Base64Serializer } from './core/serialization/formats.js';
package/dist/index.js CHANGED
@@ -1,15 +1,9 @@
1
- // Export core functionality (vanilla JS)
2
1
  export { AGGridUrlSync, createUrlSync } from './core/ag-grid-url-sync.js';
3
2
  export * from './core/types.js';
4
- // Validation utilities
5
3
  export { validateFilterValue, DEFAULT_CONFIG } from './core/validation.js';
6
- // URL parsing utilities
7
4
  export { parseUrlFilters, parseFilterParam } from './core/url-parser.js';
8
- // URL generation utilities
9
5
  export { serializeFilters, generateUrl } from './core/url-generator.js';
10
- // AG Grid integration utilities
11
6
  export { getFilterModel, applyFilterModel } from './core/grid-integration.js';
12
- // Grouped serialization utilities
13
7
  export { serializeGrouped, deserializeGrouped, detectGroupedSerialization, getAvailableFormats, getFormatSerializer } from './core/serialization/grouped.js';
14
8
  export { QueryStringSerializer, JsonSerializer, Base64Serializer } from './core/serialization/formats.js';
15
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAEzE,cAAc,iBAAiB,CAAA;AAE/B,uBAAuB;AACvB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1E,wBAAwB;AACxB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAExE,2BAA2B;AAC3B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAEvE,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAE7E,kCAAkC;AAClC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EACjB,MAAM,iCAAiC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAEzE,cAAc,iBAAiB,CAAA;AAG/B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAG1E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAGxE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAGvE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAS7E,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EACjB,MAAM,iCAAiC,CAAA"}
@@ -1,3 +1,4 @@
1
1
  export { useAGGridUrlSync } from './use-ag-grid-url-sync.js';
2
2
  export type { UseAGGridUrlSyncOptions, UseAGGridUrlSyncReturn } from './types.js';
3
+ export type { GridView } from '../core/view-storage.js';
3
4
  export type { FilterState, ColumnFilter, FilterOperation, AGGridUrlSyncConfig, GridApi } from '../core/types.js';
@@ -1,15 +1,41 @@
1
1
  import type { AGGridUrlSyncConfig, FilterState, SerializationFormat, SerializationMode } from '../core/types.js';
2
+ import type { GridView } from '../core/view-storage.js';
2
3
  /**
3
4
  * Configuration options for the React hook
4
5
  */
5
6
  export interface UseAGGridUrlSyncOptions extends AGGridUrlSyncConfig {
7
+ /**
8
+ * Enables saved views, persisted to localStorage under this key.
9
+ *
10
+ * The key both switches the feature on and namespaces the storage, so two
11
+ * grids on the same origin must use different keys. Omit it and the view
12
+ * members of the hook's return value are inert.
13
+ *
14
+ * @example 'employee-grid'
15
+ */
16
+ storageKey?: string;
6
17
  /**
7
18
  * Automatically apply URL filters when the component mounts and grid API becomes ready
19
+ *
20
+ * Also restores the active saved view when `storageKey` is set. URL filters
21
+ * take precedence: a shared link should show the sender's filters rather than
22
+ * the recipient's stored view.
23
+ *
24
+ * Attempted once per grid. A failed attempt is reported through `onError` and
25
+ * `onParseError` and is not retried on later renders; pass a new `gridApi`, or
26
+ * call `applyUrlFilters`, to try again.
27
+ *
8
28
  * Default: false
9
29
  */
10
30
  autoApplyOnMount?: boolean;
11
31
  /**
12
32
  * Whether the hook should be enabled when the grid API is ready
33
+ *
34
+ * Set to false and every operation goes inert, saved views included: no URL is
35
+ * generated, no filters are applied, and no view is saved, loaded or deleted.
36
+ * `views` still reflects what is in storage, since reading it has no effect on
37
+ * the grid.
38
+ *
13
39
  * Default: true
14
40
  */
15
41
  enabledWhenReady?: boolean;
@@ -52,7 +78,13 @@ export interface UseAGGridUrlSyncReturn {
52
78
  */
53
79
  currentUrl: string;
54
80
  /**
55
- * Whether the grid has any active text filters
81
+ * Whether the grid has filters that the library supports.
82
+ *
83
+ * Comes from the grid's filter state, not from the URL, because the URL also
84
+ * keeps the page's own params. A filter that the URL cannot carry (for
85
+ * example a text value over `maxValueLength`) still counts, so a "clear
86
+ * filters" button stays enabled. The URL leaves that filter out and reports
87
+ * it through `onParseError`.
56
88
  */
57
89
  hasFilters: boolean;
58
90
  /**
@@ -77,4 +109,74 @@ export interface UseAGGridUrlSyncReturn {
77
109
  * @returns The current format
78
110
  */
79
111
  getCurrentFormat: () => SerializationMode;
112
+ /**
113
+ * Saved views for this grid, in save order.
114
+ * Always an empty array when `storageKey` is not set.
115
+ */
116
+ views: GridView[];
117
+ /**
118
+ * Id of the view currently applied to the grid, or null when none is.
119
+ *
120
+ * This describes the live grid, not what is persisted. A stored view is only
121
+ * applied on mount when `autoApplyOnMount` is set, so with it off this stays
122
+ * null until `loadView` or `saveView` is called, even though a previous
123
+ * session's view is still listed in `views`.
124
+ *
125
+ * It goes back to null as soon as the grid stops showing that view, which
126
+ * includes routes that never mention views: `clearFilters`, `applyFilters`,
127
+ * `applyUrlFilters`, and the user editing a filter in the grid's own UI. That
128
+ * also clears the stored pointer, so `autoApplyOnMount` will not restore the
129
+ * view on the next load either - filtering away from a view is treated as
130
+ * leaving it, not as a detour back to it.
131
+ *
132
+ * "Showing" means the model the grid reported once the view was applied, not
133
+ * the stored one. A view AG Grid normalises on the way in, such as one naming
134
+ * a column the grid no longer has, stays loaded and keeps its stored pointer.
135
+ * A write AG Grid defers is recognised when it lands by the event's
136
+ * `source: 'api'`. On versions that report no source, a deferred view the
137
+ * grid also normalises unloads when it lands.
138
+ *
139
+ * Replacing `gridApi` clears this too, since nothing has been applied to the
140
+ * new grid yet, but leaves the stored pointer alone: with `autoApplyOnMount`
141
+ * the view is restored against the new grid and this becomes non-null again.
142
+ */
143
+ activeViewId: string | null;
144
+ /**
145
+ * Saves the grid's current filters under a name and makes it active.
146
+ *
147
+ * The name is trimmed, and must not be empty. Names are unique: saving over an
148
+ * existing name updates that view in place, keeping its id and list position,
149
+ * so "load a view, adjust the filters, save under the same name" is how you
150
+ * update one.
151
+ *
152
+ * @param name - Display name for the view
153
+ * @returns The saved view, or null if it could not be saved. An empty name, a
154
+ * failed write, and being called before the grid is ready are all reported
155
+ * through `onError`. Silent when `storageKey` is not set or the hook is
156
+ * disabled, since the feature was switched off by configuration rather than
157
+ * having failed.
158
+ */
159
+ saveView: (name: string) => GridView | null;
160
+ /**
161
+ * Applies a saved view's filters to the grid, or clears filters when passed
162
+ * null. Use `clearFilters` to reset filters independently of saved views.
163
+ *
164
+ * Silent when `storageKey` is not set or the hook is disabled; reports through
165
+ * `onError` when called before the grid is ready, or when the id is not found.
166
+ *
167
+ * @param id - Id of the view to load, or null to reset to unfiltered
168
+ */
169
+ loadView: (id: string | null) => void;
170
+ /**
171
+ * Deletes a saved view. Clears the grid's filters only if the grid still shows
172
+ * exactly that view's filters, so hand-edited filters survive.
173
+ *
174
+ * Unlike `saveView` and `loadView`, this does not need the grid: it works
175
+ * before the grid API resolves, since deleting only touches storage, so it
176
+ * never reports a not-ready error. Silent when `storageKey` is not set or the
177
+ * hook is disabled.
178
+ *
179
+ * @param id - Id of the view to delete
180
+ */
181
+ deleteView: (id: string) => void;
80
182
  }