@operato/data-grist 7.1.31 → 7.1.32
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/CHANGELOG.md +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/data-grist-test.html +0 -468
- package/demo/favicon.ico +0 -0
- package/demo/index.html +0 -541
- package/demo/report-test.html +0 -249
- package/dist/src/record-view/record-creator.d.ts +0 -17
- package/dist/src/record-view/record-creator.js +0 -148
- package/dist/src/record-view/record-creator.js.map +0 -1
- package/src/accumulator/accumulator.ts +0 -63
- package/src/configure/column-builder.ts +0 -114
- package/src/configure/config-builder.ts +0 -40
- package/src/configure/filters-option-builder.ts +0 -8
- package/src/configure/imex-option-builder.ts +0 -5
- package/src/configure/list-option-builder.ts +0 -9
- package/src/configure/rows-option-builder.ts +0 -38
- package/src/configure/tree-option-builder.ts +0 -22
- package/src/configure/zero-config.ts +0 -83
- package/src/const.ts +0 -1
- package/src/data-card/data-card-field.ts +0 -94
- package/src/data-card/data-card-gutter-menu.ts +0 -94
- package/src/data-card/data-card-gutter.ts +0 -103
- package/src/data-card/data-card.ts +0 -154
- package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
- package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
- package/src/data-card/record-card.ts +0 -289
- package/src/data-consumer.ts +0 -11
- package/src/data-grid/data-grid-accum-field.ts +0 -109
- package/src/data-grid/data-grid-body-style.ts +0 -99
- package/src/data-grid/data-grid-body.ts +0 -753
- package/src/data-grid/data-grid-field.ts +0 -236
- package/src/data-grid/data-grid-footer.ts +0 -117
- package/src/data-grid/data-grid-header.ts +0 -574
- package/src/data-grid/data-grid.ts +0 -293
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
- package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
- package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
- package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
- package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
- package/src/data-grist.ts +0 -1233
- package/src/data-list/data-list-field.ts +0 -82
- package/src/data-list/data-list-gutter.ts +0 -108
- package/src/data-list/data-list.ts +0 -145
- package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
- package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
- package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
- package/src/data-list/record-partial.ts +0 -255
- package/src/data-manipulator.ts +0 -426
- package/src/data-provider.ts +0 -271
- package/src/data-report/data-report-body-style.ts +0 -58
- package/src/data-report/data-report-body.ts +0 -189
- package/src/data-report/data-report-component.ts +0 -138
- package/src/data-report/data-report-field.ts +0 -83
- package/src/data-report/data-report-header.ts +0 -242
- package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
- package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
- package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
- package/src/data-report.ts +0 -424
- package/src/editors/index.ts +0 -4
- package/src/editors/ox-grist-editor-checkbox.ts +0 -28
- package/src/editors/ox-grist-editor-color.ts +0 -10
- package/src/editors/ox-grist-editor-date.ts +0 -10
- package/src/editors/ox-grist-editor-datetime.ts +0 -27
- package/src/editors/ox-grist-editor-email.ts +0 -10
- package/src/editors/ox-grist-editor-file.ts +0 -28
- package/src/editors/ox-grist-editor-image.ts +0 -31
- package/src/editors/ox-grist-editor-month.ts +0 -10
- package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
- package/src/editors/ox-grist-editor-number.ts +0 -27
- package/src/editors/ox-grist-editor-password.ts +0 -10
- package/src/editors/ox-grist-editor-select.ts +0 -55
- package/src/editors/ox-grist-editor-tel.ts +0 -10
- package/src/editors/ox-grist-editor-text.ts +0 -14
- package/src/editors/ox-grist-editor-textarea.ts +0 -16
- package/src/editors/ox-grist-editor-time.ts +0 -10
- package/src/editors/ox-grist-editor-tree.ts +0 -27
- package/src/editors/ox-grist-editor-varname.ts +0 -36
- package/src/editors/ox-grist-editor-week.ts +0 -10
- package/src/editors/ox-grist-editor.ts +0 -207
- package/src/editors/ox-input-tree.ts +0 -226
- package/src/editors/registry.ts +0 -82
- package/src/empty-note.ts +0 -46
- package/src/filters/filter-checkbox.ts +0 -49
- package/src/filters/filter-input-barcode.ts +0 -34
- package/src/filters/filter-input.ts +0 -30
- package/src/filters/filter-range-date.ts +0 -81
- package/src/filters/filter-range-number.ts +0 -64
- package/src/filters/filter-select-buttons.ts +0 -60
- package/src/filters/filter-select.ts +0 -68
- package/src/filters/filter-styles.ts +0 -119
- package/src/filters/filters-form.ts +0 -476
- package/src/filters/index.ts +0 -10
- package/src/filters/registry.ts +0 -56
- package/src/formatters/date-formatter.ts +0 -3
- package/src/formatters/index.ts +0 -1
- package/src/formatters/number-formatter.ts +0 -3
- package/src/formatters/registry.ts +0 -30
- package/src/formatters/text-formatter.ts +0 -3
- package/src/gutters/gutter-button.ts +0 -51
- package/src/gutters/gutter-dirty.ts +0 -96
- package/src/gutters/gutter-row-selector.ts +0 -89
- package/src/gutters/gutter-sequence.ts +0 -54
- package/src/gutters/index.ts +0 -1
- package/src/gutters/registry.ts +0 -32
- package/src/handlers/contextmenu-tree-mutation.ts +0 -80
- package/src/handlers/index.ts +0 -1
- package/src/handlers/move-down.ts +0 -44
- package/src/handlers/move-up.ts +0 -44
- package/src/handlers/record-copy.ts +0 -38
- package/src/handlers/record-delete.ts +0 -30
- package/src/handlers/record-view-handler.ts +0 -27
- package/src/handlers/registry.ts +0 -42
- package/src/handlers/select-row-toggle.ts +0 -30
- package/src/handlers/select-row.ts +0 -27
- package/src/index.ts +0 -17
- package/src/personalizer/index.ts +0 -1
- package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
- package/src/personalizer/ox-grist-personalizer.ts +0 -226
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
- package/src/record-view/index.ts +0 -2
- package/src/record-view/ox-record-creator.ts +0 -289
- package/src/record-view/record-view-body.ts +0 -250
- package/src/record-view/record-view-handler.ts +0 -86
- package/src/record-view/record-view.ts +0 -122
- package/src/renderers/index.ts +0 -14
- package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
- package/src/renderers/ox-grist-renderer-color.ts +0 -15
- package/src/renderers/ox-grist-renderer-date.ts +0 -62
- package/src/renderers/ox-grist-renderer-file.ts +0 -31
- package/src/renderers/ox-grist-renderer-image.ts +0 -27
- package/src/renderers/ox-grist-renderer-json5.ts +0 -36
- package/src/renderers/ox-grist-renderer-link.ts +0 -17
- package/src/renderers/ox-grist-renderer-password.ts +0 -7
- package/src/renderers/ox-grist-renderer-progress.ts +0 -45
- package/src/renderers/ox-grist-renderer-select.ts +0 -58
- package/src/renderers/ox-grist-renderer-text.ts +0 -16
- package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
- package/src/renderers/ox-grist-renderer-tree.ts +0 -189
- package/src/renderers/ox-grist-renderer.ts +0 -35
- package/src/renderers/registry.ts +0 -111
- package/src/sorters/sorters-control.ts +0 -143
- package/src/types.ts +0 -813
- package/src/utils/index.ts +0 -2
- package/src/utils/list-param.ts +0 -72
- package/src/utils/supports-passive.ts +0 -13
- package/stories/accumulator-format.stories.ts +0 -276
- package/stories/barcode-input-filter.stories.ts +0 -216
- package/stories/bounded-select-filters.stories.ts +0 -333
- package/stories/bounded-select-record.stories.ts +0 -336
- package/stories/click-event-custom.stories.ts +0 -288
- package/stories/click-event.stories.ts +0 -283
- package/stories/creatable-only-column.stories.ts +0 -253
- package/stories/default-filters.stories.ts +0 -241
- package/stories/dynamic-editable.stories.ts +0 -313
- package/stories/empty-sorters.stories.ts +0 -180
- package/stories/explicit-fetch.stories.ts +0 -186
- package/stories/fixed-column.stories.ts +0 -416
- package/stories/grid-setting.stories.ts +0 -501
- package/stories/grist-modes.stories.ts +0 -451
- package/stories/group-header.stories.ts +0 -442
- package/stories/record-view.stories.ts +0 -143
- package/stories/textarea.stories.ts +0 -261
- package/stories/tree-column-with-checkbox.stories.ts +0 -297
- package/stories/tree-column.stories.ts +0 -296
- package/tsconfig.json +0 -26
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -45
- package/yarn-error.log +0 -16971
package/src/data-manipulator.ts
DELETED
@@ -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
|
-
}
|
package/src/data-provider.ts
DELETED
@@ -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
|
-
}
|