@vc-shell/framework 1.2.1 → 1.2.3-beta.0
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/core/composables/index.ts +2 -0
- package/core/composables/useAssets/index.ts +72 -28
- package/core/composables/useAsync/index.ts +4 -1
- package/core/composables/useBladeRegistry/index.ts +6 -5
- package/core/composables/useBreadcrumbs/index.ts +4 -1
- package/core/composables/useErrorHandler/index.ts +4 -1
- package/core/composables/useFunctions/debounce.ts +0 -1
- package/core/composables/useFunctions/delay.ts +0 -1
- package/core/composables/useFunctions/index.ts +0 -1
- package/core/composables/useFunctions/once.ts +0 -1
- package/core/composables/useFunctions/sleep.ts +0 -1
- package/core/composables/useFunctions/throttle.ts +0 -1
- package/core/composables/useGlobalSearch/index.ts +3 -3
- package/core/composables/useMenuService/index.ts +5 -2
- package/core/composables/useNotifications/index.ts +5 -2
- package/core/composables/useTheme/index.ts +4 -1
- package/core/composables/useUser/index.ts +189 -20
- package/core/composables/useWidgets/index.ts +5 -2
- package/core/constants/defaults.ts +76 -0
- package/core/constants/index.ts +2 -0
- package/core/constants/ui.ts +68 -0
- package/core/interceptors/index.ts +5 -2
- package/core/plugins/ai-agent/README.md +336 -0
- package/core/plugins/ai-agent/components/VcAiAgentPanel.vue +125 -0
- package/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue +182 -0
- package/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue +77 -0
- package/core/plugins/ai-agent/components/index.ts +1 -0
- package/core/plugins/ai-agent/composables/index.ts +4 -0
- package/core/plugins/ai-agent/composables/useAiAgent.ts +231 -0
- package/core/plugins/ai-agent/composables/useAiAgentContext.ts +280 -0
- package/core/plugins/ai-agent/constants.ts +89 -0
- package/core/plugins/ai-agent/index.ts +91 -0
- package/core/plugins/ai-agent/services/ai-agent-service.ts +598 -0
- package/core/plugins/ai-agent/types.ts +310 -0
- package/core/plugins/modularity/index.ts +8 -6
- package/core/plugins/modularity/loader.ts +36 -33
- package/core/plugins/signalR/index.ts +6 -3
- package/core/services/app-bar-menu-service.ts +4 -1
- package/core/services/dashboard-service.ts +4 -1
- package/core/services/index.ts +2 -0
- package/core/services/menu-service.ts +4 -1
- package/core/services/settings-menu-service.ts +4 -1
- package/core/services/toolbar-service.ts +18 -3
- package/core/services/widget-service.ts +7 -4
- package/core/types/index.ts +3 -0
- package/core/types/services.ts +194 -0
- package/core/utilities/errorTypes.ts +126 -0
- package/core/utilities/index.ts +2 -0
- package/core/utilities/logger.ts +120 -0
- package/dist/core/composables/useAssets/index.d.ts.map +1 -1
- package/dist/core/composables/useAsync/index.d.ts.map +1 -1
- package/dist/core/composables/useBladeRegistry/index.d.ts.map +1 -1
- package/dist/core/composables/useBreadcrumbs/index.d.ts.map +1 -1
- package/dist/core/composables/useErrorHandler/index.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/debounce.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/delay.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/index.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/once.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/sleep.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/throttle.d.ts.map +1 -1
- package/dist/core/composables/useGlobalSearch/index.d.ts.map +1 -1
- package/dist/core/composables/useMenuService/index.d.ts.map +1 -1
- package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
- package/dist/core/composables/useTheme/index.d.ts.map +1 -1
- package/dist/core/composables/useUser/index.d.ts +8 -0
- package/dist/core/composables/useUser/index.d.ts.map +1 -1
- package/dist/core/composables/useWidgets/index.d.ts.map +1 -1
- package/dist/core/constants/defaults.d.ts +63 -0
- package/dist/core/constants/defaults.d.ts.map +1 -0
- package/dist/core/constants/index.d.ts +2 -0
- package/dist/core/constants/index.d.ts.map +1 -1
- package/dist/core/constants/ui.d.ts +50 -0
- package/dist/core/constants/ui.d.ts.map +1 -0
- package/dist/core/interceptors/index.d.ts.map +1 -1
- package/dist/core/plugins/ai-agent/components/VcAiAgentPanel.vue.d.ts +3 -0
- package/dist/core/plugins/ai-agent/components/VcAiAgentPanel.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue.d.ts +15 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue.d.ts +10 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/index.d.ts +2 -0
- package/dist/core/plugins/ai-agent/components/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/index.d.ts +4 -0
- package/dist/core/plugins/ai-agent/composables/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgent.d.ts +95 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgent.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgentContext.d.ts +55 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgentContext.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/constants.d.ts +47 -0
- package/dist/core/plugins/ai-agent/constants.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/index.d.ts +48 -0
- package/dist/core/plugins/ai-agent/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/services/ai-agent-service.d.ts +45 -0
- package/dist/core/plugins/ai-agent/services/ai-agent-service.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/types.d.ts +258 -0
- package/dist/core/plugins/ai-agent/types.d.ts.map +1 -0
- package/dist/core/plugins/modularity/index.d.ts.map +1 -1
- package/dist/core/plugins/modularity/loader.d.ts.map +1 -1
- package/dist/core/plugins/signalR/index.d.ts.map +1 -1
- package/dist/core/services/app-bar-menu-service.d.ts.map +1 -1
- package/dist/core/services/dashboard-service.d.ts.map +1 -1
- package/dist/core/services/menu-service.d.ts.map +1 -1
- package/dist/core/services/settings-menu-service.d.ts.map +1 -1
- package/dist/core/services/toolbar-service.d.ts.map +1 -1
- package/dist/core/services/widget-service.d.ts.map +1 -1
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/services.d.ts +169 -0
- package/dist/core/types/services.d.ts.map +1 -0
- package/dist/core/utilities/errorTypes.d.ts +61 -0
- package/dist/core/utilities/errorTypes.d.ts.map +1 -0
- package/dist/core/utilities/index.d.ts +2 -0
- package/dist/core/utilities/index.d.ts.map +1 -1
- package/dist/core/utilities/logger.d.ts +259 -0
- package/dist/core/utilities/logger.d.ts.map +1 -0
- package/dist/framework.js +9623 -8417
- package/dist/index.css +1 -1
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/injection-keys.d.ts +21 -6
- package/dist/injection-keys.d.ts.map +1 -1
- package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.d.ts.map +1 -1
- package/dist/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.d.ts.map +1 -1
- package/dist/shared/components/draggable-dashboard/composables/useLayoutPersistence.d.ts.map +1 -1
- package/dist/shared/components/notifications/composables/useContainer/index.d.ts.map +1 -1
- package/dist/shared/components/notifications/composables/useInstance/index.d.ts.map +1 -1
- package/dist/shared/components/notifications/core/notification.d.ts.map +1 -1
- package/dist/shared/components/popup-handler/components/vc-popup-container/vc-popup-container.vue.d.ts.map +1 -1
- package/dist/shared/components/sign-in/useExternalProvider.d.ts.map +1 -1
- package/dist/shared/composables/index.d.ts +1 -0
- package/dist/shared/composables/index.d.ts.map +1 -1
- package/dist/shared/composables/useExternalWidgets.d.ts.map +1 -1
- package/dist/shared/composables/useMenuExpanded.d.ts.map +1 -1
- package/dist/shared/composables/useTableSelection.d.ts +57 -0
- package/dist/shared/composables/useTableSelection.d.ts.map +1 -0
- package/dist/shared/composables/useTableSort.d.ts.map +1 -1
- package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts.map +1 -1
- package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -1
- package/dist/shared/utilities/colorUtils.d.ts +0 -6
- package/dist/shared/utilities/colorUtils.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-banner/vc-banner.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts +0 -15
- package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-container/vc-container.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-link/vc-link.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-loading/vc-loading.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-status/vc-status.vue.d.ts +0 -5
- package/dist/ui/components/atoms/vc-status/vc-status.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-tooltip/vc-tooltip.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-widget/vc-widget.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-pagination/vc-pagination.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-toast/vc-toast.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts.map +1 -1
- package/dist/{vendor-lodash-es-BqkGj3Jl.js → vendor-lodash-es-SgOIjJF8.js} +2 -0
- package/package.json +5 -5
- package/shared/components/app-switcher/composables/useAppSwitcher/index.ts +4 -1
- package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +67 -4
- package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +13 -10
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.ts +7 -4
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.ts +4 -1
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.ts +4 -1
- package/shared/components/change-password/change-password.vue +1 -1
- package/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.ts +14 -5
- package/shared/components/draggable-dashboard/composables/useLayoutPersistence.ts +5 -2
- package/shared/components/index.ts +2 -0
- package/shared/components/notifications/composables/useContainer/index.ts +8 -6
- package/shared/components/notifications/composables/useInstance/index.ts +4 -1
- package/shared/components/notifications/core/notification.ts +10 -7
- package/shared/components/popup-handler/components/vc-popup-container/vc-popup-container.vue +20 -1
- package/shared/components/sign-in/useExternalProvider.ts +6 -4
- package/shared/composables/index.ts +1 -0
- package/shared/composables/useExternalWidgets.ts +7 -4
- package/shared/composables/useMenuExpanded.ts +15 -1
- package/shared/composables/useTableSelection.ts +151 -0
- package/shared/composables/useTableSort.ts +4 -4
- package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +6 -3
- package/shared/pages/LoginPage/components/login/Login.vue +4 -1
- package/shared/utilities/colorUtils.ts +5 -12
- package/ui/components/atoms/vc-banner/vc-banner.vue +4 -1
- package/ui/components/atoms/vc-button/vc-button.vue +2 -25
- package/ui/components/atoms/vc-container/vc-container.vue +12 -3
- package/ui/components/atoms/vc-icon/vc-icon.vue +0 -10
- package/ui/components/atoms/vc-icon/vc-lucide-icon.vue +5 -2
- package/ui/components/atoms/vc-image/vc-image.vue +4 -1
- package/ui/components/atoms/vc-link/vc-link.vue +59 -54
- package/ui/components/atoms/vc-loading/vc-loading.vue +4 -0
- package/ui/components/atoms/vc-status/vc-status.vue +0 -5
- package/ui/components/atoms/vc-status-icon/vc-status-icon.vue +4 -4
- package/ui/components/atoms/vc-tooltip/vc-tooltip.vue +8 -1
- package/ui/components/atoms/vc-video/vc-video.vue +4 -2
- package/ui/components/atoms/vc-widget/vc-widget.vue +4 -1
- package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +7 -2
- package/ui/components/molecules/vc-input/vc-input.vue +0 -1
- package/ui/components/molecules/vc-pagination/vc-pagination.vue +6 -1
- package/ui/components/molecules/vc-rating/vc-rating.vue +1 -1
- package/ui/components/molecules/vc-textarea/vc-textarea.vue +1 -1
- package/ui/components/molecules/vc-toast/vc-toast.vue +11 -1
- package/ui/components/organisms/vc-app/vc-app.vue +22 -3
- package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +4 -1
- package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +14 -14
- package/ui/components/organisms/vc-blade/vc-blade.vue +3 -1
- package/ui/components/organisms/vc-login-form/vc-login-form.vue +3 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +34 -2
- package/ui/components/organisms/vc-table/composables/useTableActions.ts +7 -10
- package/ui/components/organisms/vc-table/composables/useTableColumnResize.ts +4 -1
- package/ui/components/organisms/vc-table/composables/useTableRowReorder.ts +5 -2
- package/ui/components/organisms/vc-table/composables/useTableSelection.ts +26 -18
- package/ui/components/organisms/vc-table/composables/useTableState.ts +4 -1
- package/core/services/global-search-service.ts +0 -36
- package/dist/core/services/global-search-service.d.ts +0 -10
- package/dist/core/services/global-search-service.d.ts.map +0 -1
|
@@ -6,6 +6,9 @@ import {
|
|
|
6
6
|
registerExternalWidget,
|
|
7
7
|
} from "./../../services/widget-service";
|
|
8
8
|
import { WidgetServiceKey } from "./../../../injection-keys";
|
|
9
|
+
import { createLogger, InjectionError } from "../../utilities";
|
|
10
|
+
|
|
11
|
+
const logger = createLogger("use-widgets");
|
|
9
12
|
|
|
10
13
|
export function provideWidgetService(): IWidgetService {
|
|
11
14
|
const service = createWidgetService();
|
|
@@ -16,8 +19,8 @@ export function provideWidgetService(): IWidgetService {
|
|
|
16
19
|
export function useWidgets(): IWidgetService {
|
|
17
20
|
const service = inject(WidgetServiceKey);
|
|
18
21
|
if (!service) {
|
|
19
|
-
|
|
20
|
-
throw new
|
|
22
|
+
logger.error("Widget service not found in current context. Injection chain:", getCurrentInstance());
|
|
23
|
+
throw new InjectionError("WidgetService");
|
|
21
24
|
}
|
|
22
25
|
return service;
|
|
23
26
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Default Values for VC-Shell Framework
|
|
3
|
+
* Centralized storage for default prop values across components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const COMPONENT_DEFAULTS = {
|
|
7
|
+
input: {
|
|
8
|
+
maxlength: 1024,
|
|
9
|
+
debounce: 0,
|
|
10
|
+
type: "text" as const,
|
|
11
|
+
autocomplete: "off" as const,
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
select: {
|
|
15
|
+
debounce: 500,
|
|
16
|
+
pageSize: 20,
|
|
17
|
+
searchable: true,
|
|
18
|
+
clearable: true,
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
table: {
|
|
22
|
+
pageSize: 20,
|
|
23
|
+
pageSizes: [10, 20, 50, 100] as readonly number[],
|
|
24
|
+
selectable: false,
|
|
25
|
+
multiselect: false,
|
|
26
|
+
stickyHeader: true,
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
pagination: {
|
|
30
|
+
pageSize: 20,
|
|
31
|
+
visiblePages: 5,
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
textarea: {
|
|
35
|
+
rows: 3,
|
|
36
|
+
maxlength: 4096,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
editor: {
|
|
40
|
+
minHeight: 200,
|
|
41
|
+
maxHeight: 500,
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
tooltip: {
|
|
45
|
+
delay: 300,
|
|
46
|
+
placement: "top" as const,
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
modal: {
|
|
50
|
+
closeOnEscape: true,
|
|
51
|
+
closeOnOverlayClick: true,
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
notification: {
|
|
55
|
+
duration: 5000,
|
|
56
|
+
position: "top-right" as const,
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
dashboard: {
|
|
60
|
+
columns: 12,
|
|
61
|
+
rowHeight: 80,
|
|
62
|
+
gap: 20,
|
|
63
|
+
},
|
|
64
|
+
} as const;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Type for accessing component defaults
|
|
68
|
+
*/
|
|
69
|
+
export type ComponentDefaults = typeof COMPONENT_DEFAULTS;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Helper to get defaults for a specific component
|
|
73
|
+
*/
|
|
74
|
+
export function getComponentDefaults<K extends keyof ComponentDefaults>(componentName: K): ComponentDefaults[K] {
|
|
75
|
+
return COMPONENT_DEFAULTS[componentName];
|
|
76
|
+
}
|
package/core/constants/index.ts
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Constants for VC-Shell Framework
|
|
3
|
+
* Centralized storage for magic numbers and UI-related constants
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const UI_CONSTANTS = {
|
|
7
|
+
// Grid system
|
|
8
|
+
GRID_COLUMNS: 12,
|
|
9
|
+
CELL_HEIGHT: 80,
|
|
10
|
+
WIDGET_GAP: 20,
|
|
11
|
+
|
|
12
|
+
// Timing (milliseconds)
|
|
13
|
+
DEBOUNCE_DEFAULT_MS: 500,
|
|
14
|
+
HOVER_DELAY_MS: 200,
|
|
15
|
+
TOOLTIP_DELAY_MS: 300,
|
|
16
|
+
RESIZE_DEBOUNCE_MS: 100,
|
|
17
|
+
ANIMATION_DURATION_MS: 200,
|
|
18
|
+
TRANSITION_DURATION_MS: 150,
|
|
19
|
+
|
|
20
|
+
// Thresholds
|
|
21
|
+
DRAG_THRESHOLD_PX: 3,
|
|
22
|
+
MAX_COLLISION_ITERATIONS: 50,
|
|
23
|
+
MIN_COLUMN_WIDTH_PX: 15,
|
|
24
|
+
OVERFLOW_THRESHOLD: 100,
|
|
25
|
+
|
|
26
|
+
// Z-index layers
|
|
27
|
+
Z_INDEX: {
|
|
28
|
+
DROPDOWN: 100,
|
|
29
|
+
TOOLTIP: 9999,
|
|
30
|
+
POPUP: 10000,
|
|
31
|
+
MODAL: 10001,
|
|
32
|
+
DRAG: 1000,
|
|
33
|
+
SIDEBAR: 50,
|
|
34
|
+
HEADER: 40,
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Pagination
|
|
38
|
+
PAGINATION_VISIBLE_PAGES: 5,
|
|
39
|
+
PAGINATION_EDGE_PAGES: 3,
|
|
40
|
+
|
|
41
|
+
// Table
|
|
42
|
+
TABLE_ROW_HEIGHT: 48,
|
|
43
|
+
TABLE_HEADER_HEIGHT: 56,
|
|
44
|
+
|
|
45
|
+
// Input
|
|
46
|
+
DEFAULT_MAXLENGTH: 1024,
|
|
47
|
+
DEFAULT_TEXTAREA_ROWS: 3,
|
|
48
|
+
|
|
49
|
+
// Menu
|
|
50
|
+
MENU_COLLAPSED_WIDTH: 76,
|
|
51
|
+
MENU_EXPANDED_WIDTH: 246,
|
|
52
|
+
MENU_ITEM_HEIGHT: 38,
|
|
53
|
+
|
|
54
|
+
// Breakpoints (pixels)
|
|
55
|
+
BREAKPOINTS: {
|
|
56
|
+
XS: 0,
|
|
57
|
+
SM: 576,
|
|
58
|
+
MD: 768,
|
|
59
|
+
LG: 992,
|
|
60
|
+
XL: 1200,
|
|
61
|
+
XXL: 1400,
|
|
62
|
+
},
|
|
63
|
+
} as const;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Type for accessing UI constants values
|
|
67
|
+
*/
|
|
68
|
+
export type UIConstants = typeof UI_CONSTANTS;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import { Router } from "vue-router";
|
|
3
3
|
import { useUserManagement } from "../composables/useUserManagement";
|
|
4
4
|
import { notification } from "../../shared";
|
|
5
|
+
import { createLogger } from "../utilities";
|
|
6
|
+
|
|
7
|
+
const logger = createLogger("interceptors");
|
|
5
8
|
|
|
6
9
|
export function registerInterceptors(router: Router) {
|
|
7
10
|
const { fetch: originalFetch } = window;
|
|
@@ -16,8 +19,8 @@ export function registerInterceptors(router: Router) {
|
|
|
16
19
|
* @returns A promise that resolves to the response from the API call.
|
|
17
20
|
*/
|
|
18
21
|
if (window.__DEMO_MODE__) {
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
logger.warn("CANCELLED FETCH WHILE IN __DEMO_MODE__: ", ...args);
|
|
23
|
+
logger.warn("Please logout and add APP_PLATFORM_URL into .env file of your application to enable API calls");
|
|
21
24
|
return new Promise((resolve: any) => {
|
|
22
25
|
/**
|
|
23
26
|
* This conditions are mocking login, currentuser API calls for demo purposes.
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# AI Agent Plugin for VC-Shell
|
|
2
|
+
|
|
3
|
+
A Vue plugin for integrating an AI assistant panel into VC-Shell applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ENV-based configuration (`APP_AI_AGENT_URL`)
|
|
8
|
+
- Automatic AI button in blade toolbars (via wildcard "*" support)
|
|
9
|
+
- Two operation modes:
|
|
10
|
+
- **List blade** - batch operations with multiple selected items
|
|
11
|
+
- **Details blade** - single object editing with preview
|
|
12
|
+
- Custom suggestions per blade
|
|
13
|
+
- Reactive data binding between blade and agent
|
|
14
|
+
- Simple integration API with minimal boilerplate
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
### 1. Set Environment Variable
|
|
19
|
+
|
|
20
|
+
```env
|
|
21
|
+
APP_AI_AGENT_URL=https://your-ai-agent-url.com
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 2. Install Plugin in main.ts
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createApp } from "vue";
|
|
28
|
+
import { aiAgentPlugin } from "@vc-shell/framework";
|
|
29
|
+
|
|
30
|
+
const app = createApp(App);
|
|
31
|
+
|
|
32
|
+
// Install with options (optional)
|
|
33
|
+
app.use(aiAgentPlugin, {
|
|
34
|
+
config: {
|
|
35
|
+
title: "AI Assistant",
|
|
36
|
+
width: 400,
|
|
37
|
+
},
|
|
38
|
+
addGlobalToolbarButton: true, // default: true
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### List Blade (Batch Operations)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// offers-list.vue
|
|
48
|
+
import { ref, watch } from "vue";
|
|
49
|
+
import { useAiAgentContext } from "@vc-shell/framework";
|
|
50
|
+
|
|
51
|
+
const selectedOffers = ref<IOffer[]>([]);
|
|
52
|
+
|
|
53
|
+
// Connect to AI agent
|
|
54
|
+
useAiAgentContext({ dataRef: selectedOffers });
|
|
55
|
+
|
|
56
|
+
// When table selection changes, pass full objects
|
|
57
|
+
const onSelectionChanged = (items: IOffer[]) => {
|
|
58
|
+
selectedOffers.value = items;
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Details Blade (Single Object)
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// offers-details.vue
|
|
66
|
+
import { ref, watch } from "vue";
|
|
67
|
+
import { useAiAgentContext } from "@vc-shell/framework";
|
|
68
|
+
|
|
69
|
+
const offer = ref<IOffer>({});
|
|
70
|
+
const aiData = ref<IOffer[]>([]); // Always array!
|
|
71
|
+
|
|
72
|
+
// Sync single object to array
|
|
73
|
+
watch(
|
|
74
|
+
offer,
|
|
75
|
+
(val) => {
|
|
76
|
+
aiData.value = val ? [val] : [];
|
|
77
|
+
},
|
|
78
|
+
{ deep: true, immediate: true }
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Connect to AI agent with preview support
|
|
82
|
+
const { previewState } = useAiAgentContext({ dataRef: aiData });
|
|
83
|
+
|
|
84
|
+
// Use previewState.isActive to show preview indicator
|
|
85
|
+
// Use previewState.changedFields to highlight changed fields
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Custom Suggestions
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
useAiAgentContext({
|
|
92
|
+
dataRef: aiData,
|
|
93
|
+
suggestions: [
|
|
94
|
+
{
|
|
95
|
+
id: "translate",
|
|
96
|
+
title: "Translate description",
|
|
97
|
+
icon: "translation",
|
|
98
|
+
iconColor: "#FF4A4A",
|
|
99
|
+
prompt: "Translate the offer description to English",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "seo",
|
|
103
|
+
title: "Optimize SEO",
|
|
104
|
+
icon: "search",
|
|
105
|
+
iconColor: "#57AB79",
|
|
106
|
+
prompt: "Optimize SEO for this offer",
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Manual Panel Control
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { useAiAgent } from "@vc-shell/framework";
|
|
116
|
+
|
|
117
|
+
const { togglePanel, isOpen, openPanel, closePanel } = useAiAgent();
|
|
118
|
+
|
|
119
|
+
// Toggle AI panel
|
|
120
|
+
const handleAiClick = () => togglePanel();
|
|
121
|
+
|
|
122
|
+
// Listen for messages from AI agent
|
|
123
|
+
const { onMessage } = useAiAgent();
|
|
124
|
+
onMessage((message) => {
|
|
125
|
+
if (message.type === "PREVIEW_CHANGES") {
|
|
126
|
+
// Handle preview changes
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## API Reference
|
|
132
|
+
|
|
133
|
+
### aiAgentPlugin
|
|
134
|
+
|
|
135
|
+
Vue plugin for AI agent integration.
|
|
136
|
+
|
|
137
|
+
**Options:**
|
|
138
|
+
|
|
139
|
+
| Option | Type | Default | Description |
|
|
140
|
+
| ----------------------- | ------------------------- | ------- | -------------------------------- |
|
|
141
|
+
| `config` | `Partial<IAiAgentConfig>` | `{}` | AI agent configuration |
|
|
142
|
+
| `addGlobalToolbarButton` | `boolean` | `true` | Add AI button to all toolbars |
|
|
143
|
+
|
|
144
|
+
### useAiAgentContext
|
|
145
|
+
|
|
146
|
+
Composable for binding blade data to AI agent context.
|
|
147
|
+
|
|
148
|
+
**Options:**
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
interface UseAiAgentContextOptions<T = Record<string, unknown>> {
|
|
152
|
+
/**
|
|
153
|
+
* Ref with data - ALWAYS an array:
|
|
154
|
+
* - For DETAILS blade: array with single object [item]
|
|
155
|
+
* - For LIST blade: array of selected objects [item1, item2, ...]
|
|
156
|
+
*/
|
|
157
|
+
dataRef: Ref<T[]>;
|
|
158
|
+
|
|
159
|
+
/** Custom suggestions for this blade */
|
|
160
|
+
suggestions?: ISuggestion[];
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Returns:**
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
interface UseAiAgentContextReturn {
|
|
168
|
+
previewState: {
|
|
169
|
+
isActive: ComputedRef<boolean>;
|
|
170
|
+
changedFields: ComputedRef<string[]>;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### useAiAgent
|
|
176
|
+
|
|
177
|
+
Composable for panel control and communication.
|
|
178
|
+
|
|
179
|
+
**Returns:**
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
interface UseAiAgentReturn {
|
|
183
|
+
panelState: Ref<"closed" | "open" | "expanded">;
|
|
184
|
+
config: Ref<IAiAgentConfig>;
|
|
185
|
+
context: ComputedRef<IAiAgentContext>;
|
|
186
|
+
isOpen: ComputedRef<boolean>;
|
|
187
|
+
isExpanded: ComputedRef<boolean>;
|
|
188
|
+
totalItemsCount: ComputedRef<number>;
|
|
189
|
+
openPanel: () => void;
|
|
190
|
+
closePanel: () => void;
|
|
191
|
+
togglePanel: () => void;
|
|
192
|
+
expandPanel: () => void;
|
|
193
|
+
collapsePanel: () => void;
|
|
194
|
+
setConfig: (config: Partial<IAiAgentConfig>) => void;
|
|
195
|
+
sendMessage: (type: AiAgentMessageType, payload: unknown) => void;
|
|
196
|
+
onMessage: (handler: (event: IAiAgentMessage) => void) => () => void;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### ISuggestion
|
|
201
|
+
|
|
202
|
+
Custom suggestion card interface.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
interface ISuggestion {
|
|
206
|
+
id: string;
|
|
207
|
+
title: string;
|
|
208
|
+
icon: string;
|
|
209
|
+
iconColor?: string;
|
|
210
|
+
prompt: string;
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## PostMessage Protocol
|
|
215
|
+
|
|
216
|
+
### Shell -> Agent
|
|
217
|
+
|
|
218
|
+
**INIT_CONTEXT** (on panel open)
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
{
|
|
222
|
+
type: "INIT_CONTEXT",
|
|
223
|
+
payload: {
|
|
224
|
+
userId: string,
|
|
225
|
+
locale: string,
|
|
226
|
+
blade: { id, name, title, param },
|
|
227
|
+
items: Record<string, unknown>[], // Always array
|
|
228
|
+
suggestions?: ISuggestion[],
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**UPDATE_CONTEXT** (on changes)
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
{
|
|
237
|
+
type: "UPDATE_CONTEXT",
|
|
238
|
+
payload: {
|
|
239
|
+
blade: { id, name, title, param },
|
|
240
|
+
items: Record<string, unknown>[], // Always array of full objects
|
|
241
|
+
suggestions?: ISuggestion[],
|
|
242
|
+
locale?: string,
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Agent -> Shell
|
|
248
|
+
|
|
249
|
+
**PREVIEW_CHANGES** (form preview)
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
{
|
|
253
|
+
type: "PREVIEW_CHANGES",
|
|
254
|
+
payload: {
|
|
255
|
+
data: Record<string, unknown>,
|
|
256
|
+
changedFields?: string[],
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**RELOAD_BLADE** (after save)
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
{
|
|
265
|
+
type: "RELOAD_BLADE",
|
|
266
|
+
payload: { clearSelection?: boolean }
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**DOWNLOAD_FILE** (file download)
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
{
|
|
274
|
+
type: "DOWNLOAD_FILE",
|
|
275
|
+
payload: {
|
|
276
|
+
filename: string,
|
|
277
|
+
contentType: string,
|
|
278
|
+
content: string // base64
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**NAVIGATE_TO_APP** (navigation)
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
{
|
|
287
|
+
type: "NAVIGATE_TO_APP",
|
|
288
|
+
payload: { bladeName, param?, options? }
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Architecture
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
Shell (VcApp) Agent (iframe)
|
|
296
|
+
│ │
|
|
297
|
+
│────── INIT_CONTEXT ─────────────────>│
|
|
298
|
+
│ (userId, locale, blade, items) │
|
|
299
|
+
│ │
|
|
300
|
+
│<───── CHAT_READY ────────────────────│
|
|
301
|
+
│ │
|
|
302
|
+
│────── UPDATE_CONTEXT ───────────────>│
|
|
303
|
+
│ (blade, items, suggestions) │
|
|
304
|
+
│ │
|
|
305
|
+
│<───── PREVIEW_CHANGES ───────────────│
|
|
306
|
+
│ (updates form in shell) │
|
|
307
|
+
│ │
|
|
308
|
+
│<───── RELOAD_BLADE ──────────────────│
|
|
309
|
+
│ (refreshes current blade) │
|
|
310
|
+
│ │
|
|
311
|
+
│<───── DOWNLOAD_FILE ─────────────────│
|
|
312
|
+
│ (triggers file download) │
|
|
313
|
+
└───────────────────────────────────────┘
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## File Structure
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
framework/core/plugins/ai-agent/
|
|
320
|
+
├── index.ts # Plugin entry point
|
|
321
|
+
├── types.ts # TypeScript interfaces
|
|
322
|
+
├── constants.ts # Default values
|
|
323
|
+
├── README.md # This file
|
|
324
|
+
├── services/
|
|
325
|
+
│ └── ai-agent-service.ts # Panel state, postMessage
|
|
326
|
+
├── composables/
|
|
327
|
+
│ ├── index.ts
|
|
328
|
+
│ ├── useAiAgent.ts # Panel control
|
|
329
|
+
│ └── useAiAgentContext.ts # Data binding + preview
|
|
330
|
+
└── components/
|
|
331
|
+
├── index.ts
|
|
332
|
+
├── VcAiAgentPanel.vue # Main panel
|
|
333
|
+
└── _internal/
|
|
334
|
+
├── VcAiAgentHeader.vue
|
|
335
|
+
└── VcAiAgentIframe.vue
|
|
336
|
+
```
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Transition name="ai-panel-slide">
|
|
3
|
+
<div
|
|
4
|
+
v-if="isOpen"
|
|
5
|
+
class="vc-ai-agent-panel"
|
|
6
|
+
:class="{
|
|
7
|
+
'vc-ai-agent-panel--expanded': isExpanded,
|
|
8
|
+
}"
|
|
9
|
+
:style="panelStyle"
|
|
10
|
+
>
|
|
11
|
+
<VcAiAgentHeader
|
|
12
|
+
:title="config.title"
|
|
13
|
+
:is-expanded="isExpanded"
|
|
14
|
+
:items-count="totalItemsCount"
|
|
15
|
+
@close="closePanel"
|
|
16
|
+
@expand="expandPanel"
|
|
17
|
+
@collapse="collapsePanel"
|
|
18
|
+
/>
|
|
19
|
+
|
|
20
|
+
<div class="vc-ai-agent-panel__content">
|
|
21
|
+
<VcAiAgentIframe
|
|
22
|
+
:url="config.url"
|
|
23
|
+
@iframe-ready="onIframeReady"
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</Transition>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts" setup>
|
|
31
|
+
import { computed, onUnmounted, inject } from "vue";
|
|
32
|
+
import { AiAgentServiceKey } from "../../../../injection-keys";
|
|
33
|
+
import type { IAiAgentServiceInternal } from "../services/ai-agent-service";
|
|
34
|
+
import VcAiAgentHeader from "./_internal/VcAiAgentHeader.vue";
|
|
35
|
+
import VcAiAgentIframe from "./_internal/VcAiAgentIframe.vue";
|
|
36
|
+
|
|
37
|
+
// Inject AI agent service
|
|
38
|
+
const aiAgentService = inject(AiAgentServiceKey) as IAiAgentServiceInternal | undefined;
|
|
39
|
+
|
|
40
|
+
if (!aiAgentService) {
|
|
41
|
+
console.error("[VcAiAgentPanel] AiAgentService not provided");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Destructure service properties
|
|
45
|
+
const config = computed(
|
|
46
|
+
() => aiAgentService?.config.value ?? { url: "", title: "AI Assistant", width: 360, expandedWidth: 500 },
|
|
47
|
+
);
|
|
48
|
+
const isOpen = computed(() => aiAgentService?.isOpen.value ?? false);
|
|
49
|
+
const isExpanded = computed(() => aiAgentService?.isExpanded.value ?? false);
|
|
50
|
+
const totalItemsCount = computed(() => aiAgentService?.totalItemsCount.value ?? 0);
|
|
51
|
+
|
|
52
|
+
// Panel style with dynamic width
|
|
53
|
+
const panelStyle = computed(() => ({
|
|
54
|
+
width: isExpanded.value ? "50%" : `${config.value.width ?? 350}px`,
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
// Panel control methods
|
|
58
|
+
const closePanel = () => aiAgentService?.closePanel();
|
|
59
|
+
const expandPanel = () => aiAgentService?.expandPanel();
|
|
60
|
+
const collapsePanel = () => aiAgentService?.collapsePanel();
|
|
61
|
+
|
|
62
|
+
// Handle iframe ready event
|
|
63
|
+
const onIframeReady = (iframe: HTMLIFrameElement) => {
|
|
64
|
+
aiAgentService?._setIframeRef(iframe);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Clean up iframe ref on unmount
|
|
68
|
+
onUnmounted(() => {
|
|
69
|
+
aiAgentService?._setIframeRef(null);
|
|
70
|
+
});
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<style lang="scss">
|
|
74
|
+
:root {
|
|
75
|
+
--ai-panel-bg: var(--additional-50);
|
|
76
|
+
--ai-panel-border-color: var(--neutrals-200);
|
|
77
|
+
--ai-panel-shadow: -4px 0 12px rgba(0, 0, 0, 0.08);
|
|
78
|
+
--ai-panel-header-bg: var(--primary-50);
|
|
79
|
+
--ai-panel-header-border: var(--neutrals-200);
|
|
80
|
+
--ai-panel-icon-color: var(--primary-500);
|
|
81
|
+
--ai-panel-title-color: var(--secondary-950);
|
|
82
|
+
--ai-panel-badge-bg: var(--primary-100);
|
|
83
|
+
--ai-panel-badge-color: var(--primary-700);
|
|
84
|
+
--ai-panel-button-color: var(--neutrals-600);
|
|
85
|
+
--ai-panel-button-hover-bg: var(--neutrals-100);
|
|
86
|
+
--ai-panel-button-hover-color: var(--neutrals-900);
|
|
87
|
+
--ai-panel-iframe-bg: var(--additional-50);
|
|
88
|
+
--ai-panel-placeholder-bg: var(--neutrals-50);
|
|
89
|
+
--ai-panel-placeholder-icon-color: var(--neutrals-300);
|
|
90
|
+
--ai-panel-placeholder-text-color: var(--neutrals-500);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Slide transition for panel
|
|
94
|
+
.ai-panel-slide-enter-active,
|
|
95
|
+
.ai-panel-slide-leave-active {
|
|
96
|
+
transition: transform var(--app-panel-transition-duration, 0.3s)
|
|
97
|
+
var(--app-panel-transition-timing, cubic-bezier(0.4, 0, 0.2, 1));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.ai-panel-slide-enter-from,
|
|
101
|
+
.ai-panel-slide-leave-to {
|
|
102
|
+
transform: translateX(100%);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.vc-ai-agent-panel {
|
|
106
|
+
@apply tw-flex tw-flex-col tw-h-full tw-shrink-0;
|
|
107
|
+
background-color: var(--ai-panel-bg);
|
|
108
|
+
box-shadow: var(--ai-panel-shadow);
|
|
109
|
+
// Width transition for expand/collapse
|
|
110
|
+
transition: width var(--app-panel-transition-duration, 0.3s)
|
|
111
|
+
var(--app-panel-transition-timing, cubic-bezier(0.4, 0, 0.2, 1));
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
border-width: 1px;
|
|
114
|
+
border-style: solid;
|
|
115
|
+
border-color: var(--ai-panel-border-color);
|
|
116
|
+
|
|
117
|
+
&--expanded {
|
|
118
|
+
// Additional expanded styles if needed
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
&__content {
|
|
122
|
+
@apply tw-flex-1 tw-overflow-hidden tw-flex tw-flex-col tw-pt-3;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
</style>
|