@vc-shell/vc-app-skill 2.0.0-alpha.33 → 2.0.0-alpha.34
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.
- package/CHANGELOG.md +78 -54
- package/README.md +42 -12
- package/package.json +4 -4
- package/runtime/VERSION +1 -1
- package/runtime/agents/api-analyzer.md +31 -16
- package/runtime/agents/blade-enhancer.md +15 -9
- package/runtime/agents/details-blade-generator.md +47 -31
- package/runtime/agents/list-blade-generator.md +21 -37
- package/runtime/agents/locales-generator.md +3 -0
- package/runtime/agents/migration-agent.md +18 -7
- package/runtime/agents/module-analyzer.md +2 -0
- package/runtime/agents/module-assembler.md +15 -0
- package/runtime/agents/promote-agent.md +15 -4
- package/runtime/agents/type-checker.md +11 -0
- package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
- package/runtime/knowledge/docs/core/api/platform.docs.md +30 -30
- package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +41 -41
- package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +12 -10
- package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +11 -14
- package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +35 -35
- package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +35 -35
- package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +15 -15
- package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +21 -18
- package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +28 -24
- package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +90 -61
- package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +19 -18
- package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +89 -68
- package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +27 -25
- package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
- package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +43 -47
- package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +11 -11
- package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +27 -15
- package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +30 -30
- package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +34 -36
- package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +44 -23
- package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +14 -11
- package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +47 -38
- package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +37 -28
- package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +23 -17
- package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +9 -9
- package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +42 -42
- package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +22 -12
- package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +33 -41
- package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +16 -16
- package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +28 -0
- package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +32 -24
- package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +32 -11
- package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +22 -13
- package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +7 -7
- package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +32 -24
- package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +21 -17
- package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +24 -24
- package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +28 -31
- package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +43 -24
- package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +68 -48
- package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +19 -19
- package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +42 -47
- package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +10 -4
- package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +35 -20
- package/runtime/knowledge/docs/core/notifications/notifications.docs.md +36 -35
- package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +38 -38
- package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +79 -62
- package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +10 -10
- package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +21 -23
- package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +91 -83
- package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +10 -16
- package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +9 -9
- package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +65 -22
- package/runtime/knowledge/docs/core/services/services.docs.md +19 -22
- package/runtime/knowledge/docs/core/types/types.docs.md +40 -40
- package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +27 -27
- package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +23 -23
- package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +22 -25
- package/runtime/knowledge/docs/core/utilities/utilities.docs.md +64 -64
- package/runtime/knowledge/docs/injection-keys.docs.md +52 -51
- package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +9 -9
- package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +23 -43
- package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +5 -5
- package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +5 -5
- package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +8 -7
- package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -7
- package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +8 -7
- package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +29 -13
- package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +13 -16
- package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +1 -7
- package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +5 -5
- package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -9
- package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +11 -17
- package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +34 -65
- package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +16 -26
- package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +2 -2
- package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -9
- package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +30 -40
- package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +26 -19
- package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +15 -12
- package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +15 -26
- package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +21 -19
- package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +83 -67
- package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +100 -59
- package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +28 -11
- package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +20 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +26 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +30 -32
- package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +25 -48
- package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +29 -24
- package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +23 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +22 -13
- package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +33 -18
- package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +56 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +28 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +40 -20
- package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +25 -14
- package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +40 -14
- package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +54 -42
- package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +17 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +21 -21
- package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +23 -10
- package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +55 -44
- package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +23 -20
- package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +92 -65
- package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +22 -36
- package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +65 -23
- package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +52 -73
- package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +91 -85
- package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +38 -42
- package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +56 -73
- package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +61 -27
- package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +42 -50
- package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +35 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +38 -41
- package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +109 -131
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +47 -88
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +50 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +29 -24
- package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +32 -28
- package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +57 -65
- package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +28 -26
- package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +55 -20
- package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +21 -35
- package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +38 -33
- package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +72 -83
- package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +21 -16
- package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +55 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +51 -70
- package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +58 -57
- package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +49 -26
- package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +82 -28
- package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +90 -75
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +99 -48
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +548 -367
- package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +35 -52
- package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +33 -62
- package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +17 -23
- package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +109 -68
- package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +82 -44
- package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +8 -8
- package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +164 -0
- package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +34 -26
- package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +48 -40
- package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +30 -17
- package/runtime/knowledge/docs/ui/types/ui-types.docs.md +40 -29
- package/runtime/knowledge/examples/offers-module.md +15 -13
- package/runtime/knowledge/examples/team-module.md +82 -119
- package/runtime/knowledge/examples/videos-module.md +44 -17
- package/runtime/knowledge/index.md +22 -0
- package/runtime/knowledge/migration-prompts/blade-form-migration.md +17 -8
- package/runtime/knowledge/migration-prompts/blade-props-migration.md +1 -2
- package/runtime/knowledge/migration-prompts/datatable-migration.md +801 -0
- package/runtime/knowledge/migration-prompts/icon-migration.md +97 -0
- package/runtime/knowledge/migration-prompts/manual-migration-audit.md +117 -0
- package/runtime/knowledge/migration-prompts/notifications-migration.md +8 -3
- package/runtime/knowledge/migration-prompts/nswag-migration.md +25 -29
- package/runtime/knowledge/migration-prompts/use-assets-migration.md +164 -0
- package/runtime/knowledge/migration-prompts/use-data-table-pagination-migration.md +176 -0
- package/runtime/knowledge/migration-prompts/widgets-migration.md +48 -27
- package/runtime/knowledge/patterns/assets-management.md +20 -20
- package/runtime/knowledge/patterns/blade-navigation.md +7 -14
- package/runtime/knowledge/patterns/blade-widget.md +19 -17
- package/runtime/knowledge/patterns/child-blade-flow.md +19 -7
- package/runtime/knowledge/patterns/composable-details.md +20 -50
- package/runtime/knowledge/patterns/composable-list.md +43 -31
- package/runtime/knowledge/patterns/dashboard-widget.md +14 -16
- package/runtime/knowledge/patterns/datatable-pattern.md +521 -0
- package/runtime/knowledge/patterns/details-blade-pattern.md +78 -116
- package/runtime/knowledge/patterns/extension-points-usage.md +53 -44
- package/runtime/knowledge/patterns/form-validation.md +28 -64
- package/runtime/knowledge/patterns/list-blade-pattern.md +33 -21
- package/runtime/knowledge/patterns/module-structure.md +7 -1
- package/runtime/knowledge/patterns/multilanguage-fields.md +8 -14
- package/runtime/knowledge/patterns/notification-template.md +21 -14
- package/runtime/knowledge/patterns/signalr-notifications.md +30 -32
- package/runtime/knowledge/patterns/toolbar-pattern.md +18 -20
- package/runtime/vc-app.md +241 -62
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Shared composable exposing the full user management API: sign-in, sign-out, password reset, token validation, and login type discovery. This composable extends the same internal logic as `useUser` but surfaces the administrative and authentication-flow methods that `useUser` intentionally hides. The separation ensures that regular blades only have access to read-only user state, while auth pages and admin screens get the full API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Both `useUser()` and `useUserManagement()` read from the same singleton internal logic, so everything is shared: the `user` ref, `authData`, the `loading` ref, in-flight request deduplication (`loadUser`), and the underlying `SecurityClient` instance. The two composables are thin selectors over a single source of truth — picking a narrow read-only slice or the full management slice.
|
|
6
6
|
|
|
7
7
|
## When to Use
|
|
8
8
|
|
|
@@ -17,29 +17,45 @@ Uses `createSharedComposable` from VueUse, so all callers share the same state i
|
|
|
17
17
|
|
|
18
18
|
```vue
|
|
19
19
|
<script setup lang="ts">
|
|
20
|
-
import { useUserManagement } from
|
|
21
|
-
import { ref } from
|
|
20
|
+
import { useUserManagement } from "@vc-shell/framework";
|
|
21
|
+
import { ref } from "vue";
|
|
22
22
|
|
|
23
23
|
const { signIn, loading, isAuthenticated } = useUserManagement();
|
|
24
|
-
const username = ref(
|
|
25
|
-
const password = ref(
|
|
26
|
-
const errorMessage = ref(
|
|
24
|
+
const username = ref("");
|
|
25
|
+
const password = ref("");
|
|
26
|
+
const errorMessage = ref("");
|
|
27
27
|
|
|
28
28
|
async function handleLogin() {
|
|
29
|
-
errorMessage.value =
|
|
29
|
+
errorMessage.value = "";
|
|
30
30
|
const result = await signIn(username.value, password.value);
|
|
31
31
|
if (!result.succeeded) {
|
|
32
|
-
errorMessage.value = result.error ??
|
|
32
|
+
errorMessage.value = result.error ?? "Login failed";
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
</script>
|
|
36
36
|
|
|
37
37
|
<template>
|
|
38
38
|
<form @submit.prevent="handleLogin">
|
|
39
|
-
<VcInput
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
<VcInput
|
|
40
|
+
v-model="username"
|
|
41
|
+
label="Username"
|
|
42
|
+
/>
|
|
43
|
+
<VcInput
|
|
44
|
+
v-model="password"
|
|
45
|
+
label="Password"
|
|
46
|
+
type="password"
|
|
47
|
+
/>
|
|
48
|
+
<p
|
|
49
|
+
v-if="errorMessage"
|
|
50
|
+
class="tw-text-red-500"
|
|
51
|
+
>
|
|
52
|
+
{{ errorMessage }}
|
|
53
|
+
</p>
|
|
54
|
+
<VcButton
|
|
55
|
+
type="submit"
|
|
56
|
+
:loading="loading"
|
|
57
|
+
>Sign In</VcButton
|
|
58
|
+
>
|
|
43
59
|
</form>
|
|
44
60
|
</template>
|
|
45
61
|
```
|
|
@@ -52,25 +68,25 @@ None.
|
|
|
52
68
|
|
|
53
69
|
### Returns
|
|
54
70
|
|
|
55
|
-
| Property
|
|
56
|
-
|
|
57
|
-
| `user`
|
|
58
|
-
| `loading`
|
|
59
|
-
| `isAdministrator`
|
|
60
|
-
| `isAuthenticated`
|
|
61
|
-
| `signIn`
|
|
62
|
-
| `signOut`
|
|
63
|
-
| `loadUser`
|
|
64
|
-
| `validateToken`
|
|
65
|
-
| `validatePassword`
|
|
66
|
-
| `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>`
|
|
67
|
-
| `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>`
|
|
68
|
-
| `changeUserPassword`
|
|
69
|
-
| `getLoginType`
|
|
71
|
+
| Property | Type | Description |
|
|
72
|
+
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
73
|
+
| `user` | `ComputedRef<UserDetail \| undefined>` | Current user details. |
|
|
74
|
+
| `loading` | `ComputedRef<boolean>` | Whether any operation is in progress. |
|
|
75
|
+
| `isAdministrator` | `ComputedRef<boolean \| undefined>` | Admin status of the current user. |
|
|
76
|
+
| `isAuthenticated` | `ComputedRef<boolean>` | Whether user session is active. |
|
|
77
|
+
| `signIn` | `(username: string, password: string) => Promise<SignInResult>` | Authenticates with username/password. Performs cookie-based login, obtains an OAuth token with offline_access scope, and loads user details. Returns `{ succeeded: true }` on success or `{ succeeded: false, error: string }` on failure. |
|
|
78
|
+
| `signOut` | `() => Promise<void>` | Clears session, auth data, and localStorage. Handles both standard and external SSO sign-out. |
|
|
79
|
+
| `loadUser` | `() => Promise<UserDetail>` | Loads/reloads user info from the server. Deduplicates concurrent calls. |
|
|
80
|
+
| `validateToken` | `(userId: string, token: string) => Promise<boolean>` | Validates a password-reset token. Returns `true` if valid. |
|
|
81
|
+
| `validatePassword` | `(password: string) => Promise<IdentityResult>` | Validates a password against the platform's password policy (length, complexity, etc.). |
|
|
82
|
+
| `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>` | Resets a user's password using a reset token. Returns `{ succeeded: true }` on success. |
|
|
83
|
+
| `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>` | Sends a password-reset email to the user. Returns `{ succeeded: true }` on success. |
|
|
84
|
+
| `changeUserPassword` | `(oldPassword: string, newPassword: string) => Promise<SecurityResult \| undefined>` | Changes the current user's password. Requires the old password for verification. |
|
|
85
|
+
| `getLoginType` | `() => Promise<LoginType[]>` | Returns available login types (password-based, external SSO providers, etc.). Used to render the appropriate sign-in UI. |
|
|
70
86
|
|
|
71
87
|
## How It Works
|
|
72
88
|
|
|
73
|
-
The composable
|
|
89
|
+
The composable reads from the singleton internal user logic (instantiated lazily on first call to `useUser()` or `useUserManagement()`). The `signIn` flow has three phases:
|
|
74
90
|
|
|
75
91
|
1. **Cookie login**: Calls `securityClient.login()` to establish a server-side session cookie.
|
|
76
92
|
2. **OAuth token**: Fetches an OAuth token via `POST /connect/token` with `grant_type: password` and `scope: offline_access`. The refresh token enables automatic token renewal.
|
|
@@ -82,9 +98,9 @@ Token data is stored in localStorage under `vc_auth_data` and survives page relo
|
|
|
82
98
|
|
|
83
99
|
```vue
|
|
84
100
|
<script setup lang="ts">
|
|
85
|
-
import { useUserManagement } from
|
|
86
|
-
import { ref } from
|
|
87
|
-
import { useRoute, useRouter } from
|
|
101
|
+
import { useUserManagement } from "@vc-shell/framework";
|
|
102
|
+
import { ref } from "vue";
|
|
103
|
+
import { useRoute, useRouter } from "vue-router";
|
|
88
104
|
|
|
89
105
|
const { validateToken, validatePassword, resetPasswordByToken, loading } = useUserManagement();
|
|
90
106
|
const route = useRoute();
|
|
@@ -92,39 +108,39 @@ const router = useRouter();
|
|
|
92
108
|
|
|
93
109
|
const userId = route.query.userId as string;
|
|
94
110
|
const token = route.query.token as string;
|
|
95
|
-
const newPassword = ref(
|
|
96
|
-
const confirmPassword = ref(
|
|
97
|
-
const error = ref(
|
|
111
|
+
const newPassword = ref("");
|
|
112
|
+
const confirmPassword = ref("");
|
|
113
|
+
const error = ref("");
|
|
98
114
|
const tokenValid = ref(false);
|
|
99
115
|
|
|
100
116
|
// Validate the token on mount
|
|
101
117
|
onMounted(async () => {
|
|
102
118
|
tokenValid.value = await validateToken(userId, token);
|
|
103
119
|
if (!tokenValid.value) {
|
|
104
|
-
error.value =
|
|
120
|
+
error.value = "This reset link has expired or is invalid.";
|
|
105
121
|
}
|
|
106
122
|
});
|
|
107
123
|
|
|
108
124
|
async function handleReset() {
|
|
109
|
-
error.value =
|
|
125
|
+
error.value = "";
|
|
110
126
|
|
|
111
127
|
if (newPassword.value !== confirmPassword.value) {
|
|
112
|
-
error.value =
|
|
128
|
+
error.value = "Passwords do not match.";
|
|
113
129
|
return;
|
|
114
130
|
}
|
|
115
131
|
|
|
116
132
|
// Validate against password policy
|
|
117
133
|
const validation = await validatePassword(newPassword.value);
|
|
118
134
|
if (!validation.succeeded) {
|
|
119
|
-
error.value = validation.errors?.join(
|
|
135
|
+
error.value = validation.errors?.join(", ") ?? "Password does not meet requirements.";
|
|
120
136
|
return;
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
const result = await resetPasswordByToken(userId, newPassword.value, token);
|
|
124
140
|
if (result.succeeded) {
|
|
125
|
-
router.push({ name:
|
|
141
|
+
router.push({ name: "SignIn", query: { message: "Password reset successfully" } });
|
|
126
142
|
} else {
|
|
127
|
-
error.value = result.errors?.join(
|
|
143
|
+
error.value = result.errors?.join(", ") ?? "Reset failed.";
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
</script>
|
|
@@ -134,8 +150,8 @@ async function handleReset() {
|
|
|
134
150
|
|
|
135
151
|
```vue
|
|
136
152
|
<script setup lang="ts">
|
|
137
|
-
import { useUserManagement } from
|
|
138
|
-
import { ref, onMounted } from
|
|
153
|
+
import { useUserManagement } from "@vc-shell/framework";
|
|
154
|
+
import { ref, onMounted } from "vue";
|
|
139
155
|
|
|
140
156
|
const { getLoginType, signIn } = useUserManagement();
|
|
141
157
|
const loginTypes = ref<LoginType[]>([]);
|
|
@@ -144,20 +160,24 @@ const showPasswordForm = ref(false);
|
|
|
144
160
|
onMounted(async () => {
|
|
145
161
|
loginTypes.value = await getLoginType();
|
|
146
162
|
// Show password form only if password auth is available
|
|
147
|
-
showPasswordForm.value = loginTypes.value.some((t) => t.loginProvider ===
|
|
163
|
+
showPasswordForm.value = loginTypes.value.some((t) => t.loginProvider === "password");
|
|
148
164
|
});
|
|
149
165
|
</script>
|
|
150
166
|
|
|
151
167
|
<template>
|
|
152
168
|
<div>
|
|
153
|
-
<form
|
|
169
|
+
<form
|
|
170
|
+
v-if="showPasswordForm"
|
|
171
|
+
@submit.prevent="handlePasswordLogin"
|
|
172
|
+
>
|
|
154
173
|
<!-- standard username/password form -->
|
|
155
174
|
</form>
|
|
156
175
|
|
|
157
|
-
<div
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
<div
|
|
177
|
+
v-for="provider in loginTypes.filter((t) => t.loginProvider !== 'password')"
|
|
178
|
+
:key="provider.loginProvider"
|
|
179
|
+
>
|
|
180
|
+
<VcButton @click="redirectToSSO(provider)"> Sign in with {{ provider.loginProvider }} </VcButton>
|
|
161
181
|
</div>
|
|
162
182
|
</div>
|
|
163
183
|
</template>
|
|
@@ -12,16 +12,16 @@ Registers Core Web Vitals observers (FCP, LCP, CLS, INP, TTFB) and reports metri
|
|
|
12
12
|
## Quick Start
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
|
-
import { useWebVitals } from
|
|
15
|
+
import { useWebVitals } from "@vc-shell/framework";
|
|
16
16
|
|
|
17
17
|
// Option 1: Default behavior -- logs to console.warn in dev mode, silent in production
|
|
18
18
|
useWebVitals();
|
|
19
19
|
|
|
20
20
|
// Option 2: Custom callback for production analytics
|
|
21
21
|
useWebVitals((metric) => {
|
|
22
|
-
analytics.track(
|
|
23
|
-
name: metric.name,
|
|
24
|
-
value: metric.value,
|
|
22
|
+
analytics.track("web-vital", {
|
|
23
|
+
name: metric.name, // "FCP", "LCP", "CLS", "INP", or "TTFB"
|
|
24
|
+
value: metric.value, // milliseconds (or unitless for CLS)
|
|
25
25
|
rating: metric.rating, // "good", "needs-improvement", or "poor"
|
|
26
26
|
});
|
|
27
27
|
});
|
|
@@ -32,7 +32,7 @@ Call this once after `app.mount()` in your application entry point:
|
|
|
32
32
|
```typescript
|
|
33
33
|
// main.ts
|
|
34
34
|
const app = createApp(App);
|
|
35
|
-
app.mount(
|
|
35
|
+
app.mount("#app");
|
|
36
36
|
|
|
37
37
|
// Register Web Vitals observers after mount
|
|
38
38
|
useWebVitals();
|
|
@@ -42,17 +42,17 @@ useWebVitals();
|
|
|
42
42
|
|
|
43
43
|
### Parameters
|
|
44
44
|
|
|
45
|
-
| Parameter
|
|
46
|
-
|
|
47
|
-
| `callback` | `(metric: IWebVitalsMetric) => void` | No
|
|
45
|
+
| Parameter | Type | Required | Description |
|
|
46
|
+
| ---------- | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| `callback` | `(metric: IWebVitalsMetric) => void` | No | Custom handler for each metric. Defaults to `console.warn` formatted output in dev mode; no-op in production. |
|
|
48
48
|
|
|
49
49
|
### IWebVitalsMetric
|
|
50
50
|
|
|
51
|
-
| Field
|
|
52
|
-
|
|
53
|
-
| `name`
|
|
54
|
-
| `value`
|
|
55
|
-
| `rating` | `"good" \| "needs-improvement" \| "poor"` | Performance rating based on Google's thresholds (e.g., LCP < 2500ms = "good")
|
|
51
|
+
| Field | Type | Description |
|
|
52
|
+
| -------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
53
|
+
| `name` | `string` | Metric name: `"FCP"` (First Contentful Paint), `"LCP"` (Largest Contentful Paint), `"CLS"` (Cumulative Layout Shift), `"INP"` (Interaction to Next Paint), `"TTFB"` (Time to First Byte) |
|
|
54
|
+
| `value` | `number` | Metric value in milliseconds for all metrics except CLS, which is a unitless score |
|
|
55
|
+
| `rating` | `"good" \| "needs-improvement" \| "poor"` | Performance rating based on Google's thresholds (e.g., LCP < 2500ms = "good") |
|
|
56
56
|
|
|
57
57
|
### Returns
|
|
58
58
|
|
|
@@ -75,7 +75,7 @@ The default callback formats CLS values to 4 decimal places (since CLS is a dime
|
|
|
75
75
|
## Recipe: Sending Web Vitals to Application Insights
|
|
76
76
|
|
|
77
77
|
```typescript
|
|
78
|
-
import { useWebVitals, useAppInsights } from
|
|
78
|
+
import { useWebVitals, useAppInsights } from "@vc-shell/framework";
|
|
79
79
|
|
|
80
80
|
const { appInsights } = useAppInsights();
|
|
81
81
|
|
|
@@ -96,14 +96,14 @@ This sends each Web Vital as a custom metric to Application Insights, where you
|
|
|
96
96
|
## Recipe: Conditional Reporting Based on Rating
|
|
97
97
|
|
|
98
98
|
```typescript
|
|
99
|
-
import { useWebVitals } from
|
|
99
|
+
import { useWebVitals } from "@vc-shell/framework";
|
|
100
100
|
|
|
101
101
|
useWebVitals((metric) => {
|
|
102
102
|
// Only report poor metrics to reduce noise
|
|
103
|
-
if (metric.rating ===
|
|
104
|
-
fetch(
|
|
105
|
-
method:
|
|
106
|
-
headers: {
|
|
103
|
+
if (metric.rating === "poor") {
|
|
104
|
+
fetch("/api/telemetry/web-vitals", {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: { "Content-Type": "application/json" },
|
|
107
107
|
body: JSON.stringify({
|
|
108
108
|
metric: metric.name,
|
|
109
109
|
value: metric.value,
|
|
@@ -14,15 +14,15 @@ Also exports `provideWidgetService()` for framework-level initialization and `re
|
|
|
14
14
|
## Quick Start
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
|
-
import { useWidgets } from
|
|
17
|
+
import { useWidgets } from "@vc-shell/framework";
|
|
18
18
|
|
|
19
19
|
const widgetService = useWidgets();
|
|
20
20
|
|
|
21
21
|
// Query all widgets registered for a specific blade
|
|
22
|
-
const widgets = widgetService.getWidgets(
|
|
22
|
+
const widgets = widgetService.getWidgets("order-details");
|
|
23
23
|
|
|
24
24
|
// Check if a widget is currently active (visible and expanded)
|
|
25
|
-
if (widgetService.isActiveWidget(
|
|
25
|
+
if (widgetService.isActiveWidget("order-status-widget")) {
|
|
26
26
|
// widget is currently in focus
|
|
27
27
|
}
|
|
28
28
|
```
|
|
@@ -35,29 +35,29 @@ None.
|
|
|
35
35
|
|
|
36
36
|
### Returns (`IWidgetService`)
|
|
37
37
|
|
|
38
|
-
| Property / Method
|
|
39
|
-
|
|
40
|
-
| `registerWidget`
|
|
41
|
-
| `unregisterWidget`
|
|
42
|
-
| `getWidgets`
|
|
43
|
-
| `clearBladeWidgets`
|
|
44
|
-
| `registeredWidgets`
|
|
45
|
-
| `isActiveWidget`
|
|
46
|
-
| `setActiveWidget`
|
|
47
|
-
| `updateActiveWidget`
|
|
48
|
-
| `isWidgetRegistered`
|
|
49
|
-
| `updateWidget`
|
|
50
|
-
| `resolveWidgetProps`
|
|
51
|
-
| `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules).
|
|
52
|
-
| `getAllExternalWidgets`
|
|
38
|
+
| Property / Method | Type | Description |
|
|
39
|
+
| ---------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `registerWidget` | `(widget: IWidget, bladeId: string) => void` | Registers a widget for a specific blade. The widget will appear in that blade's widget area. |
|
|
41
|
+
| `unregisterWidget` | `(widgetId: string, bladeId: string) => void` | Removes a widget from a blade by ID. |
|
|
42
|
+
| `getWidgets` | `(bladeId: string) => IWidget[]` | Returns all widgets registered for a specific blade. |
|
|
43
|
+
| `clearBladeWidgets` | `(bladeId: string) => void` | Removes all widgets for a blade (used during blade teardown). |
|
|
44
|
+
| `registeredWidgets` | `IWidgetRegistration[]` | All widget registrations across all blades. |
|
|
45
|
+
| `isActiveWidget` | `(id: string) => boolean` | Checks if a widget is currently active (selected/expanded). |
|
|
46
|
+
| `setActiveWidget` | `(args) => void` | Sets a widget as active with its exposed instance. |
|
|
47
|
+
| `updateActiveWidget` | `() => void` | Triggers the active widget's update function. Deprecated -- use headless widgets instead. |
|
|
48
|
+
| `isWidgetRegistered` | `(id: string) => boolean` | Checks if a widget ID exists in any blade's registry. |
|
|
49
|
+
| `updateWidget` | `(args) => void` | Updates properties of a registered widget (trigger, badge, etc.). |
|
|
50
|
+
| `resolveWidgetProps` | `(widget, bladeData) => Record<string, unknown>` | Resolves widget props from blade data. Deprecated. |
|
|
51
|
+
| `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules). |
|
|
52
|
+
| `getAllExternalWidgets` | `() => IExternalWidgetRegistration[]` | Gets all registered external widgets across all modules. |
|
|
53
53
|
|
|
54
54
|
### Additional Exports
|
|
55
55
|
|
|
56
|
-
| Export
|
|
57
|
-
|
|
58
|
-
| `provideWidgetService()`
|
|
59
|
-
| `registerWidget(widget, bladeId)`
|
|
60
|
-
| `registerExternalWidget(registration)` | Global pre-registration for cross-module widgets. These widgets are rendered in blades owned by other modules.
|
|
56
|
+
| Export | Description |
|
|
57
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
58
|
+
| `provideWidgetService()` | Creates and provides the widget service via Vue injection. Idempotent -- returns existing service if already provided. Cleans up via `onScopeDispose`. |
|
|
59
|
+
| `registerWidget(widget, bladeId)` | Global pre-registration. Widgets registered this way are picked up when `provideWidgetService()` creates the service. Use in module `install()`. |
|
|
60
|
+
| `registerExternalWidget(registration)` | Global pre-registration for cross-module widgets. These widgets are rendered in blades owned by other modules. |
|
|
61
61
|
|
|
62
62
|
## How It Works
|
|
63
63
|
|
|
@@ -75,20 +75,20 @@ The service tracks active widgets (which widget is currently expanded/focused) s
|
|
|
75
75
|
|
|
76
76
|
```typescript
|
|
77
77
|
// my-module/index.ts
|
|
78
|
-
import { registerWidget } from
|
|
79
|
-
import { markRaw } from
|
|
80
|
-
import OrderStatusWidget from
|
|
78
|
+
import { registerWidget } from "@vc-shell/framework";
|
|
79
|
+
import { markRaw } from "vue";
|
|
80
|
+
import OrderStatusWidget from "./widgets/OrderStatusWidget.vue";
|
|
81
81
|
|
|
82
82
|
export default {
|
|
83
83
|
install() {
|
|
84
84
|
registerWidget(
|
|
85
85
|
{
|
|
86
|
-
id:
|
|
87
|
-
title:
|
|
86
|
+
id: "order-status",
|
|
87
|
+
title: "Order Status",
|
|
88
88
|
component: markRaw(OrderStatusWidget),
|
|
89
|
-
icon:
|
|
89
|
+
icon: "fas fa-clipboard-check",
|
|
90
90
|
},
|
|
91
|
-
|
|
91
|
+
"order-details", // blade ID where this widget appears
|
|
92
92
|
);
|
|
93
93
|
},
|
|
94
94
|
};
|
|
@@ -100,18 +100,18 @@ A shipping module can add a widget to the order module's detail blade:
|
|
|
100
100
|
|
|
101
101
|
```typescript
|
|
102
102
|
// shipping-module/index.ts
|
|
103
|
-
import { registerExternalWidget } from
|
|
104
|
-
import { markRaw } from
|
|
105
|
-
import ShippingTracker from
|
|
103
|
+
import { registerExternalWidget } from "@vc-shell/framework";
|
|
104
|
+
import { markRaw } from "vue";
|
|
105
|
+
import ShippingTracker from "./widgets/ShippingTracker.vue";
|
|
106
106
|
|
|
107
107
|
export default {
|
|
108
108
|
install() {
|
|
109
109
|
registerExternalWidget({
|
|
110
|
-
widgetId:
|
|
111
|
-
bladeId:
|
|
110
|
+
widgetId: "shipping-tracker",
|
|
111
|
+
bladeId: "order-details", // target blade from another module
|
|
112
112
|
component: markRaw(ShippingTracker),
|
|
113
|
-
title:
|
|
114
|
-
icon:
|
|
113
|
+
title: "Shipping",
|
|
114
|
+
icon: "fas fa-truck",
|
|
115
115
|
});
|
|
116
116
|
},
|
|
117
117
|
};
|
|
@@ -121,21 +121,16 @@ export default {
|
|
|
121
121
|
|
|
122
122
|
```vue
|
|
123
123
|
<script setup lang="ts">
|
|
124
|
-
import { useWidgets } from
|
|
125
|
-
import { computed } from
|
|
124
|
+
import { useWidgets } from "@vc-shell/framework";
|
|
125
|
+
import { computed } from "vue";
|
|
126
126
|
|
|
127
127
|
const props = defineProps<{ bladeId: string }>();
|
|
128
128
|
const widgetService = useWidgets();
|
|
129
129
|
|
|
130
130
|
const bladeWidgets = computed(() => widgetService.getWidgets(props.bladeId));
|
|
131
|
-
const externalWidgets = computed(() =>
|
|
132
|
-
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
const allWidgets = computed(() => [
|
|
136
|
-
...bladeWidgets.value,
|
|
137
|
-
...externalWidgets.value,
|
|
138
|
-
]);
|
|
131
|
+
const externalWidgets = computed(() => widgetService.getExternalWidgetsForBlade(props.bladeId));
|
|
132
|
+
|
|
133
|
+
const allWidgets = computed(() => [...bladeWidgets.value, ...externalWidgets.value]);
|
|
139
134
|
</script>
|
|
140
135
|
```
|
|
141
136
|
|
|
@@ -12,8 +12,8 @@ The directive is registered globally by the framework, so no manual import is ne
|
|
|
12
12
|
|
|
13
13
|
## API
|
|
14
14
|
|
|
15
|
-
| Binding
|
|
16
|
-
|
|
15
|
+
| Binding | Type | Description |
|
|
16
|
+
| ------------------------- | --------- | --------------------------------------------------- |
|
|
17
17
|
| `v-autofocus="condition"` | `boolean` | Focus the element on mount if `condition` is truthy |
|
|
18
18
|
|
|
19
19
|
The directive only acts on the `mounted` hook. It does not re-focus on updates.
|
|
@@ -40,7 +40,10 @@ export const autofocus = {
|
|
|
40
40
|
```vue
|
|
41
41
|
<template>
|
|
42
42
|
<!-- The search field gets focus as soon as the blade opens -->
|
|
43
|
-
<input
|
|
43
|
+
<input
|
|
44
|
+
v-autofocus="true"
|
|
45
|
+
placeholder="Search orders..."
|
|
46
|
+
/>
|
|
44
47
|
</template>
|
|
45
48
|
```
|
|
46
49
|
|
|
@@ -68,7 +71,10 @@ const isEditMode = computed(() => !!props.param);
|
|
|
68
71
|
|
|
69
72
|
```vue
|
|
70
73
|
<template>
|
|
71
|
-
<VcPopup
|
|
74
|
+
<VcPopup
|
|
75
|
+
v-model:show="showDialog"
|
|
76
|
+
title="Rename Item"
|
|
77
|
+
>
|
|
72
78
|
<VcInput
|
|
73
79
|
v-autofocus="showDialog"
|
|
74
80
|
v-model="newName"
|
|
@@ -14,20 +14,20 @@ Unlike a standalone loading component, `v-loading` scopes the overlay to the ele
|
|
|
14
14
|
|
|
15
15
|
## API
|
|
16
16
|
|
|
17
|
-
| Binding
|
|
18
|
-
|
|
19
|
-
| `v-loading="true"`
|
|
20
|
-
| `v-loading="options"`
|
|
21
|
-
| `v-loading:1000="true"` | `arg: string`
|
|
17
|
+
| Binding | Type | Description |
|
|
18
|
+
| ----------------------- | ---------------- | ------------------------------------ |
|
|
19
|
+
| `v-loading="true"` | `boolean` | Show/hide the loading overlay |
|
|
20
|
+
| `v-loading="options"` | `LoadingOptions` | Show with configuration (see below) |
|
|
21
|
+
| `v-loading:1000="true"` | `arg: string` | Set custom z-index (default: `9999`) |
|
|
22
22
|
|
|
23
23
|
### LoadingOptions
|
|
24
24
|
|
|
25
|
-
| Property
|
|
26
|
-
|
|
27
|
-
| `size`
|
|
28
|
-
| `color`
|
|
29
|
-
| `blur`
|
|
30
|
-
| `fullscreen` | `boolean`
|
|
25
|
+
| Property | Type | Default | Description |
|
|
26
|
+
| ------------ | -------------------------------- | ------- | ------------------------------------------------------- |
|
|
27
|
+
| `size` | `"small" \| "medium" \| "large"` | -- | Spinner size via `data-loading-size` attribute |
|
|
28
|
+
| `color` | `string` | -- | Custom spinner color (sets `--v-loading-spinner-color`) |
|
|
29
|
+
| `blur` | `boolean` | `true` | Enable backdrop blur; `false` adds `v-loading--no-blur` |
|
|
30
|
+
| `fullscreen` | `boolean` | `false` | Fullscreen overlay via `v-loading--fullscreen` |
|
|
31
31
|
|
|
32
32
|
## How It Works
|
|
33
33
|
|
|
@@ -45,7 +45,10 @@ Because the directive modifies the element directly (not through Vue reactivity)
|
|
|
45
45
|
|
|
46
46
|
```vue
|
|
47
47
|
<template>
|
|
48
|
-
<div
|
|
48
|
+
<div
|
|
49
|
+
v-loading="isLoading"
|
|
50
|
+
class="tw-min-h-[200px]"
|
|
51
|
+
>
|
|
49
52
|
<p>Order details will appear here</p>
|
|
50
53
|
</div>
|
|
51
54
|
</template>
|
|
@@ -72,7 +75,10 @@ async function loadOrder() {
|
|
|
72
75
|
<template>
|
|
73
76
|
<!-- Small spinner with brand color, no blur -->
|
|
74
77
|
<div v-loading="{ size: 'small', color: 'var(--primary-500)', blur: false }">
|
|
75
|
-
<img
|
|
78
|
+
<img
|
|
79
|
+
:src="thumbnailUrl"
|
|
80
|
+
alt="Product thumbnail"
|
|
81
|
+
/>
|
|
76
82
|
</div>
|
|
77
83
|
</template>
|
|
78
84
|
```
|
|
@@ -104,9 +110,18 @@ async function loadOrder() {
|
|
|
104
110
|
|
|
105
111
|
```vue
|
|
106
112
|
<template>
|
|
107
|
-
<VcBlade
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
<VcBlade
|
|
114
|
+
title="Products"
|
|
115
|
+
:closable="true"
|
|
116
|
+
>
|
|
117
|
+
<div
|
|
118
|
+
v-loading="loading"
|
|
119
|
+
class="tw-p-4"
|
|
120
|
+
>
|
|
121
|
+
<VcDataTable
|
|
122
|
+
:items="products"
|
|
123
|
+
:columns="columns"
|
|
124
|
+
/>
|
|
110
125
|
</div>
|
|
111
126
|
</VcBlade>
|
|
112
127
|
</template>
|
|
@@ -146,10 +161,10 @@ Passing an options object when you want to hide the spinner does not work as exp
|
|
|
146
161
|
|
|
147
162
|
## CSS Classes Reference
|
|
148
163
|
|
|
149
|
-
| Class
|
|
150
|
-
|
|
151
|
-
| `v-loading`
|
|
152
|
-
| `v-loading--no-blur`
|
|
164
|
+
| Class | Applied When | Effect |
|
|
165
|
+
| ----------------------- | ------------------ | ---------------------------------- |
|
|
166
|
+
| `v-loading` | Value is truthy | Shows the spinner overlay |
|
|
167
|
+
| `v-loading--no-blur` | `blur: false` | Disables backdrop blur filter |
|
|
153
168
|
| `v-loading--fullscreen` | `fullscreen: true` | Overlay covers the entire viewport |
|
|
154
169
|
|
|
155
170
|
## Related
|