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.
- package/README.md +144 -14
- package/dist/core/ag-grid-url-sync.d.ts +13 -0
- package/dist/core/ag-grid-url-sync.js +10 -55
- package/dist/core/ag-grid-url-sync.js.map +1 -1
- package/dist/core/grid-integration.js +5 -67
- package/dist/core/grid-integration.js.map +1 -1
- package/dist/core/index.js +0 -5
- package/dist/core/index.js.map +1 -1
- package/dist/core/individual-params.d.ts +19 -0
- package/dist/core/individual-params.js +260 -0
- package/dist/core/individual-params.js.map +1 -0
- package/dist/core/serialization/formats.d.ts +8 -9
- package/dist/core/serialization/formats.js +63 -65
- package/dist/core/serialization/formats.js.map +1 -1
- package/dist/core/serialization/grouped.d.ts +10 -5
- package/dist/core/serialization/grouped.js +4 -51
- package/dist/core/serialization/grouped.js.map +1 -1
- package/dist/core/serialization/index.js +0 -4
- package/dist/core/serialization/index.js.map +1 -1
- package/dist/core/types.d.ts +42 -9
- package/dist/core/types.js +0 -118
- package/dist/core/types.js.map +1 -1
- package/dist/core/url-generator.d.ts +10 -7
- package/dist/core/url-generator.js +25 -165
- package/dist/core/url-generator.js.map +1 -1
- package/dist/core/url-parser.d.ts +19 -7
- package/dist/core/url-parser.js +28 -294
- package/dist/core/url-parser.js.map +1 -1
- package/dist/core/validation.d.ts +6 -6
- package/dist/core/validation.js +1 -78
- package/dist/core/validation.js.map +1 -1
- package/dist/core/view-storage.d.ts +63 -0
- package/dist/core/view-storage.js +112 -0
- package/dist/core/view-storage.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +0 -6
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/types.d.ts +103 -1
- package/dist/react/use-ag-grid-url-sync.js +406 -46
- package/dist/react/use-ag-grid-url-sync.js.map +1 -1
- package/package.json +98 -31
package/dist/core/validation.js
CHANGED
|
@@ -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
|
-
|
|
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":"AAQA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAKnB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,GAAG;IACnB,aAAa,EAAE,YAAqB;IACpC,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,aAAsB;IAC9B,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;CACd,CAAA;AAqBV,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAmB,EACnB,SAA2B;IAG3B,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QACtD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QACzC,MAAM,IAAI,kBAAkB,CAC1B,0CAA0C,MAAM,CAAC,cAAc,aAAa,CAC7E,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAQD,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAEhD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAA;IACxE,CAAC;IAGD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC9C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAA;IAC3E,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACxB,CAAC;AASD,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,GAAW;IAEX,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC3C,IAAI,CAAC,SAAS,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAEtC,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC3C,IAAI,CAAC,SAAS,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAEtC,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACd,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,qDAAqD;SAC7D,CAAA;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACxB,CAAC;AAQD,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,MAAM,YAAY,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IAClC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,kBAAkB,CAAC,qCAAqC,CAAC,CAAA;IACrE,CAAC;IAID,MAAM,WAAW,GAAG,yCAAyC,CAAA;IAC7D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,kBAAkB,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;IACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,kBAAkB,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAA;IACjD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,kBAAkB,CAAC,UAAU,CAAC,KAAK,IAAI,sBAAsB,CAAC,CAAA;IAC1E,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AASD,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,YAAY,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IAClC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,gBAAgB,CAAC,mCAAmC,CAAC,CAAA;IACjE,CAAC;IAGD,MAAM,YAAY,GAAG,qBAAqB,CAAA;IAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,gBAAgB,CACxB,wBAAwB,KAAK,sDAAsD,CACpF,CAAA;IACH,CAAC;IAGD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,YAAY,GAAG,gBAAgB,CAAC,CAAA;IACtD,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,gBAAgB,CACxB,iBAAiB,KAAK,wCAAwC,CAC/D,CAAA;IACH,CAAC;IAID,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9D,IACE,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI;QAC9B,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,KAAK;QAChC,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,EACzB,CAAC;QACD,MAAM,IAAI,gBAAgB,CACxB,iBAAiB,KAAK,8CAA8C,CACrE,CAAA;IACH,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AASD,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,SAA8B;IAG9B,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;SAC/D,CAAA;IACH,CAAC;AACH,CAAC;AASD,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAA;QACtD,MAAM,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;QAGlD,IAAI,cAAc,GAAG,YAAY,EAAE,CAAC;YAClC,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,mCAAmC,SAAS,0CAA0C,OAAO,GAAG;aACxG,CAAA;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB;SACrE,CAAA;IACH,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,yBAAyB,CACvC,UAAkB;IAElB,MAAM,YAAY,GAAG,UAAU,EAAE,IAAI,EAAE,CAAA;IACvC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,gBAAgB,CAAC,kCAAkC,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,gBAAgB,CACxB,8FAA8F,CAC/F,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACnE,MAAM,OAAO,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAEjE,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC7D,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,gBAAgB,CAAC,eAAe,CAAC,KAAK,IAAI,oBAAoB,CAAC,CAAA;IAC3E,CAAC;IAED,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;AAC7B,CAAC;AAQD,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,MAAM,GAAG,GAAU,CAAA;IAGzB,IACE,CAAC,MAAM,CAAC,UAAU;QAClB,CAAC,MAAM,CAAC,IAAI;QACZ,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;QACrC,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAC/B,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAGD,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACjC,OAAO,CACL,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;YACjC,sBAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAA2B,CAAC,CACpE,CAAA;IACH,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,CACL,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;YACjC,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAA6B,CAAC;YACvE,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CACvE,CAAA;IACH,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACjC,OAAO,CACL,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;YACjC,sBAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAA2B,CAAC;YACnE,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CACvE,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -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":"
|
|
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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/react/types.d.ts
CHANGED
|
@@ -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
|
|
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
|
}
|