@operato/data-grist 8.0.0-beta.0 → 8.0.0-beta.2

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 (168) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +10 -10
  3. package/.storybook/main.js +0 -3
  4. package/.storybook/preview.js +0 -52
  5. package/.storybook/server.mjs +0 -8
  6. package/demo/data-grist-test.html +0 -468
  7. package/demo/favicon.ico +0 -0
  8. package/demo/index.html +0 -541
  9. package/demo/report-test.html +0 -249
  10. package/src/accumulator/accumulator.ts +0 -63
  11. package/src/configure/column-builder.ts +0 -114
  12. package/src/configure/config-builder.ts +0 -40
  13. package/src/configure/filters-option-builder.ts +0 -8
  14. package/src/configure/imex-option-builder.ts +0 -5
  15. package/src/configure/list-option-builder.ts +0 -9
  16. package/src/configure/rows-option-builder.ts +0 -38
  17. package/src/configure/tree-option-builder.ts +0 -22
  18. package/src/configure/zero-config.ts +0 -83
  19. package/src/const.ts +0 -1
  20. package/src/data-card/data-card-field.ts +0 -94
  21. package/src/data-card/data-card-gutter-menu.ts +0 -94
  22. package/src/data-card/data-card-gutter.ts +0 -103
  23. package/src/data-card/data-card.ts +0 -154
  24. package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
  25. package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
  26. package/src/data-card/record-card.ts +0 -298
  27. package/src/data-consumer.ts +0 -11
  28. package/src/data-grid/data-grid-accum-field.ts +0 -109
  29. package/src/data-grid/data-grid-body-style.ts +0 -85
  30. package/src/data-grid/data-grid-body.ts +0 -765
  31. package/src/data-grid/data-grid-field.ts +0 -227
  32. package/src/data-grid/data-grid-footer.ts +0 -119
  33. package/src/data-grid/data-grid-header.ts +0 -578
  34. package/src/data-grid/data-grid.ts +0 -293
  35. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
  36. package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
  37. package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
  38. package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
  39. package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
  40. package/src/data-grist.ts +0 -1233
  41. package/src/data-list/data-list-field.ts +0 -82
  42. package/src/data-list/data-list-gutter.ts +0 -108
  43. package/src/data-list/data-list.ts +0 -145
  44. package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
  45. package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
  46. package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
  47. package/src/data-list/record-partial.ts +0 -264
  48. package/src/data-manipulator.ts +0 -426
  49. package/src/data-provider.ts +0 -271
  50. package/src/data-report/data-report-body-style.ts +0 -58
  51. package/src/data-report/data-report-body.ts +0 -189
  52. package/src/data-report/data-report-component.ts +0 -138
  53. package/src/data-report/data-report-field.ts +0 -83
  54. package/src/data-report/data-report-header.ts +0 -242
  55. package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
  56. package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
  57. package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
  58. package/src/data-report.ts +0 -424
  59. package/src/editors/index.ts +0 -4
  60. package/src/editors/ox-grist-editor-checkbox.ts +0 -28
  61. package/src/editors/ox-grist-editor-color.ts +0 -10
  62. package/src/editors/ox-grist-editor-date.ts +0 -10
  63. package/src/editors/ox-grist-editor-datetime.ts +0 -27
  64. package/src/editors/ox-grist-editor-email.ts +0 -10
  65. package/src/editors/ox-grist-editor-file.ts +0 -28
  66. package/src/editors/ox-grist-editor-image.ts +0 -31
  67. package/src/editors/ox-grist-editor-month.ts +0 -10
  68. package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
  69. package/src/editors/ox-grist-editor-number.ts +0 -27
  70. package/src/editors/ox-grist-editor-password.ts +0 -10
  71. package/src/editors/ox-grist-editor-select.ts +0 -55
  72. package/src/editors/ox-grist-editor-tel.ts +0 -10
  73. package/src/editors/ox-grist-editor-text.ts +0 -14
  74. package/src/editors/ox-grist-editor-textarea.ts +0 -16
  75. package/src/editors/ox-grist-editor-time.ts +0 -10
  76. package/src/editors/ox-grist-editor-tree.ts +0 -27
  77. package/src/editors/ox-grist-editor-varname.ts +0 -36
  78. package/src/editors/ox-grist-editor-week.ts +0 -10
  79. package/src/editors/ox-grist-editor.ts +0 -207
  80. package/src/editors/ox-input-tree.ts +0 -226
  81. package/src/editors/registry.ts +0 -82
  82. package/src/empty-note.ts +0 -46
  83. package/src/filters/filter-checkbox.ts +0 -49
  84. package/src/filters/filter-input-barcode.ts +0 -34
  85. package/src/filters/filter-input.ts +0 -30
  86. package/src/filters/filter-range-date.ts +0 -81
  87. package/src/filters/filter-range-number.ts +0 -64
  88. package/src/filters/filter-select-buttons.ts +0 -60
  89. package/src/filters/filter-select.ts +0 -68
  90. package/src/filters/filter-styles.ts +0 -119
  91. package/src/filters/filters-form.ts +0 -476
  92. package/src/filters/index.ts +0 -10
  93. package/src/filters/registry.ts +0 -56
  94. package/src/formatters/date-formatter.ts +0 -3
  95. package/src/formatters/index.ts +0 -1
  96. package/src/formatters/number-formatter.ts +0 -3
  97. package/src/formatters/registry.ts +0 -30
  98. package/src/formatters/text-formatter.ts +0 -3
  99. package/src/gutters/gutter-button.ts +0 -51
  100. package/src/gutters/gutter-dirty.ts +0 -96
  101. package/src/gutters/gutter-row-selector.ts +0 -89
  102. package/src/gutters/gutter-sequence.ts +0 -54
  103. package/src/gutters/index.ts +0 -1
  104. package/src/gutters/registry.ts +0 -32
  105. package/src/handlers/contextmenu-tree-mutation.ts +0 -80
  106. package/src/handlers/index.ts +0 -1
  107. package/src/handlers/move-down.ts +0 -44
  108. package/src/handlers/move-up.ts +0 -44
  109. package/src/handlers/record-copy.ts +0 -38
  110. package/src/handlers/record-delete.ts +0 -30
  111. package/src/handlers/record-view-handler.ts +0 -27
  112. package/src/handlers/registry.ts +0 -42
  113. package/src/handlers/select-row-toggle.ts +0 -30
  114. package/src/handlers/select-row.ts +0 -27
  115. package/src/index.ts +0 -17
  116. package/src/personalizer/index.ts +0 -1
  117. package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
  118. package/src/personalizer/ox-grist-personalizer.ts +0 -226
  119. package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
  120. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
  121. package/src/record-view/index.ts +0 -2
  122. package/src/record-view/ox-record-creator.ts +0 -289
  123. package/src/record-view/record-view-body.ts +0 -257
  124. package/src/record-view/record-view-handler.ts +0 -86
  125. package/src/record-view/record-view.ts +0 -122
  126. package/src/renderers/index.ts +0 -14
  127. package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
  128. package/src/renderers/ox-grist-renderer-color.ts +0 -15
  129. package/src/renderers/ox-grist-renderer-date.ts +0 -62
  130. package/src/renderers/ox-grist-renderer-file.ts +0 -31
  131. package/src/renderers/ox-grist-renderer-image.ts +0 -27
  132. package/src/renderers/ox-grist-renderer-json5.ts +0 -36
  133. package/src/renderers/ox-grist-renderer-link.ts +0 -17
  134. package/src/renderers/ox-grist-renderer-password.ts +0 -7
  135. package/src/renderers/ox-grist-renderer-progress.ts +0 -45
  136. package/src/renderers/ox-grist-renderer-select.ts +0 -58
  137. package/src/renderers/ox-grist-renderer-text.ts +0 -16
  138. package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
  139. package/src/renderers/ox-grist-renderer-tree.ts +0 -189
  140. package/src/renderers/ox-grist-renderer.ts +0 -35
  141. package/src/renderers/registry.ts +0 -111
  142. package/src/sorters/sorters-control.ts +0 -143
  143. package/src/types.ts +0 -813
  144. package/src/utils/index.ts +0 -2
  145. package/src/utils/list-param.ts +0 -72
  146. package/src/utils/supports-passive.ts +0 -13
  147. package/stories/accumulator-format.stories.ts +0 -276
  148. package/stories/barcode-input-filter.stories.ts +0 -216
  149. package/stories/bounded-select-filters.stories.ts +0 -333
  150. package/stories/bounded-select-record.stories.ts +0 -336
  151. package/stories/click-event-custom.stories.ts +0 -287
  152. package/stories/click-event.stories.ts +0 -283
  153. package/stories/creatable-only-column.stories.ts +0 -253
  154. package/stories/default-filters.stories.ts +0 -241
  155. package/stories/dynamic-editable.stories.ts +0 -313
  156. package/stories/empty-sorters.stories.ts +0 -180
  157. package/stories/explicit-fetch.stories.ts +0 -186
  158. package/stories/fixed-column.stories.ts +0 -416
  159. package/stories/grid-setting.stories.ts +0 -501
  160. package/stories/grist-modes.stories.ts +0 -451
  161. package/stories/group-header.stories.ts +0 -442
  162. package/stories/record-view.stories.ts +0 -143
  163. package/stories/textarea.stories.ts +0 -261
  164. package/stories/tree-column-with-checkbox.stories.ts +0 -297
  165. package/stories/tree-column.stories.ts +0 -296
  166. package/tsconfig.json +0 -26
  167. package/web-dev-server.config.mjs +0 -27
  168. package/web-test-runner.config.mjs +0 -45
@@ -1,426 +0,0 @@
1
- import { LitElement, PropertyValues } from 'lit'
2
- import { property } from 'lit/decorators.js'
3
-
4
- import { ZERO_CONFIG, ZERO_DATA } from './configure/zero-config'
5
- import {
6
- ColumnConfig,
7
- FilterValue,
8
- GristConfig,
9
- GristData,
10
- GristRecord,
11
- PaginationConfig,
12
- SortersConfig
13
- } from './types'
14
-
15
- export class DataManipulator extends LitElement {
16
- @property({ type: Object }) config: GristConfig = ZERO_CONFIG
17
- @property({ type: Object }) data: GristData = ZERO_DATA
18
- @property({ type: Array }) sorters: SortersConfig = []
19
- @property({ type: Array }) filters: FilterValue[] = []
20
- @property({ type: Object }) pagination: PaginationConfig = {}
21
-
22
- constructor() {
23
- super()
24
-
25
- this.addEventListener('select-record-change', async e => {
26
- var {
27
- records: selectedRecords,
28
- added = [],
29
- removed = []
30
- } = (e as CustomEvent).detail as {
31
- records: GristRecord[]
32
- added: GristRecord[]
33
- removed: GristRecord[]
34
- }
35
-
36
- this.onSelectRecordChanged({
37
- selectedRecords,
38
- added,
39
- removed
40
- })
41
- })
42
-
43
- /* field change processing */
44
- this.addEventListener('field-change', async e => {
45
- var { after, before, column, record, row } = (e as CustomEvent).detail as {
46
- after: any
47
- before: any
48
- column: ColumnConfig
49
- record: GristRecord
50
- row: number
51
- }
52
-
53
- await this.onFieldChange({ after, before, column, record, row })
54
- })
55
-
56
- /* record reset processing */
57
- this.addEventListener('record-reset', e => {
58
- var { record, row } = (e as CustomEvent).detail as {
59
- record: GristRecord
60
- row: number
61
- }
62
-
63
- this.onRecordChanged(record['__origin__'], row, null)
64
- })
65
-
66
- /* tree processing */
67
- this.addEventListener('collapse-all', (e: Event) => this.collapseAll())
68
- this.addEventListener('expand-all', (e: Event) => this.expandAll())
69
- this.addEventListener('collapse-node', (e: Event) => this.collapseNode((e as CustomEvent).detail as GristRecord))
70
- this.addEventListener('expand-node', (e: Event) => this.expandNode((e as CustomEvent).detail as GristRecord))
71
- this.addEventListener('check-in-tree', (e: Event) => this.onCheckInTree(e as CustomEvent))
72
-
73
- this.addEventListener('add-sibling-node', (e: Event) =>
74
- this.addSiblingNode((e as CustomEvent).detail as GristRecord)
75
- )
76
- this.addEventListener('add-child-node', (e: Event) => this.addChildNode((e as CustomEvent).detail as GristRecord))
77
- }
78
-
79
- async onFieldChange({
80
- after,
81
- before,
82
- column,
83
- record,
84
- row
85
- }: {
86
- after: any
87
- before: any
88
- column: ColumnConfig
89
- record: GristRecord
90
- row: number
91
- }) {
92
- /* compare changes */
93
- if (after === before) {
94
- return
95
- }
96
-
97
- var validation = column.validation
98
- if (validation && typeof validation == 'function') {
99
- if (!(await validation.call(this, after, before, record, column))) {
100
- return
101
- }
102
- }
103
-
104
- this.onRecordChanged({ [column.name]: after }, row, column)
105
- }
106
-
107
- onSelectRecordChanged({
108
- selectedRecords,
109
- added = [],
110
- removed = []
111
- }: {
112
- selectedRecords: GristRecord[]
113
- added: GristRecord[]
114
- removed: GristRecord[]
115
- }) {
116
- var { records } = this.data || {}
117
- var { selectable = false } = this.config.rows || {}
118
-
119
- if (!records || !selectable) {
120
- return
121
- }
122
-
123
- if (selectable && !selectable.multiple) {
124
- records.forEach(record => (record['__selected__'] = false))
125
- }
126
-
127
- if (selectedRecords) {
128
- records.forEach(record => (record['__selected__'] = false))
129
- selectedRecords.forEach(record => (record['__selected__'] = true))
130
- } else {
131
- removed.forEach(record => (record['__selected__'] = false))
132
- added.forEach(record => (record['__selected__'] = true))
133
- }
134
-
135
- this.requestUpdate()
136
- }
137
-
138
- onRecordChanged(
139
- recordData: GristRecord,
140
- row: number,
141
- column: ColumnConfig | null /* TODO column should be removed */
142
- ) {
143
- // TODO 오브젝트나 배열 타입인 경우 deepCompare 후에 변경 적용 여부를 결정한다.
144
-
145
- /* 빈 그리드로 시작한 경우, data 설정이 되어있지 않을 수 있다. */
146
- var records = this.data.records
147
-
148
- var beforeRecord = records[row]
149
- var afterRecord: GristRecord
150
- var wantToDelete = false
151
- var wantToAppend = false
152
-
153
- if (!recordData) {
154
- if (!beforeRecord) {
155
- /* recordData가 없고, beforeRecord도 없다면, 레코드 생성 중에 리셋된 경우이므로 아무것도 하지 않는다. */
156
- this.requestUpdate()
157
- return
158
- } else {
159
- /*
160
- * beforeRecord가 있는데, 빈데이타로 업데이트하고자 한다면,
161
- * 삭제하고자 하는 의도로 이해된다. (주의 필요)
162
- */
163
- if (beforeRecord['__dirty__'] == '+') {
164
- wantToDelete = true
165
- } else {
166
- afterRecord = {
167
- ...beforeRecord,
168
- __dirty__: '-'
169
- }
170
- }
171
- }
172
- } else {
173
- if (!beforeRecord) {
174
- /* 기존 레코드가 없는 경우에는 새로운 레코드가 생성된다 */
175
- afterRecord = {
176
- ...recordData,
177
- __dirty__: '+'
178
- }
179
-
180
- wantToAppend = true
181
- } else {
182
- let beforeDirty = beforeRecord['__dirty__']
183
- if (beforeDirty == '+') {
184
- /* 기존에 새로 생성된 레코드가 있었으며 계속 수정중이다.(레코드 레퍼런스를 유지해야한다) */
185
- afterRecord = Object.assign(beforeRecord, recordData, { __dirty__: '+' })
186
- } else {
187
- /* 기존에 레코드가 있었으며 계속 수정중이다.(레코드 레퍼런스를 유지해야한다) */
188
- afterRecord = Object.assign(beforeRecord, recordData, { __dirty__: 'M' })
189
- }
190
- }
191
- }
192
-
193
- if (wantToAppend) {
194
- records.push(afterRecord!)
195
- } else if (wantToDelete) {
196
- records.splice(row, 1)
197
- } else {
198
- records.splice(row, 1, afterRecord!)
199
- }
200
-
201
- this.dispatchEvent(
202
- new CustomEvent('record-change', {
203
- bubbles: true,
204
- composed: true,
205
- detail: {
206
- before: beforeRecord,
207
- after: afterRecord!,
208
- column,
209
- row
210
- }
211
- })
212
- )
213
-
214
- this.requestUpdate()
215
- }
216
-
217
- collapseAll() {
218
- this.refresh(false)
219
- }
220
-
221
- expandAll() {
222
- this.refresh(true)
223
- }
224
-
225
- collapseNode(record: GristRecord) {
226
- record.__expanded__ = false
227
-
228
- this.refresh()
229
- }
230
-
231
- expandNode(record: GristRecord) {
232
- record.__expanded__ = true
233
-
234
- this.refresh()
235
- }
236
-
237
- // onCollapse(e: CustomEvent) {
238
- // const record = e.detail as GristRecord
239
- // record.__expanded__ = false
240
-
241
- // this.refresh()
242
- // }
243
-
244
- // onExpand(e: CustomEvent) {
245
- // const record = e.detail as GristRecord
246
- // record.__expanded__ = true
247
-
248
- // this.refresh()
249
- // }
250
-
251
- addSiblingNode(record: GristRecord) {
252
- const { records } = this.data
253
- const toplevelRecords = records.filter(
254
- record => !record.__depth__
255
- ) /* __depth__ 가 설정되지 않았거나, 0 인 경우만 수집 */
256
-
257
- const { __depth__ } = record as GristRecord
258
-
259
- function findParent(record: GristRecord, parent?: GristRecord): GristRecord | undefined {
260
- var children = (parent ? parent.__children__ || [] : toplevelRecords) as GristRecord[]
261
-
262
- if (children.find(child => child === record)) {
263
- return parent
264
- } else {
265
- for (let child of children) {
266
- const found = findParent(record, child)
267
- if (found) {
268
- return found
269
- }
270
- }
271
- }
272
- }
273
-
274
- const parent = findParent(record)
275
-
276
- const sibling = {
277
- __depth__,
278
- __dirty__: '+'
279
- } as GristRecord
280
-
281
- if (parent) {
282
- const { id } = parent as GristRecord
283
-
284
- sibling.parent = { id }
285
-
286
- if (!parent.__children__) {
287
- parent.__children__ = [sibling]
288
- } else {
289
- let index = parent.__children__.indexOf(record)
290
-
291
- if (index !== -1) {
292
- parent.__children__ = [
293
- ...parent.__children__.slice(0, index + 1),
294
- sibling,
295
- ...parent.__children__.slice(index + 1)
296
- ]
297
- } else {
298
- parent.__children__ = [...parent.__children__, sibling]
299
- }
300
- }
301
-
302
- parent.__expanded__ = true
303
- } else {
304
- this.data.records = [...toplevelRecords, sibling]
305
- }
306
-
307
- this.refresh()
308
- }
309
-
310
- addChildNode(record: GristRecord) {
311
- const { id: parentId, __children__, __depth__ } = record as GristRecord
312
- const child = {
313
- parent: {
314
- id: parentId
315
- },
316
- __depth__: (__depth__ || 0) + 1,
317
- __dirty__: '+'
318
- }
319
-
320
- if (!record.__children__) {
321
- record.__children__ = [child]
322
- } else {
323
- record.__children__.unshift(child)
324
- }
325
-
326
- record.__expanded__ = true
327
-
328
- // this.requestUpdate()
329
-
330
- this.refresh()
331
- }
332
-
333
- onCheckInTree(e: CustomEvent) {
334
- function walkTreeCheckedUpdate(record: GristRecord, checked: 'checked' | 'unchecked') {
335
- const children = record.__children__
336
-
337
- children?.forEach(child => walkTreeCheckedUpdate(child, checked))
338
- record.__check_in_tree__ = checked
339
- record.__selected__ = checked == 'checked'
340
- }
341
-
342
- function updateCheckedAll(record: GristRecord) {
343
- /* 자식들의 checked 상태로 record의 checked 상태를 수정한다. */
344
- const children = record.__children__
345
-
346
- if (!children || children.length == 0) {
347
- return
348
- }
349
-
350
- children.forEach(child => updateCheckedAll(child))
351
-
352
- var checked: 'checked' | 'half-checked' | 'unchecked' | undefined =
353
- record.__check_in_tree__ == 'checked' ? 'checked' : undefined
354
-
355
- children.forEach(child => {
356
- const { __check_in_tree__ } = child
357
-
358
- if (__check_in_tree__ == 'half-checked') {
359
- checked = 'half-checked'
360
- } else if (__check_in_tree__ == 'checked') {
361
- checked = checked == 'checked' ? 'checked' : 'half-checked'
362
- } else {
363
- checked = checked == 'unchecked' || !checked ? 'unchecked' : 'half-checked'
364
- }
365
- })
366
-
367
- record.__check_in_tree__ = checked
368
- record.__selected__ = checked == 'checked'
369
- }
370
-
371
- e.stopPropagation()
372
-
373
- const record = e.detail
374
- var checked = record.__check_in_tree__
375
-
376
- walkTreeCheckedUpdate(record, !checked || checked == 'unchecked' ? 'checked' : 'unchecked')
377
- const toplevelRecords = this.data.records.filter(
378
- record => !record.__depth__
379
- ) /* __depth__ 가 설정되지 않았거나, 0 인 경우만 수집 */
380
-
381
- toplevelRecords.forEach(record => updateCheckedAll(record))
382
-
383
- this.refresh()
384
- }
385
-
386
- /**
387
- * Forced internal data to be reflected on the screen
388
- * Data changing through a normal method is automatically reflected on the screen, so it is a method that does not need to be used in general.
389
- * Therefore, it will be deprecated.
390
- * @method
391
- */
392
- refresh(forceExpandOrCollapse?: boolean) {
393
- /*
394
- - TODO 여기에서 TREE 형태 데이터의 접고, 펴는 것을 재구성한다.
395
- - 동적으로 서브항목을 fetch 하는 기능은 제공하지 않는다.
396
-
397
- 1. 빈배열에서 시작한다.
398
- 2. 기존 배열을 traverseRefresh하면서, collapsed 여부에 따라서, 자식의 포함여부를 결정하고 준비한 배열에 하나씩 추가한다.
399
-
400
- */
401
- const { records } = this.data
402
- const toplevelRecords = records.filter(
403
- record => !record.__depth__
404
- ) /* __depth__ 가 설정되지 않았거나, 0 인 경우만 수집 */
405
- this.data = {
406
- ...this.data,
407
- records: ([] as GristRecord[]).concat(
408
- ...toplevelRecords.map(record => this.traverseRefresh(record, forceExpandOrCollapse))
409
- )
410
- }
411
- }
412
-
413
- private traverseRefresh(record: GristRecord, forceExpandOrCollapse?: boolean): GristRecord[] {
414
- if (forceExpandOrCollapse !== undefined) {
415
- record.__expanded__ = forceExpandOrCollapse
416
- }
417
-
418
- const { __expanded__, __children__ = [] } = record
419
-
420
- if (__expanded__ && __children__.length > 0) {
421
- return [record].concat(...__children__.map(child => this.traverseRefresh(child, forceExpandOrCollapse)))
422
- } else {
423
- return [record]
424
- }
425
- }
426
- }
@@ -1,271 +0,0 @@
1
- import { ZERO_RECORDS } from './configure/zero-config.js'
2
- import { DataConsumer } from './data-consumer.js'
3
- import { FetchHandler, FetchOption, FilterValue, GristRecord, SorterConfig, SortersConfig } from './types.js'
4
-
5
- function EMPTY_FETCHHANDLER() {
6
- return {
7
- total: 0,
8
- records: []
9
- }
10
- }
11
-
12
- function _calculateTotalPage(limit: number, total: number) {
13
- /*
14
- * total page는 1이상이어야 한다.
15
- * 즉, 레코드가 하나도 없어도, 페이지 갯수는 1이 되어야 한다.
16
- */
17
- return Math.max(1, Math.ceil(total / limit))
18
- }
19
-
20
- export class DataProvider {
21
- page: number = 1
22
- limit: number = 20
23
- total: number = 0
24
- records: GristRecord[] = []
25
-
26
- private consumer?: DataConsumer
27
- private _fetchHandler?: FetchHandler
28
- private _sorters?: SorterConfig[]
29
- private _filters?: FilterValue[]
30
-
31
- private _pageChangeHandler: EventListener = this.onPageChange.bind(this)
32
- private _limitChangeHandler = this.onLimitChange.bind(this)
33
- private _fetchParamsChangeHandler = this.onFetchParamsChange.bind(this)
34
- private _recordChangeHandler = this.onRecordChange.bind(this)
35
- private _attachPageHandler: EventListener = this.onAttachPage.bind(this)
36
-
37
- private _fetchHandlerWrap: any
38
- private _fetchOptions: any
39
-
40
- constructor(consumer: DataConsumer) {
41
- this.consumer = consumer
42
-
43
- this.fetchHandler = consumer.fetchHandler
44
-
45
- this.consumer.addEventListener('attach-page', this._attachPageHandler)
46
- this.consumer.addEventListener('page-change', this._pageChangeHandler)
47
- this.consumer.addEventListener('limit-change', this._limitChangeHandler)
48
- this.consumer.addEventListener('fetch-params-change', this._fetchParamsChangeHandler)
49
- this.consumer.addEventListener('record-change', this._recordChangeHandler)
50
- }
51
-
52
- dispose() {
53
- this.consumer?.removeEventListener('attach-page', this._attachPageHandler)
54
- this.consumer?.removeEventListener('page-change', this._pageChangeHandler)
55
- this.consumer?.removeEventListener('limit-change', this._limitChangeHandler)
56
- this.consumer?.removeEventListener('fetch-params-change', this._fetchParamsChangeHandler)
57
- this.consumer?.removeEventListener('record-change', this._recordChangeHandler)
58
- }
59
-
60
- onAttachPage() {
61
- this.attach()
62
- }
63
-
64
- onPageChange(e: Event) {
65
- var page = (e as CustomEvent).detail
66
- this.fetch({ page })
67
- }
68
-
69
- onLimitChange(e: Event) {
70
- var limit = (e as CustomEvent).detail
71
- this.fetch({ limit })
72
- }
73
-
74
- onFetchParamsChange(e: Event) {
75
- const { sorters, filters, from } = (e as CustomEvent).detail || {}
76
-
77
- sorters && (this.sorters = sorters)
78
- filters && (this.filters = filters)
79
-
80
- if (this.consumer?.mode !== 'GRID') {
81
- this.page = 0
82
- }
83
-
84
- from !== 'config' && this.fetch()
85
- }
86
-
87
- onRecordChange(e: Event) {
88
- this.consumer?.checkDirties()
89
- }
90
-
91
- get fetchOptions() {
92
- return this._fetchOptions
93
- }
94
-
95
- set fetchOptions(fetchOptions) {
96
- this._fetchOptions = fetchOptions
97
-
98
- this.fetch()
99
- }
100
-
101
- get fetchHandler() {
102
- if (!this._fetchHandlerWrap) {
103
- this._fetchHandlerWrap = async (options: FetchOption) => {
104
- if (!this._fetchHandler) {
105
- return
106
- }
107
-
108
- try {
109
- this.consumer?.showSpinner()
110
- return await (this._fetchHandler || EMPTY_FETCHHANDLER)(options)
111
- } finally {
112
- this.consumer?.hideSpinner()
113
- }
114
- }
115
- }
116
-
117
- return this._fetchHandlerWrap
118
- }
119
-
120
- set fetchHandler(fetchHandler) {
121
- this._fetchHandler = fetchHandler
122
- delete this._fetchHandlerWrap
123
- }
124
-
125
- get sorters() {
126
- return this._sorters
127
- }
128
-
129
- set sorters(sorters) {
130
- this._sorters = sorters
131
- }
132
-
133
- /* alias for sorters */
134
- get sortings() {
135
- return this._sorters
136
- }
137
-
138
- set sortings(sorters) {
139
- this._sorters = sorters
140
- }
141
-
142
- get filters() {
143
- return this._filters
144
- }
145
-
146
- set filters(filters) {
147
- this._filters = filters
148
- }
149
-
150
- async attach(reset = false) {
151
- var { page = 0, limit = 20 } = this
152
-
153
- /*
154
- * page는 0 based index가 아님에 주의한다.
155
- * 즉, page 값이 1 은 첫페이지를 의미한다.
156
- */
157
- if (reset) {
158
- this.records = ZERO_RECORDS
159
- page = 1
160
- } else {
161
- /* attach의 경우는 grist data의 변경상태를 유지하기 위해서, grist._data 를 기반으로 한다. */
162
- this.records = this.consumer?._data ? this.consumer._data.records : ZERO_RECORDS
163
- page = page + 1
164
- }
165
-
166
- return this._update(
167
- {
168
- /* fetch에서 limit과 page를 제공하지 않는 경우를 대비함. */
169
- limit,
170
- page,
171
- ...(await this.fetchHandler.call(null, {
172
- page,
173
- limit,
174
- sorters: this.sorters,
175
- sortings: this.sorters,
176
- filters: this.filters,
177
- options: this.fetchOptions
178
- }))
179
- },
180
- reset
181
- )
182
- }
183
-
184
- async fetch({
185
- page = this.page,
186
- limit = this.limit,
187
- sorters,
188
- sortings,
189
- filters
190
- }: {
191
- page?: number
192
- limit?: number
193
- sorters?: SortersConfig
194
- sortings?: SortersConfig
195
- filters?: FilterValue[]
196
- } = {}) {
197
- /* sortings property is only for things-factory server-side list parameter convention */
198
- /* fetchHandler should reture { page, limit, total, records } */
199
- this.records = ZERO_RECORDS
200
-
201
- sorters = sorters || sortings || this.sorters
202
- filters = filters || this.filters
203
-
204
- this.sorters = sorters
205
-
206
- return this._update({
207
- /* fetch에서 limit과 page를 제공하지 않는 경우를 대비함. */
208
- limit,
209
- page,
210
- ...(await this.fetchHandler.call(null, {
211
- page,
212
- limit,
213
- sorters,
214
- sortings: sorters,
215
- filters,
216
- options: this.fetchOptions
217
- }))
218
- })
219
- }
220
-
221
- async _update(
222
- {
223
- page,
224
- limit,
225
- total,
226
- records
227
- }: {
228
- page: number
229
- limit: number
230
- total: number
231
- records: GristRecord[]
232
- },
233
- reset?: boolean
234
- ): Promise<void> {
235
- // total을 감안해서 page가 최대값을 넘지 않도록 한다.
236
- var maxpage = _calculateTotalPage(limit, total)
237
- if (maxpage < page) {
238
- return await this.fetch({ page: maxpage, limit })
239
- }
240
-
241
- // page와 limit이 없는 경우 records 검사 전에 초기화
242
- this.page = this.page || page
243
- this.limit = this.limit || limit
244
-
245
- if (!records) {
246
- return
247
- }
248
-
249
- if (this.records === ZERO_RECORDS) {
250
- this.records = records
251
- } else if (this.page < page) {
252
- // attach인 경우에는 records를 append한다.
253
- this.records = [...this.records, ...records]
254
- } else {
255
- return
256
- }
257
-
258
- this.limit = limit
259
- this.total = total
260
- this.page = page
261
-
262
- this.consumer &&
263
- (this.consumer.data = {
264
- page: this.page,
265
- limit: this.limit,
266
- total: this.total,
267
-
268
- records: this.records
269
- })
270
- }
271
- }