@memberjunction/ng-artifacts 5.51.0 → 6.1.0-edge.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/LICENSE +7 -0
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +2 -2
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/services/interactive-form-apply.service.d.ts.map +1 -1
- package/dist/lib/services/interactive-form-apply.service.js +12 -13
- package/dist/lib/services/interactive-form-apply.service.js.map +1 -1
- package/package.json +29 -27
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 MemberJunction
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -863,7 +863,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
863
863
|
*/
|
|
864
864
|
async fetchFullSpecByName(name) {
|
|
865
865
|
try {
|
|
866
|
-
const rv =
|
|
866
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
867
867
|
const result = await rv.RunView({
|
|
868
868
|
EntityName: 'MJ: Components',
|
|
869
869
|
ExtraFilter: `Name='${name.replace(/'/g, "''")}'`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-artifact-viewer.component.ts","../../../../src/lib/components/plugins/component-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, AfterViewInit, OnInit, OnChanges, SimpleChanges, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass, SafeJSONParse } from '@memberjunction/global';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab } from '../base-artifact-viewer.component';\nimport { MJReactComponent, AngularAdapterService } from '@memberjunction/ng-react';\nimport { BuildComponentCompleteCode, ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { isFormRole, getDeclaredFormEntityName } from '@memberjunction/interactive-component-types/forms';\nimport { BaseEntity, CompositeKey, DataSnapshot, EntityInfo, LogError, RunView } from '@memberjunction/core';\nimport { InteractiveFormComponent } from '@memberjunction/ng-base-forms';\nimport { DataRequirementsViewerComponent } from './data-requirements-viewer/data-requirements-viewer.component';\nimport { evaluateComponentPermissions, PermissionEvaluationResult } from './component-permission-evaluation';\n\n/**\n * Viewer component for interactive Component artifacts (React-based UI components)\n *\n * Features:\n * - Live component preview with React rendering\n * - Dynamic tabs for component metadata (via GetAdditionalTabs)\n * - Provides tabs for: Code, Functional Requirements, Technical Design, Data Requirements\n */\n@Component({\n standalone: false,\n selector: 'mj-component-artifact-viewer',\n templateUrl: './component-artifact-viewer.component.html',\n styleUrls: ['./component-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'ComponentArtifactViewerPlugin')\nexport class ComponentArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit, AfterViewInit, OnChanges {\n @ViewChild('reactComponent') reactComponent?: MJReactComponent;\n @ViewChild('interactiveForm') interactiveForm?: InteractiveFormComponent;\n @Output() tabsChanged = new EventEmitter<void>();\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n\n /**\n * Emitted when the user clicks \"Apply to my form\" on a form-role artifact.\n * Carries the spec (ready to hand to the agent's Create/Modify action) and\n * the entity name. The host is responsible for confirming + invoking the\n * actual server action.\n */\n @Output() applyFormRequested = new EventEmitter<{ spec: ComponentSpec; entityName: string }>();\n\n // ── Form-aware state (only populated when componentRole === 'form') ──\n\n /** True when this artifact's spec declares `componentRole: 'form'`. */\n public isFormArtifact = false;\n\n /** Entity the form targets — resolved from spec.entityName / dataRequirements. */\n public formEntityInfo: EntityInfo | null = null;\n\n /** The real or fixture record currently bound to the form preview. */\n public formRecord: BaseEntity | null = null;\n\n /** True iff `formRecord` is a real DB row (vs a fixture NewRecord()). */\n public formRecordIsReal = false;\n\n /** Label for the chip (e.g. the record's Name field). */\n public formRecordLabel = '';\n\n /** Picker UI state. */\n public showRecordPicker = false;\n public recordSearchTerm = '';\n public recordSearchResults: Array<{ ID: string; Label: string }> = [];\n public formInitError: string | null = null;\n\n // Component data\n public component: ComponentSpec | null = null;\n public componentCode: string = \"\";\n public componentName: string = '';\n\n /**\n * Cached resolved spec from the registry, preserved even after the React component\n * is destroyed (e.g., when a render error removes <mj-react-component> from the DOM).\n */\n private _cachedResolvedSpec: ComponentSpec | null = null;\n\n public get resolvedComponentSpec(): ComponentSpec | null {\n // Prefer the live React component's resolved spec (most up-to-date),\n // then fall back to our cached copy (survives DOM destruction),\n // then fall back to the stripped local spec as last resort.\n return this.reactComponent?.resolvedComponentSpec || this._cachedResolvedSpec || this.component;\n }\n\n // Feedback panel\n public ShowFeedbackPanel = false;\n\n // Error state\n public hasError = false;\n public errorMessage = '';\n public errorDetails = '';\n\n // Permission state\n public permissionResult: PermissionEvaluationResult | null = null;\n\n /**\n * Whether this plugin has content to display in the Display tab.\n * Returns true only if the component has code that can be rendered.\n *\n * IMPORTANT: Uses this.component (synchronously loaded from artifact JSON)\n * instead of resolvedComponentSpec (which depends on async React loading).\n * This ensures hasDisplayContent returns correct value immediately when\n * pluginLoaded fires, before React component finishes loading.\n */\n public override get hasDisplayContent(): boolean {\n // Use this.component directly - it's available synchronously after loadComponentSpec()\n return !!this.component?.namespace || !!this.component?.code\n }\n\n constructor(private adapter: AngularAdapterService, private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n // When artifactVersion input changes, reload the component spec\n if (changes['artifactVersion']) {\n this.loadComponentSpec();\n // Notify parent that tabs may have changed (on subsequent changes)\n if (!changes['artifactVersion'].firstChange) {\n this.tabsChanged.emit();\n }\n }\n }\n\n /**\n * Synchronously load the component spec from artifact content.\n * This is intentionally synchronous so that tabs are available immediately\n * when the parent queries GetAdditionalTabs() after pluginLoaded fires.\n *\n * The bridge purges the runtime registry + manager fetch cache itself when\n * it (re)initializes for the new spec, so we don't need to clear caches\n * from here — the bridge instance may not even exist yet when ngOnChanges\n * fires for the first time.\n */\n private loadComponentSpec(): void {\n try {\n // Clear cached resolved spec from previous version so stale data doesn't persist\n this._cachedResolvedSpec = null;\n this.permissionResult = null;\n\n if (this.artifactVersion?.Content) {\n this.component = SafeJSONParse(this.artifactVersion.Content) as ComponentSpec;\n this.extractComponentParts();\n this.evaluatePermissions();\n // Form-aware detection. Done here (not in ngAfterViewInit) so the\n // template's `@if (isFormArtifact)` branch decides which preview\n // to mount on the very first render — no flash of the non-form\n // path before the form-aware UI takes over.\n this.detectAndInitFormArtifact();\n } else {\n throw new Error('Artifact content is empty');\n }\n } catch (error) {\n console.error('Failed to load component spec:', error);\n this.hasError = true;\n this.errorMessage = 'Failed to load component';\n this.errorDetails = error instanceof Error ? error.message : String(error);\n }\n }\n\n /**\n * Evaluate whether the current user has sufficient permissions for\n * all entities and queries referenced in the component's dataRequirements.\n * Uses the best available spec: resolved (from registry) > cached > stripped artifact.\n * Runs synchronously against already-loaded client-side metadata.\n */\n private evaluatePermissions(): void {\n const spec = this.resolvedComponentSpec;\n if (!spec) return;\n\n const provider = this.ProviderToUse;\n const currentUser = provider.CurrentUser;\n if (!currentUser) return; // No user context — skip check\n\n this.permissionResult = evaluateComponentPermissions(spec, currentUser, provider);\n }\n\n /** Whether the component should be blocked from rendering due to missing permissions. */\n public get isPermissionBlocked(): boolean {\n return !!this.permissionResult && !this.permissionResult.canRun;\n }\n\n /**\n * Component initialization.\n * Note: loadComponentSpec() is called in ngOnChanges which runs before ngOnInit,\n * ensuring tabs are available when pluginLoaded fires.\n * The async adapter initialization happens here and doesn't block tab availability.\n */\n async ngOnInit(): Promise<void> {\n // Initialize Angular adapter for React components (async operation)\n try {\n await this.adapter.initialize();\n } catch (error) {\n console.error('Failed to initialize Angular adapter:', error);\n this.hasError = true;\n this.errorMessage = 'Failed to initialize component runtime';\n this.errorDetails = error instanceof Error ? error.message : String(error);\n }\n }\n\n async ngAfterViewInit(): Promise<void> {\n // Component initialization happens automatically via mj-react-component\n }\n\n /**\n * Provide additional tabs for viewing component metadata\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n const resolvedComponent = this.resolvedComponentSpec;\n\n if (!resolvedComponent) {\n return tabs;\n }\n\n // Functional Requirements tab\n if (resolvedComponent.functionalRequirements) {\n tabs.push({\n label: 'Functional',\n icon: 'fa-clipboard-list',\n contentType: 'markdown',\n content: resolvedComponent.functionalRequirements\n });\n }\n\n // Technical Design tab\n if (resolvedComponent.technicalDesign) {\n tabs.push({\n label: 'Technical',\n icon: 'fa-wrench',\n contentType: 'markdown',\n content: resolvedComponent.technicalDesign\n });\n }\n\n // Data Requirements tab - uses custom component for rich visualization\n if (resolvedComponent.dataRequirements) {\n tabs.push({\n label: 'Data',\n icon: 'fa-database',\n contentType: 'component',\n component: DataRequirementsViewerComponent,\n componentInputs: { dataRequirements: resolvedComponent.dataRequirements }\n });\n }\n\n // Code tab (lazy-loaded) - only show if there's actual code\n if (resolvedComponent.code && resolvedComponent.code.trim()) {\n tabs.push({\n label: 'Code',\n icon: 'fa-code',\n contentType: 'code',\n language: 'typescript',\n content: () => BuildComponentCompleteCode(resolvedComponent)\n });\n }\n\n // Spec tab - Shows fully resolved component spec in JSON format (rightmost)\n tabs.push({\n label: 'Spec',\n icon: 'fa-file-code',\n contentType: 'json',\n content: () => JSON.stringify(resolvedComponent, null, 2),\n language: 'json'\n });\n\n return tabs;\n }\n\n /**\n * Remove standard JSON tab since we provide \"Resolved JSON\" custom tab\n * The custom tab shows the fully resolved component spec instead of raw artifact JSON\n */\n public GetStandardTabRemovals(): string[] {\n return ['JSON'];\n }\n\n private extractComponentParts(): void {\n if (this.resolvedComponentSpec?.name) {\n this.componentName = this.resolvedComponentSpec.name;\n }\n if (this.resolvedComponentSpec?.code) {\n this.componentCode = BuildComponentCompleteCode(this.resolvedComponentSpec);\n }\n }\n\n /**\n * Called when MJReactComponent finishes loading the full component spec from the registry.\n * The full spec may contain Functional, Technical, and Data tabs not in the stripped spec.\n * Caches the resolved spec so it survives DOM destruction (e.g., if the component fails to\n * render and <mj-react-component> is removed by the @if/else block).\n * Emits tabsChanged so the parent panel re-evaluates allTabs and renders the new tab labels.\n */\n onReactComponentInitialized(): void {\n if (this.reactComponent?.resolvedComponentSpec &&\n this.reactComponent.resolvedComponentSpec !== this.component) {\n // Cache the resolved spec so it's available even after the React component is destroyed\n this._cachedResolvedSpec = this.reactComponent.resolvedComponentSpec;\n this.tabsChanged.emit();\n\n // Re-evaluate permissions against the resolved spec — the stripped artifact\n // spec has no dataRequirements, so the initial check in loadComponentSpec()\n // passes trivially. The resolved spec from the registry contains the full\n // dataRequirements with entity and query references.\n this.evaluatePermissions();\n }\n }\n\n onComponentEvent(event: unknown): void {\n console.log('Component event:', event);\n\n // Handle error events from React component\n if (event && typeof event === 'object' && 'type' in event && event.type === 'error') {\n const errorEvent = event as { type: 'error'; payload: { error: string; source: string } };\n this.hasError = true;\n this.errorMessage = 'Component Failed to Load';\n this.errorDetails = errorEvent.payload.error || 'Unknown error occurred while loading the component';\n }\n }\n\n /**\n * Handle entity record open request from React component\n * Propagates the event up to parent components\n */\n onOpenEntityRecord(event: {entityName: string; key: CompositeKey}): void {\n // Transform to use 'compositeKey' name for consistency with Angular components\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey: event.key\n });\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n // First try the component's explicit or auto-captured data state.\n // MJReactComponent.getCurrentDataState() already includes the fallback\n // to intercepted RunView/RunQuery results when the React component\n // doesn't register getCurrentDataState() via callbacks.RegisterMethod.\n const dataState = this.reactComponent?.getCurrentDataState?.();\n if (dataState && typeof dataState === 'object') {\n return dataState as DataSnapshot;\n }\n\n // Fallback for components with no captured data — static mockups,\n // pure-display components, or components whose data hooks haven't fired.\n // Rather than short-circuit Analyze with \"No data available\", emit a\n // minimal snapshot so the user can still open an agent conversation about\n // the component. The artifact itself is attached to the conversation as an\n // Input junction, so the agent can reason from the spec + any static data\n // baked into the component code.\n const spec = this.resolvedComponentSpec;\n if (!spec) return null;\n\n const snap = new DataSnapshot();\n snap.title = spec.title || spec.name || this.getDisplayTitle() || undefined;\n snap.interpretation =\n `Interactive component artifact${spec.name ? ` \"${spec.name}\"` : ''}. ` +\n `No live data was captured — the component either has no data-fetching ` +\n `hooks or has not yet run its queries. The component specification is ` +\n `attached to this conversation; the agent should inspect it directly.`;\n return snap;\n }\n\n /**\n * Component artifacts support feedback when a resolved spec is available.\n */\n public override get SupportsFeedback(): boolean {\n return !!this.resolvedComponentSpec;\n }\n\n /**\n * Toggle the feedback panel open. Called from the artifact viewer header button.\n */\n public override AskUserForFeedback(): void {\n this.ShowFeedbackPanel = !this.ShowFeedbackPanel;\n }\n\n // ════════════════════════════════════════════════════════════════════\n // FORM-AWARE BRANCH\n //\n // When the artifact's spec declares `componentRole: 'form'`, the viewer\n // delegates rendering to `<mj-interactive-form>` instead of the raw\n // `<mj-react-component>` path. This gives the React form a proper\n // FormHostProps binding (bound to a real DB record by default) and lets\n // the user swap records via a search picker before applying.\n //\n // Triggered from `loadComponentSpec()` after the spec parses.\n // ════════════════════════════════════════════════════════════════════\n\n /**\n * Detect form-role and kick off entity + record resolution. Failure modes\n * (missing entity, RunView failure, entity has no rows) fall back to a\n * synthetic record from `BaseEntity.NewRecord()` so the form still mounts\n * against type-appropriate empty values.\n */\n private async detectAndInitFormArtifact(): Promise<void> {\n this.isFormArtifact = false;\n this.formEntityInfo = null;\n this.formRecord = null;\n this.formRecordIsReal = false;\n this.formRecordLabel = '';\n this.formInitError = null;\n\n const spec = this.component;\n if (!spec || !isFormRole(spec)) return;\n\n this.isFormArtifact = true;\n\n const entityName = getDeclaredFormEntityName(spec);\n if (!entityName) {\n this.formInitError = 'Form artifact has no declared entity. Showing without record context.';\n return;\n }\n\n const provider = this.ProviderToUse;\n const entity = provider?.EntityByName(entityName);\n if (!entity) {\n this.formInitError = `Entity \"${entityName}\" not registered with the active provider.`;\n return;\n }\n this.formEntityInfo = entity;\n\n // Load Top-1 record by default. If empty / fails, fall back to a fresh\n // synthetic record. Either way the form mounts — failure to find a real\n // record is informational, not fatal.\n const record = await this.loadTopOneRecord(entity);\n if (record) {\n this.formRecord = record;\n this.formRecordIsReal = true;\n this.formRecordLabel = this.computeRecordLabel(record);\n } else {\n this.formRecord = await this.buildFixtureRecord(entity);\n this.formRecordIsReal = false;\n this.formRecordLabel = 'Mock data';\n }\n // This runs after an await on a RunView that resolves outside Angular's zone,\n // so nothing would refresh the view until the next user event — leaving the\n // \"Could not bind a record\" message up until the user clicks. Force CD so the\n // auto-loaded record binds and the form mounts immediately on first render.\n this.cdr.detectChanges();\n }\n\n /**\n * Load the first row by NameField (then __mj_CreatedAt) so different users\n * opening the same form-role artifact see the same record bound to the\n * preview. (Retrospective fix #7 — un-ordered Top-1 was physical-order\n * and non-deterministic.)\n */\n private async loadTopOneRecord(entity: EntityInfo): Promise<BaseEntity | null> {\n try {\n const orderBy = entity.NameField?.Name\n ? `${entity.NameField.Name} ASC`\n : `__mj_CreatedAt DESC`;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<BaseEntity>({\n EntityName: entity.Name,\n MaxRows: 1,\n OrderBy: orderBy,\n ResultType: 'entity_object',\n }, this.ProviderToUse.CurrentUser);\n if (result.Success && (result.Results?.length ?? 0) > 0) {\n return result.Results[0];\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: Top-1 RunView failed for ${entity.Name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n return null;\n }\n\n /** Synthetic \"create-mode\" record when no real row exists or RunView failed. */\n private async buildFixtureRecord(entity: EntityInfo): Promise<BaseEntity | null> {\n try {\n const fresh = await this.ProviderToUse.GetEntityObject<BaseEntity>(entity.Name, this.ProviderToUse.CurrentUser);\n fresh.NewRecord();\n return fresh;\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to build fixture record for ${entity.Name}: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n }\n\n /** Pull a human-readable label from the record's NameField or first text field. */\n private computeRecordLabel(record: BaseEntity): string {\n const nameField = record.EntityInfo.NameField?.Name;\n if (nameField) {\n const v = record.Get(nameField);\n if (v != null && String(v).trim().length > 0) return String(v);\n }\n if (record.PrimaryKey?.HasValue) return record.PrimaryKey.ToConcatenatedString();\n return record.EntityInfo.Name;\n }\n\n /**\n * Search-as-you-type for the picker. Queries by name field (or any\n * indexed string field, best-effort). Limits to 8 hits for tightness.\n */\n public async onPickerSearchInput(term: string): Promise<void> {\n this.recordSearchTerm = term;\n if (!this.formEntityInfo || term.trim().length === 0) {\n this.recordSearchResults = [];\n return;\n }\n const nameField = this.formEntityInfo.NameField?.Name;\n if (!nameField) {\n this.recordSearchResults = [];\n return;\n }\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n // Best-effort LIKE filter against the entity's name field. Wrap the\n // term so we don't break SQL — RunView passes ExtraFilter as-is.\n const safe = term.replace(/'/g, \"''\");\n const result = await rv.RunView<BaseEntity>({\n EntityName: this.formEntityInfo.Name,\n ExtraFilter: `${nameField} LIKE '%${safe}%'`,\n MaxRows: 8,\n ResultType: 'entity_object',\n }, this.ProviderToUse.CurrentUser);\n if (result.Success) {\n this.recordSearchResults = (result.Results ?? []).map(r => ({\n ID: r.PrimaryKey?.ToConcatenatedString() ?? '',\n Label: this.computeRecordLabel(r),\n }));\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: picker search failed: ${err instanceof Error ? err.message : String(err)}`);\n this.recordSearchResults = [];\n }\n }\n\n /** User picked a different record from the search results. Re-bind the form. */\n public async onPickerSelect(item: { ID: string; Label: string }): Promise<void> {\n if (!this.formEntityInfo) return;\n try {\n const rec = await this.ProviderToUse.GetEntityObject<BaseEntity>(\n this.formEntityInfo.Name, this.ProviderToUse.CurrentUser,\n );\n const pk = new CompositeKey();\n pk.LoadFromURLSegment(this.formEntityInfo, item.ID);\n const loaded = await rec.InnerLoad(pk);\n if (loaded) {\n this.formRecord = rec;\n this.formRecordIsReal = true;\n this.formRecordLabel = item.Label;\n this.showRecordPicker = false;\n this.recordSearchTerm = '';\n this.recordSearchResults = [];\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to load picked record ${item.ID}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /**\n * Bubble Apply intent up to the host (Form Builder dashboard / Sage chat).\n *\n * Resolves the full ComponentSpec (with code) from multiple sources:\n * 1. resolvedComponentSpec — live React bridge or cached copy (best for non-form artifacts)\n * 2. Re-parse artifact version Content — the agent stores the full spec including code\n * 3. DB fallback — fetch from MJ: Components by name\n *\n * Source #2 covers the common form-artifact case where the React component lives inside\n * <mj-interactive-form> and resolvedComponentSpec falls back to the stripped local spec.\n */\n public async onApplyClicked(): Promise<void> {\n if (!this.formEntityInfo) return;\n\n const spec = await this.resolveSpecWithCode();\n if (!spec) return;\n\n this.applyFormRequested.emit({\n spec,\n entityName: this.formEntityInfo.Name,\n });\n }\n\n /**\n * Resolve a ComponentSpec that includes code, trying multiple sources in order.\n */\n private async resolveSpecWithCode(): Promise<ComponentSpec | null> {\n // 1. Prefer the live React bridge's resolved spec (non-form path).\n const resolved = this.resolvedComponentSpec;\n if (resolved?.code) return resolved;\n\n // 2. For form artifacts, the React component lives inside <mj-interactive-form>.\n // Reach into it to get the resolved spec from the component registry.\n const formReactSpec = this.interactiveForm?.reactComponent?.resolvedComponentSpec;\n if (formReactSpec?.code) return formReactSpec;\n\n // 3. Re-parse the artifact version's Content directly — the agent stores the\n // full spec including code. This handles the case where loadComponentSpec()\n // parsed early (before Content was fully populated) and the in-memory\n // `this.component` ended up without code.\n if (this.artifactVersion?.Content) {\n const freshParse = SafeJSONParse(this.artifactVersion.Content) as ComponentSpec | null;\n if (freshParse?.code) return freshParse;\n }\n\n // 4. DB fallback — fetch from MJ: Components by name.\n const name = resolved?.name ?? this.component?.name;\n if (name) {\n const dbSpec = await this.fetchFullSpecByName(name);\n if (dbSpec?.code) return dbSpec;\n }\n\n LogError('ComponentArtifactViewer: could not resolve spec with code for Apply');\n return null;\n }\n\n /**\n * Fetch the full ComponentSpec (including code) from the MJ: Components table\n * by component name. Returns null if not found or on error.\n */\n private async fetchFullSpecByName(name: string): Promise<ComponentSpec | null> {\n try {\n const rv = new RunView();\n const result = await rv.RunView<{ Specification: string }>({\n EntityName: 'MJ: Components',\n ExtraFilter: `Name='${name.replace(/'/g, \"''\")}'`,\n Fields: ['Specification'],\n OrderBy: 'VersionSequence DESC',\n MaxRows: 1,\n ResultType: 'simple',\n });\n if (result.Success && result.Results?.length > 0 && result.Results[0].Specification) {\n return JSON.parse(result.Results[0].Specification) as ComponentSpec;\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to fetch full spec for '${name}': ${err instanceof Error ? err.message : String(err)}`);\n }\n return null;\n }\n}\n","<div class=\"component-artifact-viewer\" [ngClass]=\"cssClass\">\n <!-- Component Preview (full screen) -->\n <div class=\"component-preview\">\n @if (hasError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>{{ errorMessage }}</h3>\n <p>This component could not be loaded. This usually happens when:</p>\n <ul style=\"text-align: left; max-width: 500px; color: var(--mj-text-muted); line-height: 1.6;\">\n <li>The component registry is unavailable or unreachable</li>\n <li>The component version does not exist in the registry</li>\n <li>There was a network error during component retrieval</li>\n </ul>\n @if (errorDetails) {\n <details style=\"margin-top: 20px;\">\n <summary>Technical Details</summary>\n <pre>{{ errorDetails }}</pre>\n </details>\n }\n </div>\n } @else if (isFormArtifact) {\n <!-- ════════════════════════════════════════════════\n FORM-AWARE BRANCH\n Spec declares componentRole: 'form'. Render via\n <mj-interactive-form> bound to a real Top-1 record\n (or a synthetic NewRecord fallback). Picker chip\n lets the user swap records; Apply promotes the\n spec to an EntityFormOverride.\n ════════════════════════════════════════════════ -->\n <div class=\"form-artifact-toolstrip\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n <span class=\"form-artifact-toolstrip-label\">Previewing record:</span>\n <button\n type=\"button\"\n class=\"form-artifact-picker-chip\"\n (click)=\"showRecordPicker = !showRecordPicker\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <strong>{{ formRecordLabel || 'No record' }}</strong>\n @if (!formRecordIsReal) {\n <span class=\"form-artifact-picker-chip-badge\">Mock</span>\n }\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n @if (formEntityInfo) {\n <span class=\"form-artifact-toolstrip-entity\">{{ formEntityInfo.DisplayName || formEntityInfo.Name }}</span>\n }\n @if (formInitError) {\n <span class=\"form-artifact-toolstrip-warning\" [title]=\"formInitError\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </span>\n }\n <span style=\"flex: 1;\"></span>\n @if (formEntityInfo) {\n <button\n type=\"button\"\n class=\"form-artifact-apply-btn\"\n (click)=\"onApplyClicked()\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Apply to my form\n </button>\n }\n </div>\n\n @if (showRecordPicker && formEntityInfo) {\n <div class=\"form-artifact-picker-panel\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"text\"\n class=\"form-artifact-picker-search\"\n placeholder=\"Search records by name…\"\n [value]=\"recordSearchTerm\"\n (input)=\"onPickerSearchInput($any($event.target).value)\" />\n @if (recordSearchResults.length > 0) {\n <ul class=\"form-artifact-picker-results\">\n @for (r of recordSearchResults; track r.ID) {\n <li\n class=\"form-artifact-picker-row\"\n (click)=\"onPickerSelect(r)\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n <span>{{ r.Label }}</span>\n </li>\n }\n </ul>\n } @else if (recordSearchTerm.length > 0) {\n <div class=\"form-artifact-picker-empty\">No matches.</div>\n } @else {\n <div class=\"form-artifact-picker-empty\">Start typing to search.</div>\n }\n </div>\n }\n\n @if (formRecord && component) {\n <div class=\"form-artifact-form-host\">\n <mj-interactive-form\n #interactiveForm\n [componentSpec]=\"component\"\n [record]=\"formRecord\">\n </mj-interactive-form>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>Form preview unavailable</h3>\n <p>{{ formInitError || 'Could not bind a record to this form.' }}</p>\n </div>\n }\n } @else if (isPermissionBlocked) {\n <!-- Permission warning — user lacks access to one or more data sources -->\n <div class=\"permission-warning\">\n <div class=\"permission-warning-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <h3>Insufficient Permissions</h3>\n <p>This component requires data access that you don't currently have:</p>\n\n @if (permissionResult!.missingEntities.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Entities</span>\n <ul>\n @for (entity of permissionResult!.missingEntities; track entity) {\n <li><i class=\"fa-solid fa-table\"></i> {{ entity }}</li>\n }\n </ul>\n </div>\n }\n\n @if (permissionResult!.missingQueries.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Queries</span>\n <ul>\n @for (query of permissionResult!.missingQueries; track query) {\n <li><i class=\"fa-solid fa-database\"></i> {{ query }}</li>\n }\n </ul>\n </div>\n }\n\n <p class=\"permission-warning-hint\">Contact your administrator to request access.</p>\n </div>\n } @else {\n <!-- Default (non-form) interactive component path -->\n @if (component && (component.code || component.namespace)) {\n <mj-react-component\n #reactComponent\n [component]=\"component\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (initialized)=\"onReactComponentInitialized()\">\n </mj-react-component>\n } @else if (component) {\n <!-- Component spec exists but no code - show informational message -->\n <div class=\"no-code-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <h3>Component Specification</h3>\n <p>This component has specifications but no executable code yet.</p>\n <p>View the Functional, Data, or Spec tabs for details.</p>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>No Component Loaded</h3>\n <p>The component data is missing or invalid.</p>\n </div>\n }\n }\n </div>\n\n <!-- Feedback overlay panel (invoked from header button via AskUserForFeedback) -->\n @if (ShowFeedbackPanel && resolvedComponentSpec) {\n <mj-component-feedback-panel\n [ComponentSpec]=\"resolvedComponentSpec\"\n [ReactContainerElement]=\"reactComponent?.container?.nativeElement || null\"\n (Closed)=\"ShowFeedbackPanel = false\">\n </mj-component-feedback-panel>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"component-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-artifact-viewer.component.ts","../../../../src/lib/components/plugins/component-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, AfterViewInit, OnInit, OnChanges, SimpleChanges, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass, SafeJSONParse } from '@memberjunction/global';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab } from '../base-artifact-viewer.component';\nimport { MJReactComponent, AngularAdapterService } from '@memberjunction/ng-react';\nimport { BuildComponentCompleteCode, ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { isFormRole, getDeclaredFormEntityName } from '@memberjunction/interactive-component-types/forms';\nimport { BaseEntity, CompositeKey, DataSnapshot, EntityInfo, LogError, RunView } from '@memberjunction/core';\nimport { InteractiveFormComponent } from '@memberjunction/ng-base-forms';\nimport { DataRequirementsViewerComponent } from './data-requirements-viewer/data-requirements-viewer.component';\nimport { evaluateComponentPermissions, PermissionEvaluationResult } from './component-permission-evaluation';\n\n/**\n * Viewer component for interactive Component artifacts (React-based UI components)\n *\n * Features:\n * - Live component preview with React rendering\n * - Dynamic tabs for component metadata (via GetAdditionalTabs)\n * - Provides tabs for: Code, Functional Requirements, Technical Design, Data Requirements\n */\n@Component({\n standalone: false,\n selector: 'mj-component-artifact-viewer',\n templateUrl: './component-artifact-viewer.component.html',\n styleUrls: ['./component-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'ComponentArtifactViewerPlugin')\nexport class ComponentArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit, AfterViewInit, OnChanges {\n @ViewChild('reactComponent') reactComponent?: MJReactComponent;\n @ViewChild('interactiveForm') interactiveForm?: InteractiveFormComponent;\n @Output() tabsChanged = new EventEmitter<void>();\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n\n /**\n * Emitted when the user clicks \"Apply to my form\" on a form-role artifact.\n * Carries the spec (ready to hand to the agent's Create/Modify action) and\n * the entity name. The host is responsible for confirming + invoking the\n * actual server action.\n */\n @Output() applyFormRequested = new EventEmitter<{ spec: ComponentSpec; entityName: string }>();\n\n // ── Form-aware state (only populated when componentRole === 'form') ──\n\n /** True when this artifact's spec declares `componentRole: 'form'`. */\n public isFormArtifact = false;\n\n /** Entity the form targets — resolved from spec.entityName / dataRequirements. */\n public formEntityInfo: EntityInfo | null = null;\n\n /** The real or fixture record currently bound to the form preview. */\n public formRecord: BaseEntity | null = null;\n\n /** True iff `formRecord` is a real DB row (vs a fixture NewRecord()). */\n public formRecordIsReal = false;\n\n /** Label for the chip (e.g. the record's Name field). */\n public formRecordLabel = '';\n\n /** Picker UI state. */\n public showRecordPicker = false;\n public recordSearchTerm = '';\n public recordSearchResults: Array<{ ID: string; Label: string }> = [];\n public formInitError: string | null = null;\n\n // Component data\n public component: ComponentSpec | null = null;\n public componentCode: string = \"\";\n public componentName: string = '';\n\n /**\n * Cached resolved spec from the registry, preserved even after the React component\n * is destroyed (e.g., when a render error removes <mj-react-component> from the DOM).\n */\n private _cachedResolvedSpec: ComponentSpec | null = null;\n\n public get resolvedComponentSpec(): ComponentSpec | null {\n // Prefer the live React component's resolved spec (most up-to-date),\n // then fall back to our cached copy (survives DOM destruction),\n // then fall back to the stripped local spec as last resort.\n return this.reactComponent?.resolvedComponentSpec || this._cachedResolvedSpec || this.component;\n }\n\n // Feedback panel\n public ShowFeedbackPanel = false;\n\n // Error state\n public hasError = false;\n public errorMessage = '';\n public errorDetails = '';\n\n // Permission state\n public permissionResult: PermissionEvaluationResult | null = null;\n\n /**\n * Whether this plugin has content to display in the Display tab.\n * Returns true only if the component has code that can be rendered.\n *\n * IMPORTANT: Uses this.component (synchronously loaded from artifact JSON)\n * instead of resolvedComponentSpec (which depends on async React loading).\n * This ensures hasDisplayContent returns correct value immediately when\n * pluginLoaded fires, before React component finishes loading.\n */\n public override get hasDisplayContent(): boolean {\n // Use this.component directly - it's available synchronously after loadComponentSpec()\n return !!this.component?.namespace || !!this.component?.code\n }\n\n constructor(private adapter: AngularAdapterService, private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n // When artifactVersion input changes, reload the component spec\n if (changes['artifactVersion']) {\n this.loadComponentSpec();\n // Notify parent that tabs may have changed (on subsequent changes)\n if (!changes['artifactVersion'].firstChange) {\n this.tabsChanged.emit();\n }\n }\n }\n\n /**\n * Synchronously load the component spec from artifact content.\n * This is intentionally synchronous so that tabs are available immediately\n * when the parent queries GetAdditionalTabs() after pluginLoaded fires.\n *\n * The bridge purges the runtime registry + manager fetch cache itself when\n * it (re)initializes for the new spec, so we don't need to clear caches\n * from here — the bridge instance may not even exist yet when ngOnChanges\n * fires for the first time.\n */\n private loadComponentSpec(): void {\n try {\n // Clear cached resolved spec from previous version so stale data doesn't persist\n this._cachedResolvedSpec = null;\n this.permissionResult = null;\n\n if (this.artifactVersion?.Content) {\n this.component = SafeJSONParse(this.artifactVersion.Content) as ComponentSpec;\n this.extractComponentParts();\n this.evaluatePermissions();\n // Form-aware detection. Done here (not in ngAfterViewInit) so the\n // template's `@if (isFormArtifact)` branch decides which preview\n // to mount on the very first render — no flash of the non-form\n // path before the form-aware UI takes over.\n this.detectAndInitFormArtifact();\n } else {\n throw new Error('Artifact content is empty');\n }\n } catch (error) {\n console.error('Failed to load component spec:', error);\n this.hasError = true;\n this.errorMessage = 'Failed to load component';\n this.errorDetails = error instanceof Error ? error.message : String(error);\n }\n }\n\n /**\n * Evaluate whether the current user has sufficient permissions for\n * all entities and queries referenced in the component's dataRequirements.\n * Uses the best available spec: resolved (from registry) > cached > stripped artifact.\n * Runs synchronously against already-loaded client-side metadata.\n */\n private evaluatePermissions(): void {\n const spec = this.resolvedComponentSpec;\n if (!spec) return;\n\n const provider = this.ProviderToUse;\n const currentUser = provider.CurrentUser;\n if (!currentUser) return; // No user context — skip check\n\n this.permissionResult = evaluateComponentPermissions(spec, currentUser, provider);\n }\n\n /** Whether the component should be blocked from rendering due to missing permissions. */\n public get isPermissionBlocked(): boolean {\n return !!this.permissionResult && !this.permissionResult.canRun;\n }\n\n /**\n * Component initialization.\n * Note: loadComponentSpec() is called in ngOnChanges which runs before ngOnInit,\n * ensuring tabs are available when pluginLoaded fires.\n * The async adapter initialization happens here and doesn't block tab availability.\n */\n async ngOnInit(): Promise<void> {\n // Initialize Angular adapter for React components (async operation)\n try {\n await this.adapter.initialize();\n } catch (error) {\n console.error('Failed to initialize Angular adapter:', error);\n this.hasError = true;\n this.errorMessage = 'Failed to initialize component runtime';\n this.errorDetails = error instanceof Error ? error.message : String(error);\n }\n }\n\n async ngAfterViewInit(): Promise<void> {\n // Component initialization happens automatically via mj-react-component\n }\n\n /**\n * Provide additional tabs for viewing component metadata\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n const resolvedComponent = this.resolvedComponentSpec;\n\n if (!resolvedComponent) {\n return tabs;\n }\n\n // Functional Requirements tab\n if (resolvedComponent.functionalRequirements) {\n tabs.push({\n label: 'Functional',\n icon: 'fa-clipboard-list',\n contentType: 'markdown',\n content: resolvedComponent.functionalRequirements\n });\n }\n\n // Technical Design tab\n if (resolvedComponent.technicalDesign) {\n tabs.push({\n label: 'Technical',\n icon: 'fa-wrench',\n contentType: 'markdown',\n content: resolvedComponent.technicalDesign\n });\n }\n\n // Data Requirements tab - uses custom component for rich visualization\n if (resolvedComponent.dataRequirements) {\n tabs.push({\n label: 'Data',\n icon: 'fa-database',\n contentType: 'component',\n component: DataRequirementsViewerComponent,\n componentInputs: { dataRequirements: resolvedComponent.dataRequirements }\n });\n }\n\n // Code tab (lazy-loaded) - only show if there's actual code\n if (resolvedComponent.code && resolvedComponent.code.trim()) {\n tabs.push({\n label: 'Code',\n icon: 'fa-code',\n contentType: 'code',\n language: 'typescript',\n content: () => BuildComponentCompleteCode(resolvedComponent)\n });\n }\n\n // Spec tab - Shows fully resolved component spec in JSON format (rightmost)\n tabs.push({\n label: 'Spec',\n icon: 'fa-file-code',\n contentType: 'json',\n content: () => JSON.stringify(resolvedComponent, null, 2),\n language: 'json'\n });\n\n return tabs;\n }\n\n /**\n * Remove standard JSON tab since we provide \"Resolved JSON\" custom tab\n * The custom tab shows the fully resolved component spec instead of raw artifact JSON\n */\n public GetStandardTabRemovals(): string[] {\n return ['JSON'];\n }\n\n private extractComponentParts(): void {\n if (this.resolvedComponentSpec?.name) {\n this.componentName = this.resolvedComponentSpec.name;\n }\n if (this.resolvedComponentSpec?.code) {\n this.componentCode = BuildComponentCompleteCode(this.resolvedComponentSpec);\n }\n }\n\n /**\n * Called when MJReactComponent finishes loading the full component spec from the registry.\n * The full spec may contain Functional, Technical, and Data tabs not in the stripped spec.\n * Caches the resolved spec so it survives DOM destruction (e.g., if the component fails to\n * render and <mj-react-component> is removed by the @if/else block).\n * Emits tabsChanged so the parent panel re-evaluates allTabs and renders the new tab labels.\n */\n onReactComponentInitialized(): void {\n if (this.reactComponent?.resolvedComponentSpec &&\n this.reactComponent.resolvedComponentSpec !== this.component) {\n // Cache the resolved spec so it's available even after the React component is destroyed\n this._cachedResolvedSpec = this.reactComponent.resolvedComponentSpec;\n this.tabsChanged.emit();\n\n // Re-evaluate permissions against the resolved spec — the stripped artifact\n // spec has no dataRequirements, so the initial check in loadComponentSpec()\n // passes trivially. The resolved spec from the registry contains the full\n // dataRequirements with entity and query references.\n this.evaluatePermissions();\n }\n }\n\n onComponentEvent(event: unknown): void {\n console.log('Component event:', event);\n\n // Handle error events from React component\n if (event && typeof event === 'object' && 'type' in event && event.type === 'error') {\n const errorEvent = event as { type: 'error'; payload: { error: string; source: string } };\n this.hasError = true;\n this.errorMessage = 'Component Failed to Load';\n this.errorDetails = errorEvent.payload.error || 'Unknown error occurred while loading the component';\n }\n }\n\n /**\n * Handle entity record open request from React component\n * Propagates the event up to parent components\n */\n onOpenEntityRecord(event: {entityName: string; key: CompositeKey}): void {\n // Transform to use 'compositeKey' name for consistency with Angular components\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey: event.key\n });\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n // First try the component's explicit or auto-captured data state.\n // MJReactComponent.getCurrentDataState() already includes the fallback\n // to intercepted RunView/RunQuery results when the React component\n // doesn't register getCurrentDataState() via callbacks.RegisterMethod.\n const dataState = this.reactComponent?.getCurrentDataState?.();\n if (dataState && typeof dataState === 'object') {\n return dataState as DataSnapshot;\n }\n\n // Fallback for components with no captured data — static mockups,\n // pure-display components, or components whose data hooks haven't fired.\n // Rather than short-circuit Analyze with \"No data available\", emit a\n // minimal snapshot so the user can still open an agent conversation about\n // the component. The artifact itself is attached to the conversation as an\n // Input junction, so the agent can reason from the spec + any static data\n // baked into the component code.\n const spec = this.resolvedComponentSpec;\n if (!spec) return null;\n\n const snap = new DataSnapshot();\n snap.title = spec.title || spec.name || this.getDisplayTitle() || undefined;\n snap.interpretation =\n `Interactive component artifact${spec.name ? ` \"${spec.name}\"` : ''}. ` +\n `No live data was captured — the component either has no data-fetching ` +\n `hooks or has not yet run its queries. The component specification is ` +\n `attached to this conversation; the agent should inspect it directly.`;\n return snap;\n }\n\n /**\n * Component artifacts support feedback when a resolved spec is available.\n */\n public override get SupportsFeedback(): boolean {\n return !!this.resolvedComponentSpec;\n }\n\n /**\n * Toggle the feedback panel open. Called from the artifact viewer header button.\n */\n public override AskUserForFeedback(): void {\n this.ShowFeedbackPanel = !this.ShowFeedbackPanel;\n }\n\n // ════════════════════════════════════════════════════════════════════\n // FORM-AWARE BRANCH\n //\n // When the artifact's spec declares `componentRole: 'form'`, the viewer\n // delegates rendering to `<mj-interactive-form>` instead of the raw\n // `<mj-react-component>` path. This gives the React form a proper\n // FormHostProps binding (bound to a real DB record by default) and lets\n // the user swap records via a search picker before applying.\n //\n // Triggered from `loadComponentSpec()` after the spec parses.\n // ════════════════════════════════════════════════════════════════════\n\n /**\n * Detect form-role and kick off entity + record resolution. Failure modes\n * (missing entity, RunView failure, entity has no rows) fall back to a\n * synthetic record from `BaseEntity.NewRecord()` so the form still mounts\n * against type-appropriate empty values.\n */\n private async detectAndInitFormArtifact(): Promise<void> {\n this.isFormArtifact = false;\n this.formEntityInfo = null;\n this.formRecord = null;\n this.formRecordIsReal = false;\n this.formRecordLabel = '';\n this.formInitError = null;\n\n const spec = this.component;\n if (!spec || !isFormRole(spec)) return;\n\n this.isFormArtifact = true;\n\n const entityName = getDeclaredFormEntityName(spec);\n if (!entityName) {\n this.formInitError = 'Form artifact has no declared entity. Showing without record context.';\n return;\n }\n\n const provider = this.ProviderToUse;\n const entity = provider?.EntityByName(entityName);\n if (!entity) {\n this.formInitError = `Entity \"${entityName}\" not registered with the active provider.`;\n return;\n }\n this.formEntityInfo = entity;\n\n // Load Top-1 record by default. If empty / fails, fall back to a fresh\n // synthetic record. Either way the form mounts — failure to find a real\n // record is informational, not fatal.\n const record = await this.loadTopOneRecord(entity);\n if (record) {\n this.formRecord = record;\n this.formRecordIsReal = true;\n this.formRecordLabel = this.computeRecordLabel(record);\n } else {\n this.formRecord = await this.buildFixtureRecord(entity);\n this.formRecordIsReal = false;\n this.formRecordLabel = 'Mock data';\n }\n // This runs after an await on a RunView that resolves outside Angular's zone,\n // so nothing would refresh the view until the next user event — leaving the\n // \"Could not bind a record\" message up until the user clicks. Force CD so the\n // auto-loaded record binds and the form mounts immediately on first render.\n this.cdr.detectChanges();\n }\n\n /**\n * Load the first row by NameField (then __mj_CreatedAt) so different users\n * opening the same form-role artifact see the same record bound to the\n * preview. (Retrospective fix #7 — un-ordered Top-1 was physical-order\n * and non-deterministic.)\n */\n private async loadTopOneRecord(entity: EntityInfo): Promise<BaseEntity | null> {\n try {\n const orderBy = entity.NameField?.Name\n ? `${entity.NameField.Name} ASC`\n : `__mj_CreatedAt DESC`;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<BaseEntity>({\n EntityName: entity.Name,\n MaxRows: 1,\n OrderBy: orderBy,\n ResultType: 'entity_object',\n }, this.ProviderToUse.CurrentUser);\n if (result.Success && (result.Results?.length ?? 0) > 0) {\n return result.Results[0];\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: Top-1 RunView failed for ${entity.Name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n return null;\n }\n\n /** Synthetic \"create-mode\" record when no real row exists or RunView failed. */\n private async buildFixtureRecord(entity: EntityInfo): Promise<BaseEntity | null> {\n try {\n const fresh = await this.ProviderToUse.GetEntityObject<BaseEntity>(entity.Name, this.ProviderToUse.CurrentUser);\n fresh.NewRecord();\n return fresh;\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to build fixture record for ${entity.Name}: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n }\n\n /** Pull a human-readable label from the record's NameField or first text field. */\n private computeRecordLabel(record: BaseEntity): string {\n const nameField = record.EntityInfo.NameField?.Name;\n if (nameField) {\n const v = record.Get(nameField);\n if (v != null && String(v).trim().length > 0) return String(v);\n }\n if (record.PrimaryKey?.HasValue) return record.PrimaryKey.ToConcatenatedString();\n return record.EntityInfo.Name;\n }\n\n /**\n * Search-as-you-type for the picker. Queries by name field (or any\n * indexed string field, best-effort). Limits to 8 hits for tightness.\n */\n public async onPickerSearchInput(term: string): Promise<void> {\n this.recordSearchTerm = term;\n if (!this.formEntityInfo || term.trim().length === 0) {\n this.recordSearchResults = [];\n return;\n }\n const nameField = this.formEntityInfo.NameField?.Name;\n if (!nameField) {\n this.recordSearchResults = [];\n return;\n }\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n // Best-effort LIKE filter against the entity's name field. Wrap the\n // term so we don't break SQL — RunView passes ExtraFilter as-is.\n const safe = term.replace(/'/g, \"''\");\n const result = await rv.RunView<BaseEntity>({\n EntityName: this.formEntityInfo.Name,\n ExtraFilter: `${nameField} LIKE '%${safe}%'`,\n MaxRows: 8,\n ResultType: 'entity_object',\n }, this.ProviderToUse.CurrentUser);\n if (result.Success) {\n this.recordSearchResults = (result.Results ?? []).map(r => ({\n ID: r.PrimaryKey?.ToConcatenatedString() ?? '',\n Label: this.computeRecordLabel(r),\n }));\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: picker search failed: ${err instanceof Error ? err.message : String(err)}`);\n this.recordSearchResults = [];\n }\n }\n\n /** User picked a different record from the search results. Re-bind the form. */\n public async onPickerSelect(item: { ID: string; Label: string }): Promise<void> {\n if (!this.formEntityInfo) return;\n try {\n const rec = await this.ProviderToUse.GetEntityObject<BaseEntity>(\n this.formEntityInfo.Name, this.ProviderToUse.CurrentUser,\n );\n const pk = new CompositeKey();\n pk.LoadFromURLSegment(this.formEntityInfo, item.ID);\n const loaded = await rec.InnerLoad(pk);\n if (loaded) {\n this.formRecord = rec;\n this.formRecordIsReal = true;\n this.formRecordLabel = item.Label;\n this.showRecordPicker = false;\n this.recordSearchTerm = '';\n this.recordSearchResults = [];\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to load picked record ${item.ID}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /**\n * Bubble Apply intent up to the host (Form Builder dashboard / Sage chat).\n *\n * Resolves the full ComponentSpec (with code) from multiple sources:\n * 1. resolvedComponentSpec — live React bridge or cached copy (best for non-form artifacts)\n * 2. Re-parse artifact version Content — the agent stores the full spec including code\n * 3. DB fallback — fetch from MJ: Components by name\n *\n * Source #2 covers the common form-artifact case where the React component lives inside\n * <mj-interactive-form> and resolvedComponentSpec falls back to the stripped local spec.\n */\n public async onApplyClicked(): Promise<void> {\n if (!this.formEntityInfo) return;\n\n const spec = await this.resolveSpecWithCode();\n if (!spec) return;\n\n this.applyFormRequested.emit({\n spec,\n entityName: this.formEntityInfo.Name,\n });\n }\n\n /**\n * Resolve a ComponentSpec that includes code, trying multiple sources in order.\n */\n private async resolveSpecWithCode(): Promise<ComponentSpec | null> {\n // 1. Prefer the live React bridge's resolved spec (non-form path).\n const resolved = this.resolvedComponentSpec;\n if (resolved?.code) return resolved;\n\n // 2. For form artifacts, the React component lives inside <mj-interactive-form>.\n // Reach into it to get the resolved spec from the component registry.\n const formReactSpec = this.interactiveForm?.reactComponent?.resolvedComponentSpec;\n if (formReactSpec?.code) return formReactSpec;\n\n // 3. Re-parse the artifact version's Content directly — the agent stores the\n // full spec including code. This handles the case where loadComponentSpec()\n // parsed early (before Content was fully populated) and the in-memory\n // `this.component` ended up without code.\n if (this.artifactVersion?.Content) {\n const freshParse = SafeJSONParse(this.artifactVersion.Content) as ComponentSpec | null;\n if (freshParse?.code) return freshParse;\n }\n\n // 4. DB fallback — fetch from MJ: Components by name.\n const name = resolved?.name ?? this.component?.name;\n if (name) {\n const dbSpec = await this.fetchFullSpecByName(name);\n if (dbSpec?.code) return dbSpec;\n }\n\n LogError('ComponentArtifactViewer: could not resolve spec with code for Apply');\n return null;\n }\n\n /**\n * Fetch the full ComponentSpec (including code) from the MJ: Components table\n * by component name. Returns null if not found or on error.\n */\n private async fetchFullSpecByName(name: string): Promise<ComponentSpec | null> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<{ Specification: string }>({\n EntityName: 'MJ: Components',\n ExtraFilter: `Name='${name.replace(/'/g, \"''\")}'`,\n Fields: ['Specification'],\n OrderBy: 'VersionSequence DESC',\n MaxRows: 1,\n ResultType: 'simple',\n });\n if (result.Success && result.Results?.length > 0 && result.Results[0].Specification) {\n return JSON.parse(result.Results[0].Specification) as ComponentSpec;\n }\n } catch (err) {\n LogError(`ComponentArtifactViewer: failed to fetch full spec for '${name}': ${err instanceof Error ? err.message : String(err)}`);\n }\n return null;\n }\n}\n","<div class=\"component-artifact-viewer\" [ngClass]=\"cssClass\">\n <!-- Component Preview (full screen) -->\n <div class=\"component-preview\">\n @if (hasError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>{{ errorMessage }}</h3>\n <p>This component could not be loaded. This usually happens when:</p>\n <ul style=\"text-align: left; max-width: 500px; color: var(--mj-text-muted); line-height: 1.6;\">\n <li>The component registry is unavailable or unreachable</li>\n <li>The component version does not exist in the registry</li>\n <li>There was a network error during component retrieval</li>\n </ul>\n @if (errorDetails) {\n <details style=\"margin-top: 20px;\">\n <summary>Technical Details</summary>\n <pre>{{ errorDetails }}</pre>\n </details>\n }\n </div>\n } @else if (isFormArtifact) {\n <!-- ════════════════════════════════════════════════\n FORM-AWARE BRANCH\n Spec declares componentRole: 'form'. Render via\n <mj-interactive-form> bound to a real Top-1 record\n (or a synthetic NewRecord fallback). Picker chip\n lets the user swap records; Apply promotes the\n spec to an EntityFormOverride.\n ════════════════════════════════════════════════ -->\n <div class=\"form-artifact-toolstrip\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n <span class=\"form-artifact-toolstrip-label\">Previewing record:</span>\n <button\n type=\"button\"\n class=\"form-artifact-picker-chip\"\n (click)=\"showRecordPicker = !showRecordPicker\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <strong>{{ formRecordLabel || 'No record' }}</strong>\n @if (!formRecordIsReal) {\n <span class=\"form-artifact-picker-chip-badge\">Mock</span>\n }\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n @if (formEntityInfo) {\n <span class=\"form-artifact-toolstrip-entity\">{{ formEntityInfo.DisplayName || formEntityInfo.Name }}</span>\n }\n @if (formInitError) {\n <span class=\"form-artifact-toolstrip-warning\" [title]=\"formInitError\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </span>\n }\n <span style=\"flex: 1;\"></span>\n @if (formEntityInfo) {\n <button\n type=\"button\"\n class=\"form-artifact-apply-btn\"\n (click)=\"onApplyClicked()\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Apply to my form\n </button>\n }\n </div>\n\n @if (showRecordPicker && formEntityInfo) {\n <div class=\"form-artifact-picker-panel\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"text\"\n class=\"form-artifact-picker-search\"\n placeholder=\"Search records by name…\"\n [value]=\"recordSearchTerm\"\n (input)=\"onPickerSearchInput($any($event.target).value)\" />\n @if (recordSearchResults.length > 0) {\n <ul class=\"form-artifact-picker-results\">\n @for (r of recordSearchResults; track r.ID) {\n <li\n class=\"form-artifact-picker-row\"\n (click)=\"onPickerSelect(r)\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n <span>{{ r.Label }}</span>\n </li>\n }\n </ul>\n } @else if (recordSearchTerm.length > 0) {\n <div class=\"form-artifact-picker-empty\">No matches.</div>\n } @else {\n <div class=\"form-artifact-picker-empty\">Start typing to search.</div>\n }\n </div>\n }\n\n @if (formRecord && component) {\n <div class=\"form-artifact-form-host\">\n <mj-interactive-form\n #interactiveForm\n [componentSpec]=\"component\"\n [record]=\"formRecord\">\n </mj-interactive-form>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>Form preview unavailable</h3>\n <p>{{ formInitError || 'Could not bind a record to this form.' }}</p>\n </div>\n }\n } @else if (isPermissionBlocked) {\n <!-- Permission warning — user lacks access to one or more data sources -->\n <div class=\"permission-warning\">\n <div class=\"permission-warning-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <h3>Insufficient Permissions</h3>\n <p>This component requires data access that you don't currently have:</p>\n\n @if (permissionResult!.missingEntities.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Entities</span>\n <ul>\n @for (entity of permissionResult!.missingEntities; track entity) {\n <li><i class=\"fa-solid fa-table\"></i> {{ entity }}</li>\n }\n </ul>\n </div>\n }\n\n @if (permissionResult!.missingQueries.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Queries</span>\n <ul>\n @for (query of permissionResult!.missingQueries; track query) {\n <li><i class=\"fa-solid fa-database\"></i> {{ query }}</li>\n }\n </ul>\n </div>\n }\n\n <p class=\"permission-warning-hint\">Contact your administrator to request access.</p>\n </div>\n } @else {\n <!-- Default (non-form) interactive component path -->\n @if (component && (component.code || component.namespace)) {\n <mj-react-component\n #reactComponent\n [component]=\"component\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (initialized)=\"onReactComponentInitialized()\">\n </mj-react-component>\n } @else if (component) {\n <!-- Component spec exists but no code - show informational message -->\n <div class=\"no-code-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <h3>Component Specification</h3>\n <p>This component has specifications but no executable code yet.</p>\n <p>View the Functional, Data, or Spec tabs for details.</p>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>No Component Loaded</h3>\n <p>The component data is missing or invalid.</p>\n </div>\n }\n }\n </div>\n\n <!-- Feedback overlay panel (invoked from header button via AskUserForFeedback) -->\n @if (ShowFeedbackPanel && resolvedComponentSpec) {\n <mj-component-feedback-panel\n [ComponentSpec]=\"resolvedComponentSpec\"\n [ReactContainerElement]=\"reactComponent?.container?.nativeElement || null\"\n (Closed)=\"ShowFeedbackPanel = false\">\n </mj-component-feedback-panel>\n }\n</div>\n"]}
|
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { Component, Output, EventEmitter } from '@angular/core';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
-
import { DataSnapshot, NormalizeToTables,
|
|
9
|
+
import { DataSnapshot, NormalizeToTables, CompositeKey, KeyValuePair } from '@memberjunction/core';
|
|
10
10
|
import { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';
|
|
11
11
|
import { resolveTargetEntity } from '@memberjunction/ng-query-viewer';
|
|
12
12
|
import { BaseArtifactViewerPluginComponent } from '../base-artifact-viewer.component';
|
|
@@ -608,7 +608,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
608
608
|
if (table.metadata?.sql) {
|
|
609
609
|
// Live SQL execution
|
|
610
610
|
const pageState = this.tablePageState.get(tableIndex);
|
|
611
|
-
const rq =
|
|
611
|
+
const rq = this.RunQueryToUse;
|
|
612
612
|
const startRow = (pageState.pageNumber - 1) * pageState.pageSize;
|
|
613
613
|
const result = await rq.RunQuery({
|
|
614
614
|
SQL: table.metadata.sql,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts","../../../../src/lib/components/plugins/data-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot, DataTable, DataComputation, MJColumnDescriptor, NormalizeToTables, Metadata, RunQuery, CompositeKey, KeyValuePair } from '@memberjunction/core';\nimport { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';\nimport { QueryGridColumnConfig, QueryEntityLinkClickEvent, resolveTargetEntity } from '@memberjunction/ng-query-viewer';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab, NavigationRequest } from '../base-artifact-viewer.component';\nimport { SaveQueryResult } from './save-query-dialog.component';\nimport { createDataSnapshot, buildMultiTableSql } from '../../snapshot-helpers';\n\n/**\n * Data artifact content shape as parsed from JSON.\n *\n * Core tabular data fields (source, columns, rows, tables, metadata, etc.)\n * are handled by NormalizeToTables() from @memberjunction/core.\n * This interface adds viewer-specific fields for query sync and display.\n *\n * Columns may use either `displayName` (new) or `headerName` (legacy).\n * BuildColumnConfigsForTable handles both.\n */\ninterface DataArtifactSpec {\n source?: 'query' | 'view';\n title?: string;\n queryId?: string;\n parameters?: Record<string, string | number | boolean>;\n entityName?: string;\n extraFilter?: string;\n columns?: Array<MJColumnDescriptor & { headerName?: string }>;\n rows?: Record<string, unknown>[];\n tables?: DataTable[];\n plan?: string;\n interpretation?: string;\n computations?: DataComputation[];\n metadata?: { sql?: string; rowCount?: number; executionTimeMs?: number };\n savedQueryId?: string;\n savedQueryName?: string;\n savedAtVersionNumber?: number;\n}\n\n/**\n * Describes the relationship between the current artifact version's SQL\n * and the saved query record. Drives the toolbar UI.\n */\ntype QuerySyncState =\n | 'no-query-latest' // No saved query, viewing latest version → show \"Save Query\"\n | 'no-query-older' // No saved query, viewing older version → no actions\n | 'synced' // SQL matches saved query → green badge + \"Open Query\"\n | 'outdated-latest' // SQL differs, viewing latest → amber badge + dropdown\n | 'query-ahead' // Viewing older version, query was updated at a newer version\n | 'query-behind'; // Viewing middle version, saved at older, not latest → muted\n\n/**\n * Viewer component for Data artifacts.\n *\n * Displays tabular data using AG Grid via mj-query-data-grid. Supports two modes:\n * 1. **Live data**: When metadata.sql is present, executes the query dynamically via RunQuery({ SQL })\n * to fetch fresh data on each view. Falls back to inline rows on error.\n * 2. **Inline data**: Rows embedded directly in the artifact JSON (backward compat with older artifacts)\n *\n * The Query Builder agent emits artifacts with metadata.sql for live execution.\n */\n@Component({\n standalone: false,\n selector: 'mj-data-artifact-viewer',\n templateUrl: './data-artifact-viewer.component.html',\n styleUrls: ['./data-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'DataArtifactViewerPlugin')\nexport class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit {\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() override navigationRequest = new EventEmitter<NavigationRequest>();\n public override tabsChanged = new EventEmitter<void>();\n\n public spec: DataArtifactSpec | null = null;\n public GridData: Record<string, unknown>[] = [];\n public GridColumnConfigs: QueryGridColumnConfig[] | null = null;\n public IsLoading = false;\n public IsLive = false;\n public HasError = false;\n public ErrorMessage = '';\n public ShowSaveDialog = false;\n public ShowUpdateDropdown = false;\n public IsSaving = false;\n public SavingMessage = '';\n\n /** Paging state — passed through to mj-query-data-grid's embedded pager */\n public PagerTotalRowCount = 0;\n public PagerPageNumber = 1;\n public PagerPageSize = 100;\n\n // ─── Multi-Table State ───\n\n /** All resolved tables (from multi-table or wrapped single-table) */\n public ResolvedTables: DataTable[] = [];\n\n /** Index of the currently active table tab */\n public ActiveTableIndex = 0;\n\n /** Per-table paging state */\n private tablePageState: Map<number, { pageNumber: number; pageSize: number; totalRowCount: number }> = new Map();\n\n /** Per-table live data cache (loaded lazily on tab switch) */\n private tableDataCache: Map<number, Record<string, unknown>[]> = new Map();\n\n /** Per-table column configs cache */\n private tableColumnConfigsCache: Map<number, QueryGridColumnConfig[]> = new Map();\n\n /** Whether we're in multi-table mode */\n public get IsMultiTable(): boolean {\n return this.ResolvedTables.length > 1;\n }\n\n /** The currently active table */\n public get ActiveTable(): DataTable | null {\n return this.ResolvedTables[this.ActiveTableIndex] ?? null;\n }\n\n /** Query sync state — drives the toolbar UI for saved query actions */\n public QuerySyncState: QuerySyncState = 'no-query-latest';\n\n /** Latest version number for this artifact (from cache) */\n public LatestVersionNumber = 0;\n\n /** Metadata from live execution (overrides spec.metadata when live) */\n private liveRowCount: number | null = null;\n private liveExecutionTime: number | null = null;\n\n /** SQL from the saved query record (for comparison) */\n private savedQuerySql: string | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return this.spec != null && (this.HasData || this.IsLoading || this.ResolvedTables.length > 0);\n }\n\n public override get parentShouldShowRawContent(): boolean {\n return true;\n }\n\n public get HasData(): boolean {\n return this.GridData.length > 0;\n }\n\n public get HasInlineData(): boolean {\n // Check root-level rows (legacy single-table) or any resolved table with rows\n return !!(this.spec?.rows && this.spec.rows.length > 0) ||\n this.ResolvedTables.some(t => t.rows && t.rows.length > 0);\n }\n\n public get DisplayRowCount(): number | null {\n // In live/paged mode the pager tracks the TRUE total row count\n // (PagerTotalRowCount, from RunQueryResult.TotalRowCount) — surface that as\n // the headline count so the title reflects the full result size, not just the\n // current page (which the bottom pager already shows as a range). Falls back\n // to the page/inline row count when there's no paged total.\n if (this.PagerTotalRowCount > 0) {\n return this.PagerTotalRowCount;\n }\n return this.liveRowCount ?? this.spec?.metadata?.rowCount ?? null;\n }\n\n public get DisplayExecutionTime(): number | null {\n return this.liveExecutionTime ?? this.spec?.metadata?.executionTimeMs ?? null;\n }\n\n /** Current artifact version number */\n public get CurrentVersionNumber(): number {\n return this.artifactVersion?.VersionNumber || 1;\n }\n\n /** Whether this is the latest version of the artifact */\n public get IsLatestVersion(): boolean {\n return this.CurrentVersionNumber === this.LatestVersionNumber;\n }\n\n /**\n * The effective version number at which the query was last saved/updated.\n * When viewing an older version, this looks ahead through newer versions\n * to find the most recent savedAtVersionNumber for the same query,\n * giving the user accurate context (e.g., \"Query updated at v3\" instead\n * of the stale \"Saved at v1\" from this version's snapshot).\n */\n public EffectiveSavedAtVersion: number | null = null;\n\n /** Alias used by the template */\n public get SavedAtVersion(): number | null {\n return this.EffectiveSavedAtVersion;\n }\n\n /** Display name for the saved query */\n public get SavedQueryDisplayName(): string {\n return this.spec?.savedQueryName || 'Saved Query';\n }\n\n async ngOnInit(): Promise<void> {\n try {\n this.spec = this.parseJsonContent<DataArtifactSpec>();\n if (!this.spec) {\n this.HasError = true;\n this.ErrorMessage = 'Failed to parse data artifact content';\n return;\n }\n\n // Resolve to tables array (handles both single and multi-table)\n this.ResolvedTables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n\n if (this.ResolvedTables.length === 0 && !this.spec.plan) {\n return;\n }\n\n // Build enriched column configs for the first table\n if (this.ResolvedTables.length > 0) {\n this.GridColumnConfigs = this.BuildColumnConfigsForTable(this.ResolvedTables[0]);\n }\n\n // Initialize paging state for all tables\n for (let i = 0; i < this.ResolvedTables.length; i++) {\n this.tablePageState.set(i, { pageNumber: 1, pageSize: 100, totalRowCount: 0 });\n }\n\n // Set loading early (synchronously) so hasDisplayContent is true immediately\n if (this.ResolvedTables.some(t => t.metadata?.sql) || this.HasInlineData) {\n this.IsLoading = true;\n }\n\n // Load cached metadata and resolve query sync state\n await this.InitQuerySyncState();\n\n // Load data for the first (active) table\n if (this.ResolvedTables.length > 0) {\n await this.LoadTableData(0);\n }\n\n // Signal parent that tabs/display content may have changed after async load\n this.tabsChanged.emit();\n } catch (error) {\n this.HasError = true;\n this.ErrorMessage = error instanceof Error ? error.message : 'Failed to load data';\n }\n }\n\n /**\n * Re-execute the live SQL query for the active table\n */\n public async OnRefresh(): Promise<void> {\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Handle entity link click from the grid and bubble up as openEntityRecord.\n * Converts the grid's recordId string into a CompositeKey for the artifact viewer pipeline.\n */\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === event.entityName);\n const pkFieldName = entity?.FirstPrimaryKey?.Name ?? 'ID';\n\n const compositeKey = new CompositeKey([\n new KeyValuePair(pkFieldName, event.recordId)\n ]);\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey\n });\n }\n\n /**\n * Handle page change from the data grid's embedded pager.\n * Re-executes the query for the active table with new page parameters.\n */\n public async OnPageChange(event: PageChangeEvent): Promise<void> {\n const pageState = this.tablePageState.get(this.ActiveTableIndex);\n if (!pageState) return;\n\n pageState.pageNumber = event.PageNumber;\n pageState.pageSize = event.PageSize;\n\n // Clear cache so it reloads\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Switch to a different table tab.\n * Loads data lazily if not already cached.\n */\n public async OnTableTabClick(index: number): Promise<void> {\n if (index === this.ActiveTableIndex) return;\n this.ActiveTableIndex = index;\n\n const table = this.ResolvedTables[index];\n if (!table) return;\n\n // Use cached column configs or build new\n if (!this.tableColumnConfigsCache.has(index)) {\n const configs = this.BuildColumnConfigsForTable(table);\n if (configs) this.tableColumnConfigsCache.set(index, configs);\n }\n this.GridColumnConfigs = this.tableColumnConfigsCache.get(index) ?? null;\n\n // Use cached data or load fresh\n if (this.tableDataCache.has(index)) {\n this.GridData = this.tableDataCache.get(index)!;\n const pageState = this.tablePageState.get(index)!;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n this.PagerTotalRowCount = pageState.totalRowCount;\n } else {\n await this.LoadTableData(index);\n }\n\n this.cdr.detectChanges();\n }\n\n /**\n * Load data for a specific table.\n * Handles live SQL execution, inline rows, and caching.\n */\n private async LoadTableData(tableIndex: number): Promise<void> {\n const table = this.ResolvedTables[tableIndex];\n if (!table) return;\n\n this.IsLoading = true;\n this.HasError = false;\n this.cdr.detectChanges();\n\n try {\n if (table.metadata?.sql) {\n // Live SQL execution\n const pageState = this.tablePageState.get(tableIndex)!;\n const rq = new RunQuery();\n const startRow = (pageState.pageNumber - 1) * pageState.pageSize;\n const result = await rq.RunQuery({\n SQL: table.metadata.sql,\n StartRow: startRow,\n MaxRows: pageState.pageSize\n });\n\n if (result.Success) {\n this.tableDataCache.set(tableIndex, result.Results);\n this.GridData = result.Results;\n this.IsLive = true;\n\n pageState.totalRowCount = result.TotalRowCount ?? result.RowCount ?? 0;\n this.PagerTotalRowCount = pageState.totalRowCount;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n\n this.liveRowCount = result.RowCount;\n this.liveExecutionTime = result.ExecutionTime;\n } else {\n this.HandleTableError(tableIndex, result.ErrorMessage || 'Query failed');\n }\n } else if (table.rows && table.rows.length > 0) {\n // Inline data\n this.tableDataCache.set(tableIndex, table.rows);\n this.GridData = table.rows;\n this.liveRowCount = table.rows.length;\n } else {\n this.GridData = [];\n }\n } catch (error) {\n this.HandleTableError(tableIndex, error instanceof Error ? error.message : 'Load failed');\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Build QueryGridColumnConfig[] from a DataTable's column metadata.\n * Returns null if columns have no entity metadata (grid falls back to auto-inference).\n */\n private BuildColumnConfigsForTable(table: DataTable): QueryGridColumnConfig[] | null {\n const columns = table.columns;\n if (!columns?.length) return null;\n\n // Only build if at least one column has entity metadata or type info\n const hasMetadata = columns.some(c => c.sourceEntity || c.sqlBaseType);\n if (!hasMetadata) return null;\n\n const md = this.ProviderToUse;\n return columns.map((col, index) => {\n const target = resolveTargetEntity(col.sourceEntity, col.sourceFieldName, md);\n const isEntityLink = !!(target.targetEntityName && (target.isPrimaryKey || target.isForeignKey));\n const baseType = (col.sqlBaseType || 'nvarchar').toLowerCase();\n\n let align: 'left' | 'center' | 'right' = 'left';\n if (['int', 'bigint', 'decimal', 'numeric', 'float', 'money', 'smallmoney', 'real'].includes(baseType)) {\n align = 'right';\n } else if (baseType === 'bit') {\n align = 'center';\n }\n\n // Support both displayName (new) and headerName (legacy) for backward compat\n const colAny = col as unknown as Record<string, unknown>;\n const title = col.displayName || (colAny['headerName'] as string) || col.field;\n\n return {\n field: col.field,\n title,\n visible: true,\n sortable: true,\n resizable: true,\n reorderable: true,\n sqlBaseType: col.sqlBaseType || 'nvarchar',\n sqlFullType: col.sqlFullType || col.sqlBaseType || 'nvarchar',\n align,\n order: index,\n sourceEntityName: col.sourceEntity,\n sourceFieldName: col.sourceFieldName,\n isEntityLink,\n targetEntityName: target.targetEntityName,\n targetEntityId: target.targetEntityId,\n targetEntityIcon: target.targetEntityIcon,\n isPrimaryKey: target.isPrimaryKey,\n isForeignKey: target.isForeignKey,\n pinned: null,\n } as QueryGridColumnConfig;\n });\n }\n\n /**\n * Handle a table load error by setting error state and falling back to inline data\n */\n private HandleTableError(tableIndex: number, message: string): void {\n this.HasError = true;\n this.ErrorMessage = message;\n const table = this.ResolvedTables[tableIndex];\n if (table?.rows && table.rows.length > 0) {\n this.GridData = table.rows;\n }\n }\n\n // ─── Query Sync State ────────────────────────────────────────────\n\n /**\n * Initialize query sync state by loading cached metadata.\n * Resolves the latest version number and compares saved query SQL.\n */\n private async InitQuerySyncState(): Promise<void> {\n // Ensure the artifact-type registry is loaded (not registered for startup).\n await ArtifactMetadataEngine.Instance.Config(false);\n\n // Load THIS artifact's versions on demand (including Content, which\n // resolveEffectiveSavedAtVersion parses). Versions are no longer bulk-loaded\n // at boot — the payload here is bounded to a single artifact's versions.\n if (this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID);\n }\n\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n\n // If the loaded versions don't yet include the one we're viewing (a newer\n // version was created after we first loaded), force a re-fetch and re-resolve.\n if (this.LatestVersionNumber < this.CurrentVersionNumber && this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID, undefined, undefined, true);\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n }\n\n this.EffectiveSavedAtVersion = this.resolveEffectiveSavedAtVersion();\n await this.resolveSavedQuerySql();\n this.QuerySyncState = this.computeQuerySyncState();\n }\n\n /**\n * Determine the latest version number for this artifact from cache.\n * Falls back to current version if cache miss.\n */\n private resolveLatestVersionNumber(): number {\n if (!this.artifactVersion?.ArtifactID) {\n return this.CurrentVersionNumber;\n }\n\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n if (versions.length > 0) {\n // GetCachedVersionsForArtifact returns DESC sorted\n return versions[0].VersionNumber || 1;\n }\n\n // Cache miss — current version is our best guess\n return this.CurrentVersionNumber;\n }\n\n /**\n * Scan all versions of this artifact to find the most recent savedAtVersionNumber\n * for the same savedQueryId. When viewing an older version, this tells the user\n * where the query was *actually* last updated, not just what this version's\n * snapshot recorded at the time.\n */\n private resolveEffectiveSavedAtVersion(): number | null {\n const queryId = this.spec?.savedQueryId;\n if (!queryId) return null;\n\n // Start with this version's own value\n let effective = this.spec?.savedAtVersionNumber ?? null;\n\n if (!this.artifactVersion?.ArtifactID) return effective;\n\n // GetCachedVersionsForArtifact returns DESC sorted — scan all versions\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n for (const v of versions) {\n try {\n if (!v.Content) continue;\n const content = typeof v.Content === 'string' ? JSON.parse(v.Content) : v.Content;\n if (content.savedQueryId === queryId && content.savedAtVersionNumber != null) {\n const vSavedAt = content.savedAtVersionNumber as number;\n if (effective == null || vSavedAt > effective) {\n effective = vSavedAt;\n }\n }\n } catch {\n // Skip versions with unparseable content\n }\n }\n\n return effective;\n }\n\n /**\n * Look up the saved query's SQL from QueryEngine cache for comparison.\n * Only fetches if savedQueryId is present.\n */\n private async resolveSavedQuerySql(): Promise<void> {\n if (!this.spec?.savedQueryId) {\n this.savedQuerySql = null;\n return;\n }\n\n // QueryEngine is registered for startup, should already be loaded\n let query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n\n if (!query) {\n // Cache miss — force refresh and retry\n await QueryEngine.Instance.Config(true);\n query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n }\n\n this.savedQuerySql = query?.SQL ?? null;\n }\n\n /**\n * Compute the query sync state from current spec, version, and saved query SQL.\n * Implements the decision tree from the UX design.\n */\n private computeQuerySyncState(): QuerySyncState {\n const hasSavedQuery = !!this.spec?.savedQueryId;\n const isLatest = this.IsLatestVersion;\n\n if (!hasSavedQuery) {\n return isLatest ? 'no-query-latest' : 'no-query-older';\n }\n\n // Compare SQL (normalize whitespace for reliable comparison)\n const specSql = this.normalizeSql(this.spec?.metadata?.sql);\n const querySql = this.normalizeSql(this.savedQuerySql);\n const sqlMatches = specSql != null && querySql != null && specSql === querySql;\n\n // Only truly synced if SQL matches AND this is the version it was saved at.\n // Even with identical SQL, a newer version should show the dropdown so the\n // user can update the version association (re-save at current version).\n const savedAtCurrent = this.EffectiveSavedAtVersion === this.CurrentVersionNumber;\n if (sqlMatches && savedAtCurrent) {\n return 'synced';\n }\n\n // SQL differs — determine position relative to saved version\n if (isLatest) {\n return 'outdated-latest';\n }\n\n // Use effective saved-at (looks ahead through newer versions)\n const savedAt = this.EffectiveSavedAtVersion;\n if (savedAt != null && this.CurrentVersionNumber < savedAt) {\n return 'query-ahead'; // query was updated at a newer version\n }\n\n return 'query-behind'; // ahead of saved but not latest\n }\n\n /** Normalize SQL for comparison: trim and collapse whitespace */\n private normalizeSql(sql: string | null | undefined): string | null {\n if (sql == null) return null;\n return sql.trim().replace(/\\s+/g, ' ');\n }\n\n // ─── Actions ────────────────────────────────────────────────────\n\n /** Navigate to the saved query in the Data Explorer's Queries browser */\n public OnOpenSavedQuery(): void {\n if (!this.spec?.savedQueryId) return;\n this.navigationRequest.emit({\n appName: 'Data Explorer',\n navItemName: 'Queries',\n queryParams: { queryId: this.spec.savedQueryId }\n });\n }\n\n /** Show the save panel for creating a brand-new query */\n public OnShowSaveDialog(): void {\n this.ShowSaveDialog = true;\n this.ShowUpdateDropdown = false;\n }\n\n /** Toggle the update query dropdown */\n public OnToggleUpdateDropdown(): void {\n this.ShowUpdateDropdown = !this.ShowUpdateDropdown;\n }\n\n /** Close the dropdown (e.g., on outside click) */\n public OnCloseDropdown(): void {\n this.ShowUpdateDropdown = false;\n }\n\n /**\n * Update the existing saved query's SQL to match this version.\n * Only available from the latest version (Scenario 3).\n */\n public async OnUpdateExistingQuery(): Promise<void> {\n this.ShowUpdateDropdown = false;\n if (!this.spec?.savedQueryId || !this.spec.metadata?.sql) return;\n\n this.IsSaving = true;\n this.SavingMessage = `Updating \"${this.SavedQueryDisplayName}\"...`;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n const query = await md.GetEntityObject<import('@memberjunction/core-entities').MJQueryEntity>('MJ: Queries');\n const loaded = await query.Load(this.spec.savedQueryId);\n\n if (!loaded) {\n console.error('Failed to load saved query for update');\n return;\n }\n\n query.SQL = this.spec.metadata.sql;\n if (this.spec.plan?.trim()) {\n query.TechnicalDescription = this.spec.plan.trim();\n }\n const saved = await query.Save();\n\n if (saved) {\n // Update spec with new version tracking\n this.spec.savedAtVersionNumber = this.CurrentVersionNumber;\n await this.PersistArtifactContent();\n\n // Refresh caches so future lookups see the updated data\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n\n this.savedQuerySql = this.spec.metadata.sql;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n }\n } catch (error) {\n console.error('Failed to update saved query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Save as a new query (from the dropdown).\n * Opens the save dialog which creates a fresh query record.\n */\n public OnSaveAsNewQuery(): void {\n this.ShowUpdateDropdown = false;\n this.ShowSaveDialog = true;\n }\n\n /** Handle successful save from the dialog (both initial save and \"save as new\") */\n public async OnQuerySaved(event: SaveQueryResult): Promise<void> {\n this.ShowSaveDialog = false;\n this.IsSaving = true;\n this.SavingMessage = 'Saving query...';\n this.cdr.detectChanges();\n\n try {\n // Update spec with saved query info and version tracking\n this.spec!.savedQueryId = event.queryId;\n this.spec!.savedQueryName = event.queryName;\n this.spec!.savedAtVersionNumber = this.CurrentVersionNumber;\n\n // Persist and refresh caches\n await this.PersistArtifactContent();\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n await this.ProviderToUse.Refresh();\n\n this.savedQuerySql = this.spec!.metadata?.sql ?? null;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n } catch (error) {\n console.error('Failed to save query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Persist updated spec back to the artifact version entity */\n private async PersistArtifactContent(): Promise<void> {\n if (!this.artifactVersion || !this.spec) return;\n this.artifactVersion.Content = JSON.stringify(this.spec);\n await this.artifactVersion.Save();\n }\n\n /**\n * Returns a DataSnapshot with live grid data, current page state,\n * and query sync state.\n */\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n if (!this.spec) return null;\n\n const tables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n const activeTable = tables[this.ActiveTableIndex];\n\n if (activeTable) {\n // Override with live data for the active table\n if (this.IsLive) activeTable.rows = this.GridData;\n activeTable.pageNumber = this.PagerPageNumber;\n activeTable.metadata = {\n ...activeTable.metadata,\n ...(this.liveRowCount != null ? { rowCount: this.liveRowCount } : {}),\n ...(this.liveExecutionTime != null\n ? { executionTimeMs: this.liveExecutionTime } : {}),\n ...(this.PagerTotalRowCount > 0\n ? { totalAvailableRows: this.PagerTotalRowCount } : {}),\n pageSize: this.PagerPageSize\n };\n }\n\n return DataSnapshot.FromTables(tables, this.spec.title);\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────\n\n /**\n * Provide Plan tab (markdown), SQL tab (code), and Interpretation tab when available\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n if (this.spec?.plan) {\n tabs.push({\n label: 'Plan',\n icon: 'fa-diagram-project',\n contentType: 'markdown',\n content: this.spec.plan\n });\n }\n\n // SQL tab — multi-table shows all queries with headers\n if (this.IsMultiTable) {\n const multiSql = buildMultiTableSql(this.ResolvedTables);\n if (multiSql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: multiSql\n });\n }\n } else if (this.spec?.metadata?.sql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: this.spec.metadata.sql\n });\n }\n\n // Interpretation tab\n if (this.spec?.interpretation) {\n tabs.push({\n label: 'Interpretation',\n icon: 'fa-lightbulb',\n contentType: 'markdown',\n content: this.spec.interpretation\n });\n }\n\n return tabs;\n }\n}\n","<div class=\"data-artifact-viewer\" [ngClass]=\"cssClass\">\n @if (spec) {\n @if (HasData || IsLoading || ResolvedTables.length > 0) {\n <!-- Toolbar -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-table\"></i>\n <span>{{ spec.title || \"Data Results\" }}</span>\n @if (IsLive) {\n <span class=\"live-badge\">Live</span>\n }\n @if (DisplayRowCount != null) {\n <span class=\"row-count\">{{ DisplayRowCount | number }} rows</span>\n }\n @if (DisplayExecutionTime != null) {\n <span class=\"exec-time\">{{ DisplayExecutionTime }}ms</span>\n }\n </div>\n <div class=\"data-actions\">\n @if (IsLive) {\n <button class=\"btn-icon\" title=\"Refresh data\" (click)=\"OnRefresh()\" [disabled]=\"IsLoading\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i> Refresh\n </button>\n }\n\n @switch (QuerySyncState) {\n <!-- S1: No saved query, latest version → Save Query -->\n @case (\"no-query-latest\") {\n <button class=\"btn-icon btn-save\" title=\"Save as reusable query\" (click)=\"OnShowSaveDialog()\"><i class=\"fas fa-save\"></i> Save Query</button>\n }\n\n <!-- S2: SQL matches → green badge + Open -->\n @case (\"synced\") {\n <span class=\"query-badge query-badge-synced\"> <i class=\"fas fa-check\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-open\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S3: SQL differs, latest version → amber badge + dropdown -->\n @case (\"outdated-latest\") {\n <span class=\"query-badge query-badge-outdated\"> <i class=\"fas fa-circle-exclamation\"></i> Saved at v{{ SavedAtVersion }} </span>\n <div class=\"dropdown-wrapper\">\n <button class=\"btn-icon btn-warning\" title=\"Update or save query\" (click)=\"OnToggleUpdateDropdown()\">\n <i class=\"fas fa-save\"></i> Update Query <i class=\"fas fa-caret-down\"></i>\n </button>\n @if (ShowUpdateDropdown) {\n <div class=\"query-dropdown\" (click)=\"$event.stopPropagation()\">\n <div class=\"query-dropdown-item\" (click)=\"OnUpdateExistingQuery()\">\n <i class=\"fas fa-arrow-up-from-bracket\" style=\"color: #d97706\"></i>\n <div>\n <div class=\"dropdown-label\">Update \"{{ SavedQueryDisplayName }}\"</div>\n <div class=\"dropdown-desc\">Replace saved query SQL with this version's SQL</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnSaveAsNewQuery()\">\n <i class=\"fas fa-plus\" style=\"color: #16a34a\"></i>\n <div>\n <div class=\"dropdown-label\">Save as New Query</div>\n <div class=\"dropdown-desc\">Create a new query, keep the original unchanged</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnOpenSavedQuery(); OnCloseDropdown()\">\n <i class=\"fas fa-external-link-alt\" style=\"color: var(--mj-text-muted)\"></i>\n <div>\n <div class=\"dropdown-label\">Open Saved Query</div>\n <div class=\"dropdown-desc\">View \"{{ SavedQueryDisplayName }}\" (saved at v{{ SavedAtVersion }})</div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- S4: Older version, query was updated ahead -->\n @case (\"query-ahead\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Query updated at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S5: Middle version, saved at older, not latest -->\n @case (\"query-behind\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S6: No saved query, older version → no actions -->\n @case (\"no-query-older\") {\n <!-- No query actions available on older versions -->\n }\n }\n </div>\n </div>\n\n <!-- Multi-table tab strip -->\n @if (IsMultiTable) {\n <div class=\"table-tabs\">\n @for (table of ResolvedTables; track table.name; let i = $index) {\n <button class=\"table-tab\" [class.active]=\"i === ActiveTableIndex\" [title]=\"table.description || table.name\" (click)=\"OnTableTabClick(i)\">\n <span class=\"table-tab-name\">{{ table.name }}</span>\n @if (table.metadata?.rowCount != null || table.rows.length) {\n <span class=\"table-tab-count\"> ({{ table.metadata?.rowCount ?? table.rows.length }} rows) </span>\n }\n </button>\n }\n </div>\n }\n\n <!-- Computations summary bar -->\n @if (spec.computations?.length) {\n <div class=\"computations-bar\">\n @for (comp of spec.computations; track comp.name) {\n @if (!IsMultiTable || !comp.table || comp.table === ActiveTable?.name) {\n <div class=\"computation-chip\" [title]=\"comp.description || comp.name\">\n <span class=\"computation-label\">{{ comp.name }}</span>\n <span class=\"computation-value\">\n {{ comp.formattedValue || comp.value }}\n </span>\n </div>\n }\n }\n </div>\n }\n\n <!-- Grid -->\n <div class=\"grid-container\">\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading [text]=\"SavingMessage\"></mj-loading>\n </div>\n }\n @if (IsLoading) {\n <mj-loading text=\"Loading data...\"></mj-loading>\n } @else if (HasError && HasData) {\n <mj-alert Variant=\"warning\" Size=\"sm\" class=\"data-artifact-alert-pos\">\n {{ ErrorMessage }}\n <span class=\"fallback-note\">(Showing cached data)</span>\n </mj-alert>\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n }\n </div>\n } @else if (spec.plan) {\n <!-- Plan-only view (no results yet) -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-diagram-project\"></i>\n <span>{{ spec.title || \"Query Plan\" }}</span>\n </div>\n </div>\n <div class=\"plan-content\">\n <mj-markdown [data]=\"spec.plan\" [enableMermaid]=\"true\" [enableHighlight]=\"true\" [enableCollapsibleHeadings]=\"false\" [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n } @else {\n <!-- No data and no plan -->\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n\n <!-- Save Query Panel (slide-in) -->\n @if (ShowSaveDialog) {\n <mj-save-query-panel\n [QueryName]=\"spec?.title || 'Untitled Query'\"\n [QueryDescription]=\"''\"\n [SQL]=\"spec?.metadata?.sql || ''\"\n [Plan]=\"spec?.plan || ''\"\n (Saved)=\"OnQuerySaved($event)\"\n (Cancelled)=\"ShowSaveDialog = false\"\n >\n </mj-save-query-panel>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"data-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts","../../../../src/lib/components/plugins/data-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot, DataTable, DataComputation, MJColumnDescriptor, NormalizeToTables, Metadata, RunQuery, CompositeKey, KeyValuePair } from '@memberjunction/core';\nimport { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';\nimport { QueryGridColumnConfig, QueryEntityLinkClickEvent, resolveTargetEntity } from '@memberjunction/ng-query-viewer';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab, NavigationRequest } from '../base-artifact-viewer.component';\nimport { SaveQueryResult } from './save-query-dialog.component';\nimport { createDataSnapshot, buildMultiTableSql } from '../../snapshot-helpers';\n\n/**\n * Data artifact content shape as parsed from JSON.\n *\n * Core tabular data fields (source, columns, rows, tables, metadata, etc.)\n * are handled by NormalizeToTables() from @memberjunction/core.\n * This interface adds viewer-specific fields for query sync and display.\n *\n * Columns may use either `displayName` (new) or `headerName` (legacy).\n * BuildColumnConfigsForTable handles both.\n */\ninterface DataArtifactSpec {\n source?: 'query' | 'view';\n title?: string;\n queryId?: string;\n parameters?: Record<string, string | number | boolean>;\n entityName?: string;\n extraFilter?: string;\n columns?: Array<MJColumnDescriptor & { headerName?: string }>;\n rows?: Record<string, unknown>[];\n tables?: DataTable[];\n plan?: string;\n interpretation?: string;\n computations?: DataComputation[];\n metadata?: { sql?: string; rowCount?: number; executionTimeMs?: number };\n savedQueryId?: string;\n savedQueryName?: string;\n savedAtVersionNumber?: number;\n}\n\n/**\n * Describes the relationship between the current artifact version's SQL\n * and the saved query record. Drives the toolbar UI.\n */\ntype QuerySyncState =\n | 'no-query-latest' // No saved query, viewing latest version → show \"Save Query\"\n | 'no-query-older' // No saved query, viewing older version → no actions\n | 'synced' // SQL matches saved query → green badge + \"Open Query\"\n | 'outdated-latest' // SQL differs, viewing latest → amber badge + dropdown\n | 'query-ahead' // Viewing older version, query was updated at a newer version\n | 'query-behind'; // Viewing middle version, saved at older, not latest → muted\n\n/**\n * Viewer component for Data artifacts.\n *\n * Displays tabular data using AG Grid via mj-query-data-grid. Supports two modes:\n * 1. **Live data**: When metadata.sql is present, executes the query dynamically via RunQuery({ SQL })\n * to fetch fresh data on each view. Falls back to inline rows on error.\n * 2. **Inline data**: Rows embedded directly in the artifact JSON (backward compat with older artifacts)\n *\n * The Query Builder agent emits artifacts with metadata.sql for live execution.\n */\n@Component({\n standalone: false,\n selector: 'mj-data-artifact-viewer',\n templateUrl: './data-artifact-viewer.component.html',\n styleUrls: ['./data-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'DataArtifactViewerPlugin')\nexport class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit {\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() override navigationRequest = new EventEmitter<NavigationRequest>();\n public override tabsChanged = new EventEmitter<void>();\n\n public spec: DataArtifactSpec | null = null;\n public GridData: Record<string, unknown>[] = [];\n public GridColumnConfigs: QueryGridColumnConfig[] | null = null;\n public IsLoading = false;\n public IsLive = false;\n public HasError = false;\n public ErrorMessage = '';\n public ShowSaveDialog = false;\n public ShowUpdateDropdown = false;\n public IsSaving = false;\n public SavingMessage = '';\n\n /** Paging state — passed through to mj-query-data-grid's embedded pager */\n public PagerTotalRowCount = 0;\n public PagerPageNumber = 1;\n public PagerPageSize = 100;\n\n // ─── Multi-Table State ───\n\n /** All resolved tables (from multi-table or wrapped single-table) */\n public ResolvedTables: DataTable[] = [];\n\n /** Index of the currently active table tab */\n public ActiveTableIndex = 0;\n\n /** Per-table paging state */\n private tablePageState: Map<number, { pageNumber: number; pageSize: number; totalRowCount: number }> = new Map();\n\n /** Per-table live data cache (loaded lazily on tab switch) */\n private tableDataCache: Map<number, Record<string, unknown>[]> = new Map();\n\n /** Per-table column configs cache */\n private tableColumnConfigsCache: Map<number, QueryGridColumnConfig[]> = new Map();\n\n /** Whether we're in multi-table mode */\n public get IsMultiTable(): boolean {\n return this.ResolvedTables.length > 1;\n }\n\n /** The currently active table */\n public get ActiveTable(): DataTable | null {\n return this.ResolvedTables[this.ActiveTableIndex] ?? null;\n }\n\n /** Query sync state — drives the toolbar UI for saved query actions */\n public QuerySyncState: QuerySyncState = 'no-query-latest';\n\n /** Latest version number for this artifact (from cache) */\n public LatestVersionNumber = 0;\n\n /** Metadata from live execution (overrides spec.metadata when live) */\n private liveRowCount: number | null = null;\n private liveExecutionTime: number | null = null;\n\n /** SQL from the saved query record (for comparison) */\n private savedQuerySql: string | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return this.spec != null && (this.HasData || this.IsLoading || this.ResolvedTables.length > 0);\n }\n\n public override get parentShouldShowRawContent(): boolean {\n return true;\n }\n\n public get HasData(): boolean {\n return this.GridData.length > 0;\n }\n\n public get HasInlineData(): boolean {\n // Check root-level rows (legacy single-table) or any resolved table with rows\n return !!(this.spec?.rows && this.spec.rows.length > 0) ||\n this.ResolvedTables.some(t => t.rows && t.rows.length > 0);\n }\n\n public get DisplayRowCount(): number | null {\n // In live/paged mode the pager tracks the TRUE total row count\n // (PagerTotalRowCount, from RunQueryResult.TotalRowCount) — surface that as\n // the headline count so the title reflects the full result size, not just the\n // current page (which the bottom pager already shows as a range). Falls back\n // to the page/inline row count when there's no paged total.\n if (this.PagerTotalRowCount > 0) {\n return this.PagerTotalRowCount;\n }\n return this.liveRowCount ?? this.spec?.metadata?.rowCount ?? null;\n }\n\n public get DisplayExecutionTime(): number | null {\n return this.liveExecutionTime ?? this.spec?.metadata?.executionTimeMs ?? null;\n }\n\n /** Current artifact version number */\n public get CurrentVersionNumber(): number {\n return this.artifactVersion?.VersionNumber || 1;\n }\n\n /** Whether this is the latest version of the artifact */\n public get IsLatestVersion(): boolean {\n return this.CurrentVersionNumber === this.LatestVersionNumber;\n }\n\n /**\n * The effective version number at which the query was last saved/updated.\n * When viewing an older version, this looks ahead through newer versions\n * to find the most recent savedAtVersionNumber for the same query,\n * giving the user accurate context (e.g., \"Query updated at v3\" instead\n * of the stale \"Saved at v1\" from this version's snapshot).\n */\n public EffectiveSavedAtVersion: number | null = null;\n\n /** Alias used by the template */\n public get SavedAtVersion(): number | null {\n return this.EffectiveSavedAtVersion;\n }\n\n /** Display name for the saved query */\n public get SavedQueryDisplayName(): string {\n return this.spec?.savedQueryName || 'Saved Query';\n }\n\n async ngOnInit(): Promise<void> {\n try {\n this.spec = this.parseJsonContent<DataArtifactSpec>();\n if (!this.spec) {\n this.HasError = true;\n this.ErrorMessage = 'Failed to parse data artifact content';\n return;\n }\n\n // Resolve to tables array (handles both single and multi-table)\n this.ResolvedTables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n\n if (this.ResolvedTables.length === 0 && !this.spec.plan) {\n return;\n }\n\n // Build enriched column configs for the first table\n if (this.ResolvedTables.length > 0) {\n this.GridColumnConfigs = this.BuildColumnConfigsForTable(this.ResolvedTables[0]);\n }\n\n // Initialize paging state for all tables\n for (let i = 0; i < this.ResolvedTables.length; i++) {\n this.tablePageState.set(i, { pageNumber: 1, pageSize: 100, totalRowCount: 0 });\n }\n\n // Set loading early (synchronously) so hasDisplayContent is true immediately\n if (this.ResolvedTables.some(t => t.metadata?.sql) || this.HasInlineData) {\n this.IsLoading = true;\n }\n\n // Load cached metadata and resolve query sync state\n await this.InitQuerySyncState();\n\n // Load data for the first (active) table\n if (this.ResolvedTables.length > 0) {\n await this.LoadTableData(0);\n }\n\n // Signal parent that tabs/display content may have changed after async load\n this.tabsChanged.emit();\n } catch (error) {\n this.HasError = true;\n this.ErrorMessage = error instanceof Error ? error.message : 'Failed to load data';\n }\n }\n\n /**\n * Re-execute the live SQL query for the active table\n */\n public async OnRefresh(): Promise<void> {\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Handle entity link click from the grid and bubble up as openEntityRecord.\n * Converts the grid's recordId string into a CompositeKey for the artifact viewer pipeline.\n */\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === event.entityName);\n const pkFieldName = entity?.FirstPrimaryKey?.Name ?? 'ID';\n\n const compositeKey = new CompositeKey([\n new KeyValuePair(pkFieldName, event.recordId)\n ]);\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey\n });\n }\n\n /**\n * Handle page change from the data grid's embedded pager.\n * Re-executes the query for the active table with new page parameters.\n */\n public async OnPageChange(event: PageChangeEvent): Promise<void> {\n const pageState = this.tablePageState.get(this.ActiveTableIndex);\n if (!pageState) return;\n\n pageState.pageNumber = event.PageNumber;\n pageState.pageSize = event.PageSize;\n\n // Clear cache so it reloads\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Switch to a different table tab.\n * Loads data lazily if not already cached.\n */\n public async OnTableTabClick(index: number): Promise<void> {\n if (index === this.ActiveTableIndex) return;\n this.ActiveTableIndex = index;\n\n const table = this.ResolvedTables[index];\n if (!table) return;\n\n // Use cached column configs or build new\n if (!this.tableColumnConfigsCache.has(index)) {\n const configs = this.BuildColumnConfigsForTable(table);\n if (configs) this.tableColumnConfigsCache.set(index, configs);\n }\n this.GridColumnConfigs = this.tableColumnConfigsCache.get(index) ?? null;\n\n // Use cached data or load fresh\n if (this.tableDataCache.has(index)) {\n this.GridData = this.tableDataCache.get(index)!;\n const pageState = this.tablePageState.get(index)!;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n this.PagerTotalRowCount = pageState.totalRowCount;\n } else {\n await this.LoadTableData(index);\n }\n\n this.cdr.detectChanges();\n }\n\n /**\n * Load data for a specific table.\n * Handles live SQL execution, inline rows, and caching.\n */\n private async LoadTableData(tableIndex: number): Promise<void> {\n const table = this.ResolvedTables[tableIndex];\n if (!table) return;\n\n this.IsLoading = true;\n this.HasError = false;\n this.cdr.detectChanges();\n\n try {\n if (table.metadata?.sql) {\n // Live SQL execution\n const pageState = this.tablePageState.get(tableIndex)!;\n const rq = this.RunQueryToUse;\n const startRow = (pageState.pageNumber - 1) * pageState.pageSize;\n const result = await rq.RunQuery({\n SQL: table.metadata.sql,\n StartRow: startRow,\n MaxRows: pageState.pageSize\n });\n\n if (result.Success) {\n this.tableDataCache.set(tableIndex, result.Results);\n this.GridData = result.Results;\n this.IsLive = true;\n\n pageState.totalRowCount = result.TotalRowCount ?? result.RowCount ?? 0;\n this.PagerTotalRowCount = pageState.totalRowCount;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n\n this.liveRowCount = result.RowCount;\n this.liveExecutionTime = result.ExecutionTime;\n } else {\n this.HandleTableError(tableIndex, result.ErrorMessage || 'Query failed');\n }\n } else if (table.rows && table.rows.length > 0) {\n // Inline data\n this.tableDataCache.set(tableIndex, table.rows);\n this.GridData = table.rows;\n this.liveRowCount = table.rows.length;\n } else {\n this.GridData = [];\n }\n } catch (error) {\n this.HandleTableError(tableIndex, error instanceof Error ? error.message : 'Load failed');\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Build QueryGridColumnConfig[] from a DataTable's column metadata.\n * Returns null if columns have no entity metadata (grid falls back to auto-inference).\n */\n private BuildColumnConfigsForTable(table: DataTable): QueryGridColumnConfig[] | null {\n const columns = table.columns;\n if (!columns?.length) return null;\n\n // Only build if at least one column has entity metadata or type info\n const hasMetadata = columns.some(c => c.sourceEntity || c.sqlBaseType);\n if (!hasMetadata) return null;\n\n const md = this.ProviderToUse;\n return columns.map((col, index) => {\n const target = resolveTargetEntity(col.sourceEntity, col.sourceFieldName, md);\n const isEntityLink = !!(target.targetEntityName && (target.isPrimaryKey || target.isForeignKey));\n const baseType = (col.sqlBaseType || 'nvarchar').toLowerCase();\n\n let align: 'left' | 'center' | 'right' = 'left';\n if (['int', 'bigint', 'decimal', 'numeric', 'float', 'money', 'smallmoney', 'real'].includes(baseType)) {\n align = 'right';\n } else if (baseType === 'bit') {\n align = 'center';\n }\n\n // Support both displayName (new) and headerName (legacy) for backward compat\n const colAny = col as unknown as Record<string, unknown>;\n const title = col.displayName || (colAny['headerName'] as string) || col.field;\n\n return {\n field: col.field,\n title,\n visible: true,\n sortable: true,\n resizable: true,\n reorderable: true,\n sqlBaseType: col.sqlBaseType || 'nvarchar',\n sqlFullType: col.sqlFullType || col.sqlBaseType || 'nvarchar',\n align,\n order: index,\n sourceEntityName: col.sourceEntity,\n sourceFieldName: col.sourceFieldName,\n isEntityLink,\n targetEntityName: target.targetEntityName,\n targetEntityId: target.targetEntityId,\n targetEntityIcon: target.targetEntityIcon,\n isPrimaryKey: target.isPrimaryKey,\n isForeignKey: target.isForeignKey,\n pinned: null,\n } as QueryGridColumnConfig;\n });\n }\n\n /**\n * Handle a table load error by setting error state and falling back to inline data\n */\n private HandleTableError(tableIndex: number, message: string): void {\n this.HasError = true;\n this.ErrorMessage = message;\n const table = this.ResolvedTables[tableIndex];\n if (table?.rows && table.rows.length > 0) {\n this.GridData = table.rows;\n }\n }\n\n // ─── Query Sync State ────────────────────────────────────────────\n\n /**\n * Initialize query sync state by loading cached metadata.\n * Resolves the latest version number and compares saved query SQL.\n */\n private async InitQuerySyncState(): Promise<void> {\n // Ensure the artifact-type registry is loaded (not registered for startup).\n await ArtifactMetadataEngine.Instance.Config(false);\n\n // Load THIS artifact's versions on demand (including Content, which\n // resolveEffectiveSavedAtVersion parses). Versions are no longer bulk-loaded\n // at boot — the payload here is bounded to a single artifact's versions.\n if (this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID);\n }\n\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n\n // If the loaded versions don't yet include the one we're viewing (a newer\n // version was created after we first loaded), force a re-fetch and re-resolve.\n if (this.LatestVersionNumber < this.CurrentVersionNumber && this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID, undefined, undefined, true);\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n }\n\n this.EffectiveSavedAtVersion = this.resolveEffectiveSavedAtVersion();\n await this.resolveSavedQuerySql();\n this.QuerySyncState = this.computeQuerySyncState();\n }\n\n /**\n * Determine the latest version number for this artifact from cache.\n * Falls back to current version if cache miss.\n */\n private resolveLatestVersionNumber(): number {\n if (!this.artifactVersion?.ArtifactID) {\n return this.CurrentVersionNumber;\n }\n\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n if (versions.length > 0) {\n // GetCachedVersionsForArtifact returns DESC sorted\n return versions[0].VersionNumber || 1;\n }\n\n // Cache miss — current version is our best guess\n return this.CurrentVersionNumber;\n }\n\n /**\n * Scan all versions of this artifact to find the most recent savedAtVersionNumber\n * for the same savedQueryId. When viewing an older version, this tells the user\n * where the query was *actually* last updated, not just what this version's\n * snapshot recorded at the time.\n */\n private resolveEffectiveSavedAtVersion(): number | null {\n const queryId = this.spec?.savedQueryId;\n if (!queryId) return null;\n\n // Start with this version's own value\n let effective = this.spec?.savedAtVersionNumber ?? null;\n\n if (!this.artifactVersion?.ArtifactID) return effective;\n\n // GetCachedVersionsForArtifact returns DESC sorted — scan all versions\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n for (const v of versions) {\n try {\n if (!v.Content) continue;\n const content = typeof v.Content === 'string' ? JSON.parse(v.Content) : v.Content;\n if (content.savedQueryId === queryId && content.savedAtVersionNumber != null) {\n const vSavedAt = content.savedAtVersionNumber as number;\n if (effective == null || vSavedAt > effective) {\n effective = vSavedAt;\n }\n }\n } catch {\n // Skip versions with unparseable content\n }\n }\n\n return effective;\n }\n\n /**\n * Look up the saved query's SQL from QueryEngine cache for comparison.\n * Only fetches if savedQueryId is present.\n */\n private async resolveSavedQuerySql(): Promise<void> {\n if (!this.spec?.savedQueryId) {\n this.savedQuerySql = null;\n return;\n }\n\n // QueryEngine is registered for startup, should already be loaded\n let query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n\n if (!query) {\n // Cache miss — force refresh and retry\n await QueryEngine.Instance.Config(true);\n query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n }\n\n this.savedQuerySql = query?.SQL ?? null;\n }\n\n /**\n * Compute the query sync state from current spec, version, and saved query SQL.\n * Implements the decision tree from the UX design.\n */\n private computeQuerySyncState(): QuerySyncState {\n const hasSavedQuery = !!this.spec?.savedQueryId;\n const isLatest = this.IsLatestVersion;\n\n if (!hasSavedQuery) {\n return isLatest ? 'no-query-latest' : 'no-query-older';\n }\n\n // Compare SQL (normalize whitespace for reliable comparison)\n const specSql = this.normalizeSql(this.spec?.metadata?.sql);\n const querySql = this.normalizeSql(this.savedQuerySql);\n const sqlMatches = specSql != null && querySql != null && specSql === querySql;\n\n // Only truly synced if SQL matches AND this is the version it was saved at.\n // Even with identical SQL, a newer version should show the dropdown so the\n // user can update the version association (re-save at current version).\n const savedAtCurrent = this.EffectiveSavedAtVersion === this.CurrentVersionNumber;\n if (sqlMatches && savedAtCurrent) {\n return 'synced';\n }\n\n // SQL differs — determine position relative to saved version\n if (isLatest) {\n return 'outdated-latest';\n }\n\n // Use effective saved-at (looks ahead through newer versions)\n const savedAt = this.EffectiveSavedAtVersion;\n if (savedAt != null && this.CurrentVersionNumber < savedAt) {\n return 'query-ahead'; // query was updated at a newer version\n }\n\n return 'query-behind'; // ahead of saved but not latest\n }\n\n /** Normalize SQL for comparison: trim and collapse whitespace */\n private normalizeSql(sql: string | null | undefined): string | null {\n if (sql == null) return null;\n return sql.trim().replace(/\\s+/g, ' ');\n }\n\n // ─── Actions ────────────────────────────────────────────────────\n\n /** Navigate to the saved query in the Data Explorer's Queries browser */\n public OnOpenSavedQuery(): void {\n if (!this.spec?.savedQueryId) return;\n this.navigationRequest.emit({\n appName: 'Data Explorer',\n navItemName: 'Queries',\n queryParams: { queryId: this.spec.savedQueryId }\n });\n }\n\n /** Show the save panel for creating a brand-new query */\n public OnShowSaveDialog(): void {\n this.ShowSaveDialog = true;\n this.ShowUpdateDropdown = false;\n }\n\n /** Toggle the update query dropdown */\n public OnToggleUpdateDropdown(): void {\n this.ShowUpdateDropdown = !this.ShowUpdateDropdown;\n }\n\n /** Close the dropdown (e.g., on outside click) */\n public OnCloseDropdown(): void {\n this.ShowUpdateDropdown = false;\n }\n\n /**\n * Update the existing saved query's SQL to match this version.\n * Only available from the latest version (Scenario 3).\n */\n public async OnUpdateExistingQuery(): Promise<void> {\n this.ShowUpdateDropdown = false;\n if (!this.spec?.savedQueryId || !this.spec.metadata?.sql) return;\n\n this.IsSaving = true;\n this.SavingMessage = `Updating \"${this.SavedQueryDisplayName}\"...`;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n const query = await md.GetEntityObject<import('@memberjunction/core-entities').MJQueryEntity>('MJ: Queries');\n const loaded = await query.Load(this.spec.savedQueryId);\n\n if (!loaded) {\n console.error('Failed to load saved query for update');\n return;\n }\n\n query.SQL = this.spec.metadata.sql;\n if (this.spec.plan?.trim()) {\n query.TechnicalDescription = this.spec.plan.trim();\n }\n const saved = await query.Save();\n\n if (saved) {\n // Update spec with new version tracking\n this.spec.savedAtVersionNumber = this.CurrentVersionNumber;\n await this.PersistArtifactContent();\n\n // Refresh caches so future lookups see the updated data\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n\n this.savedQuerySql = this.spec.metadata.sql;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n }\n } catch (error) {\n console.error('Failed to update saved query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Save as a new query (from the dropdown).\n * Opens the save dialog which creates a fresh query record.\n */\n public OnSaveAsNewQuery(): void {\n this.ShowUpdateDropdown = false;\n this.ShowSaveDialog = true;\n }\n\n /** Handle successful save from the dialog (both initial save and \"save as new\") */\n public async OnQuerySaved(event: SaveQueryResult): Promise<void> {\n this.ShowSaveDialog = false;\n this.IsSaving = true;\n this.SavingMessage = 'Saving query...';\n this.cdr.detectChanges();\n\n try {\n // Update spec with saved query info and version tracking\n this.spec!.savedQueryId = event.queryId;\n this.spec!.savedQueryName = event.queryName;\n this.spec!.savedAtVersionNumber = this.CurrentVersionNumber;\n\n // Persist and refresh caches\n await this.PersistArtifactContent();\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n await this.ProviderToUse.Refresh();\n\n this.savedQuerySql = this.spec!.metadata?.sql ?? null;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n } catch (error) {\n console.error('Failed to save query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Persist updated spec back to the artifact version entity */\n private async PersistArtifactContent(): Promise<void> {\n if (!this.artifactVersion || !this.spec) return;\n this.artifactVersion.Content = JSON.stringify(this.spec);\n await this.artifactVersion.Save();\n }\n\n /**\n * Returns a DataSnapshot with live grid data, current page state,\n * and query sync state.\n */\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n if (!this.spec) return null;\n\n const tables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n const activeTable = tables[this.ActiveTableIndex];\n\n if (activeTable) {\n // Override with live data for the active table\n if (this.IsLive) activeTable.rows = this.GridData;\n activeTable.pageNumber = this.PagerPageNumber;\n activeTable.metadata = {\n ...activeTable.metadata,\n ...(this.liveRowCount != null ? { rowCount: this.liveRowCount } : {}),\n ...(this.liveExecutionTime != null\n ? { executionTimeMs: this.liveExecutionTime } : {}),\n ...(this.PagerTotalRowCount > 0\n ? { totalAvailableRows: this.PagerTotalRowCount } : {}),\n pageSize: this.PagerPageSize\n };\n }\n\n return DataSnapshot.FromTables(tables, this.spec.title);\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────\n\n /**\n * Provide Plan tab (markdown), SQL tab (code), and Interpretation tab when available\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n if (this.spec?.plan) {\n tabs.push({\n label: 'Plan',\n icon: 'fa-diagram-project',\n contentType: 'markdown',\n content: this.spec.plan\n });\n }\n\n // SQL tab — multi-table shows all queries with headers\n if (this.IsMultiTable) {\n const multiSql = buildMultiTableSql(this.ResolvedTables);\n if (multiSql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: multiSql\n });\n }\n } else if (this.spec?.metadata?.sql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: this.spec.metadata.sql\n });\n }\n\n // Interpretation tab\n if (this.spec?.interpretation) {\n tabs.push({\n label: 'Interpretation',\n icon: 'fa-lightbulb',\n contentType: 'markdown',\n content: this.spec.interpretation\n });\n }\n\n return tabs;\n }\n}\n","<div class=\"data-artifact-viewer\" [ngClass]=\"cssClass\">\n @if (spec) {\n @if (HasData || IsLoading || ResolvedTables.length > 0) {\n <!-- Toolbar -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-table\"></i>\n <span>{{ spec.title || \"Data Results\" }}</span>\n @if (IsLive) {\n <span class=\"live-badge\">Live</span>\n }\n @if (DisplayRowCount != null) {\n <span class=\"row-count\">{{ DisplayRowCount | number }} rows</span>\n }\n @if (DisplayExecutionTime != null) {\n <span class=\"exec-time\">{{ DisplayExecutionTime }}ms</span>\n }\n </div>\n <div class=\"data-actions\">\n @if (IsLive) {\n <button class=\"btn-icon\" title=\"Refresh data\" (click)=\"OnRefresh()\" [disabled]=\"IsLoading\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i> Refresh\n </button>\n }\n\n @switch (QuerySyncState) {\n <!-- S1: No saved query, latest version → Save Query -->\n @case (\"no-query-latest\") {\n <button class=\"btn-icon btn-save\" title=\"Save as reusable query\" (click)=\"OnShowSaveDialog()\"><i class=\"fas fa-save\"></i> Save Query</button>\n }\n\n <!-- S2: SQL matches → green badge + Open -->\n @case (\"synced\") {\n <span class=\"query-badge query-badge-synced\"> <i class=\"fas fa-check\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-open\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S3: SQL differs, latest version → amber badge + dropdown -->\n @case (\"outdated-latest\") {\n <span class=\"query-badge query-badge-outdated\"> <i class=\"fas fa-circle-exclamation\"></i> Saved at v{{ SavedAtVersion }} </span>\n <div class=\"dropdown-wrapper\">\n <button class=\"btn-icon btn-warning\" title=\"Update or save query\" (click)=\"OnToggleUpdateDropdown()\">\n <i class=\"fas fa-save\"></i> Update Query <i class=\"fas fa-caret-down\"></i>\n </button>\n @if (ShowUpdateDropdown) {\n <div class=\"query-dropdown\" (click)=\"$event.stopPropagation()\">\n <div class=\"query-dropdown-item\" (click)=\"OnUpdateExistingQuery()\">\n <i class=\"fas fa-arrow-up-from-bracket\" style=\"color: #d97706\"></i>\n <div>\n <div class=\"dropdown-label\">Update \"{{ SavedQueryDisplayName }}\"</div>\n <div class=\"dropdown-desc\">Replace saved query SQL with this version's SQL</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnSaveAsNewQuery()\">\n <i class=\"fas fa-plus\" style=\"color: #16a34a\"></i>\n <div>\n <div class=\"dropdown-label\">Save as New Query</div>\n <div class=\"dropdown-desc\">Create a new query, keep the original unchanged</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnOpenSavedQuery(); OnCloseDropdown()\">\n <i class=\"fas fa-external-link-alt\" style=\"color: var(--mj-text-muted)\"></i>\n <div>\n <div class=\"dropdown-label\">Open Saved Query</div>\n <div class=\"dropdown-desc\">View \"{{ SavedQueryDisplayName }}\" (saved at v{{ SavedAtVersion }})</div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- S4: Older version, query was updated ahead -->\n @case (\"query-ahead\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Query updated at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S5: Middle version, saved at older, not latest -->\n @case (\"query-behind\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S6: No saved query, older version → no actions -->\n @case (\"no-query-older\") {\n <!-- No query actions available on older versions -->\n }\n }\n </div>\n </div>\n\n <!-- Multi-table tab strip -->\n @if (IsMultiTable) {\n <div class=\"table-tabs\">\n @for (table of ResolvedTables; track table.name; let i = $index) {\n <button class=\"table-tab\" [class.active]=\"i === ActiveTableIndex\" [title]=\"table.description || table.name\" (click)=\"OnTableTabClick(i)\">\n <span class=\"table-tab-name\">{{ table.name }}</span>\n @if (table.metadata?.rowCount != null || table.rows.length) {\n <span class=\"table-tab-count\"> ({{ table.metadata?.rowCount ?? table.rows.length }} rows) </span>\n }\n </button>\n }\n </div>\n }\n\n <!-- Computations summary bar -->\n @if (spec.computations?.length) {\n <div class=\"computations-bar\">\n @for (comp of spec.computations; track comp.name) {\n @if (!IsMultiTable || !comp.table || comp.table === ActiveTable?.name) {\n <div class=\"computation-chip\" [title]=\"comp.description || comp.name\">\n <span class=\"computation-label\">{{ comp.name }}</span>\n <span class=\"computation-value\">\n {{ comp.formattedValue || comp.value }}\n </span>\n </div>\n }\n }\n </div>\n }\n\n <!-- Grid -->\n <div class=\"grid-container\">\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading [text]=\"SavingMessage\"></mj-loading>\n </div>\n }\n @if (IsLoading) {\n <mj-loading text=\"Loading data...\"></mj-loading>\n } @else if (HasError && HasData) {\n <mj-alert Variant=\"warning\" Size=\"sm\" class=\"data-artifact-alert-pos\">\n {{ ErrorMessage }}\n <span class=\"fallback-note\">(Showing cached data)</span>\n </mj-alert>\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n }\n </div>\n } @else if (spec.plan) {\n <!-- Plan-only view (no results yet) -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-diagram-project\"></i>\n <span>{{ spec.title || \"Query Plan\" }}</span>\n </div>\n </div>\n <div class=\"plan-content\">\n <mj-markdown [data]=\"spec.plan\" [enableMermaid]=\"true\" [enableHighlight]=\"true\" [enableCollapsibleHeadings]=\"false\" [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n } @else {\n <!-- No data and no plan -->\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n\n <!-- Save Query Panel (slide-in) -->\n @if (ShowSaveDialog) {\n <mj-save-query-panel\n [QueryName]=\"spec?.title || 'Untitled Query'\"\n [QueryDescription]=\"''\"\n [SQL]=\"spec?.metadata?.sql || ''\"\n [Plan]=\"spec?.plan || ''\"\n (Saved)=\"OnQuerySaved($event)\"\n (Cancelled)=\"ShowSaveDialog = false\"\n >\n </mj-save-query-panel>\n }\n</div>\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-form-apply.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/interactive-form-apply.service.ts"],"names":[],"mappings":"AAmBA,OAAO,
|
|
1
|
+
{"version":3,"file":"interactive-form-apply.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/interactive-form-apply.service.ts"],"names":[],"mappings":"AAmBA,OAAO,EAA+B,KAAK,iBAAiB,EAAiB,MAAM,sBAAsB,CAAC;AAI1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;;AAEjF,iFAAiF;AACjF,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,IAAI,CAAC,EAAE,QAAQ,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;IAC3D,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBACa,2BAA2B;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;IAE/D;;;OAGG;IACU,eAAe,CACxB,IAAI,EAAE,aAAa,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,0BAA0B,CAAC;IA8FtC;;;;;;OAMG;YACW,eAAe;IAgC7B;;;OAGG;YACW,qBAAqB;IAmBnC;;;;;OAKG;YACW,uBAAuB;IAqBrC;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAW1B,oEAAoE;YACtD,OAAO;IA+BrB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,SAAS;IAsCjB,OAAO,CAAC,IAAI;yCA1SH,2BAA2B;6CAA3B,2BAA2B;CA8SvC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* eventually the cockpit's chat-pane Apply flow) follows the same rules.
|
|
18
18
|
*/
|
|
19
19
|
import { Injectable, inject } from '@angular/core';
|
|
20
|
-
import { Metadata, LogError } from '@memberjunction/core';
|
|
20
|
+
import { Metadata, LogError, RunView } from '@memberjunction/core';
|
|
21
21
|
import { GraphQLActionClient } from '@memberjunction/graphql-dataprovider';
|
|
22
22
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
23
23
|
import { MJDialogService } from '@memberjunction/ng-ui-components';
|
|
@@ -50,7 +50,7 @@ export class InteractiveFormApplyService {
|
|
|
50
50
|
// Step 1: detect existing state via Get Active Form For Entity.
|
|
51
51
|
const activeResult = await this.runActionByName(client, 'Get Active Form For Entity', [
|
|
52
52
|
{ Name: 'EntityName', Value: entityName, Type: 'Input' },
|
|
53
|
-
]);
|
|
53
|
+
], p);
|
|
54
54
|
if (!activeResult.Success) {
|
|
55
55
|
return this.fail(`Could not check for existing override: ${activeResult.Message ?? 'unknown error'}`);
|
|
56
56
|
}
|
|
@@ -92,13 +92,13 @@ export class InteractiveFormApplyService {
|
|
|
92
92
|
// version exists yet), use in-place to avoid creating unnecessary
|
|
93
93
|
// version history.
|
|
94
94
|
{ Name: 'VersionBumpKind', Value: isPending ? 'in-place' : 'minor', Type: 'Input' },
|
|
95
|
-
]);
|
|
95
|
+
], p);
|
|
96
96
|
// Auto-activate the resulting version too. "Apply to my form" is an explicit
|
|
97
97
|
// user action — they expect the applied form to go live, not sit as a Pending
|
|
98
98
|
// draft the runtime variant switcher (Active variants only) can't reach. The
|
|
99
99
|
// prior version is preserved as history and restorable from Form Builder.
|
|
100
100
|
const modifyActivated = modifyResult.Success
|
|
101
|
-
? await this.activateCreatedOverride(client, modifyResult.Message)
|
|
101
|
+
? await this.activateCreatedOverride(client, modifyResult.Message, p)
|
|
102
102
|
: false;
|
|
103
103
|
return this.summarize(modifyResult, 'modify', user, modifyActivated);
|
|
104
104
|
}
|
|
@@ -106,13 +106,13 @@ export class InteractiveFormApplyService {
|
|
|
106
106
|
{ Name: 'EntityName', Value: entityName, Type: 'Input' },
|
|
107
107
|
{ Name: 'Name', Value: formName, Type: 'Input' },
|
|
108
108
|
{ Name: 'Spec', Value: JSON.stringify(spec), Type: 'Input' },
|
|
109
|
-
]);
|
|
109
|
+
], p);
|
|
110
110
|
// Net-new "Apply to my form" is an explicit, confirmed user action, so we
|
|
111
111
|
// activate the freshly-created (Pending) override immediately — the form goes
|
|
112
112
|
// live in one step. Refining an EXISTING active form (the branch above) stays
|
|
113
113
|
// Pending so a live form is never silently replaced.
|
|
114
114
|
const activated = createResult.Success
|
|
115
|
-
? await this.activateCreatedOverride(client, createResult.Message)
|
|
115
|
+
? await this.activateCreatedOverride(client, createResult.Message, p)
|
|
116
116
|
: false;
|
|
117
117
|
return this.summarize(createResult, 'create', user, activated);
|
|
118
118
|
}
|
|
@@ -124,12 +124,12 @@ export class InteractiveFormApplyService {
|
|
|
124
124
|
* GraphQLActionClient.RunAction() takes the action ID; we fetch it by
|
|
125
125
|
* name from the action metadata loaded on the provider.
|
|
126
126
|
*/
|
|
127
|
-
async runActionByName(client, actionName, params) {
|
|
127
|
+
async runActionByName(client, actionName, params, provider) {
|
|
128
128
|
try {
|
|
129
129
|
// The action ID is required by RunAction. We look it up from the
|
|
130
130
|
// action engine's cached metadata if available; otherwise we ask
|
|
131
131
|
// the GraphQL provider directly.
|
|
132
|
-
const actionId = await this.resolveActionIdByName(actionName);
|
|
132
|
+
const actionId = await this.resolveActionIdByName(actionName, provider);
|
|
133
133
|
if (!actionId) {
|
|
134
134
|
return { Success: false, Message: `Action '${actionName}' not found.` };
|
|
135
135
|
}
|
|
@@ -155,12 +155,11 @@ export class InteractiveFormApplyService {
|
|
|
155
155
|
* Resolve an action ID by Name. Falls back to a direct RunView against
|
|
156
156
|
* the Action entity when ActionEngine isn't loaded.
|
|
157
157
|
*/
|
|
158
|
-
async resolveActionIdByName(name) {
|
|
158
|
+
async resolveActionIdByName(name, provider) {
|
|
159
159
|
try {
|
|
160
160
|
// ActionEngine may not be initialised in the chat surface — query directly.
|
|
161
161
|
// The core Action table is registered as the "MJ: Actions" entity.
|
|
162
|
-
const
|
|
163
|
-
const rv = new RunView();
|
|
162
|
+
const rv = RunView.FromMetadataProvider(provider);
|
|
164
163
|
const result = await rv.RunView({
|
|
165
164
|
EntityName: 'MJ: Actions',
|
|
166
165
|
ExtraFilter: `Name='${name.replace(/'/g, "''")}'`,
|
|
@@ -181,7 +180,7 @@ export class InteractiveFormApplyService {
|
|
|
181
180
|
* user can activate manually, so we log and return false rather than failing the
|
|
182
181
|
* whole apply.
|
|
183
182
|
*/
|
|
184
|
-
async activateCreatedOverride(client, createMessage) {
|
|
183
|
+
async activateCreatedOverride(client, createMessage, provider) {
|
|
185
184
|
let overrideId;
|
|
186
185
|
try {
|
|
187
186
|
overrideId = JSON.parse(createMessage ?? '{}').OverrideID;
|
|
@@ -193,7 +192,7 @@ export class InteractiveFormApplyService {
|
|
|
193
192
|
return false;
|
|
194
193
|
const activateResult = await this.runActionByName(client, 'Activate Interactive Form Version', [
|
|
195
194
|
{ Name: 'OverrideID', Value: overrideId, Type: 'Input' },
|
|
196
|
-
]);
|
|
195
|
+
], provider);
|
|
197
196
|
if (!activateResult.Success) {
|
|
198
197
|
LogError(`InteractiveFormApplyService: created override ${overrideId} but auto-activation failed: ${activateResult.Message ?? 'unknown error'}`);
|
|
199
198
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-form-apply.service.js","sourceRoot":"","sources":["../../../src/lib/services/interactive-form-apply.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Apply-to-my-form service.\n *\n * When the form-aware artifact viewer's \"Apply to my form\" button fires\n * `applyFormRequested`, the host calls this service. It:\n * 1. Looks up the entity to confirm it's registered.\n * 2. Reads the current Active override for the (entity, user) pair via\n * the `Get Active Form For Entity` action.\n * 3. Shows a confirmation dialog explaining what's about to happen\n * (Create new vs. Modify existing → Pending).\n * 4. On confirmation, runs `Create Interactive Form` or\n * `Modify Interactive Form` accordingly.\n * 5. Surfaces success / failure via the notification service.\n *\n * The service centralizes the Create-vs-Modify decision so every host\n * (standalone artifact viewer in Explorer, chat conversation surfaces,\n * eventually the cockpit's chat-pane Apply flow) follows the same rules.\n */\nimport { Injectable, inject } from '@angular/core';\nimport { Metadata, LogError, type IMetadataProvider, type UserInfo } from '@memberjunction/core';\nimport { GraphQLActionClient, GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJDialogService } from '@memberjunction/ng-ui-components';\nimport type { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n/** Result of an apply attempt — surfaced to the caller for any post-apply UI. */\nexport interface InteractiveFormApplyResult {\n Success: boolean;\n /** Mode the server ran: 'create' / 'modify-new-version' / 'modify-in-place'. */\n Mode?: 'create' | 'modify-new-version' | 'modify-in-place';\n /** OverrideID the user can now reference. */\n OverrideID?: string;\n /** ComponentID that now holds the spec. */\n ComponentID?: string;\n /** Version string (e.g. '1.0.0' for create, '1.1.0' for modify-new). */\n Version?: string;\n Message?: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class InteractiveFormApplyService {\n private readonly dialog = inject(MJDialogService);\n private readonly notifications = inject(MJNotificationService);\n\n /**\n * Confirm with the user and apply the spec. Routes to Create / Modify\n * automatically based on whether an Active override already exists.\n */\n public async ConfirmAndApply(\n spec: ComponentSpec,\n entityName: string,\n provider?: IMetadataProvider,\n ): Promise<InteractiveFormApplyResult> {\n const p = provider ?? Metadata.Provider;\n if (!p) {\n return this.fail('No metadata provider configured.');\n }\n const entity = p.EntityByName(entityName);\n if (!entity) {\n return this.fail(`Entity '${entityName}' is not registered.`);\n }\n const user = p.CurrentUser;\n if (!user) {\n return this.fail('No current user.');\n }\n const gqlProvider = p as unknown as GraphQLDataProvider;\n if (!gqlProvider || typeof (gqlProvider as { ExecuteGQL?: unknown }).ExecuteGQL !== 'function') {\n return this.fail('Action invocation requires a GraphQL provider.');\n }\n\n const client = new GraphQLActionClient(gqlProvider);\n\n // Step 1: detect existing state via Get Active Form For Entity.\n const activeResult = await this.runActionByName(client, 'Get Active Form For Entity', [\n { Name: 'EntityName', Value: entityName, Type: 'Input' },\n ]);\n if (!activeResult.Success) {\n return this.fail(`Could not check for existing override: ${activeResult.Message ?? 'unknown error'}`);\n }\n const payload = this.parseActiveResult(activeResult.Message);\n const existingOverride = payload?.Active\n ?? payload?.Variants?.find(v => v.Status === 'Pending')\n ?? null;\n const hasExistingOverride = !!existingOverride?.OverrideID;\n\n // Step 2: confirm with the user.\n const proceed = await this.confirm(hasExistingOverride, entityName, existingOverride?.ComponentVersion);\n if (!proceed) {\n return { Success: false, Message: 'Cancelled by user.' };\n }\n\n // Step 3: run Create or Modify.\n const formName = (spec as unknown as { name?: string }).name ?? 'Custom Form';\n if (hasExistingOverride) {\n // MJ's Modify operates on a Component *lineage* keyed by Name — the spec\n // name must match the existing Component across versions. A freshly\n // generated form usually has a different name, so align it to the existing\n // lineage (spec.name + the root `function` declaration the linter checks)\n // before modifying.\n if (existingOverride!.ComponentName) {\n this.alignSpecToLineage(spec, existingOverride!.ComponentName);\n }\n // For Pending overrides, use in-place modification (keep iterating on\n // the same version). For Active overrides, bump a new version so the\n // prior version is preserved.\n const isPending = existingOverride!.Status === 'Pending';\n const modifyResult = await this.runActionByName(client, 'Modify Interactive Form', [\n { Name: 'OverrideID', Value: existingOverride!.OverrideID!, Type: 'Input' },\n { Name: 'Spec', Value: JSON.stringify(spec), Type: 'Input' },\n { Name: 'Notes', Value: `Applied from chat artifact at ${new Date().toISOString()}`, Type: 'Input' },\n // A user \"Apply\" is a deliberate save, never an in-flight refinement —\n // so always snapshot a new restorable version rather than risk an\n // in-place overwrite. Passing an explicit bump makes this deterministic\n // across every source status (the 'in-place' default only applies to a\n // Pending source, which is the agent's iteration loop, not this path).\n // Exception: if the existing override is already Pending (no Active\n // version exists yet), use in-place to avoid creating unnecessary\n // version history.\n { Name: 'VersionBumpKind', Value: isPending ? 'in-place' : 'minor', Type: 'Input' },\n ]);\n // Auto-activate the resulting version too. \"Apply to my form\" is an explicit\n // user action — they expect the applied form to go live, not sit as a Pending\n // draft the runtime variant switcher (Active variants only) can't reach. The\n // prior version is preserved as history and restorable from Form Builder.\n const modifyActivated = modifyResult.Success\n ? await this.activateCreatedOverride(client, modifyResult.Message)\n : false;\n return this.summarize(modifyResult, 'modify', user, modifyActivated);\n }\n const createResult = await this.runActionByName(client, 'Create Interactive Form', [\n { Name: 'EntityName', Value: entityName, Type: 'Input' },\n { Name: 'Name', Value: formName, Type: 'Input' },\n { Name: 'Spec', Value: JSON.stringify(spec), Type: 'Input' },\n ]);\n // Net-new \"Apply to my form\" is an explicit, confirmed user action, so we\n // activate the freshly-created (Pending) override immediately — the form goes\n // live in one step. Refining an EXISTING active form (the branch above) stays\n // Pending so a live form is never silently replaced.\n const activated = createResult.Success\n ? await this.activateCreatedOverride(client, createResult.Message)\n : false;\n return this.summarize(createResult, 'create', user, activated);\n }\n\n // ── internals ────────────────────────────────────────────────────────\n\n /**\n * Look up an action by name and run it. The actions module ships with\n * `__CreateInteractiveForm` / `__ModifyInteractiveForm` / etc. as their\n * DriverClass names but registers under the human-readable form name.\n * GraphQLActionClient.RunAction() takes the action ID; we fetch it by\n * name from the action metadata loaded on the provider.\n */\n private async runActionByName(\n client: GraphQLActionClient,\n actionName: string,\n params: Array<{ Name: string; Value: string; Type: 'Input' }>,\n ): Promise<{ Success: boolean; Message?: string; ResultCode?: string }> {\n try {\n // The action ID is required by RunAction. We look it up from the\n // action engine's cached metadata if available; otherwise we ask\n // the GraphQL provider directly.\n const actionId = await this.resolveActionIdByName(actionName);\n if (!actionId) {\n return { Success: false, Message: `Action '${actionName}' not found.` };\n }\n const result = await client.RunAction(actionId, params);\n // ActionResult.Result is the MJActionResultCodeEntity carrying\n // the string ResultCode; surface it on the failure path for\n // diagnostic messaging. ActionResult itself doesn't expose\n // ResultCode directly.\n const resultCode = (result as { Result?: { ResultCode?: string } })?.Result?.ResultCode;\n return {\n Success: !!result.Success,\n Message: result.Message ?? undefined,\n ResultCode: resultCode ?? undefined,\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`InteractiveFormApplyService.runActionByName(${actionName}): ${message}`);\n return { Success: false, Message: message };\n }\n }\n\n /**\n * Resolve an action ID by Name. Falls back to a direct RunView against\n * the Action entity when ActionEngine isn't loaded.\n */\n private async resolveActionIdByName(name: string): Promise<string | null> {\n try {\n // ActionEngine may not be initialised in the chat surface — query directly.\n // The core Action table is registered as the \"MJ: Actions\" entity.\n const { RunView } = await import('@memberjunction/core');\n const rv = new RunView();\n const result = await rv.RunView<{ ID: string }>({\n EntityName: 'MJ: Actions',\n ExtraFilter: `Name='${name.replace(/'/g, \"''\")}'`,\n Fields: ['ID'],\n MaxRows: 1,\n ResultType: 'simple',\n });\n return result.Success ? (result.Results?.[0]?.ID ?? null) : null;\n } catch (err) {\n LogError(`InteractiveFormApplyService.resolveActionIdByName(${name}): ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n }\n\n /**\n * Activate the override produced by a successful Create so a net-new form goes\n * live immediately. Best-effort: on failure the form stays a Pending draft the\n * user can activate manually, so we log and return false rather than failing the\n * whole apply.\n */\n private async activateCreatedOverride(\n client: GraphQLActionClient,\n createMessage: string | undefined,\n ): Promise<boolean> {\n let overrideId: string | undefined;\n try {\n overrideId = (JSON.parse(createMessage ?? '{}') as { OverrideID?: string }).OverrideID;\n } catch {\n overrideId = undefined;\n }\n if (!overrideId) return false;\n const activateResult = await this.runActionByName(client, 'Activate Interactive Form Version', [\n { Name: 'OverrideID', Value: overrideId, Type: 'Input' },\n ]);\n if (!activateResult.Success) {\n LogError(`InteractiveFormApplyService: created override ${overrideId} but auto-activation failed: ${activateResult.Message ?? 'unknown error'}`);\n }\n return activateResult.Success;\n }\n\n /**\n * Align a freshly generated spec to an existing Component lineage before Modify.\n * MJ identifies a form lineage by Component Name and refuses to change it between\n * versions, so we rename the incoming spec — both `spec.name` and the root\n * `function` declaration in `spec.code` (the linter requires them to match) — to\n * the existing lineage name.\n */\n private alignSpecToLineage(spec: ComponentSpec, existingName: string): void {\n const s = spec as { name?: string; code?: string };\n const currentName = s.name;\n if (!currentName || currentName === existingName) return;\n s.name = existingName;\n if (typeof s.code === 'string' && s.code.length > 0) {\n const escaped = currentName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n s.code = s.code.replace(new RegExp(`function\\\\s+${escaped}\\\\s*\\\\(`), `function ${existingName}(`);\n }\n }\n\n /** Show a confirmation dialog explaining what's about to happen. */\n private async confirm(\n hasExistingActive: boolean,\n entityName: string,\n currentVersion: string | null | undefined,\n ): Promise<boolean> {\n // The dialog renders string content as plain text (not innerHTML), so use\n // plain text here — HTML tags would show raw.\n const content = hasExistingActive\n ? `You already have a custom form for \"${entityName}\" (v${currentVersion ?? '?'}). Applying this will create a new version and make it your active form. The previous version is preserved and can be restored from Form Builder.`\n : `This will create a custom form for \"${entityName}\" scoped to your user and make it active. Other users will continue to see the default form.`;\n // MJDialogAction surface is {text, primary?, themeColor?}; the\n // dialog's Result observable emits the entire clicked action (or\n // undefined for backdrop/X dismissal). Detect intent via the\n // `primary` flag — Apply / Create Pending are the primary actions;\n // Cancel and dismissal both resolve false.\n const ref = this.dialog.Open({\n title: 'Apply this form?',\n content,\n width: 540,\n actions: [\n { text: 'Apply', primary: true, themeColor: 'primary' },\n { text: 'Cancel' },\n ],\n });\n return new Promise<boolean>(resolve => {\n ref.Result.subscribe((res: unknown) => {\n resolve((res as { primary?: boolean })?.primary === true);\n });\n });\n }\n\n private parseActiveResult(message: string | undefined): {\n Active?: { OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string };\n Variants?: Array<{ OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string }>;\n } | null {\n if (!message) return null;\n try {\n return JSON.parse(message) as {\n Active?: { OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string };\n Variants?: Array<{ OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string }>;\n };\n } catch {\n return null;\n }\n }\n\n private summarize(\n result: { Success: boolean; Message?: string; ResultCode?: string },\n kind: 'create' | 'modify',\n _user: UserInfo,\n activated: boolean = false,\n ): InteractiveFormApplyResult {\n if (!result.Success) {\n this.notifications.CreateSimpleNotification(\n `Apply failed: ${result.Message ?? result.ResultCode ?? 'unknown error'}`,\n 'error', 5000,\n );\n return { Success: false, Message: result.Message };\n }\n let payload: Record<string, unknown> = {};\n try { payload = JSON.parse(result.Message ?? '{}'); } catch { /* best effort */ }\n const mode: InteractiveFormApplyResult['Mode'] = kind === 'create'\n ? 'create'\n : (payload.Mode === 'in-place' ? 'modify-in-place' : 'modify-new-version');\n const note = kind === 'create'\n ? (activated\n ? 'Custom form is now active for your user.'\n : 'Custom form created as a Pending draft — activate it from Form Builder to go live.')\n : (activated\n ? `Updated form is now active${payload.Version ? ` (v${payload.Version})` : ''} for your user.`\n : (mode === 'modify-in-place'\n ? 'Pending version updated. Activate it from Form Builder when ready.'\n : `Pending v${payload.Version ?? '?'} created. Activate it from Form Builder when ready.`));\n this.notifications.CreateSimpleNotification(note, 'success', 4000);\n return {\n Success: true,\n Mode: mode,\n OverrideID: payload.OverrideID as string | undefined,\n ComponentID: payload.ComponentID as string | undefined,\n Version: payload.Version as string | undefined,\n Message: result.Message,\n };\n }\n\n private fail(message: string): InteractiveFormApplyResult {\n this.notifications.CreateSimpleNotification(`Apply failed: ${message}`, 'error', 5000);\n return { Success: false, Message: message };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-form-apply.service.js","sourceRoot":"","sources":["../../../src/lib/services/interactive-form-apply.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAyC,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sCAAsC,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;;AAkBnE,MAAM,OAAO,2BAA2B;IACnB,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IACjC,aAAa,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAE/D;;;OAGG;IACI,KAAK,CAAC,eAAe,CACxB,IAAmB,EACnB,UAAkB,EAClB,QAA4B;QAE5B,MAAM,CAAC,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,CAAC,EAAE,CAAC;YACL,OAAO,IAAI,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,UAAU,sBAAsB,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,WAAW,GAAG,CAAmC,CAAC;QACxD,IAAI,CAAC,WAAW,IAAI,OAAQ,WAAwC,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YAC7F,OAAO,IAAI,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAEpD,gEAAgE;QAChE,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,4BAA4B,EAAE;YAClF,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;SAC3D,EAAE,CAAC,CAAC,CAAC;QACN,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,CAAC,0CAA0C,YAAY,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;QAC1G,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,gBAAgB,GAAG,OAAO,EAAE,MAAM;eACjC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;eACpD,IAAI,CAAC;QACZ,MAAM,mBAAmB,GAAG,CAAC,CAAC,gBAAgB,EAAE,UAAU,CAAC;QAE3D,iCAAiC;QACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QACxG,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;QAC7D,CAAC;QAED,gCAAgC;QAChC,MAAM,QAAQ,GAAI,IAAqC,CAAC,IAAI,IAAI,aAAa,CAAC;QAC9E,IAAI,mBAAmB,EAAE,CAAC;YACtB,yEAAyE;YACzE,oEAAoE;YACpE,2EAA2E;YAC3E,0EAA0E;YAC1E,oBAAoB;YACpB,IAAI,gBAAiB,CAAC,aAAa,EAAE,CAAC;gBAClC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,gBAAiB,CAAC,aAAa,CAAC,CAAC;YACnE,CAAC;YACD,sEAAsE;YACtE,qEAAqE;YACrE,8BAA8B;YAC9B,MAAM,SAAS,GAAG,gBAAiB,CAAC,MAAM,KAAK,SAAS,CAAC;YACzD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,yBAAyB,EAAE;gBAC/E,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAiB,CAAC,UAAW,EAAE,IAAI,EAAE,OAAO,EAAE;gBAC3E,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;gBAC5D,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,iCAAiC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;gBACpG,uEAAuE;gBACvE,kEAAkE;gBAClE,wEAAwE;gBACxE,uEAAuE;gBACvE,uEAAuE;gBACvE,oEAAoE;gBACpE,kEAAkE;gBAClE,mBAAmB;gBACnB,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE;aACtF,EAAE,CAAC,CAAC,CAAC;YACN,6EAA6E;YAC7E,8EAA8E;YAC9E,6EAA6E;YAC7E,0EAA0E;YAC1E,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO;gBACxC,CAAC,CAAC,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;gBACrE,CAAC,CAAC,KAAK,CAAC;YACZ,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,yBAAyB,EAAE;YAC/E,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;YACxD,EAAE,IAAI,EAAE,MAAM,EAAQ,KAAK,EAAE,QAAQ,EAAI,IAAI,EAAE,OAAO,EAAE;YACxD,EAAE,IAAI,EAAE,MAAM,EAAQ,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;SACrE,EAAE,CAAC,CAAC,CAAC;QACN,0EAA0E;QAC1E,8EAA8E;QAC9E,8EAA8E;QAC9E,qDAAqD;QACrD,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO;YAClC,CAAC,CAAC,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC,CAAC,KAAK,CAAC;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;IAED,wEAAwE;IAExE;;;;;;OAMG;IACK,KAAK,CAAC,eAAe,CACzB,MAA2B,EAC3B,UAAkB,EAClB,MAA6D,EAC7D,QAA2B;QAE3B,IAAI,CAAC;YACD,iEAAiE;YACjE,iEAAiE;YACjE,iCAAiC;YACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,UAAU,cAAc,EAAE,CAAC;YAC5E,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACxD,+DAA+D;YAC/D,4DAA4D;YAC5D,2DAA2D;YAC3D,uBAAuB;YACvB,MAAM,UAAU,GAAI,MAA+C,EAAE,MAAM,EAAE,UAAU,CAAC;YACxF,OAAO;gBACH,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO;gBACzB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS;gBACpC,UAAU,EAAE,UAAU,IAAI,SAAS;aACtC,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,QAAQ,CAAC,+CAA+C,UAAU,MAAM,OAAO,EAAE,CAAC,CAAC;YACnF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;QAChD,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,qBAAqB,CAAC,IAAY,EAAE,QAA2B;QACzE,IAAI,CAAC;YACD,4EAA4E;YAC5E,mEAAmE;YACnE,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAiB;gBAC5C,UAAU,EAAE,aAAa;gBACzB,WAAW,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG;gBACjD,MAAM,EAAE,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,UAAU,EAAE,QAAQ;aACvB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,qDAAqD,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5H,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,uBAAuB,CACjC,MAA2B,EAC3B,aAAiC,EACjC,QAA2B;QAE3B,IAAI,UAA8B,CAAC;QACnC,IAAI,CAAC;YACD,UAAU,GAAI,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAA6B,CAAC,UAAU,CAAC;QAC3F,CAAC;QAAC,MAAM,CAAC;YACL,UAAU,GAAG,SAAS,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAC9B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,mCAAmC,EAAE;YAC3F,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;SAC3D,EAAE,QAAQ,CAAC,CAAC;QACb,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC1B,QAAQ,CAAC,iDAAiD,UAAU,gCAAgC,cAAc,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;QACrJ,CAAC;QACD,OAAO,cAAc,CAAC,OAAO,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACK,kBAAkB,CAAC,IAAmB,EAAE,YAAoB;QAChE,MAAM,CAAC,GAAG,IAAwC,CAAC;QACnD,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,YAAY;YAAE,OAAO;QACzD,CAAC,CAAC,IAAI,GAAG,YAAY,CAAC;QACtB,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;YACnE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,eAAe,OAAO,SAAS,CAAC,EAAE,YAAY,YAAY,GAAG,CAAC,CAAC;QACtG,CAAC;IACL,CAAC;IAED,oEAAoE;IAC5D,KAAK,CAAC,OAAO,CACjB,iBAA0B,EAC1B,UAAkB,EAClB,cAAyC;QAEzC,0EAA0E;QAC1E,8CAA8C;QAC9C,MAAM,OAAO,GAAG,iBAAiB;YAC7B,CAAC,CAAC,uCAAuC,UAAU,OAAO,cAAc,IAAI,GAAG,mJAAmJ;YAClO,CAAC,CAAC,uCAAuC,UAAU,8FAA8F,CAAC;QACtJ,+DAA+D;QAC/D,iEAAiE;QACjE,6DAA6D;QAC7D,mEAAmE;QACnE,2CAA2C;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACzB,KAAK,EAAE,kBAAkB;YACzB,OAAO;YACP,KAAK,EAAE,GAAG;YACV,OAAO,EAAE;gBACL,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE;gBACvD,EAAE,IAAI,EAAE,QAAQ,EAAE;aACrB;SACJ,CAAC,CAAC;QACH,OAAO,IAAI,OAAO,CAAU,OAAO,CAAC,EAAE;YAClC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAY,EAAE,EAAE;gBAClC,OAAO,CAAE,GAA6B,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,iBAAiB,CAAC,OAA2B;QAIjD,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAGxB,CAAC;QACN,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,SAAS,CACb,MAAmE,EACnE,IAAyB,EACzB,KAAe,EACf,YAAqB,KAAK;QAE1B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,CAAC,wBAAwB,CACvC,iBAAiB,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,IAAI,eAAe,EAAE,EACzE,OAAO,EAAE,IAAI,CAChB,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QACvD,CAAC;QACD,IAAI,OAAO,GAA4B,EAAE,CAAC;QAC1C,IAAI,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACjF,MAAM,IAAI,GAAuC,IAAI,KAAK,QAAQ;YAC9D,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,IAAI,KAAK,QAAQ;YAC1B,CAAC,CAAC,CAAC,SAAS;gBACR,CAAC,CAAC,0CAA0C;gBAC5C,CAAC,CAAC,oFAAoF,CAAC;YAC3F,CAAC,CAAC,CAAC,SAAS;gBACR,CAAC,CAAC,6BAA6B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,iBAAiB;gBAC/F,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB;oBACzB,CAAC,CAAC,oEAAoE;oBACtE,CAAC,CAAC,YAAY,OAAO,CAAC,OAAO,IAAI,GAAG,qDAAqD,CAAC,CAAC,CAAC;QACxG,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACnE,OAAO;YACH,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,OAAO,CAAC,UAAgC;YACpD,WAAW,EAAE,OAAO,CAAC,WAAiC;YACtD,OAAO,EAAE,OAAO,CAAC,OAA6B;YAC9C,OAAO,EAAE,MAAM,CAAC,OAAO;SAC1B,CAAC;IACN,CAAC;IAEO,IAAI,CAAC,OAAe;QACxB,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,iBAAiB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACvF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC;qHA7SQ,2BAA2B;gEAA3B,2BAA2B,WAA3B,2BAA2B,mBADd,MAAM;;iFACnB,2BAA2B;cADvC,UAAU;eAAC,EAAE,UAAU,EAAE,MAAM,EAAE","sourcesContent":["/**\n * Apply-to-my-form service.\n *\n * When the form-aware artifact viewer's \"Apply to my form\" button fires\n * `applyFormRequested`, the host calls this service. It:\n * 1. Looks up the entity to confirm it's registered.\n * 2. Reads the current Active override for the (entity, user) pair via\n * the `Get Active Form For Entity` action.\n * 3. Shows a confirmation dialog explaining what's about to happen\n * (Create new vs. Modify existing → Pending).\n * 4. On confirmation, runs `Create Interactive Form` or\n * `Modify Interactive Form` accordingly.\n * 5. Surfaces success / failure via the notification service.\n *\n * The service centralizes the Create-vs-Modify decision so every host\n * (standalone artifact viewer in Explorer, chat conversation surfaces,\n * eventually the cockpit's chat-pane Apply flow) follows the same rules.\n */\nimport { Injectable, inject } from '@angular/core';\nimport { Metadata, LogError, RunView, type IMetadataProvider, type UserInfo } from '@memberjunction/core';\nimport { GraphQLActionClient, GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJDialogService } from '@memberjunction/ng-ui-components';\nimport type { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n/** Result of an apply attempt — surfaced to the caller for any post-apply UI. */\nexport interface InteractiveFormApplyResult {\n Success: boolean;\n /** Mode the server ran: 'create' / 'modify-new-version' / 'modify-in-place'. */\n Mode?: 'create' | 'modify-new-version' | 'modify-in-place';\n /** OverrideID the user can now reference. */\n OverrideID?: string;\n /** ComponentID that now holds the spec. */\n ComponentID?: string;\n /** Version string (e.g. '1.0.0' for create, '1.1.0' for modify-new). */\n Version?: string;\n Message?: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class InteractiveFormApplyService {\n private readonly dialog = inject(MJDialogService);\n private readonly notifications = inject(MJNotificationService);\n\n /**\n * Confirm with the user and apply the spec. Routes to Create / Modify\n * automatically based on whether an Active override already exists.\n */\n public async ConfirmAndApply(\n spec: ComponentSpec,\n entityName: string,\n provider?: IMetadataProvider,\n ): Promise<InteractiveFormApplyResult> {\n const p = provider ?? Metadata.Provider;\n if (!p) {\n return this.fail('No metadata provider configured.');\n }\n const entity = p.EntityByName(entityName);\n if (!entity) {\n return this.fail(`Entity '${entityName}' is not registered.`);\n }\n const user = p.CurrentUser;\n if (!user) {\n return this.fail('No current user.');\n }\n const gqlProvider = p as unknown as GraphQLDataProvider;\n if (!gqlProvider || typeof (gqlProvider as { ExecuteGQL?: unknown }).ExecuteGQL !== 'function') {\n return this.fail('Action invocation requires a GraphQL provider.');\n }\n\n const client = new GraphQLActionClient(gqlProvider);\n\n // Step 1: detect existing state via Get Active Form For Entity.\n const activeResult = await this.runActionByName(client, 'Get Active Form For Entity', [\n { Name: 'EntityName', Value: entityName, Type: 'Input' },\n ], p);\n if (!activeResult.Success) {\n return this.fail(`Could not check for existing override: ${activeResult.Message ?? 'unknown error'}`);\n }\n const payload = this.parseActiveResult(activeResult.Message);\n const existingOverride = payload?.Active\n ?? payload?.Variants?.find(v => v.Status === 'Pending')\n ?? null;\n const hasExistingOverride = !!existingOverride?.OverrideID;\n\n // Step 2: confirm with the user.\n const proceed = await this.confirm(hasExistingOverride, entityName, existingOverride?.ComponentVersion);\n if (!proceed) {\n return { Success: false, Message: 'Cancelled by user.' };\n }\n\n // Step 3: run Create or Modify.\n const formName = (spec as unknown as { name?: string }).name ?? 'Custom Form';\n if (hasExistingOverride) {\n // MJ's Modify operates on a Component *lineage* keyed by Name — the spec\n // name must match the existing Component across versions. A freshly\n // generated form usually has a different name, so align it to the existing\n // lineage (spec.name + the root `function` declaration the linter checks)\n // before modifying.\n if (existingOverride!.ComponentName) {\n this.alignSpecToLineage(spec, existingOverride!.ComponentName);\n }\n // For Pending overrides, use in-place modification (keep iterating on\n // the same version). For Active overrides, bump a new version so the\n // prior version is preserved.\n const isPending = existingOverride!.Status === 'Pending';\n const modifyResult = await this.runActionByName(client, 'Modify Interactive Form', [\n { Name: 'OverrideID', Value: existingOverride!.OverrideID!, Type: 'Input' },\n { Name: 'Spec', Value: JSON.stringify(spec), Type: 'Input' },\n { Name: 'Notes', Value: `Applied from chat artifact at ${new Date().toISOString()}`, Type: 'Input' },\n // A user \"Apply\" is a deliberate save, never an in-flight refinement —\n // so always snapshot a new restorable version rather than risk an\n // in-place overwrite. Passing an explicit bump makes this deterministic\n // across every source status (the 'in-place' default only applies to a\n // Pending source, which is the agent's iteration loop, not this path).\n // Exception: if the existing override is already Pending (no Active\n // version exists yet), use in-place to avoid creating unnecessary\n // version history.\n { Name: 'VersionBumpKind', Value: isPending ? 'in-place' : 'minor', Type: 'Input' },\n ], p);\n // Auto-activate the resulting version too. \"Apply to my form\" is an explicit\n // user action — they expect the applied form to go live, not sit as a Pending\n // draft the runtime variant switcher (Active variants only) can't reach. The\n // prior version is preserved as history and restorable from Form Builder.\n const modifyActivated = modifyResult.Success\n ? await this.activateCreatedOverride(client, modifyResult.Message, p)\n : false;\n return this.summarize(modifyResult, 'modify', user, modifyActivated);\n }\n const createResult = await this.runActionByName(client, 'Create Interactive Form', [\n { Name: 'EntityName', Value: entityName, Type: 'Input' },\n { Name: 'Name', Value: formName, Type: 'Input' },\n { Name: 'Spec', Value: JSON.stringify(spec), Type: 'Input' },\n ], p);\n // Net-new \"Apply to my form\" is an explicit, confirmed user action, so we\n // activate the freshly-created (Pending) override immediately — the form goes\n // live in one step. Refining an EXISTING active form (the branch above) stays\n // Pending so a live form is never silently replaced.\n const activated = createResult.Success\n ? await this.activateCreatedOverride(client, createResult.Message, p)\n : false;\n return this.summarize(createResult, 'create', user, activated);\n }\n\n // ── internals ────────────────────────────────────────────────────────\n\n /**\n * Look up an action by name and run it. The actions module ships with\n * `__CreateInteractiveForm` / `__ModifyInteractiveForm` / etc. as their\n * DriverClass names but registers under the human-readable form name.\n * GraphQLActionClient.RunAction() takes the action ID; we fetch it by\n * name from the action metadata loaded on the provider.\n */\n private async runActionByName(\n client: GraphQLActionClient,\n actionName: string,\n params: Array<{ Name: string; Value: string; Type: 'Input' }>,\n provider: IMetadataProvider,\n ): Promise<{ Success: boolean; Message?: string; ResultCode?: string }> {\n try {\n // The action ID is required by RunAction. We look it up from the\n // action engine's cached metadata if available; otherwise we ask\n // the GraphQL provider directly.\n const actionId = await this.resolveActionIdByName(actionName, provider);\n if (!actionId) {\n return { Success: false, Message: `Action '${actionName}' not found.` };\n }\n const result = await client.RunAction(actionId, params);\n // ActionResult.Result is the MJActionResultCodeEntity carrying\n // the string ResultCode; surface it on the failure path for\n // diagnostic messaging. ActionResult itself doesn't expose\n // ResultCode directly.\n const resultCode = (result as { Result?: { ResultCode?: string } })?.Result?.ResultCode;\n return {\n Success: !!result.Success,\n Message: result.Message ?? undefined,\n ResultCode: resultCode ?? undefined,\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`InteractiveFormApplyService.runActionByName(${actionName}): ${message}`);\n return { Success: false, Message: message };\n }\n }\n\n /**\n * Resolve an action ID by Name. Falls back to a direct RunView against\n * the Action entity when ActionEngine isn't loaded.\n */\n private async resolveActionIdByName(name: string, provider: IMetadataProvider): Promise<string | null> {\n try {\n // ActionEngine may not be initialised in the chat surface — query directly.\n // The core Action table is registered as the \"MJ: Actions\" entity.\n const rv = RunView.FromMetadataProvider(provider);\n const result = await rv.RunView<{ ID: string }>({\n EntityName: 'MJ: Actions',\n ExtraFilter: `Name='${name.replace(/'/g, \"''\")}'`,\n Fields: ['ID'],\n MaxRows: 1,\n ResultType: 'simple',\n });\n return result.Success ? (result.Results?.[0]?.ID ?? null) : null;\n } catch (err) {\n LogError(`InteractiveFormApplyService.resolveActionIdByName(${name}): ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n }\n\n /**\n * Activate the override produced by a successful Create so a net-new form goes\n * live immediately. Best-effort: on failure the form stays a Pending draft the\n * user can activate manually, so we log and return false rather than failing the\n * whole apply.\n */\n private async activateCreatedOverride(\n client: GraphQLActionClient,\n createMessage: string | undefined,\n provider: IMetadataProvider,\n ): Promise<boolean> {\n let overrideId: string | undefined;\n try {\n overrideId = (JSON.parse(createMessage ?? '{}') as { OverrideID?: string }).OverrideID;\n } catch {\n overrideId = undefined;\n }\n if (!overrideId) return false;\n const activateResult = await this.runActionByName(client, 'Activate Interactive Form Version', [\n { Name: 'OverrideID', Value: overrideId, Type: 'Input' },\n ], provider);\n if (!activateResult.Success) {\n LogError(`InteractiveFormApplyService: created override ${overrideId} but auto-activation failed: ${activateResult.Message ?? 'unknown error'}`);\n }\n return activateResult.Success;\n }\n\n /**\n * Align a freshly generated spec to an existing Component lineage before Modify.\n * MJ identifies a form lineage by Component Name and refuses to change it between\n * versions, so we rename the incoming spec — both `spec.name` and the root\n * `function` declaration in `spec.code` (the linter requires them to match) — to\n * the existing lineage name.\n */\n private alignSpecToLineage(spec: ComponentSpec, existingName: string): void {\n const s = spec as { name?: string; code?: string };\n const currentName = s.name;\n if (!currentName || currentName === existingName) return;\n s.name = existingName;\n if (typeof s.code === 'string' && s.code.length > 0) {\n const escaped = currentName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n s.code = s.code.replace(new RegExp(`function\\\\s+${escaped}\\\\s*\\\\(`), `function ${existingName}(`);\n }\n }\n\n /** Show a confirmation dialog explaining what's about to happen. */\n private async confirm(\n hasExistingActive: boolean,\n entityName: string,\n currentVersion: string | null | undefined,\n ): Promise<boolean> {\n // The dialog renders string content as plain text (not innerHTML), so use\n // plain text here — HTML tags would show raw.\n const content = hasExistingActive\n ? `You already have a custom form for \"${entityName}\" (v${currentVersion ?? '?'}). Applying this will create a new version and make it your active form. The previous version is preserved and can be restored from Form Builder.`\n : `This will create a custom form for \"${entityName}\" scoped to your user and make it active. Other users will continue to see the default form.`;\n // MJDialogAction surface is {text, primary?, themeColor?}; the\n // dialog's Result observable emits the entire clicked action (or\n // undefined for backdrop/X dismissal). Detect intent via the\n // `primary` flag — Apply / Create Pending are the primary actions;\n // Cancel and dismissal both resolve false.\n const ref = this.dialog.Open({\n title: 'Apply this form?',\n content,\n width: 540,\n actions: [\n { text: 'Apply', primary: true, themeColor: 'primary' },\n { text: 'Cancel' },\n ],\n });\n return new Promise<boolean>(resolve => {\n ref.Result.subscribe((res: unknown) => {\n resolve((res as { primary?: boolean })?.primary === true);\n });\n });\n }\n\n private parseActiveResult(message: string | undefined): {\n Active?: { OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string };\n Variants?: Array<{ OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string }>;\n } | null {\n if (!message) return null;\n try {\n return JSON.parse(message) as {\n Active?: { OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string };\n Variants?: Array<{ OverrideID?: string; ComponentVersion?: string; ComponentName?: string; Status?: string }>;\n };\n } catch {\n return null;\n }\n }\n\n private summarize(\n result: { Success: boolean; Message?: string; ResultCode?: string },\n kind: 'create' | 'modify',\n _user: UserInfo,\n activated: boolean = false,\n ): InteractiveFormApplyResult {\n if (!result.Success) {\n this.notifications.CreateSimpleNotification(\n `Apply failed: ${result.Message ?? result.ResultCode ?? 'unknown error'}`,\n 'error', 5000,\n );\n return { Success: false, Message: result.Message };\n }\n let payload: Record<string, unknown> = {};\n try { payload = JSON.parse(result.Message ?? '{}'); } catch { /* best effort */ }\n const mode: InteractiveFormApplyResult['Mode'] = kind === 'create'\n ? 'create'\n : (payload.Mode === 'in-place' ? 'modify-in-place' : 'modify-new-version');\n const note = kind === 'create'\n ? (activated\n ? 'Custom form is now active for your user.'\n : 'Custom form created as a Pending draft — activate it from Form Builder to go live.')\n : (activated\n ? `Updated form is now active${payload.Version ? ` (v${payload.Version})` : ''} for your user.`\n : (mode === 'modify-in-place'\n ? 'Pending version updated. Activate it from Form Builder when ready.'\n : `Pending v${payload.Version ?? '?'} created. Activate it from Form Builder when ready.`));\n this.notifications.CreateSimpleNotification(note, 'success', 4000);\n return {\n Success: true,\n Mode: mode,\n OverrideID: payload.OverrideID as string | undefined,\n ComponentID: payload.ComponentID as string | undefined,\n Version: payload.Version as string | undefined,\n Message: result.Message,\n };\n }\n\n private fail(message: string): InteractiveFormApplyResult {\n this.notifications.CreateSimpleNotification(`Apply failed: ${message}`, 'error', 5000);\n return { Success: false, Message: message };\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-artifacts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0-edge.0",
|
|
4
4
|
"description": "MemberJunction: Artifact viewer plugin system for rendering different artifact types (JSON, Code, Markdown, HTML, SVG, Components)",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"/dist"
|
|
9
9
|
],
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "vitest run",
|
|
12
|
-
"build": "ngc",
|
|
13
|
-
"test:watch": "vitest"
|
|
14
|
-
},
|
|
15
10
|
"keywords": [],
|
|
16
11
|
"author": "",
|
|
17
12
|
"license": "ISC",
|
|
18
13
|
"devDependencies": {
|
|
19
14
|
"@angular/compiler": "21.1.3",
|
|
20
15
|
"@angular/compiler-cli": "21.1.3",
|
|
21
|
-
"@memberjunction/core": "
|
|
22
|
-
"@memberjunction/ng-test-utils": "
|
|
16
|
+
"@memberjunction/core": "6.1.0-edge.0",
|
|
17
|
+
"@memberjunction/ng-test-utils": "6.1.0-edge.0",
|
|
23
18
|
"sass": "^1.97.3",
|
|
24
19
|
"vitest": "^4.0.18"
|
|
25
20
|
},
|
|
@@ -34,24 +29,24 @@
|
|
|
34
29
|
"dependencies": {
|
|
35
30
|
"@angular/cdk": "21.1.3",
|
|
36
31
|
"@angular/forms": "21.1.3",
|
|
37
|
-
"@memberjunction/core": "
|
|
38
|
-
"@memberjunction/core-entities": "
|
|
39
|
-
"@memberjunction/global": "
|
|
40
|
-
"@memberjunction/graphql-dataprovider": "
|
|
41
|
-
"@memberjunction/interactive-component-types": "
|
|
42
|
-
"@memberjunction/ng-base-forms": "
|
|
43
|
-
"@memberjunction/ng-base-types": "
|
|
44
|
-
"@memberjunction/ng-code-editor": "
|
|
45
|
-
"@memberjunction/ng-export-service": "
|
|
46
|
-
"@memberjunction/ng-markdown": "
|
|
47
|
-
"@memberjunction/ng-media-player": "
|
|
48
|
-
"@memberjunction/ng-notifications": "
|
|
49
|
-
"@memberjunction/ng-pagination": "
|
|
50
|
-
"@memberjunction/ng-query-viewer": "
|
|
51
|
-
"@memberjunction/ng-react": "
|
|
52
|
-
"@memberjunction/ng-shared-generic": "
|
|
53
|
-
"@memberjunction/ng-trees": "
|
|
54
|
-
"@memberjunction/ng-ui-components": "
|
|
32
|
+
"@memberjunction/core": "6.1.0-edge.0",
|
|
33
|
+
"@memberjunction/core-entities": "6.1.0-edge.0",
|
|
34
|
+
"@memberjunction/global": "6.1.0-edge.0",
|
|
35
|
+
"@memberjunction/graphql-dataprovider": "6.1.0-edge.0",
|
|
36
|
+
"@memberjunction/interactive-component-types": "6.1.0-edge.0",
|
|
37
|
+
"@memberjunction/ng-base-forms": "6.1.0-edge.0",
|
|
38
|
+
"@memberjunction/ng-base-types": "6.1.0-edge.0",
|
|
39
|
+
"@memberjunction/ng-code-editor": "6.1.0-edge.0",
|
|
40
|
+
"@memberjunction/ng-export-service": "6.1.0-edge.0",
|
|
41
|
+
"@memberjunction/ng-markdown": "6.1.0-edge.0",
|
|
42
|
+
"@memberjunction/ng-media-player": "6.1.0-edge.0",
|
|
43
|
+
"@memberjunction/ng-notifications": "6.1.0-edge.0",
|
|
44
|
+
"@memberjunction/ng-pagination": "6.1.0-edge.0",
|
|
45
|
+
"@memberjunction/ng-query-viewer": "6.1.0-edge.0",
|
|
46
|
+
"@memberjunction/ng-react": "6.1.0-edge.0",
|
|
47
|
+
"@memberjunction/ng-shared-generic": "6.1.0-edge.0",
|
|
48
|
+
"@memberjunction/ng-trees": "6.1.0-edge.0",
|
|
49
|
+
"@memberjunction/ng-ui-components": "6.1.0-edge.0",
|
|
55
50
|
"mammoth": "^1.8.0",
|
|
56
51
|
"pdfjs-dist": "^4.10.38",
|
|
57
52
|
"rxjs": "^7.8.2",
|
|
@@ -62,5 +57,12 @@
|
|
|
62
57
|
"repository": {
|
|
63
58
|
"type": "git",
|
|
64
59
|
"url": "https://github.com/MemberJunction/MJ"
|
|
60
|
+
},
|
|
61
|
+
"mjUILayer": "widgets",
|
|
62
|
+
"scripts": {
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:types": "tsc --noEmit -p tsconfig.spec.json",
|
|
65
|
+
"build": "ngc",
|
|
66
|
+
"test:watch": "vitest"
|
|
65
67
|
}
|
|
66
|
-
}
|
|
68
|
+
}
|