@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,186 @@
1
+ <template>
2
+ <div class="vc-gallery">
3
+ <VcLabel
4
+ v-if="label"
5
+ :tooltip="tooltip"
6
+ :required="required"
7
+ :tooltip-icon="tooltipIcon"
8
+ >
9
+ {{ label }}
10
+ </VcLabel>
11
+
12
+ <template v-if="(images && images.length) || !disabled">
13
+ <div class= "tw-flex tw-flex-wrap">
14
+ <draggable
15
+ :list="images"
16
+ class= "tw-flex tw-flex-wrap tw-w-full"
17
+ tag="transition-group"
18
+ v-bind="dragOptions"
19
+ @change="updateOrder"
20
+ :component-data="{
21
+ tag: 'div',
22
+ }"
23
+ >
24
+ <template #item="{ element, index }">
25
+ <VcGalleryItem
26
+ class="tw-m-2"
27
+ :key="element.sortOrder"
28
+ :image="element"
29
+ :readonly="disabled"
30
+ @preview="onPreviewClick(index)"
31
+ @edit="$emit('item:edit', $event)"
32
+ @remove="$emit('item:remove', $event)"
33
+ :actions="itemActions"
34
+ :disableDrag="disableDrag"
35
+ ></VcGalleryItem>
36
+ </template>
37
+ <template #footer>
38
+ <VcFileUpload
39
+ v-if="!disabled && !hideAfterUpload"
40
+ class="tw-m-2"
41
+ :icon="uploadIcon"
42
+ @upload="onUpload"
43
+ :variant="variant"
44
+ :multiple="multiple"
45
+ :rules="rules"
46
+ :name="name"
47
+ ></VcFileUpload>
48
+ </template>
49
+ </draggable>
50
+ </div>
51
+ </template>
52
+ <div v-else class= "tw-flex tw-justify-center tw-p-5">
53
+ <VcHint>Gallery is empty</VcHint>
54
+ </div>
55
+
56
+ <VcGalleryPreview
57
+ v-if="preview"
58
+ :images="images"
59
+ :index="previewImageIndex"
60
+ @close="preview = false"
61
+ ></VcGalleryPreview>
62
+ </div>
63
+ </template>
64
+
65
+ <script lang="ts" setup>
66
+ import { computed, PropType, ref } from "vue";
67
+ import { VcLabel, VcFileUpload } from "@/ui/components";
68
+ import VcGalleryItem from "./_internal/vc-gallery-item/vc-gallery-item.vue";
69
+ import VcGalleryPreview from "./_internal/vc-gallery-preview/vc-gallery-preview.vue";
70
+ import { IImage } from "@/core/types";
71
+
72
+ const props = defineProps({
73
+ images: {
74
+ type: Array as PropType<IImage[]>,
75
+ default: () => [],
76
+ },
77
+
78
+ disabled: {
79
+ type: Boolean,
80
+ default: false,
81
+ },
82
+
83
+ required: {
84
+ type: Boolean,
85
+ default: false,
86
+ },
87
+
88
+ label: {
89
+ type: String,
90
+ default: undefined,
91
+ },
92
+
93
+ tooltip: {
94
+ type: String,
95
+ default: undefined,
96
+ },
97
+
98
+ tooltipIcon: {
99
+ type: String,
100
+ default: "fas fa-info",
101
+ },
102
+
103
+ uploadIcon: {
104
+ type: String,
105
+ default: "fas fa-upload",
106
+ },
107
+
108
+ multiple: {
109
+ type: Boolean,
110
+ default: false,
111
+ },
112
+
113
+ variant: {
114
+ type: String,
115
+ default: "gallery",
116
+ },
117
+
118
+ itemActions: {
119
+ type: Object,
120
+ default: () => ({
121
+ preview: true,
122
+ edit: true,
123
+ remove: true,
124
+ }),
125
+ },
126
+
127
+ disableDrag: {
128
+ type: Boolean,
129
+ default: false,
130
+ },
131
+
132
+ hideAfterUpload: {
133
+ type: Boolean,
134
+ default: false,
135
+ },
136
+
137
+ rules: {
138
+ type: [String, Object],
139
+ },
140
+
141
+ name: {
142
+ type: String,
143
+ default: "Gallery",
144
+ },
145
+ });
146
+
147
+ const emit = defineEmits([
148
+ "upload",
149
+ "sort",
150
+ "item:preview",
151
+ "item:edit",
152
+ "item:remove",
153
+ "item:move",
154
+ ]);
155
+
156
+ const preview = ref(false);
157
+ const previewImageIndex = ref();
158
+ const dragOptions = computed(() => {
159
+ return {
160
+ animation: 200,
161
+ group: "description",
162
+ disabled: props.disableDrag,
163
+ ghostClass: "ghost",
164
+ };
165
+ });
166
+
167
+ const onUpload = (files: FileList) => {
168
+ if (files && files.length) {
169
+ emit("upload", files);
170
+ }
171
+ };
172
+
173
+ const onPreviewClick = (index: number) => {
174
+ preview.value = true;
175
+ previewImageIndex.value = index;
176
+ };
177
+
178
+ const updateOrder = () => {
179
+ const images = props.images;
180
+ const sortedImgs = images.map((item, index) => {
181
+ item.sortOrder = index;
182
+ return item;
183
+ });
184
+ emit("sort", ref(sortedImgs).value);
185
+ };
186
+ </script>
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Login Form component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcLoginForm from "./vc-login-form.vue";
7
+ import VcInput from "../../molecules/vc-input/vc-input.vue";
8
+ import VcButton from "../../atoms/vc-button/vc-button.vue";
9
+
10
+ export default {
11
+ title: "organisms/vc-login-form",
12
+ component: VcLoginForm,
13
+ };
14
+
15
+ const Template: Story = (args) => ({
16
+ components: { VcLoginForm, VcInput, VcButton },
17
+ setup() {
18
+ return { args };
19
+ },
20
+ template: `<vc-login-form v-bind="args">
21
+ <vc-input
22
+ ref="loginField"
23
+ class="tw-mb-4 tw-mt-1"
24
+ label="Username"
25
+ placeholder="Enter username"
26
+ ></vc-input>
27
+ <vc-input
28
+ ref="passwordField"
29
+ class="tw-mb-4"
30
+ label="Password"
31
+ placeholder="Enter password"
32
+ type="password"
33
+ ></vc-input>
34
+ <div
35
+ class="
36
+ flex
37
+ tw-justify-center
38
+ tw-items-center
39
+ tw-pt-2
40
+ "
41
+ >
42
+ <span class="tw-grow tw-basis-0"></span>
43
+ <vc-button variant="primary">
44
+ Submit
45
+ </vc-button>
46
+ </div>
47
+ </vc-login-form>`,
48
+ });
49
+
50
+ export const LoginForm = Template.bind({});
51
+ LoginForm.storyName = "vc-login-form";
52
+ LoginForm.args = {
53
+ background: "images/background.jpg",
54
+ logo: "images/logo-white.svg",
55
+ };
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <div
3
+ class="tw-w-full tw-h-full tw-box-border tw-flex tw-flex-col tw-items-center tw-justify-center"
4
+ :style="{
5
+ background: `url(${background}) center / cover no-repeat`,
6
+ }"
7
+ >
8
+ <div
9
+ class="tw-h-[80px] tw-w-[516px] tw-max-w-[90%] tw-mb-[50px] -tw-mt-[90px]"
10
+ :style="{
11
+ background: `url(${logo}) center / contain no-repeat`,
12
+ }"
13
+ ></div>
14
+ <div
15
+ class="tw-w-[516px] tw-max-w-[90%] tw-bg-white tw-rounded-md tw-overflow-hidden tw-shadow-[0_0_0_rgba(0,0,0,0.05)]"
16
+ >
17
+ <div
18
+ class="tw-uppercase tw-text-white tw-bg-[#465769] tw-h-[50px] tw-px-[28px] tw-text-xl tw-flex tw-items-center"
19
+ >
20
+ {{ title }}
21
+ </div>
22
+ <div class="tw-pt-4 tw-px-[28px] tw-pb-[24px]">
23
+ <slot></slot>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script lang="ts" setup>
30
+ defineProps({
31
+ logo: {
32
+ type: String,
33
+ default: undefined,
34
+ },
35
+
36
+ background: {
37
+ type: String,
38
+ default: undefined,
39
+ },
40
+
41
+ title: {
42
+ type: String,
43
+ default: "Login",
44
+ },
45
+ });
46
+
47
+ console.debug("Init vc-login-form");
48
+ </script>
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Popup component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcPopup from "./vc-popup.vue";
7
+
8
+ export default {
9
+ title: "organisms/vc-popup",
10
+ component: VcPopup,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcPopup },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-popup v-bind="args"></vc-popup>',
19
+ });
20
+
21
+ export const Popup = Template.bind({});
22
+ Popup.storyName = "vc-popup";
23
+ Popup.args = {};
@@ -0,0 +1,97 @@
1
+ <template>
2
+ <div class="vc-popup" :class="`vc-popup_${variant}`">
3
+ <div class="vc-popup__wrapper">
4
+ <div class="vc-popup__inner">
5
+ <div class="vc-popup__header">
6
+ <div class="tw-truncate tw-grow tw-basis-0">
7
+ <slot name="title">{{ title }}</slot>
8
+ </div>
9
+ <VcIcon
10
+ v-if="closable"
11
+ class="vc-popup__header-icon"
12
+ icon="fas fa-times"
13
+ @click="$emit('close')"
14
+ ></VcIcon>
15
+ </div>
16
+
17
+ <div class="vc-popup__content tw-grow tw-basis-0">
18
+ <slot></slot>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script lang="ts" setup>
26
+ defineProps({
27
+ title: {
28
+ type: String,
29
+ default: undefined,
30
+ },
31
+
32
+ closable: {
33
+ type: Boolean,
34
+ default: true,
35
+ },
36
+
37
+ variant: {
38
+ type: String,
39
+ default: "fullscreen",
40
+ enum: ["small", "medium", "fullscreen"],
41
+ },
42
+ });
43
+
44
+ defineEmits(["close"]);
45
+ </script>
46
+
47
+ <style lang="scss">
48
+ .vc-popup {
49
+ @apply tw-fixed tw-top-0 tw-right-0 tw-bottom-0 tw-left-0 tw-z-[9999] tw-bg-[rgba(31,40,50,0.58)];
50
+
51
+ &_small {
52
+ .vc-popup__wrapper {
53
+ @apply tw-max-h-fit tw-items-center tw-flex tw-grow-0 tw-shrink-0 tw-basis-auto [flex-direction:inherit] tw-justify-center;
54
+ }
55
+
56
+ .vc-popup__inner {
57
+ @apply tw-max-w-[439px] tw-w-full tw-flex tw-flex-col tw-grow tw-basis-0;
58
+ }
59
+ }
60
+
61
+ &_medium {
62
+ .vc-popup__wrapper {
63
+ @apply tw-max-h-[75vh];
64
+ }
65
+ }
66
+
67
+ &_fullscreen {
68
+ .vc-popup__wrapper {
69
+ @apply tw-max-h-[100vh];
70
+ }
71
+ }
72
+
73
+ &__wrapper {
74
+ @apply tw-fixed tw-top-2/4 -tw-translate-y-2/4 tw-right-0 tw-bottom-0 tw-left-0 tw-flex tw-grow tw-shrink tw-basis-auto tw-flex-col tw-h-full;
75
+
76
+ .vc-app_phone & {
77
+ @apply tw-max-h-[100vh];
78
+ }
79
+ }
80
+
81
+ &__inner {
82
+ @apply tw-grow tw-shrink tw-basis-auto tw-m-[40px] tw-box-border tw-bg-white tw-rounded-[5px] tw-overflow-hidden tw-relative tw-flex tw-flex-col tw-grow tw-basis-0;
83
+
84
+ .vc-app_phone & {
85
+ @apply tw-m-0 tw-rounded-none;
86
+ }
87
+ }
88
+
89
+ &__header {
90
+ @apply tw-h-[44px] tw-px-4 tw-bg-[#eef5fa] tw-flex tw-shrink-0 tw-items-center;
91
+
92
+ &-icon {
93
+ @apply tw-cursor-pointer tw-text-[#a1c0d4];
94
+ }
95
+ }
96
+ }
97
+ </style>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <!-- Money cell -->
3
+ <template v-if="cell.type === 'money'">
4
+ <template v-if="value > 0">
5
+ <span>{{ Math.trunc(Number(value)) }}</span
6
+ ><span class="tw-text-[#a5a5a5] tw-text-xs"
7
+ >.{{
8
+ `${(Number(value) * 100) % 100}`.padEnd(2, "0").slice(0, 2)
9
+ }}</span
10
+ >
11
+ </template>
12
+ <template v-else>
13
+ <span>N/A</span>
14
+ </template>
15
+ </template>
16
+
17
+ <!-- Date ago cell -->
18
+ <span v-else-if="cell.type === 'date-ago'" class="tw-text-[#a5a5a5]">
19
+ <template v-if="value">
20
+ {{ moment(value).fromNow() }}
21
+ </template>
22
+ <template v-else>N/A</template>
23
+ </span>
24
+
25
+ <!-- Date exact cell -->
26
+ <span
27
+ v-else-if="
28
+ cell.type === 'date' || cell.type === 'time' || cell.type === 'date-time'
29
+ "
30
+ class="tw-text-[#a5a5a5]"
31
+ >
32
+ <template v-if="value">
33
+ <template v-if="cell.format">
34
+ {{ moment(value).locale(locale).format(cell.format) }}
35
+ </template>
36
+ <template v-else>
37
+ <template v-if="cell.type === 'date'">{{
38
+ value.toLocaleDateString()
39
+ }}</template>
40
+ <template v-if="cell.type === 'time'">{{
41
+ value.toLocaleTimeString()
42
+ }}</template>
43
+ <template v-if="cell.type === 'date-time'">{{
44
+ value.toLocaleString()
45
+ }}</template>
46
+ </template>
47
+ </template>
48
+ <template v-else>N/A</template>
49
+ </span>
50
+
51
+ <!-- Image cell -->
52
+ <template v-else-if="cell.type === 'image'">
53
+ <VcImage
54
+ :bordered="true"
55
+ size="s"
56
+ aspect="1x1"
57
+ :src="value"
58
+ background="contain"
59
+ />
60
+ </template>
61
+
62
+ <!-- Status cell -->
63
+ <template v-else-if="cell.type === 'status'">
64
+ <VcStatus>{{ value }}</VcStatus>
65
+ </template>
66
+
67
+ <!-- Status icon cell -->
68
+ <div v-else-if="cell.type === 'status-icon'" class= "tw-flex tw-justify-center">
69
+ <VcStatusIcon :status="value"></VcStatusIcon>
70
+ </div>
71
+
72
+ <!-- Number cell -->
73
+ <span v-else-if="cell.type === 'number'" class="tw-text-right">
74
+ {{ Number(value).toFixed(0) }}
75
+ </span>
76
+
77
+ <!-- Link cell -->
78
+ <template v-else-if="cell.type === 'link'">
79
+ <VcLink>{{ value }}</VcLink>
80
+ </template>
81
+
82
+ <!-- Default cell -->
83
+ <span v-else>
84
+ {{ value }}
85
+ </span>
86
+ </template>
87
+
88
+ <script lang="ts" setup>
89
+ import { computed } from "vue";
90
+ import moment from "moment";
91
+ import { ITableColumns } from "@/core/types";
92
+ import { VcImage, VcStatus, VcStatusIcon, VcLink } from "@/ui/components";
93
+
94
+ export interface Props {
95
+ cell: ITableColumns;
96
+ item: Record<string, unknown>;
97
+ }
98
+
99
+ const props = withDefaults(defineProps<Props>(), {
100
+ cell: undefined,
101
+ item: undefined,
102
+ });
103
+
104
+ const locale = window.navigator.language;
105
+ const value = computed(() =>
106
+ (props.cell.field || props.cell.id)
107
+ .split(".")
108
+ .reduce(
109
+ (p: { [x: string]: unknown }, c: string) => (p && p[c]) || null,
110
+ props.item
111
+ )
112
+ );
113
+ </script>
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <div class="tw-font-medium tw-text-base">
3
+ <span class="tw-text-[color:var(--table-counter-label-color)]"
4
+ >{{ label }}&nbsp;</span
5
+ >
6
+ <span class="tw-text-[color:var(--table-counter-value-color)]">{{
7
+ value
8
+ }}</span>
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ export interface Props {
14
+ label: string;
15
+ value: number;
16
+ }
17
+
18
+ withDefaults(defineProps<Props>(), {
19
+ label: "Total",
20
+ value: 0,
21
+ });
22
+ </script>
23
+
24
+ <style lang="scss">
25
+ :root {
26
+ --table-counter-label-color: #465769;
27
+ --table-counter-value-color: #43b0e6;
28
+ }
29
+ </style>
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <div class="tw-relative tw-overflow-visible">
3
+ <!-- Filter button -->
4
+ <div
5
+ class="tw-rounded-[3px] tw-bg-[#43b0e6] tw-flex tw-items-center tw-px-[10px] tw-text-white tw-h-[38px] tw-box-border tw-cursor-pointer"
6
+ @click="openPanel($isMobile.value)"
7
+ ref="filterToggle"
8
+ >
9
+ <VcIcon icon="fas fa-filter" size="m" />
10
+ <span v-if="title" class="tw-ml-[10px] tw-font-medium">
11
+ {{ title }}
12
+ </span>
13
+ <div
14
+ v-if="counter"
15
+ class="tw-ml-[10px] tw-rounded-[10px] tw-bg-white tw-text-[#43b0e6] tw-h-[20px] tw-min-w-[20px] tw-leading-[20px] tw-text-center tw-font-medium"
16
+ >
17
+ {{ counter }}
18
+ </div>
19
+ </div>
20
+
21
+ <!-- Filter panel -->
22
+ <teleport to="body">
23
+ <div
24
+ :class="{
25
+ 'vc-table-filter__panel_mobile tw-fixed tw-left-0 tw-top-0 tw-w-full tw-bottom-0 tw-z-[9999] tw-bg-[rgba(128,140,153,0.6)] tw-shadow-none tw-rounded-none tw-max-h-full tw-max-w-full tw-min-w-full':
26
+ $isMobile.value,
27
+ 'vc-table-filter__panel tw-absolute tw-max-h-[400px] tw-max-w-[800px] tw-min-w-[400px] tw-z-[100] tw-shadow-[1px_1px_11px_rgba(141,152,163,0.6)] tw-rounded-[3px] tw-overflow-hidden':
28
+ !$isMobile.value,
29
+ }"
30
+ v-if="isPanelVisible"
31
+ @click.self="closePanel"
32
+ ref="filterPanel"
33
+ >
34
+ <div
35
+ class="vc-table-filter__panel-inner tw-bg-white tw-box-border tw-p-5 tw-flex tw-flex-col"
36
+ @click.stop
37
+ >
38
+ <VcIcon
39
+ class="vc-table-filter__panel-close tw-text-[#43b0e6] tw-cursor-pointer tw-self-end tw-shrink-0"
40
+ icon="fas fa-times"
41
+ size="xl"
42
+ @click="closePanel"
43
+ />
44
+
45
+ <slot :closePanel="closePanel"></slot>
46
+ </div>
47
+ </div>
48
+ </teleport>
49
+ </div>
50
+ </template>
51
+
52
+ <script lang="ts">
53
+ import { defineComponent, nextTick, ref, watch } from "vue";
54
+
55
+ export default defineComponent({
56
+ inheritAttrs: false,
57
+ });
58
+ </script>
59
+
60
+ <script lang="ts" setup>
61
+ import { createPopper, Instance } from "@popperjs/core";
62
+ import { VcIcon } from "@/ui/components";
63
+
64
+ export interface Props {
65
+ title: string;
66
+ counter: number;
67
+ parentExpanded?: boolean;
68
+ }
69
+
70
+ const props = withDefaults(defineProps<Props>(), {
71
+ title: undefined,
72
+ counter: 0,
73
+ parentExpanded: true,
74
+ });
75
+
76
+ const isPanelVisible = ref(false);
77
+ const filterToggle = ref();
78
+ const filterPanel = ref();
79
+ const popper = ref<Instance>();
80
+
81
+ watch(
82
+ () => props.parentExpanded,
83
+ () => {
84
+ closePanel();
85
+ }
86
+ );
87
+
88
+ function openPanel(isMobile: boolean) {
89
+ isPanelVisible.value = !isPanelVisible.value;
90
+
91
+ if (!isMobile) {
92
+ const element = document.querySelector(".vc-blade");
93
+ if (isPanelVisible.value) {
94
+ nextTick(() => {
95
+ popper.value = createPopper(filterToggle.value, filterPanel.value, {
96
+ placement: "bottom-end",
97
+ modifiers: [
98
+ {
99
+ name: "offset",
100
+ options: {
101
+ offset: [0, 10],
102
+ },
103
+ },
104
+ {
105
+ name: "preventOverflow",
106
+ options: {
107
+ boundary: element,
108
+ },
109
+ },
110
+ ],
111
+ });
112
+ });
113
+ } else {
114
+ destroyPopper();
115
+ }
116
+ }
117
+ }
118
+
119
+ function closePanel() {
120
+ isPanelVisible.value = false;
121
+ destroyPopper();
122
+ }
123
+
124
+ function destroyPopper() {
125
+ // To prevent memory leaks Popper needs to be destroyed.
126
+ popper.value?.destroy();
127
+ }
128
+ </script>
129
+
130
+ <style lang="scss">
131
+ .vc-table-filter {
132
+ @apply tw-relative tw-overflow-visible;
133
+
134
+ &__panel {
135
+ &_mobile {
136
+ .vc-table-filter__panel {
137
+ &-inner {
138
+ @apply tw-w-[280px] tw-h-full;
139
+ }
140
+
141
+ &-close {
142
+ @apply tw-self-start;
143
+ }
144
+ }
145
+
146
+ .vc-row {
147
+ @apply tw-block;
148
+ }
149
+ }
150
+ }
151
+ }
152
+ </style>