@operato/data-grist 9.0.0-beta.7 → 9.0.0-beta.85

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 (87) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/README.md +337 -44
  3. package/dist/src/data-grid/data-grid-body.js +39 -27
  4. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  5. package/dist/src/data-grid/data-grid-header.js +9 -0
  6. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  7. package/dist/src/data-grist.d.ts +13 -1
  8. package/dist/src/data-grist.js +42 -0
  9. package/dist/src/data-grist.js.map +1 -1
  10. package/dist/src/data-report.js +4 -4
  11. package/dist/src/data-report.js.map +1 -1
  12. package/dist/src/editors/ox-grist-editor-json5.d.ts +8 -0
  13. package/dist/src/editors/ox-grist-editor-json5.js +66 -0
  14. package/dist/src/editors/ox-grist-editor-json5.js.map +1 -0
  15. package/dist/src/editors/ox-popup-code-input.d.ts +14 -0
  16. package/dist/src/editors/ox-popup-code-input.js +78 -0
  17. package/dist/src/editors/ox-popup-code-input.js.map +1 -0
  18. package/dist/src/editors/registry.js +3 -1
  19. package/dist/src/editors/registry.js.map +1 -1
  20. package/dist/src/filters/filter-select.js +2 -1
  21. package/dist/src/filters/filter-select.js.map +1 -1
  22. package/dist/src/formatters/registry.d.ts +1 -1
  23. package/dist/src/gutters/registry.d.ts +1 -1
  24. package/dist/src/handlers/registry.d.ts +1 -1
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +18 -14
  27. package/dist/index.d.ts +0 -1
  28. package/dist/index.js +0 -2
  29. package/dist/index.js.map +0 -1
  30. package/dist/stories/accumulator-format.stories.d.ts +0 -41
  31. package/dist/stories/accumulator-format.stories.js +0 -237
  32. package/dist/stories/accumulator-format.stories.js.map +0 -1
  33. package/dist/stories/barcode-input-filter.stories.d.ts +0 -33
  34. package/dist/stories/barcode-input-filter.stories.js +0 -185
  35. package/dist/stories/barcode-input-filter.stories.js.map +0 -1
  36. package/dist/stories/bounded-select-filters.stories.d.ts +0 -25
  37. package/dist/stories/bounded-select-filters.stories.js +0 -283
  38. package/dist/stories/bounded-select-filters.stories.js.map +0 -1
  39. package/dist/stories/bounded-select-record.stories.d.ts +0 -25
  40. package/dist/stories/bounded-select-record.stories.js +0 -286
  41. package/dist/stories/bounded-select-record.stories.js.map +0 -1
  42. package/dist/stories/click-event-custom.stories.d.ts +0 -45
  43. package/dist/stories/click-event-custom.stories.js +0 -248
  44. package/dist/stories/click-event-custom.stories.js.map +0 -1
  45. package/dist/stories/click-event.stories.d.ts +0 -45
  46. package/dist/stories/click-event.stories.js +0 -243
  47. package/dist/stories/click-event.stories.js.map +0 -1
  48. package/dist/stories/creatable-only-column.stories.d.ts +0 -29
  49. package/dist/stories/creatable-only-column.stories.js +0 -232
  50. package/dist/stories/creatable-only-column.stories.js.map +0 -1
  51. package/dist/stories/default-filters.stories.d.ts +0 -26
  52. package/dist/stories/default-filters.stories.js +0 -219
  53. package/dist/stories/default-filters.stories.js.map +0 -1
  54. package/dist/stories/dynamic-editable.stories.d.ts +0 -25
  55. package/dist/stories/dynamic-editable.stories.js +0 -293
  56. package/dist/stories/dynamic-editable.stories.js.map +0 -1
  57. package/dist/stories/empty-sorters.stories.d.ts +0 -25
  58. package/dist/stories/empty-sorters.stories.js +0 -162
  59. package/dist/stories/empty-sorters.stories.js.map +0 -1
  60. package/dist/stories/explicit-fetch.stories.d.ts +0 -25
  61. package/dist/stories/explicit-fetch.stories.js +0 -166
  62. package/dist/stories/explicit-fetch.stories.js.map +0 -1
  63. package/dist/stories/fixed-column.stories.d.ts +0 -26
  64. package/dist/stories/fixed-column.stories.js +0 -383
  65. package/dist/stories/fixed-column.stories.js.map +0 -1
  66. package/dist/stories/grid-setting.stories.d.ts +0 -47
  67. package/dist/stories/grid-setting.stories.js +0 -453
  68. package/dist/stories/grid-setting.stories.js.map +0 -1
  69. package/dist/stories/grist-modes.stories.d.ts +0 -37
  70. package/dist/stories/grist-modes.stories.js +0 -416
  71. package/dist/stories/grist-modes.stories.js.map +0 -1
  72. package/dist/stories/group-header.stories.d.ts +0 -26
  73. package/dist/stories/group-header.stories.js +0 -410
  74. package/dist/stories/group-header.stories.js.map +0 -1
  75. package/dist/stories/record-view.stories.d.ts +0 -24
  76. package/dist/stories/record-view.stories.js +0 -125
  77. package/dist/stories/record-view.stories.js.map +0 -1
  78. package/dist/stories/textarea.stories.d.ts +0 -37
  79. package/dist/stories/textarea.stories.js +0 -229
  80. package/dist/stories/textarea.stories.js.map +0 -1
  81. package/dist/stories/tree-column-with-checkbox.stories.d.ts +0 -26
  82. package/dist/stories/tree-column-with-checkbox.stories.js +0 -267
  83. package/dist/stories/tree-column-with-checkbox.stories.js.map +0 -1
  84. package/dist/stories/tree-column.stories.d.ts +0 -26
  85. package/dist/stories/tree-column.stories.js +0 -266
  86. package/dist/stories/tree-column.stories.js.map +0 -1
  87. package/index.ts +0 -1
package/README.md CHANGED
@@ -1,95 +1,388 @@
1
- # \<data-grist>
1
+ # Data-Grist
2
2
 
3
- This webcomponent follows the [open-wc](https://github.com/open-wc/open-wc) recommendation.
3
+ Data-Grist is a powerful web component for displaying and manipulating data. It can present data in Grid, List, or Card formats and provides various features such as data sorting, filtering, editing, and more.
4
+
5
+ ## Key Features
6
+
7
+ - **Multiple Display Modes**: Flexibly display the same data in grid, list, or card formats
8
+ - **Data Manipulation**: Add, modify, and delete records
9
+ - **Sorting and Filtering**: Single/multi-column sorting, various filtering options
10
+ - **Editing Capabilities**: Inline cell editing, validation
11
+ - **Pagination**: Standard paging and infinite scroll support
12
+ - **Selection**: Single/multiple record selection
13
+ - **State Tracking**: Track changed (dirty) records
14
+ - **Customization**: Support for various renderers, editors, and event handlers
15
+ - **Mobile Responsive**: Responsive design support
4
16
 
5
17
  ## Installation
6
18
 
7
19
  ```bash
8
- npm i data-grist
20
+ npm install @operato/data-grist
9
21
  ```
10
22
 
11
- ## Usage
23
+ ## Basic Usage
12
24
 
13
25
  ```html
14
26
  <script type="module">
15
- import 'data-grist/data-grist.js';
27
+ import '@operato/data-grist/ox-grist.js'
16
28
  </script>
17
29
 
18
- <data-grist></data-grist>
30
+ <ox-grist
31
+ .mode=${'GRID'}
32
+ .config=${gridConfig}
33
+ .fetchHandler=${fetchDataFunction}
34
+ ></ox-grist>
19
35
  ```
20
36
 
21
- ## Linting with ESLint, Prettier, and Types
37
+ ## Modes
22
38
 
23
- To scan the project for linting errors, run
39
+ Data-Grist supports three display modes:
24
40
 
25
- ```bash
26
- npm run lint
41
+ - **GRID**: Tabular data display (default)
42
+ - **LIST**: Mobile-friendly list format display
43
+ - **CARD**: Card format display
44
+
45
+ ```javascript
46
+ // Set mode
47
+ gristElement.mode = 'GRID' // or 'LIST', 'CARD'
27
48
  ```
28
49
 
29
- You can lint with ESLint and Prettier individually as well
50
+ ## Configuration (Config)
51
+
52
+ Data-Grist provides various configuration options.
53
+
54
+ ```javascript
55
+ const config = {
56
+ columns: [
57
+ {
58
+ type: 'string',
59
+ name: 'name',
60
+ header: 'Name',
61
+ record: {
62
+ editable: true
63
+ },
64
+ sortable: true,
65
+ width: 150
66
+ }
67
+ // More columns...
68
+ ],
69
+ rows: {
70
+ appendable: true, // Allow adding new records
71
+ editable: true, // Allow editing records
72
+ selectable: {
73
+ // Record selection settings
74
+ multiple: true // Allow multiple selections
75
+ }
76
+ },
77
+ pagination: {
78
+ infinite: false, // Use paging instead of infinite scroll
79
+ page: 1, // Starting page
80
+ limit: 20 // Records per page
81
+ }
82
+ // Additional settings...
83
+ }
84
+ ```
30
85
 
31
- ```bash
32
- npm run lint:eslint
86
+ ### Column Types
87
+
88
+ ```javascript
89
+ // String column
90
+ {
91
+ type: 'string',
92
+ name: 'firstName',
93
+ header: 'First Name'
94
+ }
95
+
96
+ // Number column
97
+ {
98
+ type: 'number',
99
+ name: 'age',
100
+ header: 'Age',
101
+ record: {
102
+ align: 'right'
103
+ }
104
+ }
105
+
106
+ // Boolean column
107
+ {
108
+ type: 'boolean',
109
+ name: 'isActive',
110
+ header: 'Active'
111
+ }
112
+
113
+ // Link column
114
+ {
115
+ type: 'link',
116
+ name: 'website',
117
+ header: 'Website',
118
+ record: {
119
+ options: {
120
+ href: (column, record) => record.url,
121
+ target: '_blank'
122
+ }
123
+ }
124
+ }
125
+
126
+ // Gutter column (row number, checkbox, button, etc.)
127
+ {
128
+ type: 'gutter',
129
+ gutterName: 'sequence' // 'row-selector', 'button', 'dirty', etc.
130
+ }
33
131
  ```
34
132
 
35
- ```bash
36
- npm run lint:prettier
133
+ ## Fetching Data
134
+
135
+ Data can be retrieved through the `fetchHandler` function.
136
+
137
+ ```javascript
138
+ const fetchHandler = async params => {
139
+ const { page, limit, sorters, filters } = params
140
+
141
+ // Fetch data from server
142
+ const response = await fetch(`/api/data?page=${page}&limit=${limit}`)
143
+ const data = await response.json()
144
+
145
+ return {
146
+ total: data.total,
147
+ records: data.items
148
+ }
149
+ }
150
+
151
+ // Configure the grist
152
+ gristElement.fetchHandler = fetchHandler
37
153
  ```
38
154
 
39
- To automatically fix many linting errors, run
155
+ ## Record Manipulation API
40
156
 
41
- ```bash
42
- npm run format
157
+ ### Adding Records
158
+
159
+ ```javascript
160
+ // Add record at the end (default)
161
+ gristElement.addRecord({
162
+ name: 'John Doe',
163
+ age: 30
164
+ })
165
+
166
+ // Add record at the top
167
+ gristElement.addRecordToTop({
168
+ name: 'Jane Smith',
169
+ age: 25
170
+ })
43
171
  ```
44
172
 
45
- You can format using ESLint and Prettier individually as well
173
+ ### Record Selection
46
174
 
47
- ```bash
48
- npm run format:eslint
175
+ ```javascript
176
+ // Get all selected records
177
+ const selectedRecords = gristElement.selected
178
+
179
+ // Set selection
180
+ gristElement.selected = [record1, record2]
181
+
182
+ // Select records using a selector function
183
+ gristElement.select(record => record.age > 30)
49
184
  ```
50
185
 
51
- ```bash
52
- npm run format:prettier
186
+ ### Tracking Changed Records
187
+
188
+ ```javascript
189
+ // Get modified records
190
+ const dirtyRecords = gristElement.dirtyRecords
191
+
192
+ // Check for changes
193
+ gristElement.checkDirties()
194
+
195
+ // Export changes as patches
196
+ const patches = gristElement.exportPatchList()
53
197
  ```
54
198
 
55
- ## Testing with Web Test Runner
199
+ ## Events
56
200
 
57
- To run the suite of Web Test Runner tests, run
201
+ Data-Grist triggers various events.
58
202
 
59
- ```bash
60
- npm run test
203
+ ```javascript
204
+ // Record selection change event
205
+ gristElement.addEventListener('select-record-change', e => {
206
+ const { records, added, removed } = e.detail
207
+ console.log('Selected records:', records)
208
+ })
209
+
210
+ // Field change event
211
+ gristElement.addEventListener('field-change', e => {
212
+ const { after, before, column, record, row } = e.detail
213
+ console.log('Changed field:', column.name, 'from', before, 'to', after)
214
+ })
215
+
216
+ // Record change event
217
+ gristElement.addEventListener('record-change', e => {
218
+ const { before, after, column, row } = e.detail
219
+ console.log('Record changed:', row)
220
+ })
61
221
  ```
62
222
 
63
- To run the tests in watch mode (for &lt;abbr title=&#34;test driven development&#34;&gt;TDD&lt;/abbr&gt;, for example), run
223
+ ## Advanced Features
64
224
 
65
- ```bash
66
- npm run test:watch
225
+ ### Column Accumulation Feature (Accumulator)
226
+
227
+ ```javascript
228
+ {
229
+ type: 'number',
230
+ name: 'amount',
231
+ header: 'Amount',
232
+ accumulator: 'sum' // 'avg', 'count', 'min', 'max' or custom function
233
+ }
67
234
  ```
68
235
 
69
- ## Demoing with Storybook
236
+ ### Tree Structure Data
70
237
 
71
- To run a local instance of Storybook for your component, run
238
+ ```javascript
239
+ const config = {
240
+ // ...
241
+ tree: {
242
+ childrenProperty: 'children', // Property name where child nodes are stored
243
+ expanded: true // Initial tree expansion state
244
+ }
245
+ }
246
+ ```
72
247
 
73
- ```bash
74
- npm run storybook
248
+ ### Grouped Headers
249
+
250
+ ```javascript
251
+ const config = {
252
+ columns: [
253
+ // ...
254
+ {
255
+ type: 'string',
256
+ name: 'firstName',
257
+ header: 'First Name',
258
+ group: 'personalInfo'
259
+ },
260
+ {
261
+ type: 'string',
262
+ name: 'lastName',
263
+ header: 'Last Name',
264
+ group: 'personalInfo'
265
+ }
266
+ ],
267
+ // ...
268
+ rows: {
269
+ // ...
270
+ groups: [
271
+ {
272
+ name: 'personalInfo',
273
+ title: 'Personal Information'
274
+ }
275
+ ]
276
+ }
277
+ }
75
278
  ```
76
279
 
77
- To build a production version of Storybook, run
280
+ ### User Settings Storage
281
+
282
+ ```javascript
283
+ // Configure user settings provider
284
+ gristElement.personalConfigProvider = {
285
+ async load() {
286
+ // Load saved settings
287
+ return JSON.parse(localStorage.getItem('userGristConfig'))
288
+ },
289
+ async save(preference) {
290
+ // Save user settings
291
+ localStorage.setItem('userGristConfig', JSON.stringify(preference))
292
+ }
293
+ }
294
+ ```
78
295
 
79
- ```bash
80
- npm run storybook:build
296
+ ## Styling
297
+
298
+ Data-Grist can be styled through CSS variables.
299
+
300
+ ```css
301
+ ox-grist {
302
+ --grid-header-background-color: #f5f5f5;
303
+ --grid-record-background-color: white;
304
+ --grid-record-odd-background-color: #f9f9f9;
305
+ --grid-header-color: #333;
306
+ --grid-record-hover-background-color: #e9e9e9;
307
+ }
81
308
  ```
82
309
 
83
- ## Tooling configs
310
+ ## API Reference
311
+
312
+ ### Properties
313
+
314
+ | Property | Type | Description |
315
+ | ----------------- | -------- | ------------------------------------- |
316
+ | `mode` | string | Display mode ('GRID', 'LIST', 'CARD') |
317
+ | `config` | object | Grist configuration object |
318
+ | `data` | object | Data to display |
319
+ | `selectedRecords` | array | Array of selected records |
320
+ | `explicitFetch` | boolean | Enable explicit data fetching |
321
+ | `fetchHandler` | function | Data fetching function |
322
+ | `fetchOptions` | object | Data fetching options |
323
+ | `filters` | array | Array of filters |
324
+ | `sorters` | array | Array of sorters |
325
+ | `pagination` | object | Pagination settings |
326
+
327
+ ### Methods
328
+
329
+ | Method | Description |
330
+ | ------------------------------ | ------------------------------- |
331
+ | `fetch(reset)` | Fetch data |
332
+ | `addRecord(record)` | Add a record |
333
+ | `addRecordToTop(record)` | Add a record at the top |
334
+ | `deleteSelectedRecords(dirty)` | Delete selected records |
335
+ | `cloneSelectedRecords()` | Clone selected records |
336
+ | `checkDirties()` | Check for modified records |
337
+ | `undo()` | Undo last action |
338
+ | `redo()` | Redo undone action |
339
+ | `reset()` | Reset data |
340
+ | `commit()` | Commit changes |
341
+ | `select(selector, reset)` | Select records using a function |
342
+ | `exportPatchList(options)` | Export list of change patches |
343
+ | `exportRecords(options)` | Export record data |
344
+
345
+ ## Examples
346
+
347
+ ### Basic Grid
84
348
 
85
- For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
349
+ ```html
350
+ <ox-grist
351
+ .mode=${'GRID'}
352
+ .config=${gridConfig}
353
+ .fetchHandler=${fetchData}
354
+ @record-change=${handleRecordChange}
355
+ ></ox-grist>
356
+ ```
86
357
 
87
- If you customize the configuration a lot, you can consider moving them to individual files.
358
+ ### Editable Grid
88
359
 
89
- ## Local Demo with `web-dev-server`
360
+ ```html
361
+ <ox-grist
362
+ .mode=${'GRID'}
363
+ .config=${{
364
+ columns: [/* column definitions */],
365
+ rows: {
366
+ appendable: true,
367
+ editable: true,
368
+ selectable: { multiple: true }
369
+ }
370
+ }}
371
+ .data=${{ records: initialData }}
372
+ ></ox-grist>
373
+ ```
90
374
 
91
- ```bash
92
- npm start
375
+ ### Add Row to Top Button
376
+
377
+ ```html
378
+ <button @click="${() => gristRef.addRecordToTop()}">Add Row to Top</button>
379
+ <ox-grist id="my-grist"></ox-grist>
380
+
381
+ <script>
382
+ const gristRef = document.getElementById('my-grist')
383
+ </script>
93
384
  ```
94
385
 
95
- To run a local development server that serves the basic demo located in `demo/index.html`
386
+ ## License
387
+
388
+ MIT
@@ -459,40 +459,43 @@ let DataGridBody = class DataGridBody extends LitElement {
459
459
  }
460
460
  const cells = record.querySelectorAll('td');
461
461
  cells.forEach((item, columnIndex) => {
462
- var _a;
463
462
  const targetColumn = columns[column + columnIndex];
464
- var value = (_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim();
463
+ let value = item.textContent;
464
+ // let value = item.textContent?.trim() as any
465
465
  let type = targetColumn.type || item.getAttribute('type') || 'string';
466
466
  type = type.includes('object') ? 'object' : type; // 오브젝트 타입 예외처리
467
467
  let { editable } = targetColumn.record;
468
468
  if (typeof editable === 'function') {
469
469
  editable = editable.call(this, value, targetColumn, targetRecord, row, this);
470
470
  }
471
- switch (type) {
472
- case 'object':
473
- case 'parameters':
474
- try {
475
- value = JSON.parse(value || 'null');
476
- }
477
- catch (err) { }
478
- break;
479
- case 'boolean':
480
- case 'checkbox':
481
- value = !!value && !!String(value).match(/true/i);
482
- break;
483
- case 'number':
484
- case 'float':
485
- case 'integer':
486
- case 'progress':
487
- value = parseToNumberOrNull(value);
488
- break;
489
- default:
490
- try {
491
- value = JSON.parse(value);
492
- }
493
- catch (err) {
494
- value = value;
495
- }
471
+ if (value) {
472
+ switch (type) {
473
+ case 'object':
474
+ case 'parameters':
475
+ try {
476
+ value = JSON.parse(value || 'null');
477
+ }
478
+ catch (err) { }
479
+ break;
480
+ case 'boolean':
481
+ case 'checkbox':
482
+ value = !!value && !!String(value).match(/true/i);
483
+ break;
484
+ case 'number':
485
+ case 'float':
486
+ case 'integer':
487
+ case 'progress':
488
+ value = parseToNumberOrNull(value);
489
+ break;
490
+ default:
491
+ try {
492
+ value = JSON.parse(value);
493
+ }
494
+ catch (err) { }
495
+ }
496
+ }
497
+ else {
498
+ value = undefined; /* default value 로 설정되도록 하기위해서 undefined로 설정. */
496
499
  }
497
500
  if (targetColumn && !targetColumn.gutterName && editable) {
498
501
  this.dispatchEvent(new CustomEvent('field-change', {
@@ -618,6 +621,15 @@ DataGridBody.styles = [
618
621
  ox-grid-accum-field[fixed] {
619
622
  background-color: var(--md-sys-color-primary-container);
620
623
  }
624
+
625
+ @media (max-width: 768px) {
626
+ /* 모바일에서는 그리드에서 고정된 열 해제 */
627
+ [fixed] {
628
+ position: static;
629
+ z-index: 0;
630
+ box-shadow: none !important;
631
+ }
632
+ }
621
633
  `
622
634
  ];
623
635
  __decorate([