@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,216 @@
1
+ import { computed, ref, unref, watch, Ref } from "vue";
2
+ import { isEqual } from "lodash-es";
3
+ import { useRouter, useRoute, NavigationFailure } from "vue-router";
4
+ import { usePermissions } from "@/core/composables";
5
+ import {
6
+ ExtendedComponent,
7
+ IBladeContainer,
8
+ IBladeElement,
9
+ IBladeEvent,
10
+ IParentCallArgs,
11
+ } from "@/shared";
12
+
13
+ interface IUseBladeNavigation {
14
+ readonly blades: Ref<IBladeContainer[]>;
15
+ readonly parentBladeOptions: Ref<Record<string, unknown>>;
16
+ readonly parentBladeParam: Ref<string>;
17
+ bladesRefs: Ref<IBladeElement[]>;
18
+ openBlade: (
19
+ {
20
+ parentBlade,
21
+ component,
22
+ param,
23
+ bladeOptions,
24
+ onOpen,
25
+ onClose,
26
+ }: IBladeEvent,
27
+ index?: number,
28
+ navigationCb?: () => Promise<void | NavigationFailure>
29
+ ) => void;
30
+ closeBlade: (index: number) => void;
31
+ onParentCall: (index: number, args: IParentCallArgs) => void;
32
+ }
33
+
34
+ const blades = ref<IBladeContainer[]>([]);
35
+ const bladesRefs = ref<IBladeElement[]>([]);
36
+ const parentBladeOptions = ref<Record<string, unknown>>();
37
+ const parentBladeParam = ref<string>();
38
+
39
+ export default (): IUseBladeNavigation => {
40
+ const router = useRouter();
41
+ const route = useRoute();
42
+ const { checkPermission } = usePermissions();
43
+ const isPrevented = ref(false);
44
+
45
+ watch(
46
+ () => blades.value,
47
+ (newVal) => {
48
+ const lastBlade = newVal[newVal.length - 1];
49
+
50
+ if (lastBlade && lastBlade.component.url) {
51
+ if (lastBlade.param) {
52
+ addEntryToLocation(lastBlade.component.url + "/" + lastBlade.param);
53
+ } else {
54
+ addEntryToLocation(lastBlade.component.url);
55
+ }
56
+ } else if (!lastBlade) {
57
+ addEntryToLocation(route.path);
58
+ }
59
+ },
60
+ { deep: true }
61
+ );
62
+
63
+ async function openBlade(
64
+ {
65
+ parentBlade,
66
+ component: blade,
67
+ param,
68
+ bladeOptions,
69
+ onOpen,
70
+ onClose,
71
+ }: IBladeEvent,
72
+ index?: number,
73
+ navigationCb?: () => Promise<void | NavigationFailure>
74
+ ) {
75
+ console.debug(`openBlade(${1}) called.`);
76
+
77
+ const parent = unref(parentBlade);
78
+ const child = unref(blade);
79
+ const existingChild = findBlade(child);
80
+
81
+ if (parent && parent.url) {
82
+ await closeBlade(0);
83
+
84
+ if (!isPrevented.value) {
85
+ parentBladeOptions.value = unref(bladeOptions);
86
+ parentBladeParam.value = unref(param);
87
+ if (navigationCb && typeof navigationCb === "function") {
88
+ try {
89
+ await navigationCb();
90
+ } catch (e) {
91
+ console.log(e);
92
+ } finally {
93
+ console.debug(`Navigated to: ${parent.url}`);
94
+ }
95
+ } else if (!navigationCb) {
96
+ await router.push(parent.url);
97
+ }
98
+ }
99
+ }
100
+
101
+ if (child) {
102
+ if (existingChild === undefined) {
103
+ child.idx = index + 1;
104
+ } else if (existingChild) {
105
+ await closeBlade(
106
+ blades.value.findIndex((x) => x.idx === existingChild.idx)
107
+ );
108
+ child.idx = existingChild.idx;
109
+ }
110
+
111
+ await addBlade(child, param, bladeOptions, onOpen, onClose, index);
112
+ }
113
+ }
114
+
115
+ async function closeBlade(index: number) {
116
+ if (index < bladesRefs.value.length) {
117
+ const children = bladesRefs.value.slice(index).reverse();
118
+
119
+ isPrevented.value = false;
120
+ for (let i = 0; i < children.length; i++) {
121
+ if (
122
+ children[i]?.onBeforeClose &&
123
+ typeof children[i].onBeforeClose === "function"
124
+ ) {
125
+ const result = await children[i].onBeforeClose();
126
+ if (result === false) {
127
+ isPrevented.value = true;
128
+ break;
129
+ }
130
+ }
131
+ }
132
+ if (!isPrevented.value) {
133
+ if (typeof blades.value[index]?.onClose === "function") {
134
+ blades.value[index]?.onClose?.();
135
+ }
136
+ blades.value.splice(index);
137
+ } else {
138
+ throw "Closing prevented";
139
+ }
140
+ }
141
+ }
142
+
143
+ async function addBlade(
144
+ blade: ExtendedComponent,
145
+ param: string,
146
+ bladeOptions: Record<string, unknown>,
147
+ onOpen: () => void,
148
+ onClose: () => void,
149
+ index: number
150
+ ) {
151
+ if (blades.value.length > index) {
152
+ await closeBlade(index);
153
+ }
154
+
155
+ if (blade && checkPermission(blade.permissions)) {
156
+ blades.value.push({
157
+ component: blade,
158
+ bladeOptions,
159
+ param,
160
+ onOpen,
161
+ onClose,
162
+ idx: blade.idx,
163
+ });
164
+
165
+ if (onOpen && typeof onOpen === "function") {
166
+ onOpen();
167
+ }
168
+ } else {
169
+ // TODO temporary access alert
170
+ alert("Access restricted");
171
+ }
172
+ }
173
+
174
+ async function onParentCall(index: number, args: IParentCallArgs) {
175
+ console.debug(
176
+ `vc-app#onParentCall(${index}, { method: ${args.method} }) called.`
177
+ );
178
+
179
+ if (index >= 0) {
180
+ const currentParent = unref(bladesRefs.value[index]);
181
+
182
+ if (currentParent) {
183
+ if (args.method && typeof currentParent[args.method] === "function") {
184
+ const method = currentParent[args.method] as (
185
+ args: unknown
186
+ ) => Promise<unknown>;
187
+ const result = await method(args.args);
188
+ if (typeof args.callback === "function") {
189
+ args.callback(result);
190
+ }
191
+ } else {
192
+ // TODO temporary alert
193
+ console.error(`No such method: ${args.method}.`);
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ function addEntryToLocation(params: string) {
200
+ history.pushState({}, null, "#" + params);
201
+ }
202
+
203
+ function findBlade(blade: ExtendedComponent) {
204
+ return blades.value.find((x) => isEqual(x.component, blade));
205
+ }
206
+
207
+ return {
208
+ blades: computed(() => blades.value),
209
+ parentBladeOptions: computed(() => parentBladeOptions.value),
210
+ parentBladeParam: computed(() => parentBladeParam.value),
211
+ bladesRefs,
212
+ openBlade,
213
+ closeBlade,
214
+ onParentCall,
215
+ };
216
+ };
@@ -0,0 +1,15 @@
1
+ import { App } from "vue";
2
+ import * as components from "./components";
3
+
4
+ export default {
5
+ install(app: App): void {
6
+ // Register exported pages
7
+ Object.entries(components).forEach(([componentName, component]) => {
8
+ app.component(componentName, component);
9
+ });
10
+ },
11
+ };
12
+
13
+ export * from "./components";
14
+ export * from "./composables";
15
+ export * from './types'
@@ -0,0 +1,52 @@
1
+ import { Component, ComponentPublicInstance } from "vue";
2
+ import { IMenuItems } from "@/core/types";
3
+ import { NavigationFailure } from "vue-router";
4
+
5
+ /* onParentCall event interface */
6
+ export interface IParentCallArgs {
7
+ method: string;
8
+ args?: unknown;
9
+ callback?: (args: unknown) => void;
10
+ }
11
+
12
+ /* extended component */
13
+ export type ExtendedComponent = Component & {
14
+ url?: string;
15
+ permissions?: string | string[];
16
+ idx?: number;
17
+ };
18
+
19
+ /* blade interface for navigation */
20
+ export interface IBladeContainer extends IBladeEvent {
21
+ idx?: number;
22
+ }
23
+
24
+ /* blade exposed methods */
25
+ export interface IBladeElement extends ComponentPublicInstance {
26
+ onBeforeClose?: () => Promise<boolean>;
27
+ title?: string;
28
+ reloadParent?: () => void;
29
+ openDashboard?: () => void;
30
+ }
31
+
32
+ /* emitted blade event */
33
+ export interface IBladeEvent {
34
+ parentBlade?: ExtendedComponent;
35
+ component?: ExtendedComponent;
36
+ bladeOptions?: Record<string, unknown>;
37
+ param?: string;
38
+ onOpen?: () => void;
39
+ onClose?: () => void;
40
+ }
41
+
42
+ /* menu item event */
43
+ export interface IMenuClickEvent {
44
+ item: IMenuItems;
45
+ navigationCb: () => Promise<void | NavigationFailure>;
46
+ }
47
+
48
+ /* openBlade args interface */
49
+ export interface IOpenBlade extends IBladeEvent {
50
+ id?: number;
51
+ navigationCb?: () => Promise<void | NavigationFailure>;
52
+ }
@@ -0,0 +1,16 @@
1
+ import { App } from "vue";
2
+ import { default as AssetsDetails } from "./assets";
3
+ import { default as VcAppSwitcher } from "./app-switcher";
4
+ import { default as VcBladeNavigation } from "./blade-navigation";
5
+
6
+ const components = [AssetsDetails, VcAppSwitcher, VcBladeNavigation];
7
+
8
+ export function init(app: App): App {
9
+ components.forEach((component) => app.use(component));
10
+
11
+ return app;
12
+ }
13
+
14
+ export * from "./assets";
15
+ export * from "./app-switcher";
16
+ export * from "./blade-navigation";
@@ -1,6 +1,7 @@
1
1
  /** @type { import('tailwindcss').Config } */
2
2
  module.exports = {
3
- content: ["./components/**/*.{vue,js,ts,jsx,tsx}"],
3
+ prefix: 'tw-',
4
+ content: ["./ui/components/**/*.{vue,js,ts,jsx,tsx}"],
4
5
  theme: {
5
6
  fontFamily: {
6
7
  roboto: ["Roboto", "sans-serif"],
@@ -37,12 +38,12 @@ module.exports = {
37
38
  to: {
38
39
  "background-position": '30px 0, left'
39
40
  }
40
- }
41
+ },
41
42
  },
42
43
  animation: {
43
44
  loadingMarker: "loadingMarker 3s infinite",
44
45
  loadingMarkers: "loadingMarkers 3s infinite",
45
- loadingProgress: "loadingProgress 1s linear infinite"
46
+ loadingProgress: "loadingProgress 1s linear infinite",
46
47
  }
47
48
  },
48
49
  },
@@ -0,0 +1,7 @@
1
+ import { ComponentPublicInstance } from "vue";
2
+ import { VcBadgeProps } from "./vc-badge-model";
3
+ import { ComponentConstructor } from "@/ui/types/ts-helpers";
4
+ import Badge from "./vc-badge.vue";
5
+ export const VcBadge: ComponentConstructor<
6
+ ComponentPublicInstance<VcBadgeProps>
7
+ > = Badge;
@@ -0,0 +1,30 @@
1
+ import { VNode } from "vue";
2
+
3
+ export interface VcBadgeProps {
4
+ /**
5
+ * Badge active state
6
+ * */
7
+ active?: boolean | undefined;
8
+ /**
9
+ * Put component in disabled state
10
+ * */
11
+ disabled?: boolean | undefined;
12
+ /**
13
+ * Is badge clickable?
14
+ * */
15
+ clickable?: boolean | undefined;
16
+ }
17
+
18
+ export interface VcBadgeEmits {
19
+ /**
20
+ * Emitted when component is clicked
21
+ * */
22
+ (event: "click"): void;
23
+ }
24
+
25
+ export interface VcBadgeSlots {
26
+ /**
27
+ * Slot for component content
28
+ * */
29
+ default: () => VNode[];
30
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Badge component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcBadge from "./vc-badge.vue";
7
+
8
+ export default {
9
+ title: "atoms/vc-badge",
10
+ component: VcBadge,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcBadge },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-badge v-bind="args">42</vc-badge>',
19
+ });
20
+
21
+ export const Badge = Template.bind({});
22
+ Badge.storyName = "vc-badge";
23
+ Badge.args = {
24
+ active: false,
25
+ disabled: false,
26
+ clickable: true,
27
+ };
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <div
3
+ class="tw-inline-block tw-rounded-[var(--badge-border-radius)] tw-py-1 tw-px-2 tw-text-base tw-font-normal tw-bg-[color:var(--badge-background-color)] tw-text-[color:var(--badge-text-color)] tw-border tw-border-solid tw-border-[color:var(--badge-border-color)] tw-transition tw-duration-200"
4
+ :class="{
5
+ 'tw-bg-[color:var(--badge-background-color-active)] tw-text-[color:var(--badge-text-color-active)] tw-border-[color:var(--badge-border-color-active)]':
6
+ active,
7
+ 'tw-cursor-pointer hover:tw-bg-[color:var(--badge-background-color-active)] hover:tw-text-[color:var(--badge-text-color-hover)] hover:tw-border-[color:var(--badge-border-color-hover)]':
8
+ clickable,
9
+ 'cursor-not-allowed tw-bg-[color:var(--badge-background-color-disabled)] tw-text-[color:var(--badge-text-color-disabled)] tw-border-[color:var(--badge-border-color-disabled)] hover:tw-bg-[color:var(--badge-background-color-disabled)] hover:tw-text-[color:var(--badge-text-color-disabled)] hover:tw-border-[color:var(--badge-border-color-disabled)]':
10
+ disabled,
11
+ }"
12
+ @click="onClick"
13
+ >
14
+ <slot name="default"></slot>
15
+ </div>
16
+ </template>
17
+
18
+ <script lang="ts" setup>
19
+ import {
20
+ VcBadgeEmits,
21
+ VcBadgeProps,
22
+ } from "@/ui/components/atoms/vc-badge/vc-badge-model";
23
+
24
+ const props = withDefaults(defineProps<VcBadgeProps>(), {
25
+ active: false,
26
+ disabled: false,
27
+ clickable: true,
28
+ });
29
+ const emit = defineEmits<VcBadgeEmits>();
30
+
31
+ function onClick(): void {
32
+ if (props.clickable && !props.disabled) {
33
+ emit("click");
34
+ }
35
+ }
36
+ </script>
37
+
38
+ <style lang="scss">
39
+ :root {
40
+ --badge-background-color: #ffffff;
41
+ --badge-background-color-hover: #fafafa;
42
+ --badge-background-color-active: #fafafa;
43
+ --badge-background-color-disabled: #f2f2f2;
44
+
45
+ --badge-text-color: #455668;
46
+ --badge-text-color-hover: #3b4959;
47
+ --badge-text-color-active: #3b4959;
48
+ --badge-text-color-disabled: #8296ab;
49
+
50
+ --badge-border-radius: 35px;
51
+
52
+ --badge-border-color: #a1bfd4;
53
+ --badge-border-color-hover: #8fb3cc;
54
+ --badge-border-color-active: #8fb3cc;
55
+ --badge-border-color-disabled: #b2cbdc;
56
+ }
57
+ </style>
@@ -0,0 +1,7 @@
1
+ import { ComponentPublicInstance } from "vue";
2
+ import { VcButtonProps } from "./vc-button-model";
3
+ import { ComponentConstructor } from "@/ui/types/ts-helpers";
4
+ import Button from "./vc-button.vue";
5
+ export const VcBadge: ComponentConstructor<
6
+ ComponentPublicInstance<VcButtonProps>
7
+ > = Button;
@@ -0,0 +1,30 @@
1
+ import { VNode } from "vue";
2
+
3
+ export interface VcButtonProps {
4
+ /**
5
+ * Badge active state
6
+ * */
7
+ icon?: string | undefined;
8
+ /**
9
+ * Put component in disabled state
10
+ * */
11
+ disabled?: boolean | undefined;
12
+ /**
13
+ * Is badge clickable?
14
+ * */
15
+ clickable?: boolean | undefined;
16
+ }
17
+
18
+ export interface VcButtonEmits {
19
+ /**
20
+ * Emitted when component is clicked
21
+ * */
22
+ (event: "click"): void;
23
+ }
24
+
25
+ export interface VcButtonSlots {
26
+ /**
27
+ * Slot for component content
28
+ * */
29
+ default: () => VNode[];
30
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Button component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcButton from "./vc-button.vue";
7
+
8
+ export default {
9
+ title: "atoms/vc-button",
10
+ component: VcButton,
11
+ argTypes: {
12
+ variant: {
13
+ options: ["primary", "secondary", "special"],
14
+ control: { type: "radio" },
15
+ },
16
+ },
17
+ };
18
+
19
+ const Template: Story = (args) => ({
20
+ components: { VcButton },
21
+ setup() {
22
+ return { args };
23
+ },
24
+ template: '<vc-button v-bind="args">I am a button</vc-button>',
25
+ });
26
+
27
+ export const Button = Template.bind({});
28
+ Button.storyName = "vc-button";
29
+ Button.args = {
30
+ icon: "fas fa-star",
31
+ variant: "primary",
32
+ disabled: false,
33
+ small: false,
34
+ };