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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +10 -10
  3. package/.storybook/main.js +0 -3
  4. package/.storybook/preview.js +0 -52
  5. package/.storybook/server.mjs +0 -8
  6. package/demo/data-grist-test.html +0 -468
  7. package/demo/favicon.ico +0 -0
  8. package/demo/index.html +0 -541
  9. package/demo/report-test.html +0 -249
  10. package/src/accumulator/accumulator.ts +0 -63
  11. package/src/configure/column-builder.ts +0 -114
  12. package/src/configure/config-builder.ts +0 -40
  13. package/src/configure/filters-option-builder.ts +0 -8
  14. package/src/configure/imex-option-builder.ts +0 -5
  15. package/src/configure/list-option-builder.ts +0 -9
  16. package/src/configure/rows-option-builder.ts +0 -38
  17. package/src/configure/tree-option-builder.ts +0 -22
  18. package/src/configure/zero-config.ts +0 -83
  19. package/src/const.ts +0 -1
  20. package/src/data-card/data-card-field.ts +0 -94
  21. package/src/data-card/data-card-gutter-menu.ts +0 -94
  22. package/src/data-card/data-card-gutter.ts +0 -103
  23. package/src/data-card/data-card.ts +0 -154
  24. package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
  25. package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
  26. package/src/data-card/record-card.ts +0 -298
  27. package/src/data-consumer.ts +0 -11
  28. package/src/data-grid/data-grid-accum-field.ts +0 -109
  29. package/src/data-grid/data-grid-body-style.ts +0 -85
  30. package/src/data-grid/data-grid-body.ts +0 -765
  31. package/src/data-grid/data-grid-field.ts +0 -227
  32. package/src/data-grid/data-grid-footer.ts +0 -119
  33. package/src/data-grid/data-grid-header.ts +0 -578
  34. package/src/data-grid/data-grid.ts +0 -293
  35. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
  36. package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
  37. package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
  38. package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
  39. package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
  40. package/src/data-grist.ts +0 -1233
  41. package/src/data-list/data-list-field.ts +0 -82
  42. package/src/data-list/data-list-gutter.ts +0 -108
  43. package/src/data-list/data-list.ts +0 -145
  44. package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
  45. package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
  46. package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
  47. package/src/data-list/record-partial.ts +0 -264
  48. package/src/data-manipulator.ts +0 -426
  49. package/src/data-provider.ts +0 -271
  50. package/src/data-report/data-report-body-style.ts +0 -58
  51. package/src/data-report/data-report-body.ts +0 -189
  52. package/src/data-report/data-report-component.ts +0 -138
  53. package/src/data-report/data-report-field.ts +0 -83
  54. package/src/data-report/data-report-header.ts +0 -242
  55. package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
  56. package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
  57. package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
  58. package/src/data-report.ts +0 -424
  59. package/src/editors/index.ts +0 -4
  60. package/src/editors/ox-grist-editor-checkbox.ts +0 -28
  61. package/src/editors/ox-grist-editor-color.ts +0 -10
  62. package/src/editors/ox-grist-editor-date.ts +0 -10
  63. package/src/editors/ox-grist-editor-datetime.ts +0 -27
  64. package/src/editors/ox-grist-editor-email.ts +0 -10
  65. package/src/editors/ox-grist-editor-file.ts +0 -28
  66. package/src/editors/ox-grist-editor-image.ts +0 -31
  67. package/src/editors/ox-grist-editor-month.ts +0 -10
  68. package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
  69. package/src/editors/ox-grist-editor-number.ts +0 -27
  70. package/src/editors/ox-grist-editor-password.ts +0 -10
  71. package/src/editors/ox-grist-editor-select.ts +0 -55
  72. package/src/editors/ox-grist-editor-tel.ts +0 -10
  73. package/src/editors/ox-grist-editor-text.ts +0 -14
  74. package/src/editors/ox-grist-editor-textarea.ts +0 -16
  75. package/src/editors/ox-grist-editor-time.ts +0 -10
  76. package/src/editors/ox-grist-editor-tree.ts +0 -27
  77. package/src/editors/ox-grist-editor-varname.ts +0 -36
  78. package/src/editors/ox-grist-editor-week.ts +0 -10
  79. package/src/editors/ox-grist-editor.ts +0 -207
  80. package/src/editors/ox-input-tree.ts +0 -226
  81. package/src/editors/registry.ts +0 -82
  82. package/src/empty-note.ts +0 -46
  83. package/src/filters/filter-checkbox.ts +0 -49
  84. package/src/filters/filter-input-barcode.ts +0 -34
  85. package/src/filters/filter-input.ts +0 -30
  86. package/src/filters/filter-range-date.ts +0 -81
  87. package/src/filters/filter-range-number.ts +0 -64
  88. package/src/filters/filter-select-buttons.ts +0 -60
  89. package/src/filters/filter-select.ts +0 -68
  90. package/src/filters/filter-styles.ts +0 -119
  91. package/src/filters/filters-form.ts +0 -476
  92. package/src/filters/index.ts +0 -10
  93. package/src/filters/registry.ts +0 -56
  94. package/src/formatters/date-formatter.ts +0 -3
  95. package/src/formatters/index.ts +0 -1
  96. package/src/formatters/number-formatter.ts +0 -3
  97. package/src/formatters/registry.ts +0 -30
  98. package/src/formatters/text-formatter.ts +0 -3
  99. package/src/gutters/gutter-button.ts +0 -51
  100. package/src/gutters/gutter-dirty.ts +0 -96
  101. package/src/gutters/gutter-row-selector.ts +0 -89
  102. package/src/gutters/gutter-sequence.ts +0 -54
  103. package/src/gutters/index.ts +0 -1
  104. package/src/gutters/registry.ts +0 -32
  105. package/src/handlers/contextmenu-tree-mutation.ts +0 -80
  106. package/src/handlers/index.ts +0 -1
  107. package/src/handlers/move-down.ts +0 -44
  108. package/src/handlers/move-up.ts +0 -44
  109. package/src/handlers/record-copy.ts +0 -38
  110. package/src/handlers/record-delete.ts +0 -30
  111. package/src/handlers/record-view-handler.ts +0 -27
  112. package/src/handlers/registry.ts +0 -42
  113. package/src/handlers/select-row-toggle.ts +0 -30
  114. package/src/handlers/select-row.ts +0 -27
  115. package/src/index.ts +0 -17
  116. package/src/personalizer/index.ts +0 -1
  117. package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
  118. package/src/personalizer/ox-grist-personalizer.ts +0 -226
  119. package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
  120. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
  121. package/src/record-view/index.ts +0 -2
  122. package/src/record-view/ox-record-creator.ts +0 -289
  123. package/src/record-view/record-view-body.ts +0 -257
  124. package/src/record-view/record-view-handler.ts +0 -86
  125. package/src/record-view/record-view.ts +0 -122
  126. package/src/renderers/index.ts +0 -14
  127. package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
  128. package/src/renderers/ox-grist-renderer-color.ts +0 -15
  129. package/src/renderers/ox-grist-renderer-date.ts +0 -62
  130. package/src/renderers/ox-grist-renderer-file.ts +0 -31
  131. package/src/renderers/ox-grist-renderer-image.ts +0 -27
  132. package/src/renderers/ox-grist-renderer-json5.ts +0 -36
  133. package/src/renderers/ox-grist-renderer-link.ts +0 -17
  134. package/src/renderers/ox-grist-renderer-password.ts +0 -7
  135. package/src/renderers/ox-grist-renderer-progress.ts +0 -45
  136. package/src/renderers/ox-grist-renderer-select.ts +0 -58
  137. package/src/renderers/ox-grist-renderer-text.ts +0 -16
  138. package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
  139. package/src/renderers/ox-grist-renderer-tree.ts +0 -189
  140. package/src/renderers/ox-grist-renderer.ts +0 -35
  141. package/src/renderers/registry.ts +0 -111
  142. package/src/sorters/sorters-control.ts +0 -143
  143. package/src/types.ts +0 -813
  144. package/src/utils/index.ts +0 -2
  145. package/src/utils/list-param.ts +0 -72
  146. package/src/utils/supports-passive.ts +0 -13
  147. package/stories/accumulator-format.stories.ts +0 -276
  148. package/stories/barcode-input-filter.stories.ts +0 -216
  149. package/stories/bounded-select-filters.stories.ts +0 -333
  150. package/stories/bounded-select-record.stories.ts +0 -336
  151. package/stories/click-event-custom.stories.ts +0 -287
  152. package/stories/click-event.stories.ts +0 -283
  153. package/stories/creatable-only-column.stories.ts +0 -253
  154. package/stories/default-filters.stories.ts +0 -241
  155. package/stories/dynamic-editable.stories.ts +0 -313
  156. package/stories/empty-sorters.stories.ts +0 -180
  157. package/stories/explicit-fetch.stories.ts +0 -186
  158. package/stories/fixed-column.stories.ts +0 -416
  159. package/stories/grid-setting.stories.ts +0 -501
  160. package/stories/grist-modes.stories.ts +0 -451
  161. package/stories/group-header.stories.ts +0 -442
  162. package/stories/record-view.stories.ts +0 -143
  163. package/stories/textarea.stories.ts +0 -261
  164. package/stories/tree-column-with-checkbox.stories.ts +0 -297
  165. package/stories/tree-column.stories.ts +0 -296
  166. package/tsconfig.json +0 -26
  167. package/web-dev-server.config.mjs +0 -27
  168. package/web-test-runner.config.mjs +0 -45
@@ -1,578 +0,0 @@
1
- import '@operato/popup/ox-popup.js'
2
- import '@material/web/icon/icon.js'
3
-
4
- import { css, html, LitElement, PropertyValues, nothing, TemplateResult } from 'lit'
5
- import { customElement, property, state } from 'lit/decorators.js'
6
- import { ifDefined } from 'lit/directives/if-defined.js'
7
- import throttle from 'lodash-es/throttle'
8
-
9
- import { OxPopup } from '@operato/popup'
10
- import { TooltipReactiveController, closestElement } from '@operato/utils'
11
-
12
- import { ZERO_COLUMNS, ZERO_DATA } from '../configure/zero-config'
13
- import { FilterStyles } from '../filters/filter-styles'
14
- import { getFilterRenderer } from '../filters/registry'
15
- import { ColumnConfig, FilterConfigObject, FilterValue, GristData, SortersConfig } from '../types'
16
-
17
- @customElement('ox-grid-header')
18
- export class DataGridHeader extends LitElement {
19
- static styles = [
20
- FilterStyles,
21
- css`
22
- :host {
23
- position: relative;
24
- display: grid;
25
- grid-template-columns: var(--grid-template-columns);
26
-
27
- border-top: var(--grid-header-top-border);
28
- overflow: hidden;
29
-
30
- font-variation-settings: 'FILL' 1;
31
-
32
- user-select: none;
33
- }
34
-
35
- :host([raised]) [fixed] {
36
- /* 고정 컬럼이 살짝 올라와 있는 느낌을 표현 */
37
- box-shadow: 3px 0 3px rgba(0, 0, 0, 0.1);
38
- }
39
-
40
- div[column] {
41
- display: flex;
42
-
43
- white-space: nowrap;
44
- overflow: hidden;
45
- background-color: var(--grid-header-background-color);
46
- border-bottom: var(--grid-header-bottom-border);
47
- padding: var(--grid-header-padding);
48
-
49
- text-overflow: ellipsis;
50
- font: var(--grid-header-font);
51
- color: var(--grid-header-color);
52
- }
53
-
54
- div[gutter] {
55
- padding: var(--spacing-small) 0;
56
- text-align: center;
57
- }
58
-
59
- span {
60
- display: block;
61
- white-space: nowrap;
62
- overflow: hidden;
63
- }
64
-
65
- span[for-title] {
66
- flex: 1;
67
- text-overflow: ellipsis;
68
- line-height: 1.6;
69
- text-transform: var(--grid-header-text-transform, capitalize);
70
- align-self: center;
71
- }
72
-
73
- span[for-title] * {
74
- vertical-align: middle;
75
- }
76
-
77
- span[for-title] md-icon {
78
- font-size: 1.2em;
79
- }
80
-
81
- span[sorter],
82
- span[filter] {
83
- display: flex;
84
- align-self: center;
85
-
86
- padding: 0;
87
- border: 0;
88
- }
89
-
90
- span[sorter] md-icon {
91
- font-size: var(--grid-header-sorter-size);
92
- }
93
-
94
- span[filter] > md-icon {
95
- font-size: var(--fontsize-default);
96
- line-height: 20px;
97
- }
98
-
99
- span[splitter] {
100
- cursor: col-resize;
101
- border-right: var(--grid-header-splitter-border);
102
- margin-right: 0;
103
- }
104
-
105
- span[splitter]:hover {
106
- border-right: var(--grid-header-splitter-border-hover);
107
- }
108
-
109
- [filter-title] {
110
- color: var(--grid-header-filter-title-color);
111
- font: var(--grid-header-filter-title-font);
112
- text-transform: capitalize;
113
- }
114
-
115
- [filter-title] * {
116
- vertical-align: middle;
117
- }
118
-
119
- [filter-title] md-icon {
120
- opacity: 0.7;
121
- color: var(--grid-header-filter-title-icon-color);
122
- }
123
-
124
- [filter] input[type='checkbox'] {
125
- margin-left: var(--spacing-medium);
126
- margin-bottom: var(--spacing-small);
127
- }
128
-
129
- [fixed] {
130
- position: sticky;
131
- z-index: 2;
132
- }
133
-
134
- .span-both {
135
- grid-row: 1 / span 2; /* 1단과 2단에 걸쳐 표시 */
136
- }
137
-
138
- .group-header {
139
- grid-row: 1; /* 1행에 배치 */
140
- grid-column: var(--group-start) / span var(--group-size); /* 2열부터 시작하여 2열에 걸쳐 표시 */
141
- }
142
-
143
- @media print {
144
- :host {
145
- grid-template-columns: var(--grid-template-print-columns);
146
- }
147
- }
148
- `
149
- ]
150
-
151
- @property({ type: Array }) columns: ColumnConfig[] = ZERO_COLUMNS
152
- @property({ type: Object }) data: GristData = ZERO_DATA
153
- @property({ type: Array }) sorters: SortersConfig = []
154
- @property({ type: Array }) filters: FilterValue[] = []
155
- @property({ type: Boolean, attribute: 'filtering-feature' }) filteringFeature: boolean = false
156
-
157
- @state() private row1: {
158
- index: number
159
- column: ColumnConfig
160
- clazz?: string
161
- start?: number
162
- size?: number
163
- align?: string
164
- group?: string
165
- }[] = []
166
-
167
- @state() private row2: {
168
- index: number
169
- column: ColumnConfig
170
- }[] = []
171
-
172
- private _lastAccVal?: number
173
- private _throttledNotifier?: any
174
-
175
- private tooltipController?: TooltipReactiveController = new TooltipReactiveController(this)
176
-
177
- connectedCallback() {
178
- super.connectedCallback()
179
-
180
- const grid = closestElement('ox-grist', this)
181
-
182
- this.addEventListener('scroll', function () {
183
- this.scrollLeft == 0 ? this.removeAttribute('raised') : this.setAttribute('raised', '')
184
- })
185
-
186
- if (this.filteringFeature) {
187
- this?.addEventListener('filter-change', (e: Event) => {
188
- const { name, operator, value } = (e as CustomEvent).detail
189
- const filters = this.filters instanceof Array ? [...this.filters] : []
190
-
191
- if (value == null) {
192
- const index = filters.findIndex(filter => filter.name === name)
193
- if (index === -1) {
194
- return
195
- }
196
-
197
- filters.splice(index, 1)
198
- } else {
199
- const index = filters.findIndex(filter => filter.name === name)
200
- if (index === -1) {
201
- filters.push({ name, operator, value })
202
- } else {
203
- filters.splice(index, 1, { name, operator, value })
204
- }
205
- }
206
-
207
- grid?.dispatchEvent(
208
- new CustomEvent('fetch-params-change', {
209
- detail: {
210
- filters,
211
- from: 'data-grid-header'
212
- }
213
- })
214
- )
215
- })
216
- }
217
- }
218
-
219
- render() {
220
- const clazz = this.row2.length > 0 ? 'span-both' : undefined
221
-
222
- return html`
223
- ${this.row1.map(({ column, clazz, start, size, align, index, group }) =>
224
- this.renderHeaderColumn({ column, clazz, start, size, align, index, group })
225
- )}
226
-
227
- <div column class=${ifDefined(clazz)}></div>
228
-
229
- ${this.row2.map(({ column, index }) => this.renderHeaderColumn({ column, index }))}
230
- `
231
- }
232
-
233
- renderHeaderColumn({ column, clazz, start, size, align, index, group }: any): TemplateResult {
234
- if (column.hidden) {
235
- return html`${nothing}`
236
- }
237
-
238
- return html`
239
- <div
240
- ?gutter=${column.type == 'gutter'}
241
- ?fixed=${column.fixed}
242
- column
243
- class=${ifDefined(clazz)}
244
- style=${group
245
- ? `--group-start:${start};--group-size:${size};${column.header?.style || ''}`
246
- : `${column.header?.style || ''}`}
247
- >
248
- <span
249
- for-title
250
- data-reactive-tooltip
251
- style="text-align:${align || column.record.align || 'left'};"
252
- @click=${(e: MouseEvent) => this._changeSort(column)}
253
- >${this._renderHeader(column)}
254
- </span>
255
-
256
- ${!group && column.sortable
257
- ? html`
258
- <span sorter @click=${(e: MouseEvent) => this._changeSort(column)}>
259
- ${this._renderSortHeader(column)}
260
- </span>
261
- `
262
- : nothing}
263
- ${!group &&
264
- this.filteringFeature &&
265
- column.filter &&
266
- (column.filter as FilterConfigObject).operator !== 'search'
267
- ? html` <span filter> ${this._renderFilterHeader(column)} </span> `
268
- : nothing}
269
- ${column.resizable !== false
270
- ? html`
271
- <span splitter draggable="false" @pointerdown=${(e: PointerEvent) => this._pointerdown(e, index)}
272
- >&nbsp;</span
273
- >
274
- `
275
- : nothing}
276
- </div>
277
- `
278
- }
279
-
280
- notifyFixedLeftChange() {
281
- const fixedHeaders = Array.from(this.renderRoot.querySelectorAll('div[fixed]')) as HTMLElement[]
282
- const fixedLefts = [] as number[]
283
- var left = 0
284
- fixedHeaders.forEach((header: HTMLElement) => {
285
- header.style.left = left + 'px'
286
- fixedLefts.push(left)
287
-
288
- const width = header.offsetWidth
289
- left += width
290
- })
291
-
292
- this.dispatchEvent(
293
- new CustomEvent('fixed-lefts-change', {
294
- detail: fixedLefts
295
- })
296
- )
297
- }
298
-
299
- updated(changes: PropertyValues) {
300
- var isColumnWidthChangePossible = false
301
-
302
- if (changes.has('columns')) {
303
- this.row2 = this.columns.reduce((row2, column, index) => {
304
- if (column.hidden || !column.header?.group) {
305
- return row2
306
- }
307
- return row2.concat({
308
- index,
309
- column
310
- } as any)
311
- }, [] as any[])
312
-
313
- const clazz = this.row2.length > 0 ? 'span-both' : undefined
314
-
315
- var columnNo = 0
316
-
317
- this.row1 = this.columns.reduce((row1, column, index) => {
318
- if (column.hidden) {
319
- return row1
320
- }
321
-
322
- columnNo++
323
- if (!column.header?.group) {
324
- return row1.concat({
325
- index,
326
- column,
327
- clazz
328
- } as any)
329
- }
330
- const { group, groupStyle } = column.header
331
- const last = row1[row1.length - 1] as any
332
-
333
- if (!last || group !== last.group) {
334
- return row1.concat({
335
- index,
336
- column: {
337
- ...column,
338
- header: {
339
- renderer: () => group,
340
- style: groupStyle
341
- }
342
- },
343
- group,
344
- align: 'center',
345
- clazz: 'group-header',
346
- start: columnNo,
347
- size: 1
348
- } as any)
349
- }
350
-
351
- last.size++
352
-
353
- return row1
354
- }, [] as any[])
355
-
356
- isColumnWidthChangePossible = true
357
- }
358
-
359
- if (changes.has('data')) {
360
- isColumnWidthChangePossible = true
361
- }
362
-
363
- if (isColumnWidthChangePossible) {
364
- // requestAnimationFrame(() => this.notifyFixedLeftChange())
365
- this.notifyFixedLeftChange()
366
- }
367
- }
368
-
369
- _renderHeader(column: ColumnConfig) {
370
- var { renderer } = column.header || {}
371
- var title = renderer.call(this, column)
372
-
373
- return html`${column?.record?.mandatory ? '*' : ''} ${title} `
374
- }
375
-
376
- _renderSortHeader(column: ColumnConfig) {
377
- var sorters = this.sorters || []
378
-
379
- var sorter = sorters.find(sorter => column.type !== 'gutter' && column.name == sorter.name)
380
- if (!sorter) {
381
- return html`<md-icon style="opacity: 0.2;">unfold_more</md-icon>`
382
- }
383
-
384
- if (sorters.length > 1) {
385
- var rank = sorters.indexOf(sorter) + 1
386
- return sorter.desc
387
- ? html` <md-icon>keyboard_arrow_down</md-icon><sub>${rank}</sub> `
388
- : html` <md-icon>keyboard_arrow_up</md-icon><sub>${rank}</sub> `
389
- } else {
390
- return sorter.desc ? html` <md-icon>keyboard_arrow_down</md-icon> ` : html` <md-icon>keyboard_arrow_up</md-icon> `
391
- }
392
- }
393
-
394
- _renderFilterHeader(column: ColumnConfig) {
395
- const name = column.name
396
- const filter = column.filter as FilterConfigObject
397
- const type = filter.type
398
- const value = this.filters.find(filter => filter.name === name)?.value
399
- const idx = filter!.operator === 'between' ? 1 : 0
400
- const renderer = getFilterRenderer(type)[idx]
401
-
402
- return html`
403
- <md-icon
404
- @click=${(e: Event) => {
405
- const parent = (e.target as HTMLElement).closest('[column]') as HTMLElement
406
- const popup = parent.querySelector('ox-popup, ox-popup-list') as OxPopup | null
407
- // const popup = (e.target as HTMLElement).nextSibling as OxPopupList | null
408
-
409
- // absolute position인 popup의 위치 부모는 grist 이므로,
410
- // data-grid-header 의 포지션 부모(grist)의 위치로부터 계산해야함.
411
- // this의 position을 relative로 하지 못하는 이유 : ox-popup-list가 grid body에 덮히기 때문.
412
- // const top = parent.offsetTop + parent.offsetHeight
413
- // const right = this.clientWidth - (parent.offsetLeft + parent.offsetWidth - this.scrollLeft)
414
-
415
- popup?.open({
416
- right: 0,
417
- top: parent.offsetHeight,
418
- fixed: true
419
- })
420
- }}
421
- >filter_alt</md-icon
422
- >
423
-
424
- ${!renderer
425
- ? html``
426
- : type !== 'select'
427
- ? html` <ox-popup
428
- ><div filter-title><md-icon>filter_alt</md-icon> filter by <strong>${column.name}</strong></div>
429
- ${renderer(column, value, this)}</ox-popup
430
- >`
431
- : filter!.operator === 'in'
432
- ? html`<ox-popup-list
433
- multiple
434
- attr-selected="checked"
435
- .value=${value}
436
- with-search
437
- @select=${(e: CustomEvent) =>
438
- e.target?.dispatchEvent(
439
- new CustomEvent('filter-change', {
440
- bubbles: true,
441
- composed: true,
442
- detail: {
443
- name,
444
- operator: filter!.operator,
445
- value: !e.detail
446
- ? undefined
447
- : e.detail instanceof Array && e.detail.length === 0
448
- ? undefined
449
- : e.detail
450
- }
451
- })
452
- )}
453
- ><div filter-title slot="header">
454
- <md-icon>filter_alt</md-icon> filter by <strong>${column.name}</strong>
455
- </div>
456
- ${renderer(column, value, this)}</ox-popup-list
457
- >`
458
- : html`<ox-popup-list
459
- .value=${value}
460
- with-search
461
- @select=${(e: CustomEvent) =>
462
- e.target?.dispatchEvent(
463
- new CustomEvent('filter-change', {
464
- bubbles: true,
465
- composed: true,
466
- detail: {
467
- name,
468
- operator: filter!.operator,
469
- value: e.detail ? e.detail : undefined
470
- }
471
- })
472
- )}
473
- ><div filter-title slot="header">
474
- <md-icon>filter_alt</md-icon> filter by <strong>${column.name}</strong>
475
- </div>
476
- ${renderer(column, value, this)}</ox-popup-list
477
- >`}
478
- `
479
- }
480
-
481
- _changeSort(column: ColumnConfig) {
482
- if (!column.sortable) {
483
- return
484
- }
485
-
486
- var sorters = [...this.sorters]
487
-
488
- var idx = sorters.findIndex(sorter => sorter.name == column.name)
489
- if (idx !== -1) {
490
- let sorter = sorters[idx]
491
- if (sorter.desc) {
492
- sorters.splice(idx, 1)
493
- } else {
494
- sorters.splice(idx, 1, {
495
- ...sorter,
496
- desc: true
497
- })
498
- }
499
- } else {
500
- var sorter = {
501
- name: column.name,
502
- desc: false
503
- }
504
-
505
- sorters.push(sorter)
506
- }
507
-
508
- this.sorters = sorters
509
-
510
- this.dispatchEvent(
511
- new CustomEvent('fetch-params-change', {
512
- bubbles: true,
513
- composed: true,
514
- detail: {
515
- sorters: this.sorters,
516
- from: 'data-grid-header'
517
- }
518
- })
519
- )
520
- }
521
-
522
- _accumalate(x: number) {
523
- this._lastAccVal = (this._lastAccVal ?? 0) + x
524
- return this._lastAccVal
525
- }
526
-
527
- _notifyWidthChange(idx: number, width: number) {
528
- if (!this._throttledNotifier) {
529
- this._throttledNotifier = throttle((idx: number, width: number) => {
530
- this.dispatchEvent(
531
- new CustomEvent('column-width-change', {
532
- bubbles: true,
533
- composed: true,
534
- detail: {
535
- idx,
536
- width
537
- }
538
- })
539
- )
540
-
541
- this.notifyFixedLeftChange()
542
-
543
- this._lastAccVal = 0
544
- }, 100)
545
- }
546
-
547
- this._throttledNotifier(idx, width)
548
- }
549
-
550
- _pointerdown(e: MouseEvent, idx: number) {
551
- e.stopPropagation()
552
- e.preventDefault()
553
-
554
- var pointermoveHandler = ((e: MouseEvent) => {
555
- e.stopPropagation()
556
- e.preventDefault()
557
- let column = this.columns[idx]
558
-
559
- let width = Math.max(0, Number(column.width || 100) + this._accumalate(e.movementX))
560
- if (width == 0) {
561
- /* CLARIFY-ME 왜 마지막 이벤트의 offsetX로 음수 값이 오는가 */
562
- return
563
- }
564
-
565
- this._notifyWidthChange(idx, width)
566
- }).bind(this)
567
-
568
- var pointerupHandler = ((e: MouseEvent) => {
569
- document.removeEventListener('pointermove', pointermoveHandler)
570
- document.removeEventListener('pointerup', pointerupHandler)
571
-
572
- pointermoveHandler(e)
573
- }).bind(this)
574
-
575
- document.addEventListener('pointermove', pointermoveHandler)
576
- document.addEventListener('pointerup', pointerupHandler)
577
- }
578
- }