@operato/data-grist 1.0.0-beta.9 → 1.0.0
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/.storybook/main.js +3 -0
- package/.storybook/server.mjs +8 -0
- package/CHANGELOG.md +392 -0
- package/demo/data-grist-test.html +1 -1
- package/demo/index.html +13 -2
- package/demo/report-test.html +1 -1
- package/dist/src/configure/zero-config.d.ts +2 -0
- package/dist/src/configure/zero-config.js +3 -1
- package/dist/src/configure/zero-config.js.map +1 -1
- package/dist/src/data-card/data-card-field.d.ts +1 -1
- package/dist/src/data-card/data-card-field.js +3 -2
- package/dist/src/data-card/data-card-field.js.map +1 -1
- package/dist/src/data-card/data-card.js +1 -0
- package/dist/src/data-card/data-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +4 -2
- package/dist/src/data-grid/data-grid-body.js +74 -40
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-field.d.ts +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-footer.d.ts +2 -2
- package/dist/src/data-grid/data-grid-footer.js +9 -10
- package/dist/src/data-grid/data-grid-footer.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.d.ts +4 -6
- package/dist/src/data-grid/data-grid-header.js +39 -48
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +2 -2
- package/dist/src/data-grid/data-grid.js +4 -3
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +9 -11
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
- package/dist/src/data-grist.d.ts +7 -5
- package/dist/src/data-grist.js +154 -112
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/record-partial.js +1 -5
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/data-manipulator.d.ts +4 -1
- package/dist/src/data-manipulator.js +12 -0
- package/dist/src/data-manipulator.js.map +1 -1
- package/dist/src/data-provider.d.ts +4 -6
- package/dist/src/data-provider.js +12 -23
- package/dist/src/data-provider.js.map +1 -1
- package/dist/src/data-report/data-report-body.d.ts +1 -1
- package/dist/src/data-report/data-report-body.js +4 -4
- package/dist/src/data-report/data-report-body.js.map +1 -1
- package/dist/src/data-report/data-report-header.js +4 -4
- package/dist/src/data-report/data-report-header.js.map +1 -1
- package/dist/src/editors/ox-grist-editor.d.ts +1 -1
- package/dist/src/editors/ox-grist-editor.js +7 -4
- package/dist/src/editors/ox-grist-editor.js.map +1 -1
- package/dist/src/filters/filter-checkbox.d.ts +1 -1
- package/dist/src/filters/filter-checkbox.js +1 -1
- package/dist/src/filters/filter-checkbox.js.map +1 -1
- package/dist/src/filters/filter-input-barcode.d.ts +3 -0
- package/dist/src/filters/{filter-input copy.js → filter-input-barcode.js} +8 -6
- package/dist/src/filters/filter-input-barcode.js.map +1 -0
- package/dist/src/filters/filter-input.js +1 -1
- package/dist/src/filters/filter-input.js.map +1 -1
- package/dist/src/filters/filter-styles.js +18 -23
- package/dist/src/filters/filter-styles.js.map +1 -1
- package/dist/src/filters/filters-form.js +5 -3
- package/dist/src/filters/filters-form.js.map +1 -1
- package/dist/src/filters/registry.d.ts +1 -1
- package/dist/src/filters/registry.js +10 -7
- package/dist/src/filters/registry.js.map +1 -1
- package/dist/src/gutters/gutter-button.js +5 -4
- package/dist/src/gutters/gutter-button.js.map +1 -1
- package/dist/src/gutters/gutter-dirty.d.ts +5 -1
- package/dist/src/gutters/gutter-dirty.js +17 -2
- package/dist/src/gutters/gutter-dirty.js.map +1 -1
- package/dist/src/gutters/gutter-row-selector.js +2 -1
- package/dist/src/gutters/gutter-row-selector.js.map +1 -1
- package/dist/src/gutters/gutter-sequence.js +15 -0
- package/dist/src/gutters/gutter-sequence.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +2 -4
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +2 -2
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
- package/dist/src/record-view/record-creator.js +0 -2
- package/dist/src/record-view/record-creator.js.map +1 -1
- package/dist/src/record-view/record-view-body.d.ts +0 -1
- package/dist/src/record-view/record-view-body.js +0 -5
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view-handler.d.ts +1 -1
- package/dist/src/record-view/record-view.d.ts +0 -1
- package/dist/src/record-view/record-view.js +1 -10
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-color.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-color.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-json5.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-json5.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-link.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-link.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-select.js +2 -2
- package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-text.js +6 -2
- package/dist/src/renderers/ox-grist-renderer-text.js.map +1 -1
- package/dist/src/sorters/sorters-control.d.ts +1 -1
- package/dist/src/sorters/sorters-control.js +5 -7
- package/dist/src/sorters/sorters-control.js.map +1 -1
- package/dist/src/types.d.ts +7 -4
- package/dist/src/types.js.map +1 -1
- package/dist/stories/{index.stories.d.ts → barcode-input-filter.stories.d.ts} +9 -13
- package/dist/stories/barcode-input-filter.stories.js +200 -0
- package/dist/stories/barcode-input-filter.stories.js.map +1 -0
- package/dist/stories/default-filters.stories.d.ts +20 -0
- package/dist/stories/default-filters.stories.js +187 -0
- package/dist/stories/default-filters.stories.js.map +1 -0
- package/dist/stories/empty-sorters.stories.d.ts +20 -0
- package/dist/stories/empty-sorters.stories.js +180 -0
- package/dist/stories/empty-sorters.stories.js.map +1 -0
- package/dist/stories/explicit-fetch.stories.d.ts +25 -0
- package/dist/stories/explicit-fetch.stories.js +186 -0
- package/dist/stories/explicit-fetch.stories.js.map +1 -0
- package/dist/stories/grist-modes.stories.d.ts +36 -0
- package/dist/stories/grist-modes.stories.js +448 -0
- package/dist/stories/grist-modes.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/src/configure/zero-config.ts +4 -1
- package/src/data-card/data-card-field.ts +5 -3
- package/src/data-card/data-card.ts +1 -0
- package/src/data-grid/data-grid-body.ts +96 -49
- package/src/data-grid/data-grid-field.ts +3 -2
- package/src/data-grid/data-grid-footer.ts +8 -9
- package/src/data-grid/data-grid-header.ts +38 -47
- package/src/data-grid/data-grid.ts +8 -6
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +11 -13
- package/src/data-grist.ts +179 -130
- package/src/data-list/record-partial.ts +1 -5
- package/src/data-manipulator.ts +12 -1
- package/src/data-provider.ts +13 -29
- package/src/data-report/data-report-body.ts +5 -5
- package/src/data-report/data-report-header.ts +5 -5
- package/src/editors/ox-grist-editor.ts +8 -5
- package/src/filters/filter-checkbox.ts +3 -3
- package/src/filters/filter-input-barcode.ts +33 -0
- package/src/filters/filter-input.ts +3 -3
- package/src/filters/filter-styles.ts +18 -23
- package/src/filters/filters-form.ts +5 -3
- package/src/filters/registry.ts +11 -8
- package/src/gutters/gutter-button.ts +5 -4
- package/src/gutters/gutter-dirty.ts +21 -3
- package/src/gutters/gutter-row-selector.ts +2 -1
- package/src/gutters/gutter-sequence.ts +18 -2
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +2 -4
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +2 -2
- package/src/record-view/record-creator.ts +0 -2
- package/src/record-view/record-view-body.ts +0 -2
- package/src/record-view/record-view.ts +1 -7
- package/src/renderers/ox-grist-renderer-color.ts +3 -2
- package/src/renderers/ox-grist-renderer-json5.ts +3 -2
- package/src/renderers/ox-grist-renderer-link.ts +3 -2
- package/src/renderers/ox-grist-renderer-select.ts +2 -2
- package/src/renderers/ox-grist-renderer-text.ts +8 -2
- package/src/sorters/sorters-control.ts +6 -9
- package/src/types.ts +8 -4
- package/stories/barcode-input-filter.stories.ts +220 -0
- package/stories/default-filters.stories.ts +204 -0
- package/stories/empty-sorters.stories.ts +197 -0
- package/stories/explicit-fetch.stories.ts +205 -0
- package/stories/grist-modes.stories.ts +488 -0
- package/themes/grist-theme.css +1 -1
- package/dist/src/filters/filter-input copy.d.ts +0 -2
- package/dist/src/filters/filter-input copy.js.map +0 -1
- package/dist/src/filters/filter-mwc-checkbox.d.ts +0 -4
- package/dist/src/filters/filter-mwc-checkbox.js +0 -30
- package/dist/src/filters/filter-mwc-checkbox.js.map +0 -1
- package/dist/src/filters/filter-mwc-textfield.d.ts +0 -3
- package/dist/src/filters/filter-mwc-textfield.js +0 -27
- package/dist/src/filters/filter-mwc-textfield.js.map +0 -1
- package/dist/src/filters/grist-filter-registry.d.ts +0 -12
- package/dist/src/filters/grist-filter-registry.js +0 -47
- package/dist/src/filters/grist-filter-registry.js.map +0 -1
- package/dist/src/filters/ox-grist-filter-editor-checkbox.d.ts +0 -5
- package/dist/src/filters/ox-grist-filter-editor-checkbox.js +0 -27
- package/dist/src/filters/ox-grist-filter-editor-checkbox.js.map +0 -1
- package/dist/src/filters/ox-grist-filter-editor-input.d.ts +0 -4
- package/dist/src/filters/ox-grist-filter-editor-input.js +0 -54
- package/dist/src/filters/ox-grist-filter-editor-input.js.map +0 -1
- package/dist/src/filters/ox-grist-filter-editor-select.d.ts +0 -4
- package/dist/src/filters/ox-grist-filter-editor-select.js +0 -46
- package/dist/src/filters/ox-grist-filter-editor-select.js.map +0 -1
- package/dist/src/filters/ox-grist-filter-editor.d.ts +0 -16
- package/dist/src/filters/ox-grist-filter-editor.js +0 -122
- package/dist/src/filters/ox-grist-filter-editor.js.map +0 -1
- package/dist/stories/index.stories.js +0 -33
- package/dist/stories/index.stories.js.map +0 -1
- package/stories/index.stories.ts +0 -52
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import './data-grid-field'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { LitElement, PropertyValues, css, html } from 'lit'
|
|
5
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
3
|
+
import { css, html, LitElement, PropertyValues } from 'lit'
|
|
6
4
|
import { customElement, property, query, state } from 'lit/decorators.js'
|
|
5
|
+
import debounce from 'lodash-es/debounce'
|
|
7
6
|
|
|
8
|
-
import { DataGridField } from './data-grid-field'
|
|
9
|
-
import { RecordViewHandler } from '../record-view/record-view-handler'
|
|
10
7
|
import { TooltipStyles } from '@operato/styles'
|
|
8
|
+
import { sleep } from '@operato/utils'
|
|
9
|
+
|
|
10
|
+
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
11
|
+
import { RecordViewHandler } from '../record-view/record-view-handler'
|
|
12
|
+
import { ColumnConfig, GristConfig, GristData, GristRecord } from '../types'
|
|
13
|
+
import { supportsPassive } from '../utils'
|
|
14
|
+
import { dataGridBodyStyle } from './data-grid-body-style'
|
|
15
|
+
import { DataGridField } from './data-grid-field'
|
|
11
16
|
import { dataGridBodyClickHandler } from './event-handlers/data-grid-body-click-handler'
|
|
12
17
|
import { dataGridBodyDblclickHandler } from './event-handlers/data-grid-body-dblclick-handler'
|
|
13
18
|
import { dataGridBodyKeydownHandler } from './event-handlers/data-grid-body-keydown-handler'
|
|
14
|
-
import { dataGridBodyStyle } from './data-grid-body-style'
|
|
15
|
-
import debounce from 'lodash-es/debounce'
|
|
16
|
-
import { sleep } from '@operato/utils'
|
|
17
|
-
import { supportsPassive } from '../utils'
|
|
18
19
|
|
|
19
20
|
const THRESHOLD = 300
|
|
20
21
|
const DATA_PADDING = 3
|
|
@@ -192,6 +193,17 @@ export class DataGridBody extends LitElement {
|
|
|
192
193
|
}
|
|
193
194
|
})
|
|
194
195
|
|
|
196
|
+
this.addEventListener('set-select-block', async e => {
|
|
197
|
+
e.stopPropagation()
|
|
198
|
+
|
|
199
|
+
const { startRow = -1, startColumn = -1, endRow = -1, endColumn = -1 } = ((e as CustomEvent).detail as any) || {}
|
|
200
|
+
|
|
201
|
+
const start = this.getFieldByIndex(startRow, startColumn) as DataGridField
|
|
202
|
+
const end = this.getFieldByIndex(endRow, endColumn) as DataGridField
|
|
203
|
+
|
|
204
|
+
this.setSelectBlock(start, end)
|
|
205
|
+
})
|
|
206
|
+
|
|
195
207
|
this.renderRoot.addEventListener('mousemove', (event: Event) => {
|
|
196
208
|
const e = event as MouseEvent
|
|
197
209
|
if (e.buttons !== 1) {
|
|
@@ -203,19 +215,15 @@ export class DataGridBody extends LitElement {
|
|
|
203
215
|
|
|
204
216
|
if (!this._selectBlock || this._selectBlockWillBeReset) {
|
|
205
217
|
this._selectBlockWillBeReset = false
|
|
206
|
-
this.
|
|
207
|
-
|
|
208
|
-
this.dispatchEvent(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
// column: field!.columnIndex
|
|
216
|
-
// }
|
|
217
|
-
})
|
|
218
|
-
)
|
|
218
|
+
this.setSelectBlock(field)
|
|
219
|
+
|
|
220
|
+
// this.dispatchEvent(
|
|
221
|
+
// new CustomEvent('focus-change', {
|
|
222
|
+
// bubbles: true,
|
|
223
|
+
// composed: true,
|
|
224
|
+
// detail: undefined
|
|
225
|
+
// })
|
|
226
|
+
// )
|
|
219
227
|
|
|
220
228
|
return
|
|
221
229
|
}
|
|
@@ -234,25 +242,7 @@ export class DataGridBody extends LitElement {
|
|
|
234
242
|
if (start && end !== field) {
|
|
235
243
|
end = field
|
|
236
244
|
|
|
237
|
-
|
|
238
|
-
const right = left === start ? end : start
|
|
239
|
-
const top = start.rowIndex < end.rowIndex ? start : end
|
|
240
|
-
const bottom = top === start ? end : start
|
|
241
|
-
|
|
242
|
-
const { offsetLeft } = left
|
|
243
|
-
const { offsetTop } = top
|
|
244
|
-
const width = right.offsetLeft - offsetLeft + right.offsetWidth
|
|
245
|
-
const height = bottom.offsetTop - offsetTop + bottom.offsetHeight
|
|
246
|
-
|
|
247
|
-
this.style.setProperty('--select-box-left', offsetLeft - 1 + 'px')
|
|
248
|
-
this.style.setProperty('--select-box-top', offsetTop - 1 + 'px')
|
|
249
|
-
this.style.setProperty('--select-box-width', width + 'px')
|
|
250
|
-
this.style.setProperty('--select-box-height', height + 'px')
|
|
251
|
-
|
|
252
|
-
this._selectBlock = {
|
|
253
|
-
start,
|
|
254
|
-
end
|
|
255
|
-
}
|
|
245
|
+
this.setSelectBlock(start, end)
|
|
256
246
|
}
|
|
257
247
|
})
|
|
258
248
|
|
|
@@ -277,6 +267,18 @@ export class DataGridBody extends LitElement {
|
|
|
277
267
|
)
|
|
278
268
|
}
|
|
279
269
|
|
|
270
|
+
getFieldByIndex(rowIndex: number, columnIndex: number) {
|
|
271
|
+
if (rowIndex < 0) {
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
var columns = this.columns.filter(column => !column.hidden).length
|
|
276
|
+
|
|
277
|
+
return this.renderRoot.children.item(
|
|
278
|
+
rowIndex * (columns + 1) /* 1 means last dummy column */ + ((columnIndex + columns) % columns)
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
|
|
280
282
|
_onWheelEvent(e: WheelEvent) {
|
|
281
283
|
if (this.scrollHeight <= this.clientHeight) {
|
|
282
284
|
var delta = Math.max(-1, Math.min(1, e.deltaY || 0))
|
|
@@ -316,7 +318,7 @@ export class DataGridBody extends LitElement {
|
|
|
316
318
|
return
|
|
317
319
|
}
|
|
318
320
|
|
|
319
|
-
this.
|
|
321
|
+
this.setSelectBlock()
|
|
320
322
|
|
|
321
323
|
let { top, left } = calcScrollPos(this, element)
|
|
322
324
|
// TODO this.scroll()을 사용하면, 효과가 좋으나 left 계산에 문제가 있는 것 같음.
|
|
@@ -375,11 +377,17 @@ export class DataGridBody extends LitElement {
|
|
|
375
377
|
)
|
|
376
378
|
}
|
|
377
379
|
|
|
378
|
-
getSelectedBlockValues(): Array<Array<any>> | undefined {
|
|
380
|
+
getSelectedBlockValues(): Array<Array<any>> | any | undefined {
|
|
379
381
|
var { start, end } = this._selectBlock || {}
|
|
380
382
|
|
|
381
383
|
if (!(start && end)) {
|
|
382
384
|
start = this.focusedField
|
|
385
|
+
|
|
386
|
+
if (typeof start!.value === 'string' || typeof start!.value === 'number') {
|
|
387
|
+
const selection = document.getSelection()
|
|
388
|
+
return selection?.toString() || this.focusedField?.value
|
|
389
|
+
}
|
|
390
|
+
|
|
383
391
|
end = start
|
|
384
392
|
}
|
|
385
393
|
|
|
@@ -400,14 +408,17 @@ export class DataGridBody extends LitElement {
|
|
|
400
408
|
const columnIndex = start + index
|
|
401
409
|
const column = columns[columnIndex]
|
|
402
410
|
|
|
403
|
-
return record[column.name]
|
|
411
|
+
return record?.[column.name]
|
|
404
412
|
})
|
|
405
413
|
})
|
|
406
414
|
}
|
|
407
415
|
}
|
|
408
416
|
|
|
409
417
|
async copy() {
|
|
410
|
-
|
|
418
|
+
const copied = this.getSelectedBlockValues()
|
|
419
|
+
await navigator.clipboard.writeText(
|
|
420
|
+
copied instanceof Array ? JSON.stringify(this.getSelectedBlockValues()) : copied
|
|
421
|
+
)
|
|
411
422
|
|
|
412
423
|
const selectBlock = this.selectBlock
|
|
413
424
|
if (selectBlock) {
|
|
@@ -431,11 +442,18 @@ export class DataGridBody extends LitElement {
|
|
|
431
442
|
const { row, column } = this.focused
|
|
432
443
|
const { records } = this.data
|
|
433
444
|
const columns = this.columns.filter(column => !column.hidden)
|
|
445
|
+
var block: Array<Array<any>>
|
|
434
446
|
|
|
435
|
-
|
|
447
|
+
try {
|
|
448
|
+
var parsed = JSON.parse(text)
|
|
449
|
+
} catch (ex) {
|
|
450
|
+
parsed = text
|
|
451
|
+
}
|
|
436
452
|
|
|
437
|
-
if (!(
|
|
438
|
-
|
|
453
|
+
if (!(parsed instanceof Array)) {
|
|
454
|
+
block = [[parsed]]
|
|
455
|
+
} else {
|
|
456
|
+
block = parsed
|
|
439
457
|
}
|
|
440
458
|
|
|
441
459
|
block.forEach((record, rowIndex) => {
|
|
@@ -450,7 +468,7 @@ export class DataGridBody extends LitElement {
|
|
|
450
468
|
|
|
451
469
|
record.map((item, columnIndex) => {
|
|
452
470
|
const targetColumn = columns[column + columnIndex]
|
|
453
|
-
if (!targetColumn.gutterName) {
|
|
471
|
+
if (targetColumn && !targetColumn.gutterName && targetColumn.record.editable) {
|
|
454
472
|
this.dispatchEvent(
|
|
455
473
|
new CustomEvent('field-change', {
|
|
456
474
|
bubbles: true,
|
|
@@ -471,4 +489,33 @@ export class DataGridBody extends LitElement {
|
|
|
471
489
|
console.error(e)
|
|
472
490
|
}
|
|
473
491
|
}
|
|
492
|
+
|
|
493
|
+
setSelectBlock(start?: DataGridField, end?: DataGridField) {
|
|
494
|
+
this._selectBlock = start && { start, end }
|
|
495
|
+
|
|
496
|
+
if (start && end && start !== end) {
|
|
497
|
+
const left = start.columnIndex < end.columnIndex ? start : end
|
|
498
|
+
const right = left === start ? end : start
|
|
499
|
+
const top = start.rowIndex < end.rowIndex ? start : end
|
|
500
|
+
const bottom = top === start ? end : start
|
|
501
|
+
|
|
502
|
+
const { offsetLeft } = left
|
|
503
|
+
const { offsetTop } = top
|
|
504
|
+
const width = right.offsetLeft - offsetLeft + right.offsetWidth
|
|
505
|
+
const height = bottom.offsetTop - offsetTop + bottom.offsetHeight
|
|
506
|
+
|
|
507
|
+
this.style.setProperty('--select-box-left', offsetLeft - 1 + 'px')
|
|
508
|
+
this.style.setProperty('--select-box-top', offsetTop - 1 + 'px')
|
|
509
|
+
this.style.setProperty('--select-box-width', width + 'px')
|
|
510
|
+
this.style.setProperty('--select-box-height', height + 'px')
|
|
511
|
+
|
|
512
|
+
this.dispatchEvent(
|
|
513
|
+
new CustomEvent('focus-change', {
|
|
514
|
+
bubbles: true,
|
|
515
|
+
composed: true,
|
|
516
|
+
detail: undefined
|
|
517
|
+
})
|
|
518
|
+
)
|
|
519
|
+
}
|
|
520
|
+
}
|
|
474
521
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LitElement, PropertyValues, TemplateResult, css, html } from 'lit'
|
|
1
|
+
import { css, html, LitElement, PropertyValues, TemplateResult } from 'lit'
|
|
3
2
|
import { customElement, property } from 'lit/decorators.js'
|
|
4
3
|
|
|
5
4
|
import { TooltipStyles } from '@operato/styles'
|
|
5
|
+
|
|
6
6
|
import { ZERO_COLUMN } from '../configure/zero-config'
|
|
7
|
+
import { ColumnConfig, GristRecord } from '../types'
|
|
7
8
|
|
|
8
9
|
const DEFAULT_TEXT_ALIGN = 'left'
|
|
9
10
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import '@material/mwc-icon'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { LitElement, css, html } from 'lit'
|
|
5
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
3
|
+
import { css, html, LitElement } from 'lit'
|
|
6
4
|
import { customElement, property } from 'lit/decorators.js'
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { ZERO_DATA, ZERO_PAGES } from '../configure/zero-config'
|
|
7
|
+
import { GristData, PaginationConfig } from '../types'
|
|
10
8
|
|
|
11
9
|
@customElement('ox-grid-footer')
|
|
12
10
|
export class DataGridFooter extends LitElement {
|
|
@@ -57,11 +55,12 @@ export class DataGridFooter extends LitElement {
|
|
|
57
55
|
`
|
|
58
56
|
]
|
|
59
57
|
|
|
60
|
-
@property() config: GristConfig = ZERO_CONFIG
|
|
61
58
|
@property() data: GristData = ZERO_DATA
|
|
59
|
+
@property() pagination: PaginationConfig = {}
|
|
62
60
|
|
|
63
61
|
_gotoPage(page: number) {
|
|
64
|
-
var {
|
|
62
|
+
var { pages = ZERO_PAGES } = this.pagination || {}
|
|
63
|
+
var { limit = pages[0], total = 0 } = this.data
|
|
65
64
|
|
|
66
65
|
if (page > Math.ceil(total / limit) || page <= 0) {
|
|
67
66
|
return
|
|
@@ -74,8 +73,8 @@ export class DataGridFooter extends LitElement {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
render() {
|
|
77
|
-
var {
|
|
78
|
-
var { pages =
|
|
76
|
+
var { pages = ZERO_PAGES } = this.pagination || {}
|
|
77
|
+
var { records = [], page = 1, limit = pages[0], total = 0 } = this.data
|
|
79
78
|
|
|
80
79
|
var begin = records.length == 0 ? 0 : limit * (page - 1) + 1
|
|
81
80
|
var end = records.length == 0 ? 0 : begin + records.length - 1
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import '@operato/popup/ox-popup.js'
|
|
2
2
|
import '@material/mwc-icon'
|
|
3
3
|
|
|
4
|
-
import { css, html, LitElement
|
|
5
|
-
import { customElement, property
|
|
4
|
+
import { css, html, LitElement } from 'lit'
|
|
5
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
6
6
|
import throttle from 'lodash-es/throttle'
|
|
7
7
|
|
|
8
8
|
import { OxPopup } from '@operato/popup'
|
|
9
|
-
import {
|
|
9
|
+
import { TooltipStyles } from '@operato/styles'
|
|
10
|
+
import { closestElement, detectOverflow } from '@operato/utils'
|
|
10
11
|
|
|
11
|
-
import { ZERO_COLUMNS,
|
|
12
|
+
import { ZERO_COLUMNS, ZERO_DATA } from '../configure/zero-config'
|
|
12
13
|
import { FilterStyles } from '../filters/filter-styles'
|
|
13
14
|
import { getFilterRenderer } from '../filters/registry'
|
|
14
|
-
import { ColumnConfig, FilterConfigObject, FilterValue,
|
|
15
|
+
import { ColumnConfig, FilterConfigObject, FilterValue, GristData, SortersConfig } from '../types'
|
|
15
16
|
|
|
16
17
|
@customElement('ox-grid-header')
|
|
17
18
|
export class DataGridHeader extends LitElement {
|
|
18
19
|
static styles = [
|
|
19
20
|
FilterStyles,
|
|
21
|
+
TooltipStyles,
|
|
20
22
|
css`
|
|
21
23
|
:host {
|
|
22
24
|
display: grid;
|
|
@@ -78,6 +80,7 @@ export class DataGridHeader extends LitElement {
|
|
|
78
80
|
span[splitter] {
|
|
79
81
|
cursor: col-resize;
|
|
80
82
|
border-right: var(--grid-header-splitter-border);
|
|
83
|
+
margin-right: 0;
|
|
81
84
|
}
|
|
82
85
|
span[splitter]:hover {
|
|
83
86
|
border-right: var(--grid-header-splitter-border-hover);
|
|
@@ -112,12 +115,11 @@ export class DataGridHeader extends LitElement {
|
|
|
112
115
|
`
|
|
113
116
|
]
|
|
114
117
|
|
|
115
|
-
@property({ type: Object }) config: GristConfig = ZERO_CONFIG
|
|
116
118
|
@property({ type: Array }) columns: ColumnConfig[] = ZERO_COLUMNS
|
|
117
119
|
@property({ type: Object }) data: GristData = ZERO_DATA
|
|
118
120
|
|
|
119
|
-
@
|
|
120
|
-
@
|
|
121
|
+
@property({ type: Object }) sorters: SortersConfig = []
|
|
122
|
+
@property({ type: Object }) filters: FilterValue[] = []
|
|
121
123
|
|
|
122
124
|
private _lastAccVal?: number
|
|
123
125
|
private _throttledNotifier?: any
|
|
@@ -126,20 +128,12 @@ export class DataGridHeader extends LitElement {
|
|
|
126
128
|
super.connectedCallback()
|
|
127
129
|
|
|
128
130
|
const grid = closestElement('ox-grist', this)
|
|
129
|
-
grid?.addEventListener('sorters-change', (e: Event) => {
|
|
130
|
-
const { sorters, from } = (e as CustomEvent).detail || {}
|
|
131
|
-
if (from === 'data-grid-header') {
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
this._sorters = [...(sorters || [])]
|
|
136
|
-
})
|
|
137
131
|
|
|
138
|
-
|
|
132
|
+
this?.addEventListener('filter-change', (e: Event) => {
|
|
139
133
|
const { name, operator, value } = (e as CustomEvent).detail
|
|
140
|
-
const filters = this.
|
|
134
|
+
const filters = this.filters instanceof Array ? [...this.filters] : []
|
|
141
135
|
|
|
142
|
-
if (value
|
|
136
|
+
if (value == null) {
|
|
143
137
|
const index = filters.findIndex(filter => filter.name === name)
|
|
144
138
|
if (index === -1) {
|
|
145
139
|
return
|
|
@@ -156,7 +150,7 @@ export class DataGridHeader extends LitElement {
|
|
|
156
150
|
}
|
|
157
151
|
|
|
158
152
|
grid?.dispatchEvent(
|
|
159
|
-
new CustomEvent('
|
|
153
|
+
new CustomEvent('fetch-params-change', {
|
|
160
154
|
detail: {
|
|
161
155
|
filters,
|
|
162
156
|
from: 'data-grid-header'
|
|
@@ -164,15 +158,6 @@ export class DataGridHeader extends LitElement {
|
|
|
164
158
|
})
|
|
165
159
|
)
|
|
166
160
|
})
|
|
167
|
-
|
|
168
|
-
grid?.addEventListener('filters-change', (e: Event) => {
|
|
169
|
-
const { filters, from } = (e as CustomEvent).detail || {}
|
|
170
|
-
if (from === 'data-grid-header') {
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
this._filters = [...(filters || [])]
|
|
175
|
-
})
|
|
176
161
|
}
|
|
177
162
|
|
|
178
163
|
render() {
|
|
@@ -183,7 +168,20 @@ export class DataGridHeader extends LitElement {
|
|
|
183
168
|
!column.hidden
|
|
184
169
|
? html`
|
|
185
170
|
<div ?gutter=${column.type == 'gutter'} column>
|
|
186
|
-
<span
|
|
171
|
+
<span
|
|
172
|
+
for-title
|
|
173
|
+
@click=${(e: MouseEvent) => this._changeSort(column)}
|
|
174
|
+
@mouseover=${(e: MouseEvent) => {
|
|
175
|
+
const element = e.target as HTMLSpanElement
|
|
176
|
+
|
|
177
|
+
if (detectOverflow(element)) {
|
|
178
|
+
element.setAttribute('data-tooltip', element.textContent!.trim())
|
|
179
|
+
}
|
|
180
|
+
}}
|
|
181
|
+
@mouseout=${(e: MouseEvent) => {
|
|
182
|
+
const element = e.target as HTMLSpanElement
|
|
183
|
+
element.removeAttribute('data-tooltip')
|
|
184
|
+
}}
|
|
187
185
|
>${this._renderHeader(column)}
|
|
188
186
|
</span>
|
|
189
187
|
|
|
@@ -221,7 +219,7 @@ export class DataGridHeader extends LitElement {
|
|
|
221
219
|
}
|
|
222
220
|
|
|
223
221
|
_renderSortHeader(column: ColumnConfig) {
|
|
224
|
-
var sorters = this.
|
|
222
|
+
var sorters = this.sorters || []
|
|
225
223
|
|
|
226
224
|
var sorter = sorters.find(sorter => column.type !== 'gutter' && column.name == sorter.name)
|
|
227
225
|
if (!sorter) {
|
|
@@ -231,12 +229,12 @@ export class DataGridHeader extends LitElement {
|
|
|
231
229
|
if (sorters.length > 1) {
|
|
232
230
|
var rank = sorters.indexOf(sorter) + 1
|
|
233
231
|
return sorter.desc
|
|
234
|
-
? html` <mwc-icon>
|
|
235
|
-
: html` <mwc-icon>
|
|
232
|
+
? html` <mwc-icon>keyboard_arrow_down</mwc-icon><sub>${rank}</sub> `
|
|
233
|
+
: html` <mwc-icon>keyboard_arrow_up</mwc-icon><sub>${rank}</sub> `
|
|
236
234
|
} else {
|
|
237
235
|
return sorter.desc
|
|
238
|
-
? html` <mwc-icon>
|
|
239
|
-
: html` <mwc-icon>
|
|
236
|
+
? html` <mwc-icon>keyboard_arrow_down</mwc-icon> `
|
|
237
|
+
: html` <mwc-icon>keyboard_arrow_up</mwc-icon> `
|
|
240
238
|
}
|
|
241
239
|
}
|
|
242
240
|
|
|
@@ -244,7 +242,7 @@ export class DataGridHeader extends LitElement {
|
|
|
244
242
|
const name = column.name
|
|
245
243
|
const filter = column.filter as FilterConfigObject
|
|
246
244
|
const type = filter.type
|
|
247
|
-
const value = this.
|
|
245
|
+
const value = this.filters.find(filter => filter.name === name)?.value
|
|
248
246
|
const idx = filter!.operator === 'between' ? 1 : 0
|
|
249
247
|
const renderer = getFilterRenderer(type)[idx]
|
|
250
248
|
|
|
@@ -326,19 +324,12 @@ export class DataGridHeader extends LitElement {
|
|
|
326
324
|
`
|
|
327
325
|
}
|
|
328
326
|
|
|
329
|
-
updated(changes: PropertyValues<this>) {
|
|
330
|
-
// TODO config 에 의한 sorters 설정은 제거해야 한다.
|
|
331
|
-
if (changes.has('config')) {
|
|
332
|
-
this._sorters = this._sorters || this.config.sorters || []
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
327
|
_changeSort(column: ColumnConfig) {
|
|
337
328
|
if (!column.sortable) {
|
|
338
329
|
return
|
|
339
330
|
}
|
|
340
331
|
|
|
341
|
-
var sorters = [...this.
|
|
332
|
+
var sorters = [...this.sorters]
|
|
342
333
|
|
|
343
334
|
var idx = sorters.findIndex(sorter => sorter.name == column.name)
|
|
344
335
|
if (idx !== -1) {
|
|
@@ -356,14 +347,14 @@ export class DataGridHeader extends LitElement {
|
|
|
356
347
|
sorters.push(sorter)
|
|
357
348
|
}
|
|
358
349
|
|
|
359
|
-
this.
|
|
350
|
+
this.sorters = sorters
|
|
360
351
|
|
|
361
352
|
this.dispatchEvent(
|
|
362
|
-
new CustomEvent('
|
|
353
|
+
new CustomEvent('fetch-params-change', {
|
|
363
354
|
bubbles: true,
|
|
364
355
|
composed: true,
|
|
365
356
|
detail: {
|
|
366
|
-
sorters: this.
|
|
357
|
+
sorters: this.sorters,
|
|
367
358
|
from: 'data-grid-header'
|
|
368
359
|
}
|
|
369
360
|
})
|
|
@@ -2,14 +2,15 @@ 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'
|
|
5
|
+
import { css, html, LitElement, PropertyValues } from 'lit'
|
|
7
6
|
import { customElement, property, query } from 'lit/decorators.js'
|
|
8
7
|
|
|
9
|
-
import { DataGridHeader } from './data-grid-header'
|
|
10
|
-
import { DataManipulator } from '../data-manipulator'
|
|
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
|
|
@@ -190,8 +191,9 @@ export class DataGrid extends DataManipulator {
|
|
|
190
191
|
|
|
191
192
|
return html`
|
|
192
193
|
<ox-grid-header
|
|
193
|
-
.config=${this.config}
|
|
194
194
|
.columns=${columns}
|
|
195
|
+
.sorters=${this.sorters}
|
|
196
|
+
.filters=${this.filters}
|
|
195
197
|
.data=${data}
|
|
196
198
|
@column-width-change=${(e: CustomEvent) => {
|
|
197
199
|
let { idx, width } = e.detail
|
|
@@ -202,7 +204,7 @@ export class DataGrid extends DataManipulator {
|
|
|
202
204
|
|
|
203
205
|
<ox-grid-body .config=${this.config} .columns=${columns} .data=${data} .focused=${this.focused}></ox-grid-body>
|
|
204
206
|
|
|
205
|
-
${paginatable ? html` <ox-grid-footer .
|
|
207
|
+
${paginatable ? html` <ox-grid-footer .data=${data} .pagination=${this.pagination}></ox-grid-footer> ` : html``}
|
|
206
208
|
`
|
|
207
209
|
}
|
|
208
210
|
|
|
@@ -14,20 +14,18 @@ export function dataGridBodyClickHandler(this: DataGridBody, e: Event): void {
|
|
|
14
14
|
var target = (e.target as Element).closest('ox-grid-field') as DataGridField
|
|
15
15
|
var { column, record, rowIndex, columnIndex } = target || {}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
17
|
+
this.dispatchEvent(
|
|
18
|
+
new CustomEvent('focus-change', {
|
|
19
|
+
bubbles: true,
|
|
20
|
+
composed: true,
|
|
21
|
+
detail: {
|
|
22
|
+
row: rowIndex,
|
|
23
|
+
column: columnIndex
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
)
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
}
|
|
28
|
+
this.resetEdit()
|
|
31
29
|
|
|
32
30
|
/* do column click handler */
|
|
33
31
|
if (column) {
|