@dataloop-ai/components 0.18.145 → 0.19.1

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 (86) hide show
  1. package/package.json +4 -1
  2. package/src/assets/constants.scss +25 -26
  3. package/src/assets/globals.scss +58 -56
  4. package/src/assets/grid.css +1 -1
  5. package/src/assets/grid.scss +4 -4
  6. package/src/components/basic/DlAccordion/DlAccordion.vue +10 -3
  7. package/src/components/basic/DlEmptyState/types.ts +1 -1
  8. package/src/components/basic/DlGrid/DlGrid.vue +2 -1
  9. package/src/components/basic/DlPopup/DlPopup.vue +159 -396
  10. package/src/components/basic/DlWidget/DlWidget.vue +2 -1
  11. package/src/components/basic/utils.ts +0 -9
  12. package/src/components/blocks/DlLabelPicker/DlLabelPicker.vue +127 -0
  13. package/src/components/blocks/DlLabelPicker/index.ts +3 -0
  14. package/src/components/blocks/DlLabelPicker/types.ts +6 -0
  15. package/src/components/blocks/index.ts +1 -0
  16. package/src/components/blocks/types.ts +1 -0
  17. package/src/components/compound/DlCodeEditor/README.md +5 -4
  18. package/src/components/compound/DlCodeEditor/styles/themes-base16.css +16934 -11289
  19. package/src/components/compound/DlCodeEditor/styles/themes.css +5122 -3448
  20. package/src/components/compound/DlInput/DlInput.vue +609 -178
  21. package/src/components/compound/DlInput/components/InputFileElement.vue +97 -0
  22. package/src/components/compound/DlInput/types.ts +12 -0
  23. package/src/components/compound/DlInput/utils.ts +117 -0
  24. package/src/components/compound/DlSearches/DlSearch/DlSearch.vue +10 -1
  25. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchInput.vue +3 -3
  26. package/src/components/compound/DlSearches/DlSmartSearch/utils/highlightSyntax.ts +1 -1
  27. package/src/components/compound/DlSlider/sliderStyles.scss +92 -92
  28. package/src/components/compound/DlTable/DlTable.vue +701 -358
  29. package/src/components/compound/DlTable/components/DlTd.vue +11 -9
  30. package/src/components/compound/DlTable/components/DlTh.vue +22 -21
  31. package/src/components/compound/DlTable/components/SortableJS.vue +33 -0
  32. package/src/components/compound/DlTable/hooks/tableActions.ts +3 -3
  33. package/src/components/compound/DlTable/hooks/tableColumnSelection.ts +3 -4
  34. package/src/components/compound/DlTable/hooks/use-sortable.ts +152 -0
  35. package/src/components/compound/DlTable/styles/dl-table-styles.scss +372 -377
  36. package/src/components/compound/DlTable/types.ts +6 -0
  37. package/src/components/compound/DlTable/utils/getCellValue.ts +27 -0
  38. package/src/components/compound/DlTable/utils/insertAtIndex.ts +22 -0
  39. package/src/components/compound/DlTable/utils/tableClasses.ts +22 -0
  40. package/src/components/compound/DlToast/api/useToast.ts +10 -4
  41. package/src/components/compound/DlToast/components/ToastComponent.vue +26 -21
  42. package/src/components/compound/DlToast/utils/render.ts +15 -8
  43. package/src/components/compound/DlTreeTable/DlTreeTable.vue +708 -323
  44. package/src/components/compound/DlTreeTable/components/DlTdTree.vue +10 -9
  45. package/src/components/compound/DlTreeTable/components/DlTrTree.vue +13 -0
  46. package/src/components/compound/DlTreeTable/emits.ts +2 -2
  47. package/src/components/compound/DlTreeTable/utils/index.ts +6 -0
  48. package/src/components/compound/DlTreeTable/utils/moveNestedRow.ts +95 -0
  49. package/src/components/compound/DlTreeTable/utils/trSpacing.ts +12 -1
  50. package/src/components/compound/DlTreeTable/utils/treeTableRowSelection.ts +10 -7
  51. package/src/components/compound/DlTreeTable/views/DlTrTreeView.vue +52 -58
  52. package/src/components/essential/DlMenu/DlMenu.vue +25 -0
  53. package/src/components/index.ts +1 -0
  54. package/src/components/shared/DlVirtualScroll/DlVirtualScroll.vue +2 -1
  55. package/src/components/shared/DlVirtualScroll/styles/dl-virtual-scroll-styles.scss +62 -41
  56. package/src/components/types.ts +1 -0
  57. package/src/demos/DlAccordionDemo.vue +32 -0
  58. package/src/demos/DlButtonDemo.vue +7 -0
  59. package/src/demos/DlDemoPage.vue +1 -0
  60. package/src/demos/DlInputDemo.vue +122 -64
  61. package/src/demos/DlLabelPickerDemo.vue +46 -0
  62. package/src/demos/DlPopupDemo.vue +94 -4
  63. package/src/demos/DlSearchDemo.vue +0 -1
  64. package/src/demos/DlTableDemo.vue +261 -162
  65. package/src/demos/DlToastDemo.vue +28 -1
  66. package/src/demos/DlTreeTableDemo.vue +266 -262
  67. package/src/demos/DlVirtualScrollDemo.vue +1 -4
  68. package/src/demos/index.ts +3 -1
  69. package/src/hooks/use-model-toggle.ts +26 -62
  70. package/src/utils/browse-nested-nodes.ts +26 -0
  71. package/src/utils/draggable-table.ts +100 -488
  72. package/src/utils/get-element-above.ts +8 -0
  73. package/src/utils/getSlotByVersion.ts +11 -0
  74. package/src/utils/index.ts +4 -0
  75. package/src/utils/keyCodes.ts +1 -1
  76. package/src/utils/remove-child-nodes.ts +5 -0
  77. package/src/utils/render-fn.ts +46 -0
  78. package/src/utils/resizable-table.ts +110 -0
  79. package/src/utils/selection.ts +196 -0
  80. package/src/utils/swap-nodes.ts +11 -0
  81. package/src/utils/table-columns.ts +209 -0
  82. package/src/components/compound/DlTable/utils/ResizableManager.ts +0 -236
  83. package/src/components/compound/DlTable/utils/index.ts +0 -1
  84. package/src/components/compound/DlTable/utils/props.ts +0 -120
  85. package/src/components/compound/DlTreeTable/props.ts +0 -134
  86. package/src/components/compound/DlTreeTable/utils/flatTreeData.ts +0 -19
@@ -1,286 +1,3 @@
1
- <template>
2
- <DlTable
3
- ref="dlTableRef"
4
- :selected="selectedData"
5
- :separator="separator"
6
- :columns="tableColumns"
7
- :bordered="bordered"
8
- :draggable="draggable"
9
- :dense="dense"
10
- :filter="filter"
11
- :selection="selection"
12
- :loading="loading"
13
- :rows="tableRows"
14
- :flat-tree-data="hasFlatTreeData"
15
- :resizable="resizable"
16
- :row-key="rowKey"
17
- :color="color"
18
- :title="title"
19
- :virtual-scroll="virtualScroll"
20
- :rows-per-page-options="rowsPerPageOptions"
21
- :hide-pagination="hidePagination"
22
- :is-empty="isEmpty"
23
- :empty-state-props="emptyStateProps"
24
- :no-data-label="noDataLabel"
25
- @row-click="emitRowClick"
26
- @th-click="emitThClick"
27
- @update:selected="updateSelected"
28
- >
29
- <template #header-selection>
30
- <DlCheckbox
31
- style="padding-left: 10px"
32
- :color="color"
33
- :model-value="headerSelectedValue"
34
- :indeterminate-value="true"
35
- @update:model-value="onMultipleSelectionSet"
36
- />
37
- </template>
38
- <template #table-body="tableBodyProps">
39
- <slot
40
- name="table-body"
41
- v-bind="tableBodyProps"
42
- >
43
- <template v-if="virtualScroll && !isEmpty">
44
- <slot
45
- v-for="(row, rowIndex) in dlTableRef.computedCols"
46
- name="row-body"
47
- v-bind="
48
- dlTableRef.getBodyScope({
49
- key: getRowKey(row),
50
- row,
51
- pageIndex: rowIndex,
52
- trClass: isRowSelected(rowKey, getRowKey(row))
53
- ? 'selected'
54
- : ''
55
- })
56
- "
57
- >
58
- <DlTrTreeView
59
- :row="tableBodyProps.item"
60
- :row-index="rowIndex"
61
- :is-row-selected="
62
- isRowSelected(
63
- rowKey,
64
- getRowKey(tableBodyProps.item)
65
- )
66
- ? 'selected'
67
- : ''
68
- "
69
- :has-any-action="dlTableRef.hasAnyAction"
70
- :no-hover="dlTableRef.noHover"
71
- :page-index="tableBodyProps.index"
72
- :has-draggable-rows="dlTableRef.hasDraggableRows"
73
- :has-selection-mode="dlTableRef.hasSelectionMode"
74
- :bind-body-selection="
75
- dlTableRef.getBodySelectionScope({
76
- key: getRowKey(tableBodyProps.item),
77
- row: tableBodyProps.item,
78
- pageIndex: tableBodyProps.index
79
- })
80
- "
81
- :bind-body-cell-scope="
82
- (col) =>
83
- dlTableRef.getBodyCellScope({
84
- key: getRowKey(tableBodyProps.item),
85
- row: tableBodyProps.item,
86
- pageIndex: tableBodyProps.index,
87
- col
88
- })
89
- "
90
- :color="color"
91
- :computed-cols="dlTableRef.computedCols"
92
- :slot-name="dlTableRef.slotNames"
93
- :computed-rows="computedRows"
94
- :model-value="
95
- isRowSelected(
96
- rowKey,
97
- getRowKey(tableBodyProps.item)
98
- )
99
- "
100
- @update:model-value="
101
- (adding, evt) =>
102
- updateSelectionHierarchy(
103
- adding,
104
- evt,
105
- tableBodyProps.item
106
- )
107
- "
108
- @rowClick="
109
- dlTableRef.onTrClick(
110
- $event,
111
- tableBodyProps.item,
112
- tableBodyProps.index
113
- )
114
- "
115
- @rowDoubleClick="
116
- dlTableRef.onTrDblClick(
117
- $event,
118
- tableBodyProps.item,
119
- tableBodyProps.index
120
- )
121
- "
122
- @rowContextMenu="
123
- dlTableRef.onTrContextMenu(
124
- $event,
125
- tableBodyProps.item,
126
- tableBodyProps.index
127
- )
128
- "
129
- @updateExpandedRow="
130
- updateExpandedRow(
131
- !tableBodyProps.item.expanded,
132
- getRowKey(tableBodyProps.item)
133
- )
134
- "
135
- >
136
- <template
137
- v-for="templateCol in dlTableRef.computedCols"
138
- #[getSlotByName(templateCol.name)]
139
- >
140
- <slot
141
- :name="getSlotByName(templateCol.name)"
142
- v-bind="
143
- dlTableRef.getBodyCellScope({
144
- key: getRowKey(tableBodyProps.item),
145
- row: tableBodyProps.item,
146
- pageIndex: tableBodyProps.index,
147
- col: templateCol
148
- })
149
- "
150
- />
151
- </template>
152
- </DlTrTreeView>
153
- </slot>
154
- </template>
155
- <template v-else>
156
- <template v-if="dlTableRef && !isEmpty">
157
- <template v-for="(row, rowIndex) in computedRows">
158
- <slot
159
- name="row-body"
160
- v-bind="
161
- dlTableRef.getBodyScope({
162
- key: getRowKey(row),
163
- row,
164
- pageIndex: rowIndex,
165
- trClass: isRowSelected(
166
- rowKey,
167
- getRowKey(row)
168
- )
169
- ? 'selected'
170
- : ''
171
- })
172
- "
173
- >
174
- <DlTrTreeView
175
- :key="rowIndex"
176
- :row="row"
177
- :row-index="rowIndex"
178
- :row-key="rowKey"
179
- :is-row-selected="
180
- isRowSelected(rowKey, getRowKey(row))
181
- ? 'selected'
182
- : ''
183
- "
184
- :has-any-action="dlTableRef.hasAnyAction"
185
- :no-hover="dlTableRef.noHover"
186
- :has-draggable-rows="
187
- dlTableRef.hasDraggableRows
188
- "
189
- :has-selection-mode="
190
- dlTableRef.hasSelectionMode
191
- "
192
- :bind-body-selection="
193
- dlTableRef.getBodySelectionScope({
194
- key: getRowKey(row),
195
- row,
196
- pageIndex: rowIndex
197
- })
198
- "
199
- :bind-body-cell-scope="
200
- (col) =>
201
- dlTableRef.getBodyCellScope({
202
- key: getRowKey(row),
203
- row,
204
- pageIndex: rowIndex,
205
- col
206
- })
207
- "
208
- :color="color"
209
- :computed-cols="dlTableRef.computedCols"
210
- :slot-name="dlTableRef.slotNames"
211
- :computed-rows="computedRows"
212
- :model-value="
213
- isRowSelected(rowKey, getRowKey(row))
214
- "
215
- @update:model-value="
216
- (adding, evt) =>
217
- updateSelectionHierarchy(
218
- adding,
219
- evt,
220
- row
221
- )
222
- "
223
- @rowClick="
224
- dlTableRef.onTrClick(
225
- $event,
226
- row,
227
- rowIndex
228
- )
229
- "
230
- @rowDoubleClick="
231
- dlTableRef.onTrDblClick(
232
- $event,
233
- row,
234
- rowIndex
235
- )
236
- "
237
- @rowContextMenu="
238
- dlTableRef.onTrContextMenu(
239
- $event,
240
- row,
241
- rowIndex
242
- )
243
- "
244
- @updateExpandedRow="
245
- updateExpandedRow(
246
- !row.expanded,
247
- getRowKey(row)
248
- )
249
- "
250
- >
251
- <template
252
- v-for="templateCol in dlTableRef.computedCols"
253
- #[getSlotByName(templateCol.name)]
254
- >
255
- <slot
256
- :name="
257
- getSlotByName(templateCol.name)
258
- "
259
- v-bind="
260
- dlTableRef.getBodySelectionScope(
261
- {
262
- key: getRowKey(row),
263
- row,
264
- col: templateCol,
265
- pageIndex: rowIndex
266
- }
267
- )
268
- "
269
- />
270
- </template>
271
- </DlTrTreeView>
272
- </slot>
273
- </template>
274
- </template>
275
- </template>
276
- </slot>
277
- </template>
278
- <template #no-data>
279
- <slot name="no-data" />
280
- </template>
281
- </DlTable>
282
- </template>
283
-
284
1
  <script lang="ts">
285
2
  import {
286
3
  computed,
@@ -289,26 +6,274 @@ import {
289
6
  isVue2,
290
7
  set,
291
8
  ref,
292
- h
9
+ VNode,
10
+ watch,
11
+ PropType,
12
+ toRefs
293
13
  } from 'vue-demi'
294
14
  import { DlCheckbox } from '../../essential'
15
+ import { DlEmptyState } from '../../basic'
295
16
  import DlTable from '../DlTable/DlTable.vue'
296
17
  import DlTrTreeView from './views/DlTrTreeView.vue'
297
- import { cloneDeep } from 'lodash'
298
- import { DlTableProps, DlTableRow } from '../DlTable/types'
18
+ import { DlTableColumn, DlTableProps, DlTableRow } from '../DlTable/types'
299
19
  import { useTreeTableRowSelection } from './utils/treeTableRowSelection'
300
20
  import { getFromChildren } from './utils/getFromChildren'
301
- import { props } from './props'
302
21
  import { emits } from './emits'
22
+ import Sortable from '../DlTable/components/SortableJS.vue'
23
+ import { renderComponent } from '../../../utils/render-fn'
24
+ import { isEmpty } from 'lodash'
25
+ import SortableJs from 'sortablejs'
26
+ import { v4 } from 'uuid'
27
+ import { moveNestedRow } from './utils/moveNestedRow'
28
+ import { getElementAbove } from '../../../utils'
29
+ import { SortingMovement } from '../DlTable/types'
30
+ import { getContainerClass } from '../DlTable/utils/tableClasses'
31
+ import { DlEmptyStateProps } from '../../types'
32
+ import { useTableActionsProps } from '../DlTable/hooks/tableActions'
33
+ import { commonVirtScrollProps } from '../../shared/DlVirtualScroll/useVirtualScroll'
34
+ import { useTableRowExpandProps } from '../DlTable/hooks/tableRowExpand'
35
+ import { useTablePaginationProps } from '../DlTable/hooks/tablePagination'
36
+ import { useTableFilterProps } from '../DlTable/hooks/tableFilter'
37
+ import { useTableSortProps } from '../DlTable/hooks/tableSort'
38
+ import { useTableColumnSelectionProps } from '../DlTable/hooks/tableColumnSelection'
39
+ import { useTableRowSelectionProps } from '../DlTable/hooks/tableRowSelection'
40
+
41
+ let prevMouseY = 0
303
42
 
304
43
  export default defineComponent({
305
44
  name: 'DlTreeTable',
306
45
  components: {
307
46
  DlTable,
308
47
  DlTrTreeView,
309
- DlCheckbox
48
+ DlCheckbox,
49
+ Sortable,
50
+ DlEmptyState
51
+ },
52
+ props: {
53
+ /**
54
+ * Array of DlTableColumn objects
55
+ */
56
+ columns: { type: Array, default: () => [] as Record<string, any>[] },
57
+ /**
58
+ * Array of DlTableRow objects
59
+ */
60
+ rows: {
61
+ type: Array,
62
+ default: () => [] as Record<string, any>[]
63
+ },
64
+ /**
65
+ * Specify which key will identify each row
66
+ */
67
+ rowKey: {
68
+ type: [String, Function],
69
+ default: 'id'
70
+ },
71
+ /**
72
+ * Surrounded by a border
73
+ */
74
+ bordered: Boolean,
75
+ /**
76
+ * Borders inside the table: horizontal, vertical, cell or none
77
+ */
78
+ separator: {
79
+ type: String,
80
+ default: 'horizontal',
81
+ validator: (v: string) =>
82
+ ['horizontal', 'vertical', 'cell', 'none'].includes(v)
83
+ },
84
+ /**
85
+ * Type of the draggable functionality: rows, columns or both
86
+ */
87
+ draggable: {
88
+ type: String,
89
+ default: 'none',
90
+ validator: (v: string) =>
91
+ ['rows', 'columns', 'none', 'both'].includes(v)
92
+ },
93
+ /**
94
+ * Title to be displayed next to the table
95
+ */
96
+ title: { type: String, default: '' },
97
+ /**
98
+ * Text color
99
+ */
100
+ color: {
101
+ type: String,
102
+ default: 'dl-color-darker'
103
+ },
104
+ /**
105
+ * Show a loading animation on the table
106
+ */
107
+ loading: {
108
+ type: Boolean,
109
+ default: false
110
+ },
111
+ /**
112
+ * Cells shrinks in size
113
+ */
114
+ dense: {
115
+ type: Boolean,
116
+ default: false
117
+ },
118
+ /**
119
+ * Resizable columns
120
+ */
121
+ resizable: {
122
+ type: Boolean,
123
+ default: false
124
+ },
125
+ /**
126
+ * Don't show the "No data" message
127
+ */
128
+ hideNoData: {
129
+ type: Boolean,
130
+ default: false
131
+ },
132
+ /**
133
+ * Don't show the header
134
+ */
135
+ hideHeader: {
136
+ type: Boolean,
137
+ default: false
138
+ },
139
+ /**
140
+ * Don't show the footer
141
+ */
142
+ hideBottom: {
143
+ type: Boolean,
144
+ default: false
145
+ },
146
+ /**
147
+ * Enable virtual scroll
148
+ */
149
+ virtualScroll: {
150
+ type: Boolean,
151
+ default: false
152
+ },
153
+ /**
154
+ * Hide table pagination
155
+ */
156
+ hidePagination: {
157
+ type: Boolean,
158
+ default: false
159
+ },
160
+ /**
161
+ * Hide selected banner
162
+ */
163
+ hideSelectedBanner: {
164
+ type: Boolean,
165
+ default: false
166
+ },
167
+ /**
168
+ * Function to generate the label visible when selecting rows
169
+ */
170
+ selectedRowsLabel: {
171
+ type: Function,
172
+ default: (val: number) => `${val} records selected`
173
+ },
174
+ /**
175
+ * Label visible when loading is active
176
+ */
177
+ loadingLabel: {
178
+ type: String,
179
+ default: 'Loading...'
180
+ },
181
+ /**
182
+ * Label visible when there are no results
183
+ */
184
+ noResultsLabel: {
185
+ type: String,
186
+ default: 'There are no results to display'
187
+ },
188
+ /**
189
+ * Label visible when data is empty
190
+ */
191
+ noDataLabel: {
192
+ type: String,
193
+ default: 'No data available'
194
+ },
195
+ /**
196
+ * Virtual scroll target
197
+ */
198
+ virtualScrollTarget: {
199
+ type: Object as PropType<HTMLElement>,
200
+ default: null as unknown as PropType<HTMLElement>
201
+ },
202
+ /**
203
+ * CSS class for the title
204
+ */
205
+ titleClass: {
206
+ type: [String, Array, Object],
207
+ default: null as unknown as PropType<any[]>
208
+ },
209
+ /**
210
+ * Styles to be applied to the table container
211
+ */
212
+ tableStyle: {
213
+ type: [String, Array, Object],
214
+ default: null as unknown as PropType<any[]>
215
+ },
216
+ /**
217
+ * Will add another column with a button opening a menu which lets the user choose the visible columns
218
+ */
219
+ visibleColumns: {
220
+ type: Array as PropType<DlTableColumn[]>,
221
+ default: (): [] => []
222
+ },
223
+ /**
224
+ * CSS class for the table container
225
+ */
226
+ tableClass: {
227
+ type: [String, Array, Object],
228
+ default: null as unknown as PropType<any[]>
229
+ },
230
+ /**
231
+ * Styles to be applies to the table header
232
+ */
233
+ tableHeaderStyle: {
234
+ type: [String, Array, Object],
235
+ default: null as unknown as PropType<any[]>
236
+ },
237
+ /**
238
+ * CSS class for the table header
239
+ */
240
+ tableHeaderClass: {
241
+ type: [String, Array, Object],
242
+ default: null as unknown as PropType<any[]>
243
+ },
244
+ noHover: Boolean,
245
+ /**
246
+ * Indicates the data is empty
247
+ */
248
+ isEmpty: Boolean,
249
+ /**
250
+ * Props for the empty state component
251
+ */
252
+ emptyStateProps: {
253
+ type: Object as PropType<DlEmptyStateProps>,
254
+ default: () =>
255
+ ({
256
+ title: '',
257
+ subtitle: 'No data to show yet',
258
+ icon: 'icon-dl-dataset-filled'
259
+ } as unknown as PropType<DlEmptyStateProps>)
260
+ },
261
+ /**
262
+ * Scrolling delay
263
+ */
264
+ scrollDebounce: {
265
+ type: Number,
266
+ default: 100
267
+ },
268
+ ...useTableActionsProps,
269
+ ...commonVirtScrollProps,
270
+ ...useTableRowExpandProps,
271
+ ...useTablePaginationProps,
272
+ ...useTableFilterProps,
273
+ ...useTableSortProps,
274
+ ...useTableColumnSelectionProps,
275
+ ...useTableRowSelectionProps
310
276
  },
311
- props,
312
277
  emits,
313
278
  setup(props, { emit, slots }) {
314
279
  const dlTableRef = ref(null)
@@ -316,19 +281,38 @@ export default defineComponent({
316
281
  const borderState = ref([])
317
282
  const denseState = ref([])
318
283
  const resizableState = ref([])
319
- const tableRows = ref(cloneDeep(props.rows))
320
- const tableColumns = ref(props.columns)
321
284
  const hasFlatTreeData = true
322
285
 
286
+ const vue2h = ref()
287
+
288
+ const sortingMovement = ref<SortingMovement>({
289
+ lastId: null,
290
+ direction: 'up'
291
+ })
292
+
293
+ const uuid = `dl-tree-table-${v4()}`
294
+
295
+ const mainTbodyUuid = `dl-tree-table-tbody-${v4()}`
296
+
297
+ const mainTableKey = ref()
298
+
299
+ const { rows: tableRows, columns: tableColumns } = toRefs(props)
300
+
301
+ const isDataEmpty = computed(() => !props.rows.length)
302
+
323
303
  const hasEmptyStateProps = computed(() =>
324
304
  props.emptyStateProps
325
305
  ? Object.keys(props.emptyStateProps).length > 0
326
306
  : false
327
307
  )
328
308
 
329
- const computedRows = computed(() =>
330
- dlTableRef.value?.computedRows ? dlTableRef.value?.computedRows : []
331
- )
309
+ const computedRows = computed(() => {
310
+ return dlTableRef.value?.computedRows || []
311
+ })
312
+
313
+ const tableRootRef = computed(() => {
314
+ return dlTableRef.value || {}
315
+ })
332
316
 
333
317
  const getRowKey = computed(() =>
334
318
  typeof props.rowKey === 'function'
@@ -336,6 +320,10 @@ export default defineComponent({
336
320
  : (row: Record<string, any>) => row[props.rowKey as string]
337
321
  )
338
322
 
323
+ const hasDraggableRows = computed(() =>
324
+ ['rows', 'both'].includes(props.draggable)
325
+ )
326
+
339
327
  const {
340
328
  hasSelectionMode,
341
329
  singleSelection,
@@ -350,23 +338,22 @@ export default defineComponent({
350
338
  } = useTreeTableRowSelection(
351
339
  props as unknown as DlTableProps,
352
340
  emit,
353
- computedRows,
341
+ tableRows as ComputedRef<DlTableRow[]>,
354
342
  getRowKey as ComputedRef<(val: string | DlTableRow) => any>
355
343
  )
356
344
 
357
345
  const updateExpandedRow = (
358
346
  isExpanded: boolean,
359
347
  name: string,
360
- rowsArr = tableRows.value
348
+ rowsArr: DlTableRow[] = tableRows.value
361
349
  ) => {
362
- (rowsArr as DlTableRow[]).some((o) => {
350
+ rowsArr.some((o) => {
363
351
  if (getRowKey.value(o) === name) {
364
352
  if (isVue2) {
365
- set(o, 'expanded', isExpanded)
353
+ set(o, 'isExpanded', isExpanded)
366
354
  } else {
367
- o.expanded = isExpanded
355
+ o.isExpanded = isExpanded
368
356
  }
369
- // o.expanded = isExpanded
370
357
  updateNestedRows(o, isExpanded)
371
358
  } else {
372
359
  if ((o.children || []).length > 0) {
@@ -375,7 +362,6 @@ export default defineComponent({
375
362
  }
376
363
  })
377
364
  }
378
-
379
365
  const updateNestedRows = (
380
366
  row: (typeof computedRows.value)[number],
381
367
  isExpanded: boolean
@@ -383,22 +369,19 @@ export default defineComponent({
383
369
  if ((row.children || []).length > 0) {
384
370
  row.children.forEach(
385
371
  (r: (typeof computedRows.value)[number]) => {
386
- // r.isExpandedParent = isExpanded
387
-
388
372
  if (isVue2) {
389
- set(r, 'isExpandedParent', isExpanded)
373
+ set(r, 'isExpanded', isExpanded)
390
374
  } else {
391
- r.isExpandedParent = isExpanded
375
+ r.isExpanded = isExpanded
392
376
  }
393
377
 
394
378
  if (!isExpanded) {
395
379
  if (isVue2) {
396
- set(r, 'expanded', isExpanded)
380
+ set(r, 'isExpanded', isExpanded)
397
381
  } else {
398
- r.expanded = isExpanded
382
+ r.isExpanded = isExpanded
399
383
  }
400
384
 
401
- // r.expanded = isExpanded
402
385
  updateNestedRows(r, isExpanded)
403
386
  }
404
387
  }
@@ -417,31 +400,37 @@ export default defineComponent({
417
400
 
418
401
  updateSelection(childrenKeys, childrenCollection, adding, event)
419
402
  }
403
+ const headerSelectedValue = computed(() => {
404
+ if (selectedData.value.length === tableRows.value.length)
405
+ return true
420
406
 
421
- const headerSelectedValue = computed(() =>
422
- someRowsSelected.value === true ? null : allRowsSelected.value
423
- )
407
+ if (
408
+ selectedData.value.length > 0 &&
409
+ selectedData.value.length !== tableRows.value.length
410
+ )
411
+ return null
412
+
413
+ return false
414
+ })
424
415
 
425
416
  const onMultipleSelectionSet = (val: boolean) => {
426
- if (someRowsSelected.value === true) {
427
- val = false
428
- }
417
+ const value =
418
+ selectedData.value.length > 0 &&
419
+ selectedData.value.length === tableRows.value.length
420
+ ? false
421
+ : val
429
422
 
430
- updateSelection(
431
- computedRows.value.map(getRowKey.value as any),
432
- computedRows.value,
433
- val
434
- )
423
+ updateSelected(value ? tableRows.value : [])
435
424
  }
436
425
  const updateSelected = (payload: any) => {
437
426
  selectedData.value = payload
438
427
  emitSelectedItems(payload)
439
428
  }
440
429
  const emitSelectedItems = (payload: any) => {
441
- emit('selectedItems', payload)
430
+ emit('selected-items', payload)
442
431
  }
443
- const emitRowClick = (payload: any) => {
444
- emit('row-click', payload)
432
+ const emitRowClick = (...payload: any) => {
433
+ emit('row-click', ...payload)
445
434
  }
446
435
  const emitThClick = (payload: any) => {
447
436
  emit('th-click', payload)
@@ -455,7 +444,310 @@ export default defineComponent({
455
444
  }
456
445
  }
457
446
 
447
+ const tbodySlotsData = computed(() =>
448
+ (dlTableRef.value?.computedCols || []).filter(
449
+ (item: DlTableColumn) => hasSlotByName(`body-cell-${item.name}`)
450
+ )
451
+ )
452
+
453
+ const containerClass = computed(() => {
454
+ const { separator, bordered, dense, loading } = props
455
+ return getContainerClass(separator, bordered, dense, loading)
456
+ })
457
+
458
+ const computedCellSlots = computed(() => {
459
+ const obj: any = {}
460
+ tbodySlotsData.value.forEach((item: DlTableColumn) => {
461
+ const slot = slots[`body-cell-${item.name}`]
462
+ obj[`body-cell-${item.name}`] = slot
463
+ })
464
+ return obj
465
+ })
466
+
467
+ const renderDlTrTree = (
468
+ row: DlTableRow,
469
+ index: number,
470
+ children: DlTableRow[] = [],
471
+ level: number = 1
472
+ ) => {
473
+ const currentSlots = {
474
+ default: () => children,
475
+ ...computedCellSlots.value
476
+ }
477
+ return renderComponent(vue2h.value, DlTrTreeView, {
478
+ row,
479
+ rowIndex: index,
480
+ rowKey: props.rowKey,
481
+ isRowSelected: isRowSelected(props.rowKey, getRowKey.value(row))
482
+ ? 'selected'
483
+ : '',
484
+ level,
485
+ class: 'nested-element dl-tr',
486
+ 'data-level': level,
487
+ 'data-id': row.id,
488
+ hasAnyAction: tableRootRef.value.hasAnyAction,
489
+ noHover: tableRootRef.value.noHover,
490
+ hasDraggableRows: hasDraggableRows.value,
491
+ hasSelectionMode: tableRootRef.value.hasSelectionMode,
492
+ bindBodySelection: tableRootRef.value.getBodySelectionScope({
493
+ key: getRowKey.value(row),
494
+ row,
495
+ pageIndex: index
496
+ }),
497
+ bindBodyCellScope: (col: DlTableColumn) =>
498
+ tableRootRef.value.getBodyCellScope({
499
+ key: getRowKey.value(row),
500
+ row,
501
+ pageIndex: index,
502
+ col
503
+ }),
504
+
505
+ key: getRowKey.value(row),
506
+ color: props.color,
507
+ computedCols: tableRootRef.value.computedCols,
508
+ modelValue: isRowSelected(props.rowKey, getRowKey.value(row)),
509
+ scopedSlots: currentSlots,
510
+ 'onUpdate:modelValue': (adding: boolean, evt: Event) => {
511
+ updateSelectionHierarchy(adding, evt, row)
512
+ },
513
+ onRowClick: () => {
514
+ tableRootRef.value.onTrClick(event, row, index)
515
+ },
516
+ onRowDoubleClick: () => {
517
+ tableRootRef.value.onTrDblClick(event, row, index)
518
+ },
519
+ onRowContextMenu: () => {
520
+ tableRootRef.value.onTrContextMenu(event, row, index)
521
+ },
522
+ onUpdateExpandedRow: () =>
523
+ updateExpandedRow(!row.isExpanded, getRowKey.value(row)),
524
+ on: {
525
+ 'update:modelValue': (adding: boolean, evt: Event) => {
526
+ updateSelectionHierarchy(adding, evt, row)
527
+ },
528
+ rowClick: () => {
529
+ tableRootRef.value.onTrClick(event, row, index)
530
+ },
531
+ rowDoubleClick: () => {
532
+ tableRootRef.value.onTrDblClick(event, row, index)
533
+ },
534
+ rowContextMenu: () => {
535
+ tableRootRef.value.onTrContextMenu(event, row, index)
536
+ },
537
+ updateExpandedRow: () =>
538
+ updateExpandedRow(!row.isExpanded, getRowKey.value(row))
539
+ }
540
+ })
541
+ }
542
+
543
+ const renderTr = (
544
+ row: DlTableRow,
545
+ index: number,
546
+ level: number = 1
547
+ ) => {
548
+ const children = []
549
+
550
+ children.push(renderDlTrTree(row, index, [], level))
551
+
552
+ const tbodyEls: VNode[] = []
553
+
554
+ if ((row.children || []).length > 0) {
555
+ //TODO CHECK INDEX var
556
+ level++
557
+
558
+ row.children.forEach((childRow: DlTableRow, i: number) => {
559
+ tbodyEls.push(
560
+ renderComponent(
561
+ vue2h.value,
562
+ 'tbody',
563
+ {
564
+ key: getRowKey.value(childRow),
565
+ 'data-level': level,
566
+ class: 'nested-tbody'
567
+ },
568
+ renderTr(childRow, i, level)
569
+ ) as VNode
570
+ )
571
+ })
572
+
573
+ const tdEl = renderComponent(
574
+ vue2h.value,
575
+ 'td',
576
+ {
577
+ colspan: tableRootRef.value.computedColspan,
578
+ style: 'padding: 0'
579
+ },
580
+ renderComponent(
581
+ vue2h.value,
582
+ Sortable,
583
+ {
584
+ list: [],
585
+ itemKey: getRowKey.value,
586
+ tag: 'table',
587
+ class: 'nested-table',
588
+ isSortable: hasDraggableRows.value,
589
+ onEnd: handleEndEvent,
590
+ onChange: handleChangeEvent,
591
+ onStart: handleStartEvent,
592
+ on: {
593
+ end: handleEndEvent,
594
+ change: handleChangeEvent,
595
+ start: handleStartEvent
596
+ },
597
+ options: {
598
+ group: 'nested',
599
+ animation: 150,
600
+ fallbackOnBody: true,
601
+ invertSwap: true,
602
+ swapThreshold: 0.5
603
+ }
604
+ },
605
+ isVue2 ? tbodyEls : () => tbodyEls
606
+ )
607
+ )
608
+
609
+ const childrenTrWrapper = renderComponent(
610
+ vue2h.value,
611
+ 'tr',
612
+ {
613
+ class:
614
+ (row.isExpanded ? '' : 'display-none') +
615
+ ' dl-tr--no-hover' +
616
+ ' nested-element'
617
+ },
618
+ tdEl
619
+ )
620
+
621
+ children.push(childrenTrWrapper)
622
+ }
623
+
624
+ return children
625
+ }
626
+
627
+ const handleEndEvent = (event: SortableJs.SortableEvent) => {
628
+ emit(
629
+ 'row-reorder',
630
+ moveNestedRow(tableRows.value, event, sortingMovement.value)
631
+ )
632
+ mainTableKey.value = v4()
633
+ }
634
+
635
+ const handleChangeEvent = (event: any) => {
636
+ const originalEvent = event.originalEvent
637
+ const passedElement = getElementAbove(
638
+ originalEvent.srcElement,
639
+ 'dl-tr'
640
+ ) as HTMLElement
641
+ const currentY = originalEvent.clientY
642
+ if (currentY > prevMouseY) {
643
+ sortingMovement.value.direction = 'down'
644
+ } else if (currentY < prevMouseY) {
645
+ sortingMovement.value.direction = 'up'
646
+ }
647
+ prevMouseY = currentY
648
+ sortingMovement.value.lastId = passedElement.dataset.id
649
+ }
650
+
651
+ const handleStartEvent = (event: any) =>
652
+ (prevMouseY = event.originalEvent.clientY)
653
+
654
+ const updateColumns = (newColumns: DlTableColumn[]) => {
655
+ emit('col-update', newColumns)
656
+ }
657
+
658
+ const renderEmptyState = () =>
659
+ renderComponent(
660
+ vue2h.value,
661
+ 'td',
662
+ { colspan: '100%' },
663
+ renderComponent(
664
+ vue2h.value,
665
+ 'div',
666
+ {
667
+ class: 'flex justify-center full-width'
668
+ },
669
+ renderComponent(
670
+ vue2h.value,
671
+ DlEmptyState,
672
+ props.emptyStateProps,
673
+ (): [] => []
674
+ )
675
+ )
676
+ )
677
+
678
+ const renderTBody = () => {
679
+ if (isEmpty(tableRootRef.value)) return null
680
+ const children = tableRows.value.map((row, i) => {
681
+ const rowBodySlot = slots['row-body']
682
+ const [renderRow] = rowBodySlot
683
+ ? rowBodySlot({ row })
684
+ : [renderTr(row, i)]
685
+ return renderComponent(
686
+ vue2h.value,
687
+ 'tbody',
688
+ {
689
+ 'data-level': 1,
690
+ key: getRowKey.value(row) + i,
691
+ class: 'nested-tbody'
692
+ },
693
+ isVue2 ? [renderRow] : renderRow
694
+ )
695
+ })
696
+
697
+ const tableBody = renderComponent(
698
+ vue2h.value,
699
+ 'tbody',
700
+ {},
701
+ renderComponent(
702
+ vue2h.value,
703
+ 'tr',
704
+ {
705
+ class: 'dl-tr--no-hover'
706
+ },
707
+ renderComponent(
708
+ vue2h.value,
709
+ 'td',
710
+ { colspan: tableRootRef.value.computedColspan },
711
+ renderComponent(
712
+ vue2h.value,
713
+ Sortable,
714
+ {
715
+ list: [],
716
+ itemKey: getRowKey.value,
717
+ tag: 'table',
718
+ id: mainTbodyUuid,
719
+ key: mainTableKey.value,
720
+ isSortable: hasDraggableRows.value,
721
+ onEnd: handleEndEvent,
722
+ onChange: handleChangeEvent,
723
+ onStart: handleStartEvent,
724
+ on: {
725
+ end: handleEndEvent,
726
+ change: handleChangeEvent,
727
+ start: handleStartEvent
728
+ },
729
+ class: 'nested-table',
730
+ options: {
731
+ group: 'nested',
732
+ animation: 150,
733
+ fallbackOnBody: true,
734
+ invertSwap: true,
735
+ swapThreshold: 0.5
736
+ }
737
+ },
738
+ isVue2 ? children : () => children
739
+ )
740
+ )
741
+ )
742
+ )
743
+
744
+ return tableBody
745
+ }
746
+
458
747
  return {
748
+ renderEmptyState,
749
+ isDataEmpty,
750
+ updateColumns,
459
751
  dlTableRef,
460
752
  isRowSelected,
461
753
  hasFlatTreeData,
@@ -478,8 +770,78 @@ export default defineComponent({
478
770
  emitRowClick,
479
771
  emitThClick,
480
772
  hasSlotByName,
481
- getSlotByName
773
+ getSlotByName,
774
+ renderTBody,
775
+ tableRootRef,
776
+ uuid,
777
+ mainTbodyUuid,
778
+ vue2h,
779
+ containerClass
482
780
  }
781
+ },
782
+ // adding ignore here as overloading the render function like this is not a known type
783
+ // @ts-ignore
784
+ render(vue2h: any) {
785
+ this.vue2h = vue2h
786
+ const tableBodySlot = isVue2
787
+ ? this.$slots['table-body'] &&
788
+ (() => (this.$slots['table-body'] as any)?.pop())
789
+ : this.$slots['table-body']
790
+ const tbody =
791
+ tableBodySlot ?? (this.isDataEmpty ? null : this.renderTBody)
792
+ return renderComponent(vue2h, DlTable, {
793
+ ref: 'dlTableRef',
794
+ draggable: this.draggable,
795
+ id: this.uuid,
796
+ selected: this.selectedData,
797
+ separator: this.separator,
798
+ columns: this.tableColumns,
799
+ bordered: this.bordered,
800
+ dense: this.dense,
801
+ filter: this.filter,
802
+ isTreeTable: true,
803
+ selection: this.selection,
804
+ loading: this.loading,
805
+ rows: this.tableRows,
806
+ resizable: this.resizable,
807
+ rowKey: this.rowKey,
808
+ color: this.color,
809
+ title: this.title,
810
+ virtualScroll: this.virtualScroll,
811
+ rowsPerPageOptions: this.rowsPerPageOptions,
812
+ hidePagination: this.hidePagination,
813
+ isEmpty: this.isDataEmpty,
814
+ emptyStateProps: this.emptyStateProps,
815
+ noDataLabel: this.noDataLabel,
816
+ visibleColumns: this.visibleColumns,
817
+ onRowClick: this.emitRowClick,
818
+ 'onUpdate:selected': this.updateSelected,
819
+ onColUpdate: this.updateColumns,
820
+ class: this.containerClass,
821
+ on: {
822
+ rowClick: this.emitRowClick,
823
+ 'update:selected': this.updateSelected,
824
+ 'col-update': this.updateColumns
825
+ },
826
+ scopedSlots: {
827
+ 'header-selection': () =>
828
+ renderComponent(
829
+ vue2h,
830
+ DlCheckbox,
831
+ {
832
+ color: this.color,
833
+ modelValue: this.headerSelectedValue,
834
+ indeterminateValue: true,
835
+ 'onUpdate:modelValue': this.onMultipleSelectionSet,
836
+ on: {
837
+ 'update:modelValue': this.onMultipleSelectionSet
838
+ }
839
+ },
840
+ (): [] => []
841
+ ),
842
+ tbody
843
+ }
844
+ })
483
845
  }
484
846
  })
485
847
  </script>
@@ -497,6 +859,29 @@ export default defineComponent({
497
859
  }
498
860
  }
499
861
 
862
+ table {
863
+ width: 100%;
864
+ table-layout: fixed;
865
+ border-collapse: collapse;
866
+ border-spacing: 0;
867
+ }
868
+
869
+ tbody {
870
+ // display: table-row-group;
871
+ vertical-align: middle;
872
+ border-color: inherit;
873
+ }
874
+
875
+ td {
876
+ padding: 0 !important;
877
+ }
878
+
879
+ tr {
880
+ display: table-row;
881
+ vertical-align: inherit;
882
+ border-color: inherit;
883
+ }
884
+
500
885
  .sticky-header {
501
886
  ::v-deep .dl-table__top,
502
887
  ::v-deep .dl-table__bottom,