evui 3.4.207 → 3.4.209

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 (162) hide show
  1. package/README.md +18 -33
  2. package/dist/404.html +44 -0
  3. package/dist/favicon.ico +0 -0
  4. package/dist/index.js +22738 -0
  5. package/dist/index.umd.cjs +28 -0
  6. package/dist/style.css +1 -0
  7. package/package.json +46 -43
  8. package/dist/evui.common.js +0 -63681
  9. package/dist/evui.common.js.map +0 -1
  10. package/dist/evui.umd.js +0 -63691
  11. package/dist/evui.umd.js.map +0 -1
  12. package/dist/evui.umd.min.js +0 -2
  13. package/dist/evui.umd.min.js.map +0 -1
  14. package/dist/img/EVUI.b82ee81a.svg +0 -293
  15. package/src/assets/logo.png +0 -0
  16. package/src/common/emitter.js +0 -20
  17. package/src/common/utils.bignumber.js +0 -67
  18. package/src/common/utils.debounce.js +0 -223
  19. package/src/common/utils.js +0 -151
  20. package/src/common/utils.table.js +0 -78
  21. package/src/common/utils.throttle.js +0 -83
  22. package/src/common/utils.tree.js +0 -18
  23. package/src/components/button/Button.vue +0 -195
  24. package/src/components/button/index.js +0 -7
  25. package/src/components/buttonGroup/ButtonGroup.vue +0 -11
  26. package/src/components/buttonGroup/index.js +0 -7
  27. package/src/components/calendar/Calendar.vue +0 -725
  28. package/src/components/calendar/index.js +0 -7
  29. package/src/components/calendar/uses.js +0 -1410
  30. package/src/components/chart/Chart.vue +0 -363
  31. package/src/components/chart/ChartToolbar.vue +0 -52
  32. package/src/components/chart/chart.core.js +0 -1170
  33. package/src/components/chart/chartZoom.core.js +0 -540
  34. package/src/components/chart/element/element.bar.js +0 -672
  35. package/src/components/chart/element/element.bar.time.js +0 -166
  36. package/src/components/chart/element/element.heatmap.js +0 -743
  37. package/src/components/chart/element/element.line.js +0 -611
  38. package/src/components/chart/element/element.pie.js +0 -197
  39. package/src/components/chart/element/element.scatter.js +0 -320
  40. package/src/components/chart/element/element.tip.js +0 -717
  41. package/src/components/chart/helpers/helpers.canvas.js +0 -265
  42. package/src/components/chart/helpers/helpers.constant.js +0 -235
  43. package/src/components/chart/helpers/helpers.util.js +0 -400
  44. package/src/components/chart/index.js +0 -9
  45. package/src/components/chart/model/index.js +0 -50
  46. package/src/components/chart/model/model.series.js +0 -125
  47. package/src/components/chart/model/model.store.js +0 -1427
  48. package/src/components/chart/plugins/plugins.interaction.js +0 -1659
  49. package/src/components/chart/plugins/plugins.legend.gradient.js +0 -606
  50. package/src/components/chart/plugins/plugins.legend.js +0 -1543
  51. package/src/components/chart/plugins/plugins.pie.js +0 -254
  52. package/src/components/chart/plugins/plugins.scrollbar.js +0 -732
  53. package/src/components/chart/plugins/plugins.title.js +0 -61
  54. package/src/components/chart/plugins/plugins.tooltip.js +0 -1041
  55. package/src/components/chart/scale/scale.js +0 -951
  56. package/src/components/chart/scale/scale.linear.js +0 -268
  57. package/src/components/chart/scale/scale.logarithmic.js +0 -135
  58. package/src/components/chart/scale/scale.step.js +0 -430
  59. package/src/components/chart/scale/scale.time.category.js +0 -338
  60. package/src/components/chart/scale/scale.time.js +0 -49
  61. package/src/components/chart/style/chart.scss +0 -405
  62. package/src/components/chart/uses.js +0 -721
  63. package/src/components/chartBrush/ChartBrush.vue +0 -323
  64. package/src/components/chartBrush/chartBrush.core.js +0 -691
  65. package/src/components/chartBrush/index.js +0 -9
  66. package/src/components/chartBrush/uses.js +0 -23
  67. package/src/components/chartGroup/ChartGroup.vue +0 -144
  68. package/src/components/chartGroup/index.js +0 -9
  69. package/src/components/chartGroup/style/chartGroup.scss +0 -5
  70. package/src/components/chartGroup/uses.js +0 -53
  71. package/src/components/checkbox/Checkbox.vue +0 -229
  72. package/src/components/checkbox/index.js +0 -7
  73. package/src/components/checkboxGroup/CheckboxGroup.vue +0 -44
  74. package/src/components/checkboxGroup/index.js +0 -7
  75. package/src/components/contextMenu/ContextMenu.vue +0 -95
  76. package/src/components/contextMenu/MenuList.vue +0 -182
  77. package/src/components/contextMenu/index.js +0 -7
  78. package/src/components/contextMenu/uses.js +0 -223
  79. package/src/components/datePicker/DatePicker.vue +0 -504
  80. package/src/components/datePicker/index.js +0 -7
  81. package/src/components/datePicker/uses.js +0 -460
  82. package/src/components/grid/Grid.vue +0 -1535
  83. package/src/components/grid/GridColumnSetting.vue +0 -358
  84. package/src/components/grid/GridFilterSetting.vue +0 -323
  85. package/src/components/grid/GridPagination.vue +0 -75
  86. package/src/components/grid/GridSummary.vue +0 -314
  87. package/src/components/grid/GridToolbar.vue +0 -35
  88. package/src/components/grid/icon/icon-option-button.vue +0 -17
  89. package/src/components/grid/icon/icon-sort-button.vue +0 -67
  90. package/src/components/grid/index.js +0 -11
  91. package/src/components/grid/style/grid.scss +0 -417
  92. package/src/components/grid/uses.js +0 -1629
  93. package/src/components/icon/Icon.vue +0 -53
  94. package/src/components/icon/index.js +0 -8
  95. package/src/components/inputNumber/InputNumber.vue +0 -212
  96. package/src/components/inputNumber/index.js +0 -7
  97. package/src/components/inputNumber/uses.js +0 -217
  98. package/src/components/loading/Loading.vue +0 -125
  99. package/src/components/loading/index.js +0 -7
  100. package/src/components/menu/Menu.vue +0 -79
  101. package/src/components/menu/MenuItem.vue +0 -201
  102. package/src/components/menu/index.js +0 -7
  103. package/src/components/message/Message.vue +0 -229
  104. package/src/components/message/index.js +0 -34
  105. package/src/components/messageBox/MessageBox.vue +0 -358
  106. package/src/components/messageBox/index.js +0 -22
  107. package/src/components/notification/Notification.vue +0 -316
  108. package/src/components/notification/index.js +0 -49
  109. package/src/components/pagination/Pagination.vue +0 -317
  110. package/src/components/pagination/index.js +0 -7
  111. package/src/components/pagination/pageButton.vue +0 -31
  112. package/src/components/progress/Progress.vue +0 -139
  113. package/src/components/progress/index.js +0 -7
  114. package/src/components/radio/Radio.vue +0 -159
  115. package/src/components/radio/index.js +0 -7
  116. package/src/components/radioGroup/RadioGroup.vue +0 -41
  117. package/src/components/radioGroup/index.js +0 -7
  118. package/src/components/scheduler/Scheduler.vue +0 -149
  119. package/src/components/scheduler/index.js +0 -7
  120. package/src/components/scheduler/uses.js +0 -183
  121. package/src/components/select/Select.vue +0 -556
  122. package/src/components/select/index.js +0 -7
  123. package/src/components/select/uses.js +0 -379
  124. package/src/components/slider/Slider.vue +0 -505
  125. package/src/components/slider/index.js +0 -7
  126. package/src/components/slider/uses.js +0 -391
  127. package/src/components/tabPanel/TabPanel.vue +0 -74
  128. package/src/components/tabPanel/index.js +0 -7
  129. package/src/components/tabs/Tabs.vue +0 -517
  130. package/src/components/tabs/index.js +0 -7
  131. package/src/components/textField/TextField.vue +0 -399
  132. package/src/components/textField/index.js +0 -7
  133. package/src/components/timePicker/TimePicker.vue +0 -364
  134. package/src/components/timePicker/index.js +0 -7
  135. package/src/components/toggle/Toggle.vue +0 -115
  136. package/src/components/toggle/index.js +0 -7
  137. package/src/components/tree/Tree.vue +0 -338
  138. package/src/components/tree/TreeNode.vue +0 -293
  139. package/src/components/tree/index.js +0 -7
  140. package/src/components/treeGrid/TreeGrid.vue +0 -1074
  141. package/src/components/treeGrid/TreeGridNode.vue +0 -349
  142. package/src/components/treeGrid/TreeGridToolbar.vue +0 -35
  143. package/src/components/treeGrid/icon/icon-tree.png +0 -0
  144. package/src/components/treeGrid/index.js +0 -9
  145. package/src/components/treeGrid/style/treeGrid.scss +0 -277
  146. package/src/components/treeGrid/uses.js +0 -1178
  147. package/src/components/window/Window.vue +0 -329
  148. package/src/components/window/index.js +0 -7
  149. package/src/components/window/uses.js +0 -908
  150. package/src/directives/clickoutside.js +0 -90
  151. package/src/main.js +0 -120
  152. package/src/style/components/input.scss +0 -108
  153. package/src/style/functions.scss +0 -3
  154. package/src/style/index.scss +0 -6
  155. package/src/style/lib/fonts/EVUI.eot +0 -0
  156. package/src/style/lib/fonts/EVUI.svg +0 -293
  157. package/src/style/lib/fonts/EVUI.ttf +0 -0
  158. package/src/style/lib/fonts/EVUI.woff +0 -0
  159. package/src/style/lib/icon.css +0 -888
  160. package/src/style/mixins.scss +0 -94
  161. package/src/style/themes.scss +0 -69
  162. package/src/style/variables.scss +0 -22
@@ -1,1535 +0,0 @@
1
- <template>
2
- <div
3
- v-if="$slots.toolbar || useGridSetting"
4
- ref="toolbarRef"
5
- class="toolbar-wrapper"
6
- :style="`width: ${gridWidth};`"
7
- >
8
- <!-- Toolbar -->
9
- <toolbar>
10
- <template #toolbarWrapper>
11
- <!-- Filtering Items -->
12
- <div
13
- class="filtering"
14
- :style="{ width: `${filteringItemsWidth}px` }"
15
- >
16
- <div
17
- v-if="isFiltering && !Object.keys(filteringItemsByColumn).length"
18
- class="filtering-items filtering-items--used"
19
- >
20
- <ev-icon icon="ev-icon-filter-list" />
21
- <span>Filter</span>
22
- </div>
23
- <div
24
- v-if="isFiltering && Object.keys(filteringItemsByColumn).length"
25
- ref="filteringItemsRef"
26
- class="filtering-items"
27
- >
28
- <template
29
- v-for="(field, idx) in Object.keys(filteringItemsByColumn)"
30
- :key="idx"
31
- >
32
- <template v-if="idx === 0">
33
- <div
34
- class="filtering-items__item filtering-items__item--filter"
35
- @click.stop="onExpandFilteringItems"
36
- >
37
- <ev-icon
38
- icon="ev-icon-filter-list"
39
- class="filtering-items-expand"
40
- />
41
- <span>
42
- Filter ({{ Object.keys(filteringItemsByColumn).length }})
43
- </span>
44
- <ev-icon
45
- class="filtering-items__item--remove"
46
- icon="ev-icon-s-close"
47
- style="margin-left: 0;"
48
- @click.stop="removeAllFiltering"
49
- />
50
- </div>
51
- </template>
52
- <ev-select
53
- v-if="idx === 1"
54
- v-model="columnOperator"
55
- :items="operatorItems"
56
- class="filtering-items__item--operator"
57
- @change="onChangeOperator"
58
- />
59
- <div
60
- class="filtering-items__item non-display"
61
- :data-field="field"
62
- @click.stop="onClickFilteringItem({
63
- caption: getFilteringItemByField(field)?.caption,
64
- field: field,
65
- },
66
- filteringItemsByColumn[field])"
67
- >
68
- <span class="filtering-items__item--title">
69
- {{ getFilteringItemByField(field)?.caption }}
70
- {{ getFilteringItemByField(field)?.comparison }}
71
- </span>
72
- <span
73
- v-if="filteringItemsByColumn[field].length < 2"
74
- class="filtering-items__item--value"
75
- :title="getFilteringItemByField(field)?.value"
76
- >
77
- {{ getFilteringItemByField(field)?.value }}
78
- </span>
79
- <span
80
- v-else
81
- class="filtering-items__item--value"
82
- >
83
- + {{ filteringItemsByColumn[field].length }}
84
- </span>
85
- <ev-icon
86
- class="filtering-items__item--remove"
87
- icon="ev-icon-s-close"
88
- @click="onApplyFilter(field, [])"
89
- />
90
- </div>
91
- </template>
92
- <!-- +N Count-->
93
- <div
94
- v-if="isShowColumnFilteringItems && Object.keys(filteringItemsByColumn).length
95
- && hiddenFilteringItemsCount > 0"
96
- class="filtering-items__item filtering-items__item--count"
97
- @click="onExpandFilteringItems"
98
- >
99
- + {{ hiddenFilteringItemsCount }}
100
- </div>
101
- </div>
102
- <div
103
- v-if="!isShowColumnFilteringItems && Object.keys(hiddenFilteringItemsByColumn).length"
104
- ref="hiddenFilteringItemsRef"
105
- v-clickoutside="() => { if (!isShowColumnFilteringItems) onExpandFilteringItems(); }"
106
- class="filtering-items filtering-items__hidden-items"
107
- :style="filteringItemsStyle"
108
- >
109
- <template
110
- v-for="(field, idx) in Object.keys(hiddenFilteringItemsByColumn)"
111
- :key="idx"
112
- >
113
- <div
114
- class="filtering-items__item"
115
- @click.stop="onClickFilteringItem({
116
- caption: getFilteringItemByField(field)?.caption,
117
- field: field,
118
- },
119
- hiddenFilteringItemsByColumn[field])"
120
- >
121
- <span class="filtering-items__item--title">
122
- {{ getFilteringItemByField(field)?.caption }}
123
- {{ getFilteringItemByField(field)?.comparison }}
124
- </span>
125
- <span
126
- v-if="hiddenFilteringItemsByColumn[field].length < 2"
127
- class="filtering-items__item--value"
128
- :title="getFilteringItemByField(field)?.value"
129
- >
130
- {{ getFilteringItemByField(field)?.value }}
131
- </span>
132
- <span
133
- v-else
134
- class="filtering-items__item--value"
135
- >
136
- + {{ hiddenFilteringItemsByColumn[field].length }}
137
- </span>
138
- <ev-icon
139
- class="filtering-items__item--remove"
140
- icon="ev-icon-s-close"
141
- @click="onApplyFilter(field, [], true)"
142
- />
143
- </div>
144
- </template>
145
- </div>
146
- </div>
147
- <grid-option-button
148
- v-if="useGridSetting"
149
- class="grid-setting__icon"
150
- @click="setGridSetting($event)"
151
- />
152
- <slot
153
- name="toolbar"
154
- :item="{ onSearch: onSearch }"
155
- />
156
- </template>
157
- </toolbar>
158
- </div>
159
- <div
160
- ref="grid-wrapper"
161
- v-resize="onResize"
162
- v-observe-visibility="{
163
- callback: onShow,
164
- once: true,
165
- }"
166
- v-bind="$attrs"
167
- class="grid-wrapper"
168
- :style="`width: ${gridWidth}; height: ${gridHeight};`"
169
- >
170
- <!-- Table -->
171
- <div
172
- v-cloak
173
- ref="grid"
174
- :class="{
175
- table: true,
176
- adjust: adjust,
177
- 'ev-grid': true,
178
- 'non-header': !showHeader,
179
- 'ev-grid--empty': !viewStore.length,
180
- }"
181
- >
182
- <!-- Header -->
183
- <div
184
- v-show="showHeader"
185
- ref="header"
186
- :class="{
187
- 'table-header': true,
188
- 'non-border': !!borderStyle,
189
- }"
190
- >
191
- <ul class="column-list">
192
- <!-- Header Checkbox -->
193
- <li
194
- v-if="useCheckbox.use"
195
- :class="{
196
- 'column': true,
197
- 'checkbox-all': true,
198
- 'non-border': !!borderStyle,
199
- }"
200
- :style="{
201
- width: `${minWidth}px`,
202
- 'border-right': '1px solid #CFCFCF'
203
- }"
204
- >
205
- <ev-checkbox
206
- v-if="useCheckbox.use && useCheckbox.headerCheck && useCheckbox.mode !== 'single'"
207
- v-model="isHeaderChecked"
208
- :disabled="isHeaderUncheckable"
209
- :indeterminate="isHeaderIndeterminate"
210
- @change="onCheckAll"
211
- />
212
- </li>
213
- <li
214
- v-if="useRowDetail"
215
- :class="{
216
- 'column': true,
217
- 'non-border': !!borderStyle,
218
- }"
219
- :style="{
220
- width: `${minWidth}px`,
221
- 'border-right': '1px solid #CFCFCF'
222
- }"
223
- />
224
- <!-- Column List -->
225
- <template
226
- v-for="(column, index) in orderedColumns"
227
- :key="index"
228
- >
229
- <!-- Header -->
230
- <li
231
- v-if="!column.hide && !column.hiddenDisplay"
232
- :data-index="index"
233
- :class="{
234
- column: true,
235
- render: isRenderer(column),
236
- 'non-border': !!borderStyle,
237
- [column.field]: column.field,
238
- }"
239
- :style="{
240
- width: `${column.width}px`,
241
- 'min-width': `${isRenderer(column) ? rendererMinWidth : minWidth}px`,
242
- 'margin-right': orderedColumns.length - 1 === index && (hasVerticalScrollBar
243
- || hasHorizontalScrollBar) ? `${scrollWidth}px` : '0px',
244
- 'border-right': orderedColumns.length - 1 === index ? 'none' : '1px solid #CFCFCF',
245
- }"
246
- :draggable="true"
247
- @dragstart="onDragStart"
248
- @dragover="onDragOver"
249
- @drop="onDrop"
250
- >
251
- <!-- Custom Header -->
252
- <template v-if="column.customHeader && !!$slots.customHeader">
253
- <slot name="customHeader" />
254
- </template>
255
- <template v-else>
256
- <!-- Column Name -->
257
- <span
258
- :title="column.caption"
259
- class="column-name"
260
- @click="onColumnContextMenu($event, column)"
261
- @click.prevent="columnMenu.show"
262
- >
263
- {{ column.caption }}
264
- <!-- Sort Icon -->
265
- <span @click.stop="onSort(column)">
266
- <template v-if="!!$slots.sortIcon">
267
- <span
268
- v-if="column.sortable === undefined ? true : column.sortable"
269
- class="column-sort__icon column-sort__icon--basic"
270
- :style="{
271
- height: `${rowHeight}px`,
272
- 'line-height': `${rowHeight}px`,
273
- }"
274
- >
275
- <slot name="sortIcon" />
276
- </span>
277
- <span
278
- v-if="sortField === column.field"
279
- :class="[{
280
- 'column-sort__icon': true,
281
- 'column-sort__icon--asc': sortOrder === 'asc',
282
- 'column-sort__icon--desc': sortOrder === 'desc',
283
- }]"
284
- :style="{
285
- height: `${rowHeight}px`,
286
- 'line-height': `${rowHeight}px`,
287
- }"
288
- >
289
- <slot :name="`sortIcon_${sortOrder}`" />
290
- </span>
291
- </template>
292
- <template v-else>
293
- <grid-sort-button
294
- v-if="column.sortable === undefined ? true : column.sortable"
295
- class="column-sort__icon column-sort__icon--basic"
296
- :icon="'basic'"
297
- :style="{
298
- height: `${rowHeight}px`,
299
- 'line-height': `${rowHeight}px`,
300
- }"
301
- />
302
- <grid-sort-button
303
- v-if="sortField === column.field"
304
- :class="[{
305
- 'column-sort__icon': true,
306
- 'column-sort__icon--asc': sortOrder === 'asc',
307
- 'column-sort__icon--desc': sortOrder === 'desc',
308
- }]"
309
- :icon="sortOrder"
310
- :style="{
311
- height: `${rowHeight}px`,
312
- 'line-height': `${rowHeight}px`,
313
- visibility: !!sortOrder ? column.hidden : true,
314
- }"
315
- />
316
- </template>
317
- </span>
318
- </span>
319
- </template>
320
- <!-- Column Resize -->
321
- <span
322
- class="column-resize"
323
- @mousedown.stop.left="onColumnResize(index, $event)"
324
- />
325
- </li>
326
- </template>
327
- <!-- Row Contextmenu Column -->
328
- <li
329
- v-if="$props.option.customContextMenu?.length"
330
- :class="{
331
- column: true,
332
- 'non-border': !!borderStyle,
333
- }"
334
- :style="{
335
- width: '30px',
336
- 'min-width': '30px',
337
- 'margin-right': (hasVerticalScrollBar || hasHorizontalScrollBar)
338
- ? `${scrollWidth}px` : '0px',
339
- }"
340
- >
341
- </li>
342
- </ul>
343
- </div>
344
- <!-- Body -->
345
- <div
346
- ref="body"
347
- :class="{
348
- stripe: stripeStyle,
349
- 'table-body': true,
350
- 'bottom-border': !!viewStore.length,
351
- 'non-border': !!borderStyle,
352
- }"
353
- @scroll="onScroll"
354
- @contextmenu="onContextMenu($event)"
355
- >
356
- <!-- vScroll Top -->
357
- <div
358
- :style="`height: ${vScrollTopHeight}px;`"
359
- class="vscroll-spacer"
360
- />
361
-
362
- <table ref="table">
363
- <tbody>
364
- <!-- Row List -->
365
- <template
366
- v-for="(row, rowIndex) in viewStore"
367
- :key="idColIndex != null ? row[2][idColIndex] : rowIndex"
368
- >
369
- <tr
370
- :data-index="row[0]"
371
- :class="{
372
- row: true,
373
- selected: row[3],
374
- highlight: row[0] === highlightIdx,
375
- 'non-border': !!borderStyle && borderStyle !== 'rows',
376
- }"
377
- :disabled="row[ROW_DISABLED_INDEX]"
378
- @click="onRowClick($event, row)"
379
- @contextmenu="onRowClick($event, row, true)"
380
- @dblclick="onRowDblClick($event, row)"
381
- >
382
- <!-- Row Checkbox -->
383
- <td
384
- v-if="useCheckbox.use"
385
- :class="{
386
- cell: true,
387
- 'row-checkbox': true,
388
- 'non-border': !!borderStyle,
389
- }"
390
- :style="{
391
- width: `${minWidth}px`,
392
- height: `${rowHeight}px`,
393
- 'border-right': '1px solid #CFCFCF',
394
- }"
395
- >
396
- <ev-checkbox
397
- v-model="row[1]"
398
- class="row-checkbox-input"
399
- :disabled="row[5] || row[ROW_DISABLED_INDEX]"
400
- @change="onCheck($event, row)"
401
- />
402
- </td>
403
- <!-- Row Detail toggle -->
404
- <td
405
- v-if="useRowDetail"
406
- :class="{
407
- cell: true,
408
- 'row-detail-toggle': true,
409
- 'non-border': !!borderStyle,
410
- 'row-detail-toggle--expanded': row[4],
411
- }"
412
- :style="{
413
- width: `${minWidth}px`,
414
- height: `${rowHeight}px`,
415
- 'border-right': '1px solid #CFCFCF',
416
- }"
417
- >
418
- <ev-icon
419
- v-model="row[4]"
420
- icon="ev-icon-s-play"
421
- class="row-detail-toggle-icon"
422
- @click.stop="onExpanded($event, row)"
423
- />
424
- </td>
425
- <!-- Cell -->
426
- <template
427
- v-for="(column, cellIndex) in orderedColumns"
428
- :key="`${idColIndex != null ? row[2][idColIndex] : rowIndex}-${cellIndex}`"
429
- >
430
- <td
431
- v-if="!column.hide && !column.hiddenDisplay"
432
- :data-name="column.field"
433
- :data-index="column.index"
434
- :class="{
435
- cell: true,
436
- render: isRenderer(column),
437
- [column.type]: column.type,
438
- [column.align]: column.align,
439
- [column.field]: column.field,
440
- 'non-border': !!borderStyle,
441
- }"
442
- :style="{
443
- width: `${column.width}px`,
444
- height: `${rowHeight}px`,
445
- 'line-height': `${rowHeight}px`,
446
- 'min-width': `${isRenderer(column) ? rendererMinWidth : minWidth}px`,
447
- 'border-right': orderedColumns.length - 1 === cellIndex
448
- ? 'none' : '1px solid #CFCFCF',
449
- }"
450
- :disabled="row[ROW_DISABLED_INDEX]"
451
- >
452
- <!-- Cell Renderer -->
453
- <div v-if="!!$slots[column.field]">
454
- <slot
455
- :name="column.field"
456
- :item="{ row, column }"
457
- :disabled="row[ROW_DISABLED_INDEX]"
458
- />
459
- </div>
460
- <!-- Cell Value -->
461
- <template v-else>
462
- <div :title="getConvertValue(column, row[2][column.index])">
463
- {{ getConvertValue(column, row[2][column.index]) }}
464
- </div>
465
- </template>
466
- </td>
467
- </template>
468
- <!-- Row Contextmenu Button -->
469
- <td
470
- v-if="$props.option.customContextMenu?.length"
471
- :class="{
472
- 'row-contextmenu': true,
473
- 'non-border': !!borderStyle,
474
- }"
475
- :style="{
476
- position: 'sticky',
477
- right: 0,
478
- width: '30px',
479
- height: `${rowHeight}px`,
480
- 'min-width': '30px',
481
- 'line-height': `${rowHeight}px`,
482
- }"
483
- :disabled="row[ROW_DISABLED_INDEX]"
484
- >
485
- <template v-if="$slots.contextmenuIcon">
486
- <span
487
- class="row-contextmenu__btn"
488
- :disabled="row[ROW_DISABLED_INDEX]"
489
- @click="onContextMenu($event)"
490
- >
491
- <slot name="contextmenuIcon"></slot>
492
- </span>
493
- </template>
494
- <template v-else>
495
- <grid-option-button
496
- icon="ev-icon-warning2"
497
- class="row-contextmenu__btn"
498
- :disabled="row[ROW_DISABLED_INDEX]"
499
- @click="onContextMenu($event)"
500
- />
501
- </template>
502
- </td>
503
- </tr>
504
- <tr
505
- v-if="useRowDetail && $slots?.rowDetail && row[4]"
506
- >
507
- <td :colspan="row.length">
508
- <div
509
- :style="{
510
- width: '100%',
511
- height: `${detailRowHeight}px`,
512
- 'min-height': `${detailRowHeight}px`,
513
- 'max-height': `${detailRowHeight}px`
514
- }"
515
- >
516
- <slot
517
- name="rowDetail"
518
- :item="{ row }"
519
- />
520
- </div>
521
- </td>
522
- </tr>
523
- </template>
524
- <tr v-if="!viewStore.length">
525
- <td class="is-empty">{{ emptyText }}</td>
526
- </tr>
527
- </tbody>
528
- </table>
529
- <!-- vScroll Bottom -->
530
- <div
531
- :style="`height: ${vScrollBottomHeight}px;`"
532
- class="vscroll-spacer"
533
- />
534
-
535
- <!-- Context Menu -->
536
- <ev-context-menu
537
- ref="menu"
538
- :custom-class="contextMenuClass"
539
- :items="contextMenuItems"
540
- />
541
- <ev-context-menu
542
- ref="columnMenu"
543
- :items="columnMenuItems"
544
- />
545
- <ev-context-menu
546
- ref="gridSettingMenu"
547
- :items="gridSettingContextMenuItems"
548
- :is-show-menu-on-click="isShowMenuOnClick"
549
- />
550
- </div>
551
- <!-- Resize Line -->
552
- <div
553
- v-show="showResizeLine"
554
- ref="resizeLine"
555
- class="table-resize-line"
556
- />
557
- </div>
558
- </div>
559
- <!-- Summary -->
560
- <grid-summary
561
- v-if="useSummary"
562
- :ordered-columns="orderedColumns"
563
- :stores="stores"
564
- :use-checkbox="useCheckbox.use"
565
- :style-option="{
566
- borderStyle,
567
- minWidth,
568
- rowHeight,
569
- }"
570
- :scroll-left="summaryScroll"
571
- />
572
- <!-- Pagination -->
573
- <grid-pagination
574
- v-if="usePage && !isInfinite"
575
- v-model="currentPage"
576
- :total="pageTotal"
577
- :per-page="perPage"
578
- :visible-page="visiblePage"
579
- :show-page-info="showPageInfo"
580
- :order="order"
581
- />
582
- <!-- Filter Setting -->
583
- <filter-setting
584
- v-model:is-show="isShowFilterSetting"
585
- v-model:items="filteringItemsByColumn"
586
- :column="filteringColumn"
587
- :position="filterSettingPosition"
588
- @apply-filtering="onApplyFilter"
589
- />
590
- <!-- Column Setting -->
591
- <column-setting
592
- v-model:is-show="isShowColumnSetting"
593
- v-model:is-show-menu-on-click="isShowMenuOnClick"
594
- :columns="updatedColumns"
595
- :hidden-column="hiddenColumn"
596
- :position="columnSettingPosition"
597
- :text-info="columnSettingTextInfo"
598
- @apply-column="onApplyColumn"
599
- />
600
- </template>
601
-
602
- <script>
603
- import {
604
- reactive,
605
- toRefs,
606
- computed,
607
- watch,
608
- onMounted,
609
- onUpdated,
610
- onActivated,
611
- nextTick,
612
- ref,
613
- onBeforeMount, onUnmounted,
614
- } from 'vue';
615
- import { clickoutside } from '@/directives/clickoutside';
616
- import { cloneDeep } from 'lodash-es';
617
- import Toolbar from './GridToolbar';
618
- import GridPagination from './GridPagination';
619
- import GridSummary from './GridSummary';
620
- import ColumnSetting from './GridColumnSetting.vue';
621
- import FilterSetting from './GridFilterSetting.vue';
622
- import GridSortButton from './icon/icon-sort-button';
623
- import GridOptionButton from './icon/icon-option-button.vue';
624
- import {
625
- commonFunctions,
626
- scrollEvent,
627
- resizeEvent,
628
- clickEvent,
629
- checkEvent,
630
- expandEvent,
631
- sortEvent,
632
- filterEvent,
633
- contextMenuEvent,
634
- storeEvent,
635
- pagingEvent,
636
- columnSettingEvent,
637
- dragEvent,
638
- getUpdatedColumns,
639
- } from './uses';
640
-
641
- export default {
642
- name: 'EvGrid',
643
- directives: {
644
- clickoutside,
645
- },
646
- components: {
647
- Toolbar,
648
- GridPagination,
649
- GridSummary,
650
- ColumnSetting,
651
- FilterSetting,
652
- GridSortButton,
653
- GridOptionButton,
654
- },
655
- props: {
656
- columns: {
657
- type: [Array],
658
- default: () => [],
659
- },
660
- rows: {
661
- type: [Array],
662
- default: () => [],
663
- },
664
- width: {
665
- type: [String, Number],
666
- default: '100%',
667
- },
668
- height: {
669
- type: [String, Number],
670
- default: '100%',
671
- },
672
- selected: {
673
- type: [Array],
674
- default: () => [],
675
- },
676
- checked: {
677
- type: [Array],
678
- default: () => [],
679
- },
680
- uncheckable: {
681
- type: [Array],
682
- default: () => [],
683
- },
684
- expanded: {
685
- type: [Array],
686
- default: () => [],
687
- },
688
- disabledRows: {
689
- type: [Array],
690
- default: () => [],
691
- },
692
- /**
693
- * @type {Object}
694
- * @property {number} columnWidth 컬럼 너비 minWidth
695
- * @property {number} scrollWidth 스크롤 너비
696
- * @property {number} rowHeight 행 높이
697
- * @property {number} gridWidth 그리드 너비 width
698
- * @property {number} gridHeight 그리드 높이
699
- * @property {boolean} adjust 컬럼 너비 조정 여부
700
- * @property {boolean} useGridSetting 그리드 설정 사용 여부
701
- * @property {number} gridWidth 그리드 너비 width
702
- * @property {number} gridHeight 그리드 높이
703
- * @property {boolean} adjust 컬럼 너비 조정 여부
704
- * @property {boolean} useGridSetting 그리드 설정 사용 여부
705
- */
706
- option: {
707
- type: Object,
708
- default: () => ({}),
709
- },
710
- },
711
- emits: {
712
- 'update:selected': null,
713
- 'update:checked': null,
714
- 'update:expanded': null,
715
- 'check-row': null,
716
- 'check-all': null,
717
- 'click-row': null,
718
- 'dblclick-row': null,
719
- 'page-change': null,
720
- 'sort-column': null,
721
- 'expand-row': null,
722
- 'resize-column': ({ column, columns }) => ({ column, columns }),
723
- 'change-column-order': ({ column, columns }) => ({ column, columns }),
724
- 'change-column-status': ({ columns }) => ({ columns }),
725
- 'change-column-info': ({ type, columns }) => ({ type, columns }),
726
- },
727
- setup(props) {
728
- // const ROW_INDEX = 0;
729
- const ROW_CHECK_INDEX = 1;
730
- const ROW_DATA_INDEX = 2;
731
- const ROW_SELECT_INDEX = 3;
732
- const ROW_EXPAND_INDEX = 4;
733
- const ROW_DISABLED_INDEX = 6;
734
- const {
735
- isRenderer,
736
- getComponentName,
737
- getConvertValue,
738
- getColumnIndex,
739
- setPixelUnit,
740
- } = commonFunctions();
741
- const toolbarRef = ref(null);
742
- const useGridSetting = computed(() => (props.option?.useGridSetting?.use || false));
743
- const showHeader = computed(() => (props.option.showHeader ?? true));
744
- const useSummary = computed(() => (props.option?.useSummary || false));
745
- const stripeStyle = computed(() => (props.option.style?.stripe || false));
746
- const borderStyle = computed(() => (props.option.style?.border || ''));
747
- const highlightIdx = computed(() => (props.option.style?.highlight ?? -1));
748
- const emptyText = computed(() => (props.option.emptyText ?? 'No records'));
749
- const rowMinHeight = props.option.rowMinHeight || 35;
750
- const filteringItemsWidth = ref(0);
751
- const elementInfo = reactive({
752
- body: null,
753
- header: null,
754
- table: null,
755
- resizeLine: null,
756
- 'grid-wrapper': null,
757
- });
758
- const filterInfo = reactive({
759
- isSearch: false,
760
- searchWord: '',
761
- isFiltering: computed(() => (props.option.useFilter ?? false)),
762
- isShowFilterSetting: false,
763
- filterSettingPosition: {
764
- left: 0,
765
- top: 0,
766
- },
767
- filteringColumn: null,
768
- filteringItemsByColumn: {},
769
- columnOperator: 'and',
770
- });
771
- const columnSettingInfo = reactive({
772
- isShowColumnSetting: false,
773
- isFilteringColumn: false, // hide된 컬럼이 있는지
774
- visibleColumnIdx: [], // 보여지는 컬럼의 인덱스 목록
775
- hiddenColumn: '',
776
- columnSettingPosition: {
777
- top: 0,
778
- left: 0,
779
- columnListMenuWidth: 0,
780
- },
781
- useDefaultColumnSetting: computed(
782
- () => props.option?.useGridSetting?.useDefaultColumnSetting ?? true,
783
- ),
784
- columnSettingTextInfo: {
785
- title: props.option?.useGridSetting?.columnMenuText ?? 'Column List',
786
- search: props.option?.useGridSetting?.searchText ?? 'Search',
787
- empty: props.option?.useGridSetting?.emptyText ?? 'No records',
788
- ok: props.option?.useGridSetting?.okBtnText ?? 'OK',
789
- },
790
- });
791
- const stores = reactive({
792
- viewStore: [],
793
- originStore: [],
794
- pagingStore: [],
795
- searchStore: [],
796
- filterStore: [],
797
- store: computed(() => {
798
- const store = filterInfo.isFiltering ? stores.filterStore : stores.originStore;
799
- return filterInfo.isSearch ? stores.searchStore : store;
800
- }),
801
- filteredColumns: [],
802
- movedColumns: [],
803
- originColumns: computed(() => props.columns.map((column, index) => ({
804
- index,
805
- hiddenDisplay: false,
806
- ...column,
807
- width: isFinite(column.width) ? column.width : undefined,
808
- sortOption: {
809
- sortType: column?.sortOption?.sortType || 'init',
810
- },
811
- }))),
812
- orderedColumns: computed(() => {
813
- const columns = stores.movedColumns.length
814
- ? stores.movedColumns : stores.originColumns;
815
- return stores.filteredColumns.length ? stores.filteredColumns : columns;
816
- }),
817
- updatedColumns: computed(() => getUpdatedColumns(stores)),
818
- });
819
- const pageInfo = reactive({
820
- usePage: computed(() => (props.option.page?.use || false)),
821
- useClient: props.option.page?.useClient || false,
822
- isInfinite: computed(() => (props.option.page?.isInfinite || false)),
823
- startIndex: 0,
824
- prevPage: 0,
825
- currentPage: 0,
826
- pageTotal: computed(() =>
827
- (props.option.page?.useClient ? stores.store.length : props.option.page?.total)),
828
- perPage: computed(() => (props.option.page?.perPage || 20)),
829
- visiblePage: computed(() => (props.option.page?.visiblePage || 8)),
830
- order: computed(() => (props.option.page?.order || 'center')),
831
- showPageInfo: computed(() => (props.option.page?.showPageInfo || false)),
832
- isClientPaging: computed(() =>
833
- pageInfo.useClient && pageInfo.usePage && !pageInfo.isInfinite),
834
- isHighlight: false,
835
- highlightPage: 0,
836
- });
837
- const checkInfo = reactive({
838
- prevCheckedRow: [],
839
- isHeaderChecked: false,
840
- isHeaderUncheckable: false,
841
- isHeaderIndeterminate: false,
842
- checkedRows: props.checked,
843
- useCheckbox: computed(() => (props.option.useCheckbox || {})),
844
- });
845
- const expandedInfo = reactive({
846
- expandedRows: props.expanded,
847
- useRowDetail: computed(() => props.option?.rowDetail?.use ?? false),
848
- detailRowHeight: computed(() => (props.option?.rowDetail?.detailRowHeight)),
849
- });
850
- const scrollInfo = reactive({
851
- lastScroll: {
852
- top: 0,
853
- left: 0,
854
- },
855
- vScrollTopHeight: 0,
856
- vScrollBottomHeight: 0,
857
- hasVerticalScrollBar: false,
858
- hasHorizontalScrollBar: false,
859
- });
860
- const selectInfo = reactive({
861
- contextmenuInfo: props.contextmenuInfo,
862
- selectedRow: props.selected,
863
- useSelect: computed(() => props.option?.useSelection?.use ?? true),
864
- multiple: computed(() => props.option?.useSelection?.multiple ?? false),
865
- });
866
- const sortInfo = reactive({
867
- isSorting: false,
868
- sortField: '',
869
- sortOrder: '',
870
- sortColumn: {},
871
- sortFunction: props.option.customAscFunction ?? {},
872
- });
873
- const contextInfo = reactive({
874
- menu: null,
875
- contextMenuItems: [],
876
- contextMenuClass: props.option.customContextMenuClass || '',
877
- columnMenu: null,
878
- columnMenuItems: [],
879
- columnMenuTextInfo: props.option.columnMenuText || {},
880
- hiddenColumnMenuItem: props.option.hiddenColumnMenuItem || {},
881
- customContextMenu: props.option.customContextMenu || [],
882
- gridSettingMenu: null,
883
- gridSettingContextMenuItems: [],
884
- customGridSettingContextMenu: computed(
885
- () => props.option?.useGridSetting?.customContextMenu || [],
886
- ),
887
- isShowMenuOnClick: false,
888
- });
889
- const resizeInfo = reactive({
890
- minWidth: 40,
891
- rendererMinWidth: 80,
892
- iconWidth: 42,
893
- showResizeLine: false,
894
- adjust: props.option.adjust || false,
895
- columnWidth: props.option.columnWidth || 80,
896
- scrollWidth: props.option.scrollWidth || 17,
897
- rowHeight: computed(() =>
898
- (props.option.rowHeight > rowMinHeight ? props.option.rowHeight : rowMinHeight)),
899
- gridWidth: computed(() => (props.width ? setPixelUnit(props.width) : '100%')),
900
- gridHeight: computed(() => (props.height ? setPixelUnit(props.height) : '100%')),
901
- });
902
- const clearCheckInfo = () => {
903
- checkInfo.checkedRows = [];
904
- checkInfo.isHeaderChecked = false;
905
- checkInfo.isHeaderIndeterminate = false;
906
- stores.store.forEach((row) => {
907
- row[ROW_CHECK_INDEX] = false;
908
- });
909
- };
910
- const clearSelectInfo = () => {
911
- selectInfo.selectedRow = [];
912
- stores.store.forEach((row) => {
913
- row[ROW_SELECT_INDEX] = false;
914
- });
915
- };
916
- const clearExpandedInfo = () => {
917
- stores.store.forEach((row) => {
918
- row[ROW_EXPAND_INDEX] = false;
919
- });
920
- expandedInfo.expandedRows = [];
921
- };
922
- const {
923
- getPagingData,
924
- updatePagingInfo,
925
- changePage,
926
- } = pagingEvent({
927
- stores,
928
- pageInfo,
929
- sortInfo,
930
- filterInfo,
931
- elementInfo,
932
- clearCheckInfo,
933
- });
934
- const summaryScroll = ref(0);
935
- const {
936
- updateVScroll,
937
- updateHScroll,
938
- onScroll,
939
- } = scrollEvent({
940
- scrollInfo,
941
- stores,
942
- elementInfo,
943
- resizeInfo,
944
- pageInfo,
945
- summaryScroll,
946
- expandedInfo,
947
- getPagingData,
948
- updatePagingInfo,
949
- });
950
-
951
- const {
952
- onCheck,
953
- onCheckAll,
954
- } = checkEvent({ checkInfo, stores, pageInfo, getPagingData, updatePagingInfo });
955
-
956
- const {
957
- onExpanded,
958
- } = expandEvent({
959
- expandedInfo,
960
- stores,
961
- });
962
-
963
- const {
964
- onSort,
965
- getSortTarget,
966
- setSort,
967
- setSortInfo,
968
- hasSortTarget,
969
- } = sortEvent({ sortInfo, stores, updatePagingInfo });
970
-
971
- const {
972
- onSearch,
973
- setFilter,
974
- setHeaderCheckboxByFilter,
975
- } = filterEvent({
976
- columnSettingInfo,
977
- filterInfo,
978
- stores,
979
- checkInfo,
980
- pageInfo,
981
- getConvertValue,
982
- updateVScroll,
983
- getPagingData,
984
- updatePagingInfo,
985
- getColumnIndex,
986
- });
987
-
988
- const {
989
- setStore,
990
- } = storeEvent({
991
- selectInfo,
992
- checkInfo,
993
- stores,
994
- sortInfo,
995
- elementInfo,
996
- filterInfo,
997
- expandedInfo,
998
- setSort,
999
- setSortInfo,
1000
- updateVScroll,
1001
- setFilter,
1002
- });
1003
-
1004
- const {
1005
- calculatedColumn,
1006
- onResize,
1007
- onShow,
1008
- onColumnResize,
1009
- } = resizeEvent({
1010
- resizeInfo,
1011
- elementInfo,
1012
- checkInfo,
1013
- expandedInfo,
1014
- stores,
1015
- filterInfo,
1016
- isRenderer,
1017
- updateVScroll,
1018
- updateHScroll,
1019
- contextInfo,
1020
- });
1021
-
1022
- const {
1023
- setPositionColumnSetting,
1024
- initColumnSettingInfo,
1025
- onApplyColumn,
1026
- setColumnHidden,
1027
- } = columnSettingEvent({
1028
- stores,
1029
- columnSettingInfo,
1030
- contextInfo,
1031
- onSearch,
1032
- onResize,
1033
- });
1034
-
1035
- const {
1036
- setContextMenu,
1037
- onContextMenu,
1038
- onColumnContextMenu,
1039
- onGridSettingContextMenu,
1040
- } = contextMenuEvent({
1041
- contextInfo,
1042
- stores,
1043
- selectInfo,
1044
- useGridSetting,
1045
- filterInfo,
1046
- columnSettingInfo,
1047
- setColumnHidden,
1048
- onSort,
1049
- });
1050
-
1051
- const {
1052
- onRowClick,
1053
- onRowDblClick,
1054
- } = clickEvent({ selectInfo, stores });
1055
-
1056
- const {
1057
- onDragStart,
1058
- onDragOver,
1059
- onDrop,
1060
- } = dragEvent({ stores });
1061
-
1062
- const setGridSetting = (e) => {
1063
- contextInfo.gridSettingContextMenuItems.length = 0;
1064
- if (contextInfo.customGridSettingContextMenu.length) {
1065
- onGridSettingContextMenu(e);
1066
- } else {
1067
- columnSettingInfo.isShowColumnSetting = true;
1068
- }
1069
- };
1070
-
1071
- const onMouseWheel = (e) => {
1072
- if (e.type === 'wheel') {
1073
- contextInfo.menu?.hide(e);
1074
- }
1075
- if (e.type === 'scroll' && !e.target.classList?.contains('table-body')
1076
- && !e.target.offsetParent?.classList?.contains('ev-select-dropbox')
1077
- && !e.target.offsetParent?.classList?.contains('ev-grid-column-setting')
1078
- && !e.target.offsetParent?.classList?.contains('ev-text-field-wrapper')) {
1079
- filterInfo.isShowFilterSetting = false;
1080
- columnSettingInfo.isShowColumnSetting = false;
1081
- contextInfo.isShowMenuOnClick = false;
1082
- contextInfo.columnMenu?.hide(e);
1083
- contextInfo.gridSettingMenu?.hide();
1084
- }
1085
- };
1086
-
1087
- onMounted(() => {
1088
- calculatedColumn();
1089
- setStore({ rows: props.rows, isInit: true });
1090
- document.addEventListener('wheel', onMouseWheel, { capture: false });
1091
- document.addEventListener('scroll', onMouseWheel, { capture: true });
1092
- });
1093
-
1094
- onUnmounted(() => {
1095
- document.removeEventListener('wheel', onMouseWheel, { capture: false });
1096
- document.removeEventListener('scroll', onMouseWheel, { capture: true });
1097
- });
1098
-
1099
- onActivated(() => {
1100
- onResize();
1101
- });
1102
-
1103
- onUpdated(() => {
1104
- filteringItemsWidth.value = elementInfo['grid-wrapper']?.offsetWidth / 1.5 || 0;
1105
- });
1106
-
1107
- watch(() => columnSettingInfo.isShowColumnSetting, (isShowColumnSetting) => {
1108
- if (!isShowColumnSetting) {
1109
- contextInfo.gridSettingMenu?.hide();
1110
- return;
1111
- }
1112
- setPositionColumnSetting(toolbarRef.value);
1113
- });
1114
-
1115
- watch(
1116
- () => props.columns,
1117
- () => {
1118
- if (!hasSortTarget()) {
1119
- setSortInfo(getSortTarget());
1120
- setSort();
1121
- } else {
1122
- setSortInfo(getSortTarget());
1123
- }
1124
- filterInfo.filteringColumn = null;
1125
- filterInfo.filteringItemsByColumn = {};
1126
- stores.filterStore = [];
1127
- setStore({ rows: [], isMakeIndex: false });
1128
- initColumnSettingInfo();
1129
- stores.movedColumns.length = 0;
1130
- }, { deep: true },
1131
- );
1132
- watch(
1133
- () => sortInfo.isSorting,
1134
- (value) => {
1135
- if (value) {
1136
- setStore({ rows: stores.originStore, isMakeIndex: false });
1137
- sortInfo.isSorting = !value;
1138
- if (pageInfo.isClientPaging) {
1139
- pageInfo.currentPage = 1;
1140
- stores.pagingStore = getPagingData();
1141
- clearCheckInfo();
1142
- }
1143
- }
1144
- },
1145
- );
1146
- watch(
1147
- () => props.rows,
1148
- (value) => {
1149
- setStore({ rows: value });
1150
- if (filterInfo.isSearch) {
1151
- onSearch(filterInfo.searchWord);
1152
- }
1153
- onResize();
1154
- }, { deep: true },
1155
- );
1156
- watch(() => props.uncheckable,
1157
- () => {
1158
- setStore({ rows: props.rows });
1159
- }, { deep: true });
1160
- watch(
1161
- () => props.checked,
1162
- (value) => {
1163
- checkInfo.checkedRows = value;
1164
- },
1165
- );
1166
- watch(() => props.disabledRows, () => {
1167
- if (stores.store.length) {
1168
- stores.store.forEach((row) => {
1169
- row[ROW_DISABLED_INDEX] = props.disabledRows.includes(row[ROW_DATA_INDEX]);
1170
- });
1171
- }
1172
- }, { deep: true });
1173
- watch(
1174
- () => checkInfo.checkedRows,
1175
- (value) => {
1176
- checkInfo.isHeaderChecked = false;
1177
- let store = stores.store;
1178
- if (pageInfo.isClientPaging) {
1179
- store = getPagingData();
1180
- }
1181
- if (store.length) {
1182
- store.forEach((row) => {
1183
- row[ROW_CHECK_INDEX] = value.includes(row[ROW_DATA_INDEX]);
1184
- });
1185
- checkInfo.isHeaderChecked = value.length === store.length;
1186
- }
1187
- updateVScroll();
1188
- },
1189
- );
1190
- watch(
1191
- () => props.selected,
1192
- (value) => {
1193
- if (selectInfo.useSelect) {
1194
- selectInfo.selectedRow = value;
1195
- }
1196
- },
1197
- );
1198
- watch(
1199
- () => selectInfo.selectedRow,
1200
- (value) => {
1201
- if (selectInfo.useSelect) {
1202
- stores.store.forEach((row) => {
1203
- row[ROW_SELECT_INDEX] = value.includes(row[ROW_DATA_INDEX])
1204
- && !props.disabledRows.includes(row[ROW_DATA_INDEX]);
1205
- });
1206
- updateVScroll();
1207
- }
1208
- },
1209
- );
1210
- watch(
1211
- () => highlightIdx.value,
1212
- async (index) => {
1213
- await nextTick();
1214
- if (index >= 0) {
1215
- if (pageInfo.usePage && !pageInfo.isInfinite) {
1216
- pageInfo.highlightPage = Math.ceil(index / pageInfo.perPage) || 1;
1217
- if (pageInfo.highlightPage !== pageInfo.currentPage) {
1218
- pageInfo.currentPage = pageInfo.highlightPage;
1219
- pageInfo.isHighlight = true;
1220
- return;
1221
- }
1222
- }
1223
- elementInfo.body.scrollTop = resizeInfo.rowHeight * highlightIdx.value;
1224
- }
1225
- },
1226
- );
1227
- watch(
1228
- () => checkInfo.useCheckbox.mode,
1229
- () => {
1230
- clearCheckInfo();
1231
- },
1232
- );
1233
- watch(
1234
- () => selectInfo.useSelect,
1235
- () => {
1236
- clearSelectInfo();
1237
- },
1238
- );
1239
- watch(
1240
- () => selectInfo.multiple,
1241
- () => {
1242
- clearSelectInfo();
1243
- },
1244
- );
1245
- watch(
1246
- () => props.checked.length,
1247
- (checkedSize) => {
1248
- if (!checkedSize) {
1249
- clearCheckInfo();
1250
- }
1251
- },
1252
- );
1253
- watch(
1254
- () => props.expanded.length,
1255
- (expendedSize) => {
1256
- if (!expendedSize) {
1257
- clearExpandedInfo();
1258
- }
1259
- updateVScroll();
1260
- },
1261
- );
1262
- watch(
1263
- () => [props.option.columnWidth, resizeInfo.gridWidth],
1264
- async () => {
1265
- await nextTick();
1266
- resizeInfo.columnWidth = props.option.columnWidth;
1267
- const gridWrapper = elementInfo['grid-wrapper'];
1268
- gridWrapper.style.width = resizeInfo.gridWidth;
1269
- gridWrapper.style.height = resizeInfo.gridHeight;
1270
- stores.orderedColumns.map((column) => {
1271
- const item = column;
1272
-
1273
- if (!props.columns[column.index]?.width && !item.resized) {
1274
- item.width = 0;
1275
- }
1276
-
1277
- return item;
1278
- });
1279
- onResize();
1280
- },
1281
- );
1282
- watch(
1283
- () => props.option.searchValue,
1284
- (value) => {
1285
- if (value !== undefined) {
1286
- onSearch(value?.value ?? value);
1287
- if (pageInfo.isClientPaging) {
1288
- clearCheckInfo();
1289
- clearSelectInfo();
1290
- }
1291
- }
1292
- }, { immediate: true },
1293
- );
1294
- watch(
1295
- () => props.option.page?.currentPage,
1296
- (value) => {
1297
- const current = !value ? 1 : value;
1298
- pageInfo.currentPage = !props.option.page?.isInfinite ? current : 1;
1299
- }, { immediate: true },
1300
- );
1301
- watch(
1302
- () => pageInfo.currentPage,
1303
- (current, before) => {
1304
- nextTick(() => {
1305
- changePage(before);
1306
- if (pageInfo.isClientPaging && current !== before) {
1307
- clearCheckInfo();
1308
- clearSelectInfo();
1309
- }
1310
- updateVScroll();
1311
- if (current === pageInfo.highlightPage && pageInfo.isHighlight) {
1312
- elementInfo.body.scrollTop = resizeInfo.rowHeight * highlightIdx.value;
1313
- pageInfo.isHighlight = !pageInfo.isHighlight;
1314
- }
1315
- });
1316
- },
1317
- );
1318
- const filteringItemsBoxPosition = reactive({
1319
- boxTop: 0,
1320
- boxLeft: 0,
1321
- });
1322
- const filteringItemsRef = ref(null);
1323
- const isShowFilteringItemsBox = ref(false);
1324
- const isShowColumnFilteringItems = ref(false);
1325
- const hiddenFilteringItemsRef = ref(null);
1326
- const hiddenFilteringItemsByColumn = ref({});
1327
- const selectedFilteringColumn = reactive({
1328
- caption: '',
1329
- field: '',
1330
- });
1331
- const selectedFilteringItems = ref([]);
1332
- const operatorItems = [
1333
- { name: 'AND', value: 'and' },
1334
- { name: 'OR', value: 'or' },
1335
- ];
1336
- const hiddenFilteringItemsCount = ref(0);
1337
-
1338
- const onClickFilteringItem = ({ caption, field }, filters) => {
1339
- selectedFilteringColumn.caption = caption;
1340
- selectedFilteringColumn.field = field;
1341
- selectedFilteringItems.value = filters;
1342
- if (filters?.length > 1) { // open filtering items box
1343
- isShowFilteringItemsBox.value = true;
1344
- const x = filteringItemsRef.value.getBoundingClientRect().left;
1345
- const y = window.pageYOffset + filteringItemsRef.value.getBoundingClientRect().top
1346
- + filteringItemsRef.value.getBoundingClientRect().height;
1347
- filteringItemsBoxPosition.boxTop = `${y}px`;
1348
- filteringItemsBoxPosition.boxLeft = `${x}px`;
1349
- }
1350
- };
1351
-
1352
- const onChangeOperator = () => {
1353
- stores.filterStore = [];
1354
- setStore({ rows: [], isMakeIndex: false });
1355
- };
1356
-
1357
- const setColumnFilteringItems = async (isInit) => {
1358
- if (isInit && isShowColumnFilteringItems.value) {
1359
- hiddenFilteringItemsCount.value = 0;
1360
- }
1361
- const conditionItems = filteringItemsRef.value
1362
- ?.getElementsByClassName('filtering-items__item');
1363
- const hiddenItemList = [];
1364
- let sumWidth = 0;
1365
- if (conditionItems) {
1366
- for (let i = 0; i < conditionItems.length; i++) {
1367
- const itemEl = conditionItems[i];
1368
- itemEl.classList.remove('non-display');
1369
- const boxWidth = filteringItemsRef.value.getBoundingClientRect()?.width;
1370
- const { width } = itemEl.getBoundingClientRect();
1371
- sumWidth += width + 10;
1372
- if (boxWidth - 150 <= sumWidth
1373
- && !itemEl.classList.contains('filtering-items__item--count')) {
1374
- hiddenFilteringItemsCount.value++;
1375
- hiddenItemList.push(itemEl);
1376
- hiddenFilteringItemsByColumn.value = {
1377
- ...hiddenFilteringItemsByColumn.value,
1378
- [itemEl.dataset.field]:
1379
- cloneDeep(filterInfo.filteringItemsByColumn[itemEl.dataset.field]),
1380
- };
1381
- } else {
1382
- delete hiddenFilteringItemsByColumn.value[itemEl.dataset.field];
1383
- }
1384
- }
1385
- conditionItems.forEach((item) => {
1386
- const isHidden = hiddenItemList.includes(item);
1387
- item.classList.toggle('non-display', isHidden);
1388
- });
1389
- }
1390
- };
1391
-
1392
- const onApplyFilter = async (field, list) => {
1393
- if (!list?.length) {
1394
- delete hiddenFilteringItemsByColumn.value[field];
1395
- delete filterInfo.filteringItemsByColumn[field];
1396
- } else {
1397
- filterInfo.filteringItemsByColumn[field] = list;
1398
- isShowColumnFilteringItems.value = true;
1399
- }
1400
- await nextTick();
1401
- setColumnFilteringItems(true);
1402
- filterInfo.isShowFilterSetting = false; // filter setting close
1403
- stores.filterStore = [];
1404
- setStore({ rows: [], isMakeIndex: false });
1405
-
1406
- setHeaderCheckboxByFilter(stores.filterStore);
1407
- };
1408
-
1409
- let expandTimer = null;
1410
- const onExpandFilteringItems = () => {
1411
- if (expandTimer) {
1412
- clearTimeout(expandTimer);
1413
- }
1414
- expandTimer = setTimeout(() => {
1415
- isShowColumnFilteringItems.value = !isShowColumnFilteringItems.value;
1416
- setColumnFilteringItems(isShowColumnFilteringItems.value);
1417
- }, 150);
1418
- };
1419
-
1420
- const removeAllFiltering = () => {
1421
- filterInfo.filteringColumn = null;
1422
- filterInfo.filteringItemsByColumn = {};
1423
- hiddenFilteringItemsByColumn.value = {};
1424
- stores.filterStore = [];
1425
- setStore({ rows: [], isMakeIndex: false });
1426
- };
1427
-
1428
- const filteringItemsStyle = computed(() => ({
1429
- width: `${filteringItemsWidth.value}px`,
1430
- top: `${filteringItemsRef.value?.getBoundingClientRect().height || 0}px`,
1431
- }));
1432
-
1433
- const getFilteringItemByField = (field) => {
1434
- const filteringFieldInfo = filterInfo.filteringItemsByColumn[field];
1435
- return filteringFieldInfo?.[filteringFieldInfo.length - 1];
1436
- };
1437
-
1438
- const initWrapperDiv = () => {
1439
- const root = document.createElement('div');
1440
- root.id = 'ev-grid-filtering-items-modal';
1441
- root.setAttribute('style', 'position: absolute; top: 0; left: 0;');
1442
- const hasRoot = document.getElementById('ev-grid-filtering-items-modal');
1443
- if (!hasRoot) {
1444
- document.body.appendChild(root);
1445
- }
1446
- };
1447
-
1448
- onBeforeMount(() => initWrapperDiv());
1449
-
1450
- const idColIndex = computed(() => stores.orderedColumns.find(c => c.field === 'id')?.index);
1451
-
1452
- return {
1453
- idColIndex,
1454
- summaryScroll,
1455
- showHeader,
1456
- stripeStyle,
1457
- borderStyle,
1458
- highlightIdx,
1459
- useSummary,
1460
- useGridSetting,
1461
- toolbarRef,
1462
- stores,
1463
- emptyText,
1464
- ...toRefs(elementInfo),
1465
- ...toRefs(stores),
1466
- ...toRefs(filterInfo),
1467
- ...toRefs(scrollInfo),
1468
- ...toRefs(pageInfo),
1469
- ...toRefs(resizeInfo),
1470
- ...toRefs(selectInfo),
1471
- ...toRefs(checkInfo),
1472
- ...toRefs(expandedInfo),
1473
- ...toRefs(sortInfo),
1474
- ...toRefs(contextInfo),
1475
- ...toRefs(columnSettingInfo),
1476
- isRenderer,
1477
- getComponentName,
1478
- getConvertValue,
1479
- getColumnIndex,
1480
- setPixelUnit,
1481
- updateVScroll,
1482
- updateHScroll,
1483
- onScroll,
1484
- calculatedColumn,
1485
- onResize,
1486
- onShow,
1487
- onColumnResize,
1488
- onRowClick,
1489
- onRowDblClick,
1490
- onCheck,
1491
- onCheckAll,
1492
- onExpanded,
1493
- onSort,
1494
- setSort,
1495
- setStore,
1496
- setContextMenu,
1497
- onContextMenu,
1498
- onSearch,
1499
- setGridSetting,
1500
- onApplyColumn,
1501
- onColumnContextMenu,
1502
- // filtering
1503
- filteringItemsWidth,
1504
- isShowColumnFilteringItems,
1505
- operatorItems,
1506
- selectedFilteringItems,
1507
- selectedFilteringColumn,
1508
- filteringItemsRef,
1509
- isShowFilteringItemsBox,
1510
- filteringItemsStyle,
1511
- hiddenFilteringItemsCount,
1512
- ...toRefs(filteringItemsBoxPosition),
1513
- hiddenFilteringItemsRef,
1514
- hiddenFilteringItemsByColumn,
1515
- removeAllFiltering,
1516
- onExpandFilteringItems,
1517
- setColumnFilteringItems,
1518
- onChangeOperator,
1519
- onApplyFilter,
1520
- onClickFilteringItem,
1521
- getFilteringItemByField,
1522
- // drag
1523
- onDragStart,
1524
- onDragOver,
1525
- onDrop,
1526
-
1527
- ROW_DISABLED_INDEX,
1528
- };
1529
- },
1530
- };
1531
- </script>
1532
-
1533
- <style lang="scss" scoped>
1534
- @import 'style/grid.scss';
1535
- </style>