@vc-shell/framework 1.0.293 → 1.0.294

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 (95) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/core/composables/useLanguages/index.ts +30 -0
  3. package/core/composables/useMenuService/index.ts +1 -1
  4. package/core/composables/useSettings/index.ts +2 -3
  5. package/core/composables/useTheme/index.ts +2 -1
  6. package/core/composables/useUser/index.ts +4 -76
  7. package/core/constants/index.ts +1 -0
  8. package/core/constants/locale.ts +78 -0
  9. package/core/interceptors/index.ts +3 -0
  10. package/core/plugins/modularity/index.ts +106 -16
  11. package/dist/core/composables/useLanguages/index.d.ts +5 -0
  12. package/dist/core/composables/useLanguages/index.d.ts.map +1 -1
  13. package/dist/core/composables/useSettings/index.d.ts.map +1 -1
  14. package/dist/core/composables/useTheme/index.d.ts.map +1 -1
  15. package/dist/core/composables/useUser/index.d.ts +1 -3
  16. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  17. package/dist/core/constants/index.d.ts +2 -0
  18. package/dist/core/constants/index.d.ts.map +1 -0
  19. package/dist/core/constants/locale.d.ts +7 -0
  20. package/dist/core/constants/locale.d.ts.map +1 -0
  21. package/dist/core/interceptors/index.d.ts.map +1 -1
  22. package/dist/core/plugins/modularity/index.d.ts.map +1 -1
  23. package/dist/framework.js +21278 -20967
  24. package/dist/index.css +1 -1
  25. package/dist/index.d.ts +9 -4
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/locales/en.json +2 -1
  28. package/dist/shared/components/app-switcher/components/vc-app-switcher/vc-app-switcher.vue.d.ts.map +1 -1
  29. package/dist/shared/components/index.d.ts +1 -0
  30. package/dist/shared/components/index.d.ts.map +1 -1
  31. package/dist/shared/components/language-selector/language-selector.vue.d.ts.map +1 -1
  32. package/dist/shared/components/sidebar/sidebar.vue.d.ts +1 -1
  33. package/dist/shared/components/sidebar/sidebar.vue.d.ts.map +1 -1
  34. package/dist/shared/components/sign-in/azuread.vue.d.ts +17 -0
  35. package/dist/shared/components/sign-in/azuread.vue.d.ts.map +1 -0
  36. package/dist/shared/components/sign-in/external-provider.vue.d.ts +23 -0
  37. package/dist/shared/components/sign-in/external-provider.vue.d.ts.map +1 -0
  38. package/dist/shared/components/sign-in/external-providers.vue.d.ts +16 -0
  39. package/dist/shared/components/sign-in/external-providers.vue.d.ts.map +1 -0
  40. package/dist/shared/components/sign-in/index.d.ts +2 -0
  41. package/dist/shared/components/sign-in/index.d.ts.map +1 -0
  42. package/dist/shared/components/sign-in/useExternalProvider.d.ts +12 -0
  43. package/dist/shared/components/sign-in/useExternalProvider.d.ts.map +1 -0
  44. package/dist/shared/components/theme-selector/theme-selector.vue.d.ts.map +1 -1
  45. package/dist/shared/modules/dynamic/index.d.ts +13 -10
  46. package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
  47. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts +1 -0
  48. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  49. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -1
  50. package/dist/tailwind.config.d.ts +1 -1
  51. package/dist/tailwind.config.d.ts.map +1 -1
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/dist/ui/components/atoms/vc-image/index.d.ts +1 -68
  54. package/dist/ui/components/atoms/vc-image/index.d.ts.map +1 -1
  55. package/dist/ui/components/atoms/vc-image/vc-image.stories.d.ts +3 -3
  56. package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts +2 -2
  57. package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts.map +1 -1
  58. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue.d.ts +2 -2
  59. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue.d.ts.map +1 -1
  60. package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
  61. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts +1 -1
  62. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts.map +1 -1
  63. package/dist/ui/components/organisms/vc-table/vc-table.stories.d.ts +30 -30
  64. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +9 -6
  65. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  66. package/package.json +5 -5
  67. package/shared/components/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +1 -2
  68. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +1 -1
  69. package/shared/components/index.ts +1 -0
  70. package/shared/components/language-selector/language-selector.vue +59 -6
  71. package/shared/components/sidebar/sidebar.vue +1 -1
  72. package/shared/components/sign-in/azuread.vue +24 -0
  73. package/shared/components/sign-in/external-provider.vue +38 -0
  74. package/shared/components/sign-in/external-providers.vue +39 -0
  75. package/shared/components/sign-in/index.ts +1 -0
  76. package/shared/components/sign-in/useExternalProvider.ts +102 -0
  77. package/shared/components/theme-selector/theme-selector.vue +7 -8
  78. package/shared/modules/dynamic/helpers/nodeBuilder.ts +2 -2
  79. package/shared/modules/dynamic/helpers/override.ts +1 -1
  80. package/shared/modules/dynamic/index.ts +166 -63
  81. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +99 -20
  82. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +1 -1
  83. package/shared/pages/LoginPage/components/login/Login.vue +8 -40
  84. package/tailwind.config.ts +6 -198
  85. package/ui/components/atoms/vc-image/index.ts +1 -3
  86. package/ui/components/atoms/vc-image/vc-image.vue +3 -2
  87. package/ui/components/atoms/vc-tooltip/vc-tooltip.vue +1 -1
  88. package/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue +1 -1
  89. package/ui/components/molecules/vc-input/vc-input.vue +38 -0
  90. package/ui/components/molecules/vc-input-currency/vc-input-currency.vue +1 -1
  91. package/ui/components/molecules/vc-select/vc-select.vue +15 -5
  92. package/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +2 -24
  93. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +12 -3
  94. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +1 -1
  95. package/ui/components/organisms/vc-table/vc-table.vue +124 -65
@@ -1,9 +1,17 @@
1
1
  <template>
2
2
  <AppBarButtonTemplate
3
3
  :title="$t('COMPONENTS.LANGUAGE_SELECTOR.TITLE')"
4
- icon="fas fa-globe"
5
4
  position="bottom-end"
6
5
  >
6
+ <template #button>
7
+ <div class="vc-language-selector__button-wrap">
8
+ <VcImage
9
+ :src="currLocaleFlag"
10
+ class="vc-language-selector__img vc-language-selector__img--button"
11
+ empty-icon="fas fa-globe"
12
+ />
13
+ </div>
14
+ </template>
7
15
  <template #dropdown-content="{ opened, toggle }">
8
16
  <Sidebar
9
17
  :is-expanded="$isMobile.value ? opened : false"
@@ -20,8 +28,13 @@
20
28
  v-for="(lang, i) in languageItems"
21
29
  :key="i"
22
30
  class="vc-language-selector__item"
31
+ :class="{ 'vc-language-selector__item--active': lang.lang === $i18n.locale }"
23
32
  @click="lang.hasOwnProperty('clickHandler') && lang.clickHandler(lang.lang)"
24
33
  >
34
+ <VcImage
35
+ :src="lang.flag"
36
+ class="vc-language-selector__img"
37
+ />
25
38
  {{ lang.title }}
26
39
  </div>
27
40
  </div>
@@ -36,19 +49,42 @@ import { useI18n } from "vue-i18n";
36
49
  import { useLanguages } from "../../../core/composables";
37
50
  import { AppBarButtonTemplate } from "./../app-bar-button";
38
51
  import { Sidebar } from "./../sidebar";
52
+ import { watch, ref } from "vue";
53
+
54
+ interface ILanguage {
55
+ lang: string;
56
+ title: string;
57
+ clickHandler: (lang: string) => void;
58
+ flag: string;
59
+ }
39
60
 
40
- const { availableLocales, getLocaleMessage } = useI18n({ useScope: "global" });
41
- const { setLocale } = useLanguages();
61
+ const { availableLocales, getLocaleMessage, locale } = useI18n({ useScope: "global" });
62
+ const { setLocale, getFlag } = useLanguages();
42
63
 
43
- const languageItems = availableLocales
64
+ const languageItems: ILanguage[] = availableLocales
44
65
  .map((locale: string) => ({
45
66
  lang: locale,
46
67
  title: (getLocaleMessage(locale) as { language_name: string }).language_name,
47
68
  clickHandler(lang: string) {
48
69
  setLocale(lang);
49
70
  },
71
+ flag: "",
50
72
  }))
51
73
  .filter((item) => item.title);
74
+
75
+ const currLocaleFlag = ref<string>();
76
+
77
+ watch(
78
+ [() => languageItems, () => locale.value],
79
+ async ([newValLangItem]) => {
80
+ for (const lang of newValLangItem) {
81
+ lang.flag = await getFlag(lang.lang);
82
+
83
+ currLocaleFlag.value = languageItems.find((lang) => lang.lang === locale.value)?.flag;
84
+ }
85
+ },
86
+ { immediate: true },
87
+ );
52
88
  </script>
53
89
 
54
90
  <style lang="scss">
@@ -57,15 +93,16 @@ const languageItems = availableLocales
57
93
  --language-selector-text-color: var(--base-text-color, var(--neutrals-950));
58
94
  --language-selector-border-color: var(--app-bar-divider-color);
59
95
  --language-selector-hover-bg-color: var(--primary-50);
96
+ --language-selector-button-width: var(--app-bar-button-width);
60
97
  }
61
98
 
62
99
  .vc-language-selector {
63
100
  &__dropdown {
64
- @apply tw-bg-[color:var(--language-selector-bg-color)] tw-w-full;
101
+ @apply tw-bg-[color:var(--language-selector-bg-color)] tw-min-w-max;
65
102
  }
66
103
 
67
104
  &__item {
68
- @apply tw-p-3 tw-text-sm tw-text-[color:var(--language-selector-text-color)]
105
+ @apply tw-truncate tw-flex tw-items-center tw-p-3 tw-text-sm tw-text-[color:var(--language-selector-text-color)]
69
106
  tw-border-l tw-border-solid tw-border-l-[var(--language-selector-border-color)]
70
107
  tw-border-b tw-border-b-[var(--language-selector-border-color)] tw-w-full tw-cursor-pointer;
71
108
  transition: background-color 0.2s;
@@ -73,6 +110,22 @@ const languageItems = availableLocales
73
110
  &:hover {
74
111
  background-color: var(--language-selector-hover-bg-color);
75
112
  }
113
+
114
+ &--active {
115
+ @apply tw-bg-[color:var(--language-selector-hover-bg-color)];
116
+ }
117
+ }
118
+
119
+ &__img {
120
+ @apply tw-w-6 tw-h-6 tw-mr-2;
121
+
122
+ &--button {
123
+ @apply tw-mr-0;
124
+ }
125
+ }
126
+
127
+ &__button-wrap {
128
+ @apply tw-w-[var(--language-selector-button-width)] tw-flex tw-justify-center;
76
129
  }
77
130
  }
78
131
  </style>
@@ -39,7 +39,7 @@
39
39
 
40
40
  <script lang="ts" setup>
41
41
  export interface Props {
42
- position: "left" | "right";
42
+ position?: "left" | "right";
43
43
  render: "always" | "mobile" | "desktop";
44
44
  isExpanded: boolean;
45
45
  }
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <ExternalProvider
3
+ :logo="logo"
4
+ :display-name="displayName"
5
+ @sign-in="signIn(authenticationType, '/signin-oidc')"
6
+ />
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ import { default as ExternalProvider } from "./external-provider.vue";
11
+ import { useExternalProvider } from "./useExternalProvider";
12
+
13
+ export interface Props {
14
+ logo: string;
15
+ displayName: string;
16
+ authenticationType: string;
17
+ }
18
+
19
+ defineProps<Props>();
20
+
21
+ const { signIn } = useExternalProvider();
22
+ </script>
23
+
24
+ <style lang="scss" scoped></style>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <VcButton
3
+ outline
4
+ class="vc-external-provider"
5
+ @click="$emit('signIn')"
6
+ >
7
+ <div class="vc-external-provider__content">
8
+ <VcImage
9
+ :src="logo"
10
+ class="vc-external-provider__icon"
11
+ size="xxs"
12
+ />{{ displayName }}
13
+ </div>
14
+ </VcButton>
15
+ </template>
16
+
17
+ <script lang="ts" setup>
18
+ import { VcButton, VcImage } from "./../../../ui/components";
19
+ export interface Props {
20
+ logo: string;
21
+ displayName: string;
22
+ }
23
+
24
+ export interface Emits {
25
+ (event: "signIn"): void;
26
+ }
27
+
28
+ defineEmits<Emits>();
29
+ defineProps<Props>();
30
+ </script>
31
+
32
+ <style lang="scss">
33
+ .vc-external-provider {
34
+ &__content {
35
+ @apply tw-flex tw-flex-row tw-items-center tw-gap-2;
36
+ }
37
+ }
38
+ </style>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="vc-external-providers">
3
+ <component
4
+ :is="loadProviderComponent(provider.authenticationType!)"
5
+ v-for="provider in providers"
6
+ :key="provider"
7
+ :logo="'/' + provider.logoUrl"
8
+ :display-name="provider.displayName"
9
+ :authentication-type="provider.authenticationType"
10
+ />
11
+ </div>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { defineProps, defineAsyncComponent } from "vue";
16
+ import type { Component } from "vue";
17
+ import { ExternalSignInProviderInfo } from "../../../core/api/platform";
18
+
19
+ export interface Props {
20
+ providers: ExternalSignInProviderInfo[];
21
+ }
22
+
23
+ defineProps<Props>();
24
+
25
+ const loadProviderComponent = (providerName: string) => {
26
+ return defineAsyncComponent<Component>({
27
+ loader: () => import(/* @vite-ignore */ `./${providerName.toLowerCase()}.vue`),
28
+ onError(error) {
29
+ console.error(`Failed to load ${providerName} provider component`, error);
30
+ },
31
+ });
32
+ };
33
+ </script>
34
+
35
+ <style lang="scss">
36
+ .vc-external-providers {
37
+ @apply tw-flex tw-justify-center tw-mt-4 tw-flex-wrap tw-gap-2;
38
+ }
39
+ </style>
@@ -0,0 +1 @@
1
+ export { default as ExternalProviders } from "./external-providers.vue";
@@ -0,0 +1,102 @@
1
+ import { useLocalStorage } from "@vueuse/core";
2
+ import type { Ref } from "vue";
3
+ import { ExternalSignInClient, ExternalSignInProviderInfo } from "../../../core/api/platform";
4
+
5
+ export interface IUseExternalProvider {
6
+ storage: Ref<{ providerType?: string | undefined }>;
7
+ signIn: (authenticationType: string, oidcUrl: string) => void;
8
+ signOut: (authenticationType: string) => void;
9
+ getProviders: () => Promise<ExternalSignInProviderInfo[] | undefined>;
10
+ }
11
+
12
+ const VC_EXTERNAL_AUTH_DATA_KEY = "externalSignIn";
13
+
14
+ export const useExternalProvider = (): IUseExternalProvider => {
15
+ const externalSecurityClient = new ExternalSignInClient();
16
+ const externalSignInStorage = useLocalStorage<{ providerType?: string | undefined }>(
17
+ VC_EXTERNAL_AUTH_DATA_KEY,
18
+ {},
19
+ {
20
+ listenToStorageChanges: true,
21
+ deep: true,
22
+ },
23
+ );
24
+
25
+ function getReturnUrlValue(): string | null {
26
+ const { searchParams } = new URL(location.href);
27
+ return searchParams.get("returnUrl") || searchParams.get("ReturnUrl");
28
+ }
29
+
30
+ async function externalSignIn(authenticationType: string, oidcUrl: string) {
31
+ try {
32
+ const origin = location.origin;
33
+ const finalReturnUrl = location.pathname ?? getReturnUrlValue() ?? "/";
34
+
35
+ if (!authenticationType) {
36
+ throw new Error("The parameter 'authenticationType' cannot be null or undefined.");
37
+ }
38
+
39
+ // const oidcUrlObject = new URL(oidcUrl, origin);
40
+ // const callbackUrl = new URL("/auth/callback", origin);
41
+ const url = new URL("/externalsignin", origin);
42
+ console.log("url", url);
43
+
44
+ // Set query parameters
45
+ // callbackUrl.searchParams.set("returnUrl", finalReturnUrl);
46
+ url.searchParams.set("authenticationType", authenticationType);
47
+ // url.searchParams.set("callbackUrl", callbackUrl.href);
48
+ url.searchParams.set("returnUrl", finalReturnUrl);
49
+
50
+ // Store sign-in data
51
+ externalSignInStorage.value = { providerType: authenticationType };
52
+
53
+ console.log("url", url);
54
+ // Redirect to the constructed URL
55
+ location.assign(url);
56
+ } catch (e) {
57
+ console.error(e);
58
+ throw e;
59
+ }
60
+ }
61
+
62
+ async function externalSignOut(authenticationType: string): Promise<void> {
63
+ try {
64
+ const origin = location.origin;
65
+ const returnUrl = location.pathname ?? "/";
66
+
67
+ const url = new URL("/externalsignin/signout", origin);
68
+
69
+ // Set query parameters
70
+ url.searchParams.set("authenticationType", authenticationType);
71
+ url.searchParams.set("returnUrl", returnUrl);
72
+
73
+ // Clear sign-in data
74
+ externalSignInStorage.value = {};
75
+
76
+ // Redirect to the sign-out URL
77
+ location.assign(url);
78
+ } catch (e) {
79
+ console.error(e);
80
+ throw e;
81
+ }
82
+ }
83
+
84
+ async function getExternalLoginProviders() {
85
+ let result: ExternalSignInProviderInfo[] | undefined = undefined;
86
+ try {
87
+ result = await externalSecurityClient.getExternalLoginProviders();
88
+ } catch (e) {
89
+ console.error(e);
90
+ // TODO check error in app!!!
91
+ }
92
+
93
+ return result;
94
+ }
95
+
96
+ return {
97
+ storage: externalSignInStorage,
98
+ signIn: externalSignIn,
99
+ signOut: externalSignOut,
100
+ getProviders: getExternalLoginProviders,
101
+ };
102
+ };
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <AppBarButtonTemplate
3
3
  icon="fas fa-palette"
4
- :title="themeText(current)"
4
+ :title="$t('COMPONENTS.THEME_SELECTOR.THEME_SELECTOR')"
5
+ position="bottom-end"
5
6
  >
6
7
  <template #dropdown-content="{ opened, toggle }">
7
8
  <Sidebar
@@ -43,23 +44,21 @@ import { useTheme } from "./../../../core/composables/useTheme";
43
44
  import { watch, computed } from "vue";
44
45
  import { notification } from "./../";
45
46
  import * as _ from "lodash-es";
46
- import { useI18n } from "vue-i18n";
47
47
  import { createUnrefFn } from "@vueuse/core";
48
48
 
49
49
  const { current, themes, setTheme } = useTheme();
50
- const { t } = useI18n({ useScope: "global" });
51
50
 
52
51
  watch(
53
- () => current,
52
+ () => current.value,
54
53
  (newVal) => {
55
- notification(themeText.value(newVal));
54
+ notification(_.capitalize(newVal));
56
55
  },
57
56
  { deep: true },
58
57
  );
59
58
 
60
59
  const themeText = computed(() => {
61
60
  return createUnrefFn((theme: string) => {
62
- return _.capitalize(theme) + t("COMPONENTS.THEME_SELECTOR.THEME_CHANGED");
61
+ return _.capitalize(theme);
63
62
  });
64
63
  });
65
64
  </script>
@@ -74,11 +73,11 @@ const themeText = computed(() => {
74
73
 
75
74
  .vc-theme-selector {
76
75
  &__dropdown {
77
- @apply tw-bg-[color:var(--theme-selector-bg-color)] tw-w-full;
76
+ @apply tw-bg-[color:var(--theme-selector-bg-color)] tw-min-w-20 tw-max-w-max;
78
77
  }
79
78
 
80
79
  &__item {
81
- @apply tw-p-3 tw-text-sm tw-text-[color:var(--theme-selector-text-color)]
80
+ @apply tw-truncate tw-p-3 tw-text-sm tw-text-[color:var(--theme-selector-text-color)]
82
81
  tw-border-l tw-border-solid tw-border-l-[var(--theme-selector-border-color)]
83
82
  tw-border-b tw-border-b-[var(--theme-selector-border-color)] tw-w-full tw-cursor-pointer;
84
83
  transition: background-color 0.2s;
@@ -79,9 +79,9 @@ function nodeBuilder<
79
79
 
80
80
  const hint =
81
81
  safeIn("hint", controlSchema) && controlSchema.hint
82
- ? (bladeContext.scope && unref(unwrapInterpolation(controlSchema.hint, bladeContext.scope))) ??
82
+ ? ((bladeContext.scope && unref(unwrapInterpolation(controlSchema.hint, bladeContext.scope))) ??
83
83
  unref(unwrapInterpolation(controlSchema.hint, internalContext)) ??
84
- undefined
84
+ undefined)
85
85
  : undefined;
86
86
 
87
87
  const disabled =
@@ -60,7 +60,7 @@ const upsertHelper = (overrides: OverridesSchema, schemaCopy: { [key: string]: D
60
60
  const findIndex = _.findIndex(valueByPath, { id: args.value.id });
61
61
 
62
62
  const spliced = valueByPath /* @ts-expect-error - toSpliced is not parsed correctly by ts */
63
- .toSpliced(findIndex >= 0 ? findIndex : args.index ?? 0, findIndex >= 0 ? 1 : 0, args.value);
63
+ .toSpliced(findIndex >= 0 ? findIndex : (args.index ?? 0), findIndex >= 0 ? 1 : 0, args.value);
64
64
  _.set(clonedSchema, currentPath, spliced);
65
65
  } else {
66
66
  _.set(clonedSchema, currentPath, args.value);