@vc-shell/framework 1.0.38 → 1.0.40

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 (256) hide show
  1. package/core/api/index.ts +1 -0
  2. package/core/api/platform.ts +8332 -0
  3. package/core/composables/index.ts +8 -0
  4. package/core/composables/useAutosave/index.ts +57 -0
  5. package/core/composables/useFunctions/debounce.ts +18 -0
  6. package/core/composables/useFunctions/delay.ts +7 -0
  7. package/core/composables/useFunctions/index.ts +21 -0
  8. package/core/composables/useFunctions/once.ts +14 -0
  9. package/core/composables/useFunctions/sleep.ts +4 -0
  10. package/core/composables/useFunctions/throttle.ts +17 -0
  11. package/core/composables/useI18n/index.ts +28 -0
  12. package/core/composables/useLogger/index.ts +24 -0
  13. package/core/composables/useNotifications/index.ts +116 -0
  14. package/core/composables/usePermissions/index.ts +32 -0
  15. package/core/composables/useSettings/index.ts +62 -0
  16. package/core/composables/useUser/index.ts +266 -0
  17. package/core/directives/autofocus/index.ts +9 -0
  18. package/core/directives/click-outside/index.ts +21 -0
  19. package/core/directives/index.ts +4 -0
  20. package/core/directives/loading/index.ts +28 -0
  21. package/core/directives/permissions/index.ts +20 -0
  22. package/core/plugins/index.ts +1 -0
  23. package/core/plugins/validation/index.ts +2 -0
  24. package/core/plugins/validation/rules.ts +196 -0
  25. package/core/types/index.ts +92 -0
  26. package/core/utilities/camelToSnake.ts +7 -0
  27. package/core/utilities/index.ts +1 -0
  28. package/dist/core/composables/useNotifications/index.d.ts +1 -1
  29. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  30. package/dist/core/composables/useSettings/index.d.ts +10 -1
  31. package/dist/core/composables/useSettings/index.d.ts.map +1 -1
  32. package/dist/core/composables/useUser/index.d.ts +2 -2
  33. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  34. package/dist/core/plugins/validation/index.d.ts.map +1 -1
  35. package/dist/core/types/index.d.ts +1 -1
  36. package/dist/core/types/index.d.ts.map +1 -1
  37. package/dist/framework.js +72 -99
  38. package/dist/framework.js.map +1 -1
  39. package/dist/index.d.ts +3 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts +1 -1
  42. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  43. package/dist/shared/app-switcher/index.d.ts +2 -2
  44. package/dist/shared/app-switcher/index.d.ts.map +1 -1
  45. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  46. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  47. package/dist/shared/blade-navigation/types/index.d.ts +1 -1
  48. package/dist/shared/blade-navigation/types/index.d.ts.map +1 -1
  49. package/dist/style.css +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -0
  51. package/dist/ui/components/atoms/vc-badge/index.d.ts +5 -0
  52. package/dist/ui/components/atoms/vc-badge/index.d.ts.map +1 -0
  53. package/dist/ui/components/atoms/vc-badge/vc-badge-model.d.ts +28 -0
  54. package/dist/ui/components/atoms/vc-badge/vc-badge-model.d.ts.map +1 -0
  55. package/dist/{components → ui/components}/atoms/vc-badge/vc-badge.stories.d.ts +0 -0
  56. package/dist/ui/components/atoms/vc-badge/vc-badge.stories.d.ts.map +1 -0
  57. package/dist/ui/components/atoms/vc-button/index.d.ts +5 -0
  58. package/dist/ui/components/atoms/vc-button/index.d.ts.map +1 -0
  59. package/dist/ui/components/atoms/vc-button/vc-button-model.d.ts +28 -0
  60. package/dist/ui/components/atoms/vc-button/vc-button-model.d.ts.map +1 -0
  61. package/dist/{components → ui/components}/atoms/vc-button/vc-button.stories.d.ts +0 -0
  62. package/dist/ui/components/atoms/vc-button/vc-button.stories.d.ts.map +1 -0
  63. package/dist/{components → ui/components}/atoms/vc-checkbox/vc-checkbox.stories.d.ts +0 -0
  64. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +1 -0
  65. package/dist/{components → ui/components}/atoms/vc-container/vc-container.stories.d.ts +0 -0
  66. package/dist/ui/components/atoms/vc-container/vc-container.stories.d.ts.map +1 -0
  67. package/dist/{components → ui/components}/atoms/vc-hint/vc-hint.stories.d.ts +0 -0
  68. package/dist/ui/components/atoms/vc-hint/vc-hint.stories.d.ts.map +1 -0
  69. package/dist/{components → ui/components}/atoms/vc-icon/vc-icon.stories.d.ts +0 -0
  70. package/dist/ui/components/atoms/vc-icon/vc-icon.stories.d.ts.map +1 -0
  71. package/dist/{components → ui/components}/atoms/vc-image/vc-image.stories.d.ts +0 -0
  72. package/dist/ui/components/atoms/vc-image/vc-image.stories.d.ts.map +1 -0
  73. package/dist/{components → ui/components}/atoms/vc-label/vc-label.stories.d.ts +0 -0
  74. package/dist/ui/components/atoms/vc-label/vc-label.stories.d.ts.map +1 -0
  75. package/dist/{components → ui/components}/atoms/vc-link/vc-link.stories.d.ts +0 -0
  76. package/dist/ui/components/atoms/vc-link/vc-link.stories.d.ts.map +1 -0
  77. package/dist/{components → ui/components}/atoms/vc-progress/vc-progress.stories.d.ts +0 -0
  78. package/dist/ui/components/atoms/vc-progress/vc-progress.stories.d.ts.map +1 -0
  79. package/dist/{components → ui/components}/atoms/vc-status/vc-status.stories.d.ts +0 -0
  80. package/dist/ui/components/atoms/vc-status/vc-status.stories.d.ts.map +1 -0
  81. package/dist/{components → ui/components}/atoms/vc-switch/vc-switch.stories.d.ts +0 -0
  82. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts.map +1 -0
  83. package/dist/{components → ui/components}/index.d.ts +4 -3
  84. package/dist/ui/components/index.d.ts.map +1 -0
  85. package/dist/{components → ui/components}/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +0 -0
  86. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +1 -0
  87. package/dist/{components → ui/components}/molecules/vc-form/vc-form.stories.d.ts +0 -0
  88. package/dist/ui/components/molecules/vc-form/vc-form.stories.d.ts.map +1 -0
  89. package/dist/ui/components/molecules/vc-input/index.d.ts +5 -0
  90. package/dist/ui/components/molecules/vc-input/index.d.ts.map +1 -0
  91. package/dist/ui/components/molecules/vc-input/vc-input-model.d.ts +140 -0
  92. package/dist/ui/components/molecules/vc-input/vc-input-model.d.ts.map +1 -0
  93. package/dist/ui/components/molecules/vc-input-currency/index.d.ts +5 -0
  94. package/dist/ui/components/molecules/vc-input-currency/index.d.ts.map +1 -0
  95. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency-model.d.ts +124 -0
  96. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency-model.d.ts.map +1 -0
  97. package/dist/{components → ui/components}/molecules/vc-pagination/vc-pagination.stories.d.ts +0 -0
  98. package/dist/ui/components/molecules/vc-pagination/vc-pagination.stories.d.ts.map +1 -0
  99. package/dist/{components → ui/components}/molecules/vc-rating/vc-rating.stories.d.ts +0 -0
  100. package/dist/ui/components/molecules/vc-rating/vc-rating.stories.d.ts.map +1 -0
  101. package/dist/ui/components/molecules/vc-select/index.d.ts +5 -0
  102. package/dist/ui/components/molecules/vc-select/index.d.ts.map +1 -0
  103. package/dist/ui/components/molecules/vc-select/vc-select-model.d.ts +207 -0
  104. package/dist/ui/components/molecules/vc-select/vc-select-model.d.ts.map +1 -0
  105. package/dist/{components → ui/components}/molecules/vc-textarea/vc-textarea.stories.d.ts +0 -0
  106. package/dist/ui/components/molecules/vc-textarea/vc-textarea.stories.d.ts.map +1 -0
  107. package/dist/{components → ui/components}/organisms/vc-app/vc-app.stories.d.ts +0 -0
  108. package/dist/ui/components/organisms/vc-app/vc-app.stories.d.ts.map +1 -0
  109. package/dist/{components → ui/components}/organisms/vc-blade/vc-blade.stories.d.ts +0 -0
  110. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts.map +1 -0
  111. package/dist/{components → ui/components}/organisms/vc-login-form/vc-login-form.stories.d.ts +0 -0
  112. package/dist/ui/components/organisms/vc-login-form/vc-login-form.stories.d.ts.map +1 -0
  113. package/dist/{components → ui/components}/organisms/vc-popup/vc-popup.stories.d.ts +0 -0
  114. package/dist/ui/components/organisms/vc-popup/vc-popup.stories.d.ts.map +1 -0
  115. package/dist/{components → ui/components}/organisms/vc-table/vc-table.stories.d.ts +0 -0
  116. package/dist/ui/components/organisms/vc-table/vc-table.stories.d.ts.map +1 -0
  117. package/dist/ui/types/index.d.ts +13 -0
  118. package/dist/ui/types/index.d.ts.map +1 -0
  119. package/dist/ui/types/ts-helpers.d.ts +13 -0
  120. package/dist/ui/types/ts-helpers.d.ts.map +1 -0
  121. package/dist/vite.config.d.ts.map +1 -1
  122. package/package.json +30 -10
  123. package/shared/app-switcher/components/index.ts +1 -0
  124. package/shared/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +90 -0
  125. package/shared/app-switcher/composables/index.ts +1 -0
  126. package/shared/app-switcher/composables/useAppSwitcher/index.ts +54 -0
  127. package/shared/app-switcher/index.ts +14 -0
  128. package/shared/assets/components/assets-details/assets-details.vue +138 -0
  129. package/shared/assets/components/index.ts +1 -0
  130. package/shared/assets/index.ts +19 -0
  131. package/shared/assets/locales/en.json +29 -0
  132. package/shared/assets/locales/index.ts +2 -0
  133. package/shared/blade-navigation/components/index.ts +1 -0
  134. package/shared/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -0
  135. package/shared/blade-navigation/composables/index.ts +1 -0
  136. package/shared/blade-navigation/composables/useBladeNavigation/index.ts +216 -0
  137. package/shared/blade-navigation/index.ts +15 -0
  138. package/shared/blade-navigation/types/index.ts +52 -0
  139. package/shared/index.ts +16 -0
  140. package/tailwind.config.js +4 -3
  141. package/ui/components/atoms/vc-badge/index.ts +7 -0
  142. package/ui/components/atoms/vc-badge/vc-badge-model.ts +30 -0
  143. package/ui/components/atoms/vc-badge/vc-badge.stories.ts +27 -0
  144. package/ui/components/atoms/vc-badge/vc-badge.vue +57 -0
  145. package/ui/components/atoms/vc-button/index.ts +7 -0
  146. package/ui/components/atoms/vc-button/vc-button-model.ts +30 -0
  147. package/ui/components/atoms/vc-button/vc-button.stories.ts +34 -0
  148. package/ui/components/atoms/vc-button/vc-button.vue +219 -0
  149. package/ui/components/atoms/vc-card/vc-card.vue +137 -0
  150. package/ui/components/atoms/vc-checkbox/vc-checkbox.stories.ts +25 -0
  151. package/ui/components/atoms/vc-checkbox/vc-checkbox.vue +130 -0
  152. package/ui/components/atoms/vc-col/vc-col.vue +22 -0
  153. package/ui/components/atoms/vc-container/vc-container.stories.ts +31 -0
  154. package/ui/components/atoms/vc-container/vc-container.vue +222 -0
  155. package/ui/components/atoms/vc-hint/vc-hint.stories.ts +23 -0
  156. package/ui/components/atoms/vc-hint/vc-hint.vue +11 -0
  157. package/ui/components/atoms/vc-icon/vc-icon.stories.ts +32 -0
  158. package/ui/components/atoms/vc-icon/vc-icon.vue +36 -0
  159. package/ui/components/atoms/vc-image/vc-image.stories.ts +40 -0
  160. package/ui/components/atoms/vc-image/vc-image.vue +122 -0
  161. package/ui/components/atoms/vc-info-row/vc-info-row.vue +42 -0
  162. package/ui/components/atoms/vc-label/vc-label.stories.ts +23 -0
  163. package/ui/components/atoms/vc-label/vc-label.vue +49 -0
  164. package/ui/components/atoms/vc-link/vc-link.stories.ts +30 -0
  165. package/ui/components/atoms/vc-link/vc-link.vue +46 -0
  166. package/ui/components/atoms/vc-loading/vc-loading.vue +33 -0
  167. package/ui/components/atoms/vc-progress/vc-progress.stories.ts +25 -0
  168. package/ui/components/atoms/vc-progress/vc-progress.vue +65 -0
  169. package/ui/components/atoms/vc-row/vc-row.vue +13 -0
  170. package/ui/components/atoms/vc-status/vc-status.stories.ts +26 -0
  171. package/ui/components/atoms/vc-status/vc-status.vue +78 -0
  172. package/ui/components/atoms/vc-status-icon/vc-status-icon.vue +21 -0
  173. package/ui/components/atoms/vc-switch/vc-switch.stories.ts +27 -0
  174. package/ui/components/atoms/vc-switch/vc-switch.vue +100 -0
  175. package/ui/components/atoms/vc-widget/vc-widget.vue +85 -0
  176. package/ui/components/index.ts +44 -0
  177. package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +103 -0
  178. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.ts +39 -0
  179. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +21 -0
  180. package/ui/components/molecules/vc-currency-input/vc-input.vue +436 -0
  181. package/ui/components/molecules/vc-editor/vc-editor.vue +117 -0
  182. package/ui/components/molecules/vc-file-upload/vc-file-upload.vue +134 -0
  183. package/ui/components/molecules/vc-form/vc-form.stories.ts +23 -0
  184. package/ui/components/molecules/vc-form/vc-form.vue +5 -0
  185. package/ui/components/molecules/vc-input/index.ts +8 -0
  186. package/ui/components/molecules/vc-input/vc-input-model.ts +150 -0
  187. package/ui/components/molecules/vc-input/vc-input.vue +324 -0
  188. package/ui/components/molecules/vc-input-currency/index.ts +8 -0
  189. package/ui/components/molecules/vc-input-currency/vc-input-currency-model.ts +128 -0
  190. package/ui/components/molecules/vc-input-currency/vc-input-currency.vue +86 -0
  191. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +447 -0
  192. package/ui/components/molecules/vc-notification/vc-notification.vue +101 -0
  193. package/ui/components/molecules/vc-pagination/vc-pagination.stories.ts +23 -0
  194. package/ui/components/molecules/vc-pagination/vc-pagination.vue +169 -0
  195. package/ui/components/molecules/vc-rating/vc-rating.stories.ts +23 -0
  196. package/ui/components/molecules/vc-rating/vc-rating.vue +77 -0
  197. package/ui/components/molecules/vc-select/index.ts +7 -0
  198. package/ui/components/molecules/vc-select/vc-select-model.ts +216 -0
  199. package/ui/components/molecules/vc-select/vc-select.vue +727 -0
  200. package/ui/components/molecules/vc-slider/vc-slider.vue +106 -0
  201. package/ui/components/molecules/vc-textarea/vc-textarea.stories.ts +23 -0
  202. package/ui/components/molecules/vc-textarea/vc-textarea.vue +155 -0
  203. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +150 -0
  204. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +148 -0
  205. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +157 -0
  206. package/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +110 -0
  207. package/ui/components/organisms/vc-app/vc-app.stories.ts +75 -0
  208. package/ui/components/organisms/vc-app/vc-app.vue +169 -0
  209. package/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +126 -0
  210. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +223 -0
  211. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +67 -0
  212. package/ui/components/organisms/vc-blade/vc-blade.stories.ts +46 -0
  213. package/ui/components/organisms/vc-blade/vc-blade.vue +87 -0
  214. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +426 -0
  215. package/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue +123 -0
  216. package/ui/components/organisms/vc-gallery/_internal/vc-gallery-preview/vc-gallery-preview.vue +93 -0
  217. package/ui/components/organisms/vc-gallery/vc-gallery.vue +186 -0
  218. package/ui/components/organisms/vc-login-form/vc-login-form.stories.ts +55 -0
  219. package/ui/components/organisms/vc-login-form/vc-login-form.vue +48 -0
  220. package/ui/components/organisms/vc-popup/vc-popup.stories.ts +23 -0
  221. package/ui/components/organisms/vc-popup/vc-popup.vue +97 -0
  222. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +113 -0
  223. package/ui/components/organisms/vc-table/_internal/vc-table-counter/vc-table-counter.vue +29 -0
  224. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +152 -0
  225. package/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +272 -0
  226. package/ui/components/organisms/vc-table/vc-table.stories.ts +99 -0
  227. package/ui/components/organisms/vc-table/vc-table.vue +638 -0
  228. package/ui/types/index.ts +38 -0
  229. package/ui/types/ts-helpers.ts +46 -0
  230. package/dist/components/atoms/vc-badge/vc-badge.stories.d.ts.map +0 -1
  231. package/dist/components/atoms/vc-button/vc-button.stories.d.ts.map +0 -1
  232. package/dist/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +0 -1
  233. package/dist/components/atoms/vc-container/vc-container.stories.d.ts.map +0 -1
  234. package/dist/components/atoms/vc-hint/vc-hint.stories.d.ts.map +0 -1
  235. package/dist/components/atoms/vc-icon/vc-icon.stories.d.ts.map +0 -1
  236. package/dist/components/atoms/vc-image/vc-image.stories.d.ts.map +0 -1
  237. package/dist/components/atoms/vc-label/vc-label.stories.d.ts.map +0 -1
  238. package/dist/components/atoms/vc-link/vc-link.stories.d.ts.map +0 -1
  239. package/dist/components/atoms/vc-progress/vc-progress.stories.d.ts.map +0 -1
  240. package/dist/components/atoms/vc-status/vc-status.stories.d.ts.map +0 -1
  241. package/dist/components/atoms/vc-switch/vc-switch.stories.d.ts.map +0 -1
  242. package/dist/components/index.d.ts.map +0 -1
  243. package/dist/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +0 -1
  244. package/dist/components/molecules/vc-form/vc-form.stories.d.ts.map +0 -1
  245. package/dist/components/molecules/vc-input/vc-input.stories.d.ts +0 -7
  246. package/dist/components/molecules/vc-input/vc-input.stories.d.ts.map +0 -1
  247. package/dist/components/molecules/vc-pagination/vc-pagination.stories.d.ts.map +0 -1
  248. package/dist/components/molecules/vc-rating/vc-rating.stories.d.ts.map +0 -1
  249. package/dist/components/molecules/vc-select/vc-select.stories.d.ts +0 -7
  250. package/dist/components/molecules/vc-select/vc-select.stories.d.ts.map +0 -1
  251. package/dist/components/molecules/vc-textarea/vc-textarea.stories.d.ts.map +0 -1
  252. package/dist/components/organisms/vc-app/vc-app.stories.d.ts.map +0 -1
  253. package/dist/components/organisms/vc-blade/vc-blade.stories.d.ts.map +0 -1
  254. package/dist/components/organisms/vc-login-form/vc-login-form.stories.d.ts.map +0 -1
  255. package/dist/components/organisms/vc-popup/vc-popup.stories.d.ts.map +0 -1
  256. package/dist/components/organisms/vc-table/vc-table.stories.d.ts.map +0 -1
@@ -0,0 +1,638 @@
1
+ <template>
2
+ <div class="tw-relative tw-overflow-hidden tw-flex tw-flex-col tw-grow tw-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="tw-shrink-0 tw-flex tw-items-center tw-justify-between tw-p-4">
15
+ <!-- Table filter mobile button -->
16
+ <div v-if="$isMobile.value && $slots['filters']" class="tw-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="tw-grow tw-basis-0"
27
+ :placeholder="searchPlaceholder"
28
+ clearable
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="tw-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= "tw-flex tw-relative tw-overflow-hidden tw-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="tw-grow tw-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] tw-border-collapse tw-relative tw-pt-[43px] tw-table-fixed tw-box-border tw-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="tw-h-[42px] tw-bg-[#f9f9f9] !tw-border-0 tw-shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] tw-box-border sticky tw-top-0 tw-select-none tw-overflow-hidden tw-z-[1]"
93
+ width="50"
94
+ >
95
+ <div class= "tw-flex tw-justify-center tw-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="tw-h-[42px] tw-bg-[#f9f9f9] !tw-border-0 tw-shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] tw-box-border sticky tw-top-0 tw-select-none tw-overflow-hidden tw-z-[1] tw-px-3"
107
+ :class="{
108
+ 'tw-cursor-pointer tw-group': item.sortable,
109
+ }"
110
+ :width="item.width"
111
+ @click="handleHeaderClick(item)"
112
+ >
113
+ <div
114
+ class= "tw-flex tw-items-center tw-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="tw-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= "tw-flex tw-flex-col tw-ml-1 tw-invisible group-hover:tw-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="tw-h-[42px] tw-bg-[#f9f9f9] !tw-border-0 tw-shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] tw-box-border sticky tw-top-0 tw-select-none tw-overflow-hidden tw-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 tw-h-[60px] tw-bg-white hover:tw-bg-[#dfeef9]"
150
+ :class="{
151
+ 'tw-cursor-pointer hover:tw-bg-[#dfeef9]': onItemClick,
152
+ 'tw-bg-[#f8f8f8]': i % 2 === 1,
153
+ '!tw-bg-[#dfeef9] hover:tw-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= "tw-flex tw-justify-center tw-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="tw-box-border tw-overflow-hidden tw-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="tw-box-border tw-overflow-visible tw-px-3"
182
+ width="44"
183
+ v-if="itemActionBuilder"
184
+ >
185
+ <div
186
+ class="vc-table__body-actions-container tw-relative !tw-hidden tw-justify-center tw-items-center"
187
+ >
188
+ <button
189
+ class="tw-text-[#319ed4] tw-cursor-pointer tw-border-none tw-bg-transparent disabled:tw-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 tw-bg-white tw-rounded-l-[4px] tw-p-[15px] tw-z-0 tw-absolute tw-right-0 tw-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= "tw-flex tw-items-center tw-flex-row tw-text-[#3f3f3f] tw-font-normal not-italic tw-text-base tw-leading-[20px] tw-gap-[25px]"
206
+ >
207
+ <div
208
+ v-for="(itemAction, i) in itemActions"
209
+ :key="i"
210
+ :class="[
211
+ 'tw-flex tw-flex-row tw-items-center tw-text-[#319ed4] tw-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="tw-not-italic tw-font-normal tw-text-base tw-leading-[20px] tw-text-[#3f3f3f] tw-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="tw-w-full tw-h-full tw-box-border tw-flex tw-flex-col tw-items-center tw-justify-center"
245
+ >
246
+ <img v-if="notfound.image" :src="notfound.image" />
247
+ <div class="tw-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="tw-w-full tw-h-full tw-box-border tw-flex tw-flex-col tw-items-center tw-justify-center"
259
+ >
260
+ <img v-if="empty.image" :src="empty.image" />
261
+ <div class="tw-m-4 tw-text-xl tw-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="tw-bg-[#fbfdfe] tw-border-t tw-border-solid tw-border-[#eaedf3] tw-flex-shrink-0 tw-flex tw-items-center tw-justify-between tw-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 "@/ui/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 tw-flex #{!important};
610
+ }
611
+
612
+ &-actions-item {
613
+ @each $name, $variant in $variants {
614
+ &_#{$name} {
615
+ @apply tw-text-[#{$variant}];
616
+ }
617
+ }
618
+ }
619
+
620
+ &-tooltip-arrow,
621
+ &-tooltip-arrow:before {
622
+ @apply tw-absolute tw-w-2 tw-h-2 tw-bg-inherit;
623
+ }
624
+
625
+ &-tooltip-arrow {
626
+ @apply tw-invisible before:tw-visible before:tw-content-[""] before:tw-rotate-45;
627
+ }
628
+
629
+ &-tooltip[data-popper-placement^="top"] > .vc-table__body-tooltip-arrow {
630
+ @apply tw-bottom-[-5px];
631
+ }
632
+
633
+ &-tooltip[data-popper-placement^="bottom"] > .vc-table__body-tooltip-arrow {
634
+ @apply tw-top-[-5px];
635
+ }
636
+ }
637
+ }
638
+ </style>
@@ -0,0 +1,38 @@
1
+ import { GlobalComponentConstructor } from "./ts-helpers";
2
+ import {
3
+ VcInputEmits,
4
+ VcInputProps,
5
+ VcInputSlots,
6
+ } from "../components/molecules/vc-input/vc-input-model";
7
+ import {
8
+ VcSelectEmits,
9
+ VcSelectProps,
10
+ VcSelectSlots,
11
+ } from "../components/molecules/vc-select/vc-select-model";
12
+ import {
13
+ VcInputCurrencyProps,
14
+ VcInputCurrencyEmits,
15
+ VcInputCurrencySlots,
16
+ } from "@/ui/components/molecules/vc-input-currency/vc-input-currency-model";
17
+
18
+ declare module "@vue/runtime-core" {
19
+ interface GlobalComponents {
20
+ VcInput: GlobalComponentConstructor<
21
+ VcInputProps,
22
+ VcInputSlots,
23
+ VcInputEmits
24
+ >;
25
+ VcInputCurrency: GlobalComponentConstructor<
26
+ VcInputCurrencyProps,
27
+ VcInputCurrencySlots,
28
+ VcInputCurrencyEmits
29
+ >;
30
+ VcSelect: GlobalComponentConstructor<
31
+ VcSelectProps,
32
+ VcSelectSlots,
33
+ VcSelectEmits
34
+ >;
35
+ }
36
+ }
37
+
38
+ export {};