@vc-shell/framework 2.0.1 → 2.0.3-pr222.ba0d3c5
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 +14 -0
- package/dist/ai-agent/index.js +2 -2
- package/dist/chunks/{VcAiAgentPanel.vue_vue_type_style_index_0_lang-D0kWIlz3.js → VcAiAgentPanel.vue_vue_type_style_index_0_lang-Bgkc3--0.js} +40 -40
- package/dist/chunks/{VcAiAgentPanel.vue_vue_type_style_index_0_lang-D0kWIlz3.js.map → VcAiAgentPanel.vue_vue_type_style_index_0_lang-Bgkc3--0.js.map} +1 -1
- package/dist/chunks/{VcTableAdapter.vue_vue_type_style_index_0_lang-Dh7DDZB9.js → VcTableAdapter.vue_vue_type_style_index_0_lang-Df8FWaeV.js} +5446 -5441
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-Df8FWaeV.js.map +1 -0
- package/dist/chunks/{index-CDUdOax4.js → index-BXwiMzC3.js} +1 -1
- package/dist/chunks/{index-CDUdOax4.js.map → index-BXwiMzC3.js.map} +1 -1
- package/dist/framework.js +1698 -1653
- package/dist/framework.js.map +1 -1
- package/dist/index.css +2 -2
- package/dist/injection-keys.d.ts +5 -0
- package/dist/injection-keys.d.ts.map +1 -1
- package/dist/shell/_internal/popup/common/vc-popup-base.vue.d.ts.map +1 -1
- package/dist/shell/dashboard/draggable-dashboard/DashboardWidgetSkeleton.vue.d.ts +4 -0
- package/dist/shell/dashboard/draggable-dashboard/DashboardWidgetSkeleton.vue.d.ts.map +1 -0
- package/dist/shell/dashboard/draggable-dashboard/GridstackDashboard.vue.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-field/vc-field.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/_internal/vc-table-base-header/vc-table-base-header.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableCellRenderer.vue.d.ts +2 -0
- package/dist/ui/components/organisms/vc-data-table/components/DataTableCellRenderer.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableRow.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
- package/dist/ui/index.js +2 -2
- package/package.json +4 -4
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-Dh7DDZB9.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inject as A, computed as g, ref as y, watch as R, onUnmounted as I } from "vue";
|
|
2
|
-
import { b as S, B as j, d as C, D as T, A as F } from "./VcAiAgentPanel.vue_vue_type_style_index_0_lang-
|
|
2
|
+
import { b as S, B as j, d as C, D as T, A as F } from "./VcAiAgentPanel.vue_vue_type_style_index_0_lang-Bgkc3--0.js";
|
|
3
3
|
import { m as N, i as m } from "./vendor-lodash-es-CfnUOh0o.js";
|
|
4
4
|
function E(t, r) {
|
|
5
5
|
return N({}, t, r, (i, a) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-CDUdOax4.js","sources":["../../core/plugins/ai-agent/utils/deep-merge-changes.ts","../../core/plugins/ai-agent/composables/useAiAgentContext.ts","../../core/plugins/ai-agent/index.ts"],"sourcesContent":["import { mergeWith, isPlainObject } from \"lodash-es\";\n\n/**\n * Custom merge function for AI agent preview changes.\n * Handles sparse arrays where null means \"skip this index\".\n *\n * @example\n * // Nested objects - deep merge\n * deepMergeChanges({seo: {title: \"Old\", desc: \"Desc\"}}, {seo: {title: \"New\"}})\n * // -> {seo: {title: \"New\", desc: \"Desc\"}}\n *\n * @example\n * // Sparse arrays - null skips index\n * deepMergeChanges({items: [{a:1}, {b:2}]}, {items: [null, {c:3}]})\n * // -> {items: [{a:1}, {b:2, c:3}]}\n */\nexport function deepMergeChanges<T extends object>(target: T, source: object): T {\n const customizer = (targetVal: unknown, sourceVal: unknown): unknown => {\n // If source value is null/undefined, keep target value (skip this index/field)\n if (sourceVal === null || sourceVal === undefined) {\n return targetVal;\n }\n\n // If both are arrays, merge by index with sparse array support\n if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {\n const result = [...targetVal];\n sourceVal.forEach((item, index) => {\n if (item !== null && item !== undefined) {\n if (isPlainObject(item) && isPlainObject(result[index])) {\n // Recursively merge objects in array\n result[index] = deepMergeChanges(result[index] as object, item);\n } else {\n // Replace primitive or non-object values\n result[index] = item;\n }\n }\n // null/undefined in source array = skip this index\n });\n return result;\n }\n\n // For objects, let mergeWith handle recursively with this customizer\n return undefined;\n };\n\n return mergeWith({}, target, source, customizer);\n}\n","import { inject, ref, computed, watch, onUnmounted, type Ref } from \"vue\";\nimport { AiAgentServiceKey } from \"@framework/injection-keys\";\nimport { BladeDescriptorKey } from \"@core/blade-navigation/types\";\nimport { deepMergeChanges } from \"@core/plugins/ai-agent/utils/deep-merge-changes\";\nimport type { IAiAgentServiceInternal } from \"@core/plugins/ai-agent/services/ai-agent-service\";\nimport type {\n UseAiAgentContextOptions,\n UseAiAgentContextReturn,\n IPreviewChangesPayload,\n AiAgentContextType,\n} from \"@core/plugins/ai-agent/types\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-ai-agent-context\");\n\n/**\n * Checks if the ref value is an array\n */\nfunction isArrayRef<T>(dataRef: Ref<T> | Ref<T[]>): dataRef is Ref<T[]> {\n return Array.isArray(dataRef.value);\n}\n\n/**\n * Normalizes any ref value to an array for sending to the AI agent\n */\nfunction normalizeToArray<T>(value: T | T[]): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\n/**\n * Gets the target object for applying changes based on ref type\n */\nfunction getTargetForChanges<T>(dataRef: Ref<T> | Ref<T[]>): T | undefined {\n if (isArrayRef(dataRef)) {\n // Array ref - return first item\n return dataRef.value[0];\n }\n // Single object ref - return the object directly\n return dataRef.value;\n}\n\n/**\n * Composable for binding blade data to AI agent context.\n *\n * This composable automatically:\n * - Sends data updates to the AI agent when dataRef changes\n * - Normalizes single objects to arrays for the AI agent\n * - Handles PREVIEW_CHANGES messages to update form data\n * - Provides preview state for visual feedback\n *\n * @example List blade (array of selected items)\n * ```typescript\n * const { selectedItems } = useTableSelection<Offer>();\n *\n * useAiAgentContext({ dataRef: selectedItems });\n * ```\n *\n * @example Details blade (single object - automatically wrapped in array)\n * ```typescript\n * const offer = ref<Offer>({});\n *\n * // Just pass the ref directly - no need to wrap in array!\n * const { previewState } = useAiAgentContext({ dataRef: offer });\n *\n * // Use previewState.isActive to show preview indicator\n * ```\n *\n * @example With custom suggestions\n * ```typescript\n * useAiAgentContext({\n * dataRef: offer,\n * suggestions: [\n * {\n * id: \"translate\",\n * title: \"Translate description\",\n * icon: \"translation\",\n * iconColor: \"#FF4A4A\",\n * prompt: \"Translate the offer description to English\"\n * },\n * ],\n * });\n * ```\n */\nexport function useAiAgentContext<\n T extends {\n id: string | undefined;\n objectType: string | undefined;\n name?: string | undefined;\n [key: string]: unknown;\n },\n>(options: UseAiAgentContextOptions<T>): UseAiAgentContextReturn {\n const { dataRef, suggestions } = options;\n\n // Try to get the service (may not be available if plugin not installed)\n const service = inject(AiAgentServiceKey) as IAiAgentServiceInternal | undefined;\n\n // Get current blade descriptor to identify which blade this context belongs to\n const bladeDescriptor = inject(BladeDescriptorKey, null);\n const bladeId = computed(() => bladeDescriptor?.value?.id);\n\n // Preview state\n const isPreviewActive = ref(false);\n const changedFieldsList = ref<string[]>([]);\n\n // If service is not available, return dummy preview state\n if (!service) {\n logger.debug(\"AiAgentService not available, context binding disabled\");\n return {\n previewState: {\n isActive: computed(() => false),\n changedFields: computed(() => []),\n },\n clearPreview: () => {},\n };\n }\n\n // Determine context type based on dataRef type\n // Array ref = list blade (multiple selected items)\n // Single object ref = details blade (single item being edited)\n const detectedContextType: AiAgentContextType = isArrayRef(dataRef) ? \"list\" : \"details\";\n\n // Set context data in service (items, contextType, and suggestions)\n // Always sends an array to the service, normalizing single objects\n // Context is bound to specific blade ID\n const updateContextData = () => {\n const raw = normalizeToArray(dataRef.value);\n const items =\n detectedContextType === \"details\"\n ? raw.map((item) => ({ ...item }))\n : raw.map((item) => ({ id: item.id, objectType: item.objectType, name: item.name }));\n service._setContextData(items, detectedContextType, suggestions, bladeId.value);\n logger.debug(`Context updated: ${items.length} items, type: ${detectedContextType}, blade: ${bladeId.value}`);\n };\n\n // Log that the handler is being registered\n logger.debug(\"Registering PREVIEW_CHANGES handler for blade:\", bladeId.value);\n\n // Watch dataRef for changes and update context\n const stopWatch = watch(\n dataRef,\n () => {\n updateContextData();\n // Clear preview state when data changes from outside\n if (isPreviewActive.value) {\n isPreviewActive.value = false;\n changedFieldsList.value = [];\n }\n },\n { deep: true, immediate: true },\n );\n\n // Handle PREVIEW_CHANGES messages\n // Applies changes to the target object (single ref or first item in array)\n const unsubscribe = service._onPreviewChanges((payload: IPreviewChangesPayload) => {\n logger.debug(\"PREVIEW_CHANGES handler called\", {\n bladeId: bladeId.value,\n payloadKeys: Object.keys(payload.data || {}),\n changedFields: payload.changedFields,\n hasDataRef: !!dataRef,\n dataRefValue: dataRef?.value ? \"present\" : \"empty\",\n });\n\n const target = getTargetForChanges(dataRef);\n if (!target) {\n logger.warn(\"Cannot apply preview changes: no data in dataRef\", {\n bladeId: bladeId.value,\n dataRefValue: dataRef?.value,\n });\n return;\n }\n\n const targetObj = target as Record<string, unknown>;\n const updatedData = payload.data;\n\n logger.debug(\"Applying preview changes\", {\n bladeId: bladeId.value,\n targetObjKeys: Object.keys(targetObj),\n updatedDataKeys: Object.keys(updatedData),\n updatedDataPreview: JSON.stringify(updatedData).substring(0, 500),\n });\n\n // Deep merge changes into target object\n // Supports:\n // - Nested objects: {\"seo\": {\"metaTitle\": \"New\"}} merges into existing seo\n // - Sparse arrays: [null, {\"price\": 50}] updates index 1 only (null = skip)\n const mergedResult = deepMergeChanges(targetObj, updatedData);\n\n // Copy merged result back to target object (to trigger Vue reactivity)\n Object.keys(mergedResult).forEach((key) => {\n targetObj[key] = mergedResult[key as keyof typeof mergedResult];\n });\n\n logger.debug(\"Deep merge completed\", {\n bladeId: bladeId.value,\n resultPreview: JSON.stringify(targetObj).substring(0, 500),\n });\n\n // Update preview state\n isPreviewActive.value = true;\n changedFieldsList.value = payload.changedFields || Object.keys(updatedData);\n\n logger.debug(\"Preview changes applied successfully\", {\n bladeId: bladeId.value,\n changedFields: changedFieldsList.value,\n isPreviewActive: isPreviewActive.value,\n targetObjAfter: JSON.stringify(targetObj).substring(0, 500),\n });\n });\n\n // Cleanup on unmount\n onUnmounted(() => {\n stopWatch();\n unsubscribe();\n // Clear context for this specific blade when component unmounts\n service._setContextData([], \"list\", undefined, bladeId.value);\n logger.debug(`Context cleared on unmount for blade: ${bladeId.value}`);\n });\n\n return {\n previewState: {\n isActive: computed(() => isPreviewActive.value),\n changedFields: computed(() => changedFieldsList.value),\n },\n clearPreview: () => {\n isPreviewActive.value = false;\n changedFieldsList.value = [];\n logger.debug(\"Preview state cleared manually\");\n },\n };\n}\n\n/**\n * @deprecated Use the `clearPreview()` method returned by useAiAgentContext() instead.\n */\nexport function clearPreviewState(_previewState: UseAiAgentContextReturn[\"previewState\"]): void {\n console.warn(\n \"[ai-agent] clearPreviewState() is deprecated. Use clearPreview() from useAiAgentContext() return value instead.\",\n );\n}\n","import type { App } from \"vue\";\r\nimport type { IAiAgentConfig } from \"@core/plugins/ai-agent/types\";\r\nimport { DEFAULT_AI_AGENT_CONFIG, AI_AGENT_URL_ENV_KEY } from \"@core/plugins/ai-agent/constants\";\r\nimport { createLogger } from \"@core/utilities\";\r\n\r\nconst logger = createLogger(\"ai-agent-plugin\");\r\n\r\n/**\r\n * Options for the AI Agent Plugin\r\n */\r\nexport interface AiAgentPluginOptions {\r\n /**\r\n * AI Agent configuration.\r\n * URL can also be set via APP_AI_AGENT_URL environment variable.\r\n */\r\n config?: Partial<IAiAgentConfig>;\r\n\r\n /**\r\n * Whether to add the AI button to all blade toolbars automatically.\r\n * Default: true\r\n */\r\n addGlobalToolbarButton?: boolean;\r\n}\r\n\r\n/**\r\n * Vue plugin for AI Agent integration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { createApp } from \"vue\";\r\n * import { aiAgentPlugin } from \"@vc-shell/framework\";\r\n *\r\n * const app = createApp(App);\r\n *\r\n * // Install with options\r\n * app.use(aiAgentPlugin, {\r\n * config: {\r\n * title: \"AI Assistant\",\r\n * width: 400,\r\n * },\r\n * addGlobalToolbarButton: true,\r\n * });\r\n * ```\r\n */\r\nexport const aiAgentPlugin = {\r\n install(app: App, options: AiAgentPluginOptions = {}) {\r\n const { config = {}, addGlobalToolbarButton = true } = options;\r\n\r\n // Get URL from environment variable if not provided\r\n let url = config.url || \"\";\r\n if (!url && typeof import.meta !== \"undefined\" && import.meta.env) {\r\n url = import.meta.env[AI_AGENT_URL_ENV_KEY] || \"\";\r\n }\r\n\r\n // Skip installation if no URL configured\r\n if (!url) {\r\n logger.info(\r\n \"AI Agent plugin skipped: no URL configured. Set APP_AI_AGENT_URL env variable or pass config.url option.\",\r\n );\r\n return;\r\n }\r\n\r\n // Merge config with defaults\r\n const finalConfig: IAiAgentConfig = {\r\n ...DEFAULT_AI_AGENT_CONFIG,\r\n ...config,\r\n url,\r\n };\r\n\r\n // Store config in app global properties for access during service creation\r\n app.config.globalProperties.$aiAgentConfig = finalConfig;\r\n app.provide(\"aiAgentConfig\", finalConfig);\r\n app.provide(\"aiAgentAddGlobalToolbarButton\", addGlobalToolbarButton);\r\n\r\n logger.info(`AI Agent plugin installed. URL: ${url}, addGlobalToolbarButton: ${addGlobalToolbarButton}`);\r\n },\r\n};\r\n\r\n// Re-export all types\r\nexport * from \"@core/plugins/ai-agent/types\";\r\nexport * from \"@core/plugins/ai-agent/constants\";\r\n\r\n// Re-export composables\r\nexport {\r\n useAiAgent,\r\n provideAiAgentService,\r\n createAiAgentToolbarButton,\r\n} from \"@core/plugins/ai-agent/composables/useAiAgent\";\r\nexport type { UseAiAgentReturn, ProvideAiAgentServiceOptions } from \"@core/plugins/ai-agent/composables/useAiAgent\";\r\n\r\nexport { useAiAgentContext, clearPreviewState } from \"@core/plugins/ai-agent/composables/useAiAgentContext\";\r\n\r\n// Re-export components\r\nexport { VcAiAgentPanel } from \"@core/plugins/ai-agent/components\";\r\n\r\n// Re-export service types\r\nexport type {\r\n IAiAgentServiceInternal,\r\n CreateAiAgentServiceOptions,\r\n} from \"@core/plugins/ai-agent/services/ai-agent-service\";\r\n"],"names":["deepMergeChanges","target","source","mergeWith","targetVal","sourceVal","result","item","index","isPlainObject","logger","createLogger","isArrayRef","dataRef","normalizeToArray","value","getTargetForChanges","useAiAgentContext","options","suggestions","service","inject","AiAgentServiceKey","bladeDescriptor","BladeDescriptorKey","bladeId","computed","isPreviewActive","ref","changedFieldsList","detectedContextType","updateContextData","raw","items","stopWatch","watch","unsubscribe","payload","targetObj","updatedData","mergedResult","key","onUnmounted","aiAgentPlugin","app","config","addGlobalToolbarButton","url","__vite_import_meta_env__","AI_AGENT_URL_ENV_KEY","finalConfig","DEFAULT_AI_AGENT_CONFIG"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-BXwiMzC3.js","sources":["../../core/plugins/ai-agent/utils/deep-merge-changes.ts","../../core/plugins/ai-agent/composables/useAiAgentContext.ts","../../core/plugins/ai-agent/index.ts"],"sourcesContent":["import { mergeWith, isPlainObject } from \"lodash-es\";\n\n/**\n * Custom merge function for AI agent preview changes.\n * Handles sparse arrays where null means \"skip this index\".\n *\n * @example\n * // Nested objects - deep merge\n * deepMergeChanges({seo: {title: \"Old\", desc: \"Desc\"}}, {seo: {title: \"New\"}})\n * // -> {seo: {title: \"New\", desc: \"Desc\"}}\n *\n * @example\n * // Sparse arrays - null skips index\n * deepMergeChanges({items: [{a:1}, {b:2}]}, {items: [null, {c:3}]})\n * // -> {items: [{a:1}, {b:2, c:3}]}\n */\nexport function deepMergeChanges<T extends object>(target: T, source: object): T {\n const customizer = (targetVal: unknown, sourceVal: unknown): unknown => {\n // If source value is null/undefined, keep target value (skip this index/field)\n if (sourceVal === null || sourceVal === undefined) {\n return targetVal;\n }\n\n // If both are arrays, merge by index with sparse array support\n if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {\n const result = [...targetVal];\n sourceVal.forEach((item, index) => {\n if (item !== null && item !== undefined) {\n if (isPlainObject(item) && isPlainObject(result[index])) {\n // Recursively merge objects in array\n result[index] = deepMergeChanges(result[index] as object, item);\n } else {\n // Replace primitive or non-object values\n result[index] = item;\n }\n }\n // null/undefined in source array = skip this index\n });\n return result;\n }\n\n // For objects, let mergeWith handle recursively with this customizer\n return undefined;\n };\n\n return mergeWith({}, target, source, customizer);\n}\n","import { inject, ref, computed, watch, onUnmounted, type Ref } from \"vue\";\nimport { AiAgentServiceKey } from \"@framework/injection-keys\";\nimport { BladeDescriptorKey } from \"@core/blade-navigation/types\";\nimport { deepMergeChanges } from \"@core/plugins/ai-agent/utils/deep-merge-changes\";\nimport type { IAiAgentServiceInternal } from \"@core/plugins/ai-agent/services/ai-agent-service\";\nimport type {\n UseAiAgentContextOptions,\n UseAiAgentContextReturn,\n IPreviewChangesPayload,\n AiAgentContextType,\n} from \"@core/plugins/ai-agent/types\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-ai-agent-context\");\n\n/**\n * Checks if the ref value is an array\n */\nfunction isArrayRef<T>(dataRef: Ref<T> | Ref<T[]>): dataRef is Ref<T[]> {\n return Array.isArray(dataRef.value);\n}\n\n/**\n * Normalizes any ref value to an array for sending to the AI agent\n */\nfunction normalizeToArray<T>(value: T | T[]): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\n/**\n * Gets the target object for applying changes based on ref type\n */\nfunction getTargetForChanges<T>(dataRef: Ref<T> | Ref<T[]>): T | undefined {\n if (isArrayRef(dataRef)) {\n // Array ref - return first item\n return dataRef.value[0];\n }\n // Single object ref - return the object directly\n return dataRef.value;\n}\n\n/**\n * Composable for binding blade data to AI agent context.\n *\n * This composable automatically:\n * - Sends data updates to the AI agent when dataRef changes\n * - Normalizes single objects to arrays for the AI agent\n * - Handles PREVIEW_CHANGES messages to update form data\n * - Provides preview state for visual feedback\n *\n * @example List blade (array of selected items)\n * ```typescript\n * const { selectedItems } = useTableSelection<Offer>();\n *\n * useAiAgentContext({ dataRef: selectedItems });\n * ```\n *\n * @example Details blade (single object - automatically wrapped in array)\n * ```typescript\n * const offer = ref<Offer>({});\n *\n * // Just pass the ref directly - no need to wrap in array!\n * const { previewState } = useAiAgentContext({ dataRef: offer });\n *\n * // Use previewState.isActive to show preview indicator\n * ```\n *\n * @example With custom suggestions\n * ```typescript\n * useAiAgentContext({\n * dataRef: offer,\n * suggestions: [\n * {\n * id: \"translate\",\n * title: \"Translate description\",\n * icon: \"translation\",\n * iconColor: \"#FF4A4A\",\n * prompt: \"Translate the offer description to English\"\n * },\n * ],\n * });\n * ```\n */\nexport function useAiAgentContext<\n T extends {\n id: string | undefined;\n objectType: string | undefined;\n name?: string | undefined;\n [key: string]: unknown;\n },\n>(options: UseAiAgentContextOptions<T>): UseAiAgentContextReturn {\n const { dataRef, suggestions } = options;\n\n // Try to get the service (may not be available if plugin not installed)\n const service = inject(AiAgentServiceKey) as IAiAgentServiceInternal | undefined;\n\n // Get current blade descriptor to identify which blade this context belongs to\n const bladeDescriptor = inject(BladeDescriptorKey, null);\n const bladeId = computed(() => bladeDescriptor?.value?.id);\n\n // Preview state\n const isPreviewActive = ref(false);\n const changedFieldsList = ref<string[]>([]);\n\n // If service is not available, return dummy preview state\n if (!service) {\n logger.debug(\"AiAgentService not available, context binding disabled\");\n return {\n previewState: {\n isActive: computed(() => false),\n changedFields: computed(() => []),\n },\n clearPreview: () => {},\n };\n }\n\n // Determine context type based on dataRef type\n // Array ref = list blade (multiple selected items)\n // Single object ref = details blade (single item being edited)\n const detectedContextType: AiAgentContextType = isArrayRef(dataRef) ? \"list\" : \"details\";\n\n // Set context data in service (items, contextType, and suggestions)\n // Always sends an array to the service, normalizing single objects\n // Context is bound to specific blade ID\n const updateContextData = () => {\n const raw = normalizeToArray(dataRef.value);\n const items =\n detectedContextType === \"details\"\n ? raw.map((item) => ({ ...item }))\n : raw.map((item) => ({ id: item.id, objectType: item.objectType, name: item.name }));\n service._setContextData(items, detectedContextType, suggestions, bladeId.value);\n logger.debug(`Context updated: ${items.length} items, type: ${detectedContextType}, blade: ${bladeId.value}`);\n };\n\n // Log that the handler is being registered\n logger.debug(\"Registering PREVIEW_CHANGES handler for blade:\", bladeId.value);\n\n // Watch dataRef for changes and update context\n const stopWatch = watch(\n dataRef,\n () => {\n updateContextData();\n // Clear preview state when data changes from outside\n if (isPreviewActive.value) {\n isPreviewActive.value = false;\n changedFieldsList.value = [];\n }\n },\n { deep: true, immediate: true },\n );\n\n // Handle PREVIEW_CHANGES messages\n // Applies changes to the target object (single ref or first item in array)\n const unsubscribe = service._onPreviewChanges((payload: IPreviewChangesPayload) => {\n logger.debug(\"PREVIEW_CHANGES handler called\", {\n bladeId: bladeId.value,\n payloadKeys: Object.keys(payload.data || {}),\n changedFields: payload.changedFields,\n hasDataRef: !!dataRef,\n dataRefValue: dataRef?.value ? \"present\" : \"empty\",\n });\n\n const target = getTargetForChanges(dataRef);\n if (!target) {\n logger.warn(\"Cannot apply preview changes: no data in dataRef\", {\n bladeId: bladeId.value,\n dataRefValue: dataRef?.value,\n });\n return;\n }\n\n const targetObj = target as Record<string, unknown>;\n const updatedData = payload.data;\n\n logger.debug(\"Applying preview changes\", {\n bladeId: bladeId.value,\n targetObjKeys: Object.keys(targetObj),\n updatedDataKeys: Object.keys(updatedData),\n updatedDataPreview: JSON.stringify(updatedData).substring(0, 500),\n });\n\n // Deep merge changes into target object\n // Supports:\n // - Nested objects: {\"seo\": {\"metaTitle\": \"New\"}} merges into existing seo\n // - Sparse arrays: [null, {\"price\": 50}] updates index 1 only (null = skip)\n const mergedResult = deepMergeChanges(targetObj, updatedData);\n\n // Copy merged result back to target object (to trigger Vue reactivity)\n Object.keys(mergedResult).forEach((key) => {\n targetObj[key] = mergedResult[key as keyof typeof mergedResult];\n });\n\n logger.debug(\"Deep merge completed\", {\n bladeId: bladeId.value,\n resultPreview: JSON.stringify(targetObj).substring(0, 500),\n });\n\n // Update preview state\n isPreviewActive.value = true;\n changedFieldsList.value = payload.changedFields || Object.keys(updatedData);\n\n logger.debug(\"Preview changes applied successfully\", {\n bladeId: bladeId.value,\n changedFields: changedFieldsList.value,\n isPreviewActive: isPreviewActive.value,\n targetObjAfter: JSON.stringify(targetObj).substring(0, 500),\n });\n });\n\n // Cleanup on unmount\n onUnmounted(() => {\n stopWatch();\n unsubscribe();\n // Clear context for this specific blade when component unmounts\n service._setContextData([], \"list\", undefined, bladeId.value);\n logger.debug(`Context cleared on unmount for blade: ${bladeId.value}`);\n });\n\n return {\n previewState: {\n isActive: computed(() => isPreviewActive.value),\n changedFields: computed(() => changedFieldsList.value),\n },\n clearPreview: () => {\n isPreviewActive.value = false;\n changedFieldsList.value = [];\n logger.debug(\"Preview state cleared manually\");\n },\n };\n}\n\n/**\n * @deprecated Use the `clearPreview()` method returned by useAiAgentContext() instead.\n */\nexport function clearPreviewState(_previewState: UseAiAgentContextReturn[\"previewState\"]): void {\n console.warn(\n \"[ai-agent] clearPreviewState() is deprecated. Use clearPreview() from useAiAgentContext() return value instead.\",\n );\n}\n","import type { App } from \"vue\";\r\nimport type { IAiAgentConfig } from \"@core/plugins/ai-agent/types\";\r\nimport { DEFAULT_AI_AGENT_CONFIG, AI_AGENT_URL_ENV_KEY } from \"@core/plugins/ai-agent/constants\";\r\nimport { createLogger } from \"@core/utilities\";\r\n\r\nconst logger = createLogger(\"ai-agent-plugin\");\r\n\r\n/**\r\n * Options for the AI Agent Plugin\r\n */\r\nexport interface AiAgentPluginOptions {\r\n /**\r\n * AI Agent configuration.\r\n * URL can also be set via APP_AI_AGENT_URL environment variable.\r\n */\r\n config?: Partial<IAiAgentConfig>;\r\n\r\n /**\r\n * Whether to add the AI button to all blade toolbars automatically.\r\n * Default: true\r\n */\r\n addGlobalToolbarButton?: boolean;\r\n}\r\n\r\n/**\r\n * Vue plugin for AI Agent integration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { createApp } from \"vue\";\r\n * import { aiAgentPlugin } from \"@vc-shell/framework\";\r\n *\r\n * const app = createApp(App);\r\n *\r\n * // Install with options\r\n * app.use(aiAgentPlugin, {\r\n * config: {\r\n * title: \"AI Assistant\",\r\n * width: 400,\r\n * },\r\n * addGlobalToolbarButton: true,\r\n * });\r\n * ```\r\n */\r\nexport const aiAgentPlugin = {\r\n install(app: App, options: AiAgentPluginOptions = {}) {\r\n const { config = {}, addGlobalToolbarButton = true } = options;\r\n\r\n // Get URL from environment variable if not provided\r\n let url = config.url || \"\";\r\n if (!url && typeof import.meta !== \"undefined\" && import.meta.env) {\r\n url = import.meta.env[AI_AGENT_URL_ENV_KEY] || \"\";\r\n }\r\n\r\n // Skip installation if no URL configured\r\n if (!url) {\r\n logger.info(\r\n \"AI Agent plugin skipped: no URL configured. Set APP_AI_AGENT_URL env variable or pass config.url option.\",\r\n );\r\n return;\r\n }\r\n\r\n // Merge config with defaults\r\n const finalConfig: IAiAgentConfig = {\r\n ...DEFAULT_AI_AGENT_CONFIG,\r\n ...config,\r\n url,\r\n };\r\n\r\n // Store config in app global properties for access during service creation\r\n app.config.globalProperties.$aiAgentConfig = finalConfig;\r\n app.provide(\"aiAgentConfig\", finalConfig);\r\n app.provide(\"aiAgentAddGlobalToolbarButton\", addGlobalToolbarButton);\r\n\r\n logger.info(`AI Agent plugin installed. URL: ${url}, addGlobalToolbarButton: ${addGlobalToolbarButton}`);\r\n },\r\n};\r\n\r\n// Re-export all types\r\nexport * from \"@core/plugins/ai-agent/types\";\r\nexport * from \"@core/plugins/ai-agent/constants\";\r\n\r\n// Re-export composables\r\nexport {\r\n useAiAgent,\r\n provideAiAgentService,\r\n createAiAgentToolbarButton,\r\n} from \"@core/plugins/ai-agent/composables/useAiAgent\";\r\nexport type { UseAiAgentReturn, ProvideAiAgentServiceOptions } from \"@core/plugins/ai-agent/composables/useAiAgent\";\r\n\r\nexport { useAiAgentContext, clearPreviewState } from \"@core/plugins/ai-agent/composables/useAiAgentContext\";\r\n\r\n// Re-export components\r\nexport { VcAiAgentPanel } from \"@core/plugins/ai-agent/components\";\r\n\r\n// Re-export service types\r\nexport type {\r\n IAiAgentServiceInternal,\r\n CreateAiAgentServiceOptions,\r\n} from \"@core/plugins/ai-agent/services/ai-agent-service\";\r\n"],"names":["deepMergeChanges","target","source","mergeWith","targetVal","sourceVal","result","item","index","isPlainObject","logger","createLogger","isArrayRef","dataRef","normalizeToArray","value","getTargetForChanges","useAiAgentContext","options","suggestions","service","inject","AiAgentServiceKey","bladeDescriptor","BladeDescriptorKey","bladeId","computed","isPreviewActive","ref","changedFieldsList","detectedContextType","updateContextData","raw","items","stopWatch","watch","unsubscribe","payload","targetObj","updatedData","mergedResult","key","onUnmounted","aiAgentPlugin","app","config","addGlobalToolbarButton","url","__vite_import_meta_env__","AI_AGENT_URL_ENV_KEY","finalConfig","DEFAULT_AI_AGENT_CONFIG"],"mappings":"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"}
|