@vc-shell/framework 1.0.38 → 1.0.39

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 (142) hide show
  1. package/components/atoms/vc-badge/vc-badge.stories.ts +27 -0
  2. package/components/atoms/vc-badge/vc-badge.vue +63 -0
  3. package/components/atoms/vc-button/vc-button.stories.ts +34 -0
  4. package/components/atoms/vc-button/vc-button.vue +219 -0
  5. package/components/atoms/vc-card/vc-card.vue +137 -0
  6. package/components/atoms/vc-checkbox/vc-checkbox.stories.ts +25 -0
  7. package/components/atoms/vc-checkbox/vc-checkbox.vue +130 -0
  8. package/components/atoms/vc-col/vc-col.vue +22 -0
  9. package/components/atoms/vc-container/vc-container.stories.ts +31 -0
  10. package/components/atoms/vc-container/vc-container.vue +220 -0
  11. package/components/atoms/vc-hint/vc-hint.stories.ts +23 -0
  12. package/components/atoms/vc-hint/vc-hint.vue +11 -0
  13. package/components/atoms/vc-icon/vc-icon.stories.ts +32 -0
  14. package/components/atoms/vc-icon/vc-icon.vue +36 -0
  15. package/components/atoms/vc-image/vc-image.stories.ts +40 -0
  16. package/components/atoms/vc-image/vc-image.vue +122 -0
  17. package/components/atoms/vc-info-row/vc-info-row.vue +42 -0
  18. package/components/atoms/vc-label/vc-label.stories.ts +23 -0
  19. package/components/atoms/vc-label/vc-label.vue +49 -0
  20. package/components/atoms/vc-link/vc-link.stories.ts +30 -0
  21. package/components/atoms/vc-link/vc-link.vue +46 -0
  22. package/components/atoms/vc-loading/vc-loading.vue +30 -0
  23. package/components/atoms/vc-progress/vc-progress.stories.ts +25 -0
  24. package/components/atoms/vc-progress/vc-progress.vue +65 -0
  25. package/components/atoms/vc-row/vc-row.vue +13 -0
  26. package/components/atoms/vc-status/vc-status.stories.ts +26 -0
  27. package/components/atoms/vc-status/vc-status.vue +78 -0
  28. package/components/atoms/vc-status-icon/vc-status-icon.vue +21 -0
  29. package/components/atoms/vc-switch/vc-switch.stories.ts +27 -0
  30. package/components/atoms/vc-switch/vc-switch.vue +100 -0
  31. package/components/atoms/vc-widget/vc-widget.vue +85 -0
  32. package/components/index.ts +43 -0
  33. package/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +103 -0
  34. package/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.ts +39 -0
  35. package/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +21 -0
  36. package/components/molecules/vc-editor/vc-editor.vue +117 -0
  37. package/components/molecules/vc-file-upload/vc-file-upload.vue +134 -0
  38. package/components/molecules/vc-form/vc-form.stories.ts +23 -0
  39. package/components/molecules/vc-form/vc-form.vue +5 -0
  40. package/components/molecules/vc-input/vc-input.stories.ts +26 -0
  41. package/components/molecules/vc-input/vc-input.vue +443 -0
  42. package/components/molecules/vc-multivalue/vc-multivalue.vue +447 -0
  43. package/components/molecules/vc-notification/vc-notification.vue +101 -0
  44. package/components/molecules/vc-pagination/vc-pagination.stories.ts +23 -0
  45. package/components/molecules/vc-pagination/vc-pagination.vue +169 -0
  46. package/components/molecules/vc-rating/vc-rating.stories.ts +23 -0
  47. package/components/molecules/vc-rating/vc-rating.vue +77 -0
  48. package/components/molecules/vc-select/vc-select.stories.ts +25 -0
  49. package/components/molecules/vc-select/vc-select.vue +402 -0
  50. package/components/molecules/vc-slider/vc-slider.vue +106 -0
  51. package/components/molecules/vc-textarea/vc-textarea.stories.ts +23 -0
  52. package/components/molecules/vc-textarea/vc-textarea.vue +155 -0
  53. package/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +146 -0
  54. package/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +148 -0
  55. package/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +157 -0
  56. package/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +110 -0
  57. package/components/organisms/vc-app/vc-app.stories.ts +75 -0
  58. package/components/organisms/vc-app/vc-app.vue +171 -0
  59. package/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +126 -0
  60. package/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +223 -0
  61. package/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +67 -0
  62. package/components/organisms/vc-blade/vc-blade.stories.ts +46 -0
  63. package/components/organisms/vc-blade/vc-blade.vue +87 -0
  64. package/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +292 -0
  65. package/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue +123 -0
  66. package/components/organisms/vc-gallery/_internal/vc-gallery-preview/vc-gallery-preview.vue +93 -0
  67. package/components/organisms/vc-gallery/vc-gallery.vue +186 -0
  68. package/components/organisms/vc-login-form/vc-login-form.stories.ts +55 -0
  69. package/components/organisms/vc-login-form/vc-login-form.vue +48 -0
  70. package/components/organisms/vc-popup/vc-popup.stories.ts +23 -0
  71. package/components/organisms/vc-popup/vc-popup.vue +97 -0
  72. package/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +113 -0
  73. package/components/organisms/vc-table/_internal/vc-table-counter/vc-table-counter.vue +29 -0
  74. package/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +152 -0
  75. package/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +272 -0
  76. package/components/organisms/vc-table/vc-table.stories.ts +99 -0
  77. package/components/organisms/vc-table/vc-table.vue +638 -0
  78. package/core/api/index.ts +1 -0
  79. package/core/api/platform.ts +8332 -0
  80. package/core/composables/index.ts +8 -0
  81. package/core/composables/useAutosave/index.ts +57 -0
  82. package/core/composables/useFunctions/debounce.ts +18 -0
  83. package/core/composables/useFunctions/delay.ts +7 -0
  84. package/core/composables/useFunctions/index.ts +21 -0
  85. package/core/composables/useFunctions/once.ts +14 -0
  86. package/core/composables/useFunctions/sleep.ts +4 -0
  87. package/core/composables/useFunctions/throttle.ts +17 -0
  88. package/core/composables/useI18n/index.ts +28 -0
  89. package/core/composables/useLogger/index.ts +24 -0
  90. package/core/composables/useNotifications/index.ts +116 -0
  91. package/core/composables/usePermissions/index.ts +32 -0
  92. package/core/composables/useSettings/index.ts +36 -0
  93. package/core/composables/useUser/index.ts +266 -0
  94. package/core/directives/autofocus/index.ts +9 -0
  95. package/core/directives/click-outside/index.ts +21 -0
  96. package/core/directives/index.ts +4 -0
  97. package/core/directives/loading/index.ts +28 -0
  98. package/core/directives/permissions/index.ts +20 -0
  99. package/core/plugins/index.ts +1 -0
  100. package/core/plugins/validation/index.ts +2 -0
  101. package/core/plugins/validation/rules.ts +196 -0
  102. package/core/types/index.ts +92 -0
  103. package/core/utilities/camelToSnake.ts +7 -0
  104. package/core/utilities/index.ts +1 -0
  105. package/dist/core/composables/useNotifications/index.d.ts +1 -1
  106. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  107. package/dist/core/composables/useUser/index.d.ts +2 -2
  108. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  109. package/dist/core/plugins/validation/index.d.ts.map +1 -1
  110. package/dist/core/types/index.d.ts +1 -1
  111. package/dist/core/types/index.d.ts.map +1 -1
  112. package/dist/framework.js +70 -97
  113. package/dist/framework.js.map +1 -1
  114. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts +1 -1
  115. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  116. package/dist/shared/app-switcher/index.d.ts +2 -2
  117. package/dist/shared/app-switcher/index.d.ts.map +1 -1
  118. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  119. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  120. package/dist/shared/blade-navigation/types/index.d.ts +1 -1
  121. package/dist/shared/blade-navigation/types/index.d.ts.map +1 -1
  122. package/dist/style.css +1 -1
  123. package/dist/tsconfig.tsbuildinfo +1 -0
  124. package/dist/vite.config.d.ts.map +1 -1
  125. package/package.json +11 -8
  126. package/shared/app-switcher/components/index.ts +1 -0
  127. package/shared/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +90 -0
  128. package/shared/app-switcher/composables/index.ts +1 -0
  129. package/shared/app-switcher/composables/useAppSwitcher/index.ts +54 -0
  130. package/shared/app-switcher/index.ts +14 -0
  131. package/shared/assets/components/assets-details/assets-details.vue +138 -0
  132. package/shared/assets/components/index.ts +1 -0
  133. package/shared/assets/index.ts +19 -0
  134. package/shared/assets/locales/en.json +29 -0
  135. package/shared/assets/locales/index.ts +2 -0
  136. package/shared/blade-navigation/components/index.ts +1 -0
  137. package/shared/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -0
  138. package/shared/blade-navigation/composables/index.ts +1 -0
  139. package/shared/blade-navigation/composables/useBladeNavigation/index.ts +216 -0
  140. package/shared/blade-navigation/index.ts +15 -0
  141. package/shared/blade-navigation/types/index.ts +52 -0
  142. package/shared/index.ts +16 -0
@@ -0,0 +1,638 @@
1
+ <template>
2
+ <div class="relative overflow-hidden flex flex-col grow basis-0">
3
+ <!-- Header slot with filter and searchbar -->
4
+ <slot
5
+ name="header"
6
+ v-if="
7
+ ($slots['header'] || header) &&
8
+ ((items && items.length) ||
9
+ searchValue ||
10
+ searchValue === '' ||
11
+ activeFilterCount)
12
+ "
13
+ >
14
+ <div class="shrink-0 flex items-center justify-between p-4">
15
+ <!-- Table filter mobile button -->
16
+ <div v-if="$isMobile.value && $slots['filters']" class="mr-3">
17
+ <VcTableFilter :counter="activeFilterCount">
18
+ <template v-slot:default="{ closePanel }">
19
+ <slot name="filters" :closePanel="closePanel"></slot>
20
+ </template>
21
+ </VcTableFilter>
22
+ </div>
23
+
24
+ <!-- Table search input -->
25
+ <VcInput
26
+ class="grow basis-0"
27
+ :placeholder="searchPlaceholder"
28
+ :clearable="true"
29
+ name="table_search"
30
+ :modelValue="searchValue"
31
+ @update:modelValue="$emit('search:change', $event)"
32
+ ></VcInput>
33
+
34
+ <!-- Table filter desktop button -->
35
+ <div v-if="$isDesktop.value && $slots['filters']" class="ml-3">
36
+ <VcTableFilter
37
+ :title="$t('Filters')"
38
+ :counter="activeFilterCount"
39
+ :parentExpanded="expanded"
40
+ >
41
+ <template v-slot:default="{ closePanel }">
42
+ <slot name="filters" :closePanel="closePanel"></slot>
43
+ </template>
44
+ </VcTableFilter>
45
+ </div>
46
+ </div>
47
+ </slot>
48
+
49
+ <div class="flex relative overflow-hidden grow">
50
+ <!-- Table loading overlay -->
51
+ <VcLoading :active="loading"></VcLoading>
52
+
53
+ <!-- Table scroll container -->
54
+ <VcContainer
55
+ v-if="items && items.length"
56
+ ref="scrollContainer"
57
+ :noPadding="true"
58
+ class="grow basis-0"
59
+ :usePtr="!!$attrs['onScroll:ptr']"
60
+ @scroll:ptr="$emit('scroll:ptr')"
61
+ >
62
+ <!-- Mobile table view -->
63
+ <template v-if="$isMobile.value && $slots['mobile-item']">
64
+ <div>
65
+ <VcTableMobileItem
66
+ v-for="item in items"
67
+ :key="item.id"
68
+ :item="item"
69
+ :actionBuilder="itemActionBuilder"
70
+ @click="$emit('itemClick', item)"
71
+ @swipeStart="handleSwipe"
72
+ :swipingItem="mobileSwipeItem"
73
+ >
74
+ <slot name="mobile-item" :item="item"></slot>
75
+ </VcTableMobileItem>
76
+ </div>
77
+ </template>
78
+
79
+ <!-- Desktop table view -->
80
+ <table
81
+ v-else
82
+ class="[border-spacing:0] border-collapse relative pt-[43px] table-fixed box-border w-full"
83
+ :class="{
84
+ 'vc-table_empty': !items || !items.length,
85
+ 'vc-table_multiselect': multiselect,
86
+ }"
87
+ >
88
+ <thead v-if="columns" class="vc-table__header">
89
+ <tr class="vc-table__header-row">
90
+ <th
91
+ v-if="multiselect"
92
+ class="h-[42px] bg-[#f9f9f9] !border-0 shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] box-border sticky top-0 select-none overflow-hidden z-[1]"
93
+ width="50"
94
+ >
95
+ <div class="flex justify-center items-center">
96
+ <VcCheckbox
97
+ :modelValue="headerCheckbox"
98
+ @update:modelValue="processHeaderCheckbox"
99
+ @click.stop
100
+ ></VcCheckbox>
101
+ </div>
102
+ </th>
103
+ <th
104
+ v-for="item in columns"
105
+ :key="item.id"
106
+ class="h-[42px] bg-[#f9f9f9] !border-0 shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] box-border sticky top-0 select-none overflow-hidden z-[1] px-3"
107
+ :class="{
108
+ 'cursor-pointer group': item.sortable,
109
+ }"
110
+ :width="item.width"
111
+ @click="handleHeaderClick(item)"
112
+ >
113
+ <div
114
+ class="flex items-center flex-nowrap"
115
+ :class="tableAlignment[item.align]"
116
+ >
117
+ <div>
118
+ <slot :name="`header_${item.id}`">{{ item.title }}</slot>
119
+ </div>
120
+ <div v-if="sortField === item.id" class="ml-1">
121
+ <VcIcon
122
+ size="xs"
123
+ :icon="`fas fa-caret-${
124
+ sortDirection === 'DESC' ? 'down' : 'up'
125
+ }`"
126
+ ></VcIcon>
127
+ </div>
128
+ <div
129
+ class="flex flex-col ml-1 invisible group-hover:visible"
130
+ v-else
131
+ >
132
+ <VcIcon size="xs" icon="fas fa-caret-up"></VcIcon>
133
+ <VcIcon size="xs" icon="fas fa-caret-down"></VcIcon>
134
+ </div>
135
+ </div>
136
+ </th>
137
+ <th
138
+ class="h-[42px] bg-[#f9f9f9] !border-0 shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] box-border sticky top-0 select-none overflow-hidden z-[1]"
139
+ width="44"
140
+ v-if="itemActionBuilder"
141
+ ></th>
142
+ </tr>
143
+ </thead>
144
+
145
+ <tbody v-if="items" class="vc-table__body">
146
+ <tr
147
+ v-for="(item, i) in items"
148
+ :key="item.id"
149
+ class="vc-table__body-row h-[60px] bg-white hover:bg-[#dfeef9]"
150
+ :class="{
151
+ 'cursor-pointer hover:bg-[#dfeef9]': onItemClick,
152
+ 'bg-[#f8f8f8]': i % 2 === 1,
153
+ '!bg-[#dfeef9] hover:bg-[#dfeef9]':
154
+ item && item.id ? selectedItemId === item.id : false,
155
+ }"
156
+ @click="$emit('itemClick', item)"
157
+ @mouseover="calculateActions(item)"
158
+ @mouseleave="closeActions"
159
+ >
160
+ <td v-if="multiselect" width="50">
161
+ <div class="flex justify-center items-center">
162
+ <VcCheckbox
163
+ :modelValue="checkboxes[item.id]"
164
+ @update:modelValue="processCheckbox(item.id, $event)"
165
+ @click.stop
166
+ ></VcCheckbox>
167
+ </div>
168
+ </td>
169
+ <td
170
+ v-for="cell in columns"
171
+ :key="`${item.id}_${cell.id}`"
172
+ class="box-border overflow-hidden px-3"
173
+ :class="cell.class"
174
+ :width="cell.width"
175
+ >
176
+ <slot :name="`item_${cell.id}`" :item="item" :cell="cell">
177
+ <VcTableCell :cell="cell" :item="item"></VcTableCell>
178
+ </slot>
179
+ </td>
180
+ <td
181
+ class="box-border overflow-visible px-3"
182
+ width="44"
183
+ v-if="itemActionBuilder"
184
+ >
185
+ <div
186
+ class="vc-table__body-actions-container relative !hidden justify-center items-center"
187
+ >
188
+ <button
189
+ class="text-[#319ed4] cursor-pointer border-none bg-transparent disabled:text-[gray]"
190
+ @click.stop="showActions(item, item.id)"
191
+ :ref="(el) => setActionToggleRefs(el, item.id)"
192
+ aria-describedby="tooltip"
193
+ :disabled="!(itemActions && itemActions.length)"
194
+ >
195
+ <VcIcon icon="fas fa-cog" size="m" />
196
+ </button>
197
+ <div
198
+ class="vc-table__body-tooltip bg-white rounded-l-[4px] p-[15px] z-0 absolute right-0 drop-shadow-[1px_3px_14px_rgba(111,122,131,0.25)]"
199
+ v-show="selectedRow === item.id"
200
+ @mouseleave="closeActions"
201
+ :ref="(el) => setTooltipRefs(el, item.id)"
202
+ role="tooltip"
203
+ >
204
+ <div
205
+ class="flex items-center flex-row text-[#3f3f3f] font-normal not-italic text-base leading-[20px] gap-[25px]"
206
+ >
207
+ <div
208
+ v-for="(itemAction, i) in itemActions"
209
+ :key="i"
210
+ :class="[
211
+ 'flex flex-row items-center text-[#319ed4] cursor-pointer',
212
+ `vc-table__body-actions-item_${itemAction.variant}`,
213
+ ]"
214
+ @click.stop="itemAction.clickHandler(item)"
215
+ >
216
+ <VcIcon :icon="itemAction.icon" size="m" />
217
+ <div
218
+ class="not-italic font-normal text-base leading-[20px] text-[#3f3f3f] ml-[7px]"
219
+ >
220
+ {{ itemAction.title }}
221
+ </div>
222
+ </div>
223
+ </div>
224
+ <div
225
+ class="vc-table__body-tooltip-arrow"
226
+ data-popper-arrow
227
+ ></div>
228
+ </div>
229
+ </div>
230
+ </td>
231
+ </tr>
232
+ </tbody>
233
+ </table>
234
+ </VcContainer>
235
+
236
+ <!-- Empty table view -->
237
+ <template v-else>
238
+ <slot
239
+ v-if="searchValue || searchValue === '' || activeFilterCount"
240
+ name="notfound"
241
+ >
242
+ <div
243
+ v-if="notfound"
244
+ class="w-full h-full box-border flex flex-col items-center justify-center"
245
+ >
246
+ <img v-if="notfound.image" :src="notfound.image" />
247
+ <div class="m-4 vc-table__empty-text">
248
+ {{ notfound.text }}
249
+ </div>
250
+ <VcButton v-if="notfound.action" @click="notfound.clickHandler">
251
+ {{ notfound.action }}
252
+ </VcButton>
253
+ </div>
254
+ </slot>
255
+ <slot v-else name="empty">
256
+ <div
257
+ v-if="empty"
258
+ class="w-full h-full box-border flex flex-col items-center justify-center"
259
+ >
260
+ <img v-if="empty.image" :src="empty.image" />
261
+ <div class="m-4 text-xl font-medium">{{ empty.text }}</div>
262
+ <VcButton v-if="empty.action" @click="empty.clickHandler">
263
+ {{ empty.action }}
264
+ </VcButton>
265
+ </div>
266
+ </slot>
267
+ </template>
268
+ </div>
269
+
270
+ <!-- Table footer -->
271
+ <slot
272
+ name="footer"
273
+ v-if="($slots['footer'] || footer) && items && items.length"
274
+ >
275
+ <div
276
+ class="bg-[#fbfdfe] border-t border-solid border-[#eaedf3] flex-shrink-0 flex items-center justify-between p-4"
277
+ >
278
+ <!-- Table pagination -->
279
+ <VcPagination
280
+ :expanded="expanded"
281
+ :pages="pages"
282
+ :currentPage="currentPage"
283
+ @itemClick="$emit('paginationClick', $event)"
284
+ ></VcPagination>
285
+
286
+ <!-- Table counter -->
287
+ <VcTableCounter
288
+ :label="totalLabel"
289
+ :value="totalCount"
290
+ ></VcTableCounter>
291
+ </div>
292
+ </slot>
293
+ </div>
294
+ </template>
295
+
296
+ <script lang="ts" setup>
297
+ import { computed, nextTick, PropType, ref, watch, onBeforeUpdate } from "vue";
298
+ import {
299
+ VcIcon,
300
+ VcLoading,
301
+ VcCheckbox,
302
+ VcContainer,
303
+ VcInput,
304
+ VcPagination,
305
+ } from "@/components";
306
+ import VcTableCounter from "./_internal/vc-table-counter/vc-table-counter.vue";
307
+ import VcTableFilter from "./_internal/vc-table-filter/vc-table-filter.vue";
308
+ import VcTableMobileItem from "./_internal/vc-table-mobile-item/vc-table-mobile-item.vue";
309
+ import VcTableCell from "./_internal/vc-table-cell/vc-table-cell.vue";
310
+ import { createPopper, Instance } from "@popperjs/core";
311
+ import { IActionBuilderResult } from "@/core/types";
312
+
313
+ interface ITableItemRef {
314
+ element: HTMLDivElement;
315
+ id: string;
316
+ }
317
+
318
+ const props = defineProps({
319
+ columns: {
320
+ type: Array,
321
+ default: () => [],
322
+ },
323
+
324
+ items: {
325
+ type: Array as PropType<{ id: string }[]>,
326
+ default: () => [],
327
+ },
328
+
329
+ filterItems: {
330
+ type: Array,
331
+ default: () => [],
332
+ },
333
+
334
+ itemActionBuilder: {
335
+ type: Function,
336
+ default: undefined,
337
+ },
338
+
339
+ sort: {
340
+ type: String,
341
+ default: undefined,
342
+ },
343
+
344
+ multiselect: {
345
+ type: Boolean,
346
+ default: false,
347
+ },
348
+
349
+ expanded: {
350
+ type: Boolean,
351
+ default: false,
352
+ },
353
+
354
+ totalLabel: {
355
+ type: String,
356
+ default: "Totals:",
357
+ },
358
+
359
+ totalCount: {
360
+ type: Number,
361
+ default: 0,
362
+ },
363
+
364
+ pages: {
365
+ type: Number,
366
+ default: 0,
367
+ },
368
+
369
+ currentPage: {
370
+ type: Number,
371
+ default: 0,
372
+ },
373
+
374
+ searchPlaceholder: {
375
+ type: String,
376
+ default: "Search...",
377
+ },
378
+
379
+ searchValue: {
380
+ type: String,
381
+ default: undefined,
382
+ },
383
+
384
+ loading: {
385
+ type: Boolean,
386
+ default: false,
387
+ },
388
+
389
+ empty: {
390
+ type: Object,
391
+ default: () => ({
392
+ text: "List is empty.",
393
+ }),
394
+ },
395
+
396
+ notfound: {
397
+ type: Object,
398
+ default: () => ({
399
+ text: "Nothing found.",
400
+ }),
401
+ },
402
+
403
+ header: {
404
+ type: Boolean,
405
+ default: true,
406
+ },
407
+
408
+ footer: {
409
+ type: Boolean,
410
+ default: true,
411
+ },
412
+
413
+ activeFilterCount: {
414
+ type: Number,
415
+ default: 0,
416
+ },
417
+
418
+ selectedItemId: {
419
+ type: String,
420
+ default: undefined,
421
+ },
422
+
423
+ scrolling: {
424
+ type: Boolean,
425
+ default: false,
426
+ },
427
+
428
+ onItemClick: {
429
+ type: Function,
430
+ default: undefined,
431
+ },
432
+ });
433
+
434
+ const emit = defineEmits([
435
+ "paginationClick",
436
+ "selectionChanged",
437
+ "search:change",
438
+ "filter:apply",
439
+ "filter:reset",
440
+ "headerClick",
441
+ ]);
442
+
443
+ const checkboxes = ref<Record<string, boolean>>({});
444
+ const selectedRow = ref<string>();
445
+ const tooltip = ref<Instance>();
446
+ const scrollContainer = ref<typeof VcContainer>();
447
+ const actionToggleRefs = ref<ITableItemRef[]>([]);
448
+ const tooltipRefs = ref<ITableItemRef[]>([]);
449
+ const itemActions = ref<IActionBuilderResult[]>([]);
450
+ const mobileSwipeItem = ref<string>();
451
+
452
+ onBeforeUpdate(() => {
453
+ actionToggleRefs.value = [];
454
+ tooltipRefs.value = [];
455
+ });
456
+
457
+ const sortDirection = computed(() => {
458
+ const entry = props.sort?.split(":");
459
+ return entry && entry.length === 2 && entry[1];
460
+ });
461
+
462
+ const sortField = computed(() => {
463
+ const entry = props.sort?.split(":");
464
+ return entry && entry.length === 2 && entry[0];
465
+ });
466
+
467
+ const tableAlignment = {
468
+ start: "justify-start",
469
+ end: "justify-end",
470
+ center: "justify-center",
471
+ between: "justify-between",
472
+ around: "justify-around",
473
+ evenly: "justify-evenly",
474
+ };
475
+
476
+ const headerCheckbox = computed(() =>
477
+ Object.values(checkboxes.value).every((value) => value)
478
+ );
479
+
480
+ watch(
481
+ () => props.items,
482
+ (value: { id: string }[]) => {
483
+ checkboxes.value = {};
484
+ value?.forEach((item) => (checkboxes.value[item.id] = false));
485
+ scrollContainer.value?.scrollTop();
486
+ }
487
+ );
488
+
489
+ function setTooltipRefs(el: HTMLDivElement, id: string) {
490
+ if (el) {
491
+ const isExists = tooltipRefs.value.some((item) => item.id === id);
492
+ if (!isExists) {
493
+ tooltipRefs.value.push({ element: el, id });
494
+ }
495
+ }
496
+ }
497
+
498
+ function setActionToggleRefs(el: HTMLDivElement, id: string) {
499
+ if (el) {
500
+ const isExists = actionToggleRefs.value.some((item) => item.id === id);
501
+ if (!isExists) {
502
+ actionToggleRefs.value.push({ element: el, id });
503
+ }
504
+ }
505
+ }
506
+
507
+ function processHeaderCheckbox() {
508
+ const currentState = Object.values(checkboxes.value).every((value) => value);
509
+ Object.keys(checkboxes.value).forEach(
510
+ (key) => (checkboxes.value[key] = !currentState)
511
+ );
512
+ emit("selectionChanged", checkboxes.value);
513
+ }
514
+
515
+ function processCheckbox(id: string, state: boolean) {
516
+ checkboxes.value[id] = state;
517
+ emit("selectionChanged", checkboxes.value);
518
+ }
519
+
520
+ function showActions(item: { id: string }, index: string) {
521
+ selectedRow.value = item.id;
522
+
523
+ const toggleRef = actionToggleRefs.value.find((item) => item.id === index);
524
+ const tooltipRef = tooltipRefs.value.find((item) => item.id === index);
525
+
526
+ if (toggleRef && tooltipRef) {
527
+ nextTick(() => {
528
+ tooltip.value = createPopper(toggleRef.element, tooltipRef.element, {
529
+ placement: "bottom",
530
+ onFirstUpdate: () => tooltip.value?.update(),
531
+ modifiers: [
532
+ {
533
+ name: "offset",
534
+ options: {
535
+ offset: [-15, 15],
536
+ },
537
+ },
538
+ ],
539
+ });
540
+ });
541
+ }
542
+ }
543
+
544
+ async function calculateActions(item: { id: string }) {
545
+ if (typeof props.itemActionBuilder === "function") {
546
+ itemActions.value = await props.itemActionBuilder(item);
547
+ }
548
+ }
549
+
550
+ function closeActions() {
551
+ selectedRow.value = undefined;
552
+ tooltip.value?.destroy();
553
+ }
554
+
555
+ function handleSwipe(id: string) {
556
+ mobileSwipeItem.value = id;
557
+ }
558
+
559
+ function handleHeaderClick(item: Record<string, unknown>) {
560
+ emit("headerClick", item);
561
+ }
562
+ </script>
563
+
564
+ <style lang="scss">
565
+ $variants: (
566
+ danger: #ff4a4a,
567
+ success: #87b563,
568
+ );
569
+
570
+ .vc-table {
571
+ &__body {
572
+ &-tooltip {
573
+ background: #ffffff;
574
+ border-radius: 4px 0 0 4px;
575
+ padding: 15px;
576
+ z-index: 0;
577
+ position: absolute;
578
+ right: 0;
579
+ filter: drop-shadow(1px 3px 14px rgba(111, 122, 131, 0.25));
580
+ }
581
+
582
+ &-tooltip-arrow,
583
+ &-tooltip-arrow:before {
584
+ position: absolute;
585
+ width: 8px;
586
+ height: 8px;
587
+ background: inherit;
588
+ }
589
+
590
+ &-tooltip-arrow {
591
+ visibility: hidden;
592
+ }
593
+
594
+ &-tooltip-arrow:before {
595
+ visibility: visible;
596
+ content: "";
597
+ transform: rotate(45deg);
598
+ }
599
+
600
+ &-tooltip[data-popper-placement^="top"] > .vc-table__body-tooltip-arrow {
601
+ bottom: -5px;
602
+ }
603
+
604
+ &-tooltip[data-popper-placement^="bottom"] > .vc-table__body-tooltip-arrow {
605
+ top: -5px;
606
+ }
607
+
608
+ &-row:hover .vc-table__body-actions-container {
609
+ @apply flex #{!important};
610
+ }
611
+
612
+ &-actions-item {
613
+ @each $name, $variant in $variants {
614
+ &_#{$name} {
615
+ @apply text-[#{$variant}];
616
+ }
617
+ }
618
+ }
619
+
620
+ &-tooltip-arrow,
621
+ &-tooltip-arrow:before {
622
+ @apply absolute w-2 h-2 bg-inherit;
623
+ }
624
+
625
+ &-tooltip-arrow {
626
+ @apply invisible before:visible before:content-[""] before:rotate-45;
627
+ }
628
+
629
+ &-tooltip[data-popper-placement^="top"] > .vc-table__body-tooltip-arrow {
630
+ @apply bottom-[-5px];
631
+ }
632
+
633
+ &-tooltip[data-popper-placement^="bottom"] > .vc-table__body-tooltip-arrow {
634
+ @apply top-[-5px];
635
+ }
636
+ }
637
+ }
638
+ </style>
@@ -0,0 +1 @@
1
+ export * from "./platform";