@vc-shell/vc-app-skill 2.2.0 → 2.3.0-pr265.96a7e3e
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/package.json +1 -1
- package/runtime/VERSION +1 -1
- package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
- package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +3 -0
- package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +32 -12
- package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vc-shell/vc-app-skill",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0-pr265.96a7e3e",
|
|
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.
|
|
1
|
+
2.3.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Synced from framework at commit
|
|
1
|
+
Synced from framework at commit eb3675e7a on 2026-07-28T09:06:26.940Z
|
|
@@ -172,6 +172,8 @@ const {
|
|
|
172
172
|
|
|
173
173
|
By default, `useAsync` shows a toast notification on failure. The notification is **deferred** via `setTimeout(0)` so that the `ErrorInterceptor` can cancel it when a blade error banner is already displayed -- this prevents duplicate toast + banner for the same error.
|
|
174
174
|
|
|
175
|
+
No toast is scheduled at all while the session is flagged as expired. When a platform API call returns 401, the fetch interceptor signs the user out and redirects to the login page; every data load in flight on the page being left fails at the same time. Suppressing those toasts keeps the single "session expired" message from being buried under a cascade of load errors. The `error` ref is still populated as usual -- only the toast is skipped -- and the flag is cleared when a new sign-in begins.
|
|
176
|
+
|
|
175
177
|
```typescript
|
|
176
178
|
// Default: shows toast on error
|
|
177
179
|
const { action: save } = useAsync(async () => {
|
|
@@ -419,6 +421,7 @@ const { action: save, loading: saveLoading } = useAsync(async () => saveData());
|
|
|
419
421
|
- Errors are parsed via `parseError()` into `DisplayableError` objects that have a user-friendly `message` property.
|
|
420
422
|
- Toast notifications are deferred with `setTimeout(0)` and registered via `setPendingErrorNotification`. The `ErrorInterceptor` (blade-level `onErrorCaptured`) can call `cancelPendingErrorNotification` to suppress the toast when a blade error banner is shown instead.
|
|
421
423
|
- The notification module is lazy-imported to avoid circular dependencies with `@core/composables`.
|
|
424
|
+
- `isSessionExpired()` from `@core/utilities/sessionExpiration` gates the notification. The flag is set by the fetch interceptor on the 401 that kills the session and cleared by `useUser.signIn`. It is imported directly, not through the `@core/utilities` barrel, for the same circular-dependency reason as `pendingErrorNotifications`.
|
|
422
425
|
|
|
423
426
|
<!-- internal:end -->
|
|
424
427
|
|
|
@@ -234,6 +234,24 @@ registerToolbarItem({
|
|
|
234
234
|
});
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
+
### Keyboard shortcut for a button
|
|
238
|
+
|
|
239
|
+
Add `shortcut: hotkey.mod.s` to give a button a `Cmd/Ctrl+S`-style shortcut. The button automatically shows an OS-aware `⌘S`/`Ctrl+S` tooltip and sets `aria-keyshortcuts` -- no extra wiring:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { hotkey } from "@vc-shell/framework";
|
|
243
|
+
|
|
244
|
+
registerToolbarItem({
|
|
245
|
+
id: "save",
|
|
246
|
+
title: "Save",
|
|
247
|
+
icon: "fas fa-save",
|
|
248
|
+
clickHandler: () => save(),
|
|
249
|
+
shortcut: hotkey.mod.s,
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
See [useKeyboardShortcuts](../useKeyboardShortcuts/) for the full `hotkey` builder, OS adaptation, and accessibility details.
|
|
254
|
+
|
|
237
255
|
## Common mistakes
|
|
238
256
|
|
|
239
257
|
### Reaching for `useToolbar` before considering the array pattern
|
|
@@ -334,18 +352,19 @@ function helperFunction() {
|
|
|
334
352
|
|
|
335
353
|
### IToolbarItem
|
|
336
354
|
|
|
337
|
-
| Property | Type | Required | Description
|
|
338
|
-
| -------------- | ----------------------------------------------------------------------------------------------------------------- | -------- |
|
|
339
|
-
| `id` | `string` | Yes | Unique identifier for the button
|
|
340
|
-
| `title` | `string \| Ref<string> \| ComputedRef<string>` | No | Button label (supports reactive values)
|
|
341
|
-
| `icon` | `string \| (() => string)` | No | Icon class (e.g., `"fas fa-save"`) or a function returning one
|
|
342
|
-
| `clickHandler` | `(app?) => void` | No | Click callback
|
|
343
|
-
| `disabled` | `boolean \| ComputedRef<boolean \| undefined>` | No | Whether the button is disabled
|
|
344
|
-
| `isVisible` | `boolean \| Ref<boolean \| undefined> \| ComputedRef<boolean \| undefined> \| ((blade?) => boolean \| undefined)` | No | Controls button visibility
|
|
345
|
-
| `priority` | `number` | No | Sort order (higher = displayed first, default `0`)
|
|
346
|
-
| `separator` | `"left" \| "right" \| "both"` | No | Adds a visual divider next to the button
|
|
347
|
-
| `permissions` | `string \| string[]` | No | Required permission(s) to display the button
|
|
348
|
-
| `bladeId` | `string` | No | Target blade ID (auto-resolved from context)
|
|
355
|
+
| Property | Type | Required | Description |
|
|
356
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
357
|
+
| `id` | `string` | Yes | Unique identifier for the button |
|
|
358
|
+
| `title` | `string \| Ref<string> \| ComputedRef<string>` | No | Button label (supports reactive values) |
|
|
359
|
+
| `icon` | `string \| (() => string)` | No | Icon class (e.g., `"fas fa-save"`) or a function returning one |
|
|
360
|
+
| `clickHandler` | `(app?) => void` | No | Click callback |
|
|
361
|
+
| `disabled` | `boolean \| ComputedRef<boolean \| undefined>` | No | Whether the button is disabled |
|
|
362
|
+
| `isVisible` | `boolean \| Ref<boolean \| undefined> \| ComputedRef<boolean \| undefined> \| ((blade?) => boolean \| undefined)` | No | Controls button visibility |
|
|
363
|
+
| `priority` | `number` | No | Sort order (higher = displayed first, default `0`) |
|
|
364
|
+
| `separator` | `"left" \| "right" \| "both"` | No | Adds a visual divider next to the button |
|
|
365
|
+
| `permissions` | `string \| string[]` | No | Required permission(s) to display the button |
|
|
366
|
+
| `bladeId` | `string` | No | Target blade ID (auto-resolved from context) |
|
|
367
|
+
| `shortcut` | `ShortcutDefinition` | No | Keyboard shortcut that triggers `clickHandler`; build with `hotkey.*`. See [useKeyboardShortcuts](../useKeyboardShortcuts/) |
|
|
349
368
|
|
|
350
369
|
`IToolbarItem` is the shape consumed by `ToolbarService`. The blade-level array binding uses `IBladeToolbar` (see [Core types](../../types/)), a near-identical shape that the framework normalizes into `IToolbarItem` before render.
|
|
351
370
|
|
|
@@ -354,4 +373,5 @@ function helperFunction() {
|
|
|
354
373
|
- [useBlade](../useBlade/) -- blade context that toolbar items are scoped to
|
|
355
374
|
- [usePermissions](../usePermissions/) -- conditionally register toolbar items based on permissions
|
|
356
375
|
- [useAsync](../useAsync/) -- wraps async operations with loading state for disabling buttons
|
|
376
|
+
- [useKeyboardShortcuts](../useKeyboardShortcuts/) -- the `hotkey` builder and OS-aware formatting behind the `shortcut` field
|
|
357
377
|
- `IBladeToolbar` in [Core types](../../types/) — the shape used by the `:toolbar-items` array binding
|
|
@@ -21,6 +21,7 @@ The component is renderless -- it renders its default slot and passes the curren
|
|
|
21
21
|
2. When inside a blade (`hasBlade = true`), errors are intercepted and forwarded to `bladeStack.setBladeError()`. This displays the error in the blade's built-in error banner and prevents the error from propagating to the global error handler (avoiding duplicate toast notifications).
|
|
22
22
|
3. When not inside a blade or when `capture` is true, errors are captured and exposed via the slot's `error` prop.
|
|
23
23
|
4. Pending `useAsync` error notifications are cancelled via `cancelPendingErrorNotification` when the blade banner takes over.
|
|
24
|
+
5. If the session has expired (a platform API call returned 401 and the app is redirecting to login), the banner is skipped -- the deferred toast is still cancelled in step 4, so the failed load leaves no trace on the page being abandoned.
|
|
24
25
|
|
|
25
26
|
## Props
|
|
26
27
|
|
|
@@ -74,6 +75,7 @@ The component is renderless -- it renders its default slot and passes the curren
|
|
|
74
75
|
- **Inside a blade**: Errors set `BladeDescriptor.error` via the stack. The blade header renders the error banner. Calling `reset` clears the blade error.
|
|
75
76
|
- **Outside a blade** (with `capture`): Errors are stored in a local ref and exposed via slot props. No blade banner is involved.
|
|
76
77
|
- **Error propagation**: When inside a blade, the error is stopped from propagating (prevents duplicate toasts from the global handler). The `capture` prop also stops propagation.
|
|
78
|
+
- **Expired session**: While the session is flagged as expired, no blade banner is set. A dead auth cookie fails every data load on the page at once, and one redirect to login is more useful than a banner on each blade being left behind.
|
|
77
79
|
|
|
78
80
|
## Exports
|
|
79
81
|
|
|
@@ -93,4 +95,5 @@ The component must be imported before use, as shown above.
|
|
|
93
95
|
|
|
94
96
|
- `framework/core/composables/useErrorHandler/` -- the underlying composable
|
|
95
97
|
- `framework/core/utilities/pendingErrorNotifications.ts` -- cancels deferred toasts
|
|
98
|
+
- `framework/core/utilities/sessionExpiration.ts` -- the expired-session flag that suppresses the banner
|
|
96
99
|
- `framework/core/blade-navigation/` -- BladeStack error management (types the interceptor injects)
|