@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.
- package/CHANGELOG.md +6 -0
- package/README.md +7 -7
- package/package.json +1 -1
- package/runtime/VERSION +1 -1
- package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
- package/runtime/knowledge/docs/core/api/platform.docs.md +6 -6
- package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +1 -1
- package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +2 -2
- package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +67 -42
- package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +2 -2
- package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +15 -13
- package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +11 -11
- package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +17 -14
- package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +4 -2
- package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +31 -23
- package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +46 -26
- package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +1 -0
- package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +1 -1
- package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +1 -1
- package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +1 -0
- package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +20 -6
- package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +2 -1
- package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +2 -2
- package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +109 -133
- package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +1 -2
- package/runtime/knowledge/docs/core/notifications/composables/useBladeNotifications.docs.md +184 -0
- package/runtime/knowledge/docs/core/notifications/composables/useBroadcastFilter.docs.md +117 -0
- package/runtime/knowledge/docs/core/notifications/composables/useNotificationContext.docs.md +150 -0
- package/runtime/knowledge/docs/core/notifications/composables/useNotificationStore.docs.md +113 -0
- package/runtime/knowledge/docs/core/notifications/notifications.docs.md +12 -15
- package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +1 -1
- package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +54 -116
- package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +12 -3
- package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +20 -20
- package/runtime/knowledge/docs/injection-keys.docs.md +1 -1
- package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/notification-dropdown/notification-dropdown.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +7 -7
- package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +2 -2
- package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +4 -4
- package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +21 -1
- package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +22 -6
- package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +2 -2
- package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +32 -26
- package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +3 -3
- package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +13 -13
- package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +1 -1
- package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +4 -4
- package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +39 -37
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +17 -17
- package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +16 -7
- package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +1 -1
|
@@ -39,15 +39,30 @@ import { VcStatusIcon } from "@vc-shell/framework";
|
|
|
39
39
|
|
|
40
40
|
### Boolean Column in a Table
|
|
41
41
|
|
|
42
|
+
For a simple yes/no indicator, declare the column with `type="status-icon"` — `VcDataTable` renders the icon based on the boolean cell value, no slot needed:
|
|
43
|
+
|
|
44
|
+
```vue
|
|
45
|
+
<template>
|
|
46
|
+
<VcColumn
|
|
47
|
+
id="isActive"
|
|
48
|
+
title="Active"
|
|
49
|
+
type="status-icon"
|
|
50
|
+
width="80px"
|
|
51
|
+
/>
|
|
52
|
+
</template>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Reach for the `#body` slot only when you need a custom predicate or a non-boolean source:
|
|
56
|
+
|
|
42
57
|
```vue
|
|
43
58
|
<template>
|
|
44
59
|
<VcColumn
|
|
45
60
|
id="isActive"
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
title="Active"
|
|
62
|
+
width="80px"
|
|
48
63
|
>
|
|
49
|
-
<template #
|
|
50
|
-
<VcStatusIcon :status="
|
|
64
|
+
<template #body="{ data }">
|
|
65
|
+
<VcStatusIcon :status="data.isActive && data.confirmed" />
|
|
51
66
|
</template>
|
|
52
67
|
</VcColumn>
|
|
53
68
|
</template>
|
|
@@ -57,35 +72,26 @@ import { VcStatusIcon } from "@vc-shell/framework";
|
|
|
57
72
|
|
|
58
73
|
```vue
|
|
59
74
|
<template>
|
|
60
|
-
<VcDataTable
|
|
61
|
-
:columns="columns"
|
|
62
|
-
:items="users"
|
|
63
|
-
>
|
|
75
|
+
<VcDataTable :items="users">
|
|
64
76
|
<VcColumn
|
|
65
77
|
id="emailVerified"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<VcStatusIcon :status="row.emailVerified" />
|
|
71
|
-
</template>
|
|
72
|
-
</VcColumn>
|
|
78
|
+
title="Email"
|
|
79
|
+
type="status-icon"
|
|
80
|
+
width="70px"
|
|
81
|
+
/>
|
|
73
82
|
<VcColumn
|
|
74
83
|
id="isActive"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<VcStatusIcon :status="row.isActive" />
|
|
80
|
-
</template>
|
|
81
|
-
</VcColumn>
|
|
84
|
+
title="Active"
|
|
85
|
+
type="status-icon"
|
|
86
|
+
width="70px"
|
|
87
|
+
/>
|
|
82
88
|
<VcColumn
|
|
83
89
|
id="hasAvatar"
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
title="Avatar"
|
|
91
|
+
width="70px"
|
|
86
92
|
>
|
|
87
|
-
<template #
|
|
88
|
-
<VcStatusIcon :status="!!
|
|
93
|
+
<template #body="{ data }">
|
|
94
|
+
<VcStatusIcon :status="!!data.avatarUrl" />
|
|
89
95
|
</template>
|
|
90
96
|
</VcColumn>
|
|
91
97
|
</VcDataTable>
|
|
@@ -143,7 +143,7 @@ Set a maximum width to prevent wide tooltips from stretching across the screen:
|
|
|
143
143
|
<VcTooltip>...</VcTooltip>
|
|
144
144
|
|
|
145
145
|
<!-- Wider tooltip for long content -->
|
|
146
|
-
<VcTooltip
|
|
146
|
+
<VcTooltip max-width="400px">...</VcTooltip>
|
|
147
147
|
|
|
148
148
|
<!-- CSS string value -->
|
|
149
149
|
<VcTooltip max-width="50vw">...</VcTooltip>
|
|
@@ -165,7 +165,7 @@ Suppress the tooltip dynamically without removing it from the template:
|
|
|
165
165
|
The `#tooltip` slot accepts any HTML or Vue components, not just text:
|
|
166
166
|
|
|
167
167
|
```vue
|
|
168
|
-
<VcTooltip placement="top"
|
|
168
|
+
<VcTooltip placement="top" max-width="320px">
|
|
169
169
|
<span class="tw-underline tw-decoration-dotted tw-cursor-help">
|
|
170
170
|
Fulfillment status
|
|
171
171
|
</span>
|
|
@@ -225,7 +225,7 @@ const actions = [
|
|
|
225
225
|
<template>
|
|
226
226
|
<VcTooltip
|
|
227
227
|
placement="top"
|
|
228
|
-
|
|
228
|
+
max-width="400px"
|
|
229
229
|
>
|
|
230
230
|
<span class="tw-truncate tw-max-w-[200px] tw-block">
|
|
231
231
|
{{ longProductName }}
|
|
@@ -144,4 +144,4 @@ onMounted(async () => {
|
|
|
144
144
|
|
|
145
145
|
## Related Components
|
|
146
146
|
|
|
147
|
-
-
|
|
147
|
+
- **LanguageSelector** -- shell-internal settings menu entry for UI locale switching (different purpose)
|
|
@@ -275,7 +275,7 @@ interface AccordionItem {
|
|
|
275
275
|
|
|
276
276
|
## Related Components
|
|
277
277
|
|
|
278
|
-
-
|
|
278
|
+
- **VcAccordionItem** -- internal sub-component for individual accordion panels (used internally and available via the default slot)
|
|
279
279
|
|
|
280
280
|
::storybook id="action-vcaccordion--skeleton"
|
|
281
281
|
|
package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md
CHANGED
|
@@ -288,7 +288,7 @@ clickHandler: () => { navigate(); return true; }
|
|
|
288
288
|
## Related Components
|
|
289
289
|
|
|
290
290
|
- [VcDropdown](../vc-dropdown/) -- Used internally to render the overflow menu
|
|
291
|
-
-
|
|
291
|
+
- **VcBreadcrumbsItem** -- internal sub-component for individual breadcrumb rendering
|
|
292
292
|
- [VcButton](../../atoms/vc-button/) -- Can be used inside the `trigger` slot for a styled overflow button
|
|
293
293
|
|
|
294
294
|
<!-- internal:start -->
|
package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md
CHANGED
|
@@ -49,18 +49,18 @@ const open = ref(false);
|
|
|
49
49
|
|
|
50
50
|
## Key Props
|
|
51
51
|
|
|
52
|
-
| Prop | Type
|
|
53
|
-
| --------------------- |
|
|
54
|
-
| `show` | `boolean`
|
|
55
|
-
| `anchorRef` | `
|
|
56
|
-
| `title` | `string`
|
|
57
|
-
| `placement` | `Placement`
|
|
58
|
-
| `width` | `string`
|
|
59
|
-
| `maxWidth` | `string`
|
|
60
|
-
| `maxHeight` | `number`
|
|
61
|
-
| `contentScrollable` | `boolean`
|
|
62
|
-
| `closeOnClickOutside` | `boolean`
|
|
63
|
-
| `closeOnEscape` | `boolean`
|
|
52
|
+
| Prop | Type | Default | Description |
|
|
53
|
+
| --------------------- | -------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `show` | `boolean` | — | Panel visibility (v-model:show) |
|
|
55
|
+
| `anchorRef` | `ReferenceElement \| null` | `null` | Anchor for floating positioning — accepts an `HTMLElement` or a floating-ui `VirtualElement` (`{ getBoundingClientRect, contextElement? }`). Use a `VirtualElement` when the underlying DOM root can swap dynamically — e.g. wrapping a component whose root changes via internal `v-if` — so `getBoundingClientRect` is resolved fresh on every update instead of caching a stale `$el`. |
|
|
56
|
+
| `title` | `string` | `""` | Header title text (header hidden when empty and no `#header` slot) |
|
|
57
|
+
| `placement` | `Placement` | `"bottom-start"` | Floating UI placement relative to anchor |
|
|
58
|
+
| `width` | `string` | `"280px"` | Panel min-width |
|
|
59
|
+
| `maxWidth` | `string` | `"400px"` | Panel max-width |
|
|
60
|
+
| `maxHeight` | `number` | `350` | Max height in pixels (clamped by viewport) |
|
|
61
|
+
| `contentScrollable` | `boolean` | `true` | Enable scrolling in the content area |
|
|
62
|
+
| `closeOnClickOutside` | `boolean` | `true` | Close when clicking outside |
|
|
63
|
+
| `closeOnEscape` | `boolean` | `true` | Close on Escape key |
|
|
64
64
|
|
|
65
65
|
## Events
|
|
66
66
|
|
|
@@ -158,7 +158,7 @@ const open = ref(false);
|
|
|
158
158
|
## Architecture Notes
|
|
159
159
|
|
|
160
160
|
- Click-outside detection uses a `pointerdown` listener on `document` rather than a backdrop overlay. This ensures clicks on high-z-index siblings (sidebar, other teleported panels) are still caught.
|
|
161
|
-
- `panelAnchorRegistry` (`panel-anchor-registry.ts`) is a `WeakMap<Element,
|
|
161
|
+
- `panelAnchorRegistry` (`panel-anchor-registry.ts`) is a `WeakMap<Element, Element | null>` that maps each open panel's DOM element to its anchor element. When `anchorRef` is a floating-ui `VirtualElement`, the registry stores its `contextElement` (the live DOM element backing the virtual reference). This is used to distinguish child panels (whose anchor lives inside this panel) from sibling/parent panels when deciding whether to close on outside click.
|
|
162
162
|
- Nested VcSelect dropdowns teleported to `<body>` are exempt from click-outside via an ARIA `aria-controls` check: if the clicked `.vc-select__dropdown` has an `id` that matches an `aria-controls` attribute inside this panel, the close is suppressed.
|
|
163
163
|
- The panel exposes a `close()` method via `defineExpose` for use with template refs.
|
|
164
164
|
- `useTeleportTarget` resolves the teleport destination (typically `body`) respecting any custom portal container.
|
|
@@ -538,6 +538,6 @@ disabled: computed(() => !modified.value),
|
|
|
538
538
|
- **[VcCheckbox](../vc-checkbox/)** -- checkbox input
|
|
539
539
|
- **[VcRow](../../atoms/vc-row/)** -- horizontal flex row for form layout
|
|
540
540
|
- **[VcCol](../../atoms/vc-col/)** -- column within a VcRow
|
|
541
|
-
- **[VcCard](
|
|
541
|
+
- **[VcCard](../../atoms/vc-card/vc-card.docs.md)** -- collapsible card for grouping form sections
|
|
542
542
|
- **[VcBlade](../../organisms/vc-blade/)** -- blade container that hosts the form
|
|
543
543
|
- **[VcPopup](../../organisms/vc-popup/)** -- modal dialog, often used for inline forms
|
|
@@ -301,7 +301,7 @@ currentPage.value = Math.min(currentPage.value, totalPages.value);
|
|
|
301
301
|
|
|
302
302
|
## Related Components
|
|
303
303
|
|
|
304
|
-
- [VcDataTable](../../organisms/vc-table) -- Data table that commonly pairs with pagination for large datasets
|
|
304
|
+
- [VcDataTable](../../organisms/vc-data-table/vc-data-table.docs.md) -- Data table that commonly pairs with pagination for large datasets
|
|
305
305
|
- [VcSelect](../vc-select/) -- Can be used alongside pagination for a "rows per page" selector
|
|
306
306
|
|
|
307
307
|
<!-- internal:start -->
|
|
@@ -38,7 +38,7 @@ import { VcApp } from "@vc-shell/framework";
|
|
|
38
38
|
|
|
39
39
|
const isReady = ref(true);
|
|
40
40
|
const logoUrl = "/logo.svg";
|
|
41
|
-
const appTitle = "
|
|
41
|
+
const appTitle = "Operations Console";
|
|
42
42
|
const user = reactive({ name: "John", role: "Admin" });
|
|
43
43
|
</script>
|
|
44
44
|
```
|
|
@@ -146,8 +146,8 @@ Modules registered via `useDynamicModules()` are loaded at runtime. Each module
|
|
|
146
146
|
|
|
147
147
|
The App Hub is a popover panel (desktop) or a swipeable tab (mobile) that combines two sections:
|
|
148
148
|
|
|
149
|
-
- **Applications** — tile grid of registered apps (
|
|
150
|
-
- **Widgets** — registered
|
|
149
|
+
- **Applications** — tile grid of registered apps (for example, Operations Console or Marketplace Admin). Clicking an app switches context without a full page reload. This section can be hidden with `disableAppHub` or customized via the `app-hub` slot. The list is searchable via a built-in search input inside the hub.
|
|
150
|
+
- **Widgets** — cross-app widgets registered through `useAppBarWidget()` (sync status, background tasks, language picker, and the like). Clicking a widget either runs its `onClick` (for action widgets) or expands its component inline inside the popover with a back-arrow to return (for component widgets). On mobile, the content flies out below the panel. Widgets can display badges for unread counts.
|
|
151
151
|
|
|
152
152
|
On desktop, the App Hub opens from the sidebar header menu button (`AppHubPopover`). On mobile, it appears as a second tab ("Hub") in the slide-out navigation panel — users can swipe between Menu and Hub tabs.
|
|
153
153
|
|
|
@@ -225,7 +225,7 @@ Replace the default user info section with a custom footer:
|
|
|
225
225
|
- The `disableMenu` prop is useful for single-purpose apps that do not need sidebar navigation (e.g., a standalone settings page or an embedded widget).
|
|
226
226
|
- Use the `layout` slot only as a last resort for completely custom layouts. For most customizations, the more specific slots (`menu`, `sidebar-header`, `sidebar-footer`) are sufficient.
|
|
227
227
|
- The `version` prop is informational and can be displayed in the sidebar footer or a settings page. It does not affect any runtime behavior.
|
|
228
|
-
- VcApp provides shell services via Vue's provide/inject system. Child components access them through composables like `useMenuService()`, `
|
|
228
|
+
- VcApp provides shell services via Vue's provide/inject system. Child components access them through composables like `useMenuService()`, `useToolbar()`, `useAppBarWidget()`, `useSettingsMenu()`, and `useDashboard()`.
|
|
229
229
|
|
|
230
230
|
## Accessibility
|
|
231
231
|
|
|
@@ -12,16 +12,18 @@ The foundational container component of the VirtoCommerce admin shell. Blades ar
|
|
|
12
12
|
|
|
13
13
|
Traditional admin panels use page-based routing: click a link, the entire viewport changes. Context is lost. Blades solve this by **stacking panels horizontally**. When a user clicks an item in a list, a details blade slides in from the right while the list remains visible. This preserves context, enables comparison, and supports deep drill-down workflows without losing your place.
|
|
14
14
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
```mermaid
|
|
16
|
+
flowchart LR
|
|
17
|
+
subgraph WS["Products (workspace)"]
|
|
18
|
+
L1["[list...]<br/>[list...]"]
|
|
19
|
+
end
|
|
20
|
+
subgraph CH["Product Details (child blade)"]
|
|
21
|
+
L2["Name: Widget<br/>SKU: WDG-001"]
|
|
22
|
+
end
|
|
23
|
+
subgraph GC["Edit Variant (grandchild blade)"]
|
|
24
|
+
L3["Color: Red<br/>Size: Large"]
|
|
25
|
+
end
|
|
26
|
+
WS --> CH --> GC
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
| Aspect | Pages/Routes | Blades |
|
|
@@ -33,12 +35,12 @@ Traditional admin panels use page-based routing: click a link, the entire viewpo
|
|
|
33
35
|
|
|
34
36
|
## When to Use
|
|
35
37
|
|
|
36
|
-
| Scenario | Component
|
|
37
|
-
| ------------------------------------------------- |
|
|
38
|
-
| Stacked panel with toolbar, header, and lifecycle | **VcBlade**
|
|
39
|
-
| One-off confirmation or input dialog | [VcPopup](
|
|
40
|
-
| Full-page route without blade stack | Vue Router view
|
|
41
|
-
| Scrollable content section inside a blade | [VcContainer](../../
|
|
38
|
+
| Scenario | Component |
|
|
39
|
+
| ------------------------------------------------- | ------------------------------------------------------------ |
|
|
40
|
+
| Stacked panel with toolbar, header, and lifecycle | **VcBlade** |
|
|
41
|
+
| One-off confirmation or input dialog | [VcPopup](../vc-popup/vc-popup.docs.md) |
|
|
42
|
+
| Full-page route without blade stack | Vue Router view |
|
|
43
|
+
| Scrollable content section inside a blade | [VcContainer](../../atoms/vc-container/vc-container.docs.md) |
|
|
42
44
|
|
|
43
45
|
::storybook id="navigation-vcblade--default"
|
|
44
46
|
|
|
@@ -58,12 +60,12 @@ Use VcBlade for every screen in a vc-shell application -- it is the standard con
|
|
|
58
60
|
</template>
|
|
59
61
|
|
|
60
62
|
<script setup lang="ts">
|
|
61
|
-
|
|
63
|
+
defineBlade({ name: "MyFirstBlade", url: "/my-first-blade" });
|
|
62
64
|
</script>
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
!!! tip "Every blade needs a name"
|
|
66
|
-
Every blade must define a `name` in `
|
|
68
|
+
Every blade must define a `name` in `defineBlade`. This is how other blades reference it: `openBlade({ name: "MyFirstBlade" })`. The `url` is optional and controls the URL segment.
|
|
67
69
|
|
|
68
70
|
## Blade Anatomy
|
|
69
71
|
|
|
@@ -87,7 +89,7 @@ A blade has four visual zones, rendered top-to-bottom:
|
|
|
87
89
|
|
|
88
90
|
**Toolbar** -- Action buttons from the `toolbarItems` prop. Overflow items automatically collapse into a "More" dropdown (via `ResizeObserver`).
|
|
89
91
|
|
|
90
|
-
**Status Banners** -- Unified, priority-sorted banner area. System banners: yellow when `modified` is `true`, red when the blade has an error (via `setError()`). Custom banners can be added programmatically via `useBlade().addBanner()` — see [useBlade docs](
|
|
92
|
+
**Status Banners** -- Unified, priority-sorted banner area. System banners: yellow when `modified` is `true`, red when the blade has an error (via `setError()`). Custom banners can be added programmatically via `useBlade().addBanner()` — see [useBlade docs](../../../../core/composables/useBlade/useBlade.docs.md#banner-management).
|
|
91
93
|
|
|
92
94
|
**Content Area** -- The `default` slot. Scrolls independently of header and toolbar.
|
|
93
95
|
|
|
@@ -117,7 +119,7 @@ import { computed, ref } from "vue";
|
|
|
117
119
|
import { useBlade, type IBladeToolbar } from "@vc-shell/framework";
|
|
118
120
|
|
|
119
121
|
// Registration metadata
|
|
120
|
-
|
|
122
|
+
defineBlade({
|
|
121
123
|
name: "OfferDetails", // Required: unique blade name
|
|
122
124
|
url: "/offer", // Optional: URL segment
|
|
123
125
|
routable: false, // Optional: exclude from direct URL access
|
|
@@ -447,12 +449,12 @@ addBanner({
|
|
|
447
449
|
</script>
|
|
448
450
|
```
|
|
449
451
|
|
|
450
|
-
Four variants are available: `danger`, `warning`, `info`, `success`. System banners (error and unsaved changes) are always present and cannot be removed by `clearBanners()`. For the full API reference, see [useBlade — Banner Management](
|
|
452
|
+
Four variants are available: `danger`, `warning`, `info`, `success`. System banners (error and unsaved changes) are always present and cannot be removed by `clearBanners()`. For the full API reference, see [useBlade — Banner Management](../../../../core/composables/useBlade/useBlade.docs.md#banner-management).
|
|
451
453
|
|
|
452
454
|
## Blade Width Control
|
|
453
455
|
|
|
454
456
|
```vue
|
|
455
|
-
<VcBlade
|
|
457
|
+
<VcBlade width="350px"> <!-- Pixels (number) -->
|
|
456
458
|
<VcBlade width="50%"> <!-- CSS value (string) -->
|
|
457
459
|
<VcBlade> <!-- Default: "30%" -->
|
|
458
460
|
```
|
|
@@ -463,12 +465,12 @@ On mobile, width is forced to `100%`. When `expanded` is `true`, the blade fills
|
|
|
463
465
|
|
|
464
466
|
### Master-Detail (List + Details)
|
|
465
467
|
|
|
466
|
-
The most common vc-shell pattern. Key points
|
|
468
|
+
The most common vc-shell pattern. Key points:
|
|
467
469
|
|
|
468
470
|
**List blade** -- Opens a details blade on row click, tracks selected item:
|
|
469
471
|
|
|
470
472
|
```ts
|
|
471
|
-
|
|
473
|
+
defineBlade({ name: "Offers", url: "/offers", isWorkspace: true });
|
|
472
474
|
|
|
473
475
|
const { openBlade } = useBlade();
|
|
474
476
|
const selectedItemId = ref<string>();
|
|
@@ -493,7 +495,7 @@ defineExpose({ title: bladeTitle, reload });
|
|
|
493
495
|
**Details blade** -- Loads entity, saves, notifies parent, replaces self on create:
|
|
494
496
|
|
|
495
497
|
```ts
|
|
496
|
-
|
|
498
|
+
defineBlade({ name: "Offer", url: "/offer", routable: false });
|
|
497
499
|
|
|
498
500
|
const { callParent, replaceWith, onBeforeClose } = useBlade();
|
|
499
501
|
|
|
@@ -577,7 +579,7 @@ const toolbar = ref([
|
|
|
577
579
|
defineOptions({});
|
|
578
580
|
|
|
579
581
|
// CORRECT
|
|
580
|
-
|
|
582
|
+
defineBlade({ name: "ProductDetails", url: "/product" });
|
|
581
583
|
```
|
|
582
584
|
|
|
583
585
|
### Forgetting to expose the title
|
|
@@ -624,17 +626,17 @@ openBlade({ name: "ProductsList" });
|
|
|
624
626
|
|
|
625
627
|
## Props
|
|
626
628
|
|
|
627
|
-
| Prop | Type | Default | Description
|
|
628
|
-
| -------------- | ------------------ | ----------- |
|
|
629
|
-
| `title` | `string` | `undefined` | Title text in the blade header.
|
|
630
|
-
| `subtitle` | `string` | `undefined` | Secondary text below the title.
|
|
631
|
-
| `icon` | `string` | `undefined` | Icon name (e.g., `"lucide-box"`) displayed before the title.
|
|
632
|
-
| `width` | `number \| string` | `"30%"` | Blade width. Numbers are pixels; strings are CSS values.
|
|
633
|
-
| `expanded` | `boolean` | `
|
|
634
|
-
| `closable` | `boolean` | `true` | Whether the close button is shown.
|
|
635
|
-
| `toolbarItems` | `IBladeToolbar[]` | `[]` | Action buttons in the toolbar zone.
|
|
636
|
-
| `modified` | `boolean` | `undefined` | Shows unsaved changes indicator and banner.
|
|
637
|
-
| `loading` | `boolean` | `
|
|
629
|
+
| Prop | Type | Default | Description |
|
|
630
|
+
| -------------- | ------------------ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
631
|
+
| `title` | `string` | `undefined` | Title text in the blade header. |
|
|
632
|
+
| `subtitle` | `string` | `undefined` | Secondary text below the title. |
|
|
633
|
+
| `icon` | `string` | `undefined` | Icon name (e.g., `"lucide-box"`) displayed before the title. |
|
|
634
|
+
| `width` | `number \| string` | `"30%"` | Blade width. Numbers are pixels; strings are CSS values. |
|
|
635
|
+
| `expanded` | `boolean` | `undefined` | Whether the blade fills all available width. Inside a blade-navigation context this prop is overridden by the active blade's expanded state; in standalone use the prop is read directly. |
|
|
636
|
+
| `closable` | `boolean` | `true` | Whether the close button is shown. |
|
|
637
|
+
| `toolbarItems` | `IBladeToolbar[]` | `[]` | Action buttons in the toolbar zone. |
|
|
638
|
+
| `modified` | `boolean` | `undefined` | Shows unsaved changes indicator and banner. |
|
|
639
|
+
| `loading` | `boolean` | `undefined` | Shows skeleton placeholders for all blade zones. |
|
|
638
640
|
|
|
639
641
|
## Events
|
|
640
642
|
|
|
@@ -167,7 +167,7 @@ Formats as currency. Reads the currency code from each row's `currency` field by
|
|
|
167
167
|
### Image
|
|
168
168
|
|
|
169
169
|
```vue
|
|
170
|
-
<VcColumn id="thumbnail" field="imgSrc" title="Image" type="image"
|
|
170
|
+
<VcColumn id="thumbnail" field="imgSrc" title="Image" type="image" width="60px" />
|
|
171
171
|
```
|
|
172
172
|
|
|
173
173
|
Renders a small thumbnail from the field's URL value.
|
|
@@ -351,7 +351,7 @@ For explicit control over checkbox column placement:
|
|
|
351
351
|
|
|
352
352
|
```vue
|
|
353
353
|
<VcDataTable :items="products" v-model:selection="selected">
|
|
354
|
-
<VcColumn id="select" selection-mode="multiple"
|
|
354
|
+
<VcColumn id="select" selection-mode="multiple" width="40px" />
|
|
355
355
|
<VcColumn id="name" field="name" title="Name" />
|
|
356
356
|
</VcDataTable>
|
|
357
357
|
```
|
|
@@ -485,7 +485,7 @@ A row enters edit mode when the user clicks the edit button. All editable cells
|
|
|
485
485
|
<VcColumn id="name" field="name" title="Name" editable />
|
|
486
486
|
<VcColumn id="price" field="price" title="Price" type="money" editable />
|
|
487
487
|
<VcColumn id="stock" field="stock" title="Stock" type="number" editable />
|
|
488
|
-
<VcColumn id="actions" :row-editor="true" title=""
|
|
488
|
+
<VcColumn id="actions" :row-editor="true" title="" width="80px" />
|
|
489
489
|
</VcDataTable>
|
|
490
490
|
```
|
|
491
491
|
|
|
@@ -550,7 +550,7 @@ Columns are resizable by default. Drag the right border of any column header to
|
|
|
550
550
|
Set per-column min/max constraints:
|
|
551
551
|
|
|
552
552
|
```vue
|
|
553
|
-
<VcColumn id="name" field="name" title="Name"
|
|
553
|
+
<VcColumn id="name" field="name" title="Name" min-width="100px" max-width="400px" />
|
|
554
554
|
```
|
|
555
555
|
|
|
556
556
|
### Reorder
|
|
@@ -583,11 +583,11 @@ VcDataTable uses a **weight-based engine** to compute exact pixel widths for eve
|
|
|
583
583
|
|
|
584
584
|
**Width prop contract:**
|
|
585
585
|
|
|
586
|
-
| Declaration
|
|
587
|
-
|
|
|
588
|
-
| `width="200"` or
|
|
589
|
-
| `width="20%"`
|
|
590
|
-
| `width` omitted
|
|
586
|
+
| Declaration | Meaning |
|
|
587
|
+
| -------------------------------- | ------------------------------------------------------------ |
|
|
588
|
+
| `width="200"` or `width="200px"` | Initial 200 px hint |
|
|
589
|
+
| `width="20%"` | Initial hint based on 20% of available width |
|
|
590
|
+
| `width` omitted | Auto — splits remaining space equally among all auto columns |
|
|
591
591
|
|
|
592
592
|
After initialization the column lives in the weight model. Container resizes recompute px values without changing weights.
|
|
593
593
|
|
|
@@ -628,7 +628,7 @@ When a blade narrows (e.g., a second blade opens), only `alwaysVisible` columns
|
|
|
628
628
|
|
|
629
629
|
```vue
|
|
630
630
|
<VcDataTable :items="products" :show-all-columns="!isBladeNarrow">
|
|
631
|
-
<VcColumn id="image" field="imgSrc" type="image"
|
|
631
|
+
<VcColumn id="image" field="imgSrc" type="image" width="60px" :always-visible="true" />
|
|
632
632
|
<VcColumn id="name" field="name" title="Name" :always-visible="true" />
|
|
633
633
|
<VcColumn id="price" field="price" title="Price" type="money" />
|
|
634
634
|
<VcColumn id="stock" field="stock" title="Stock" type="number" />
|
|
@@ -653,7 +653,7 @@ Enable drag-and-drop row reordering with a drag handle column:
|
|
|
653
653
|
<VcColumn
|
|
654
654
|
id="drag"
|
|
655
655
|
:row-reorder="true"
|
|
656
|
-
|
|
656
|
+
width="40px"
|
|
657
657
|
/>
|
|
658
658
|
<VcColumn
|
|
659
659
|
id="name"
|
|
@@ -695,7 +695,7 @@ Show additional detail below a row when the user clicks the expand toggle:
|
|
|
695
695
|
<VcColumn
|
|
696
696
|
id="expand"
|
|
697
697
|
:expander="true"
|
|
698
|
-
|
|
698
|
+
width="40px"
|
|
699
699
|
/>
|
|
700
700
|
<VcColumn
|
|
701
701
|
id="orderNumber"
|
|
@@ -752,7 +752,7 @@ Use `isRowExpandable` to control which rows show the expand toggle. Rows that fa
|
|
|
752
752
|
<VcColumn
|
|
753
753
|
id="expand"
|
|
754
754
|
:expander="true"
|
|
755
|
-
|
|
755
|
+
width="40px"
|
|
756
756
|
/>
|
|
757
757
|
<VcColumn
|
|
758
758
|
id="orderNumber"
|
|
@@ -1028,9 +1028,9 @@ async function loadNextPage() {
|
|
|
1028
1028
|
## State Persistence
|
|
1029
1029
|
|
|
1030
1030
|
!!! tip "Use unique state keys"
|
|
1031
|
-
Every table in your application must have a distinct `state-key`. Two tables sharing the same key will silently overwrite each other's persisted column widths, order, and
|
|
1031
|
+
Every table in your application must have a distinct `state-key`. Two tables sharing the same key will silently overwrite each other's persisted column widths, order, and hidden/shown column lists.
|
|
1032
1032
|
|
|
1033
|
-
Persist column widths, column order,
|
|
1033
|
+
Persist column widths, column order, and column visibility across page reloads. Sort, filters, pagination, selection, and search input are session-scoped — they are deliberately excluded from the persisted state so the blade owns them through its own URL or store:
|
|
1034
1034
|
|
|
1035
1035
|
```vue
|
|
1036
1036
|
<VcDataTable :items="products" state-key="product-list">
|
|
@@ -1135,7 +1135,7 @@ On mobile screens, VcDataTable automatically switches from a table to a card lay
|
|
|
1135
1135
|
|
|
1136
1136
|
```vue
|
|
1137
1137
|
<VcDataTable :items="products">
|
|
1138
|
-
<VcColumn id="image" field="imgSrc" type="image" mobile-role="image"
|
|
1138
|
+
<VcColumn id="image" field="imgSrc" type="image" mobile-role="image" width="60px" />
|
|
1139
1139
|
<VcColumn id="name" field="name" title="Name" mobile-role="title" />
|
|
1140
1140
|
<VcColumn id="price" field="price" title="Price" type="money" mobile-role="field" />
|
|
1141
1141
|
<VcColumn id="stock" field="stock" title="Stock" type="number" mobile-role="field" />
|
|
@@ -1589,7 +1589,7 @@ function onRowRemove(event: { data: Product; index: number; cancel: () => void }
|
|
|
1589
1589
|
|
|
1590
1590
|
### Recipe 1: Products List Blade
|
|
1591
1591
|
|
|
1592
|
-
A typical list blade with search, pagination, row actions, and empty states
|
|
1592
|
+
A typical list blade with search, pagination, row actions, and empty states.
|
|
1593
1593
|
|
|
1594
1594
|
```vue
|
|
1595
1595
|
<template>
|
|
@@ -22,19 +22,28 @@ Renders a VirtoCommerce platform dynamic property as the appropriate form contro
|
|
|
22
22
|
```vue
|
|
23
23
|
<template>
|
|
24
24
|
<VcDynamicProperty
|
|
25
|
-
:property="
|
|
26
|
-
:model-value="
|
|
27
|
-
:value-type="
|
|
28
|
-
:name="
|
|
29
|
-
:required="
|
|
30
|
-
:dictionary="
|
|
31
|
-
:multivalue="
|
|
25
|
+
:property="property"
|
|
26
|
+
:model-value="property.value"
|
|
27
|
+
:value-type="property.valueType ?? ''"
|
|
28
|
+
:name="property.name"
|
|
29
|
+
:required="property.required"
|
|
30
|
+
:dictionary="property.dictionary"
|
|
31
|
+
:multivalue="property.multivalue"
|
|
32
|
+
:multilanguage="property.multilanguage"
|
|
33
|
+
:current-language="currentLocale"
|
|
34
|
+
:rules="{
|
|
35
|
+
min: property.validationRule?.charCountMin,
|
|
36
|
+
max: property.validationRule?.charCountMax,
|
|
37
|
+
regex: property.validationRule?.regExp,
|
|
38
|
+
}"
|
|
32
39
|
:options-getter="loadDictionaryOptions"
|
|
33
40
|
@update:model-value="handlePropertyUpdate"
|
|
34
41
|
/>
|
|
35
42
|
</template>
|
|
36
43
|
```
|
|
37
44
|
|
|
45
|
+
The prop names match the `DynamicObjectProperty` shape returned by the platform — pass `property.dictionary`, `property.multivalue`, `property.required` directly without renaming. Always pass `valueType` with a string fallback because the API can return `undefined` for newly-created properties. The `:multilanguage` and `:current-language` props are required when the property supports localized values; the `:rules` object maps the property's `validationRule` to the form-validation engine.
|
|
46
|
+
|
|
38
47
|
## Key Props
|
|
39
48
|
|
|
40
49
|
| Prop | Type | Default | Description |
|
|
@@ -126,7 +126,7 @@ Override with the `width` or `height` prop for custom dimensions.
|
|
|
126
126
|
### Elevated Variant with Custom Width
|
|
127
127
|
|
|
128
128
|
```vue
|
|
129
|
-
<VcSidebar v-model="open" variant="elevated"
|
|
129
|
+
<VcSidebar v-model="open" variant="elevated" width="480px" title="Details">
|
|
130
130
|
<div class="tw-p-5">Content</div>
|
|
131
131
|
</VcSidebar>
|
|
132
132
|
```
|