@vc-shell/vc-app-skill 2.0.0-alpha.27 → 2.0.0-alpha.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- 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/useBladeContext.docs.md +4 -1
- package/runtime/knowledge/docs/core/composables/useBladeWidgets.docs.md +2 -2
- package/runtime/knowledge/docs/injection-keys.docs.md +2 -2
- package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +1 -1
- package/runtime/knowledge/docs/shell/_internal/popup/popup-handler.docs.md +0 -135
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [2.0.0-alpha.29](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.0-alpha.28...v2.0.0-alpha.29) (2026-03-26)
|
|
2
|
+
|
|
3
|
+
**Note:** Version bump only for package @vc-shell/vc-app-skill
|
|
4
|
+
|
|
5
|
+
# [2.0.0-alpha.28](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.0-alpha.27...v2.0.0-alpha.28) (2026-03-26)
|
|
6
|
+
|
|
7
|
+
**Note:** Version bump only for package @vc-shell/vc-app-skill
|
|
8
|
+
|
|
1
9
|
# [2.0.0-alpha.27](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.0-alpha.26...v2.0.0-alpha.27) (2026-03-25)
|
|
2
10
|
|
|
3
11
|
**Note:** Version bump only for package @vc-shell/vc-app-skill
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vc-shell/vc-app-skill",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.29",
|
|
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.0-alpha.
|
|
1
|
+
2.0.0-alpha.29
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Synced from framework at commit
|
|
1
|
+
Synced from framework at commit d863d7620 on 2026-03-26T14:29:54.970Z
|
|
@@ -17,7 +17,7 @@ The pattern follows a "define once, inject anywhere" approach: the blade compone
|
|
|
17
17
|
// In a blade's <script setup>
|
|
18
18
|
import { defineBladeContext, injectBladeContext } from '@vc-shell/framework';
|
|
19
19
|
|
|
20
|
-
// Provide context
|
|
20
|
+
// Provide context — refs/computeds are auto-unwrapped for consumers
|
|
21
21
|
defineBladeContext({ item, disabled, loading });
|
|
22
22
|
|
|
23
23
|
// Or with a computed for selective exposure
|
|
@@ -29,7 +29,9 @@ defineBladeContext(computed(() => ({ id: item.value?.id })));
|
|
|
29
29
|
import { injectBladeContext } from '@vc-shell/framework';
|
|
30
30
|
|
|
31
31
|
const ctx = injectBladeContext();
|
|
32
|
+
// Refs are already unwrapped — access values directly, no .value needed
|
|
32
33
|
const entityId = computed(() => ctx.value.id as string);
|
|
34
|
+
const item = computed(() => ctx.value.item as { id: string; name: string });
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
## API
|
|
@@ -90,6 +92,7 @@ defineBladeContext(computed(() => ({
|
|
|
90
92
|
|
|
91
93
|
## Details
|
|
92
94
|
|
|
95
|
+
- **Automatic ref unwrapping**: `defineBladeContext` shallow-unwraps all ref/computed values in the provided object. Consumers get plain values directly (`ctx.value.item` instead of `ctx.value.item.value`). This works reactively — when the source ref changes, the context updates automatically.
|
|
93
96
|
- **Reactivity**: The provided context is always wrapped in a `computed`, so consumers receive a `ComputedRef` regardless of whether the provider passed a plain object, a ref, or a getter. Changes propagate automatically.
|
|
94
97
|
- **Injection key**: Uses `BladeContextKey` from `framework/injection-keys.ts`. This is a framework-level Symbol, so there is no risk of key collision with application code.
|
|
95
98
|
- **Error handling**: `injectBladeContext` throws an `InjectionError` with a descriptive message if called outside a blade component tree. This fails fast during development rather than silently returning `undefined`.
|
|
@@ -112,7 +112,7 @@ A complete example of an external widget that shows an unread message count and
|
|
|
112
112
|
**1. Register the external widget (module index.ts):**
|
|
113
113
|
|
|
114
114
|
```typescript
|
|
115
|
-
import { createAppModule, registerExternalWidget,
|
|
115
|
+
import { createAppModule, registerExternalWidget, BladeDescriptor } from "@vc-shell/framework";
|
|
116
116
|
import { markRaw } from "vue";
|
|
117
117
|
import { MessageWidget } from "./components/widgets";
|
|
118
118
|
|
|
@@ -120,7 +120,7 @@ registerExternalWidget({
|
|
|
120
120
|
id: "MessageWidget",
|
|
121
121
|
component: markRaw(MessageWidget),
|
|
122
122
|
targetBlades: ["ProductDetails", "OrderDetails"],
|
|
123
|
-
isVisible: (blade?:
|
|
123
|
+
isVisible: (blade?: BladeDescriptor) => !!blade?.param,
|
|
124
124
|
});
|
|
125
125
|
```
|
|
126
126
|
|
|
@@ -21,7 +21,7 @@ This centralized approach has several advantages:
|
|
|
21
21
|
| Key | Type | Description |
|
|
22
22
|
|-----|------|-------------|
|
|
23
23
|
| `NavigationViewLocationKey` | `BladeVNode` | Current blade VNode location in navigation |
|
|
24
|
-
| `
|
|
24
|
+
| `BladeDescriptorKey` | `ComputedRef<BladeDescriptor>` | Current blade descriptor metadata |
|
|
25
25
|
| `BladeBackButtonKey` | `Component \| undefined` | Custom back button component for a blade |
|
|
26
26
|
| `BladeDataKey` | *(from blade-navigation types)* | Data passed between parent/child blades |
|
|
27
27
|
| `BladeContextKey` | `ComputedRef<Record<string, unknown>>` | Blade-exposed context for widgets/extensions |
|
|
@@ -83,7 +83,7 @@ This centralized approach has several advantages:
|
|
|
83
83
|
| Deprecated | Use Instead |
|
|
84
84
|
|------------|-------------|
|
|
85
85
|
| `navigationViewLocation` | `NavigationViewLocationKey` |
|
|
86
|
-
| `
|
|
86
|
+
| `BladeDescriptor` | `BladeDescriptorKey` |
|
|
87
87
|
| `NotificationTemplatesSymbol` | `NotificationTemplatesKey` |
|
|
88
88
|
| `BLADE_BACK_BUTTON` | `BladeBackButtonKey` |
|
|
89
89
|
| `TOOLBAR_SERVICE` | `ToolbarServiceKey` |
|
|
@@ -355,7 +355,7 @@ interface IBladeToolbar {
|
|
|
355
355
|
clickHandler?(): void;
|
|
356
356
|
disabled?: boolean | ComputedRef<boolean>;
|
|
357
357
|
isVisible?: boolean | Ref<boolean> | ComputedRef<boolean>
|
|
358
|
-
| ((blade?:
|
|
358
|
+
| ((blade?: BladeDescriptor) => boolean);
|
|
359
359
|
separator?: "left" | "right" | "both";
|
|
360
360
|
}
|
|
361
361
|
```
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
# PopupHandler
|
|
2
|
-
|
|
3
|
-
A global popup management system that renders modal dialogs on demand. Installed as a Vue plugin (`VcPopupHandler`), it provides the `usePopup` composable for programmatic popup control. Popups are rendered in a dedicated container at the app root level, ensuring they overlay all other content including blades and sidebars.
|
|
4
|
-
|
|
5
|
-
The system supports both built-in dialog types (confirmation, error, info) and fully custom popup components with typed props and emits.
|
|
6
|
-
|
|
7
|
-
## When to Use
|
|
8
|
-
|
|
9
|
-
- To show confirmation dialogs before destructive actions (delete, discard, bulk operations)
|
|
10
|
-
- To display error or info messages in a modal overlay
|
|
11
|
-
- To open custom popup components with typed props and emits
|
|
12
|
-
- Do NOT use for passive feedback (use `notification()` toast instead)
|
|
13
|
-
- Do NOT use for navigation (use blade navigation instead)
|
|
14
|
-
|
|
15
|
-
## Basic Usage
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import { usePopup } from "@vc-shell/framework";
|
|
19
|
-
|
|
20
|
-
const { showConfirmation, showError, showInfo } = usePopup();
|
|
21
|
-
|
|
22
|
-
// Confirmation dialog (returns Promise<boolean>)
|
|
23
|
-
const confirmed = await showConfirmation("Delete this item?");
|
|
24
|
-
|
|
25
|
-
// Error popup
|
|
26
|
-
showError("Something went wrong.");
|
|
27
|
-
|
|
28
|
-
// Info popup
|
|
29
|
-
showInfo("Operation completed successfully.");
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Custom Popup Component
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
import { usePopup } from "@vc-shell/framework";
|
|
36
|
-
import MyDialog from "./MyDialog.vue";
|
|
37
|
-
|
|
38
|
-
const { open, close } = usePopup({
|
|
39
|
-
component: MyDialog,
|
|
40
|
-
props: { title: "Custom Dialog" },
|
|
41
|
-
emits: { onConfirm: () => close() },
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
open();
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## API (`usePopup`)
|
|
48
|
-
|
|
49
|
-
| Method | Signature | Description |
|
|
50
|
-
|--------|-----------|-------------|
|
|
51
|
-
| `open` | `() => void` | Push the popup onto the stack and render it |
|
|
52
|
-
| `close` | `() => void` | Remove the popup from the stack |
|
|
53
|
-
| `showConfirmation` | `(message: string \| Ref<string>) => Promise<boolean>` | Warning dialog with confirm/cancel |
|
|
54
|
-
| `showError` | `(message: string \| Ref<string>) => void` | Error-styled popup |
|
|
55
|
-
| `showInfo` | `(message: string \| Ref<string>) => void` | Info-styled popup |
|
|
56
|
-
|
|
57
|
-
## Recipe: Delete Confirmation Before API Call
|
|
58
|
-
|
|
59
|
-
The most common popup pattern is asking for confirmation before a destructive action:
|
|
60
|
-
|
|
61
|
-
```vue
|
|
62
|
-
<script setup lang="ts">
|
|
63
|
-
import { usePopup, notification } from "@vc-shell/framework";
|
|
64
|
-
|
|
65
|
-
const { showConfirmation } = usePopup();
|
|
66
|
-
|
|
67
|
-
async function deleteProduct(id: string) {
|
|
68
|
-
const confirmed = await showConfirmation(
|
|
69
|
-
"Are you sure you want to delete this product? This action cannot be undone."
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
if (!confirmed) return;
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
await api.deleteProduct(id);
|
|
76
|
-
notification("Product deleted.", { type: "success" });
|
|
77
|
-
closeSelf();
|
|
78
|
-
} catch (error) {
|
|
79
|
-
showError(error.message || "Failed to delete product.");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
</script>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Recipe: Custom Popup with Form
|
|
86
|
-
|
|
87
|
-
Create a custom popup component for complex interactions:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// Using a custom popup component
|
|
91
|
-
import { usePopup } from "@vc-shell/framework";
|
|
92
|
-
import AddNotePopup from "./AddNotePopup.vue";
|
|
93
|
-
|
|
94
|
-
const { open, close } = usePopup({
|
|
95
|
-
component: AddNotePopup,
|
|
96
|
-
props: { entityId: "prod-1" },
|
|
97
|
-
emits: {
|
|
98
|
-
onConfirm: async (note: string) => {
|
|
99
|
-
await api.addNote(entityId, note);
|
|
100
|
-
close();
|
|
101
|
-
notification("Note added.", { type: "success" });
|
|
102
|
-
},
|
|
103
|
-
onCancel: () => close(),
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
open();
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Key Parts
|
|
111
|
-
|
|
112
|
-
| Export | Description |
|
|
113
|
-
|--------|-------------|
|
|
114
|
-
| `VcPopupHandler` | Vue plugin that installs the popup registry |
|
|
115
|
-
| `VcPopupContainer` | Renders all active popups (placed once in the app root) |
|
|
116
|
-
| `usePopup` | Composable for opening/closing popups |
|
|
117
|
-
|
|
118
|
-
## Details
|
|
119
|
-
|
|
120
|
-
- **Popup stack**: Multiple popups can be open simultaneously, stacking with the most recent on top.
|
|
121
|
-
- **Promise-based confirmation**: `showConfirmation` returns a `Promise<boolean>` that resolves to `true` on confirm, `false` on cancel.
|
|
122
|
-
- **Plugin requirement**: `VcPopupHandler` must be installed as a Vue plugin, and `VcPopupContainer` must be mounted in the component tree. Both are automatically set up in the standard vc-shell app shell.
|
|
123
|
-
|
|
124
|
-
## Tips
|
|
125
|
-
|
|
126
|
-
- Always `await` the result of `showConfirmation` before proceeding with the destructive action.
|
|
127
|
-
- For simple yes/no questions, use `showConfirmation`. For forms or complex interactions, create a custom popup component.
|
|
128
|
-
- The `usePopup` composable can be called without arguments (for built-in dialogs) or with a component config (for custom popups).
|
|
129
|
-
- Avoid nesting popups more than 2 levels deep. Consider blades for complex multi-step workflows.
|
|
130
|
-
|
|
131
|
-
## Related Components
|
|
132
|
-
|
|
133
|
-
- **VcPopup** - The default popup shell component (header, content, actions)
|
|
134
|
-
- **VcBlade** - For panel-based UI; use popups for modal interruptions
|
|
135
|
-
- **notification()** - For passive, non-blocking feedback
|