@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.
Files changed (189) hide show
  1. package/.storybook/main.js +3 -0
  2. package/.storybook/server.mjs +8 -0
  3. package/CHANGELOG.md +392 -0
  4. package/demo/data-grist-test.html +1 -1
  5. package/demo/index.html +13 -2
  6. package/demo/report-test.html +1 -1
  7. package/dist/src/configure/zero-config.d.ts +2 -0
  8. package/dist/src/configure/zero-config.js +3 -1
  9. package/dist/src/configure/zero-config.js.map +1 -1
  10. package/dist/src/data-card/data-card-field.d.ts +1 -1
  11. package/dist/src/data-card/data-card-field.js +3 -2
  12. package/dist/src/data-card/data-card-field.js.map +1 -1
  13. package/dist/src/data-card/data-card.js +1 -0
  14. package/dist/src/data-card/data-card.js.map +1 -1
  15. package/dist/src/data-grid/data-grid-body.d.ts +4 -2
  16. package/dist/src/data-grid/data-grid-body.js +74 -40
  17. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  18. package/dist/src/data-grid/data-grid-field.d.ts +1 -1
  19. package/dist/src/data-grid/data-grid-field.js +1 -1
  20. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  21. package/dist/src/data-grid/data-grid-footer.d.ts +2 -2
  22. package/dist/src/data-grid/data-grid-footer.js +9 -10
  23. package/dist/src/data-grid/data-grid-footer.js.map +1 -1
  24. package/dist/src/data-grid/data-grid-header.d.ts +4 -6
  25. package/dist/src/data-grid/data-grid-header.js +39 -48
  26. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  27. package/dist/src/data-grid/data-grid.d.ts +2 -2
  28. package/dist/src/data-grid/data-grid.js +4 -3
  29. package/dist/src/data-grid/data-grid.js.map +1 -1
  30. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +9 -11
  31. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
  32. package/dist/src/data-grist.d.ts +7 -5
  33. package/dist/src/data-grist.js +154 -112
  34. package/dist/src/data-grist.js.map +1 -1
  35. package/dist/src/data-list/record-partial.js +1 -5
  36. package/dist/src/data-list/record-partial.js.map +1 -1
  37. package/dist/src/data-manipulator.d.ts +4 -1
  38. package/dist/src/data-manipulator.js +12 -0
  39. package/dist/src/data-manipulator.js.map +1 -1
  40. package/dist/src/data-provider.d.ts +4 -6
  41. package/dist/src/data-provider.js +12 -23
  42. package/dist/src/data-provider.js.map +1 -1
  43. package/dist/src/data-report/data-report-body.d.ts +1 -1
  44. package/dist/src/data-report/data-report-body.js +4 -4
  45. package/dist/src/data-report/data-report-body.js.map +1 -1
  46. package/dist/src/data-report/data-report-header.js +4 -4
  47. package/dist/src/data-report/data-report-header.js.map +1 -1
  48. package/dist/src/editors/ox-grist-editor.d.ts +1 -1
  49. package/dist/src/editors/ox-grist-editor.js +7 -4
  50. package/dist/src/editors/ox-grist-editor.js.map +1 -1
  51. package/dist/src/filters/filter-checkbox.d.ts +1 -1
  52. package/dist/src/filters/filter-checkbox.js +1 -1
  53. package/dist/src/filters/filter-checkbox.js.map +1 -1
  54. package/dist/src/filters/filter-input-barcode.d.ts +3 -0
  55. package/dist/src/filters/{filter-input copy.js → filter-input-barcode.js} +8 -6
  56. package/dist/src/filters/filter-input-barcode.js.map +1 -0
  57. package/dist/src/filters/filter-input.js +1 -1
  58. package/dist/src/filters/filter-input.js.map +1 -1
  59. package/dist/src/filters/filter-styles.js +18 -23
  60. package/dist/src/filters/filter-styles.js.map +1 -1
  61. package/dist/src/filters/filters-form.js +5 -3
  62. package/dist/src/filters/filters-form.js.map +1 -1
  63. package/dist/src/filters/registry.d.ts +1 -1
  64. package/dist/src/filters/registry.js +10 -7
  65. package/dist/src/filters/registry.js.map +1 -1
  66. package/dist/src/gutters/gutter-button.js +5 -4
  67. package/dist/src/gutters/gutter-button.js.map +1 -1
  68. package/dist/src/gutters/gutter-dirty.d.ts +5 -1
  69. package/dist/src/gutters/gutter-dirty.js +17 -2
  70. package/dist/src/gutters/gutter-dirty.js.map +1 -1
  71. package/dist/src/gutters/gutter-row-selector.js +2 -1
  72. package/dist/src/gutters/gutter-row-selector.js.map +1 -1
  73. package/dist/src/gutters/gutter-sequence.js +15 -0
  74. package/dist/src/gutters/gutter-sequence.js.map +1 -1
  75. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +2 -4
  76. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
  77. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +2 -2
  78. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
  79. package/dist/src/record-view/record-creator.js +0 -2
  80. package/dist/src/record-view/record-creator.js.map +1 -1
  81. package/dist/src/record-view/record-view-body.d.ts +0 -1
  82. package/dist/src/record-view/record-view-body.js +0 -5
  83. package/dist/src/record-view/record-view-body.js.map +1 -1
  84. package/dist/src/record-view/record-view-handler.d.ts +1 -1
  85. package/dist/src/record-view/record-view.d.ts +0 -1
  86. package/dist/src/record-view/record-view.js +1 -10
  87. package/dist/src/record-view/record-view.js.map +1 -1
  88. package/dist/src/renderers/ox-grist-renderer-color.js +1 -1
  89. package/dist/src/renderers/ox-grist-renderer-color.js.map +1 -1
  90. package/dist/src/renderers/ox-grist-renderer-json5.js +1 -1
  91. package/dist/src/renderers/ox-grist-renderer-json5.js.map +1 -1
  92. package/dist/src/renderers/ox-grist-renderer-link.js +1 -1
  93. package/dist/src/renderers/ox-grist-renderer-link.js.map +1 -1
  94. package/dist/src/renderers/ox-grist-renderer-select.js +2 -2
  95. package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
  96. package/dist/src/renderers/ox-grist-renderer-text.js +6 -2
  97. package/dist/src/renderers/ox-grist-renderer-text.js.map +1 -1
  98. package/dist/src/sorters/sorters-control.d.ts +1 -1
  99. package/dist/src/sorters/sorters-control.js +5 -7
  100. package/dist/src/sorters/sorters-control.js.map +1 -1
  101. package/dist/src/types.d.ts +7 -4
  102. package/dist/src/types.js.map +1 -1
  103. package/dist/stories/{index.stories.d.ts → barcode-input-filter.stories.d.ts} +9 -13
  104. package/dist/stories/barcode-input-filter.stories.js +200 -0
  105. package/dist/stories/barcode-input-filter.stories.js.map +1 -0
  106. package/dist/stories/default-filters.stories.d.ts +20 -0
  107. package/dist/stories/default-filters.stories.js +187 -0
  108. package/dist/stories/default-filters.stories.js.map +1 -0
  109. package/dist/stories/empty-sorters.stories.d.ts +20 -0
  110. package/dist/stories/empty-sorters.stories.js +180 -0
  111. package/dist/stories/empty-sorters.stories.js.map +1 -0
  112. package/dist/stories/explicit-fetch.stories.d.ts +25 -0
  113. package/dist/stories/explicit-fetch.stories.js +186 -0
  114. package/dist/stories/explicit-fetch.stories.js.map +1 -0
  115. package/dist/stories/grist-modes.stories.d.ts +36 -0
  116. package/dist/stories/grist-modes.stories.js +448 -0
  117. package/dist/stories/grist-modes.stories.js.map +1 -0
  118. package/dist/tsconfig.tsbuildinfo +1 -1
  119. package/package.json +11 -11
  120. package/src/configure/zero-config.ts +4 -1
  121. package/src/data-card/data-card-field.ts +5 -3
  122. package/src/data-card/data-card.ts +1 -0
  123. package/src/data-grid/data-grid-body.ts +96 -49
  124. package/src/data-grid/data-grid-field.ts +3 -2
  125. package/src/data-grid/data-grid-footer.ts +8 -9
  126. package/src/data-grid/data-grid-header.ts +38 -47
  127. package/src/data-grid/data-grid.ts +8 -6
  128. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +11 -13
  129. package/src/data-grist.ts +179 -130
  130. package/src/data-list/record-partial.ts +1 -5
  131. package/src/data-manipulator.ts +12 -1
  132. package/src/data-provider.ts +13 -29
  133. package/src/data-report/data-report-body.ts +5 -5
  134. package/src/data-report/data-report-header.ts +5 -5
  135. package/src/editors/ox-grist-editor.ts +8 -5
  136. package/src/filters/filter-checkbox.ts +3 -3
  137. package/src/filters/filter-input-barcode.ts +33 -0
  138. package/src/filters/filter-input.ts +3 -3
  139. package/src/filters/filter-styles.ts +18 -23
  140. package/src/filters/filters-form.ts +5 -3
  141. package/src/filters/registry.ts +11 -8
  142. package/src/gutters/gutter-button.ts +5 -4
  143. package/src/gutters/gutter-dirty.ts +21 -3
  144. package/src/gutters/gutter-row-selector.ts +2 -1
  145. package/src/gutters/gutter-sequence.ts +18 -2
  146. package/src/record-view/event-handlers/record-view-body-click-handler.ts +2 -4
  147. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +2 -2
  148. package/src/record-view/record-creator.ts +0 -2
  149. package/src/record-view/record-view-body.ts +0 -2
  150. package/src/record-view/record-view.ts +1 -7
  151. package/src/renderers/ox-grist-renderer-color.ts +3 -2
  152. package/src/renderers/ox-grist-renderer-json5.ts +3 -2
  153. package/src/renderers/ox-grist-renderer-link.ts +3 -2
  154. package/src/renderers/ox-grist-renderer-select.ts +2 -2
  155. package/src/renderers/ox-grist-renderer-text.ts +8 -2
  156. package/src/sorters/sorters-control.ts +6 -9
  157. package/src/types.ts +8 -4
  158. package/stories/barcode-input-filter.stories.ts +220 -0
  159. package/stories/default-filters.stories.ts +204 -0
  160. package/stories/empty-sorters.stories.ts +197 -0
  161. package/stories/explicit-fetch.stories.ts +205 -0
  162. package/stories/grist-modes.stories.ts +488 -0
  163. package/themes/grist-theme.css +1 -1
  164. package/dist/src/filters/filter-input copy.d.ts +0 -2
  165. package/dist/src/filters/filter-input copy.js.map +0 -1
  166. package/dist/src/filters/filter-mwc-checkbox.d.ts +0 -4
  167. package/dist/src/filters/filter-mwc-checkbox.js +0 -30
  168. package/dist/src/filters/filter-mwc-checkbox.js.map +0 -1
  169. package/dist/src/filters/filter-mwc-textfield.d.ts +0 -3
  170. package/dist/src/filters/filter-mwc-textfield.js +0 -27
  171. package/dist/src/filters/filter-mwc-textfield.js.map +0 -1
  172. package/dist/src/filters/grist-filter-registry.d.ts +0 -12
  173. package/dist/src/filters/grist-filter-registry.js +0 -47
  174. package/dist/src/filters/grist-filter-registry.js.map +0 -1
  175. package/dist/src/filters/ox-grist-filter-editor-checkbox.d.ts +0 -5
  176. package/dist/src/filters/ox-grist-filter-editor-checkbox.js +0 -27
  177. package/dist/src/filters/ox-grist-filter-editor-checkbox.js.map +0 -1
  178. package/dist/src/filters/ox-grist-filter-editor-input.d.ts +0 -4
  179. package/dist/src/filters/ox-grist-filter-editor-input.js +0 -54
  180. package/dist/src/filters/ox-grist-filter-editor-input.js.map +0 -1
  181. package/dist/src/filters/ox-grist-filter-editor-select.d.ts +0 -4
  182. package/dist/src/filters/ox-grist-filter-editor-select.js +0 -46
  183. package/dist/src/filters/ox-grist-filter-editor-select.js.map +0 -1
  184. package/dist/src/filters/ox-grist-filter-editor.d.ts +0 -16
  185. package/dist/src/filters/ox-grist-filter-editor.js +0 -122
  186. package/dist/src/filters/ox-grist-filter-editor.js.map +0 -1
  187. package/dist/stories/index.stories.js +0 -33
  188. package/dist/stories/index.stories.js.map +0 -1
  189. package/stories/index.stories.ts +0 -52
@@ -1,20 +1,21 @@
1
1
  import './data-grid-field'
2
2
 
3
- import { ColumnConfig, GristConfig, GristData, GristRecord } from '../types'
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._selectBlock = { start: field }
207
-
208
- this.dispatchEvent(
209
- new CustomEvent('focus-change', {
210
- bubbles: true,
211
- composed: true,
212
- detail: undefined
213
- // detail: {
214
- // row: field!.rowIndex,
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
- const left = start.columnIndex < end.columnIndex ? start : end
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._selectBlock = undefined
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
- await navigator.clipboard.writeText(JSON.stringify(this.getSelectedBlockValues()))
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
- const block = JSON.parse(text)
447
+ try {
448
+ var parsed = JSON.parse(text)
449
+ } catch (ex) {
450
+ parsed = text
451
+ }
436
452
 
437
- if (!(block instanceof Array)) {
438
- return
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 { ColumnConfig, GristRecord } from '../types'
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 { GristConfig, GristData } from '../types'
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
- const DEFAULT_PAGES = [20, 30, 50, 100]
9
- const DEFAULT_LIMIT = 30
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 { limit = 20, total = 0 } = this.data
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 { records = [], page = 1, limit = DEFAULT_LIMIT, total = 0 } = this.data
78
- var { pages = DEFAULT_PAGES } = this.config.pagination || {}
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, PropertyValues } from 'lit'
5
- import { customElement, property, state } from 'lit/decorators.js'
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 { closestElement } from '@operato/utils'
9
+ import { TooltipStyles } from '@operato/styles'
10
+ import { closestElement, detectOverflow } from '@operato/utils'
10
11
 
11
- import { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
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, GristConfig, GristData, SortersConfig } from '../types'
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
- @state() private _sorters: SortersConfig = []
120
- @state() private _filters: FilterValue[] = []
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
- grid?.addEventListener('filter-change', (e: Event) => {
132
+ this?.addEventListener('filter-change', (e: Event) => {
139
133
  const { name, operator, value } = (e as CustomEvent).detail
140
- const filters = this._filters instanceof Array ? [...this._filters] : []
134
+ const filters = this.filters instanceof Array ? [...this.filters] : []
141
135
 
142
- if (value === undefined || value === null) {
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('filters-change', {
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 for-title @click=${(e: MouseEvent) => this._changeSort(column)}
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._sorters
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>keyboard_arrow_up</mwc-icon><sub>${rank}</sub> `
235
- : html` <mwc-icon>keyboard_arrow_down</mwc-icon><sub>${rank}</sub> `
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>keyboard_arrow_up</mwc-icon> `
239
- : html` <mwc-icon>keyboard_arrow_down</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._filters.find(filter => filter.name === name)?.value
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._sorters]
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._sorters = sorters
350
+ this.sorters = sorters
360
351
 
361
352
  this.dispatchEvent(
362
- new CustomEvent('sorters-change', {
353
+ new CustomEvent('fetch-params-change', {
363
354
  bubbles: true,
364
355
  composed: true,
365
356
  detail: {
366
- sorters: this._sorters,
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 { ColumnConfig, GristRecord, PaginationConfig } from '../types'
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 .config=${this.config} .data=${data}></ox-grid-footer> ` : html``}
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
- if (!this.focused || rowIndex !== this.focused.row || columnIndex !== this.focused.column) {
18
- this.dispatchEvent(
19
- new CustomEvent('focus-change', {
20
- bubbles: true,
21
- composed: true,
22
- detail: {
23
- row: rowIndex,
24
- column: columnIndex
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
- this.resetEdit()
30
- }
28
+ this.resetEdit()
31
29
 
32
30
  /* do column click handler */
33
31
  if (column) {