@vc-shell/vc-app-skill 2.0.5 → 2.0.6

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 (60) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +7 -7
  3. package/package.json +1 -1
  4. package/runtime/VERSION +1 -1
  5. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  6. package/runtime/knowledge/docs/core/api/platform.docs.md +6 -6
  7. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +1 -1
  8. package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +2 -2
  9. package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +67 -42
  10. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +2 -2
  11. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +15 -13
  12. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +11 -11
  13. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +17 -14
  14. package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +4 -2
  15. package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +31 -23
  16. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +46 -26
  17. package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +1 -0
  18. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +1 -1
  19. package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +1 -1
  20. package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +1 -0
  21. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +20 -6
  22. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +2 -1
  23. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +2 -2
  24. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +109 -133
  25. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +1 -2
  26. package/runtime/knowledge/docs/core/notifications/composables/useBladeNotifications.docs.md +184 -0
  27. package/runtime/knowledge/docs/core/notifications/composables/useBroadcastFilter.docs.md +117 -0
  28. package/runtime/knowledge/docs/core/notifications/composables/useNotificationContext.docs.md +150 -0
  29. package/runtime/knowledge/docs/core/notifications/composables/useNotificationStore.docs.md +113 -0
  30. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +12 -15
  31. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +1 -1
  32. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +54 -116
  33. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +12 -3
  34. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +20 -20
  35. package/runtime/knowledge/docs/injection-keys.docs.md +1 -1
  36. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +1 -1
  37. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
  38. package/runtime/knowledge/docs/shell/components/notification-dropdown/notification-dropdown.docs.md +1 -1
  39. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +1 -1
  40. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +7 -7
  41. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +2 -2
  42. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +1 -1
  43. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +4 -4
  44. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +1 -1
  45. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +21 -1
  46. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +22 -6
  47. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +2 -2
  48. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +32 -26
  49. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +3 -3
  50. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +1 -1
  51. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +1 -1
  52. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +1 -1
  53. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +13 -13
  54. package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +1 -1
  55. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +1 -1
  56. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +4 -4
  57. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +39 -37
  58. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +17 -17
  59. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +16 -7
  60. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.6](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.5...v2.0.6) (2026-05-25)
4
+
5
+ ### Features
6
+
7
+ - docs-sync improvements, lint rules, and reference docs alignment (#229) ([a3ddbc2](https://github.com/VirtoCommerce/vc-shell/commit/a3ddbc29a90e55632df702f776e11bc8bc4aec67)), closes [#229](https://github.com/VirtoCommerce/vc-shell/issues/229)
8
+
3
9
  ## [2.0.5](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.4...v2.0.5) (2026-05-25)
4
10
 
5
11
  **Note:** Version bump only for package @vc-shell/vc-app-skill
package/README.md CHANGED
@@ -22,7 +22,7 @@ The skill covers:
22
22
  ### Claude Code / Cursor / GitHub Copilot
23
23
 
24
24
  ```bash
25
- npx @vc-shell/vc-app-skill@alpha install
25
+ npx @vc-shell/vc-app-skill@latest install
26
26
  ```
27
27
 
28
28
  Installs skill files into `~/.claude/vc-app-skill/` and registers the `/vc-app` slash command.
@@ -30,19 +30,19 @@ Installs skill files into `~/.claude/vc-app-skill/` and registers the `/vc-app`
30
30
  ### OpenCode
31
31
 
32
32
  ```bash
33
- npx @vc-shell/vc-app-skill@alpha install --runtime opencode
33
+ npx @vc-shell/vc-app-skill@latest install --runtime opencode
34
34
  ```
35
35
 
36
36
  ### Gemini CLI
37
37
 
38
38
  ```bash
39
- npx @vc-shell/vc-app-skill@alpha install --runtime gemini
39
+ npx @vc-shell/vc-app-skill@latest install --runtime gemini
40
40
  ```
41
41
 
42
42
  ### Codex
43
43
 
44
44
  ```bash
45
- npx @vc-shell/vc-app-skill@alpha install --runtime codex
45
+ npx @vc-shell/vc-app-skill@latest install --runtime codex
46
46
  ```
47
47
 
48
48
  ### Verify installation
@@ -180,7 +180,7 @@ Handles topics: widgets, form management (`useBladeForm`), injection-key renames
180
180
  ## Update
181
181
 
182
182
  ```bash
183
- npx @vc-shell/vc-app-skill@alpha install
183
+ npx @vc-shell/vc-app-skill@latest install
184
184
  ```
185
185
 
186
186
  Or from within your AI tool:
@@ -194,7 +194,7 @@ The installer checks the installed version against the package version and overw
194
194
  ## Uninstall
195
195
 
196
196
  ```bash
197
- npx @vc-shell/vc-app-skill@alpha uninstall
197
+ npx @vc-shell/vc-app-skill@latest uninstall
198
198
  ```
199
199
 
200
200
  Removes skill files from the AI tool's configuration directory. Does not affect your application source code.
@@ -202,7 +202,7 @@ Removes skill files from the AI tool's configuration directory. Does not affect
202
202
  To uninstall for a specific runtime:
203
203
 
204
204
  ```bash
205
- npx @vc-shell/vc-app-skill@alpha uninstall --runtime opencode
205
+ npx @vc-shell/vc-app-skill@latest uninstall --runtime opencode
206
206
  ```
207
207
 
208
208
  ## Architecture
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vc-shell/vc-app-skill",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "AI coding skill for scaffolding and generating VirtoCommerce Shell applications. Works with Claude Code, OpenCode, Gemini, Codex, Cursor.",
5
5
  "bin": "./bin/install.cjs",
6
6
  "files": [
package/runtime/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.5
1
+ 2.0.6
@@ -1 +1 @@
1
- Synced from framework at commit b767fd821 on 2026-05-25T06:22:23.513Z
1
+ Synced from framework at commit a3ddbc29a on 2026-05-25T13:00:53.288Z
@@ -11,9 +11,9 @@ Auto-generated TypeScript API client for the VirtoCommerce Platform REST API. Ge
11
11
 
12
12
  ## Overview
13
13
 
14
- Communicating with the VirtoCommerce platform backend requires typed HTTP client classes that match the platform's REST endpoints. Rather than manually writing fetch calls or Axios requests, the framework provides auto-generated client classes that handle URL construction, request serialization, response deserialization, and authentication token injection.
14
+ Communicating with the VirtoCommerce platform backend requires typed HTTP client classes that match the platform's REST endpoints. Rather than manually writing fetch calls or Axios requests, the framework provides auto-generated client classes that handle URL construction, request serialization, and response deserialization.
15
15
 
16
- Each API client class extends `AuthApiBase`, which automatically attaches the Bearer token to every request. Data model types (DTOs, Commands, Queries) are generated as **interfaces** (not classes), so they cannot be instantiated with `new` -- use object literals with type annotations instead. The clients are generated by NSwag from the platform's Swagger/OpenAPI specification and should not be edited manually -- any manual changes will be overwritten during regeneration.
16
+ Each API client class extends `AuthApiBase`. The base class carries an `authToken` field and, when that field has a value, attaches it as a `Bearer` header through `transformOptions`. In the default `useApiClient` flow, the client is instantiated without arguments and `authToken` stays empty — same-origin API calls are authenticated by the session cookie that the browser replays automatically. Code that needs to bypass cookies (cross-origin, non-browser, manual flows) can call `setAuthToken(token)` on a client instance directly. Data model types (DTOs, Commands, Queries) are generated as **interfaces** (not classes), so they cannot be instantiated with `new` -- use object literals with type annotations instead. The clients are generated by NSwag from the platform's Swagger/OpenAPI specification and should not be edited manually -- any manual changes will be overwritten during regeneration.
17
17
 
18
18
  **File:** `platform.ts` (auto-generated, do not edit manually)
19
19
 
@@ -21,7 +21,7 @@ Each API client class extends `AuthApiBase`, which automatically attaches the Be
21
21
 
22
22
  - Call platform-level REST endpoints (security, settings, notifications, modules, dynamic properties) from typed TypeScript clients
23
23
  - Access platform DTOs (`ApplicationUser`, `PushNotification`, `Role`, `Permission`, etc.) as typed interfaces
24
- - Combine with `useApiClient` for automatic token management and caching
24
+ - Combine with `useApiClient` to obtain a configured client instance through a single composable
25
25
  - When NOT to use: for domain-module APIs (orders, catalog, inventory) -- use their own generated clients instead; for third-party APIs -- use `fetch` or Axios directly
26
26
 
27
27
  ## API Clients
@@ -68,7 +68,7 @@ export class AuthApiBase {
68
68
  authToken: string;
69
69
  setAuthToken(token: string): void;
70
70
  protected getBaseUrl(defaultUrl: string, baseUrl: string): string; // always returns ""
71
- protected transformOptions(options: RequestInit): Promise<RequestInit>; // injects Bearer token
71
+ protected transformOptions(options: RequestInit): Promise<RequestInit>; // sets the Bearer header only if `authToken` is non-empty
72
72
  }
73
73
  ```
74
74
 
@@ -161,8 +161,8 @@ You do not need to manually set the auth token on client instances. The `useApiC
161
161
  Do not import from the `platform.ts` file path directly. Always import from `@vc-shell/framework` to ensure proper module resolution and tree-shaking:
162
162
 
163
163
  ```typescript
164
- // Bad: direct file import
165
- import { SecurityClient } from "@core/api/platform";
164
+ // Bad: direct file path
165
+ "@core/api/platform";
166
166
 
167
167
  // Good: framework re-export
168
168
  import { SecurityClient } from "@vc-shell/framework";
@@ -158,7 +158,7 @@ The plain data object stored in the stack for each blade:
158
158
  ## Related
159
159
 
160
160
  - [`useBlade`](../composables/useBlade/) -- recommended API for everyday blade operations
161
- - [`useBladeContext`](../composables/bladeContext/) -- share reactive blade data with descendant components
161
+ - [`useBladeContext`](../composables/bladeContext/index.docs.md) -- share reactive blade data with descendant components
162
162
 
163
163
  <!-- internal:start -->
164
164
 
@@ -115,8 +115,8 @@ defineBladeContext(
115
115
 
116
116
  ## Related
117
117
 
118
- - [`useBladeWidgets`](../useBladeWidgets/) -- widgets that consume blade context
119
- - [`useBlade`](../useBlade/) -- cross-blade communication via `callParent` / `exposeToChildren`
118
+ - [`useBladeWidgets`](../useBladeWidgets/index.docs.md) -- widgets that consume blade context
119
+ - [`useBlade`](../useBlade/useBlade.docs.md) -- cross-blade communication via `callParent` / `exposeToChildren`
120
120
 
121
121
  <!-- internal:start -->
122
122
 
@@ -6,31 +6,48 @@ group: data
6
6
 
7
7
  # useApiClient
8
8
 
9
- Creates a typed API client instance for communicating with VirtoCommerce platform APIs. The composable accepts a generated client class constructor and returns an async factory function that produces a configured, authenticated client. Base URL resolution and authentication token injection are handled automatically.
9
+ Creates a typed API client instance for communicating with VirtoCommerce platform APIs. The composable accepts a generated client class constructor (extending `AuthApiBase`) and returns an async factory function that produces a client instance. The composable itself is intentionally thin — it constructs the client and returns it. Platform authentication flows through the session cookie that the browser replays on every same-origin API call; the framework's fetch wrapper enforces timeout, offline checks, and 401-redirect on top.
10
10
 
11
11
  !!! tip "Always call getApiClient inside async functions"
12
- `getApiClient` is async. Never call it at the top level of `<script setup>` — always call it inside the async function you pass to `useAsync`. Storing the client in a variable outside the function gives you a stale reference when tokens rotate.
12
+ `getApiClient` is async. Never call it at the top level of `<script setup>` — call it inside the async function you pass to `useAsync`. Holding one client instance for the lifetime of the component couples your code to a single object across action runs; prefer one `await getApiClient()` per action so the call shape stays uniform with `useAsync`.
13
13
 
14
14
  ## When to Use
15
15
 
16
- - Instantiate a generated VirtoCommerce API client with automatic authentication and base-URL resolution
16
+ - Instantiate a generated VirtoCommerce API client that extends `AuthApiBase`
17
17
  - Pair with `useAsync` for loading/error state on every API call in a blade or composable
18
18
  - When NOT to use: for third-party or non-platform APIs that do not extend `AuthApiBase` -- use `fetch` or Axios directly
19
19
 
20
20
  ## Quick Start
21
21
 
22
- ```typescript
23
- <script setup lang="ts">
24
- import { useApiClient } from "@vc-shell/framework";
25
- import { OrderClient } from "@api/orders";
22
+ The canonical place to call `useApiClient` is at the top of a domain composable file. The factory is created once per module-scope; every action that needs the client awaits `getApiClient()` from the same closure.
26
23
 
27
- const { getApiClient } = useApiClient(OrderClient);
24
+ ```typescript title="modules/orders/composables/useOrder/index.ts"
25
+ // pseudo-code: replace OrderClient with your generated API client
26
+ import { useApiClient, useAsync } from "@vc-shell/framework";
27
+ import { OrderClient, type Order } from "@api/orders";
28
+ import { ref } from "vue";
28
29
 
29
- async function loadOrder(orderId: string) {
30
- const client = await getApiClient();
31
- const order = await client.getOrderById(orderId);
32
- return order;
30
+ export function useOrder() {
31
+ const { getApiClient } = useApiClient(OrderClient);
32
+ const item = ref<Order>();
33
+
34
+ const { action: loadItem, loading } = useAsync<{ id: string }>(async ({ id }) => {
35
+ const client = await getApiClient();
36
+ item.value = await client.getOrderById(id);
37
+ });
38
+
39
+ return { item, loading, loadItem };
33
40
  }
41
+ ```
42
+
43
+ If you call `useApiClient` inside a blade's `<script setup>` directly, the same shape works. The composable pattern above is preferred because it keeps API access encapsulated behind a domain interface that the blade consumes.
44
+
45
+ ```vue title="modules/orders/pages/order-details.vue"
46
+ <script setup lang="ts">
47
+ import { useOrder } from "../composables/useOrder";
48
+
49
+ const { item, loading, loadItem } = useOrder();
50
+ onMounted(() => loadItem({ id: param.value }));
34
51
  </script>
35
52
  ```
36
53
 
@@ -39,6 +56,7 @@ async function loadOrder(orderId: string) {
39
56
  The standard pattern for API calls in blades combines `useApiClient` with `useAsync`. This gives you automatic loading state, error handling, and a clean async action:
40
57
 
41
58
  ```typescript
59
+ // pseudo-code: replace ProductClient with your generated API client
42
60
  <script setup lang="ts">
43
61
  import { useApiClient, useAsync } from "@vc-shell/framework";
44
62
  import { ProductClient, Product } from "@api/catalog";
@@ -78,6 +96,7 @@ The `loading` ref is `true` while the request is in-flight. The `error` ref capt
78
96
  When a blade needs data from multiple platform modules, create multiple client instances using destructuring aliases:
79
97
 
80
98
  ```typescript
99
+ // pseudo-code: replace these clients with your generated API clients
81
100
  <script setup lang="ts">
82
101
  import { useApiClient, useAsync } from "@vc-shell/framework";
83
102
  import { OrderClient } from "@api/orders";
@@ -105,6 +124,7 @@ const { action: loadOrderDetails } = useAsync(async (orderId: string) => {
105
124
  API clients generated from VirtoCommerce platform endpoints follow a consistent search pattern with `SearchCriteria` objects:
106
125
 
107
126
  ```typescript
127
+ // pseudo-code: replace OrderClient with your generated API client
108
128
  <script setup lang="ts">
109
129
  import { useApiClient, useAsync } from "@vc-shell/framework";
110
130
  import { OrderClient, OrderSearchCriteria, OrderSearchResult } from "@api/orders";
@@ -129,60 +149,63 @@ searchOrders();
129
149
 
130
150
  ## CRUD Operations Pattern
131
151
 
132
- A complete CRUD composable for a domain entity:
152
+ A complete CRUD composable for a domain entity. The toolbar is declared as a plain `IBladeToolbar[]` array and bound via `<VcBlade :toolbar-items>`; reactive `disabled` follows the `loading` refs directly, without a `watch`/`updateToolbarItem` pair:
133
153
 
134
- ```typescript
154
+ ```vue
155
+ <!-- pseudo-code: replace ProductClient with your generated API client -->
135
156
  <script setup lang="ts">
136
- import { ref, onMounted } from "vue";
137
- import { useApiClient, useAsync, useToolbar } from "@vc-shell/framework";
138
- import { ProductClient, Product } from "@api/catalog";
157
+ import { computed, onMounted, ref } from "vue";
158
+ import { useApiClient, useAsync, VcBlade, type IBladeToolbar } from "@vc-shell/framework";
159
+ import { ProductClient, type Product } from "@api/catalog";
139
160
 
140
161
  const props = defineProps<{ param: string }>();
141
162
 
142
163
  const { getApiClient } = useApiClient(ProductClient);
143
- const { registerToolbarItem, updateToolbarItem } = useToolbar();
144
164
  const product = ref<Product>();
145
165
 
146
- // Load
147
166
  const { loading, action: load } = useAsync(async () => {
148
167
  const client = await getApiClient();
149
168
  product.value = await client.getProductById(props.param);
150
169
  });
151
170
 
152
- // Save
153
171
  const { loading: saving, action: save } = useAsync(async () => {
154
172
  const client = await getApiClient();
155
173
  product.value = await client.updateProduct(product.value);
156
174
  });
157
175
 
158
- // Delete
159
176
  const { loading: deleting, action: remove } = useAsync(async () => {
160
177
  const client = await getApiClient();
161
178
  await client.deleteProducts([props.param]);
162
179
  });
163
180
 
164
- registerToolbarItem({
165
- id: "save",
166
- title: "Save",
167
- icon: "fas fa-save",
168
- clickHandler: () => save(),
169
- priority: 100,
170
- });
171
-
172
- registerToolbarItem({
173
- id: "refresh",
174
- title: "Refresh",
175
- icon: "fas fa-sync",
176
- clickHandler: () => load(),
177
- priority: 50,
178
- });
179
-
180
- watch([saving, deleting, loading], ([s, d, l]) => {
181
- updateToolbarItem("save", { disabled: s || d || l });
182
- });
181
+ const busy = computed(() => saving.value || deleting.value || loading.value);
182
+
183
+ const bladeToolbar = ref<IBladeToolbar[]>([
184
+ {
185
+ id: "save",
186
+ title: "Save",
187
+ icon: "fas fa-save",
188
+ clickHandler: () => save(),
189
+ disabled: busy,
190
+ },
191
+ {
192
+ id: "refresh",
193
+ title: "Refresh",
194
+ icon: "fas fa-sync",
195
+ clickHandler: () => load(),
196
+ disabled: busy,
197
+ },
198
+ ]);
183
199
 
184
200
  onMounted(() => load());
185
201
  </script>
202
+
203
+ <template>
204
+ <VcBlade
205
+ :loading="loading"
206
+ :toolbar-items="bladeToolbar"
207
+ />
208
+ </template>
186
209
  ```
187
210
 
188
211
  ## Recipes
@@ -281,7 +304,7 @@ const response = await fetch("https://api.weather.com/forecast");
281
304
 
282
305
  ### IAuthApiBase Interface
283
306
 
284
- All generated API client classes implement this interface:
307
+ All generated API client classes extend `AuthApiBase`, which conforms to this interface:
285
308
 
286
309
  | Property / Method | Type | Description |
287
310
  | ----------------- | ------------------------------------------------- | ----------------------------- |
@@ -289,6 +312,8 @@ All generated API client classes implement this interface:
289
312
  | `setAuthToken` | `(token: string) => void` | Sets the authentication token |
290
313
  | `getBaseUrl` | `(defaultUrl: string, baseUrl: string) => string` | Resolves the API base URL |
291
314
 
315
+ The interface is the public contract used by `useApiClient`'s type parameter. In the everyday flow, application code does not call `setAuthToken` — `useApiClient` constructs the client with no arguments, the `authToken` field stays empty, and authentication flows through the session cookie attached by the browser to each same-origin `/api/*` request. `setAuthToken` is the explicit-token path consumed by code that needs to attach a token directly (for example, when calling the API from a context where the cookie is unavailable).
316
+
292
317
  ### Generated Client Classes
293
318
 
294
319
  API clients are generated from Swagger/OpenAPI specs using the `@vc-shell/api-client-generator` CLI tool. Each generated class:
@@ -302,5 +327,5 @@ API clients are generated from Swagger/OpenAPI specs using the `@vc-shell/api-cl
302
327
 
303
328
  - [`useAsync`](../useAsync/) -- wraps async API calls with loading/error state management
304
329
  - CLI API Client Generator (`@vc-shell/api-client-generator`) -- generates typed client classes from Swagger specs
305
- - [`useToolbar`](../useToolbar/) -- disable toolbar buttons during API calls using the loading ref
330
+ - Blade toolbar — declare as `ref<IBladeToolbar[]>([...])` and bind via `<VcBlade :toolbar-items>`; see [`useToolbar`](../useToolbar/) for the advanced dynamic-registration API
306
331
  - [`useNotifications`](../useNotifications/) -- display success/error messages after API operations
@@ -13,7 +13,7 @@ Manages custom action buttons in the mobile app bar. Uses provide/inject to shar
13
13
  - Register custom buttons (icons, components) in the mobile top bar from any blade or module
14
14
  - Show notification badges, filter toggles, or action shortcuts in the mobile app bar
15
15
  - Dynamically show/hide buttons based on blade state (e.g., only show a "filter" button when a list blade is active)
16
- - When NOT to use: for desktop-only toolbar actions (use `useToolbar` instead); for buttons inside blade content (just use regular template markup)
16
+ - When NOT to use: for desktop blade toolbar actions, declare an `IBladeToolbar[]` array and pass it to `<VcBlade :toolbar-items>` (reach for `useToolbar` only when toolbar items must be added after mount); for buttons inside blade content, just use regular template markup
17
17
 
18
18
  ## Quick Start
19
19
 
@@ -137,6 +137,6 @@ onUnmounted(() => unregister("language-switcher"));
137
137
 
138
138
  ## Related
139
139
 
140
- - `useToolbar` -- desktop toolbar actions (different service, different UI placement)
140
+ - Desktop blade toolbar actions — declare an `IBladeToolbar[]` array bound via `<VcBlade :toolbar-items>`; `useToolbar` is the advanced API for dynamic registration after mount
141
141
  - `framework/core/services/app-bar-mobile-buttons-service.ts` -- underlying service implementation
142
142
  - `VcApp` -- provides the service via `provideAppBarMobileButtonsService()`
@@ -6,23 +6,25 @@ group: services
6
6
 
7
7
  # useAppBarWidget
8
8
 
9
- Provides access to the app bar widget service for registering custom widgets (buttons, icons, dropdowns) in the application's top navigation bar. Uses Vue's provide/inject system.
9
+ Provides access to the widget service that powers the **Widgets** section of the App hub popover. Modules use it to register cross-app widgets — sync status indicators, language pickers, feature shortcuts — that the shell renders next to the apps grid in the hub. Uses Vue's provide/inject system.
10
10
 
11
11
  Also exports `provideAppBarWidget()` for framework-level initialization.
12
12
 
13
+ > The `useAppBarWidget` name is a holdover from an earlier shell version where widgets rendered directly in the sidebar app-bar. In the current shell, the API name is the only place "app-bar" survives — the actual surface is the App hub popover.
14
+
13
15
  ## Overview
14
16
 
15
- The vc-shell application header (app bar) contains a row of widget slots for global actions: notification bell, language picker, user menu, and more. Modules can add their own widgets to this bar -- for example, a "quick create" button, a sync status indicator, or a custom dropdown.
17
+ In the default VcApp shell, registered widgets render inside the **Widgets** section of the App hub popover (the panel that opens from the app-hub trigger button in the sidebar). The sidebar app-bar itself only holds the notification bell and the app-hub trigger; widgets do not appear there. On mobile, the same widgets surface in the hub tab and fly out below the panel when activated.
16
18
 
17
- The `useAppBarWidget()` composable provides the `IAppBarWidgetService` interface, which allows registering, unregistering, and listing app bar widgets. Widgets can be simple icon buttons with click handlers or fully custom Vue components.
19
+ The `useAppBarWidget()` composable provides the `IAppBarWidgetService` interface, which allows registering, unregistering, and listing widgets. Each widget is either an action widget (an icon plus an `onClick` handler) or a component widget (a custom Vue component that the hub expands inline when clicked).
18
20
 
19
21
  The service follows the same provide/inject singleton pattern as other framework services. The framework calls `provideAppBarWidget()` during bootstrap; modules consume it via `useAppBarWidget()`.
20
22
 
21
23
  ## When to Use
22
24
 
23
- - To register a custom widget (notification bell, language picker, user avatar) in the app bar
24
- - To list or manage currently registered app bar widgets
25
- - When NOT to use: for blade-level toolbar actions, use `useToolbar()` instead
25
+ - To register a cross-app widget (sync status, language picker, feature shortcut) in the App hub
26
+ - To list or manage currently registered hub widgets
27
+ - When NOT to use: for blade-level toolbar actions, declare an `IBladeToolbar[]` array and pass it to `<VcBlade :toolbar-items>` (use `useToolbar()` only for dynamic registration after mount)
26
28
 
27
29
  ## Basic Usage
28
30
 
@@ -49,16 +51,16 @@ None.
49
51
 
50
52
  | Property / Method | Type | Description |
51
53
  | ----------------- | -------------------------------------------------- | ---------------------------------------------------------- |
52
- | `register` | `(options: registerAppBarWidgetOptions) => string` | Registers a widget in the app bar, returns the assigned ID |
53
- | `unregister` | `(id: string) => void` | Removes a widget from the app bar by ID |
54
- | `items` | `ComputedRef<AppBarWidget[]>` | Reactive list of all registered app bar widgets |
54
+ | `register` | `(options: registerAppBarWidgetOptions) => string` | Registers a widget in the App hub, returns the assigned ID |
55
+ | `unregister` | `(id: string) => void` | Removes a widget from the App hub by ID |
56
+ | `items` | `ComputedRef<AppBarWidget[]>` | Reactive list of all registered hub widgets |
55
57
 
56
58
  ### registerAppBarWidgetOptions
57
59
 
58
60
  | Field | Type | Required | Description |
59
61
  | ----------- | ------------------------- | -------- | ------------------------------------------------------------- |
60
62
  | `id` | `string` | No | Custom ID; auto-generated if omitted |
61
- | `order` | `number` | No | Sort order in the app bar (lower = further left) |
63
+ | `order` | `number` | No | Sort order in the hub Widgets list (lower = appears first) |
62
64
  | `title` | `string` | No | Tooltip or label text |
63
65
  | `icon` | `Component \| string` | No | Lucide icon name or a Vue component |
64
66
  | `component` | `Component` | No | Custom Vue component to render instead of default icon button |
@@ -136,14 +138,14 @@ const { items } = useAppBarWidget();
136
138
 
137
139
  // Iterate over all widgets (sorted by order)
138
140
  watchEffect(() => {
139
- console.log(`${items.value.length} widgets in app bar`);
141
+ console.log(`${items.value.length} widgets in the App hub`);
140
142
  items.value.forEach((w) => console.log(` - ${w.title ?? w.id}`));
141
143
  });
142
144
  ```
143
145
 
144
146
  ### Pre-registration before service exists
145
147
 
146
- If your module code runs before the app bar service is provided (e.g., during module `install()`), use the `addAppBarWidget()` bus function. Items are automatically flushed when `provideAppBarWidget()` runs:
148
+ If your module code runs before the widget service is provided (e.g., during module `install()`), use the `addAppBarWidget()` bus function. Items are automatically flushed when `provideAppBarWidget()` runs:
147
149
 
148
150
  ```typescript
149
151
  import { addAppBarWidget } from "@vc-shell/framework";
@@ -185,7 +187,7 @@ register({ component: markRaw(MyWidget) });
185
187
 
186
188
  ## Related
187
189
 
188
- - [useToolbar](../useToolbar/) -- blade-level toolbar actions (different scope than app bar)
190
+ - Blade toolbar actions — declare an `IBladeToolbar[]` array and bind it via `<VcBlade :toolbar-items>`; see [useToolbar](../useToolbar/) for the advanced dynamic-registration API
189
191
  - [useWidgets](../useWidgets/useWidgets.docs.md) -- blade widget registration system
190
192
  - `framework/injection-keys.ts` -- `AppBarWidgetServiceKey`
191
193
  - `framework/core/services/app-bar-menu-service.ts` -- the underlying service implementation
@@ -6,7 +6,7 @@ group: utilities
6
6
 
7
7
  # useAppInsights
8
8
 
9
- Integrates Azure Application Insights page-view tracking with Vue Router and the current user context. This composable bridges the `vue3-application-insights` plugin with the vc-shell framework by automatically enriching every page-view event with the authenticated user's ID and name, generating fresh W3C trace IDs per navigation for distributed tracing, and optionally prefixing page names with the application name (e.g., `[Vendor Portal] Dashboard`).
9
+ Integrates Azure Application Insights page-view tracking with Vue Router and the current user context. This composable bridges the `vue3-application-insights` plugin with the vc-shell framework by automatically enriching every page-view event with the authenticated user's ID and name, generating fresh W3C trace IDs per navigation for distributed tracing, and optionally prefixing page names with the application name (for example, `[Operations Console] Dashboard`).
10
10
 
11
11
  ## When to Use
12
12
 
@@ -42,17 +42,17 @@ export default router;
42
42
 
43
43
  ### Returns
44
44
 
45
- | Property | Type | Description |
46
- | ------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
47
- | `setupPageTracking.beforeEach` | `(route: { name: string }) => void` | Call in router `beforeEach` to start page-view timing and generate a new trace ID |
48
- | `setupPageTracking.afterEach` | `(route: { name: string; fullPath: string }) => void` | Call in router `afterEach` to stop page-view timing and flush the telemetry event |
49
- | `appInsights` | `ApplicationInsights` | Raw Application Insights instance for custom telemetry (trackEvent, trackException, trackMetric, etc.) |
45
+ | Property | Type | Description |
46
+ | ------------------------------ | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
47
+ | `setupPageTracking.beforeEach` | `(route: { name: string }) => void` | Call in router `beforeEach` to start page-view timing and generate a new trace ID |
48
+ | `setupPageTracking.afterEach` | `(route: { name: string; fullPath: string }) => void` | Call in router `afterEach` to stop page-view timing and flush the telemetry event |
49
+ | `appInsights` | `ApplicationInsights \| null` | Raw Application Insights instance for custom telemetry (`trackEvent`, `trackException`, `trackMetric`, etc.). `null` when the AI plugin is not installed -- `setupPageTracking` handlers are no-ops in that case. |
50
50
 
51
51
  ### Injection Key
52
52
 
53
- | Key | Type | Description |
54
- | ----------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------- |
55
- | `AppInsightsOptionsKey` | `InjectionKey<AppInsightsPluginOptions>` | Optional. Provide this at app level with `{ appName: 'Vendor Portal' }` to prefix all page names. |
53
+ | Key | Type | Description |
54
+ | ----------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ |
55
+ | `AppInsightsOptionsKey` | `InjectionKey<AppInsightsPluginOptions>` | Optional. Provide this at app level with `{ appName: 'Operations Console' }` to prefix all page names. |
56
56
 
57
57
  ## How It Works
58
58
 
@@ -99,12 +99,12 @@ import { AppInsightsOptionsKey } from "@vc-shell/framework";
99
99
  const app = createApp(App);
100
100
 
101
101
  app.provide(AppInsightsOptionsKey, {
102
- appName: "Vendor Portal",
102
+ appName: "Operations Console",
103
103
  // ... other AppInsightsPluginOptions
104
104
  });
105
105
  ```
106
106
 
107
- This results in page names like `[Vendor Portal] Dashboard` instead of just `Dashboard`.
107
+ This results in page names like `[Operations Console] Dashboard` instead of just `Dashboard`.
108
108
 
109
109
  ## Tips
110
110
 
@@ -28,26 +28,27 @@ When the returned `action` is called, `useAsync` automatically:
28
28
  ## Quick Start
29
29
 
30
30
  ```typescript
31
+ // pseudo-code: replace OrderClient with your generated API client
31
32
  import { useAsync, useApiClient } from "@vc-shell/framework";
32
33
  import { OrderClient } from "@api/orders";
33
34
 
34
35
  const { getApiClient } = useApiClient(OrderClient);
35
36
 
36
- const {
37
- loading,
38
- error,
39
- action: loadOrder,
40
- } = useAsync<string>(async (id) => {
37
+ // Alias `loading` and `action` to domain names so multiple useAsync blocks in the
38
+ // same composable can coexist without colliding on `loading` / `action`.
39
+ const { loading: loadOrderLoading, action: loadOrder } = useAsync<string>(async (id) => {
41
40
  const client = await getApiClient();
42
41
  return await client.getOrderById(id);
43
42
  });
44
43
 
45
- // In a blade's onMounted:
46
44
  await loadOrder("order-123");
47
- // loading.value was true during the call, now false
48
- // error.value is null on success, or a DisplayableError on failure
45
+ // loadOrderLoading.value was true during the call, now false.
46
+ // Errors auto-toast through the default `notify: true` option no need to read
47
+ // `error` unless you want to render a custom error UI.
49
48
  ```
50
49
 
50
+ Per-action aliasing scales: a CRUD composable typically has `loadItemLoading`, `saveItemLoading`, `removeItemLoading` from three separate `useAsync` calls. Aggregate them through `useLoading` to drive a single blade-level loading state.
51
+
51
52
  ## API Reference
52
53
 
53
54
  ### Import
@@ -204,6 +205,7 @@ const { action: silentRefresh } = useAsync(
204
205
  The standard pattern for API operations in VC-Shell:
205
206
 
206
207
  ```typescript
208
+ // pseudo-code: replace VcmpSellerCatalogClient with your generated API client
207
209
  import { useAsync, useApiClient } from "@vc-shell/framework";
208
210
  import { VcmpSellerCatalogClient } from "@api/client";
209
211
 
@@ -246,6 +248,7 @@ The standard VC-Shell pattern: encapsulate all CRUD operations for an entity in
246
248
 
247
249
  ```typescript
248
250
  // composables/useFulfillmentCenter/index.ts
251
+ // pseudo-code: replace VcmpSellerCatalogClient with your generated API client
249
252
  import { useApiClient, useAsync, useLoading } from "@vc-shell/framework";
250
253
  import { VcmpSellerCatalogClient, type FulfillmentCenter } from "@api/client";
251
254
 
@@ -423,9 +426,9 @@ const { action: save, loading: saveLoading } = useAsync(async () => saveData());
423
426
 
424
427
  ## Related
425
428
 
426
- | Resource | Description |
427
- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------- |
428
- | [`useApiClient`](../useApiClient/) | Provides typed API client instances to pass into `useAsync` |
429
- | [`useLoading`](../useLoading/) | Combines multiple `loading` refs into a single boolean |
430
- | [`useModificationTracker`](../useModificationTracker/) | Tracks dirty state for forms -- often used alongside `useAsync` for save operations |
431
- | [`notification`](../../../shared/components/notifications/) | The toast notification system used by `useAsync` for error display |
429
+ | Resource | Description |
430
+ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------- |
431
+ | [`useApiClient`](../useApiClient/) | Provides typed API client instances to pass into `useAsync` |
432
+ | [`useLoading`](../useLoading/) | Combines multiple `loading` refs into a single boolean |
433
+ | [`useModificationTracker`](../useModificationTracker/) | Tracks dirty state for forms -- often used alongside `useAsync` for save operations |
434
+ | [Notifications](../../notifications/notifications.docs.md) | The notification and toast system used by `useAsync` for error display |
@@ -8,11 +8,13 @@ group: utilities
8
8
 
9
9
  Prevents the browser tab from closing when unsaved changes exist by hooking into the native `beforeunload` event. This composable is the last line of defense against accidental data loss -- it triggers the browser's built-in "Leave site?" confirmation dialog whenever the user tries to close or refresh the tab while the `modified` flag is `true`. It complements in-app guards (like blade `onBeforeClose`) by covering the case where the user bypasses the application entirely via the browser chrome.
10
10
 
11
+ > Form blades already wire this for you. `useBladeForm` registers `useBeforeUnload(isModified)` by default; pass `autoBeforeUnload: false` if you ever need to opt out. Reach for `useBeforeUnload` directly only when the unsaved state lives outside a form (a kanban board, a wizard, a custom editor not backed by `useBladeForm`).
12
+
11
13
  ## When to Use
12
14
 
13
- - Protect forms or blades with unsaved edits from accidental tab/window close or page refresh
15
+ - Protect non-form blades with unsaved edits (kanban, wizard, custom editor) from accidental tab/window close or page refresh
14
16
  - Pair with `useModificationTracker` to get a reactive `modified` flag automatically
15
- - When NOT to use: for in-app navigation guards (use Vue Router `beforeRouteLeave` or blade `onBeforeClose` instead). This composable only handles the browser-level close/refresh event, not SPA route changes.
17
+ - When NOT to use: inside a blade backed by `useBladeForm` (the form already registers it); for in-app navigation guards (use Vue Router `beforeRouteLeave` or blade `onBeforeClose` instead). This composable only handles the browser-level close/refresh event, not SPA route changes.
16
18
 
17
19
  ## Quick Start
18
20