@operato/data-grist 0.3.13 → 0.3.17
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 +47 -0
- package/assets/images/no-image.png +0 -0
- package/custom-elements.json +2382 -1803
- package/demo/index.html +41 -62
- package/dist/src/configure/list-option-builder.js +0 -2
- package/dist/src/configure/list-option-builder.js.map +1 -1
- package/dist/src/configure/zero-config.d.ts +0 -1
- package/dist/src/configure/zero-config.js +0 -2
- package/dist/src/configure/zero-config.js.map +1 -1
- package/dist/src/data-card/data-card.d.ts +3 -6
- package/dist/src/data-card/data-card.js +3 -131
- package/dist/src/data-card/data-card.js.map +1 -1
- package/dist/src/data-card/record-card.d.ts +0 -3
- package/dist/src/data-card/record-card.js +22 -71
- package/dist/src/data-card/record-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +7 -1
- package/dist/src/data-grid/data-grid-body.js +26 -5
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-field.js +1 -1
- package/dist/src/data-grid/data-grid-field.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.d.ts +1 -0
- package/dist/src/data-grid/data-grid-header.js +9 -1
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +8 -4
- package/dist/src/data-grid/data-grid.js +12 -132
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grist.d.ts +1 -0
- package/dist/src/data-grist.js +3 -0
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/data-list.d.ts +3 -6
- package/dist/src/data-list/data-list.js +3 -131
- package/dist/src/data-list/data-list.js.map +1 -1
- package/dist/src/data-list/record-partial.d.ts +0 -2
- package/dist/src/data-list/record-partial.js +7 -58
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/data-manipulator.d.ts +20 -0
- package/dist/src/data-manipulator.js +148 -0
- package/dist/src/data-manipulator.js.map +1 -0
- package/dist/src/editors/image-editor.d.ts +9 -0
- package/dist/src/editors/image-editor.js +53 -0
- package/dist/src/editors/image-editor.js.map +1 -0
- package/dist/src/editors/image-input.d.ts +7 -0
- package/dist/src/editors/image-input.js +31 -0
- package/dist/src/editors/image-input.js.map +1 -0
- package/dist/src/editors/index.d.ts +1 -0
- package/dist/src/editors/index.js +1 -0
- package/dist/src/editors/index.js.map +1 -1
- package/dist/src/editors/input-editors copy.d.ts +75 -0
- package/dist/src/editors/input-editors copy.js +373 -0
- package/dist/src/editors/input-editors copy.js.map +1 -0
- package/dist/src/editors/input-editors.d.ts +1 -8
- package/dist/src/editors/input-editors.js +3 -47
- package/dist/src/editors/input-editors.js.map +1 -1
- package/dist/src/editors/registry.d.ts +1 -1
- package/dist/src/editors/registry.js +2 -1
- package/dist/src/editors/registry.js.map +1 -1
- package/dist/src/handlers/record-view-handler.d.ts +1 -2
- package/dist/src/handlers/record-view-handler.js +5 -35
- package/dist/src/handlers/record-view-handler.js.map +1 -1
- package/dist/src/handlers/select-row-toggle.d.ts +1 -1
- package/dist/src/handlers/select-row-toggle.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.d.ts +7 -0
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +24 -0
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.d.ts +7 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +22 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -0
- package/dist/src/record-view/index.d.ts +1 -0
- package/dist/src/record-view/index.js +1 -0
- package/dist/src/record-view/index.js.map +1 -1
- package/dist/src/record-view/record-creator copy.d.ts +13 -0
- package/dist/src/record-view/record-creator copy.js +90 -0
- package/dist/src/record-view/record-creator copy.js.map +1 -0
- package/dist/src/record-view/record-creator-backup.d.ts +13 -0
- package/dist/src/record-view/record-creator-backup.js +90 -0
- package/dist/src/record-view/record-creator-backup.js.map +1 -0
- package/dist/src/record-view/record-creator.d.ts +16 -0
- package/dist/src/record-view/record-creator.js +145 -0
- package/dist/src/record-view/record-creator.js.map +1 -0
- package/dist/src/record-view/record-view-body.d.ts +3 -4
- package/dist/src/record-view/record-view-body.js +15 -42
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view-handler.d.ts +9 -0
- package/dist/src/record-view/record-view-handler.js +57 -0
- package/dist/src/record-view/record-view-handler.js.map +1 -0
- package/dist/src/record-view/record-view.d.ts +5 -1
- package/dist/src/record-view/record-view.js +61 -36
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/renderers/image-renderer.js +12 -4
- package/dist/src/renderers/image-renderer.js.map +1 -1
- package/dist/src/sorters/sorters-control.d.ts +12 -0
- package/dist/src/sorters/sorters-control.js +106 -0
- package/dist/src/sorters/sorters-control.js.map +1 -0
- package/dist/src/types.d.ts +2 -3
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -8
- package/src/configure/list-option-builder.ts +0 -2
- package/src/configure/zero-config.ts +0 -2
- package/src/data-card/data-card.ts +4 -158
- package/src/data-card/record-card.ts +30 -87
- package/src/data-grid/data-grid-body.ts +43 -6
- package/src/data-grid/data-grid-field.ts +1 -1
- package/src/data-grid/data-grid-header.ts +11 -1
- package/src/data-grid/data-grid.ts +25 -143
- package/src/data-grist.ts +4 -0
- package/src/data-list/data-list.ts +4 -158
- package/src/data-list/record-partial.ts +14 -73
- package/src/data-manipulator.ts +201 -0
- package/src/editors/image-input.ts +29 -0
- package/src/editors/index.ts +1 -0
- package/src/editors/input-editors.ts +5 -48
- package/src/editors/registry.ts +3 -4
- package/src/handlers/record-view-handler.ts +8 -44
- package/src/handlers/select-row-toggle.ts +1 -2
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +30 -0
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +26 -0
- package/src/record-view/index.ts +1 -0
- package/src/record-view/record-creator.ts +180 -0
- package/src/record-view/record-view-body.ts +16 -55
- package/src/record-view/record-view-handler.ts +86 -0
- package/src/record-view/record-view.ts +69 -42
- package/src/renderers/image-renderer.ts +14 -5
- package/src/sorters/sorters-control.ts +111 -0
- package/src/types.ts +10 -3
- package/yarn-error.log +16718 -0
|
@@ -8,6 +8,7 @@ import { css, html, LitElement, PropertyValues } from 'lit'
|
|
|
8
8
|
import { customElement, property } from 'lit/decorators.js'
|
|
9
9
|
|
|
10
10
|
import { ZERO_CONFIG, ZERO_DATA, ZERO_RECORD } from '../configure/zero-config'
|
|
11
|
+
import { RecordViewHandler } from '../record-view/record-view-handler'
|
|
11
12
|
import { GristConfig, GristData, GristRecord } from '../types'
|
|
12
13
|
import { recordCardClickHandler } from './event-handlers/record-card-click-handler'
|
|
13
14
|
import { recordCardDblClickHandler } from './event-handlers/record-card-dblclick-handler'
|
|
@@ -67,7 +68,10 @@ export class RecordCard extends LitElement {
|
|
|
67
68
|
border-top-right-radius: var(--data-card-record-card-border-radius);
|
|
68
69
|
border-bottom: var(--data-card-thumbnail-border-bottom);
|
|
69
70
|
overflow: hidden;
|
|
70
|
-
|
|
71
|
+
|
|
72
|
+
display: flex;
|
|
73
|
+
align-content: center;
|
|
74
|
+
justify-content: center;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
[content] {
|
|
@@ -139,36 +143,6 @@ export class RecordCard extends LitElement {
|
|
|
139
143
|
private clickHandler = recordCardClickHandler.bind(this) as EventListener
|
|
140
144
|
private dblclickHandler = recordCardDblClickHandler.bind(this) as EventListener
|
|
141
145
|
|
|
142
|
-
attributeChangedCallback(name: string, oldval: any, newval: any) {
|
|
143
|
-
super.attributeChangedCallback(name, oldval, newval)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
onFieldChange(e: Event) {
|
|
147
|
-
/* record-view의 이벤트를 부모에게로 전달한다. */
|
|
148
|
-
this.dispatchEvent(
|
|
149
|
-
new CustomEvent('field-change', {
|
|
150
|
-
bubbles: true,
|
|
151
|
-
composed: true,
|
|
152
|
-
detail: (e as any).detail
|
|
153
|
-
})
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
get recordView() {
|
|
158
|
-
if (!this._recordView) {
|
|
159
|
-
this._recordView = document.createElement('ox-record-view')
|
|
160
|
-
this._recordView.addEventListener('field-change', (e: CustomEvent) => this.onFieldChange(e))
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
var columns = this.config.columns
|
|
164
|
-
|
|
165
|
-
this._recordView.columns = columns
|
|
166
|
-
this._recordView.record = this.record
|
|
167
|
-
this._recordView.rowIndex = this.rowIndex
|
|
168
|
-
|
|
169
|
-
return this._recordView
|
|
170
|
-
}
|
|
171
|
-
|
|
172
146
|
firstUpdated() {
|
|
173
147
|
/*
|
|
174
148
|
long-press
|
|
@@ -178,6 +152,8 @@ export class RecordCard extends LitElement {
|
|
|
178
152
|
// this.renderRoot.addEventListener('long-press', recordPartialLongPressHandler.bind(this))
|
|
179
153
|
this.renderRoot.addEventListener('click', this.clickHandler)
|
|
180
154
|
this.renderRoot.addEventListener('dblclick', this.dblclickHandler)
|
|
155
|
+
|
|
156
|
+
this.addEventListener('show-record-view', () => this.popupRecordView())
|
|
181
157
|
}
|
|
182
158
|
|
|
183
159
|
updated(changes: PropertyValues<this>) {
|
|
@@ -187,18 +163,21 @@ export class RecordCard extends LitElement {
|
|
|
187
163
|
}
|
|
188
164
|
|
|
189
165
|
render() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
166
|
+
const record = this.record
|
|
167
|
+
const rowIndex = this.rowIndex
|
|
168
|
+
const { columns, list } = this.config
|
|
169
|
+
const { thumbnail, fields, details } = list || {}
|
|
194
170
|
|
|
195
|
-
|
|
196
|
-
|
|
171
|
+
const briefFields = fields.map(field => columns.find(column => column.name == field)).filter(column => column) || []
|
|
172
|
+
const detailFields =
|
|
173
|
+
details.map(field => columns.find(column => column.name == field)).filter(column => column) || []
|
|
197
174
|
|
|
198
|
-
|
|
175
|
+
const thumbnailColumn = thumbnail ? columns.find(column => column.name == thumbnail) : undefined
|
|
176
|
+
const thumbRenderer = thumbnailColumn?.record.renderer
|
|
177
|
+
const thumbnailTemplate = thumbRenderer?.call(this, record[thumbnail!], thumbnailColumn!, record, rowIndex, this)
|
|
199
178
|
|
|
200
|
-
|
|
201
|
-
|
|
179
|
+
const gutters = (columns || []).filter(column => column.type == 'gutter' && column.forList)
|
|
180
|
+
const firstGutter = gutters[0]
|
|
202
181
|
|
|
203
182
|
if (this.hasAttribute('dirty')) {
|
|
204
183
|
var dirtyIcon
|
|
@@ -301,53 +280,17 @@ export class RecordCard extends LitElement {
|
|
|
301
280
|
title = column?.record.renderer(title, column, this.record, this.rowIndex, this /* cautious */)
|
|
302
281
|
}
|
|
303
282
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
this.dispatchEvent(
|
|
316
|
-
new CustomEvent('record-reset', {
|
|
317
|
-
bubbles: true,
|
|
318
|
-
composed: true,
|
|
319
|
-
detail: {
|
|
320
|
-
record: this.record,
|
|
321
|
-
row: this.rowIndex
|
|
322
|
-
}
|
|
323
|
-
})
|
|
324
|
-
)
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
this.recordView.addEventListener('cancel', () => {
|
|
328
|
-
this.dispatchEvent(
|
|
329
|
-
new CustomEvent('record-reset', {
|
|
330
|
-
bubbles: true,
|
|
331
|
-
composed: true,
|
|
332
|
-
detail: {
|
|
333
|
-
record: this.record,
|
|
334
|
-
row: this.rowIndex
|
|
335
|
-
}
|
|
336
|
-
})
|
|
337
|
-
)
|
|
338
|
-
popup.close()
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
this.recordView.addEventListener('ok', () => {
|
|
342
|
-
popup.close()
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
popup.onclosed = () => {
|
|
346
|
-
delete this._recordView
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
})
|
|
283
|
+
this._recordView = RecordViewHandler(
|
|
284
|
+
this.config.columns,
|
|
285
|
+
this.record,
|
|
286
|
+
this.rowIndex,
|
|
287
|
+
this,
|
|
288
|
+
{
|
|
289
|
+
title
|
|
290
|
+
},
|
|
291
|
+
() => {
|
|
292
|
+
delete this._recordView
|
|
293
|
+
}
|
|
351
294
|
)
|
|
352
295
|
}
|
|
353
296
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import './data-grid-field'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { LitElement, PropertyValues, html } from 'lit'
|
|
5
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
3
|
+
import { html, LitElement, PropertyValues } from 'lit'
|
|
6
4
|
import { customElement, property } from 'lit/decorators.js'
|
|
5
|
+
import debounce from 'lodash-es/debounce'
|
|
7
6
|
|
|
7
|
+
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
8
|
+
import { RecordViewHandler } from '../record-view/record-view-handler'
|
|
9
|
+
import { ColumnConfig, GristConfig, GristData, GristRecord } from '../types'
|
|
10
|
+
import { supportsPassive } from '../utils'
|
|
11
|
+
import { dataGridBodyStyle } from './data-grid-body-style'
|
|
8
12
|
import { dataGridBodyClickHandler } from './event-handlers/data-grid-body-click-handler'
|
|
9
13
|
import { dataGridBodyDblclickHandler } from './event-handlers/data-grid-body-dblclick-handler'
|
|
10
14
|
import { dataGridBodyKeydownHandler } from './event-handlers/data-grid-body-keydown-handler'
|
|
11
|
-
import { dataGridBodyStyle } from './data-grid-body-style'
|
|
12
|
-
import debounce from 'lodash-es/debounce'
|
|
13
|
-
import { supportsPassive } from '../utils'
|
|
14
15
|
|
|
15
16
|
const THRESHOLD = 300
|
|
16
17
|
const DATA_PADDING = 3
|
|
@@ -58,6 +59,8 @@ export class DataGridBody extends LitElement {
|
|
|
58
59
|
@property({ type: Number }) to = -1
|
|
59
60
|
|
|
60
61
|
private _focusedListener?: (e: KeyboardEvent) => void
|
|
62
|
+
private _recordView?: any
|
|
63
|
+
private _recordViewRow?: number
|
|
61
64
|
|
|
62
65
|
resetEdit() {
|
|
63
66
|
this.editTarget = null
|
|
@@ -171,6 +174,10 @@ export class DataGridBody extends LitElement {
|
|
|
171
174
|
'--focused-background-image',
|
|
172
175
|
`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><rect fill='${primaryColor}' x='0' y='0' width='100%' height='100%' style='opacity:.3'/></svg>")`
|
|
173
176
|
)
|
|
177
|
+
|
|
178
|
+
this.addEventListener('show-record-view', (e: Event) =>
|
|
179
|
+
this.popupRecordView((e as CustomEvent).detail as { row: number; record: GristRecord })
|
|
180
|
+
)
|
|
174
181
|
}
|
|
175
182
|
|
|
176
183
|
_onWheelEvent(e: WheelEvent) {
|
|
@@ -226,6 +233,10 @@ export class DataGridBody extends LitElement {
|
|
|
226
233
|
this.scrollLeft = left
|
|
227
234
|
}
|
|
228
235
|
}
|
|
236
|
+
|
|
237
|
+
if (this._recordView) {
|
|
238
|
+
this._recordView.record = this.data.records[this._recordViewRow!]
|
|
239
|
+
}
|
|
229
240
|
}
|
|
230
241
|
|
|
231
242
|
focus() {
|
|
@@ -238,4 +249,30 @@ export class DataGridBody extends LitElement {
|
|
|
238
249
|
this.focused = { row: row == -1 ? 0 : row, column: 0 }
|
|
239
250
|
}
|
|
240
251
|
}
|
|
252
|
+
|
|
253
|
+
popupRecordView({ record, row }: { row: number; record: GristRecord }) {
|
|
254
|
+
var titleField = this.config.list.fields[0] || 'name'
|
|
255
|
+
var title = record[titleField]
|
|
256
|
+
|
|
257
|
+
/* field가 오브젝트형인 경우에는 렌더러를 타이틀로 사용한다. */
|
|
258
|
+
if (typeof title == 'object') {
|
|
259
|
+
var column = this.config.columns.find(column => column.name == titleField)
|
|
260
|
+
title = column?.record.renderer(title, column, record, row, this /* cautious */)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
this._recordViewRow = row
|
|
264
|
+
this._recordView = RecordViewHandler(
|
|
265
|
+
this.config.columns,
|
|
266
|
+
record,
|
|
267
|
+
row,
|
|
268
|
+
this,
|
|
269
|
+
{
|
|
270
|
+
title
|
|
271
|
+
},
|
|
272
|
+
() => {
|
|
273
|
+
delete this._recordView
|
|
274
|
+
delete this._recordViewRow
|
|
275
|
+
}
|
|
276
|
+
)
|
|
277
|
+
}
|
|
241
278
|
}
|
|
@@ -118,7 +118,7 @@ export class DataGridField extends LitElement {
|
|
|
118
118
|
if (changes.has('editing')) {
|
|
119
119
|
if (this.isEditing) {
|
|
120
120
|
this._onKeydownInEditingMode = ((e: KeyboardEvent) => {
|
|
121
|
-
if (e.
|
|
121
|
+
if (e.key === 'Esc' || e.key === 'Escape') {
|
|
122
122
|
/* 편집 취소 */
|
|
123
123
|
this._editCancelled = true
|
|
124
124
|
}
|
|
@@ -6,6 +6,7 @@ import { customElement, property, state } from 'lit/decorators.js'
|
|
|
6
6
|
import throttle from 'lodash-es/throttle'
|
|
7
7
|
|
|
8
8
|
import { OxPopup } from '@operato/popup'
|
|
9
|
+
import { closestElement } from '@operato/utils'
|
|
9
10
|
|
|
10
11
|
import { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
11
12
|
import { FilterStyles } from '../filters/filter-styles'
|
|
@@ -24,7 +25,7 @@ export class DataGridHeader extends LitElement {
|
|
|
24
25
|
overflow: hidden;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
div[column] {
|
|
28
29
|
display: flex;
|
|
29
30
|
|
|
30
31
|
white-space: nowrap;
|
|
@@ -119,6 +120,15 @@ export class DataGridHeader extends LitElement {
|
|
|
119
120
|
private _lastAccVal?: number
|
|
120
121
|
private _throttledNotifier?: any
|
|
121
122
|
|
|
123
|
+
connectedCallback() {
|
|
124
|
+
super.connectedCallback()
|
|
125
|
+
|
|
126
|
+
const grid = closestElement('ox-grist', this)
|
|
127
|
+
grid?.addEventListener('sorters-change', (e: Event) => {
|
|
128
|
+
this._sorters = (e as CustomEvent).detail
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
122
132
|
render() {
|
|
123
133
|
var columns = this.columns || []
|
|
124
134
|
|
|
@@ -2,20 +2,21 @@ import './data-grid-header'
|
|
|
2
2
|
import './data-grid-body'
|
|
3
3
|
import './data-grid-footer'
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { LitElement, PropertyValues, css, html } from 'lit'
|
|
7
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
5
|
+
import { css, html, LitElement, PropertyValues } from 'lit'
|
|
8
6
|
import { customElement, property, query } from 'lit/decorators.js'
|
|
9
7
|
|
|
10
|
-
import { DataGridHeader } from './data-grid-header'
|
|
11
8
|
import { ScrollbarStyles } from '@operato/styles'
|
|
9
|
+
|
|
10
|
+
import { DataManipulator } from '../data-manipulator'
|
|
11
|
+
import { ColumnConfig, GristRecord, PaginationConfig } from '../types'
|
|
12
12
|
import { supportsPassive } from '../utils'
|
|
13
|
+
import { DataGridHeader } from './data-grid-header'
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* DataGrid
|
|
16
17
|
*/
|
|
17
18
|
@customElement('ox-grid')
|
|
18
|
-
export class DataGrid extends
|
|
19
|
+
export class DataGrid extends DataManipulator {
|
|
19
20
|
static styles = [
|
|
20
21
|
ScrollbarStyles,
|
|
21
22
|
css`
|
|
@@ -40,8 +41,6 @@ export class DataGrid extends LitElement {
|
|
|
40
41
|
`
|
|
41
42
|
]
|
|
42
43
|
|
|
43
|
-
@property({ type: Object }) config: GristConfig = ZERO_CONFIG
|
|
44
|
-
@property({ type: Object }) data: GristData = ZERO_DATA
|
|
45
44
|
@property({ type: Object }) focused?: { row: number; column: number }
|
|
46
45
|
|
|
47
46
|
@query('ox-grid-body', true) body!: LitElement
|
|
@@ -82,70 +81,11 @@ export class DataGrid extends LitElement {
|
|
|
82
81
|
this.body.requestUpdate()
|
|
83
82
|
})
|
|
84
83
|
|
|
85
|
-
this.addEventListener('select-record-change', e => {
|
|
86
|
-
var {
|
|
87
|
-
records: selectedRecords,
|
|
88
|
-
added = [],
|
|
89
|
-
removed = []
|
|
90
|
-
} = (e as CustomEvent).detail as {
|
|
91
|
-
records: GristRecord[]
|
|
92
|
-
added: GristRecord[]
|
|
93
|
-
removed: GristRecord[]
|
|
94
|
-
}
|
|
95
|
-
var { records } = this.data
|
|
96
|
-
var { selectable } = this.config.rows
|
|
97
|
-
|
|
98
|
-
if (!records) {
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (selectable && !selectable.multiple) {
|
|
103
|
-
records.forEach(record => (record['__selected__'] = false))
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (selectedRecords) {
|
|
107
|
-
records.forEach(record => (record['__selected__'] = false))
|
|
108
|
-
selectedRecords.forEach(record => (record['__selected__'] = true))
|
|
109
|
-
} else {
|
|
110
|
-
removed.forEach(record => (record['__selected__'] = false))
|
|
111
|
-
added.forEach(record => (record['__selected__'] = true))
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.header.requestUpdate()
|
|
115
|
-
this.body.requestUpdate()
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
/* field change processing */
|
|
119
|
-
this.addEventListener('field-change', e => {
|
|
120
|
-
var { after, before, column, record, row } = (e as CustomEvent).detail
|
|
121
|
-
|
|
122
|
-
/* compare changes */
|
|
123
|
-
if (after === before) {
|
|
124
|
-
return
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
var validation = column.validation
|
|
128
|
-
if (validation && typeof (validation == 'function')) {
|
|
129
|
-
if (!validation.call(this, after, before, record, column)) {
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.onRecordChanged({ [column.name]: after }, row, column)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
84
|
this.addEventListener('focus-change', e => {
|
|
138
85
|
this.focused = (e as CustomEvent).detail
|
|
139
86
|
this.focus()
|
|
140
87
|
this.requestUpdate()
|
|
141
88
|
})
|
|
142
|
-
|
|
143
|
-
/* record reset processing */
|
|
144
|
-
this.addEventListener('record-reset', e => {
|
|
145
|
-
var { record, row } = (e as CustomEvent).detail
|
|
146
|
-
|
|
147
|
-
this.onRecordChanged(record['__origin__'], row, null)
|
|
148
|
-
})
|
|
149
89
|
}
|
|
150
90
|
|
|
151
91
|
onWheelEvent(e: WheelEvent) {
|
|
@@ -155,89 +95,31 @@ export class DataGrid extends LitElement {
|
|
|
155
95
|
supportsPassive || e.preventDefault()
|
|
156
96
|
}
|
|
157
97
|
|
|
98
|
+
onSelectRecordChanged({
|
|
99
|
+
selectedRecords,
|
|
100
|
+
added,
|
|
101
|
+
removed
|
|
102
|
+
}: {
|
|
103
|
+
selectedRecords: GristRecord[]
|
|
104
|
+
added: GristRecord[]
|
|
105
|
+
removed: GristRecord[]
|
|
106
|
+
}): void {
|
|
107
|
+
super.onSelectRecordChanged({ selectedRecords, added, removed })
|
|
108
|
+
|
|
109
|
+
this.header.requestUpdate()
|
|
110
|
+
this.body.requestUpdate()
|
|
111
|
+
}
|
|
112
|
+
|
|
158
113
|
onRecordChanged(
|
|
159
114
|
recordData: GristRecord,
|
|
160
115
|
row: number,
|
|
161
116
|
column: ColumnConfig | null /* TODO column should be removed */
|
|
162
117
|
) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
/* 빈 그리드로 시작한 경우, data 설정이 되어있지 않을 수 있다. */
|
|
166
|
-
var records = this.data.records
|
|
167
|
-
|
|
168
|
-
var beforeRecord: GristRecord = records[row]
|
|
169
|
-
var afterRecord: GristRecord
|
|
170
|
-
var wantToDelete = false
|
|
171
|
-
var wantToAppend = false
|
|
172
|
-
|
|
173
|
-
if (!recordData) {
|
|
174
|
-
if (!beforeRecord) {
|
|
175
|
-
/* recordData가 없고, beforeRecord도 없다면, 레코드 생성 중에 리셋된 경우이므로 아무것도 하지 않는다. */
|
|
176
|
-
this.requestUpdate()
|
|
177
|
-
return
|
|
178
|
-
} else {
|
|
179
|
-
/*
|
|
180
|
-
* beforeRecord가 있는데, 빈데이타로 업데이트하고자 한다면,
|
|
181
|
-
* 삭제하고자 하는 의도로 이해된다. (주의 필요)
|
|
182
|
-
*/
|
|
183
|
-
if (beforeRecord['__dirty__'] == '+') {
|
|
184
|
-
wantToDelete = true
|
|
185
|
-
} else {
|
|
186
|
-
afterRecord = {
|
|
187
|
-
...beforeRecord,
|
|
188
|
-
__dirty__: '-'
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} else {
|
|
193
|
-
if (!beforeRecord) {
|
|
194
|
-
/* 기존 레코드가 없는 경우에는 새로운 레코드가 생성된다 */
|
|
195
|
-
afterRecord = {
|
|
196
|
-
...recordData,
|
|
197
|
-
__dirty__: '+'
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
wantToAppend = true
|
|
201
|
-
} else {
|
|
202
|
-
let beforeDirty = beforeRecord.__dirty__
|
|
203
|
-
if (beforeDirty == '+') {
|
|
204
|
-
/* 기존에 새로 생성된 레코드가 있었으며 계속 수정중이다. */
|
|
205
|
-
afterRecord = {
|
|
206
|
-
...beforeRecord,
|
|
207
|
-
...recordData,
|
|
208
|
-
__dirty__: '+'
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
/* 기존에 레코드가 있었으며 계속 수정중이다. */
|
|
212
|
-
afterRecord = {
|
|
213
|
-
...beforeRecord,
|
|
214
|
-
...recordData,
|
|
215
|
-
__dirty__: 'M'
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (wantToAppend) {
|
|
222
|
-
records.push(afterRecord!)
|
|
223
|
-
} else if (wantToDelete) {
|
|
224
|
-
records.splice(row, 1)
|
|
225
|
-
} else {
|
|
226
|
-
records.splice(row, 1, afterRecord!)
|
|
227
|
-
}
|
|
118
|
+
/* record-viewer 등 grid 외에서 변경되는 경우에도 header와 body를 refresh 하도록 한다. */
|
|
119
|
+
super.onRecordChanged(recordData, row, column)
|
|
228
120
|
|
|
229
|
-
this.
|
|
230
|
-
|
|
231
|
-
bubbles: true,
|
|
232
|
-
composed: true,
|
|
233
|
-
detail: {
|
|
234
|
-
before: beforeRecord,
|
|
235
|
-
after: afterRecord!,
|
|
236
|
-
column,
|
|
237
|
-
row
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
)
|
|
121
|
+
this.header.requestUpdate()
|
|
122
|
+
this.body.requestUpdate()
|
|
241
123
|
}
|
|
242
124
|
|
|
243
125
|
updated(changes: PropertyValues<this>) {
|
package/src/data-grist.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import '@material/mwc-icon'
|
|
2
2
|
import './record-partial'
|
|
3
3
|
|
|
4
|
-
import { css, html,
|
|
4
|
+
import { css, html, PropertyValues } from 'lit'
|
|
5
5
|
import { customElement, property } from 'lit/decorators.js'
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { DataManipulator } from '../data-manipulator'
|
|
8
|
+
import { GristRecord } from '../types'
|
|
9
9
|
|
|
10
10
|
@customElement('ox-list')
|
|
11
|
-
export class DataList extends
|
|
11
|
+
export class DataList extends DataManipulator {
|
|
12
12
|
static styles = [
|
|
13
13
|
css`
|
|
14
14
|
:host {
|
|
@@ -42,8 +42,6 @@ export class DataList extends LitElement {
|
|
|
42
42
|
`
|
|
43
43
|
]
|
|
44
44
|
|
|
45
|
-
@property({ type: Object }) config: GristConfig = ZERO_CONFIG
|
|
46
|
-
@property({ type: Object }) data: GristData = ZERO_DATA
|
|
47
45
|
@property({ type: Boolean }) isTop: boolean = false
|
|
48
46
|
@property({ type: Array }) private _records: GristRecord[] = []
|
|
49
47
|
|
|
@@ -71,158 +69,6 @@ export class DataList extends LitElement {
|
|
|
71
69
|
|
|
72
70
|
this.isTop = this.scrollTop == 0
|
|
73
71
|
})
|
|
74
|
-
|
|
75
|
-
this.addEventListener('select-record-change', e => {
|
|
76
|
-
var {
|
|
77
|
-
records: selectedRecords,
|
|
78
|
-
added = [],
|
|
79
|
-
removed = []
|
|
80
|
-
} = (e as CustomEvent).detail as {
|
|
81
|
-
records: GristRecord[]
|
|
82
|
-
added: GristRecord[]
|
|
83
|
-
removed: GristRecord[]
|
|
84
|
-
}
|
|
85
|
-
var { records } = this.data || {}
|
|
86
|
-
var { selectable = false } = this.config.rows || {}
|
|
87
|
-
|
|
88
|
-
if (!records || !selectable) {
|
|
89
|
-
return
|
|
90
|
-
} else if (selectable && !selectable.multiple) {
|
|
91
|
-
records.forEach(record => (record['__selected__'] = false))
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (selectedRecords) {
|
|
95
|
-
records.forEach(record => (record['__selected__'] = false))
|
|
96
|
-
selectedRecords.forEach(record => (record['__selected__'] = true))
|
|
97
|
-
} else {
|
|
98
|
-
removed.forEach(record => (record['__selected__'] = false))
|
|
99
|
-
added.forEach(record => (record['__selected__'] = true))
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
this.requestUpdate()
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
/* field change processing */
|
|
106
|
-
this.addEventListener('field-change', e => {
|
|
107
|
-
var { after, before, column, record, row } = (e as CustomEvent).detail as {
|
|
108
|
-
after: any
|
|
109
|
-
before: any
|
|
110
|
-
column: ColumnConfig
|
|
111
|
-
record: GristRecord
|
|
112
|
-
row: number
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/* compare changes */
|
|
116
|
-
if (after === before) {
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
var validation = column.validation
|
|
121
|
-
if (validation && typeof validation == 'function') {
|
|
122
|
-
if (!validation.call(this, after, before, record, column)) {
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.onRecordChanged({ [column.name]: after }, row, column)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
/* record reset processing */
|
|
131
|
-
this.addEventListener('record-reset', e => {
|
|
132
|
-
var { record, row } = (e as CustomEvent).detail as {
|
|
133
|
-
record: GristRecord
|
|
134
|
-
row: number
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
this.onRecordChanged(record['__origin__'], row, null)
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
onRecordChanged(
|
|
142
|
-
recordData: GristRecord,
|
|
143
|
-
row: number,
|
|
144
|
-
column: ColumnConfig | null /* TODO column should be removed */
|
|
145
|
-
) {
|
|
146
|
-
// TODO 오브젝트나 배열 타입인 경우 deepCompare 후에 변경 적용 여부를 결정한다.
|
|
147
|
-
|
|
148
|
-
/* 빈 그리드로 시작한 경우, data 설정이 되어있지 않을 수 있다. */
|
|
149
|
-
var records = this.data.records
|
|
150
|
-
|
|
151
|
-
var beforeRecord = records[row]
|
|
152
|
-
var afterRecord: GristRecord
|
|
153
|
-
var wantToDelete = false
|
|
154
|
-
var wantToAppend = false
|
|
155
|
-
|
|
156
|
-
if (!recordData) {
|
|
157
|
-
if (!beforeRecord) {
|
|
158
|
-
/* recordData가 없고, beforeRecord도 없다면, 레코드 생성 중에 리셋된 경우이므로 아무것도 하지 않는다. */
|
|
159
|
-
this.requestUpdate()
|
|
160
|
-
return
|
|
161
|
-
} else {
|
|
162
|
-
/*
|
|
163
|
-
* beforeRecord가 있는데, 빈데이타로 업데이트하고자 한다면,
|
|
164
|
-
* 삭제하고자 하는 의도로 이해된다. (주의 필요)
|
|
165
|
-
*/
|
|
166
|
-
if (beforeRecord['__dirty__'] == '+') {
|
|
167
|
-
wantToDelete = true
|
|
168
|
-
} else {
|
|
169
|
-
afterRecord = {
|
|
170
|
-
...beforeRecord,
|
|
171
|
-
__dirty__: '-'
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
if (!beforeRecord) {
|
|
177
|
-
/* 기존 레코드가 없는 경우에는 새로운 레코드가 생성된다 */
|
|
178
|
-
afterRecord = {
|
|
179
|
-
...recordData,
|
|
180
|
-
__dirty__: '+'
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
wantToAppend = true
|
|
184
|
-
} else {
|
|
185
|
-
let beforeDirty = beforeRecord['__dirty__']
|
|
186
|
-
if (beforeDirty == '+') {
|
|
187
|
-
/* 기존에 새로 생성된 레코드가 있었으며 계속 수정중이다. */
|
|
188
|
-
afterRecord = {
|
|
189
|
-
...beforeRecord,
|
|
190
|
-
...recordData,
|
|
191
|
-
__dirty__: '+'
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
/* 기존에 레코드가 있었으며 계속 수정중이다. */
|
|
195
|
-
afterRecord = {
|
|
196
|
-
...beforeRecord,
|
|
197
|
-
...recordData,
|
|
198
|
-
__dirty__: 'M'
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (wantToAppend) {
|
|
205
|
-
records.push(afterRecord!)
|
|
206
|
-
} else if (wantToDelete) {
|
|
207
|
-
records.splice(row, 1)
|
|
208
|
-
} else {
|
|
209
|
-
records.splice(row, 1, afterRecord!)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
this.dispatchEvent(
|
|
213
|
-
new CustomEvent('record-change', {
|
|
214
|
-
bubbles: true,
|
|
215
|
-
composed: true,
|
|
216
|
-
detail: {
|
|
217
|
-
before: beforeRecord,
|
|
218
|
-
after: afterRecord!,
|
|
219
|
-
column,
|
|
220
|
-
row
|
|
221
|
-
}
|
|
222
|
-
})
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
this.requestUpdate()
|
|
226
72
|
}
|
|
227
73
|
|
|
228
74
|
updated(changes: PropertyValues<this>) {
|