@vc-shell/vc-app-skill 2.0.0-alpha.32 → 2.0.0-alpha.33-pr220.455e322
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 +59 -47
- package/README.md +18 -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 +94 -0
- 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 +31 -27
- 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 +75 -19
- package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
- package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +74 -78
- 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 +10 -10
- 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/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 +24 -15
- 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 +107 -91
- 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 +98 -90
- 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 +102 -0
- 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 +12 -18
- 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 +104 -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 +59 -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 +96 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +26 -35
- package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +69 -22
- package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +58 -72
- 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 +60 -72
- package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +65 -26
- package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +46 -49
- 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 +115 -130
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +53 -87
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +56 -63
- 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 +63 -64
- 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 +59 -19
- package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +25 -34
- package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +42 -32
- package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +78 -82
- package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +25 -15
- package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +59 -63
- package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +57 -69
- 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 +120 -75
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +30 -44
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +536 -365
- 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 +255 -0
- package/runtime/knowledge/migration-prompts/blade-props-migration.md +194 -0
- 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 +223 -0
- package/runtime/knowledge/migration-prompts/nswag-migration.md +244 -0
- 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 +178 -0
- 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 +354 -49
- package/runtime/knowledge/docs/core/constants/constants.docs.md +0 -185
|
@@ -40,33 +40,43 @@ const toolbar = ref<IBladeToolbar[]>([
|
|
|
40
40
|
|
|
41
41
|
### Options
|
|
42
42
|
|
|
43
|
-
| Option
|
|
44
|
-
|
|
45
|
-
| `data`
|
|
46
|
-
| `canSaveOverride`
|
|
47
|
-
| `autoBeforeClose`
|
|
48
|
-
| `autoBeforeUnload`
|
|
49
|
-
| `closeConfirmMessage` | `MaybeRefOrGetter<string>`
|
|
50
|
-
| `onRevert`
|
|
43
|
+
| Option | Type | Default | Description |
|
|
44
|
+
| --------------------- | --------------------------------- | -------- | --------------------------------- |
|
|
45
|
+
| `data` | `Ref<T>` | required | Reactive data object for the form |
|
|
46
|
+
| `canSaveOverride` | `ComputedRef<boolean>` | — | Additional condition for canSave |
|
|
47
|
+
| `autoBeforeClose` | `boolean \| ComputedRef<boolean>` | `true` | Close guard behavior |
|
|
48
|
+
| `autoBeforeUnload` | `boolean` | `true` | Browser tab close guard |
|
|
49
|
+
| `closeConfirmMessage` | `MaybeRefOrGetter<string>` | — | Custom unsaved changes message |
|
|
50
|
+
| `onRevert` | `() => void \| Promise<void>` | — | Custom revert handler |
|
|
51
51
|
|
|
52
52
|
### Returns
|
|
53
53
|
|
|
54
|
-
| Property
|
|
55
|
-
|
|
56
|
-
| `setBaseline()` | `() => void`
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
54
|
+
| Property | Type | Description |
|
|
55
|
+
| --------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| `setBaseline()` | `() => void` | Snapshot current data as pristine. Call after load and after save |
|
|
57
|
+
| `markReady()` | `() => void` | Mark form ready without resetting pristine snapshot. Computes modification state from current data vs setup-time snapshot |
|
|
58
|
+
| `revert()` | `() => void \| Promise<void>` | Revert data to pristine (or call onRevert) |
|
|
59
|
+
| `canSave` | `ComputedRef<boolean>` | `isReady && valid && modified && canSaveOverride` |
|
|
60
|
+
| `isModified` | `ComputedRef<boolean>` | Data differs from pristine (false until setBaseline) |
|
|
61
|
+
| `isReady` | `ComputedRef<boolean>` | setBaseline() called at least once |
|
|
62
|
+
| `formMeta` | vee-validate meta | Form validation state |
|
|
63
|
+
| `setFieldError` | function | Set field error programmatically |
|
|
64
|
+
| `errorBag` | Ref | All field errors |
|
|
64
65
|
|
|
65
66
|
## Lifecycle
|
|
66
67
|
|
|
68
|
+
### Standard (edit existing entity)
|
|
69
|
+
|
|
67
70
|
```
|
|
68
71
|
Mount → Load data → setBaseline() → User edits → Save → setBaseline()
|
|
69
|
-
|
|
72
|
+
└→ Cancel → revert()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Pre-filled (create from template)
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
Mount → Pre-fill data → markReady() → canSave = true immediately
|
|
79
|
+
└→ Save → setBaseline()
|
|
70
80
|
```
|
|
71
81
|
|
|
72
82
|
## VcBlade Integration
|
|
@@ -102,6 +112,52 @@ const form = useBladeForm({
|
|
|
102
112
|
});
|
|
103
113
|
```
|
|
104
114
|
|
|
115
|
+
## Advanced: Pre-filled Entity (markReady)
|
|
116
|
+
|
|
117
|
+
When creating a new entity that is pre-populated from a parent (e.g. new offer from a product), the form should be immediately saveable. Use `markReady()` instead of `setBaseline()`:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const form = useBladeForm({ data: item });
|
|
121
|
+
|
|
122
|
+
onMounted(async () => {
|
|
123
|
+
// Populate base fields
|
|
124
|
+
item.value.sku = generateSku();
|
|
125
|
+
await addEmptyInventory();
|
|
126
|
+
|
|
127
|
+
const hasTemplate = !param.value && !!options.value?.templateId;
|
|
128
|
+
|
|
129
|
+
if (hasTemplate) {
|
|
130
|
+
// Fill from template — data diverges from the setup-time snapshot
|
|
131
|
+
await fillFromTemplate(options.value.templateId);
|
|
132
|
+
// Mark ready: compares current data to setup-time snapshot → isModified = true
|
|
133
|
+
form.markReady();
|
|
134
|
+
} else {
|
|
135
|
+
// Standard load — current state becomes the pristine baseline
|
|
136
|
+
await loadItem({ id: param.value });
|
|
137
|
+
form.setBaseline();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### setBaseline vs markReady
|
|
143
|
+
|
|
144
|
+
| | `setBaseline()` | `markReady()` |
|
|
145
|
+
| ------------------------------ | --------------------------------------- | --------------------------------------------------- |
|
|
146
|
+
| Sets `isReady` | yes | yes |
|
|
147
|
+
| Updates pristine snapshot | yes (current data → pristine) | no (keeps setup-time snapshot) |
|
|
148
|
+
| `trackerIsModified` after call | `false` | computed: `data !== pristineSnapshot` |
|
|
149
|
+
| Use case | Load / Save — "this is the clean state" | Pre-fill — "form is ready, changes are intentional" |
|
|
150
|
+
|
|
151
|
+
### How it works
|
|
152
|
+
|
|
153
|
+
At composable creation, `useBladeForm` takes a snapshot of `data` (the **setup-time snapshot**). When `markReady()` is called:
|
|
154
|
+
|
|
155
|
+
1. `isReady` → `true` (gates `canSave` and the deep watcher)
|
|
156
|
+
2. `trackerIsModified` = `!semanticEqual(data, setupTimeSnapshot)` — since data was mutated during `onMounted`, this evaluates to `true`
|
|
157
|
+
3. Subsequent edits are tracked normally by the deep watcher
|
|
158
|
+
|
|
159
|
+
After save, call `setBaseline()` as usual to capture the saved state as the new pristine snapshot.
|
|
160
|
+
|
|
105
161
|
## Constraints
|
|
106
162
|
|
|
107
163
|
- **Must be called from component `setup()`** (or `<script setup>`). Do NOT call from shared data-composables.
|
|
@@ -32,22 +32,22 @@ const component = getBladeComponent("OrderDetails");
|
|
|
32
32
|
|
|
33
33
|
### Returns
|
|
34
34
|
|
|
35
|
-
| Property
|
|
36
|
-
|
|
37
|
-
| `registeredBladesMap` | `ComputedRef<ReadonlyMap<string, IBladeRegistrationData>>` | Reactive readonly map of all registered blades
|
|
38
|
-
| `getBlade`
|
|
39
|
-
| `getBladeComponent`
|
|
40
|
-
| `getBladeByRoute`
|
|
35
|
+
| Property | Type | Description |
|
|
36
|
+
| --------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
37
|
+
| `registeredBladesMap` | `ComputedRef<ReadonlyMap<string, IBladeRegistrationData>>` | Reactive readonly map of all registered blades |
|
|
38
|
+
| `getBlade` | `(name: string) => IBladeRegistrationData \| undefined` | Get registration data (component, route, permissions) by blade name |
|
|
39
|
+
| `getBladeComponent` | `(name: string) => BladeInstanceConstructor \| undefined` | Get the Vue component for a blade name (falls back to global components) |
|
|
40
|
+
| `getBladeByRoute` | `(route: string) => { name, data } \| undefined` | Reverse lookup: find a blade by its URL route segment (O(1)) |
|
|
41
41
|
|
|
42
42
|
### IBladeRegistrationData
|
|
43
43
|
|
|
44
|
-
| Property
|
|
45
|
-
|
|
46
|
-
| `component`
|
|
47
|
-
| `route`
|
|
48
|
-
| `isWorkspace` | `boolean?`
|
|
49
|
-
| `routable`
|
|
50
|
-
| `permissions` | `string \| string[]?`
|
|
44
|
+
| Property | Type | Description |
|
|
45
|
+
| ------------- | -------------------------- | ------------------------------------------------ |
|
|
46
|
+
| `component` | `BladeInstanceConstructor` | The Vue component for the blade |
|
|
47
|
+
| `route` | `string?` | URL route segment (e.g. `"orders"`) |
|
|
48
|
+
| `isWorkspace` | `boolean?` | Whether this blade opens as a workspace root |
|
|
49
|
+
| `routable` | `boolean?` | Whether this blade supports URL-based navigation |
|
|
50
|
+
| `permissions` | `string \| string[]?` | Required permissions to access this blade |
|
|
51
51
|
|
|
52
52
|
## Common Patterns
|
|
53
53
|
|
|
@@ -91,8 +91,8 @@ function resolveDeepLink(routeSegment: string) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Works with or without leading slash
|
|
94
|
-
resolveDeepLink("orders");
|
|
95
|
-
resolveDeepLink("/orders");
|
|
94
|
+
resolveDeepLink("orders"); // { name: "OrdersList", data: { ... } }
|
|
95
|
+
resolveDeepLink("/orders"); // Same result
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
### Listing all registered blades
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Two composables for the widget system — one for the **blade side**, one for the **widget side**.
|
|
4
4
|
|
|
5
|
-
| Composable
|
|
6
|
-
|
|
7
|
-
| `useBladeWidgets`
|
|
5
|
+
| Composable | Called from | Purpose |
|
|
6
|
+
| ------------------ | ------------------------- | ---------------------------------------------------------------------- |
|
|
7
|
+
| `useBladeWidgets` | Blade component | Register headless widgets + get `refresh()` / `refreshAll()` |
|
|
8
8
|
| `useWidgetTrigger` | External widget component | Register trigger callbacks (`onRefresh`, `onClick`) via provide/inject |
|
|
9
9
|
|
|
10
10
|
Headless widgets are defined as plain configuration objects with reactive refs for dynamic values like badge counts and loading states. External component-based widgets use `useWidgetTrigger` to register their refresh callbacks so the hosting blade can trigger them.
|
|
@@ -18,25 +18,25 @@ Headless widgets are defined as plain configuration objects with reactive refs f
|
|
|
18
18
|
## Basic Usage
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
|
-
import { useBladeWidgets } from
|
|
21
|
+
import { useBladeWidgets } from "@vc-shell/framework";
|
|
22
22
|
|
|
23
23
|
const { refreshAll } = useBladeWidgets([
|
|
24
24
|
{
|
|
25
|
-
id:
|
|
26
|
-
icon:
|
|
27
|
-
title:
|
|
28
|
-
badge:
|
|
29
|
-
loading:
|
|
30
|
-
onClick: () => openBlade({ name:
|
|
31
|
-
onRefresh: () =>
|
|
25
|
+
id: "ChildListWidget",
|
|
26
|
+
icon: "lucide-tag",
|
|
27
|
+
title: "MODULE.WIDGETS.CHILD_LIST.TITLE",
|
|
28
|
+
badge: childCount,
|
|
29
|
+
loading: childLoading,
|
|
30
|
+
onClick: () => openBlade({ name: "ChildList" }),
|
|
31
|
+
onRefresh: () => reloadChildren(),
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
id:
|
|
35
|
-
icon:
|
|
36
|
-
title:
|
|
37
|
-
badge:
|
|
34
|
+
id: "NotesWidget",
|
|
35
|
+
icon: "lucide-star",
|
|
36
|
+
title: "MODULE.WIDGETS.NOTES.TITLE",
|
|
37
|
+
badge: notesCount,
|
|
38
38
|
isVisible: computed(() => !!item.value?.id),
|
|
39
|
-
onClick: () => openBlade({ name:
|
|
39
|
+
onClick: () => openBlade({ name: "NotesList" }),
|
|
40
40
|
},
|
|
41
41
|
]);
|
|
42
42
|
|
|
@@ -49,30 +49,30 @@ refreshAll();
|
|
|
49
49
|
|
|
50
50
|
### Parameters
|
|
51
51
|
|
|
52
|
-
| Parameter | Type
|
|
53
|
-
|
|
54
|
-
| `widgets` | `HeadlessWidgetDeclaration[]` | Yes
|
|
52
|
+
| Parameter | Type | Required | Description |
|
|
53
|
+
| --------- | ----------------------------- | -------- | ---------------------------- |
|
|
54
|
+
| `widgets` | `HeadlessWidgetDeclaration[]` | Yes | Array of widget declarations |
|
|
55
55
|
|
|
56
56
|
### HeadlessWidgetDeclaration
|
|
57
57
|
|
|
58
|
-
| Field
|
|
59
|
-
|
|
60
|
-
| `id`
|
|
61
|
-
| `icon`
|
|
62
|
-
| `title`
|
|
63
|
-
| `badge`
|
|
64
|
-
| `loading`
|
|
65
|
-
| `disabled`
|
|
66
|
-
| `isVisible` | `ComputedRef<boolean> \| boolean` | No
|
|
67
|
-
| `onClick`
|
|
68
|
-
| `onRefresh` | `() => void \| Promise<void>`
|
|
58
|
+
| Field | Type | Required | Description |
|
|
59
|
+
| ----------- | --------------------------------- | -------- | ----------------------------------------- |
|
|
60
|
+
| `id` | `string` | Yes | Unique widget identifier |
|
|
61
|
+
| `icon` | `string` | Yes | Icon name (e.g., `"lucide-tag"`) |
|
|
62
|
+
| `title` | `string` | Yes | i18n key or display title |
|
|
63
|
+
| `badge` | `Ref<number \| string>` | No | Badge counter value |
|
|
64
|
+
| `loading` | `Ref<boolean>` | No | Show loading indicator |
|
|
65
|
+
| `disabled` | `Ref<boolean> \| boolean` | No | Disable the widget |
|
|
66
|
+
| `isVisible` | `ComputedRef<boolean> \| boolean` | No | Toggle visibility |
|
|
67
|
+
| `onClick` | `() => void` | No | Action when widget is clicked |
|
|
68
|
+
| `onRefresh` | `() => void \| Promise<void>` | No | Called by `refresh(id)` or `refreshAll()` |
|
|
69
69
|
|
|
70
70
|
### Returns
|
|
71
71
|
|
|
72
|
-
| Property
|
|
73
|
-
|
|
74
|
-
| `refresh`
|
|
75
|
-
| `refreshAll` | `() => void`
|
|
72
|
+
| Property | Type | Description |
|
|
73
|
+
| ------------ | ---------------------------- | ------------------------------------------------ |
|
|
74
|
+
| `refresh` | `(widgetId: string) => void` | Trigger `onRefresh` on a specific widget |
|
|
75
|
+
| `refreshAll` | `() => void` | Trigger `onRefresh` on all widgets that have one |
|
|
76
76
|
|
|
77
77
|
## useWidgetTrigger
|
|
78
78
|
|
|
@@ -81,7 +81,7 @@ Widget-side composable for external component-based widgets. Registers a trigger
|
|
|
81
81
|
### Basic Usage
|
|
82
82
|
|
|
83
83
|
```typescript
|
|
84
|
-
import { useWidgetTrigger } from
|
|
84
|
+
import { useWidgetTrigger } from "@vc-shell/framework";
|
|
85
85
|
|
|
86
86
|
// Inside an external widget component:
|
|
87
87
|
useWidgetTrigger({ onRefresh: loadData });
|
|
@@ -89,14 +89,14 @@ useWidgetTrigger({ onRefresh: loadData });
|
|
|
89
89
|
|
|
90
90
|
### IWidgetTrigger
|
|
91
91
|
|
|
92
|
-
| Field
|
|
93
|
-
|
|
94
|
-
| `icon`
|
|
95
|
-
| `title`
|
|
96
|
-
| `badge`
|
|
97
|
-
| `onClick`
|
|
98
|
-
| `onRefresh` | `() => void \| Promise<void>` | No
|
|
99
|
-
| `disabled`
|
|
92
|
+
| Field | Type | Required | Description |
|
|
93
|
+
| ----------- | ----------------------------- | -------- | ------------------------------------------------- |
|
|
94
|
+
| `icon` | `string` | No | Lucide icon name for dropdown rendering |
|
|
95
|
+
| `title` | `string` | No | Display title (fallback: widget's title) |
|
|
96
|
+
| `badge` | `Ref<number \| string>` | No | Reactive badge value |
|
|
97
|
+
| `onClick` | `() => void` | No | Handler called when widget is clicked in dropdown |
|
|
98
|
+
| `onRefresh` | `() => void \| Promise<void>` | No | Handler called to refresh widget data |
|
|
99
|
+
| `disabled` | `Ref<boolean> \| boolean` | No | Disabled state |
|
|
100
100
|
|
|
101
101
|
### How It Works
|
|
102
102
|
|
|
@@ -119,7 +119,7 @@ import { MessageWidget } from "./components/widgets";
|
|
|
119
119
|
registerExternalWidget({
|
|
120
120
|
id: "MessageWidget",
|
|
121
121
|
component: markRaw(MessageWidget),
|
|
122
|
-
targetBlades: ["
|
|
122
|
+
targetBlades: ["EntityDetails", "AnotherDetails"],
|
|
123
123
|
isVisible: (blade?: BladeDescriptor) => !!blade?.param,
|
|
124
124
|
});
|
|
125
125
|
```
|
|
@@ -139,13 +139,7 @@ registerExternalWidget({
|
|
|
139
139
|
|
|
140
140
|
<script setup lang="ts">
|
|
141
141
|
import { ref, computed, onMounted } from "vue";
|
|
142
|
-
import {
|
|
143
|
-
loading as vLoading,
|
|
144
|
-
useBlade,
|
|
145
|
-
injectBladeContext,
|
|
146
|
-
useWidgetTrigger,
|
|
147
|
-
VcWidget,
|
|
148
|
-
} from "@vc-shell/framework";
|
|
142
|
+
import { loading as vLoading, useBlade, injectBladeContext, useWidgetTrigger, VcWidget } from "@vc-shell/framework";
|
|
149
143
|
|
|
150
144
|
const ctx = injectBladeContext();
|
|
151
145
|
const entityId = computed(() => (ctx.value.item as { id?: string })?.id ?? "");
|
|
@@ -182,61 +176,61 @@ import { useBladeWidgets } from "@vc-shell/framework";
|
|
|
182
176
|
const { refresh, refreshAll } = useBladeWidgets([]);
|
|
183
177
|
|
|
184
178
|
async function save() {
|
|
185
|
-
await api.
|
|
186
|
-
refreshAll();
|
|
179
|
+
await api.saveEntity(entity.value);
|
|
180
|
+
refreshAll(); // refresh all widgets (including MessageWidget)
|
|
187
181
|
// or: refresh("MessageWidget"); // refresh a specific widget by ID
|
|
188
182
|
}
|
|
189
183
|
</script>
|
|
190
184
|
```
|
|
191
185
|
|
|
192
|
-
## Recipe:
|
|
186
|
+
## Recipe: Entity Detail Blade with Multiple Widgets
|
|
193
187
|
|
|
194
188
|
```vue
|
|
195
189
|
<script setup lang="ts">
|
|
196
190
|
import { ref, computed } from "vue";
|
|
197
191
|
import { useBladeWidgets, defineBladeContext } from "@vc-shell/framework";
|
|
198
192
|
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
const
|
|
202
|
-
const
|
|
193
|
+
const entity = ref({ id: "ent-1", name: "Sample" });
|
|
194
|
+
const childCount = ref(0);
|
|
195
|
+
const notesCount = ref(0);
|
|
196
|
+
const childLoading = ref(false);
|
|
203
197
|
|
|
204
|
-
// Expose
|
|
205
|
-
defineBladeContext(computed(() => ({ id:
|
|
198
|
+
// Expose entity data to widgets
|
|
199
|
+
defineBladeContext(computed(() => ({ id: entity.value?.id })));
|
|
206
200
|
|
|
207
|
-
async function
|
|
208
|
-
|
|
201
|
+
async function reloadChildren() {
|
|
202
|
+
childLoading.value = true;
|
|
209
203
|
try {
|
|
210
|
-
const result = await api.
|
|
211
|
-
|
|
204
|
+
const result = await api.searchChildren({ entityId: entity.value.id });
|
|
205
|
+
childCount.value = result.totalCount;
|
|
212
206
|
} finally {
|
|
213
|
-
|
|
207
|
+
childLoading.value = false;
|
|
214
208
|
}
|
|
215
209
|
}
|
|
216
210
|
|
|
217
211
|
const { refreshAll } = useBladeWidgets([
|
|
218
212
|
{
|
|
219
|
-
id: "
|
|
213
|
+
id: "ChildListWidget",
|
|
220
214
|
icon: "lucide-tag",
|
|
221
|
-
title: "
|
|
222
|
-
badge:
|
|
223
|
-
loading:
|
|
224
|
-
isVisible: computed(() => !!
|
|
225
|
-
onClick: () => openBlade({ name: "
|
|
226
|
-
onRefresh:
|
|
215
|
+
title: "MODULE.WIDGETS.CHILD_LIST",
|
|
216
|
+
badge: childCount,
|
|
217
|
+
loading: childLoading,
|
|
218
|
+
isVisible: computed(() => !!entity.value?.id),
|
|
219
|
+
onClick: () => openBlade({ name: "ChildList" }),
|
|
220
|
+
onRefresh: reloadChildren,
|
|
227
221
|
},
|
|
228
222
|
{
|
|
229
|
-
id: "
|
|
223
|
+
id: "NotesWidget",
|
|
230
224
|
icon: "lucide-star",
|
|
231
|
-
title: "
|
|
232
|
-
badge:
|
|
233
|
-
isVisible: computed(() => !!
|
|
234
|
-
onClick: () => openBlade({ name: "
|
|
225
|
+
title: "MODULE.WIDGETS.NOTES",
|
|
226
|
+
badge: notesCount,
|
|
227
|
+
isVisible: computed(() => !!entity.value?.id),
|
|
228
|
+
onClick: () => openBlade({ name: "NotesList" }),
|
|
235
229
|
},
|
|
236
230
|
]);
|
|
237
231
|
|
|
238
232
|
async function save() {
|
|
239
|
-
await api.
|
|
233
|
+
await api.saveEntity(entity.value);
|
|
240
234
|
// Refresh all widget counts after saving
|
|
241
235
|
refreshAll();
|
|
242
236
|
}
|
|
@@ -246,11 +240,13 @@ async function save() {
|
|
|
246
240
|
## Prerequisites
|
|
247
241
|
|
|
248
242
|
**`useBladeWidgets`**:
|
|
243
|
+
|
|
249
244
|
- Must be called inside a blade component rendered by `VcBladeSlot` (requires `BladeDescriptorKey` injection).
|
|
250
245
|
- `WidgetService` must be provided in the component tree (automatically available in vc-shell apps).
|
|
251
246
|
- Calling outside a blade context throws an error with a descriptive message.
|
|
252
247
|
|
|
253
248
|
**`useWidgetTrigger`**:
|
|
249
|
+
|
|
254
250
|
- Must be called inside a widget component rendered by `WidgetContainer` (requires `WidgetScopeKey` injection).
|
|
255
251
|
- If called outside a widget scope, logs a warning and does nothing (does not throw).
|
|
256
252
|
|
|
@@ -34,20 +34,20 @@ push({
|
|
|
34
34
|
|
|
35
35
|
### Returns
|
|
36
36
|
|
|
37
|
-
| Property
|
|
38
|
-
|
|
39
|
-
| `breadcrumbs` | `ComputedRef<Breadcrumbs[]>`
|
|
40
|
-
| `push`
|
|
41
|
-
| `remove`
|
|
37
|
+
| Property | Type | Description |
|
|
38
|
+
| ------------- | ----------------------------------- | ------------------------------------------------------------------- |
|
|
39
|
+
| `breadcrumbs` | `ComputedRef<Breadcrumbs[]>` | Reactive array of current breadcrumb items |
|
|
40
|
+
| `push` | `(breadcrumb: Breadcrumbs) => void` | Add a breadcrumb (deduplicates by `id`, updates in place if exists) |
|
|
41
|
+
| `remove` | `(ids: string[]) => void` | Remove breadcrumbs by their IDs |
|
|
42
42
|
|
|
43
43
|
### Breadcrumbs Interface
|
|
44
44
|
|
|
45
|
-
| Property
|
|
46
|
-
|
|
47
|
-
| `id`
|
|
48
|
-
| `title`
|
|
49
|
-
| `icon`
|
|
50
|
-
| `clickHandler` | `(id: string) => void \| boolean \| Promise<void \| boolean>` | No
|
|
45
|
+
| Property | Type | Required | Description |
|
|
46
|
+
| -------------- | ------------------------------------------------------------- | -------- | -------------------------------------------------------- |
|
|
47
|
+
| `id` | `string` | Yes | Unique identifier for the breadcrumb |
|
|
48
|
+
| `title` | `MaybeRef<string \| undefined>` | Yes | Display text (can be reactive) |
|
|
49
|
+
| `icon` | `string?` | No | Icon identifier |
|
|
50
|
+
| `clickHandler` | `(id: string) => void \| boolean \| Promise<void \| boolean>` | No | Click callback; return `false` to prevent trail trimming |
|
|
51
51
|
|
|
52
52
|
## Common Patterns
|
|
53
53
|
|
package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md
CHANGED
|
@@ -12,18 +12,25 @@ Monitors the browser's network connectivity and shows a persistent notification
|
|
|
12
12
|
|
|
13
13
|
```vue
|
|
14
14
|
<script setup lang="ts">
|
|
15
|
-
import { useConnectionStatus } from
|
|
15
|
+
import { useConnectionStatus } from "@vc-shell/framework";
|
|
16
16
|
|
|
17
17
|
const { isOnline } = useConnectionStatus();
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<template>
|
|
21
21
|
<VcBlade title="Order Details">
|
|
22
|
-
<div
|
|
22
|
+
<div
|
|
23
|
+
v-if="!isOnline"
|
|
24
|
+
class="tw-bg-yellow-100 tw-p-2 tw-rounded tw-mb-4"
|
|
25
|
+
>
|
|
23
26
|
You are offline. Changes will not be saved until connectivity is restored.
|
|
24
27
|
</div>
|
|
25
28
|
|
|
26
|
-
<VcButton
|
|
29
|
+
<VcButton
|
|
30
|
+
:disabled="!isOnline"
|
|
31
|
+
@click="save"
|
|
32
|
+
>Save Order</VcButton
|
|
33
|
+
>
|
|
27
34
|
</VcBlade>
|
|
28
35
|
</template>
|
|
29
36
|
```
|
|
@@ -32,8 +39,8 @@ const { isOnline } = useConnectionStatus();
|
|
|
32
39
|
|
|
33
40
|
### Returns
|
|
34
41
|
|
|
35
|
-
| Property
|
|
36
|
-
|
|
42
|
+
| Property | Type | Description |
|
|
43
|
+
| ---------- | ------------------------ | --------------------------------------------------------------------------------------------------------------- |
|
|
37
44
|
| `isOnline` | `Readonly<Ref<boolean>>` | `true` when the browser has network connectivity, `false` when offline. Read-only to prevent external mutation. |
|
|
38
45
|
|
|
39
46
|
## How It Works
|
|
@@ -41,6 +48,7 @@ const { isOnline } = useConnectionStatus();
|
|
|
41
48
|
On the very first call to `useConnectionStatus()`, the composable initializes a watcher on `@vueuse/core`'s `useNetwork().isOnline`. This watcher runs with `{ immediate: true }`, so the state is correct from the start. Subsequent calls skip initialization and return the same shared reactive state.
|
|
42
49
|
|
|
43
50
|
When the network drops:
|
|
51
|
+
|
|
44
52
|
1. A warning notification is shown with a stable ID (`vc-framework-offline-status`) so it cannot be duplicated.
|
|
45
53
|
2. The CSS class `vc-offline` is added to `document.documentElement`.
|
|
46
54
|
3. A warning is logged via `createLogger`.
|
|
@@ -51,21 +59,25 @@ When connectivity is restored, the notification is removed, the CSS class is cle
|
|
|
51
59
|
|
|
52
60
|
```vue
|
|
53
61
|
<script setup lang="ts">
|
|
54
|
-
import { useConnectionStatus } from
|
|
55
|
-
import { watch, ref } from
|
|
62
|
+
import { useConnectionStatus } from "@vc-shell/framework";
|
|
63
|
+
import { watch, ref } from "vue";
|
|
56
64
|
|
|
57
65
|
const { isOnline } = useConnectionStatus();
|
|
58
66
|
const pendingSave = ref(false);
|
|
59
|
-
const formData = ref({ name:
|
|
67
|
+
const formData = ref({ name: "" });
|
|
60
68
|
|
|
61
69
|
// Auto-save on changes, but only when online
|
|
62
|
-
watch(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
watch(
|
|
71
|
+
formData,
|
|
72
|
+
() => {
|
|
73
|
+
if (isOnline.value) {
|
|
74
|
+
saveToServer(formData.value);
|
|
75
|
+
} else {
|
|
76
|
+
pendingSave.value = true;
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{ deep: true },
|
|
80
|
+
);
|
|
69
81
|
|
|
70
82
|
// Flush pending save when connectivity returns
|
|
71
83
|
watch(isOnline, (online) => {
|
|
@@ -98,19 +98,19 @@ registerDashboardWidget({
|
|
|
98
98
|
|
|
99
99
|
The `size` property defines the widget's grid dimensions:
|
|
100
100
|
|
|
101
|
-
| Property | Type
|
|
102
|
-
|
|
103
|
-
| `width`
|
|
104
|
-
| `height` | `number` | Number of grid rows the widget spans
|
|
101
|
+
| Property | Type | Description |
|
|
102
|
+
| -------- | -------- | --------------------------------------- |
|
|
103
|
+
| `width` | `number` | Number of grid columns the widget spans |
|
|
104
|
+
| `height` | `number` | Number of grid rows the widget spans |
|
|
105
105
|
|
|
106
106
|
### Widget position
|
|
107
107
|
|
|
108
108
|
The optional `position` property sets the initial grid coordinates:
|
|
109
109
|
|
|
110
|
-
| Property | Type
|
|
111
|
-
|
|
112
|
-
| `x`
|
|
113
|
-
| `y`
|
|
110
|
+
| Property | Type | Description |
|
|
111
|
+
| -------- | -------- | ---------------------- |
|
|
112
|
+
| `x` | `number` | Column index (0-based) |
|
|
113
|
+
| `y` | `number` | Row index (0-based) |
|
|
114
114
|
|
|
115
115
|
### Custom props
|
|
116
116
|
|
|
@@ -357,38 +357,38 @@ Returns the injected `IDashboardService` instance. Throws `InjectionError` if th
|
|
|
357
357
|
|
|
358
358
|
#### IDashboardService Interface
|
|
359
359
|
|
|
360
|
-
| Method
|
|
361
|
-
|
|
362
|
-
| `registerWidget`
|
|
363
|
-
| `getWidgets`
|
|
364
|
-
| `updateWidgetPosition` | `(widgetId: string, position: DashboardWidgetPosition) => void` | Update a widget's grid position (throws if widget not found)
|
|
365
|
-
| `getLayout`
|
|
360
|
+
| Method | Type | Description |
|
|
361
|
+
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
362
|
+
| `registerWidget` | `(widget: DashboardWidget) => void` | Register a widget (throws on duplicate ID) |
|
|
363
|
+
| `getWidgets` | `() => DashboardWidget[]` | Get all registered widgets filtered by current user's permissions |
|
|
364
|
+
| `updateWidgetPosition` | `(widgetId: string, position: DashboardWidgetPosition) => void` | Update a widget's grid position (throws if widget not found) |
|
|
365
|
+
| `getLayout` | `() => ReadonlyMap<string, DashboardWidgetPosition>` | Get the current layout map |
|
|
366
366
|
|
|
367
367
|
### Standalone Exports
|
|
368
368
|
|
|
369
|
-
| Function
|
|
370
|
-
|
|
369
|
+
| Function | Description |
|
|
370
|
+
| --------------------------------- | ------------------------------------------------------- |
|
|
371
371
|
| `registerDashboardWidget(widget)` | Pre-register a widget before the service is initialized |
|
|
372
|
-
| `provideDashboardService()`
|
|
372
|
+
| `provideDashboardService()` | Create and provide the service in a root component |
|
|
373
373
|
|
|
374
374
|
### DashboardWidget
|
|
375
375
|
|
|
376
|
-
| Property
|
|
377
|
-
|
|
378
|
-
| `id`
|
|
379
|
-
| `name`
|
|
380
|
-
| `component`
|
|
381
|
-
| `size`
|
|
382
|
-
| `position`
|
|
383
|
-
| `permissions` | `string[]`
|
|
384
|
-
| `props`
|
|
376
|
+
| Property | Type | Required | Description |
|
|
377
|
+
| ------------- | ----------------------------------- | -------- | ---------------------------------------------- |
|
|
378
|
+
| `id` | `string` | Yes | Unique widget identifier |
|
|
379
|
+
| `name` | `string` | Yes | Display title |
|
|
380
|
+
| `component` | `Component` | Yes | Vue component to render |
|
|
381
|
+
| `size` | `{ width: number; height: number }` | Yes | Grid size (columns x rows) |
|
|
382
|
+
| `position` | `{ x: number; y: number }` | No | Initial grid position |
|
|
383
|
+
| `permissions` | `string[]` | No | Required permissions for visibility (OR logic) |
|
|
384
|
+
| `props` | `Record<string, unknown>` | No | Props passed to the widget component |
|
|
385
385
|
|
|
386
386
|
### DashboardWidgetPosition
|
|
387
387
|
|
|
388
|
-
| Property | Type
|
|
389
|
-
|
|
390
|
-
| `x`
|
|
391
|
-
| `y`
|
|
388
|
+
| Property | Type | Description |
|
|
389
|
+
| -------- | -------- | ---------------------- |
|
|
390
|
+
| `x` | `number` | Column index (0-based) |
|
|
391
|
+
| `y` | `number` | Row index (0-based) |
|
|
392
392
|
|
|
393
393
|
## Related
|
|
394
394
|
|