@vc-shell/framework 1.0.196 → 1.0.198

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 (61) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/core/composables/useBreadcrumbs/index.ts +15 -9
  3. package/core/plugins/modularity/index.ts +1 -1
  4. package/dist/core/composables/useBreadcrumbs/index.d.ts +1 -6
  5. package/dist/core/composables/useBreadcrumbs/index.d.ts.map +1 -1
  6. package/dist/framework.js +26235 -26049
  7. package/dist/index.css +1 -1
  8. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  9. package/dist/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.d.ts.map +1 -1
  10. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -2
  11. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  12. package/dist/shared/components/blade-navigation/types/index.d.ts +1 -1
  13. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  14. package/dist/shared/modules/dynamic/composables/index.d.ts +1 -0
  15. package/dist/shared/modules/dynamic/composables/index.d.ts.map +1 -1
  16. package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts +10 -0
  17. package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts.map +1 -0
  18. package/dist/shared/modules/dynamic/factories/types/index.d.ts +13 -1
  19. package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
  20. package/dist/shared/modules/dynamic/index.d.ts +2 -3
  21. package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
  22. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts +1 -0
  23. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  24. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +2 -0
  25. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts +1 -0
  28. package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts.map +1 -1
  29. package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts +1 -13
  30. package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts.map +1 -1
  31. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +33 -0
  32. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +1 -1
  33. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts +14 -0
  34. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
  35. package/dist/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue.d.ts.map +1 -1
  36. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue.d.ts.map +1 -1
  37. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts +1 -1
  38. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  39. package/dist/ui/types/index.d.ts +3 -2
  40. package/dist/ui/types/index.d.ts.map +1 -1
  41. package/package.json +4 -4
  42. package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -38
  43. package/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.ts +11 -4
  44. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +40 -62
  45. package/shared/components/blade-navigation/types/index.ts +1 -1
  46. package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +2 -2
  47. package/shared/modules/dynamic/components/fields/GalleryField.ts +1 -1
  48. package/shared/modules/dynamic/composables/index.ts +1 -0
  49. package/shared/modules/dynamic/composables/useDynamicViewsUtils/index.ts +46 -0
  50. package/shared/modules/dynamic/factories/types/index.ts +16 -1
  51. package/shared/modules/dynamic/index.ts +2 -3
  52. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +1 -0
  53. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +7 -1
  54. package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +3 -0
  55. package/ui/components/molecules/vc-breadcrumbs/index.ts +1 -3
  56. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +123 -5
  57. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +10 -14
  58. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +11 -9
  59. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +5 -1
  60. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -1
  61. package/ui/types/index.ts +3 -2
@@ -0,0 +1,46 @@
1
+ import { ref, WatchStopHandle, watch, onMounted, onUnmounted, getCurrentInstance, Ref } from "vue";
2
+ import { ListBaseBladeScope, DetailsBaseBladeScope, DetailsBladeExposed, ListBladeExposed } from "../..";
3
+
4
+ export interface IUseDynamicViewsUtils {
5
+ getBladeExposedData: <BladeScope extends ListBaseBladeScope | DetailsBaseBladeScope>(
6
+ scope: BladeScope,
7
+ ) => BladeScope extends ListBaseBladeScope ? Ref<ListBladeExposed<BladeScope>> : Ref<DetailsBladeExposed<BladeScope>>;
8
+ }
9
+
10
+ export default () => {
11
+ const instance = getCurrentInstance();
12
+
13
+ function getBladeExposedData<BladeScope extends ListBaseBladeScope | DetailsBaseBladeScope>() {
14
+ const reactiveBlade = ref<BladeScope | null>(null);
15
+
16
+ const blade = ref(instance?.vnode);
17
+
18
+ let unwatch: WatchStopHandle | null = null;
19
+
20
+ const updateReactiveBlade = () => {
21
+ if (blade.value && blade.value.props?.navigation?.instance) {
22
+ reactiveBlade.value = blade.value.props.navigation.instance;
23
+ }
24
+ };
25
+
26
+ unwatch = watch(blade, updateReactiveBlade, { immediate: true, deep: true });
27
+
28
+ onMounted(() => {
29
+ updateReactiveBlade();
30
+ });
31
+
32
+ onUnmounted(() => {
33
+ if (unwatch) {
34
+ unwatch();
35
+ }
36
+ });
37
+
38
+ return reactiveBlade as unknown as BladeScope extends ListBaseBladeScope
39
+ ? Ref<ListBladeExposed<BladeScope>>
40
+ : Ref<DetailsBladeExposed<BladeScope>>;
41
+ }
42
+
43
+ return {
44
+ getBladeExposedData,
45
+ };
46
+ };
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs } from "vue";
3
3
  import { AsyncAction } from "../../../../../core/composables";
4
- import { SettingsSchema } from "../../types";
4
+ import { SettingsDetails, SettingsGrid, SettingsSchema } from "../../types";
5
5
  import { AssetsHandler, IBladeToolbar, ICommonAsset } from "../../../../../core/types";
6
6
  import { useBladeNavigation } from "../../../../components";
7
7
  import { FormContext } from "vee-validate";
@@ -122,3 +122,18 @@ export interface ListBladeContext extends UseList<Record<string, any>[], Record<
122
122
  settings: ComputedRef<SettingsSchema>;
123
123
  selectedIds: ComputedRef<string[]>;
124
124
  }
125
+
126
+ export interface BaseBladeExposed {
127
+ updateActiveWidgetCount: () => void;
128
+ readonly title: MaybeRef<string>;
129
+ }
130
+
131
+ export type ListBladeExposed<Scope extends ListBaseBladeScope> = BaseBladeExposed & {
132
+ readonly selectedIds: string[];
133
+ reload: () => void;
134
+ readonly settings: SettingsGrid;
135
+ } & UnwrapNestedRefs<Scope>;
136
+
137
+ export type DetailsBladeExposed<Scope extends DetailsBaseBladeScope> = BaseBladeExposed & {
138
+ readonly settings: SettingsDetails;
139
+ } & UnwrapNestedRefs<Scope>;
@@ -171,8 +171,7 @@ export const createDynamicAppModule = (args: {
171
171
  };
172
172
  };
173
173
 
174
- export * from "./pages";
175
- export * from "./composables";
176
- export * from "./components";
177
174
  export * from "./factories";
178
175
  export * from "./types";
176
+ export * from "./pages";
177
+ export { useDynamicViewsUtils } from "./composables";
@@ -357,6 +357,7 @@ defineExpose({
357
357
  title: bladeTitle ?? "",
358
358
  updateActiveWidgetCount,
359
359
  ...toRefs(scope?.value ?? {}),
360
+ settings: toValue(settings),
360
361
  });
361
362
  </script>
362
363
 
@@ -262,6 +262,9 @@ const { load, remove, items, loading, pagination, query, scope } = props.composa
262
262
  emit,
263
263
  props,
264
264
  mounted: useMounted(),
265
+ /**
266
+ * @deprecated use `useDynamicViewsUtils` instead. This will be removed in the next major version.
267
+ */
265
268
  bladeContext: {
266
269
  settings,
267
270
  selectedIds: computed(() => selectedIds.value),
@@ -382,7 +385,8 @@ const toolbarComputed =
382
385
  [];
383
386
 
384
387
  onBeforeMount(async () => {
385
- if (props.composables) await load({ sort: sort.value, ...query.value, ...getNavigationQuery() });
388
+ if (props.composables)
389
+ await load({ sort: sort.value, ...query.value, ...(props.isWidgetView ? {} : getNavigationQuery()) });
386
390
  });
387
391
 
388
392
  watch(
@@ -658,5 +662,7 @@ defineExpose({
658
662
  title,
659
663
  updateActiveWidgetCount,
660
664
  ...toRefs(scope?.value ?? {}),
665
+ selectedIds,
666
+ settings: toValue(settings),
661
667
  });
662
668
  </script>
@@ -3,6 +3,7 @@
3
3
  class="vc-breadcrumbs-item"
4
4
  :class="{
5
5
  'vc-breadcrumbs-item_current': current,
6
+ 'tw-px-1 tw-h-[var(--breadcrumbs-item-height-light)]': variant === 'light',
6
7
  }"
7
8
  @click="onClick"
8
9
  >
@@ -24,6 +25,7 @@ import { VcIcon } from "./../../../../";
24
25
 
25
26
  export interface Props extends Breadcrumbs {
26
27
  current: boolean;
28
+ variant?: "default" | "light";
27
29
  }
28
30
 
29
31
  export interface Emits {
@@ -48,6 +50,7 @@ function onClick(): void {
48
50
  <style lang="scss">
49
51
  :root {
50
52
  --breadcrumbs-item-height: 28px;
53
+ --breadcrumbs-item-height-light: 20px;
51
54
  --breadcrumbs-item-border-color: #a1c0d4;
52
55
  --breadcrumbs-item-border-color-hover: #8fb0c6;
53
56
  --breadcrumbs-item-border-color-current: #838d9a;
@@ -1,3 +1 @@
1
- import _Breadcrumbs from "./vc-breadcrumbs.vue";
2
-
3
- export const VcBreadcrumbs = _Breadcrumbs as typeof _Breadcrumbs;
1
+ export { default as VcBreadcrumbs } from "./vc-breadcrumbs.vue";
@@ -1,26 +1,144 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="items && items.length"
4
+ ref="el"
4
5
  class="tw-flex tw-items-center tw-flex-wrap tw-gap-[10px]"
5
6
  >
6
7
  <VcBreadcrumbsItem
7
- v-for="(item, i) in items"
8
- :key="item?.id ?? `item-${i}`"
9
- v-bind="item"
10
- :current="i === items.length - 1"
8
+ v-if="items.length"
9
+ :id="items[0]?.id"
10
+ :title="items[0]?.title"
11
+ :current="items.length === 1"
12
+ :variant="variant"
13
+ >
14
+ </VcBreadcrumbsItem>
15
+ <VcIcon
16
+ v-if="withArrow && canExpand"
17
+ :icon="arrowIcon"
18
+ :size="arrowSize"
19
+ class="tw-text-[color:let(--chevron-color)]"
11
20
  />
21
+ <VcBreadcrumbsItem
22
+ v-if="canExpand"
23
+ id="Expand"
24
+ :current="false"
25
+ title="..."
26
+ :variant="variant"
27
+ @click="expand"
28
+ >
29
+ </VcBreadcrumbsItem>
30
+ <template
31
+ v-for="(item, i) in visibleBreadcrumbs"
32
+ :key="item?.id ?? `breadcrumb-item-${i}`"
33
+ >
34
+ <div v-if="item && item.title && item.isVisible">
35
+ <VcIcon
36
+ v-if="withArrow && i < items.length - 1"
37
+ :icon="arrowIcon"
38
+ :size="arrowSize"
39
+ class="tw-text-[color:let(--chevron-color)] tw-mr-[10px]"
40
+ />
41
+ <VcBreadcrumbsItem
42
+ v-bind="item"
43
+ :current="i === items.length - 1"
44
+ :variant="variant"
45
+ />
46
+ </div>
47
+ </template>
12
48
  </div>
13
49
  </template>
14
50
 
15
51
  <script lang="ts" setup>
16
52
  import { Breadcrumbs } from "../../../types";
17
53
  import VcBreadcrumbsItem from "./_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue";
54
+ import { VcIcon } from "./../../atoms/vc-icon";
55
+ import { useElementBounding } from "@vueuse/core";
56
+ import { MaybeRef, Ref, computed, ref, toRefs, toValue, watch } from "vue";
57
+ import * as _ from "lodash-es";
18
58
 
19
59
  export interface Props {
20
60
  items?: Breadcrumbs[];
61
+ variant?: "default" | "light";
62
+ withArrow?: boolean;
63
+ arrowIcon?: string;
64
+ arrowSize?: InstanceType<typeof VcIcon>["$props"]["size"];
65
+ }
66
+
67
+ interface InternalBreadcrumbs extends Breadcrumbs {
68
+ isVisible?: boolean;
21
69
  }
22
70
 
23
- withDefaults(defineProps<Props>(), {
71
+ const props = withDefaults(defineProps<Props>(), {
24
72
  items: () => [],
73
+ variant: "default",
74
+ arrowIcon: "fas fa-chevron-right",
75
+ arrowSize: "xs",
25
76
  });
77
+
78
+ const el = ref(null);
79
+ const visibleBreadcrumbs = ref([]) as Ref<InternalBreadcrumbs[]>;
80
+
81
+ const { width } = useElementBounding(el);
82
+
83
+ const { items } = toRefs(props);
84
+
85
+ const canExpand = computed(
86
+ () =>
87
+ visibleBreadcrumbs.value &&
88
+ _.some(
89
+ visibleBreadcrumbs.value,
90
+ (breadcrumb) => !(typeof breadcrumb?.isVisible === "undefined" ? true : breadcrumb.isVisible),
91
+ ),
92
+ );
93
+
94
+ watch(items, computeVisibleBreadcrumbs, { deep: true });
95
+
96
+ function computeVisibleBreadcrumbs(breadcrumbs: InternalBreadcrumbs[]) {
97
+ if (!(breadcrumbs && breadcrumbs.length)) return [];
98
+
99
+ const expanderWidth = 40;
100
+ const availableWidth = width.value;
101
+ let widthOfItems = calculateTotalWidth(breadcrumbs[0].title);
102
+
103
+ const items = _.tail(_.cloneDeep(breadcrumbs)).reverse();
104
+
105
+ for (let i = 0; i < items.length; i++) {
106
+ const x = items[i];
107
+ const elWidth = calculateTotalWidth(x.title);
108
+ if (widthOfItems + elWidth <= availableWidth) {
109
+ x.isVisible = true;
110
+ widthOfItems += elWidth;
111
+ } else {
112
+ if (i > 0) items[i - 1].isVisible = false;
113
+ widthOfItems += expanderWidth;
114
+ if (widthOfItems > availableWidth) break;
115
+ }
116
+ }
117
+
118
+ visibleBreadcrumbs.value = items.reverse();
119
+ }
120
+
121
+ function calculateTotalWidth(title: MaybeRef<string | undefined>) {
122
+ const unrefTitle = toValue(title);
123
+ if (!unrefTitle) return 0;
124
+
125
+ const paddings = 40;
126
+ const averageCharacterWidth = 4.87;
127
+
128
+ const wordWidth = Math.floor(unrefTitle.length * averageCharacterWidth) + paddings;
129
+
130
+ return wordWidth;
131
+ }
132
+
133
+ function expand() {
134
+ visibleBreadcrumbs.value.forEach((breadcrumb) => {
135
+ breadcrumb.isVisible = true;
136
+ });
137
+ }
26
138
  </script>
139
+
140
+ <style lang="scss">
141
+ :root {
142
+ --chevron-color: #a1c0d4;
143
+ }
144
+ </style>
@@ -70,7 +70,8 @@ import { useI18n } from "vue-i18n";
70
70
  import { VcIcon, VcLink } from "./../../../../";
71
71
  import { IBladeToolbar } from "./../../../../../../core/types";
72
72
  import { useBladeNavigation } from "./../../../../../../shared";
73
- import { Ref, nextTick, ref, toRef, unref, watch } from "vue";
73
+ import { Ref, ref } from "vue";
74
+ import { watchDebounced } from "@vueuse/core";
74
75
 
75
76
  export interface Props {
76
77
  logo?: string;
@@ -93,22 +94,17 @@ const { t } = useI18n({ useScope: "global" });
93
94
 
94
95
  const { blades } = useBladeNavigation();
95
96
 
96
- let viewTitle: Ref<string>;
97
+ const viewTitle: Ref<string> = ref("");
97
98
  const quantity = ref();
98
99
 
99
- watch(
100
- () => blades,
101
- async (newVal) => {
102
- await nextTick().then(() => {
103
- viewTitle = toRef(
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- unref(newVal.value[newVal.value.length - 1]?.props?.navigation?.instance) as Record<string, any>,
106
- "title",
107
- );
108
- quantity.value = newVal.value.length;
109
- });
100
+ watchDebounced(
101
+ blades,
102
+ (newVal) => {
103
+ viewTitle.value = newVal[newVal.length - 1]?.props?.navigation?.instance?.title ?? "";
104
+
105
+ quantity.value = newVal.length;
110
106
  },
111
- { deep: true, immediate: true, flush: "post" },
107
+ { deep: true, immediate: true, flush: "post", debounce: 1 },
112
108
  );
113
109
  </script>
114
110
 
@@ -115,18 +115,20 @@ function onMenuItemClick() {
115
115
  }
116
116
 
117
117
  const isActive = (url: string) => {
118
- let path = route.path;
119
- if (Object.values(params).length) {
120
- path = path.replace(Object.values(params)[0] as string, "");
121
- }
118
+ if (url) {
119
+ let path = route.path;
120
+ if (Object.values(params).length) {
121
+ path = path.replace(Object.values(params)[0] as string, "");
122
+ }
122
123
 
123
- const active = path.endsWith(url);
124
+ const active = path.endsWith(url);
124
125
 
125
- if (active && props.children?.length) {
126
- isOpened.value = true;
127
- }
126
+ if (active && props.children?.length) {
127
+ isOpened.value = true;
128
+ }
128
129
 
129
- return active;
130
+ return active;
131
+ } else return false;
130
132
  };
131
133
  </script>
132
134
 
@@ -245,6 +245,7 @@ const { locale, te, t } = useI18n({ useScope: "global" });
245
245
 
246
246
  const items: Ref<any[]> = ref([]);
247
247
  const loading = ref(false);
248
+ const initialOptions = ref<any[]>([]);
248
249
 
249
250
  const computedProperty = computed(() => {
250
251
  const rules: IValidationRules = {};
@@ -302,6 +303,7 @@ const value = computed({
302
303
 
303
304
  onMounted(async () => {
304
305
  await getOptions();
306
+ initialOptions.value = items.value;
305
307
  });
306
308
 
307
309
  async function getOptions(keyword: string | undefined = undefined) {
@@ -324,6 +326,8 @@ async function onSearch(keyword: string) {
324
326
  }
325
327
 
326
328
  async function onClose() {
327
- getOptions();
329
+ if (initialOptions.value.length) {
330
+ items.value = initialOptions.value;
331
+ }
328
332
  }
329
333
  </script>
@@ -116,7 +116,7 @@
116
116
  class="tw-text-right tw-truncate"
117
117
  :class="cell.class"
118
118
  >
119
- {{ Number(value).toFixed(0) }}
119
+ {{ typeof Number(value) === "number" && Number(value) >= 0 ? Number(value).toFixed(0) : "N/A" }}
120
120
  </div>
121
121
 
122
122
  <!-- Link cell -->
package/ui/types/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { MaybeRef } from "vue";
1
2
  import * as components from "./../components";
2
3
 
3
4
  // Declare all components globally
@@ -12,7 +13,7 @@ declare module "vue" {
12
13
 
13
14
  export interface Breadcrumbs {
14
15
  icon?: string;
15
- title: string;
16
- clickHandler?: (id: string) => void | Promise<void>;
16
+ title: MaybeRef<string | undefined>;
17
+ clickHandler?: (id: string) => void | boolean | Promise<void | boolean>;
17
18
  id: string;
18
19
  }