@vc-shell/vc-app-skill 2.0.0-alpha.33 → 2.0.0-alpha.34
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 +78 -54
- package/README.md +42 -12
- package/package.json +4 -4
- package/runtime/VERSION +1 -1
- package/runtime/agents/api-analyzer.md +31 -16
- package/runtime/agents/blade-enhancer.md +15 -9
- package/runtime/agents/details-blade-generator.md +47 -31
- package/runtime/agents/list-blade-generator.md +21 -37
- package/runtime/agents/locales-generator.md +3 -0
- package/runtime/agents/migration-agent.md +18 -7
- package/runtime/agents/module-analyzer.md +2 -0
- package/runtime/agents/module-assembler.md +15 -0
- package/runtime/agents/promote-agent.md +15 -4
- package/runtime/agents/type-checker.md +11 -0
- package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
- package/runtime/knowledge/docs/core/api/platform.docs.md +30 -30
- package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +41 -41
- package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +12 -10
- package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +11 -14
- package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +35 -35
- package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +35 -35
- package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +15 -15
- package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +21 -18
- package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +28 -24
- package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +90 -61
- package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +19 -18
- package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +89 -68
- package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +27 -25
- package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
- package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +43 -47
- package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +11 -11
- package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +27 -15
- package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +30 -30
- package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +34 -36
- package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +44 -23
- package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +14 -11
- package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +47 -38
- package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +37 -28
- package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +23 -17
- package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +9 -9
- package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +42 -42
- package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +22 -12
- package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +33 -41
- package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +16 -16
- package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +28 -0
- package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +32 -24
- package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +32 -11
- package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +22 -13
- package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +7 -7
- package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +32 -24
- package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +21 -17
- package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +24 -24
- package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +28 -31
- package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +43 -24
- package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +68 -48
- package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +19 -19
- package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +42 -47
- package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +10 -4
- package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +35 -20
- package/runtime/knowledge/docs/core/notifications/notifications.docs.md +36 -35
- package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +38 -38
- package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +79 -62
- package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +10 -10
- package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +21 -23
- package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +91 -83
- package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +10 -16
- package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +9 -9
- package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +65 -22
- package/runtime/knowledge/docs/core/services/services.docs.md +19 -22
- package/runtime/knowledge/docs/core/types/types.docs.md +40 -40
- package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +27 -27
- package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +23 -23
- package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +22 -25
- package/runtime/knowledge/docs/core/utilities/utilities.docs.md +64 -64
- package/runtime/knowledge/docs/injection-keys.docs.md +52 -51
- package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +9 -9
- package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +23 -43
- package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +5 -5
- package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +5 -5
- package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +8 -7
- package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -7
- package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +8 -7
- package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +29 -13
- package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +13 -16
- package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +1 -7
- package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +5 -5
- package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
- package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -9
- package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +11 -17
- package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +34 -65
- package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +16 -26
- package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +2 -2
- package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -9
- package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +30 -40
- package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +26 -19
- package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +15 -12
- package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +15 -26
- package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +21 -19
- package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +83 -67
- package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +100 -59
- package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +28 -11
- package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +20 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +26 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +30 -32
- package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +25 -48
- package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +29 -24
- package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +23 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +22 -13
- package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +33 -18
- package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +56 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +28 -15
- package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +40 -20
- package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +25 -14
- package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +40 -14
- package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +54 -42
- package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +17 -17
- package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +21 -21
- package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +23 -10
- package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +55 -44
- package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +23 -20
- package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +92 -65
- package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +22 -36
- package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +65 -23
- package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +52 -73
- package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +91 -85
- package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +38 -42
- package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +56 -73
- package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +61 -27
- package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +42 -50
- package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +35 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +38 -41
- package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +109 -131
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +47 -88
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +50 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +29 -24
- package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +32 -28
- package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +57 -65
- package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +28 -26
- package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +55 -20
- package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +21 -35
- package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +38 -33
- package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +72 -83
- package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +21 -16
- package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +55 -64
- package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +51 -70
- package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +58 -57
- package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +49 -26
- package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +82 -28
- package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +90 -75
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +99 -48
- package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +548 -367
- package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +35 -52
- package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +33 -62
- package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +17 -23
- package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +109 -68
- package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +82 -44
- package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +8 -8
- package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +164 -0
- package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +34 -26
- package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +48 -40
- package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +30 -17
- package/runtime/knowledge/docs/ui/types/ui-types.docs.md +40 -29
- package/runtime/knowledge/examples/offers-module.md +15 -13
- package/runtime/knowledge/examples/team-module.md +82 -119
- package/runtime/knowledge/examples/videos-module.md +44 -17
- package/runtime/knowledge/index.md +22 -0
- package/runtime/knowledge/migration-prompts/blade-form-migration.md +17 -8
- package/runtime/knowledge/migration-prompts/blade-props-migration.md +1 -2
- package/runtime/knowledge/migration-prompts/datatable-migration.md +801 -0
- package/runtime/knowledge/migration-prompts/icon-migration.md +97 -0
- package/runtime/knowledge/migration-prompts/manual-migration-audit.md +117 -0
- package/runtime/knowledge/migration-prompts/notifications-migration.md +8 -3
- package/runtime/knowledge/migration-prompts/nswag-migration.md +25 -29
- package/runtime/knowledge/migration-prompts/use-assets-migration.md +164 -0
- package/runtime/knowledge/migration-prompts/use-data-table-pagination-migration.md +176 -0
- package/runtime/knowledge/migration-prompts/widgets-migration.md +48 -27
- package/runtime/knowledge/patterns/assets-management.md +20 -20
- package/runtime/knowledge/patterns/blade-navigation.md +7 -14
- package/runtime/knowledge/patterns/blade-widget.md +19 -17
- package/runtime/knowledge/patterns/child-blade-flow.md +19 -7
- package/runtime/knowledge/patterns/composable-details.md +20 -50
- package/runtime/knowledge/patterns/composable-list.md +43 -31
- package/runtime/knowledge/patterns/dashboard-widget.md +14 -16
- package/runtime/knowledge/patterns/datatable-pattern.md +521 -0
- package/runtime/knowledge/patterns/details-blade-pattern.md +78 -116
- package/runtime/knowledge/patterns/extension-points-usage.md +53 -44
- package/runtime/knowledge/patterns/form-validation.md +28 -64
- package/runtime/knowledge/patterns/list-blade-pattern.md +33 -21
- package/runtime/knowledge/patterns/module-structure.md +7 -1
- package/runtime/knowledge/patterns/multilanguage-fields.md +8 -14
- package/runtime/knowledge/patterns/notification-template.md +21 -14
- package/runtime/knowledge/patterns/signalr-notifications.md +30 -32
- package/runtime/knowledge/patterns/toolbar-pattern.md +18 -20
- package/runtime/vc-app.md +241 -62
|
@@ -14,11 +14,11 @@ The sort expression is formatted as `"property:DIRECTION"` (e.g., `"createdDate:
|
|
|
14
14
|
## Basic Usage
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
|
-
import { useTableSort } from
|
|
17
|
+
import { useTableSort } from "@vc-shell/framework";
|
|
18
18
|
|
|
19
19
|
const { sortExpression, handleSortChange, resetSort } = useTableSort({
|
|
20
|
-
initialProperty:
|
|
21
|
-
initialDirection:
|
|
20
|
+
initialProperty: "createdDate",
|
|
21
|
+
initialDirection: "DESC",
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
// Wire to VcTable
|
|
@@ -34,19 +34,19 @@ watch(sortExpression, (sort) => {
|
|
|
34
34
|
|
|
35
35
|
### Parameters (Options)
|
|
36
36
|
|
|
37
|
-
| Option
|
|
38
|
-
|
|
39
|
-
| `initialProperty`
|
|
40
|
-
| `initialDirection` | `"ASC" \| "DESC"` | `null`
|
|
37
|
+
| Option | Type | Default | Description |
|
|
38
|
+
| ------------------ | ----------------- | ------- | ------------------------------------ |
|
|
39
|
+
| `initialProperty` | `string` | `null` | Column property to sort by initially |
|
|
40
|
+
| `initialDirection` | `"ASC" \| "DESC"` | `null` | Initial sort direction |
|
|
41
41
|
|
|
42
42
|
### Returns
|
|
43
43
|
|
|
44
|
-
| Property
|
|
45
|
-
|
|
46
|
-
| `currentSort`
|
|
47
|
-
| `sortExpression`
|
|
48
|
-
| `handleSortChange` | `(sortParam: string) => void`
|
|
49
|
-
| `resetSort`
|
|
44
|
+
| Property | Type | Description |
|
|
45
|
+
| ------------------ | ------------------------------------- | ----------------------------------------------------------------- |
|
|
46
|
+
| `currentSort` | `WritableComputedRef<TableSortState>` | Current `{ property, direction }` state |
|
|
47
|
+
| `sortExpression` | `Ref<string \| undefined>` | Formatted string (e.g., `"name:ASC"`) or `undefined` when no sort |
|
|
48
|
+
| `handleSortChange` | `(sortParam: string) => void` | Handle column header click; accepts `"field"` or `"field:DIR"` |
|
|
49
|
+
| `resetSort` | `() => void` | Reset to initial sort options (or clear if none) |
|
|
50
50
|
|
|
51
51
|
### TableSortState
|
|
52
52
|
|
|
@@ -60,6 +60,7 @@ interface TableSortState {
|
|
|
60
60
|
## Sort Cycling
|
|
61
61
|
|
|
62
62
|
When clicking the same column without an explicit direction:
|
|
63
|
+
|
|
63
64
|
1. First click: `ASC`
|
|
64
65
|
2. Second click: `DESC`
|
|
65
66
|
3. Third click: sort cleared (`undefined`)
|
|
@@ -87,7 +88,7 @@ async function loadItems() {
|
|
|
87
88
|
loading.value = true;
|
|
88
89
|
try {
|
|
89
90
|
const response = await api.searchProducts({
|
|
90
|
-
sort: sortExpression.value,
|
|
91
|
+
sort: sortExpression.value, // "createdDate:DESC"
|
|
91
92
|
skip: 0,
|
|
92
93
|
take: 20,
|
|
93
94
|
});
|
|
@@ -108,9 +109,21 @@ watch(sortExpression, () => loadItems(), { immediate: true });
|
|
|
108
109
|
:sort-expression="sortExpression"
|
|
109
110
|
@header-click="handleSortChange"
|
|
110
111
|
>
|
|
111
|
-
<VcColumn
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
<VcColumn
|
|
113
|
+
id="name"
|
|
114
|
+
header="Name"
|
|
115
|
+
sortable
|
|
116
|
+
/>
|
|
117
|
+
<VcColumn
|
|
118
|
+
id="createdDate"
|
|
119
|
+
header="Created"
|
|
120
|
+
sortable
|
|
121
|
+
/>
|
|
122
|
+
<VcColumn
|
|
123
|
+
id="price"
|
|
124
|
+
header="Price"
|
|
125
|
+
sortable
|
|
126
|
+
/>
|
|
114
127
|
</VcTable>
|
|
115
128
|
</template>
|
|
116
129
|
```
|
|
@@ -21,41 +21,41 @@ When building custom form field components, extending these interfaces ensures c
|
|
|
21
21
|
|
|
22
22
|
Base props shared by all form field components (VcCheckbox, VcSwitch, VcRadioButton, VcInput, VcTextarea, VcSelect, VcDatePicker, VcEditor, VcFileUpload, VcColorInput, etc.).
|
|
23
23
|
|
|
24
|
-
| Prop
|
|
25
|
-
|
|
26
|
-
| `label`
|
|
27
|
-
| `tooltip`
|
|
28
|
-
| `disabled`
|
|
29
|
-
| `required`
|
|
30
|
-
| `name`
|
|
31
|
-
| `error`
|
|
32
|
-
| `errorMessage` | `string?`
|
|
24
|
+
| Prop | Type | Description |
|
|
25
|
+
| -------------- | ---------- | ------------------------------------------------------ |
|
|
26
|
+
| `label` | `string?` | Field label text |
|
|
27
|
+
| `tooltip` | `string?` | Tooltip shown on label hover |
|
|
28
|
+
| `disabled` | `boolean?` | Whether the field is disabled |
|
|
29
|
+
| `required` | `boolean?` | Whether the field is required |
|
|
30
|
+
| `name` | `string?` | Form field name attribute |
|
|
31
|
+
| `error` | `boolean?` | External error flag |
|
|
32
|
+
| `errorMessage` | `string?` | Error message text (also sets error state when truthy) |
|
|
33
33
|
|
|
34
34
|
### `ITextFieldProps`
|
|
35
35
|
|
|
36
36
|
Extended props for text-input-like components (VcInput, VcTextarea, VcSelect, VcDatePicker, VcColorInput). Extends `IFormFieldProps`.
|
|
37
37
|
|
|
38
|
-
| Prop
|
|
39
|
-
|
|
40
|
-
| `placeholder`
|
|
41
|
-
| `hint`
|
|
42
|
-
| `clearable`
|
|
43
|
-
| `loading`
|
|
44
|
-
| `autofocus`
|
|
45
|
-
| `size`
|
|
46
|
-
| `multilanguage`
|
|
47
|
-
| `currentLanguage` | `string?`
|
|
38
|
+
| Prop | Type | Description |
|
|
39
|
+
| ----------------- | ----------------------- | -------------------------------------------- |
|
|
40
|
+
| `placeholder` | `string?` | Placeholder text |
|
|
41
|
+
| `hint` | `string?` | Hint text shown below the field |
|
|
42
|
+
| `clearable` | `boolean?` | Show clear button |
|
|
43
|
+
| `loading` | `boolean?` | Show loading indicator |
|
|
44
|
+
| `autofocus` | `boolean?` | Auto-focus on mount |
|
|
45
|
+
| `size` | `"default" \| "small"?` | Field size variant |
|
|
46
|
+
| `multilanguage` | `boolean?` | Whether multilanguage mode is active |
|
|
47
|
+
| `currentLanguage` | `string?` | Current language code for multilanguage mode |
|
|
48
48
|
|
|
49
49
|
### `Breadcrumbs`
|
|
50
50
|
|
|
51
51
|
Breadcrumb navigation item used by blade headers.
|
|
52
52
|
|
|
53
|
-
| Prop
|
|
54
|
-
|
|
55
|
-
| `id`
|
|
56
|
-
| `title`
|
|
57
|
-
| `icon`
|
|
58
|
-
| `clickHandler` | `(id: string) => void \| boolean \| Promise<void \| boolean>?` | Navigation handler
|
|
53
|
+
| Prop | Type | Description |
|
|
54
|
+
| -------------- | -------------------------------------------------------------- | ------------------------------ |
|
|
55
|
+
| `id` | `string` | Unique breadcrumb identifier |
|
|
56
|
+
| `title` | `MaybeRef<string \| undefined>` | Display text (can be reactive) |
|
|
57
|
+
| `icon` | `string?` | Icon identifier |
|
|
58
|
+
| `clickHandler` | `(id: string) => void \| boolean \| Promise<void \| boolean>?` | Navigation handler |
|
|
59
59
|
|
|
60
60
|
## Usage Examples
|
|
61
61
|
|
|
@@ -94,8 +94,15 @@ const emit = defineEmits<{
|
|
|
94
94
|
</script>
|
|
95
95
|
|
|
96
96
|
<template>
|
|
97
|
-
<div
|
|
98
|
-
|
|
97
|
+
<div
|
|
98
|
+
class="my-toggle"
|
|
99
|
+
:class="{ 'my-toggle--error': error || !!errorMessage }"
|
|
100
|
+
>
|
|
101
|
+
<VcLabel
|
|
102
|
+
v-if="label"
|
|
103
|
+
:tooltip="tooltip"
|
|
104
|
+
:required="required"
|
|
105
|
+
>
|
|
99
106
|
{{ label }}
|
|
100
107
|
</VcLabel>
|
|
101
108
|
<button
|
|
@@ -104,9 +111,13 @@ const emit = defineEmits<{
|
|
|
104
111
|
role="switch"
|
|
105
112
|
@click="emit('update:modelValue', !modelValue)"
|
|
106
113
|
>
|
|
107
|
-
{{ modelValue ? (onLabel ??
|
|
114
|
+
{{ modelValue ? (onLabel ?? "On") : (offLabel ?? "Off") }}
|
|
108
115
|
</button>
|
|
109
|
-
<span
|
|
116
|
+
<span
|
|
117
|
+
v-if="errorMessage"
|
|
118
|
+
class="my-toggle__error"
|
|
119
|
+
>{{ errorMessage }}</span
|
|
120
|
+
>
|
|
110
121
|
</div>
|
|
111
122
|
</template>
|
|
112
123
|
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Example: Offers Module (Notifications + Dashboard Widget)
|
|
2
2
|
|
|
3
3
|
This example covers patterns NOT shown in team-module.md:
|
|
4
|
+
|
|
4
5
|
- `registerDashboardWidget` — registering a dashboard widget from module index
|
|
5
6
|
- `notifications` registration in `defineAppModule` — mapping event names to Vue templates
|
|
6
7
|
- `useNotificationContext` — accessing notification data inside a notification template
|
|
@@ -40,11 +41,11 @@ export default defineAppModule({
|
|
|
40
41
|
notifications: {
|
|
41
42
|
OfferCreatedDomainEvent: {
|
|
42
43
|
template: OfferCreatedDomainEvent,
|
|
43
|
-
toast: { mode: "auto" },
|
|
44
|
+
toast: { mode: "auto" }, // auto-dismiss toast
|
|
44
45
|
},
|
|
45
46
|
OfferDeletedDomainEvent: {
|
|
46
47
|
template: OfferDeletedDomainEvent,
|
|
47
|
-
toast: { mode: "auto", severity: "warning" },
|
|
48
|
+
toast: { mode: "auto", severity: "warning" }, // warning severity
|
|
48
49
|
},
|
|
49
50
|
},
|
|
50
51
|
});
|
|
@@ -73,7 +74,8 @@ export * from "./composables";
|
|
|
73
74
|
<VcHint
|
|
74
75
|
v-if="notification.description"
|
|
75
76
|
class="tw-mb-1"
|
|
76
|
-
|
|
77
|
+
>{{ notification.description }}</VcHint
|
|
78
|
+
>
|
|
77
79
|
</NotificationTemplate>
|
|
78
80
|
</template>
|
|
79
81
|
|
|
@@ -98,17 +100,17 @@ const notificationStyle = {
|
|
|
98
100
|
|
|
99
101
|
## Notes on notification severity values
|
|
100
102
|
|
|
101
|
-
| severity
|
|
102
|
-
|
|
103
|
+
| severity | use case |
|
|
104
|
+
| ----------- | ----------------------------------- |
|
|
103
105
|
| `"success"` | Positive completion (default green) |
|
|
104
|
-
| `"warning"` | Non-critical issue (yellow)
|
|
105
|
-
| `"error"`
|
|
106
|
-
| (omitted)
|
|
106
|
+
| `"warning"` | Non-critical issue (yellow) |
|
|
107
|
+
| `"error"` | Failure (red) |
|
|
108
|
+
| (omitted) | Informational (blue/neutral) |
|
|
107
109
|
|
|
108
110
|
## Notes on toast mode values
|
|
109
111
|
|
|
110
|
-
| mode
|
|
111
|
-
|
|
112
|
-
| `"auto"`
|
|
113
|
-
| `"manual"` | User must click to dismiss
|
|
114
|
-
| `"none"`
|
|
112
|
+
| mode | behavior |
|
|
113
|
+
| ---------- | -------------------------------------------------------- |
|
|
114
|
+
| `"auto"` | Dismisses automatically after timeout |
|
|
115
|
+
| `"manual"` | User must click to dismiss |
|
|
116
|
+
| `"none"` | No toast shown; notification only in notification center |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Example: Team Module (Full List + Details Pattern)
|
|
2
2
|
|
|
3
|
-
This is a complete
|
|
3
|
+
This is a complete worked example showing the canonical
|
|
4
4
|
list-blade + details-blade pattern with `defineBlade`, `useDataTableSort`, `useModificationTracker`,
|
|
5
5
|
`Field` validation, `callParent`, `exposeToChildren`, and `onBeforeClose`.
|
|
6
6
|
|
|
@@ -9,6 +9,7 @@ list-blade + details-blade pattern with `defineBlade`, `useDataTableSort`, `useM
|
|
|
9
9
|
## `index.ts` — Module entry point
|
|
10
10
|
|
|
11
11
|
<!-- PATTERN: defineAppModule — minimal entry point wiring blades + locales -->
|
|
12
|
+
|
|
12
13
|
```typescript
|
|
13
14
|
import * as pages from "./pages";
|
|
14
15
|
import * as locales from "./locales";
|
|
@@ -25,6 +26,7 @@ export * from "./composables";
|
|
|
25
26
|
## `pages/index.ts` — Re-export all page blades
|
|
26
27
|
|
|
27
28
|
<!-- PATTERN: barrel export for pages used by defineAppModule -->
|
|
29
|
+
|
|
28
30
|
```typescript
|
|
29
31
|
export { default as TeamList } from "./team-list.vue";
|
|
30
32
|
export { default as TeamMemberDetails } from "./team-member-details.vue";
|
|
@@ -35,6 +37,7 @@ export { default as TeamMemberDetails } from "./team-member-details.vue";
|
|
|
35
37
|
## `composables/index.ts`
|
|
36
38
|
|
|
37
39
|
<!-- PATTERN: barrel export for composables -->
|
|
40
|
+
|
|
38
41
|
```typescript
|
|
39
42
|
export { default as useTeamMembers } from "./useTeamMembers";
|
|
40
43
|
export { default as useTeamMember } from "./useTeamMember";
|
|
@@ -45,6 +48,7 @@ export { default as useTeamMember } from "./useTeamMember";
|
|
|
45
48
|
## `locales/index.ts`
|
|
46
49
|
|
|
47
50
|
<!-- PATTERN: locale barrel — import JSON and re-export by language key -->
|
|
51
|
+
|
|
48
52
|
```typescript
|
|
49
53
|
import en from "./en.json";
|
|
50
54
|
export { en };
|
|
@@ -144,7 +148,7 @@ export { en };
|
|
|
144
148
|
>
|
|
145
149
|
<template #body="{ data }">
|
|
146
150
|
<VcStatus :variant="data.isLockedOut ? 'danger' : 'success'">
|
|
147
|
-
{{ data.isLockedOut ? t(
|
|
151
|
+
{{ data.isLockedOut ? t("TEAM.PAGES.LIST.TABLE.STATUS.LOCKED") : t("TEAM.PAGES.LIST.TABLE.STATUS.ACTIVE") }}
|
|
148
152
|
</VcStatus>
|
|
149
153
|
</template>
|
|
150
154
|
</VcColumn>
|
|
@@ -168,7 +172,7 @@ defineBlade({
|
|
|
168
172
|
name: "Team",
|
|
169
173
|
url: "/team",
|
|
170
174
|
isWorkspace: true,
|
|
171
|
-
permissions: [UserPermissions.
|
|
175
|
+
permissions: [UserPermissions.UsersManage],
|
|
172
176
|
menuItem: {
|
|
173
177
|
title: "TEAM.MENU.TITLE",
|
|
174
178
|
icon: "lucide-users",
|
|
@@ -463,7 +467,7 @@ exposeToChildren({ reload });
|
|
|
463
467
|
import { computed, ref, onMounted, unref, WritableComputedRef } from "vue";
|
|
464
468
|
import { useUser, IBladeToolbar, usePopup, useAssets, useBlade, ICommonAsset } from "@vc-shell/framework";
|
|
465
469
|
import { Field, useForm } from "vee-validate";
|
|
466
|
-
import type { Image,
|
|
470
|
+
import type { Image, User as IUser } from "../../../api_client/virtocommerce.mymodule";
|
|
467
471
|
import { useI18n } from "vue-i18n";
|
|
468
472
|
import { useTeamMember } from "../composables";
|
|
469
473
|
import { roles } from "../common";
|
|
@@ -479,14 +483,14 @@ defineBlade({
|
|
|
479
483
|
const { user } = useUser();
|
|
480
484
|
const { upload: uploadImage, remove: removeImage, loading: imageLoading } = useAssets();
|
|
481
485
|
// PATTERN: typed options generic on useBlade<OptionsType>
|
|
482
|
-
const { onBeforeClose, param, options, callParent, closeSelf } = useBlade<{ user:
|
|
486
|
+
const { onBeforeClose, param, options, callParent, closeSelf } = useBlade<{ user: IUser }>();
|
|
483
487
|
const { t } = useI18n({ useScope: "global" });
|
|
484
488
|
const {
|
|
485
489
|
userDetails,
|
|
486
490
|
loading,
|
|
487
|
-
modified,
|
|
491
|
+
modified, // from useModificationTracker — true when data differs from pristine
|
|
488
492
|
createTeamMember,
|
|
489
|
-
resetEntries,
|
|
493
|
+
resetEntries, // resets to pristineValue
|
|
490
494
|
deleteTeamMember,
|
|
491
495
|
updateTeamMember,
|
|
492
496
|
sendTeamMemberInvitation,
|
|
@@ -500,9 +504,7 @@ const isOwnerReadonly = computed(() => userDetails.value?.role === "vcmp-owner-r
|
|
|
500
504
|
const isCurrentUser = computed(() => userDetails.value?.userName === user.value?.userName);
|
|
501
505
|
const isOwnerReadonlyComputed = computed(() => isOwnerReadonly.value && !isCurrentUser.value);
|
|
502
506
|
|
|
503
|
-
const title = computed(() =>
|
|
504
|
-
param.value ? userDetails.value.firstName + " " + userDetails.value.lastName : t("TEAM.PAGES.DETAILS.TITLE"),
|
|
505
|
-
);
|
|
507
|
+
const title = computed(() => (param.value ? userDetails.value.firstName + " " + userDetails.value.lastName : t("TEAM.PAGES.DETAILS.TITLE")));
|
|
506
508
|
|
|
507
509
|
const sendInviteStatus = ref(false);
|
|
508
510
|
|
|
@@ -519,7 +521,7 @@ const bladeToolbar = ref<IBladeToolbar[]>([
|
|
|
519
521
|
async clickHandler() {
|
|
520
522
|
try {
|
|
521
523
|
await createTeamMember(userDetails.value, sendInviteStatus.value);
|
|
522
|
-
callParent("reload");
|
|
524
|
+
callParent("reload"); // PATTERN: call parent's exposed reload function
|
|
523
525
|
closeSelf();
|
|
524
526
|
} catch (e) {
|
|
525
527
|
if (e === "EMAIL_ALREADY_EXISTS") {
|
|
@@ -529,7 +531,7 @@ const bladeToolbar = ref<IBladeToolbar[]>([
|
|
|
529
531
|
}
|
|
530
532
|
}
|
|
531
533
|
},
|
|
532
|
-
isVisible: !param.value,
|
|
534
|
+
isVisible: !param.value, // PATTERN: isVisible for create-only button
|
|
533
535
|
disabled: computed(() => !(!isDisabled.value && modified.value)),
|
|
534
536
|
},
|
|
535
537
|
{
|
|
@@ -547,7 +549,7 @@ const bladeToolbar = ref<IBladeToolbar[]>([
|
|
|
547
549
|
}
|
|
548
550
|
}
|
|
549
551
|
},
|
|
550
|
-
isVisible: !!param.value,
|
|
552
|
+
isVisible: !!param.value, // PATTERN: isVisible for edit-only button
|
|
551
553
|
disabled: computed(() => !(!isDisabled.value && modified.value)),
|
|
552
554
|
},
|
|
553
555
|
{
|
|
@@ -555,7 +557,7 @@ const bladeToolbar = ref<IBladeToolbar[]>([
|
|
|
555
557
|
title: computed(() => t("TEAM.PAGES.DETAILS.TOOLBAR.RESET")),
|
|
556
558
|
icon: "lucide-undo-2",
|
|
557
559
|
clickHandler() {
|
|
558
|
-
resetEntries();
|
|
560
|
+
resetEntries(); // PATTERN: reset to pristine value
|
|
559
561
|
},
|
|
560
562
|
isVisible: !!param.value,
|
|
561
563
|
disabled: computed(() => !!param.value && !modified.value),
|
|
@@ -601,9 +603,7 @@ const isActive = computed({
|
|
|
601
603
|
const assetsHandler = {
|
|
602
604
|
loading: imageLoading,
|
|
603
605
|
async upload(files: FileList) {
|
|
604
|
-
photoHandler.value = (await uploadImage(files, `
|
|
605
|
-
(x) => ({ ...x } as Image),
|
|
606
|
-
);
|
|
606
|
+
photoHandler.value = (await uploadImage(files, `entities/${userDetails.value?.ownerId}/users`)).map((x) => ({ ...x }) as Image);
|
|
607
607
|
},
|
|
608
608
|
remove: (file: Image) => {
|
|
609
609
|
photoHandler.value = removeImage([file as unknown as ICommonAsset], photoHandler.value);
|
|
@@ -656,44 +656,37 @@ onBeforeClose(async () => {
|
|
|
656
656
|
|
|
657
657
|
```typescript
|
|
658
658
|
import { useApiClient, useAsync, useLoading } from "@vc-shell/framework";
|
|
659
|
-
import {
|
|
660
|
-
|
|
661
|
-
SearchSellerUsersResult,
|
|
662
|
-
SellerUser,
|
|
663
|
-
VcmpSellerSecurityClient,
|
|
664
|
-
} from "../../../../api_client/virtocommerce.marketplacevendor";
|
|
665
|
-
import type { SearchSellerUsersQuery as ISearchSellerUsersQuery } from "../../../../api_client/virtocommerce.marketplacevendor";
|
|
659
|
+
import { SearchUsersQuery, SearchUsersResult, User, UserSecurityClient } from "../../../../api_client/virtocommerce.mymodule";
|
|
660
|
+
import type { SearchUsersQuery as ISearchUsersQuery } from "../../../../api_client/virtocommerce.mymodule";
|
|
666
661
|
import { computed, Ref, ref } from "vue";
|
|
667
662
|
import { useRoute } from "vue-router";
|
|
668
663
|
|
|
669
664
|
interface IUseTeamMembers {
|
|
670
665
|
readonly loading: Ref<boolean>;
|
|
671
|
-
readonly membersList: Ref<
|
|
666
|
+
readonly membersList: Ref<User[]>;
|
|
672
667
|
readonly totalCount: Ref<number>;
|
|
673
668
|
readonly pages: Ref<number>;
|
|
674
669
|
currentPage: Ref<number>;
|
|
675
|
-
searchQuery: Ref<
|
|
676
|
-
getTeamMembers: (query?:
|
|
670
|
+
searchQuery: Ref<ISearchUsersQuery>;
|
|
671
|
+
getTeamMembers: (query?: ISearchUsersQuery) => Promise<void>;
|
|
677
672
|
}
|
|
678
673
|
|
|
679
674
|
export default (options?: { pageSize?: number; sort?: string }): IUseTeamMembers => {
|
|
680
|
-
const { getApiClient } = useApiClient(
|
|
675
|
+
const { getApiClient } = useApiClient(UserSecurityClient);
|
|
681
676
|
const route = useRoute();
|
|
682
677
|
|
|
683
678
|
const loading = ref(false);
|
|
684
679
|
const pageSize = options?.pageSize || 20;
|
|
685
|
-
const searchQuery = ref<
|
|
686
|
-
const searchResult = ref<
|
|
680
|
+
const searchQuery = ref<ISearchUsersQuery>({ take: pageSize, sort: options?.sort });
|
|
681
|
+
const searchResult = ref<SearchUsersResult>();
|
|
687
682
|
|
|
688
683
|
// PATTERN: useAsync<InputType> — wraps API call, returns { action, loading }
|
|
689
|
-
const { action: getTeamMembers, loading: getTeamMembersLoading } = useAsync<
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
},
|
|
696
|
-
);
|
|
684
|
+
const { action: getTeamMembers, loading: getTeamMembersLoading } = useAsync<ISearchUsersQuery>(async (query) => {
|
|
685
|
+
const client = await getApiClient();
|
|
686
|
+
const ownerId = route?.params?.ownerId as string;
|
|
687
|
+
searchQuery.value = { ...searchQuery.value, ...query };
|
|
688
|
+
searchResult.value = await client.searchUsers({ ...searchQuery.value, ownerId } as SearchUsersQuery);
|
|
689
|
+
});
|
|
697
690
|
|
|
698
691
|
return {
|
|
699
692
|
loading: useLoading(getTeamMembersLoading),
|
|
@@ -718,40 +711,30 @@ export default (options?: { pageSize?: number; sort?: string }): IUseTeamMembers
|
|
|
718
711
|
|
|
719
712
|
```typescript
|
|
720
713
|
import { useModificationTracker, useApiClient, useAsync, useLoading } from "@vc-shell/framework";
|
|
721
|
-
import {
|
|
722
|
-
|
|
723
|
-
CreateSellerUserCommand,
|
|
724
|
-
UpdateSellerUserCommand,
|
|
725
|
-
SendSellerUserInvitationCommand,
|
|
726
|
-
ValidationFailure,
|
|
727
|
-
ValidateSellerUserQuery,
|
|
728
|
-
VcmpSellerSecurityClient,
|
|
729
|
-
SearchSellerUsersQuery,
|
|
730
|
-
SellerUser,
|
|
731
|
-
} from "../../../../api_client/virtocommerce.marketplacevendor";
|
|
732
|
-
import type { SellerUserDetails as ISellerUserDetails, SellerUser as ISellerUser } from "../../../../api_client/virtocommerce.marketplacevendor";
|
|
714
|
+
import { UserDetails, CreateUserCommand, UpdateUserCommand, SendUserInvitationCommand, ValidationFailure, ValidateUserQuery, UserSecurityClient, SearchUsersQuery, User } from "../../../../api_client/virtocommerce.mymodule";
|
|
715
|
+
import type { UserDetails as IUserDetails, User as IUser } from "../../../../api_client/virtocommerce.mymodule";
|
|
733
716
|
import { computed, ComputedRef, Ref, ref } from "vue";
|
|
734
717
|
import { useRoute } from "vue-router";
|
|
735
718
|
|
|
736
719
|
interface IUseTeamMember {
|
|
737
720
|
loading: ComputedRef<boolean>;
|
|
738
|
-
userDetails: Ref<
|
|
721
|
+
userDetails: Ref<User>;
|
|
739
722
|
modified: ComputedRef<boolean>;
|
|
740
|
-
createTeamMember: (details:
|
|
741
|
-
updateTeamMember: (details:
|
|
723
|
+
createTeamMember: (details: IUser, inviteStatus: boolean) => Promise<void>;
|
|
724
|
+
updateTeamMember: (details: IUser) => Promise<void>;
|
|
742
725
|
sendTeamMemberInvitation: (args: { id: string }) => Promise<void>;
|
|
743
726
|
deleteTeamMember: (args: { id: string }) => Promise<void>;
|
|
744
|
-
validateTeamMember: (details:
|
|
727
|
+
validateTeamMember: (details: UserDetails) => Promise<ValidationFailure[]>;
|
|
745
728
|
resetEntries: () => void;
|
|
746
729
|
getTeamMember: (args: { id: string }) => Promise<void>;
|
|
747
730
|
resetModificationState: () => void;
|
|
748
731
|
}
|
|
749
732
|
|
|
750
733
|
export default (): IUseTeamMember => {
|
|
751
|
-
const { getApiClient } = useApiClient(
|
|
734
|
+
const { getApiClient } = useApiClient(UserSecurityClient);
|
|
752
735
|
const route = useRoute();
|
|
753
736
|
|
|
754
|
-
const userDetails = ref({} as
|
|
737
|
+
const userDetails = ref({} as User) as Ref<User>;
|
|
755
738
|
|
|
756
739
|
// PATTERN: useModificationTracker — currentValue is reactive proxy of userDetails
|
|
757
740
|
// isModified is true when currentValue differs from pristineValue (deep compare)
|
|
@@ -759,12 +742,10 @@ export default (): IUseTeamMember => {
|
|
|
759
742
|
|
|
760
743
|
const { action: getTeamMember, loading: getTeamMemberLoading } = useAsync<{ id: string }>(async (args) => {
|
|
761
744
|
const client = await getApiClient();
|
|
762
|
-
const
|
|
745
|
+
const ownerId = route?.params?.ownerId as string;
|
|
763
746
|
if (!args?.id) throw new Error("Id is required");
|
|
764
747
|
|
|
765
|
-
const result = await client
|
|
766
|
-
.searchSellerUsers({ sellerId, objectIds: [args.id] } as SearchSellerUsersQuery)
|
|
767
|
-
.then((res) => res.results?.find((x) => x.id === args.id));
|
|
748
|
+
const result = await client.searchUsers({ ownerId, objectIds: [args.id] } as SearchUsersQuery).then((res) => res.results?.find((x) => x.id === args.id));
|
|
768
749
|
|
|
769
750
|
if (result) {
|
|
770
751
|
currentValue.value = result;
|
|
@@ -772,65 +753,54 @@ export default (): IUseTeamMember => {
|
|
|
772
753
|
resetModificationState();
|
|
773
754
|
});
|
|
774
755
|
|
|
775
|
-
const { action: createTeamMember, loading: createTeamMemberLoading } = useAsync<
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
}
|
|
756
|
+
const { action: createTeamMember, loading: createTeamMemberLoading } = useAsync<IUser>(async (details, inviteStatus) => {
|
|
757
|
+
const client = await getApiClient();
|
|
758
|
+
const ownerId = route?.params?.ownerId as string;
|
|
759
|
+
|
|
760
|
+
const command = {
|
|
761
|
+
userDetails: { ...details } as UserDetails,
|
|
762
|
+
sendInvitation: inviteStatus,
|
|
763
|
+
ownerId,
|
|
764
|
+
} as CreateUserCommand;
|
|
765
|
+
|
|
766
|
+
// PATTERN: validate before create, throw string error code for blade to handle
|
|
767
|
+
const validationResult = await validateTeamMember(command.userDetails);
|
|
768
|
+
if (validationResult.length && validationResult[0].errorCode === "EMAIL_ALREADY_EXISTS") {
|
|
769
|
+
throw validationResult[0].errorCode;
|
|
770
|
+
}
|
|
791
771
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
);
|
|
772
|
+
await client.createUser(command);
|
|
773
|
+
resetModificationState();
|
|
774
|
+
});
|
|
796
775
|
|
|
797
|
-
const { action: updateTeamMember, loading: updateTeamMemberLoading } = useAsync<
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
if (!details?.id || !details?.sellerId) throw new Error("Id and sellerId are required");
|
|
776
|
+
const { action: updateTeamMember, loading: updateTeamMemberLoading } = useAsync<IUser, void>(async (details) => {
|
|
777
|
+
const client = await getApiClient();
|
|
778
|
+
if (!details?.id || !details?.ownerId) throw new Error("Id and ownerId are required");
|
|
801
779
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
780
|
+
await client.updateUser({
|
|
781
|
+
ownerId: details.ownerId,
|
|
782
|
+
userId: details.id,
|
|
783
|
+
userDetails: { ...details } as UserDetails,
|
|
784
|
+
} as UpdateUserCommand);
|
|
807
785
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
);
|
|
786
|
+
resetModificationState();
|
|
787
|
+
});
|
|
811
788
|
|
|
812
|
-
const { action: sendTeamMemberInvitation, loading: sendTeamMemberInvitationLoading } = useAsync<{ id: string }, void>(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
},
|
|
818
|
-
);
|
|
789
|
+
const { action: sendTeamMemberInvitation, loading: sendTeamMemberInvitationLoading } = useAsync<{ id: string }, void>(async (args) => {
|
|
790
|
+
if (!args?.id) throw new Error("Id is required");
|
|
791
|
+
const client = await getApiClient();
|
|
792
|
+
await client.sendUserInvitation({ userId: args?.id } as SendUserInvitationCommand);
|
|
793
|
+
});
|
|
819
794
|
|
|
820
|
-
const { action: deleteTeamMember, loading: deleteTeamMemberLoading } = useAsync<{ id: string }, void>(
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
},
|
|
826
|
-
);
|
|
795
|
+
const { action: deleteTeamMember, loading: deleteTeamMemberLoading } = useAsync<{ id: string }, void>(async (args) => {
|
|
796
|
+
if (!args?.id) throw new Error("Id is required");
|
|
797
|
+
const client = await getApiClient();
|
|
798
|
+
return await client.deleteUsers([args.id]);
|
|
799
|
+
});
|
|
827
800
|
|
|
828
|
-
const { action: validateTeamMember, loading: validateTeamMemberLoading } = useAsync<
|
|
829
|
-
SellerUserDetails,
|
|
830
|
-
ValidationFailure[]
|
|
831
|
-
>(async (details) => {
|
|
801
|
+
const { action: validateTeamMember, loading: validateTeamMemberLoading } = useAsync<UserDetails, ValidationFailure[]>(async (details) => {
|
|
832
802
|
const client = await getApiClient();
|
|
833
|
-
return await client.validateUser({
|
|
803
|
+
return await client.validateUser({ user: details } as ValidateUserQuery);
|
|
834
804
|
});
|
|
835
805
|
|
|
836
806
|
async function resetEntries() {
|
|
@@ -840,14 +810,7 @@ export default (): IUseTeamMember => {
|
|
|
840
810
|
|
|
841
811
|
return {
|
|
842
812
|
// PATTERN: useLoading(a, b, c, ...) — combines multiple loading refs into one
|
|
843
|
-
loading: useLoading(
|
|
844
|
-
createTeamMemberLoading,
|
|
845
|
-
updateTeamMemberLoading,
|
|
846
|
-
sendTeamMemberInvitationLoading,
|
|
847
|
-
deleteTeamMemberLoading,
|
|
848
|
-
validateTeamMemberLoading,
|
|
849
|
-
getTeamMemberLoading,
|
|
850
|
-
),
|
|
813
|
+
loading: useLoading(createTeamMemberLoading, updateTeamMemberLoading, sendTeamMemberInvitationLoading, deleteTeamMemberLoading, validateTeamMemberLoading, getTeamMemberLoading),
|
|
851
814
|
userDetails: currentValue,
|
|
852
815
|
modified: computed(() => isModified.value),
|
|
853
816
|
createTeamMember,
|