webcake-ui-kit 1.2.0 → 1.2.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 (67) hide show
  1. package/package.json +8 -2
  2. package/src/components/checkbox/Checkbox.vue +1 -1
  3. package/src/components/drawer/Drawer.vue +261 -0
  4. package/src/components/drawer/drawer.css +162 -0
  5. package/src/components/dropdown/Dropdown.vue +15 -9
  6. package/src/components/hover-card/HoverCard.vue +159 -0
  7. package/src/components/hover-card/hover-card.css +10 -0
  8. package/src/components/input-counter/InputCounter.vue +250 -0
  9. package/src/components/input-counter/input-counter.css +209 -0
  10. package/src/components/menu/Menu.vue +4 -2
  11. package/src/components/popover/Popover.vue +144 -0
  12. package/src/components/popover/popover.css +3 -0
  13. package/src/components/table-v2/ColumnDragHandle.vue +103 -0
  14. package/src/components/table-v2/Table.vue +299 -0
  15. package/src/components/table-v2/TableColGroup.vue +55 -0
  16. package/src/components/table-v2/TableEmpty.vue +10 -0
  17. package/src/components/table-v2/TableLoading.vue +25 -0
  18. package/src/components/table-v2/TableResizeObserver.vue +93 -0
  19. package/src/components/table-v2/TableWrapper.vue +193 -0
  20. package/src/components/table-v2/body/DragPreview.vue +65 -0
  21. package/src/components/table-v2/body/MeasureCell.vue +42 -0
  22. package/src/components/table-v2/body/TableBody.vue +126 -0
  23. package/src/components/table-v2/body/TableCell.vue +108 -0
  24. package/src/components/table-v2/body/TableRow.vue +73 -0
  25. package/src/components/table-v2/composables/useColumns.js +19 -0
  26. package/src/components/table-v2/composables/useSorter.js +12 -0
  27. package/src/components/table-v2/composables/useSticky.js +31 -0
  28. package/src/components/table-v2/constants.js +2 -0
  29. package/src/components/table-v2/context/createTableContext.js +79 -0
  30. package/src/components/table-v2/header/TableHeader.vue +15 -0
  31. package/src/components/table-v2/header/TableHeaderCell.vue +89 -0
  32. package/src/components/table-v2/header/TableHeaderRow.vue +107 -0
  33. package/src/components/table-v2/style/table-body.css +0 -0
  34. package/src/components/table-v2/style/table-header.css +0 -0
  35. package/src/components/table-v2/style/table-loading.css +19 -0
  36. package/src/components/table-v2/style/table-wrapper.css +287 -0
  37. package/src/components/table-v2/style/table.css +5 -0
  38. package/src/icons/BoxShadow.vue +35 -0
  39. package/src/icons/Carousel.vue +34 -0
  40. package/src/icons/CloudSync2.vue +42 -0
  41. package/src/icons/CornerBottomLeft.vue +26 -0
  42. package/src/icons/CornerBottomRight.vue +26 -0
  43. package/src/icons/CornerTopLeft.vue +26 -0
  44. package/src/icons/CornerTopRight.vue +26 -0
  45. package/src/icons/DistanceRight.vue +30 -0
  46. package/src/icons/DistanceTop.vue +30 -0
  47. package/src/icons/DropShadow.vue +35 -0
  48. package/src/icons/Fire.vue +26 -0
  49. package/src/icons/GlobeAccess.vue +32 -0
  50. package/src/icons/InnerShadow.vue +33 -0
  51. package/src/icons/Livestream.vue +54 -0
  52. package/src/icons/PaddingBottom.vue +30 -0
  53. package/src/icons/PaddingLeft.vue +30 -0
  54. package/src/icons/PaddingRight.vue +30 -0
  55. package/src/icons/PaddingTop.vue +30 -0
  56. package/src/icons/SkewHeight.vue +32 -0
  57. package/src/icons/SkewWidth.vue +32 -0
  58. package/src/icons/SquareDashedBottomSolid.vue +26 -0
  59. package/src/icons/SquareDashedLeftSolid.vue +26 -0
  60. package/src/icons/SquareDashedRightSolid.vue +26 -0
  61. package/src/icons/StrokeLine.vue +23 -0
  62. package/src/icons/Topline.vue +26 -0
  63. package/src/icons/index.js +25 -0
  64. package/src/index.js +5 -0
  65. package/src/styles/.omc/state/agent-replay-645326b7-372b-463d-ab45-0adaafe31a51.jsonl +2 -0
  66. package/src/styles/.omc/state/subagent-tracking.json +7 -0
  67. package/src/utils/common.js +34 -0
@@ -0,0 +1,193 @@
1
+ <template>
2
+ <div
3
+ class="ui-table-v2__wrapper"
4
+ :class="{
5
+ 'ui-table-v2__wrapper--ping-left': isPingedLeft,
6
+ 'ui-table-v2__wrapper--ping-right': isPingedRight
7
+ }"
8
+ >
9
+ <DragPreview v-if="hasDraggable" ref="dragPreview">
10
+ <template #bodyCell="slotData">
11
+ <slot name="bodyCell" v-bind="slotData"></slot>
12
+ </template>
13
+ </DragPreview>
14
+
15
+ <!-- Case 3: scroll.y — header và body là 2 table riêng để sticky header -->
16
+ <template v-if="hasScrollY && !isEmpty">
17
+ <div ref="headerRef" class="ui-table-v2__header-hold" style="overflow: hidden">
18
+ <table :class="tableClass" :style="fixedTableStyle">
19
+ <TableColGroup :is-header="true" />
20
+ <TableHeader />
21
+ </table>
22
+ </div>
23
+ <div ref="bodyRef" class="ui-table-v2__body-hold" :style="bodyHoldStyle" @scroll="handleBodyScroll">
24
+ <table :class="tableClass" :style="fixedTableStyle">
25
+ <TableColGroup />
26
+ <TableBody :measureColumnWidth="hasScrollY || hasScrollX || hasSticky">
27
+ <template #bodyCell="slotData">
28
+ <slot name="bodyCell" v-bind="slotData"></slot>
29
+ </template>
30
+ </TableBody>
31
+ </table>
32
+ </div>
33
+ </template>
34
+
35
+ <!-- Case 1 & 2: một table duy nhất -->
36
+ <div v-else class="ui-table-v2__content" ref="bodyRef" :style="contentStyle" @scroll="handleBodyScroll">
37
+ <table :class="tableClass" :style="tableStyle">
38
+ <TableColGroup />
39
+ <TableHeader />
40
+ <TableBody :measureColumnWidth="hasScrollY || hasScrollX || hasSticky" :is-empty="isEmpty">
41
+ <template #bodyCell="slotData">
42
+ <slot name="bodyCell" v-bind="slotData"></slot>
43
+ </template>
44
+ </TableBody>
45
+ </table>
46
+ </div>
47
+ </div>
48
+ </template>
49
+
50
+ <script>
51
+ import TableColGroup from './TableColGroup.vue'
52
+ import TableHeader from './header/TableHeader.vue'
53
+ import TableBody from './body/TableBody.vue'
54
+ import DragPreview from './body/DragPreview.vue'
55
+ import { toCssSize, getTargetScrollBarSize } from '../../utils/common'
56
+
57
+ export default {
58
+ name: 'TableV2Wrapper',
59
+
60
+ data: () => {
61
+ return {
62
+ toCssSize,
63
+ getTargetScrollBarSize,
64
+ isPingedLeft: false,
65
+ isPingedRight: false
66
+ }
67
+ },
68
+
69
+ components: { TableColGroup, TableHeader, TableBody, DragPreview },
70
+
71
+ inject: ['tableContext'],
72
+
73
+ computed: {
74
+ scroll: function () {
75
+ return this.tableContext.layout.scroll
76
+ },
77
+
78
+ isEmpty() {
79
+ return this.tableContext.data.display.length === 0
80
+ },
81
+
82
+ hasScrollY: function () {
83
+ // has fix header
84
+ return !!(this.scroll && this.scroll.y)
85
+ },
86
+
87
+ hasScrollX: function () {
88
+ // has horizontal scroll
89
+ return !!(this.scroll && this.scroll.x)
90
+ },
91
+
92
+ hasSticky: function () {
93
+ // has sticky column
94
+ const leftOffsets = this.tableContext.sticky.leftOffsets
95
+ const rightOffsets = this.tableContext.sticky.rightOffsets
96
+ return Object.keys(leftOffsets).length > 0 || Object.keys(rightOffsets).length > 0
97
+ },
98
+
99
+ hasDraggable() {
100
+ return !!(this.tableContext.draggable && this.tableContext.draggable.enabled)
101
+ },
102
+
103
+ tableClass: function () {
104
+ return {
105
+ 'ui-table-v2__table': true,
106
+ 'ui-table-v2__table--bordered': this.tableContext.layout.bordered
107
+ }
108
+ },
109
+
110
+ // Case 1 & 2 — wrapper có overflow-x khi scroll.x
111
+ contentStyle: function () {
112
+ return this.hasScrollX ? { overflow: 'auto hidden' } : {}
113
+ },
114
+
115
+ // Case 1 & 2 — table style
116
+ tableStyle: function () {
117
+ if (this.hasScrollX && !this.isEmpty) {
118
+ return {
119
+ tableLayout: 'fixed',
120
+ width: this.toCssSize(this.scroll.x),
121
+ minWidth: '100%'
122
+ }
123
+ }
124
+ return { tableLayout: 'auto' }
125
+ },
126
+
127
+ // Case 3 — cả header table và body table dùng chung style này
128
+ fixedTableStyle: function () {
129
+ return {
130
+ tableLayout: 'fixed',
131
+ width: this.scroll && this.scroll.x ? this.toCssSize(this.scroll.x) : undefined,
132
+ minWidth: '100%'
133
+ }
134
+ },
135
+
136
+ // Case 3 — body scroll container
137
+ bodyHoldStyle: function () {
138
+ var style = {
139
+ overflowY: 'auto',
140
+ maxHeight: this.toCssSize(this.scroll.y)
141
+ }
142
+ if (this.hasScrollX) {
143
+ style.overflowX = 'auto'
144
+ }
145
+ return style
146
+ }
147
+ },
148
+ methods: {
149
+ handleBodyScroll(e) {
150
+ const { scrollLeft, scrollWidth, clientWidth } = e.currentTarget
151
+ if (this.$refs.headerRef) {
152
+ this.$refs.headerRef.scrollLeft = scrollLeft
153
+ }
154
+
155
+ this.isPingedLeft = scrollLeft > 0
156
+ this.isPingedRight = scrollLeft < scrollWidth - clientWidth
157
+ },
158
+ updateScrollState() {
159
+ console.log('update')
160
+ if (this.$refs.bodyRef) {
161
+ const { width } = getTargetScrollBarSize(this.$refs.bodyRef)
162
+ this.tableContext.layout.scrollBarWidth = width == 'auto' ? '0px' : width
163
+
164
+ const { scrollWidth, clientWidth, scrollLeft } = this.$refs.bodyRef
165
+ this.isPingedLeft = scrollLeft > 0
166
+ this.isPingedRight = scrollLeft < scrollWidth - clientWidth
167
+ }
168
+ }
169
+ },
170
+
171
+ watch: {
172
+ 'tableContext.data.display.length': function () {
173
+ this.$nextTick(() => {
174
+ this.updateScrollState()
175
+ })
176
+ },
177
+ hasScrollY(val) {
178
+ console.log('hasScrollY', val)
179
+ }
180
+ },
181
+
182
+ mounted: function () {
183
+ const self = this
184
+ this.tableContext.draggable.getPreviewEl = function () {
185
+ return self.$refs.dragPreview && self.$refs.dragPreview.$el
186
+ }
187
+
188
+ this.updateScrollState()
189
+ }
190
+ }
191
+ </script>
192
+
193
+ <style src="./style/table-wrapper.css" scoped></style>
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <table
3
+ class="ui-table-v2__drag-preview"
4
+ aria-hidden="true"
5
+ :style="{ width: containerWidth ? containerWidth + 'px' : '100%' }"
6
+ >
7
+ <tbody class="ui-table-v2__body">
8
+ <tr class="ui-table-v2__row">
9
+ <td v-for="col in columns" :key="col.key">
10
+ <div v-if="col.type === DRAGGABLE_COLUMN" class="wrapper-option">
11
+ <span class="drag-handle">
12
+ <WkiGripVertical :size="16" />
13
+ </span>
14
+ </div>
15
+ <div v-else-if="col.type === SELECTION_COLUMN" class="wrapper-option" />
16
+ <slot v-else name="bodyCell" :column="col" :text="record && record[col.dataIndex]" :record="record">
17
+ <span>{{ record && record[col.dataIndex] }}</span>
18
+ </slot>
19
+ </td>
20
+ </tr>
21
+ </tbody>
22
+ </table>
23
+ </template>
24
+
25
+ <script>
26
+ import { WkiGripVertical } from '../../../icons'
27
+ import { SELECTION_COLUMN, DRAGGABLE_COLUMN } from '../constants.js'
28
+
29
+ export default {
30
+ name: 'TableV2DragPreview',
31
+ components: { WkiGripVertical },
32
+ inject: ['tableContext'],
33
+ data: function () {
34
+ return {
35
+ SELECTION_COLUMN: SELECTION_COLUMN,
36
+ DRAGGABLE_COLUMN: DRAGGABLE_COLUMN
37
+ }
38
+ },
39
+ computed: {
40
+ record: function () {
41
+ return this.tableContext.draggable.draggingRecord
42
+ },
43
+ columns: function () {
44
+ return this.tableContext.columns.flat
45
+ },
46
+ containerWidth: function () {
47
+ return this.tableContext.layout.containerWidth
48
+ }
49
+ }
50
+ }
51
+ </script>
52
+
53
+ <style scoped>
54
+ .ui-table-v2__drag-preview {
55
+ position: fixed;
56
+ top: -10000px;
57
+ left: -10000px;
58
+ pointer-events: none;
59
+ border-collapse: separate;
60
+ border-spacing: 0;
61
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
62
+ border-radius: 4px;
63
+ overflow: hidden;
64
+ }
65
+ </style>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <TableResizeObserver @resize="handleCellResize">
3
+ <td ref="cellRef" :style="{ padding: '0', border: '0', height: '0' }">
4
+ <div :style="{ height: 0, overflow: 'hidden' }">&nbsp;</div>
5
+ </td>
6
+ </TableResizeObserver>
7
+ </template>
8
+
9
+ <script>
10
+ import TableResizeObserver from '../TableResizeObserver.vue'
11
+ import { DRAGGABLE_COLUMN, SELECTION_COLUMN } from '../constants.js'
12
+ export default {
13
+ name: 'MeasureCell',
14
+ components: { TableResizeObserver },
15
+ props: {
16
+ measureColumnWidth: {
17
+ type: Boolean,
18
+ default: false
19
+ },
20
+ colKey: {
21
+ type: String,
22
+ required: true
23
+ }
24
+ },
25
+ inject: ['tableContext'],
26
+
27
+ methods: {
28
+ handleCellResize({ offsetWidth }) {
29
+ if (this.colKey === DRAGGABLE_COLUMN || this.colKey === SELECTION_COLUMN) {
30
+ return
31
+ }
32
+ this.tableContext.actions.resize(this.colKey, offsetWidth)
33
+ }
34
+ },
35
+
36
+ mounted() {
37
+ if (this.$refs.cellRef) {
38
+ this.handleCellResize({ offsetWidth: this.$refs.cellRef.offsetWidth })
39
+ }
40
+ }
41
+ }
42
+ </script>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <tbody class="ui-table-v2__body">
3
+ <template v-if="measureColumnWidth">
4
+ <tr aria-hidden="true" class="ui-table-v2__measure-row" :style="{ height: '0', fontSize: '0' }">
5
+ <MeasureCell v-for="(column, colIndex) in tableContext.columns.flat" :key="colIndex" :colKey="column.key" />
6
+ </tr>
7
+ </template>
8
+
9
+ <template v-if="isEmpty">
10
+ <tr class="ui-table-v2__row">
11
+ <td colspan="100">
12
+ <div class="ui-table-v2__row-empty ui-table-v2__empty">
13
+ <div class="wrapper-img">
14
+ <img
15
+ src="https://content.pancake.vn/web-media-262/2e/2a/0c/96/c2b58ae9f06c4dc2a3b83016e56d5b4132ff40637862ba23435e43a0-w:224-h:224-l:3927-t:image/png.png"
16
+ />
17
+ </div>
18
+ <span class="wk-paragraph-small">{{ emptyText }}</span>
19
+ </div>
20
+ </td>
21
+ </tr>
22
+ </template>
23
+
24
+ <TableRow
25
+ v-for="(record, rowIndex) in tableContext.data.display"
26
+ :key="record[tableContext.layout.rowKey]"
27
+ :record="record"
28
+ :row-index="rowIndex"
29
+ :is-last-item="rowIndex == tableContext.data.display.length - 1"
30
+ >
31
+ <template #bodyCell="slotData">
32
+ <slot name="bodyCell" v-bind="slotData"></slot>
33
+ </template>
34
+ </TableRow>
35
+ </tbody>
36
+ </template>
37
+
38
+ <script>
39
+ import Sortable from 'sortablejs'
40
+ import TableRow from './TableRow.vue'
41
+ import MeasureCell from './MeasureCell.vue'
42
+
43
+ export default {
44
+ name: 'TableV2Body',
45
+ components: { TableRow, MeasureCell },
46
+ props: {
47
+ measureColumnWidth: {
48
+ type: Boolean,
49
+ default: false
50
+ },
51
+ isEmpty: {
52
+ type: Boolean,
53
+ default: false
54
+ }
55
+ },
56
+ inject: ['tableContext'],
57
+ watch: {
58
+ 'tableContext.draggable.enabled': function (val) {
59
+ val ? this._initSortable() : this._destroySortable()
60
+ },
61
+ 'tableContext.draggable.enableAnimationFlip': function () {
62
+ if (this.tableContext.draggable.enabled) this._initSortable()
63
+ }
64
+ },
65
+ mounted: function () {
66
+ if (this.tableContext.draggable.enabled) {
67
+ this._initSortable()
68
+ }
69
+ },
70
+ computed: {
71
+ emptyText() {
72
+ return this.tableContext.data.emptyText || 'Không có dữ liệu'
73
+ }
74
+ },
75
+ beforeUnmount: function () {
76
+ this._destroySortable()
77
+ },
78
+ // eslint-disable-next-line vue/no-deprecated-destroyed-lifecycle, vue/no-dupe-keys
79
+ beforeDestroy: function () {
80
+ this._destroySortable()
81
+ },
82
+ methods: {
83
+ _initSortable: function () {
84
+ this._destroySortable()
85
+ const self = this
86
+ const offset = this.measureColumnWidth ? 1 : 0
87
+ this._sortable = Sortable.create(this.$el, {
88
+ handle: '.drag-handle',
89
+ draggable: '.ui-table-v2__row',
90
+ animation: this.tableContext.draggable.enableAnimationFlip ? 150 : 0,
91
+ onChoose: function (evt) {
92
+ const rowIndex = evt.oldIndex - offset
93
+ self.tableContext.draggable.draggingRecord = self.tableContext.data.display[rowIndex] || null
94
+ },
95
+ setData: function (dataTransfer, dragEl) {
96
+ let previewEl =
97
+ typeof self.tableContext.draggable.getPreviewEl === 'function'
98
+ ? self.tableContext.draggable.getPreviewEl()
99
+ : null
100
+ if (!previewEl) return
101
+ dataTransfer.setDragImage(previewEl, 0, previewEl.offsetHeight / 2)
102
+ },
103
+ onEnd: function (evt) {
104
+ self.tableContext.draggable.draggingRecord = null
105
+ // Revert SortableJS DOM move — Vue owns the DOM
106
+ evt.from.insertBefore(evt.item, evt.from.children[evt.oldIndex] || null)
107
+ const oldIndex = evt.oldIndex - offset
108
+ const newIndex = evt.newIndex - offset
109
+ if (oldIndex === newIndex) return
110
+ if (typeof self.tableContext.actions.reorder === 'function') {
111
+ self.tableContext.actions.reorder(oldIndex, newIndex)
112
+ }
113
+ }
114
+ })
115
+ },
116
+ _destroySortable: function () {
117
+ if (this._sortable) {
118
+ this._sortable.destroy()
119
+ this._sortable = null
120
+ }
121
+ }
122
+ }
123
+ }
124
+ </script>
125
+
126
+ <style src="../style/table-body.css" scoped></style>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <td
3
+ :class="[
4
+ 'ui-table-v2__cell',
5
+ isSelectionCol && 'ui-table-v2__cell--selection',
6
+ isSelectionCol && 'ui-table-v2__header-cell--selection',
7
+ column.fixed && `ui-table-v2__cell--fixed-${column.fixed}`,
8
+ isLastFixedLeft && 'ui-table-v2__cell--fixed-left__last',
9
+ isFirstFixedRight && 'ui-table-v2__cell--fixed-right__first'
10
+ ]"
11
+ :style="cellStyle"
12
+ >
13
+ <div v-if="isSelectionCol" class="wrapper-option">
14
+ <Checkbox :checked="isSelected" :model-value="isSelected" @change="onToggle" />
15
+ </div>
16
+
17
+ <div v-else-if="isDraggableCol" class="wrapper-option">
18
+ <span class="drag-handle">
19
+ <WkiGripVertical :size="16" />
20
+ </span>
21
+ </div>
22
+
23
+ <slot name="bodyCell" :column="column" :text="record[column.dataIndex]" :record="record">
24
+ <span :class="[column.ellipsis && 'ui-table-v2__cell--ellipsis']">
25
+ {{ record[column.dataIndex] }}
26
+ </span>
27
+ </slot>
28
+ </td>
29
+ </template>
30
+
31
+ <script>
32
+ import Checkbox from '../../checkbox/Checkbox.vue'
33
+ import { SELECTION_COLUMN, DRAGGABLE_COLUMN } from '../constants.js'
34
+ import { toCssSize } from '../../../utils/common.js'
35
+ import { WkiGripVertical } from '../../../icons'
36
+
37
+ export default {
38
+ name: 'TableV2Cell',
39
+ components: { Checkbox, WkiGripVertical },
40
+ inject: ['tableContext'],
41
+ props: {
42
+ column: { type: Object, required: true },
43
+ record: { type: Object, required: true },
44
+ offset: { type: [Number, String], default: 0 }
45
+ },
46
+ computed: {
47
+ isSelectionCol: function () {
48
+ return this.column.type === SELECTION_COLUMN
49
+ },
50
+ isDraggableCol: function () {
51
+ return this.column.type === DRAGGABLE_COLUMN
52
+ },
53
+ isLastFixedLeft: function () {
54
+ if (this.column.fixed !== 'left') return false
55
+ const cols = this.tableContext.columns.flat
56
+ let lastKey = null
57
+ for (let i = 0; i < cols.length; i++) {
58
+ if (cols[i].fixed === 'left') lastKey = cols[i].key
59
+ }
60
+ return lastKey === this.column.key
61
+ },
62
+ isFirstFixedRight: function () {
63
+ if (this.column.fixed !== 'right') return false
64
+ const cols = this.tableContext.columns.flat
65
+ for (let i = 0; i < cols.length; i++) {
66
+ if (cols[i].fixed === 'right') return cols[i].key === this.column.key
67
+ }
68
+ return false
69
+ },
70
+ isSelected: function () {
71
+ var key = this.record[this.tableContext.layout.rowKey]
72
+ return this.tableContext.selection.selectedRowKeys.indexOf(key) !== -1
73
+ },
74
+ cellStyle: function () {
75
+ const res = { textAlign: this.column.align }
76
+ if (this.column.fixed) {
77
+ res.position = 'sticky'
78
+ if (this.column.fixed === 'left') {
79
+ res.left = toCssSize(this.offset)
80
+ } else if (this.column.fixed === 'right') {
81
+ res.right = toCssSize(this.offset)
82
+ }
83
+ }
84
+ return res
85
+ }
86
+ },
87
+ methods: {
88
+ onToggle: function (checked, nativeEvent) {
89
+ const key = this.record[this.tableContext.layout.rowKey]
90
+ const keys = [...this.tableContext.selection.selectedRowKeys]
91
+ const idx = keys.indexOf(key)
92
+
93
+ if (checked && idx === -1) {
94
+ keys.push(key)
95
+ } else if (!checked && idx !== -1) {
96
+ keys.splice(idx, 1)
97
+ }
98
+
99
+ this.tableContext.actions.select(keys, {
100
+ type: 'row',
101
+ record: this.record,
102
+ selected: checked,
103
+ nativeEvent: nativeEvent
104
+ })
105
+ }
106
+ }
107
+ }
108
+ </script>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <tr
3
+ v-bind="customAttrs"
4
+ v-on="customListeners"
5
+ :class="[
6
+ 'ui-table-v2__row',
7
+ isLastItem && 'ui-table-v2__row--last',
8
+ isSelected && 'ui-table-v2__row--selected',
9
+ customAttrs.class
10
+ ]"
11
+ :style="rowStyle"
12
+ >
13
+ <TableCell
14
+ v-for="column in tableContext.columns.flat"
15
+ :key="column.key"
16
+ :column="column"
17
+ :record="record"
18
+ :offset="column.fixed === 'left' ? leftStickyOffsets[column.key] : rightStickyOffsets[column.key]"
19
+ >
20
+ <template #bodyCell="slotData">
21
+ <slot name="bodyCell" v-bind="slotData"></slot>
22
+ </template>
23
+ </TableCell>
24
+ </tr>
25
+ </template>
26
+
27
+ <script>
28
+ import TableCell from './TableCell.vue'
29
+ import { splitProps } from '../../../utils/common.js'
30
+
31
+ export default {
32
+ name: 'TableV2Row',
33
+ components: { TableCell },
34
+ inject: ['tableContext'],
35
+ props: {
36
+ record: { type: Object, required: true },
37
+ rowIndex: { type: Number, required: true },
38
+ isLastItem: { type: Boolean, default: false }
39
+ },
40
+
41
+ computed: {
42
+ rowStyle() {
43
+ return { height: this.tableContext.layout.rowHeight + 'px' }
44
+ },
45
+
46
+ isSelected: function () {
47
+ var key = this.record[this.tableContext.layout.rowKey]
48
+ return this.tableContext.selection.selectedRowKeys.indexOf(key) !== -1
49
+ },
50
+
51
+ leftStickyOffsets() {
52
+ return this.tableContext.sticky.leftOffsets
53
+ },
54
+
55
+ rightStickyOffsets() {
56
+ return this.tableContext.sticky.rightOffsets
57
+ },
58
+
59
+ customProps: function () {
60
+ var fn = this.tableContext.rows.customRow
61
+ return typeof fn === 'function' ? fn(this.record, this.rowIndex) || {} : {}
62
+ },
63
+
64
+ customAttrs: function () {
65
+ return splitProps(this.customProps).attrs
66
+ },
67
+
68
+ customListeners: function () {
69
+ return splitProps(this.customProps).listeners
70
+ }
71
+ }
72
+ }
73
+ </script>
@@ -0,0 +1,19 @@
1
+ export function flattenColumns(columns) {
2
+ return (columns || []).map(function (col, i) {
3
+ return {
4
+ key: col.key || col.dataIndex || String(i),
5
+ type: col.type || null,
6
+ dataIndex: col.dataIndex || '',
7
+ title: col.title || '',
8
+ width: col.width || null,
9
+ align: col.align == 'left' ? null : col.align,
10
+ fixed: col.fixed || null,
11
+ ellipsis: col.ellipsis || false,
12
+ customCell: col.customCell || null,
13
+ customHeaderCell: col.customHeaderCell || null,
14
+ minWidth: col.minWidth || 50,
15
+ maxWidth: col.maxWidth || Infinity,
16
+ resizable: col.resizable || false
17
+ }
18
+ })
19
+ }
@@ -0,0 +1,12 @@
1
+ export function sortData(source, columnKey, order) {
2
+ if (!columnKey || !order) return source
3
+ var arr = source.slice()
4
+ arr.sort(function (a, b) {
5
+ var av = a[columnKey]
6
+ var bv = b[columnKey]
7
+ if (av === bv) return 0
8
+ var asc = av < bv ? -1 : 1
9
+ return order === 'ascend' ? asc : -asc
10
+ })
11
+ return arr
12
+ }
@@ -0,0 +1,31 @@
1
+ export function computeOffsets(columns, columnWidths) {
2
+ var left = {}
3
+ var right = {}
4
+ var leftAcc = 0
5
+ var rightAcc = 0
6
+
7
+ for (var i = 0; i < columns.length; i++) {
8
+ var col = columns[i]
9
+ if (col.fixed === 'left') {
10
+ left[col.key] = leftAcc
11
+ leftAcc += columnWidths.get(col.key) || parseWidth(col.width) || 0
12
+ }
13
+ }
14
+
15
+ for (var j = columns.length - 1; j >= 0; j--) {
16
+ var colR = columns[j]
17
+ if (colR.fixed === 'right') {
18
+ right[colR.key] = rightAcc
19
+ rightAcc += columnWidths.get(colR.key) || parseWidth(colR.width) || 0
20
+ }
21
+ }
22
+
23
+ return { left: left, right: right }
24
+ }
25
+
26
+ function parseWidth(width) {
27
+ if (!width) return 0
28
+ if (typeof width === 'number') return width
29
+ var n = parseInt(width, 10)
30
+ return isNaN(n) ? 0 : n
31
+ }
@@ -0,0 +1,2 @@
1
+ export var SELECTION_COLUMN = 'SELECTION_COLUMN'
2
+ export var DRAGGABLE_COLUMN = 'DRAGGABLE_COLUMN'