@vc-shell/framework 1.0.70 → 1.0.71

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 (160) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/core/composables/useNotifications/index.ts +1 -1
  3. package/core/composables/useUser/index.ts +175 -9
  4. package/dist/core/composables/useNotifications/index.d.ts +1 -1
  5. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  6. package/dist/core/composables/useUser/index.d.ts +18 -1
  7. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  8. package/dist/framework.mjs +17124 -15573
  9. package/dist/index.css +1 -1
  10. package/dist/index.d.ts +3 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/injectionSymbols.d.ts +6 -0
  13. package/dist/injectionSymbols.d.ts.map +1 -0
  14. package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts +1 -1
  15. package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  16. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  17. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  18. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  19. package/dist/shared/components/change-password/change-password.vue.d.ts +7 -0
  20. package/dist/shared/components/change-password/change-password.vue.d.ts.map +1 -0
  21. package/dist/shared/components/change-password/index.d.ts +11 -0
  22. package/dist/shared/components/change-password/index.d.ts.map +1 -0
  23. package/dist/shared/components/index.d.ts +9 -0
  24. package/dist/shared/components/index.d.ts.map +1 -0
  25. package/dist/shared/components/language-selector/index.d.ts +55 -0
  26. package/dist/shared/components/language-selector/index.d.ts.map +1 -0
  27. package/dist/shared/components/language-selector/language-selector.vue.d.ts +45 -0
  28. package/dist/shared/components/language-selector/language-selector.vue.d.ts.map +1 -0
  29. package/dist/shared/components/notifications/core/notification.d.ts.map +1 -1
  30. package/dist/shared/components/notifications/types/index.d.ts +3 -1
  31. package/dist/shared/components/notifications/types/index.d.ts.map +1 -1
  32. package/dist/shared/components/user-dropdown-button/index.d.ts +43 -0
  33. package/dist/shared/components/user-dropdown-button/index.d.ts.map +1 -0
  34. package/dist/shared/components/user-dropdown-button/user-dropdown-button.vue.d.ts +33 -0
  35. package/dist/shared/components/user-dropdown-button/user-dropdown-button.vue.d.ts.map +1 -0
  36. package/dist/shared/index.d.ts +3 -7
  37. package/dist/shared/index.d.ts.map +1 -1
  38. package/dist/shared/locales/index.d.ts +3 -0
  39. package/dist/shared/locales/index.d.ts.map +1 -0
  40. package/dist/shared/modules/assets/components/assets-details/assets-details.vue.d.ts +2 -9
  41. package/dist/shared/modules/assets/components/assets-details/assets-details.vue.d.ts.map +1 -1
  42. package/dist/shared/modules/assets/components/assets-details/index.d.ts +23 -157
  43. package/dist/shared/modules/assets/components/assets-details/index.d.ts.map +1 -1
  44. package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts +2 -9
  45. package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts.map +1 -1
  46. package/dist/shared/modules/assets-manager/components/assets-manager/index.d.ts +27 -172
  47. package/dist/shared/modules/assets-manager/components/assets-manager/index.d.ts.map +1 -1
  48. package/dist/shared/modules/index.d.ts +3 -0
  49. package/dist/shared/modules/index.d.ts.map +1 -0
  50. package/dist/shared/pages/InvitePage/components/index.d.ts +2 -0
  51. package/dist/shared/pages/InvitePage/components/index.d.ts.map +1 -0
  52. package/dist/shared/pages/InvitePage/components/invite/Invite.vue.d.ts +33 -0
  53. package/dist/shared/pages/InvitePage/components/invite/Invite.vue.d.ts.map +1 -0
  54. package/dist/shared/pages/InvitePage/components/invite/index.d.ts +32 -0
  55. package/dist/shared/pages/InvitePage/components/invite/index.d.ts.map +1 -0
  56. package/dist/shared/pages/InvitePage/index.d.ts +5 -0
  57. package/dist/shared/pages/InvitePage/index.d.ts.map +1 -0
  58. package/dist/shared/pages/InvitePage/locales/index.d.ts +3 -0
  59. package/dist/shared/pages/InvitePage/locales/index.d.ts.map +1 -0
  60. package/dist/shared/pages/LoginPage/components/index.d.ts +2 -0
  61. package/dist/shared/pages/LoginPage/components/index.d.ts.map +1 -0
  62. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts +17 -0
  63. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -0
  64. package/dist/shared/pages/LoginPage/components/login/index.d.ts +28 -0
  65. package/dist/shared/pages/LoginPage/components/login/index.d.ts.map +1 -0
  66. package/dist/shared/pages/LoginPage/index.d.ts +3 -0
  67. package/dist/shared/pages/LoginPage/index.d.ts.map +1 -0
  68. package/dist/shared/pages/LoginPage/locales/index.d.ts +3 -0
  69. package/dist/shared/pages/LoginPage/locales/index.d.ts.map +1 -0
  70. package/dist/shared/pages/LoginPage/plugin.d.ts +6 -0
  71. package/dist/shared/pages/LoginPage/plugin.d.ts.map +1 -0
  72. package/dist/shared/pages/ResetPasswordPage/components/index.d.ts +2 -0
  73. package/dist/shared/pages/ResetPasswordPage/components/index.d.ts.map +1 -0
  74. package/dist/shared/pages/ResetPasswordPage/components/reset-password/ResetPassword.vue.d.ts +33 -0
  75. package/dist/shared/pages/ResetPasswordPage/components/reset-password/ResetPassword.vue.d.ts.map +1 -0
  76. package/dist/shared/pages/ResetPasswordPage/components/reset-password/index.d.ts +32 -0
  77. package/dist/shared/pages/ResetPasswordPage/components/reset-password/index.d.ts.map +1 -0
  78. package/dist/shared/pages/ResetPasswordPage/index.d.ts +5 -0
  79. package/dist/shared/pages/ResetPasswordPage/index.d.ts.map +1 -0
  80. package/dist/shared/pages/ResetPasswordPage/locales/index.d.ts +3 -0
  81. package/dist/shared/pages/ResetPasswordPage/locales/index.d.ts.map +1 -0
  82. package/dist/shared/pages/index.d.ts +10 -0
  83. package/dist/shared/pages/index.d.ts.map +1 -0
  84. package/dist/tsconfig.tsbuildinfo +1 -1
  85. package/dist/typings/index.d.ts +8 -0
  86. package/dist/typings/index.d.ts.map +1 -0
  87. package/dist/ui/components/atoms/vc-button/index.d.ts +36 -6
  88. package/dist/ui/components/atoms/vc-button/index.d.ts.map +1 -1
  89. package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts +10 -7
  90. package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts.map +1 -1
  91. package/dist/ui/components/atoms/vc-status/index.d.ts +6 -6
  92. package/dist/ui/components/atoms/vc-status/vc-status.vue.d.ts +1 -1
  93. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue.d.ts +1 -1
  94. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue.d.ts.map +1 -1
  95. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts +2 -2
  96. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
  97. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue.d.ts.map +1 -1
  98. package/dist/ui/components/organisms/vc-blade/index.d.ts +1 -31
  99. package/dist/ui/components/organisms/vc-blade/index.d.ts.map +1 -1
  100. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts +1 -6
  101. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
  102. package/dist/ui/components/organisms/vc-popup/index.d.ts +6 -6
  103. package/dist/ui/components/organisms/vc-popup/vc-popup.vue.d.ts +1 -1
  104. package/dist/ui/components/organisms/vc-popup/vc-popup.vue.d.ts.map +1 -1
  105. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts +2 -1
  106. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts.map +1 -1
  107. package/dist/ui/components/organisms/vc-table/index.d.ts +7 -7
  108. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +7 -7
  109. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  110. package/package.json +9 -7
  111. package/shared/components/app-switcher/composables/useAppSwitcher/index.ts +1 -1
  112. package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +4 -11
  113. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +4 -7
  114. package/shared/components/change-password/change-password.vue +167 -0
  115. package/shared/components/change-password/index.ts +10 -0
  116. package/shared/components/index.ts +8 -0
  117. package/shared/components/language-selector/index.ts +10 -0
  118. package/shared/components/language-selector/language-selector.vue +60 -0
  119. package/shared/components/notifications/core/notification.ts +3 -3
  120. package/shared/components/notifications/types/index.ts +4 -1
  121. package/shared/components/user-dropdown-button/index.ts +10 -0
  122. package/shared/components/user-dropdown-button/user-dropdown-button.vue +124 -0
  123. package/shared/index.ts +12 -8
  124. package/shared/locales/en.json +35 -0
  125. package/shared/locales/index.ts +2 -0
  126. package/shared/modules/assets/components/assets-details/assets-details.vue +1 -7
  127. package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +0 -6
  128. package/shared/modules/index.ts +2 -0
  129. package/shared/pages/InvitePage/components/index.ts +1 -0
  130. package/shared/pages/InvitePage/components/invite/Invite.vue +172 -0
  131. package/shared/pages/InvitePage/components/invite/index.ts +3 -0
  132. package/shared/pages/InvitePage/index.ts +7 -0
  133. package/shared/pages/InvitePage/locales/en.json +31 -0
  134. package/shared/pages/InvitePage/locales/index.ts +2 -0
  135. package/shared/pages/LoginPage/components/index.ts +1 -0
  136. package/shared/pages/LoginPage/components/login/Login.vue +283 -0
  137. package/shared/pages/LoginPage/components/login/index.ts +3 -0
  138. package/shared/pages/LoginPage/index.ts +2 -0
  139. package/shared/pages/LoginPage/locales/en.json +36 -0
  140. package/shared/pages/LoginPage/locales/index.ts +2 -0
  141. package/shared/pages/LoginPage/plugin.ts +17 -0
  142. package/shared/pages/ResetPasswordPage/components/index.ts +1 -0
  143. package/shared/pages/ResetPasswordPage/components/reset-password/ResetPassword.vue +166 -0
  144. package/shared/pages/ResetPasswordPage/components/reset-password/index.ts +3 -0
  145. package/shared/pages/ResetPasswordPage/index.ts +7 -0
  146. package/shared/pages/ResetPasswordPage/locales/en.json +28 -0
  147. package/shared/pages/ResetPasswordPage/locales/index.ts +2 -0
  148. package/shared/pages/index.ts +12 -0
  149. package/ui/components/atoms/vc-button/vc-button.vue +109 -143
  150. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +1 -1
  151. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +3 -4
  152. package/ui/components/organisms/vc-app/vc-app.vue +6 -9
  153. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +5 -8
  154. package/ui/components/organisms/vc-blade/vc-blade.vue +14 -22
  155. package/ui/components/organisms/vc-login-form/vc-login-form.stories.ts +1 -1
  156. package/ui/components/organisms/vc-popup/_internal/vc-popup-warning/vc-popup-warning.vue +1 -1
  157. package/ui/components/organisms/vc-popup/vc-popup.vue +1 -1
  158. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +5 -8
  159. package/ui/components/organisms/vc-table/vc-table.vue +25 -18
  160. package/ui/locales/en.json +3 -3
package/shared/index.ts CHANGED
@@ -4,9 +4,18 @@ import { VcAppSwitcherComponent } from "./components/app-switcher";
4
4
  import { VcBladeNavigationComponent } from "./components/blade-navigation";
5
5
  import { AssetsManagerModule } from "./modules/assets-manager";
6
6
  import { VcPopupHandler } from "./components/popup-handler";
7
+ import * as locales from "./locales";
8
+ import { i18n } from "./../core/plugins";
7
9
 
8
10
  export const SharedModule = {
9
11
  install(app: App): void {
12
+ // Load locales
13
+ if (locales) {
14
+ Object.entries(locales).forEach(([key, message]) => {
15
+ i18n.global.mergeLocaleMessage(key, message);
16
+ });
17
+ }
18
+
10
19
  app
11
20
  .use(AssetsDetailsModule)
12
21
  .use(AssetsManagerModule)
@@ -16,11 +25,6 @@ export const SharedModule = {
16
25
  },
17
26
  };
18
27
 
19
- export * from "./modules/assets";
20
- export * from "./modules/assets-manager";
21
-
22
- export * from "./components/app-switcher";
23
- export * from "./components/blade-navigation";
24
- export * from "./components/notifications";
25
- export * from "./components/error-interceptor";
26
- export * from "./components/popup-handler";
28
+ export * from "./modules";
29
+ export * from "./components";
30
+ export * from "./pages";
@@ -0,0 +1,35 @@
1
+ {
2
+ "COMPONENTS": {
3
+ "CHANGE_PASSWORD": {
4
+ "TITLE": "Change password",
5
+ "CURRENT_PASSWORD": {
6
+ "LABEL": "Current password",
7
+ "PLACEHOLDER": "Enter password"
8
+ },
9
+ "NEW_PASSWORD": {
10
+ "LABEL": "New password",
11
+ "PLACEHOLDER": "Enter password"
12
+ },
13
+ "CONFIRM_PASSWORD": {
14
+ "LABEL": "Confirm password",
15
+ "PLACEHOLDER": "Confirm password"
16
+ },
17
+ "CANCEL": "Cancel",
18
+ "SAVE": "Update",
19
+ "ERRORS": {
20
+ "Repeat-password": "Passwords are not same",
21
+ "Equal-passwords": "The new password must not match the old one",
22
+ "Invalid-token": "Token is invalid or expired",
23
+ "Password-too-weak": "New password does not comply one or more password security policies:",
24
+ "PasswordTooShort": "Passwords too short",
25
+ "PasswordRequiresUniqueChars": "Passwords must use different characters",
26
+ "PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z')",
27
+ "PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z')",
28
+ "PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9')",
29
+ "PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character",
30
+ "Incorrect password.": "You entered an incorrect password",
31
+ "You have used this password in the past. Choose another one.": "You have used this password in the past. Choose another one."
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,2 @@
1
+ import * as en from "./en.json";
2
+ export { en };
@@ -9,12 +9,6 @@
9
9
  @expand="$emit('expand:blade')"
10
10
  @collapse="$emit('collapse:blade')"
11
11
  >
12
- <template
13
- v-if="$slots['error']"
14
- #error
15
- >
16
- <slot name="error"></slot>
17
- </template>
18
12
  <!-- Blade contents -->
19
13
  <div class="tw-flex tw-grow-1 tw-border-t tw-border-solid tw-border-t-[#eaedf3]">
20
14
  <div class="assets-details__content tw-grow tw-basis-0 tw-w-full">
@@ -62,7 +56,7 @@
62
56
  icon="far fa-copy"
63
57
  size="m"
64
58
  class="tw-ml-2"
65
- variant="onlytext"
59
+ text
66
60
  title="Copy link"
67
61
  @click="copyLink(defaultAsset.url)"
68
62
  ></VcButton>
@@ -9,12 +9,6 @@
9
9
  @expand="$emit('expand:blade')"
10
10
  @collapse="$emit('collapse:blade')"
11
11
  >
12
- <template
13
- v-if="$slots['error']"
14
- #error
15
- >
16
- <slot name="error"></slot>
17
- </template>
18
12
  <div
19
13
  class="tw-relative tw-h-full"
20
14
  @dragover.prevent.stop="dragOver"
@@ -0,0 +1,2 @@
1
+ export * from "./assets";
2
+ export * from "./assets-manager";
@@ -0,0 +1 @@
1
+ export * from "./invite";
@@ -0,0 +1,172 @@
1
+ <template>
2
+ <div class="vc-app tw-w-full tw-h-full tw-box-border tw-flex tw-flex-col tw-m-0 vc-theme_light">
3
+ <VcLoading
4
+ v-if="loading"
5
+ active
6
+ ></VcLoading>
7
+
8
+ <VcLoginForm
9
+ logo="/assets/logo-white.svg"
10
+ background="/assets/background.jpg"
11
+ :title="$t('INVITATION.TITLE')"
12
+ >
13
+ <VcForm>
14
+ <VcInput
15
+ class="tw-mb-4 tw-mt-1"
16
+ :label="$t('INVITATION.FIELDS.EMAIL.LABEL')"
17
+ :model-value="userName"
18
+ name="username"
19
+ disabled
20
+ ></VcInput>
21
+ <Field
22
+ v-slot="{ field, errorMessage, handleChange, errors }"
23
+ :label="$t('INVITATION.FIELDS.PASSWORD.LABEL')"
24
+ :model-value="form.password"
25
+ rules="required"
26
+ name="password"
27
+ >
28
+ <VcInput
29
+ v-bind="field"
30
+ ref="passwordField"
31
+ v-model="form.password"
32
+ class="tw-mb-4 tw-mt-1"
33
+ :label="$t('INVITATION.FIELDS.PASSWORD.LABEL')"
34
+ :placeholder="$t('INVITATION.FIELDS.PASSWORD.PLACEHOLDER')"
35
+ type="password"
36
+ :disabled="!form.tokenIsValid"
37
+ :error="!!errors.length"
38
+ :error-message="errorMessage"
39
+ required
40
+ @update:model-value="
41
+ (e) => {
42
+ handleChange(e);
43
+ validate();
44
+ }
45
+ "
46
+ ></VcInput>
47
+ </Field>
48
+ <Field
49
+ v-slot="{ field, errorMessage, handleChange, errors }"
50
+ :label="$t('INVITATION.FIELDS.CONFIRM_PASSWORD.LABEL')"
51
+ :model-value="form.confirmPassword"
52
+ rules="required"
53
+ name="confirm_password"
54
+ >
55
+ <VcInput
56
+ v-bind="field"
57
+ ref="confirmPasswordField"
58
+ v-model="form.confirmPassword"
59
+ class="tw-mb-4"
60
+ :label="$t('INVITATION.FIELDS.CONFIRM_PASSWORD.LABEL')"
61
+ :placeholder="$t('INVITATION.FIELDS.CONFIRM_PASSWORD.PLACEHOLDER')"
62
+ :disabled="!form.tokenIsValid"
63
+ type="password"
64
+ :error="!!errors.length"
65
+ :error-message="errorMessage"
66
+ required
67
+ @update:model-value="
68
+ (e) => {
69
+ handleChange(e);
70
+ validate();
71
+ }
72
+ "
73
+ @keyup.enter="acceptInvitation"
74
+ ></VcInput>
75
+ </Field>
76
+ <div class="tw-flex tw-justify-center tw-items-center tw-pt-2">
77
+ <span
78
+ v-if="$isDesktop.value"
79
+ class="tw-grow tw-basis-0"
80
+ ></span>
81
+ <vc-button
82
+ :disabled="loading || !form.isValid || !form.tokenIsValid"
83
+ @click="acceptInvitation"
84
+ >
85
+ {{ $t("INVITATION.ACCEPT_INVITATION") }}
86
+ </vc-button>
87
+ </div>
88
+
89
+ <VcHint
90
+ v-for="error in form.errors"
91
+ :key="error"
92
+ class="tw-mt-3"
93
+ style="color: #f14e4e"
94
+ >
95
+ <!-- TODO: stylizing-->
96
+ {{ $t(`INVITATION.ERRORS.${error}`) }}
97
+ </VcHint>
98
+ </VcForm>
99
+ </VcLoginForm>
100
+ </div>
101
+ </template>
102
+
103
+ <script lang="ts" setup>
104
+ import { reactive, onMounted, computed } from "vue";
105
+ import { useRouter } from "vue-router";
106
+ import { useIsFormValid, Field, useIsFormDirty, useForm } from "vee-validate";
107
+ import { useUser } from "./../../../../../core/composables";
108
+
109
+ useForm({ validateOnMount: false });
110
+
111
+ const props = defineProps({
112
+ userId: {
113
+ type: String,
114
+ default: undefined,
115
+ },
116
+ userName: {
117
+ type: String,
118
+ default: undefined,
119
+ },
120
+ token: {
121
+ type: String,
122
+ default: undefined,
123
+ },
124
+ });
125
+ const { validateToken, validatePassword, resetPasswordByToken, signIn, loading } = useUser();
126
+ const router = useRouter();
127
+ const isFormValid = useIsFormValid();
128
+ const isDirty = useIsFormDirty();
129
+ const form = reactive({
130
+ isValid: false,
131
+ tokenIsValid: false,
132
+ errors: [],
133
+ password: "",
134
+ confirmPassword: "",
135
+ });
136
+
137
+ const isDisabled = computed(() => {
138
+ return !isDirty.value || !isFormValid.value;
139
+ });
140
+
141
+ onMounted(async () => {
142
+ form.tokenIsValid = await validateToken(props.userId, props.token);
143
+ if (!form.tokenIsValid) {
144
+ form.errors.push("Invalid-token");
145
+ }
146
+ });
147
+
148
+ const validate = async () => {
149
+ if (form.tokenIsValid) {
150
+ const errors = (await validatePassword(form.password)).errors;
151
+ form.errors = errors.map((x) => x.code);
152
+ if (form.confirmPassword && form.confirmPassword !== form.password) {
153
+ form.errors.push("Repeat-password");
154
+ }
155
+ form.isValid = form.errors.length == 0 && !isDisabled.value;
156
+ }
157
+ };
158
+
159
+ const acceptInvitation = async () => {
160
+ const result = await resetPasswordByToken(props.userId, form.password, props.token);
161
+ if (result.succeeded) {
162
+ const result = await signIn(props.userName, form.password);
163
+ if (result.succeeded) {
164
+ router.push("/");
165
+ } else {
166
+ form.errors = [result.errorCode];
167
+ }
168
+ } else {
169
+ form.errors = result.errors;
170
+ }
171
+ };
172
+ </script>
@@ -0,0 +1,3 @@
1
+ import _Invite from "./Invite.vue";
2
+
3
+ export const Invite = _Invite as typeof _Invite;
@@ -0,0 +1,7 @@
1
+ import { createModule } from "./../../../core/plugins";
2
+ import * as components from "./components";
3
+ import * as locales from "./locales";
4
+
5
+ export const InvitePage = createModule(components, locales);
6
+
7
+ export * from "./components";
@@ -0,0 +1,31 @@
1
+ {
2
+ "INVITATION": {
3
+ "TITLE": "New user activation",
4
+ "FIELDS": {
5
+ "EMAIL": {
6
+ "LABEL": "Email"
7
+ },
8
+ "PASSWORD": {
9
+ "LABEL": "New password",
10
+ "PLACEHOLDER": "Enter password"
11
+ },
12
+ "CONFIRM_PASSWORD": {
13
+ "LABEL": "Confirm password",
14
+ "PLACEHOLDER": "Confirm password"
15
+ }
16
+ },
17
+ "ACCEPT_INVITATION": "Activate",
18
+ "ERRORS": {
19
+ "Repeat-password": "Passwords are not same",
20
+ "Invalid-token": "Token is invalid or expired",
21
+ "Password-too-weak": "New password does not comply one or more password security policies:",
22
+ "PasswordTooShort": "Passwords too short",
23
+ "PasswordRequiresUniqueChars": "Passwords must use different characters",
24
+ "PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z')",
25
+ "PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z')",
26
+ "PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9')",
27
+ "PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character",
28
+ "recentPasswordUsed": "You have used this password in the past. Choose another one."
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,2 @@
1
+ import * as en from "./en.json";
2
+ export { en };
@@ -0,0 +1 @@
1
+ export * from "./login";
@@ -0,0 +1,283 @@
1
+ <template>
2
+ <VcLoginForm
3
+ :logo="customization.logo"
4
+ :background="background"
5
+ :title="title"
6
+ >
7
+ <template v-if="isLogin">
8
+ <VcForm @submit.prevent="login">
9
+ <Field
10
+ v-slot="{ field, errorMessage, handleChange, errors }"
11
+ :label="$t('LOGIN.FIELDS.LOGIN.LABEL')"
12
+ name="username"
13
+ :model-value="form.username"
14
+ rules="required"
15
+ >
16
+ <VcInput
17
+ v-bind="field"
18
+ ref="loginField"
19
+ v-model="form.username"
20
+ class="tw-mb-4 tw-mt-1"
21
+ :label="$t('LOGIN.FIELDS.LOGIN.LABEL')"
22
+ :placeholder="$t('LOGIN.FIELDS.LOGIN.PLACEHOLDER')"
23
+ required
24
+ :error="!!errors.length"
25
+ :error-message="errorMessage"
26
+ @update:model-value="handleChange"
27
+ />
28
+ </Field>
29
+ <Field
30
+ v-slot="{ field, errorMessage, handleChange, errors }"
31
+ :label="$t('LOGIN.FIELDS.PASSWORD.LABEL')"
32
+ name="password"
33
+ :model-value="form.password"
34
+ rules="required"
35
+ >
36
+ <VcInput
37
+ v-bind="field"
38
+ ref="passwordField"
39
+ v-model="form.password"
40
+ class="tw-mb-4"
41
+ :label="$t('LOGIN.FIELDS.PASSWORD.LABEL')"
42
+ :placeholder="$t('LOGIN.FIELDS.PASSWORD.PLACEHOLDER')"
43
+ type="password"
44
+ required
45
+ :error="!!errors.length"
46
+ :error-message="errorMessage"
47
+ @keyup.enter="login"
48
+ @update:model-value="handleChange"
49
+ />
50
+ </Field>
51
+
52
+ <div class="tw-flex tw-justify-end tw-items-center tw-pt-2">
53
+ <VcButton
54
+ text
55
+ type="button"
56
+ @click="togglePassRequest"
57
+ >
58
+ {{ $t("LOGIN.FORGOT_PASSWORD_BUTTON") }}
59
+ </VcButton>
60
+ </div>
61
+ <div class="tw-flex tw-justify-center tw-items-center tw-pt-2">
62
+ <vc-button
63
+ :disabled="loading || !isValid"
64
+ class="tw-w-28"
65
+ @click="login"
66
+ >
67
+ {{ $t("LOGIN.BUTTON") }}
68
+ </vc-button>
69
+ </div>
70
+ </VcForm>
71
+ <div
72
+ v-if="azureAdAuthAvailable && azureAdAuthCaption"
73
+ class="tw-mt-4"
74
+ >
75
+ <div
76
+ class="tw-flex tw-items-center tw-text-center tw-uppercase tw-text-[color:var(--separator-text)] before:tw-content-[''] before:tw-flex-1 before:tw-border-b before:tw-border-b-[color:var(--separator)] before:tw-mr-2 after:tw-content-[''] after:tw-flex-1 after:tw-border-b after:tw-border-b-[color:var(--separator)] after:tw-ml-2"
77
+ >
78
+ OR
79
+ </div>
80
+ <div class="tw-flex tw-justify-center tw-mt-4">
81
+ <VcButton
82
+ outline
83
+ @click="azureSignOn"
84
+ ><div class="tw-flex tw-flex-row tw-items-center">
85
+ <img
86
+ :src="AzureAdIcon"
87
+ alt="AzureAd"
88
+ class="tw-h-5 tw-mr-2"
89
+ />{{ azureAdAuthCaption }}
90
+ </div></VcButton
91
+ >
92
+ </div>
93
+ </div>
94
+ </template>
95
+ <template v-else>
96
+ <template v-if="!forgotPasswordRequestSent">
97
+ <VcForm @submit.prevent="forgot">
98
+ <Field
99
+ v-slot="{ field, errorMessage, handleChange, errors }"
100
+ :label="$t('LOGIN.FIELDS.FORGOT_PASSWORD.LABEL')"
101
+ name="loginOrEmail"
102
+ :model-value="forgotPasswordForm.loginOrEmail"
103
+ rules="required|email"
104
+ >
105
+ <VcInput
106
+ v-bind="field"
107
+ ref="forgotPasswordField"
108
+ v-model="forgotPasswordForm.loginOrEmail"
109
+ class="tw-mb-4 tw-mt-1"
110
+ :label="$t('LOGIN.FIELDS.FORGOT_PASSWORD.LABEL')"
111
+ :placeholder="$t('LOGIN.FIELDS.FORGOT_PASSWORD.PLACEHOLDER')"
112
+ :hint="$t('LOGIN.RESET_EMAIL_TEXT')"
113
+ required
114
+ :error="!!errors.length"
115
+ :error-message="errorMessage"
116
+ @update:model-value="handleChange"
117
+ ></VcInput>
118
+ </Field>
119
+ <div class="tw-flex tw-justify-between tw-items-center tw-pt-2">
120
+ <vc-button
121
+ text
122
+ type="button"
123
+ @click="togglePassRequest"
124
+ >
125
+ {{ $t("LOGIN.BACK_BUTTON") }}
126
+ </vc-button>
127
+ <vc-button
128
+ :disabled="loading || isDisabled"
129
+ @click="forgot"
130
+ >
131
+ {{ $t("LOGIN.FORGOT_BUTTON") }}
132
+ </vc-button>
133
+ </div>
134
+ </VcForm>
135
+ </template>
136
+
137
+ <template v-if="requestPassResult.succeeded && forgotPasswordRequestSent">
138
+ <div>{{ $t("LOGIN.RESET_EMAIL_SENT") }}</div>
139
+ <div class="tw-flex tw-justify-center tw-items-center tw-pt-2">
140
+ <span
141
+ v-if="$isDesktop.value"
142
+ class="tw-grow tw-basis-0"
143
+ ></span>
144
+ <vc-button
145
+ :disabled="loading"
146
+ @click="togglePassRequest"
147
+ >
148
+ {{ $t("LOGIN.BUTTON_OK") }}
149
+ </vc-button>
150
+ </div>
151
+ </template>
152
+ </template>
153
+
154
+ <VcHint
155
+ v-if="!signInResult.succeeded"
156
+ class="tw-mt-3"
157
+ style="color: #f14e4e"
158
+ >
159
+ <!-- TODO: stylizing-->
160
+ {{ signInResult.error }}
161
+ </VcHint>
162
+ <VcHint
163
+ v-if="!requestPassResult.succeeded"
164
+ class="tw-mt-3"
165
+ style="color: #f14e4e"
166
+ >
167
+ <!-- TODO: stylizing-->
168
+ {{ requestPassResult.error }}
169
+ </VcHint>
170
+ </VcLoginForm>
171
+ </template>
172
+
173
+ <script lang="ts" setup>
174
+ import { ref, reactive, computed, onMounted, inject } from "vue";
175
+ import { useRouter } from "vue-router";
176
+ import { useIsFormValid, Field, useIsFormDirty, useForm } from "vee-validate";
177
+ import { useSettings, useUser } from "./../../../../../core/composables";
178
+ import { RequestPasswordResult, SignInResults } from "./../../../../../core/types";
179
+ import { CommonPageComposables } from "typings";
180
+ import { asyncComputed } from "@vueuse/core";
181
+ import AzureAdIcon from "./../../../../../assets/img/AzureAd.svg";
182
+
183
+ export interface Props {
184
+ logo: string;
185
+ background: string;
186
+ title: string;
187
+ }
188
+
189
+ const props = defineProps<Props>();
190
+
191
+ const router = useRouter();
192
+
193
+ useForm({ validateOnMount: false });
194
+ const { getUiCustomizationSettings, uiSettings } = useSettings();
195
+ const { useLogin } = inject<CommonPageComposables>("commonPageComposables");
196
+
197
+ const signInResult = ref<SignInResults>({ succeeded: true });
198
+ const requestPassResult = ref<RequestPasswordResult>({ succeeded: true });
199
+ const forgotPasswordRequestSent = ref(false);
200
+ const { signIn, loading, loadUser, externalSignIn, isAzureAdAuthAvailable, getAzureAdAuthCaption } = useUser();
201
+ const { forgotPassword } = useLogin();
202
+ const isLogin = ref(true);
203
+ const isValid = useIsFormValid();
204
+ const isDirty = useIsFormDirty();
205
+ const customizationLoading = ref(false);
206
+
207
+ onMounted(async () => {
208
+ try {
209
+ customizationLoading.value = true;
210
+ await getUiCustomizationSettings(import.meta.env.APP_PLATFORM_URL);
211
+ } finally {
212
+ customizationLoading.value = false;
213
+ }
214
+ });
215
+
216
+ const customization = computed(() => {
217
+ return (
218
+ !customizationLoading.value && {
219
+ logo: uiSettings.value?.logo || props.logo,
220
+ }
221
+ );
222
+ });
223
+
224
+ const isDisabled = computed(() => {
225
+ return !isDirty.value || !isValid.value;
226
+ });
227
+
228
+ const azureAdAuthAvailable = asyncComputed(async () => {
229
+ return await isAzureAdAuthAvailable();
230
+ });
231
+ const azureAdAuthCaption = asyncComputed(async () => {
232
+ return await getAzureAdAuthCaption();
233
+ });
234
+
235
+ const form = reactive({
236
+ username: "",
237
+ password: "",
238
+ });
239
+
240
+ const forgotPasswordForm = reactive({
241
+ loginOrEmail: "",
242
+ });
243
+
244
+ const login = async () => {
245
+ if (isValid.value) {
246
+ signInResult.value = await signIn(form.username, form.password);
247
+
248
+ if (signInResult.value.succeeded) {
249
+ router.push("/");
250
+ }
251
+ }
252
+ };
253
+
254
+ const forgot = async () => {
255
+ if (isValid.value) {
256
+ await forgotPassword({ loginOrEmail: forgotPasswordForm.loginOrEmail });
257
+ forgotPasswordRequestSent.value = true;
258
+ }
259
+ };
260
+
261
+ const togglePassRequest = () => {
262
+ isLogin.value = !isLogin.value;
263
+ if (isLogin.value) {
264
+ forgotPasswordRequestSent.value = false;
265
+ forgotPasswordForm.loginOrEmail = "";
266
+ requestPassResult.value.error = "";
267
+ }
268
+ };
269
+
270
+ const azureSignOn = async () => {
271
+ await externalSignIn("AzureAD", import.meta.env.BASE_URL);
272
+ await loadUser();
273
+ };
274
+
275
+ console.debug("Init login-page");
276
+ </script>
277
+
278
+ <style lang="scss">
279
+ :root {
280
+ --separator: #d3dbe9;
281
+ --separator-text: #83a3be;
282
+ }
283
+ </style>
@@ -0,0 +1,3 @@
1
+ import _Login from "./Login.vue";
2
+
3
+ export const Login = _Login as typeof _Login;
@@ -0,0 +1,2 @@
1
+ export * from "./plugin";
2
+ export * from "./components";
@@ -0,0 +1,36 @@
1
+ {
2
+ "LOGIN": {
3
+ "FIELDS": {
4
+ "LOGIN": {
5
+ "LABEL": "Username",
6
+ "PLACEHOLDER": "Enter your username"
7
+ },
8
+ "PASSWORD": {
9
+ "LABEL": "Password",
10
+ "PLACEHOLDER": "Enter your password"
11
+ },
12
+ "FORGOT_PASSWORD": {
13
+ "TITLE": "Forgot password",
14
+ "LABEL": "Email",
15
+ "PLACEHOLDER": "Please enter your email"
16
+ }
17
+ },
18
+ "FORGOT_PASSWORD_BUTTON": "Forgot your password?",
19
+ "BUTTON": "Log in",
20
+ "FORGOT_BUTTON": "Submit",
21
+ "BACK_BUTTON": "Back",
22
+ "BUTTON_OK": "Ok",
23
+ "RESET_EMAIL_TEXT": "We will send you an email with instructions on how to reset your password.",
24
+ "RESET_EMAIL_SENT": "Email with instructions has been sent to you."
25
+ },
26
+ "MENU": {
27
+ "DASHBOARD": "Home"
28
+ },
29
+ "TOOLBAR": {
30
+ "LOGIN": "Log In",
31
+ "SETTINGS": "Settings",
32
+ "HELP": "Help",
33
+ "NOTIFICATIONS": "Notifications",
34
+ "LANGUAGE": "Language selector"
35
+ }
36
+ }
@@ -0,0 +1,2 @@
1
+ import * as en from "./en.json";
2
+ export { en };