ag-grid-url-sync 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +407 -43
  2. package/dist/{ag-grid-url-sync.js → core/ag-grid-url-sync.js} +4 -2
  3. package/dist/core/ag-grid-url-sync.js.map +1 -0
  4. package/dist/core/grid-integration.d.ts +9 -0
  5. package/dist/core/grid-integration.js +66 -0
  6. package/dist/core/grid-integration.js.map +1 -0
  7. package/dist/core/index.d.ts +6 -0
  8. package/dist/core/index.js +11 -0
  9. package/dist/core/index.js.map +1 -0
  10. package/dist/core/types.d.ts +112 -0
  11. package/dist/core/types.js +79 -0
  12. package/dist/core/types.js.map +1 -0
  13. package/dist/core/url-generator.d.ts +9 -0
  14. package/dist/core/url-generator.js +42 -0
  15. package/dist/core/url-generator.js.map +1 -0
  16. package/dist/core/url-parser.d.ts +9 -0
  17. package/dist/core/url-parser.js +85 -0
  18. package/dist/core/url-parser.js.map +1 -0
  19. package/dist/core/validation.d.ts +18 -0
  20. package/dist/core/validation.js +28 -0
  21. package/dist/core/validation.js.map +1 -0
  22. package/dist/index.d.ts +6 -3
  23. package/dist/index.js +11 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/react/index.d.ts +3 -0
  26. package/dist/react/index.js +2 -0
  27. package/dist/react/index.js.map +1 -0
  28. package/dist/react/types.d.ts +64 -0
  29. package/dist/react/types.js +2 -0
  30. package/dist/react/types.js.map +1 -0
  31. package/dist/react/use-ag-grid-url-sync.d.ts +10 -0
  32. package/dist/react/use-ag-grid-url-sync.js +215 -0
  33. package/dist/react/use-ag-grid-url-sync.js.map +1 -0
  34. package/package.json +95 -6
  35. package/dist/ag-grid-url-sync.js.map +0 -1
  36. package/dist/types.d.ts +0 -69
  37. package/dist/types.js +0 -31
  38. package/dist/types.js.map +0 -1
  39. package/dist/utils.d.ts +0 -36
  40. package/dist/utils.js +0 -188
  41. package/dist/utils.js.map +0 -1
  42. /package/dist/{ag-grid-url-sync.d.ts → core/ag-grid-url-sync.d.ts} +0 -0
package/README.md CHANGED
@@ -6,10 +6,11 @@ A lightweight TypeScript library for synchronizing AG Grid text filters with URL
6
6
 
7
7
  ## Features
8
8
 
9
- - 🔍 Text filter synchronization (`contains` and `equals` operations)
9
+ - 🔍 **Complete text filter support** - All 8 AG Grid text operations (contains, equals, not contains, not equal, starts with, ends with, blank, not blank)
10
10
  - 🔗 Manual URL generation for sharing filter states
11
11
  - ↔️ Bidirectional sync between grid and URL
12
12
  - 🛠️ Framework agnostic - works with any AG Grid setup
13
+ - ⚛️ **React hook** - dedicated `useAGGridUrlSync` with state management
13
14
  - 📝 Full TypeScript support with strict mode compliance
14
15
  - 🚦 Graceful error handling with configurable error callbacks
15
16
  - 🧹 Clean, human-readable URL format
@@ -18,6 +19,58 @@ A lightweight TypeScript library for synchronizing AG Grid text filters with URL
18
19
  - 🛡️ Robust edge case handling (special characters, malformed URLs)
19
20
  - 📦 Lightweight bundle size (~3KB gzipped)
20
21
 
22
+ ## Supported Filter Types
23
+
24
+ Supports **all AG Grid text filter operations** (8 total) with clean, human-readable URL parameters:
25
+
26
+ | Filter Type | Operation | URL Format | Example | Description |
27
+ | ----------- | ------------ | ---------------------------- | -------------------------- | --------------------------- |
28
+ | **Text** | Contains | `f_column_contains=value` | `f_name_contains=john` | Text contains value |
29
+ | **Text** | Equals | `f_column_eq=value` | `f_status_eq=active` | Text equals value exactly |
30
+ | **Text** | Not Contains | `f_column_notContains=value` | `f_name_notContains=spam` | Text does not contain value |
31
+ | **Text** | Not Equal | `f_column_neq=value` | `f_status_neq=inactive` | Text does not equal value |
32
+ | **Text** | Starts With | `f_column_startsWith=value` | `f_email_startsWith=admin` | Text starts with value |
33
+ | **Text** | Ends With | `f_column_endsWith=value` | `f_file_endsWith=.pdf` | Text ends with value |
34
+ | **Text** | Blank | `f_column_blank=true` | `f_optional_blank=true` | Field is empty/null |
35
+ | **Text** | Not Blank | `f_column_notBlank=true` | `f_required_notBlank=true` | Field has any value |
36
+
37
+ > **💡 Naming Convention Note**: URL parameters use short, clean names for better readability (`eq` for equals, `neq` for not equal). These are automatically converted to the proper AG Grid operation names (`equals`, `notEqual`) internally. This design keeps URLs concise while maintaining full compatibility with AG Grid's filter API.
38
+
39
+ ### Filter Detection
40
+
41
+ The library automatically works with:
42
+
43
+ - Columns configured with `filter: 'agTextColumnFilter'`
44
+ - Columns with `filter: true` (AG Grid's default text filter)
45
+ - Any column where users apply text-based filters
46
+ - All AG Grid text filter operations through the filter menu
47
+
48
+ ### URL Examples
49
+
50
+ **Simple filter:**
51
+
52
+ ```
53
+ https://app.com/data?f_name_contains=john
54
+ ```
55
+
56
+ **Multiple operations:**
57
+
58
+ ```
59
+ https://app.com/data?f_name_contains=john&f_department_eq=Engineering&f_email_startsWith=admin&f_status_neq=inactive
60
+ ```
61
+
62
+ **Complex filtering with all operations:**
63
+
64
+ ```
65
+ https://app.com/data?f_name_contains=john&f_email_startsWith=admin&f_status_neq=inactive&f_description_endsWith=test&f_optional_blank=true&f_required_notBlank=true&f_tags_notContains=spam&f_title_eq=manager
66
+ ```
67
+
68
+ **Blank operations:**
69
+
70
+ ```
71
+ https://app.com/data?f_comments_blank=true&f_name_notBlank=true
72
+ ```
73
+
21
74
  ## Installation
22
75
 
23
76
  ```bash
@@ -26,6 +79,96 @@ npm install ag-grid-url-sync
26
79
 
27
80
  ## Usage
28
81
 
82
+ ### Importing the Library
83
+
84
+ The library provides two main entry points:
85
+
86
+ ```typescript
87
+ // Core functionality - works with any framework
88
+ import { createUrlSync } from 'ag-grid-url-sync'
89
+
90
+ // React hook - for React applications
91
+ import { useAGGridUrlSync } from 'ag-grid-url-sync/react'
92
+
93
+ // TypeScript types (available from both imports)
94
+ import type { FilterState, AGGridUrlSyncConfig } from 'ag-grid-url-sync'
95
+ ```
96
+
97
+ ### Tree-Shaking & Granular Imports
98
+
99
+ For optimal bundle sizes, you can import only the specific utilities you need:
100
+
101
+ ```typescript
102
+ import {
103
+ validateFilterValue,
104
+ DEFAULT_CONFIG
105
+ } from 'ag-grid-url-sync/validation'
106
+
107
+ import { parseUrlFilters, parseFilterParam } from 'ag-grid-url-sync/url-parser'
108
+
109
+ import { serializeFilters, generateUrl } from 'ag-grid-url-sync/url-generator'
110
+
111
+ import {
112
+ getFilterModel,
113
+ applyFilterModel
114
+ } from 'ag-grid-url-sync/grid-integration'
115
+
116
+ import type {
117
+ FilterState,
118
+ ColumnFilter,
119
+ FilterOperation
120
+ } from 'ag-grid-url-sync/types'
121
+ ```
122
+
123
+ #### Bundle Size Comparison
124
+
125
+ | Import Pattern | Bundle Size | Use Case |
126
+ | ---------------- | ----------- | ---------------------- |
127
+ | Full library | 5KB | Complete functionality |
128
+ | Core class only | 3.2KB | Basic URL sync |
129
+ | React hook only | 7KB | React applications |
130
+ | URL parsing only | 1.05KB | Parse existing URLs |
131
+ | Validation only | 318B | Input validation |
132
+ | Types only | 0B | TypeScript types |
133
+
134
+ #### Example: Custom URL Parser
135
+
136
+ ```typescript
137
+ import { parseUrlFilters } from 'ag-grid-url-sync/url-parser'
138
+ import { DEFAULT_CONFIG } from 'ag-grid-url-sync/validation'
139
+ import type { FilterState } from 'ag-grid-url-sync/types'
140
+
141
+ function getFiltersFromUrl(url: string): FilterState {
142
+ const config = {
143
+ gridApi: null, // Not needed for parsing
144
+ ...DEFAULT_CONFIG,
145
+ onParseError: error => console.error('Parse error:', error)
146
+ }
147
+
148
+ return parseUrlFilters(url, config)
149
+ }
150
+ ```
151
+
152
+ #### Example: Custom URL Generator
153
+
154
+ ```typescript
155
+ import { generateUrl, serializeFilters } from 'ag-grid-url-sync/url-generator'
156
+ import type { FilterState } from 'ag-grid-url-sync/types'
157
+
158
+ function createShareableUrl(filters: FilterState, baseUrl: string): string {
159
+ const config = {
160
+ gridApi: null, // Not needed for generation
161
+ paramPrefix: 'f_',
162
+ maxValueLength: 200,
163
+ onParseError: () => {}
164
+ }
165
+
166
+ return generateUrl(baseUrl, filters, config)
167
+ }
168
+ ```
169
+
170
+ **💡 Pro Tip**: Use granular imports in libraries and applications where bundle size matters. All existing import patterns remain fully supported for backward compatibility.
171
+
29
172
  ### Basic Example
30
173
 
31
174
  ```typescript
@@ -44,40 +187,257 @@ urlSync.applyFromUrl()
44
187
  urlSync.clearFilters()
45
188
  ```
46
189
 
47
- ### React Integration
190
+ ## React Integration
191
+
192
+ For React applications, use the dedicated `useAGGridUrlSync` hook that provides a complete solution with React-specific features and state management.
193
+
194
+ ### Installation for React
195
+
196
+ ```bash
197
+ npm install ag-grid-url-sync
198
+ ```
199
+
200
+ ### Basic React Usage
48
201
 
49
202
  ```tsx
50
- import { createUrlSync } from 'ag-grid-url-sync'
51
- import { useCallback, useMemo } from 'react'
203
+ import React, { useState } from 'react'
204
+ import { AgGridReact } from 'ag-grid-react'
205
+ import { useAGGridUrlSync } from 'ag-grid-url-sync/react'
206
+
207
+ function GridComponent() {
208
+ const [gridApi, setGridApi] = useState(null)
209
+
210
+ const {
211
+ shareUrl,
212
+ applyUrlFilters,
213
+ clearFilters,
214
+ hasFilters,
215
+ isReady,
216
+ currentUrl
217
+ } = useAGGridUrlSync(gridApi, {
218
+ autoApplyOnMount: true,
219
+ paramPrefix: 'filter_'
220
+ })
221
+
222
+ const handleShare = async () => {
223
+ const url = shareUrl()
224
+ await navigator.clipboard.writeText(url)
225
+ alert('Filter URL copied!')
226
+ }
52
227
 
53
- function useGridUrlSync(gridApi) {
54
- const urlSync = useMemo(
55
- () => (gridApi ? createUrlSync(gridApi) : null),
56
- [gridApi]
228
+ return (
229
+ <div>
230
+ <div style={{ marginBottom: '10px' }}>
231
+ <button onClick={handleShare} disabled={!isReady}>
232
+ 📋 Share Filters
233
+ </button>
234
+ <button onClick={clearFilters} disabled={!hasFilters}>
235
+ 🗑️ Clear Filters
236
+ </button>
237
+ <button onClick={applyUrlFilters}>🔄 Apply URL Filters</button>
238
+ </div>
239
+
240
+ <div className="ag-theme-alpine" style={{ height: 400, width: '100%' }}>
241
+ <AgGridReact
242
+ onGridReady={params => setGridApi(params.api)}
243
+ rowData={rowData}
244
+ columnDefs={columnDefs}
245
+ defaultColDef={{
246
+ filter: 'agTextColumnFilter',
247
+ floatingFilter: true
248
+ }}
249
+ />
250
+ </div>
251
+ </div>
57
252
  )
253
+ }
254
+ ```
58
255
 
59
- const shareUrl = useCallback(() => urlSync?.generateUrl() || '', [urlSync])
256
+ ### React Router Integration
60
257
 
61
- const applyUrlFilters = useCallback(() => urlSync?.applyFromUrl(), [urlSync])
258
+ For single-page applications using React Router, you can sync filters with the browser URL:
62
259
 
63
- return { shareUrl, applyUrlFilters }
64
- }
260
+ ```tsx
261
+ import React, { useState } from 'react'
262
+ import { useNavigate, useLocation } from 'react-router-dom'
263
+ import { useAGGridUrlSync } from 'ag-grid-url-sync/react'
264
+
265
+ function RouterGridComponent() {
266
+ const [gridApi, setGridApi] = useState(null)
267
+ const navigate = useNavigate()
268
+ const location = useLocation()
269
+
270
+ const { shareUrl, clearFilters, hasFilters, isReady } = useAGGridUrlSync(
271
+ gridApi,
272
+ {
273
+ autoApplyOnMount: true, // Automatically apply filters from URL on mount
274
+ paramPrefix: 'f_'
275
+ }
276
+ )
65
277
 
66
- // In your component
67
- function GridComponent() {
68
- const { shareUrl, applyUrlFilters } = useGridUrlSync(gridApi)
278
+ // Update browser URL with current filters
279
+ const updateUrlWithFilters = () => {
280
+ const url = shareUrl()
281
+ const urlParams = new URL(url).searchParams
282
+ const currentParams = new URLSearchParams(location.search)
283
+
284
+ // Clear existing filter params
285
+ for (const [key] of currentParams) {
286
+ if (key.startsWith('f_')) {
287
+ currentParams.delete(key)
288
+ }
289
+ }
290
+
291
+ // Add current filter params
292
+ for (const [key, value] of urlParams) {
293
+ currentParams.set(key, value)
294
+ }
295
+
296
+ navigate(`${location.pathname}?${currentParams.toString()}`, {
297
+ replace: true
298
+ })
299
+ }
69
300
 
70
301
  return (
71
302
  <div>
72
- <button
73
- onClick={() => {
74
- const url = shareUrl()
75
- navigator.clipboard.writeText(url)
76
- }}
77
- >
78
- Share Filters
303
+ <button onClick={updateUrlWithFilters} disabled={!isReady}>
304
+ Update URL with Filters
79
305
  </button>
80
- <button onClick={applyUrlFilters}>Apply URL Filters</button>
306
+ <button onClick={clearFilters} disabled={!hasFilters}>
307
+ Clear All Filters
308
+ </button>
309
+ {/* Grid component */}
310
+ </div>
311
+ )
312
+ }
313
+ ```
314
+
315
+ ### React Hook API
316
+
317
+ #### `useAGGridUrlSync(gridApi, options?)`
318
+
319
+ ```tsx
320
+ import { useAGGridUrlSync } from 'ag-grid-url-sync/react'
321
+
322
+ const {
323
+ shareUrl,
324
+ getQueryParams,
325
+ applyUrlFilters,
326
+ clearFilters,
327
+ isReady,
328
+ currentUrl,
329
+ hasFilters,
330
+ parseUrlFilters,
331
+ applyFilters
332
+ } = useAGGridUrlSync(gridApi, options)
333
+ ```
334
+
335
+ #### Hook Options
336
+
337
+ ```tsx
338
+ interface UseAGGridUrlSyncOptions {
339
+ // Core options (same as createUrlSync)
340
+ paramPrefix?: string // Default: 'f_'
341
+ maxValueLength?: number // Default: 200
342
+ onParseError?: (error: Error) => void
343
+
344
+ // React-specific options
345
+ autoApplyOnMount?: boolean // Default: false
346
+ enabledWhenReady?: boolean // Default: true
347
+ }
348
+ ```
349
+
350
+ #### Hook Return Values
351
+
352
+ | Property | Type | Description |
353
+ | ----------------- | -------------------------------- | ----------------------------------------------- |
354
+ | `shareUrl` | `(baseUrl?: string) => string` | Generate shareable URL with current filters |
355
+ | `getQueryParams` | `() => string` | Get filter state as query parameters |
356
+ | `applyUrlFilters` | `(url?: string) => void` | Apply filters from URL to grid |
357
+ | `clearFilters` | `() => void` | Clear all text filters |
358
+ | `isReady` | `boolean` | Whether grid API is available and hook is ready |
359
+ | `currentUrl` | `string` | Current URL with filters applied |
360
+ | `hasFilters` | `boolean` | Whether grid has any active text filters |
361
+ | `parseUrlFilters` | `(url: string) => FilterState` | Parse filters from URL without applying |
362
+ | `applyFilters` | `(filters: FilterState) => void` | Apply filter state object to grid |
363
+
364
+ ### React Features
365
+
366
+ - **🔄 Automatic State Management**: Tracks grid state and filter changes automatically
367
+ - **⚡ Ready State**: `isReady` indicates when the grid API is available
368
+ - **🎯 Auto-Apply**: `autoApplyOnMount` applies URL filters when component mounts
369
+ - **🧹 Cleanup**: Automatically cleans up resources when component unmounts
370
+ - **🛡️ Error Boundaries**: Graceful error handling with configurable callbacks
371
+ - **📊 Filter Status**: `hasFilters` tracks whether any filters are active
372
+
373
+ ### Advanced React Example
374
+
375
+ ```tsx
376
+ import React, { useState, useEffect } from 'react'
377
+ import { useAGGridUrlSync } from 'ag-grid-url-sync/react'
378
+
379
+ function AdvancedGridComponent() {
380
+ const [gridApi, setGridApi] = useState(null)
381
+ const [shareMessage, setShareMessage] = useState('')
382
+
383
+ const {
384
+ shareUrl,
385
+ applyUrlFilters,
386
+ clearFilters,
387
+ hasFilters,
388
+ isReady,
389
+ currentUrl,
390
+ parseUrlFilters
391
+ } = useAGGridUrlSync(gridApi, {
392
+ autoApplyOnMount: true,
393
+ paramPrefix: 'emp_',
394
+ maxValueLength: 100,
395
+ onParseError: error => {
396
+ console.warn('Filter parsing error:', error.message)
397
+ setShareMessage('Invalid filter URL detected')
398
+ }
399
+ })
400
+
401
+ // Watch for URL changes
402
+ useEffect(() => {
403
+ if (currentUrl !== window.location.href) {
404
+ setShareMessage('Filters have changed - URL ready to share')
405
+ }
406
+ }, [currentUrl])
407
+
408
+ const handleShareToEmail = () => {
409
+ const url = shareUrl()
410
+ const subject = 'Check out this filtered data'
411
+ const body = `View the filtered data here: ${url}`
412
+ window.open(
413
+ `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`
414
+ )
415
+ }
416
+
417
+ const handlePreviewFilters = () => {
418
+ const url = prompt('Enter URL to preview filters:')
419
+ if (url) {
420
+ const filters = parseUrlFilters(url)
421
+ console.log('Parsed filters:', filters)
422
+ alert(`Found ${Object.keys(filters).length} filter(s)`)
423
+ }
424
+ }
425
+
426
+ return (
427
+ <div>
428
+ <div className="controls">
429
+ <button onClick={handleShareToEmail} disabled={!isReady}>
430
+ 📧 Share via Email
431
+ </button>
432
+ <button onClick={handlePreviewFilters}>👁️ Preview URL Filters</button>
433
+ <button onClick={clearFilters} disabled={!hasFilters}>
434
+ Clear ({hasFilters ? 'has filters' : 'no filters'})
435
+ </button>
436
+ </div>
437
+
438
+ {shareMessage && <div className="message">{shareMessage}</div>}
439
+
440
+ {/* Grid component */}
81
441
  </div>
82
442
  )
83
443
  }
@@ -203,35 +563,39 @@ interface AGGridUrlSyncConfig {
203
563
 
204
564
  Check out the [examples](./examples) directory for comprehensive working demos:
205
565
 
206
- ### 📝 [Basic Example](./examples/basic-example.html)
566
+ ### 🚀 [Vanilla JavaScript Demo](./examples/vanilla-js/demo.html)
207
567
 
208
- Simple HTML/JS implementation showing core functionality:
568
+ Comprehensive demonstration showcasing all features:
209
569
 
210
- - Initialize URL sync with AG Grid
211
- - Generate shareable URLs
212
- - Apply filters from URLs
213
- - Handle filter changes
570
+ - **Complete text filter support** - All 8 AG Grid text operations (contains, equals, not contains, not equal, starts with, ends with, blank, not blank)
571
+ - **Filter scenarios** - Pre-configured examples (Sales team, Engineering, Executive view, etc.)
572
+ - **New operation demos** - Dedicated buttons for startsWith, endsWith, and notContains filters
573
+ - **URL sharing workflow** - Copy to clipboard, email, and Slack integration
574
+ - **Performance monitoring** - Real-time benchmarks and stress testing
575
+ - **Error handling** - Malformed URL and invalid filter testing
576
+ - **Complete API showcase** - Generate URLs, apply filters, clear filters
214
577
 
215
- ### 🚀 [Advanced Demo](./examples/advanced-demo.html)
578
+ ### ⚛️ [React Integration](./examples/react-basic/basic-grid.tsx)
216
579
 
217
- Feature-rich demonstration including:
580
+ Clean React component showing the `useAGGridUrlSync` hook:
218
581
 
219
- - Performance monitoring and benchmarks
220
- - Multiple filter scenarios (Sales, Engineering, Executive views)
221
- - URL sharing workflow with copy/email/Slack functionality
222
- - Error testing with malformed URLs and invalid filters
223
- - Memory and stress testing capabilities
582
+ - React hook integration with AG Grid
583
+ - Automatic filter state management
584
+ - Share button with clipboard functionality
585
+ - Filter status indicators and controls
586
+ - Auto-apply filters on component mount
587
+ - Full TypeScript support
224
588
 
225
- ### 🔗 [Multi-Grid Demo](./examples/multi-grid-demo.html)
589
+ ### 📊 [Shared Data](./examples/shared-data.js)
226
590
 
227
- Complex example with multiple independent grids:
591
+ Common data and column definitions used across examples:
228
592
 
229
- - Four separate grids (Employees, Projects, Departments, Metrics)
230
- - Individual URL namespacing with different prefixes
231
- - Combined URL generation merging all grid states
232
- - Independent grid controls and clearing functions
593
+ - Employee data with realistic company information
594
+ - Project data with status and priority fields
595
+ - Column definitions with complete text filter support
596
+ - All 8 text filter operations enabled by default
233
597
 
234
- All examples work out-of-the-box by opening the HTML files in your browser.
598
+ All examples work out-of-the-box and demonstrate the complete functionality. The HTML demo can be opened directly in your browser, while the React example shows clean integration patterns.
235
599
 
236
600
  ## Contributing
237
601
 
@@ -1,5 +1,7 @@
1
- import { DEFAULT_CONFIG } from './utils.js';
2
- import { parseUrlFilters, generateUrl, getFilterModel, applyFilterModel } from './utils.js';
1
+ import { DEFAULT_CONFIG } from './validation.js';
2
+ import { parseUrlFilters } from './url-parser.js';
3
+ import { generateUrl } from './url-generator.js';
4
+ import { getFilterModel, applyFilterModel } from './grid-integration.js';
3
5
  /**
4
6
  * AGGridUrlSync class for synchronizing AG Grid text filters with URL parameters
5
7
  */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-grid-url-sync.js","sourceRoot":"","sources":["../../src/core/ag-grid-url-sync.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExE;;GAEG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgB;IAE9B;;;;OAIG;IACH,YAAY,OAAgB,EAAE,SAA8B,EAAE;QAC5D,IAAI,CAAC,MAAM,GAAG;YACZ,OAAO;YACP,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,cAAc,CAAC,WAAW;YAC7D,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,cAAc,CAAC,cAAc;YACtE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;SAChD,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,OAAgB;QAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/C,MAAM,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAA;QAC3C,OAAO,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACnD,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,OAAO,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,GAAY;QACvB,MAAM,UAAU,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAA;QAC9C,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5D,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,WAAwB;QACnC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,2DAA2D;IAC7D,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,MAA4B;IAE5B,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { FilterState, InternalConfig } from './types.js';
2
+ /**
3
+ * Gets the current filter model from AG Grid
4
+ */
5
+ export declare function getFilterModel(config: InternalConfig): FilterState;
6
+ /**
7
+ * Applies a filter state to AG Grid
8
+ */
9
+ export declare function applyFilterModel(filterState: FilterState, config: InternalConfig): void;
@@ -0,0 +1,66 @@
1
+ import { AG_GRID_OPERATION_NAMES, REVERSE_AG_GRID_OPERATION_NAMES } from './types.js';
2
+ /**
3
+ * Gets the current filter model from AG Grid
4
+ */
5
+ export function getFilterModel(config) {
6
+ try {
7
+ const model = config.gridApi.getFilterModel();
8
+ const filterState = {};
9
+ if (!model || typeof model !== 'object') {
10
+ return filterState;
11
+ }
12
+ for (const [column, filter] of Object.entries(model)) {
13
+ if (!filter || typeof filter !== 'object')
14
+ continue;
15
+ const { filterType, type, filter: value } = filter;
16
+ if (filterType !== 'text')
17
+ continue;
18
+ // Map AG Grid operations back to our internal operations using centralized mapping
19
+ const internalOperation = REVERSE_AG_GRID_OPERATION_NAMES[type];
20
+ if (internalOperation) {
21
+ filterState[column] = {
22
+ filterType: 'text',
23
+ type: internalOperation,
24
+ filter: value || ''
25
+ };
26
+ }
27
+ }
28
+ return filterState;
29
+ }
30
+ catch (error) {
31
+ if (config.onParseError) {
32
+ config.onParseError(error);
33
+ }
34
+ return {};
35
+ }
36
+ }
37
+ /**
38
+ * Applies a filter state to AG Grid
39
+ */
40
+ export function applyFilterModel(filterState, config) {
41
+ try {
42
+ const model = {};
43
+ for (const [column, filter] of Object.entries(filterState)) {
44
+ if (filter &&
45
+ typeof filter === 'object' &&
46
+ filter.filterType === 'text') {
47
+ // Convert our internal operation to AG Grid operation using centralized mapping
48
+ const agGridOperation = AG_GRID_OPERATION_NAMES[filter.type];
49
+ if (agGridOperation) {
50
+ model[column] = {
51
+ filterType: filter.filterType,
52
+ type: agGridOperation,
53
+ filter: filter.filter
54
+ };
55
+ }
56
+ }
57
+ }
58
+ config.gridApi.setFilterModel(model);
59
+ }
60
+ catch (error) {
61
+ if (config.onParseError) {
62
+ config.onParseError(error);
63
+ }
64
+ }
65
+ }
66
+ //# sourceMappingURL=grid-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-integration.js","sourceRoot":"","sources":["../../src/core/grid-integration.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAChC,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAA;QAC7C,MAAM,WAAW,GAAgB,EAAE,CAAA;QAEnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;gBAAE,SAAQ;YAEnD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAa,CAAA;YACzD,IAAI,UAAU,KAAK,MAAM;gBAAE,SAAQ;YAEnC,mFAAmF;YACnF,MAAM,iBAAiB,GACrB,+BAA+B,CAC7B,IAAoD,CACrD,CAAA;YAEH,IAAI,iBAAiB,EAAE,CAAC;gBACtB,WAAW,CAAC,MAAM,CAAC,GAAG;oBACpB,UAAU,EAAE,MAAM;oBAClB,IAAI,EAAE,iBAAoC;oBAC1C,MAAM,EAAE,KAAK,IAAI,EAAE;iBACpB,CAAA;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAA;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,MAAM,CAAC,YAAY,CAAC,KAAc,CAAC,CAAA;QACrC,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,WAAwB,EACxB,MAAsB;IAEtB,IAAI,CAAC;QACH,MAAM,KAAK,GAAQ,EAAE,CAAA;QAErB,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3D,IACE,MAAM;gBACN,OAAO,MAAM,KAAK,QAAQ;gBAC1B,MAAM,CAAC,UAAU,KAAK,MAAM,EAC5B,CAAC;gBACD,gFAAgF;gBAChF,MAAM,eAAe,GACnB,uBAAuB,CACrB,MAAM,CAAC,IAA4C,CACpD,CAAA;gBACH,IAAI,eAAe,EAAE,CAAC;oBACpB,KAAK,CAAC,MAAM,CAAC,GAAG;wBACd,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,IAAI,EAAE,eAAe;wBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;qBACtB,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,MAAM,CAAC,YAAY,CAAC,KAAc,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { AGGridUrlSync, createUrlSync } from './ag-grid-url-sync.js';
2
+ export * from './types.js';
3
+ export { validateFilterValue, DEFAULT_CONFIG } from './validation.js';
4
+ export { parseUrlFilters, parseFilterParam } from './url-parser.js';
5
+ export { serializeFilters, generateUrl } from './url-generator.js';
6
+ export { getFilterModel, applyFilterModel } from './grid-integration.js';
@@ -0,0 +1,11 @@
1
+ export { AGGridUrlSync, createUrlSync } from './ag-grid-url-sync.js';
2
+ export * from './types.js';
3
+ // Validation utilities
4
+ export { validateFilterValue, DEFAULT_CONFIG } from './validation.js';
5
+ // URL parsing utilities
6
+ export { parseUrlFilters, parseFilterParam } from './url-parser.js';
7
+ // URL generation utilities
8
+ export { serializeFilters, generateUrl } from './url-generator.js';
9
+ // AG Grid integration utilities
10
+ export { getFilterModel, applyFilterModel } from './grid-integration.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,cAAc,YAAY,CAAA;AAE1B,uBAAuB;AACvB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErE,wBAAwB;AACxB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEnE,2BAA2B;AAC3B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAElE,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}