@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.
Files changed (195) hide show
  1. package/CHANGELOG.md +59 -47
  2. package/README.md +18 -12
  3. package/package.json +4 -4
  4. package/runtime/VERSION +1 -1
  5. package/runtime/agents/api-analyzer.md +31 -16
  6. package/runtime/agents/blade-enhancer.md +15 -9
  7. package/runtime/agents/details-blade-generator.md +47 -31
  8. package/runtime/agents/list-blade-generator.md +21 -37
  9. package/runtime/agents/locales-generator.md +3 -0
  10. package/runtime/agents/migration-agent.md +94 -0
  11. package/runtime/agents/module-analyzer.md +2 -0
  12. package/runtime/agents/module-assembler.md +15 -0
  13. package/runtime/agents/promote-agent.md +15 -4
  14. package/runtime/agents/type-checker.md +11 -0
  15. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  16. package/runtime/knowledge/docs/core/api/platform.docs.md +30 -30
  17. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +41 -41
  18. package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +12 -10
  19. package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +11 -14
  20. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +35 -35
  21. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +35 -35
  22. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +15 -15
  23. package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +21 -18
  24. package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +31 -27
  25. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +90 -61
  26. package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +19 -18
  27. package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +89 -68
  28. package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +75 -19
  29. package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
  30. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +74 -78
  31. package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +11 -11
  32. package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +27 -15
  33. package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +30 -30
  34. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +34 -36
  35. package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +44 -23
  36. package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +14 -11
  37. package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +47 -38
  38. package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +37 -28
  39. package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +23 -17
  40. package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +10 -10
  41. package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +42 -42
  42. package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +22 -12
  43. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +33 -41
  44. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +16 -16
  45. package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +32 -24
  46. package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +32 -11
  47. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +24 -15
  48. package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +7 -7
  49. package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +32 -24
  50. package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +21 -17
  51. package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +24 -24
  52. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +28 -31
  53. package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +43 -24
  54. package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +68 -48
  55. package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +19 -19
  56. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +42 -47
  57. package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +10 -4
  58. package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +35 -20
  59. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +36 -35
  60. package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +38 -38
  61. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +107 -91
  62. package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +10 -10
  63. package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +21 -23
  64. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +98 -90
  65. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +10 -16
  66. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +9 -9
  67. package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +65 -22
  68. package/runtime/knowledge/docs/core/services/services.docs.md +19 -22
  69. package/runtime/knowledge/docs/core/types/types.docs.md +40 -40
  70. package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +27 -27
  71. package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +23 -23
  72. package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +22 -25
  73. package/runtime/knowledge/docs/core/utilities/utilities.docs.md +64 -64
  74. package/runtime/knowledge/docs/injection-keys.docs.md +52 -51
  75. package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +9 -9
  76. package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +23 -43
  77. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +102 -0
  78. package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +5 -5
  79. package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +8 -7
  80. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -7
  81. package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +8 -7
  82. package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +29 -13
  83. package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +13 -16
  84. package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +1 -7
  85. package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +5 -5
  86. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
  87. package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
  88. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -9
  89. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +12 -18
  90. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +34 -65
  91. package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +16 -26
  92. package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +2 -2
  93. package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -9
  94. package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +30 -40
  95. package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +26 -19
  96. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +15 -12
  97. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +15 -26
  98. package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +21 -19
  99. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +83 -67
  100. package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +104 -59
  101. package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +28 -11
  102. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +20 -17
  103. package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +26 -17
  104. package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +30 -32
  105. package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +25 -48
  106. package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +29 -24
  107. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +23 -15
  108. package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +22 -13
  109. package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +33 -18
  110. package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +56 -15
  111. package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +28 -15
  112. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +40 -20
  113. package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +25 -14
  114. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +40 -14
  115. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +54 -42
  116. package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +17 -17
  117. package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +21 -21
  118. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +23 -10
  119. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +59 -44
  120. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +23 -20
  121. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +96 -64
  122. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +26 -35
  123. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +69 -22
  124. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +58 -72
  125. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +91 -85
  126. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +38 -42
  127. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +60 -72
  128. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +65 -26
  129. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +46 -49
  130. package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +35 -64
  131. package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +38 -41
  132. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +115 -130
  133. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +53 -87
  134. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +56 -63
  135. package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +29 -24
  136. package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +32 -28
  137. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +63 -64
  138. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +28 -26
  139. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +59 -19
  140. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +25 -34
  141. package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +42 -32
  142. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +78 -82
  143. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +25 -15
  144. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +59 -63
  145. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +57 -69
  146. package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +58 -57
  147. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +49 -26
  148. package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +82 -28
  149. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +120 -75
  150. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +30 -44
  151. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +536 -365
  152. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +35 -52
  153. package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +33 -62
  154. package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +17 -23
  155. package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +109 -68
  156. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +82 -44
  157. package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +8 -8
  158. package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +164 -0
  159. package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +34 -26
  160. package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +48 -40
  161. package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +30 -17
  162. package/runtime/knowledge/docs/ui/types/ui-types.docs.md +40 -29
  163. package/runtime/knowledge/examples/offers-module.md +15 -13
  164. package/runtime/knowledge/examples/team-module.md +82 -119
  165. package/runtime/knowledge/examples/videos-module.md +44 -17
  166. package/runtime/knowledge/index.md +22 -0
  167. package/runtime/knowledge/migration-prompts/blade-form-migration.md +255 -0
  168. package/runtime/knowledge/migration-prompts/blade-props-migration.md +194 -0
  169. package/runtime/knowledge/migration-prompts/datatable-migration.md +801 -0
  170. package/runtime/knowledge/migration-prompts/icon-migration.md +97 -0
  171. package/runtime/knowledge/migration-prompts/manual-migration-audit.md +117 -0
  172. package/runtime/knowledge/migration-prompts/notifications-migration.md +223 -0
  173. package/runtime/knowledge/migration-prompts/nswag-migration.md +244 -0
  174. package/runtime/knowledge/migration-prompts/use-assets-migration.md +164 -0
  175. package/runtime/knowledge/migration-prompts/use-data-table-pagination-migration.md +176 -0
  176. package/runtime/knowledge/migration-prompts/widgets-migration.md +178 -0
  177. package/runtime/knowledge/patterns/assets-management.md +20 -20
  178. package/runtime/knowledge/patterns/blade-navigation.md +7 -14
  179. package/runtime/knowledge/patterns/blade-widget.md +19 -17
  180. package/runtime/knowledge/patterns/child-blade-flow.md +19 -7
  181. package/runtime/knowledge/patterns/composable-details.md +20 -50
  182. package/runtime/knowledge/patterns/composable-list.md +43 -31
  183. package/runtime/knowledge/patterns/dashboard-widget.md +14 -16
  184. package/runtime/knowledge/patterns/datatable-pattern.md +521 -0
  185. package/runtime/knowledge/patterns/details-blade-pattern.md +78 -116
  186. package/runtime/knowledge/patterns/extension-points-usage.md +53 -44
  187. package/runtime/knowledge/patterns/form-validation.md +28 -64
  188. package/runtime/knowledge/patterns/list-blade-pattern.md +33 -21
  189. package/runtime/knowledge/patterns/module-structure.md +7 -1
  190. package/runtime/knowledge/patterns/multilanguage-fields.md +8 -14
  191. package/runtime/knowledge/patterns/notification-template.md +21 -14
  192. package/runtime/knowledge/patterns/signalr-notifications.md +30 -32
  193. package/runtime/knowledge/patterns/toolbar-pattern.md +18 -20
  194. package/runtime/vc-app.md +354 -49
  195. 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 | 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 |
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 | Type | Description |
55
- |----------|------|-------------|
56
- | `setBaseline()` | `() => void` | Snapshot current data as pristine. Call after load and after save |
57
- | `revert()` | `() => void \| Promise<void>` | Revert data to pristine (or call onRevert) |
58
- | `canSave` | `ComputedRef<boolean>` | `isReady && valid && modified && canSaveOverride` |
59
- | `isModified` | `ComputedRef<boolean>` | Data differs from pristine (false until setBaseline) |
60
- | `isReady` | `ComputedRef<boolean>` | setBaseline() called at least once |
61
- | `formMeta` | vee-validate meta | Form validation state |
62
- | `setFieldError` | function | Set field error programmatically |
63
- | `errorBag` | Ref | All field errors |
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
- └→ Cancel → revert()
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 | 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)) |
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 | 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 |
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"); // { name: "OrdersList", data: { ... } }
95
- resolveDeepLink("/orders"); // Same result
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 | Called from | Purpose |
6
- |---|---|---|
7
- | `useBladeWidgets` | Blade component | Register headless widgets + get `refresh()` / `refreshAll()` |
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 '@vc-shell/framework';
21
+ import { useBladeWidgets } from "@vc-shell/framework";
22
22
 
23
23
  const { refreshAll } = useBladeWidgets([
24
24
  {
25
- id: 'OffersWidget',
26
- icon: 'lucide-tag',
27
- title: 'OFFERS.TITLE',
28
- badge: offersCount,
29
- loading: offersLoading,
30
- onClick: () => openBlade({ name: 'OffersList' }),
31
- onRefresh: () => reloadOffers(),
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: 'ReviewsWidget',
35
- icon: 'lucide-star',
36
- title: 'REVIEWS.TITLE',
37
- badge: reviewsCount,
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: 'ReviewsList' }),
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 | Required | Description |
53
- |---|---|---|---|
54
- | `widgets` | `HeadlessWidgetDeclaration[]` | Yes | Array of widget declarations |
52
+ | Parameter | Type | Required | Description |
53
+ | --------- | ----------------------------- | -------- | ---------------------------- |
54
+ | `widgets` | `HeadlessWidgetDeclaration[]` | Yes | Array of widget declarations |
55
55
 
56
56
  ### HeadlessWidgetDeclaration
57
57
 
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()` |
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 | 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 |
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 '@vc-shell/framework';
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 | 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 |
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: ["ProductDetails", "OrderDetails"],
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.saveProduct(product.value);
186
- refreshAll(); // refresh all widgets (including MessageWidget)
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: Product Detail Blade with Multiple Widgets
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 product = ref({ id: "prod-1", name: "Widget A" });
200
- const offersCount = ref(0);
201
- const reviewsCount = ref(0);
202
- const offersLoading = ref(false);
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 product data to widgets
205
- defineBladeContext(computed(() => ({ id: product.value?.id })));
198
+ // Expose entity data to widgets
199
+ defineBladeContext(computed(() => ({ id: entity.value?.id })));
206
200
 
207
- async function reloadOffers() {
208
- offersLoading.value = true;
201
+ async function reloadChildren() {
202
+ childLoading.value = true;
209
203
  try {
210
- const result = await api.searchOffers({ productId: product.value.id });
211
- offersCount.value = result.totalCount;
204
+ const result = await api.searchChildren({ entityId: entity.value.id });
205
+ childCount.value = result.totalCount;
212
206
  } finally {
213
- offersLoading.value = false;
207
+ childLoading.value = false;
214
208
  }
215
209
  }
216
210
 
217
211
  const { refreshAll } = useBladeWidgets([
218
212
  {
219
- id: "OffersWidget",
213
+ id: "ChildListWidget",
220
214
  icon: "lucide-tag",
221
- title: "PRODUCT.WIDGETS.OFFERS",
222
- badge: offersCount,
223
- loading: offersLoading,
224
- isVisible: computed(() => !!product.value?.id),
225
- onClick: () => openBlade({ name: "OffersList" }),
226
- onRefresh: reloadOffers,
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: "ReviewsWidget",
223
+ id: "NotesWidget",
230
224
  icon: "lucide-star",
231
- title: "PRODUCT.WIDGETS.REVIEWS",
232
- badge: reviewsCount,
233
- isVisible: computed(() => !!product.value?.id),
234
- onClick: () => openBlade({ name: "ReviewsList" }),
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.saveProduct(product.value);
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 | 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 |
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 | 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 |
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
 
@@ -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 '@vc-shell/framework';
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 v-if="!isOnline" class="tw-bg-yellow-100 tw-p-2 tw-rounded tw-mb-4">
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 :disabled="!isOnline" @click="save">Save Order</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 | Type | Description |
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 '@vc-shell/framework';
55
- import { watch, ref } from 'vue';
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(formData, () => {
63
- if (isOnline.value) {
64
- saveToServer(formData.value);
65
- } else {
66
- pendingSave.value = true;
67
- }
68
- }, { deep: true });
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 | Description |
102
- |----------|------|-------------|
103
- | `width` | `number` | Number of grid columns the widget spans |
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 | Description |
111
- |----------|------|-------------|
112
- | `x` | `number` | Column index (0-based) |
113
- | `y` | `number` | Row index (0-based) |
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 | 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 |
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 | Description |
370
- |----------|-------------|
369
+ | Function | Description |
370
+ | --------------------------------- | ------------------------------------------------------- |
371
371
  | `registerDashboardWidget(widget)` | Pre-register a widget before the service is initialized |
372
- | `provideDashboardService()` | Create and provide the service in a root component |
372
+ | `provideDashboardService()` | Create and provide the service in a root component |
373
373
 
374
374
  ### DashboardWidget
375
375
 
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 |
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 | Description |
389
- |----------|------|-------------|
390
- | `x` | `number` | Column index (0-based) |
391
- | `y` | `number` | Row index (0-based) |
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