@memberjunction/ng-artifacts 6.1.4 → 6.2.0-edge.1
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/dist/lib/components/artifact-message-card.component.d.ts +60 -8
- package/dist/lib/components/artifact-message-card.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-message-card.component.js +135 -39
- package/dist/lib/components/artifact-message-card.component.js.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +58 -6
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.js +113 -35
- package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
- package/dist/lib/components/artifact-version-download.d.ts +5 -3
- package/dist/lib/components/artifact-version-download.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-download.js +11 -7
- package/dist/lib/components/artifact-version-download.js.map +1 -1
- package/dist/lib/components/artifact-version-history.component.d.ts +74 -8
- package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-history.component.js +152 -34
- package/dist/lib/components/artifact-version-history.component.js.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +328 -35
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +701 -213
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.d.ts +112 -10
- package/dist/lib/components/file-artifact-toolbar.component.d.ts.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.js +197 -23
- package/dist/lib/components/file-artifact-toolbar.component.js.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts +23 -5
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.js +69 -31
- package/dist/lib/components/plugins/code-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +136 -18
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +285 -97
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +2 -2
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +7 -7
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts +2 -0
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.js +6 -2
- package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts +17 -6
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +32 -22
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts +56 -4
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +142 -36
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts +14 -2
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js +32 -8
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/html-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +41 -5
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.js +102 -30
- package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +33 -5
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.js +89 -33
- package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts +12 -2
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js +28 -8
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +4 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +14 -6
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts +47 -5
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +129 -45
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts +5 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.js +12 -4
- package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts +28 -4
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +64 -16
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts +16 -2
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.js +35 -7
- package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
- package/dist/lib/interfaces/artifact-viewer-plugin.interface.js.map +1 -1
- package/dist/lib/services/artifact-file.service.d.ts +8 -0
- package/dist/lib/services/artifact-file.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-file.service.js +22 -6
- package/dist/lib/services/artifact-file.service.js.map +1 -1
- package/dist/lib/services/artifact-icon.service.d.ts +2 -0
- package/dist/lib/services/artifact-icon.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-icon.service.js +5 -1
- package/dist/lib/services/artifact-icon.service.js.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.d.ts +2 -0
- package/dist/lib/services/artifact-preview-resolver.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.js +5 -1
- package/dist/lib/services/artifact-preview-resolver.service.js.map +1 -1
- package/dist/lib/snapshot-helpers.d.ts +10 -0
- package/dist/lib/snapshot-helpers.d.ts.map +1 -1
- package/dist/lib/snapshot-helpers.js +25 -5
- package/dist/lib/snapshot-helpers.js.map +1 -1
- package/package.json +21 -21
|
@@ -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 = 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"]}
|
|
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\n /** @deprecated Use {@link ReactComponent}. */\n get reactComponent(): MJReactComponent | undefined {\n return this.ReactComponent;\n }\n /** @deprecated Use {@link ReactComponent}. */\n set reactComponent(value: MJReactComponent | undefined) {\n this.ReactComponent = value;\n }\n @ViewChild('interactiveForm') InteractiveForm?: InteractiveFormComponent;\n\n /** @deprecated Use {@link InteractiveForm}. */\n get interactiveForm(): InteractiveFormComponent | undefined {\n return this.InteractiveForm;\n }\n /** @deprecated Use {@link InteractiveForm}. */\n set interactiveForm(value: InteractiveFormComponent | undefined) {\n this.InteractiveForm = value;\n }\n @Output() tabsChanged = new EventEmitter<void>();\n @Output() OpenEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n\n /**\n * @deprecated Use {@link OpenEntityRecord}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() openEntityRecord = this.OpenEntityRecord;\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 /**\n * @deprecated Use {@link ApplyFormRequested}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (applyFormRequested) keeps working. Must stay AFTER ApplyFormRequested: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() applyFormRequested = this.ApplyFormRequested;\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 /** @deprecated Use {@link IsFormArtifact}. */\n public get isFormArtifact() {\n return this.IsFormArtifact;\n }\n /** @deprecated Use {@link IsFormArtifact}. */\n public set isFormArtifact(value) {\n this.IsFormArtifact = value;\n }\n\n /** Entity the form targets — resolved from spec.entityName / dataRequirements. */\n public FormEntityInfo: EntityInfo | null = null;\n\n /** @deprecated Use {@link FormEntityInfo}. */\n public get formEntityInfo(): EntityInfo | null {\n return this.FormEntityInfo;\n }\n /** @deprecated Use {@link FormEntityInfo}. */\n public set formEntityInfo(value: EntityInfo | null) {\n this.FormEntityInfo = value;\n }\n\n /** The real or fixture record currently bound to the form preview. */\n public FormRecord: BaseEntity | null = null;\n\n /** @deprecated Use {@link FormRecord}. */\n public get formRecord(): BaseEntity | null {\n return this.FormRecord;\n }\n /** @deprecated Use {@link FormRecord}. */\n public set formRecord(value: BaseEntity | null) {\n this.FormRecord = value;\n }\n\n /** True iff `formRecord` is a real DB row (vs a fixture NewRecord()). */\n public FormRecordIsReal = false;\n\n /** @deprecated Use {@link FormRecordIsReal}. */\n public get formRecordIsReal() {\n return this.FormRecordIsReal;\n }\n /** @deprecated Use {@link FormRecordIsReal}. */\n public set formRecordIsReal(value) {\n this.FormRecordIsReal = value;\n }\n\n /** Label for the chip (e.g. the record's Name field). */\n public FormRecordLabel = '';\n\n /** @deprecated Use {@link FormRecordLabel}. */\n public get formRecordLabel() {\n return this.FormRecordLabel;\n }\n /** @deprecated Use {@link FormRecordLabel}. */\n public set formRecordLabel(value) {\n this.FormRecordLabel = value;\n }\n\n /** Picker UI state. */\n public ShowRecordPicker = false;\n\n /** @deprecated Use {@link ShowRecordPicker}. */\n public get showRecordPicker() {\n return this.ShowRecordPicker;\n }\n /** @deprecated Use {@link ShowRecordPicker}. */\n public set showRecordPicker(value) {\n this.ShowRecordPicker = value;\n }\n public RecordSearchTerm = '';\n\n /** @deprecated Use {@link RecordSearchTerm}. */\n public get recordSearchTerm() {\n return this.RecordSearchTerm;\n }\n /** @deprecated Use {@link RecordSearchTerm}. */\n public set recordSearchTerm(value) {\n this.RecordSearchTerm = value;\n }\n public RecordSearchResults: Array<{ ID: string; Label: string }> = [];\n\n /** @deprecated Use {@link RecordSearchResults}. */\n public get recordSearchResults(): Array<{ ID: string; Label: string }> {\n return this.RecordSearchResults;\n }\n /** @deprecated Use {@link RecordSearchResults}. */\n public set recordSearchResults(value: Array<{ ID: string; Label: string }>) {\n this.RecordSearchResults = value;\n }\n public FormInitError: string | null = null;\n\n /** @deprecated Use {@link FormInitError}. */\n public get formInitError(): string | null {\n return this.FormInitError;\n }\n /** @deprecated Use {@link FormInitError}. */\n public set formInitError(value: string | null) {\n this.FormInitError = value;\n }\n\n // Component data\n public Component: ComponentSpec | null = null;\n\n /** @deprecated Use {@link Component}. */\n public get component(): ComponentSpec | null {\n return this.Component;\n }\n /** @deprecated Use {@link Component}. */\n public set component(value: ComponentSpec | null) {\n this.Component = value;\n }\n public ComponentCode: string = \"\";\n\n /** @deprecated Use {@link ComponentCode}. */\n public get componentCode(): string {\n return this.ComponentCode;\n }\n /** @deprecated Use {@link ComponentCode}. */\n public set componentCode(value: string) {\n this.ComponentCode = value;\n }\n public ComponentName: string = '';\n\n /** @deprecated Use {@link ComponentName}. */\n public get componentName(): string {\n return this.ComponentName;\n }\n /** @deprecated Use {@link ComponentName}. */\n public set componentName(value: string) {\n this.ComponentName = value;\n }\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 /** @deprecated Use {@link ResolvedComponentSpec}. */\n public get resolvedComponentSpec(): ComponentSpec | null {\n return this.ResolvedComponentSpec;\n }\n\n // Feedback panel\n public ShowFeedbackPanel = false;\n\n // Error state\n public HasError = false;\n\n /** @deprecated Use {@link HasError}. */\n public get hasError() {\n return this.HasError;\n }\n /** @deprecated Use {@link HasError}. */\n public set hasError(value) {\n this.HasError = value;\n }\n public errorMessage = '';\n public ErrorDetails = '';\n\n /** @deprecated Use {@link ErrorDetails}. */\n public get errorDetails() {\n return this.ErrorDetails;\n }\n /** @deprecated Use {@link ErrorDetails}. */\n public set errorDetails(value) {\n this.ErrorDetails = value;\n }\n\n // Permission state\n public PermissionResult: PermissionEvaluationResult | null = null;\n\n /** @deprecated Use {@link PermissionResult}. */\n public get permissionResult(): PermissionEvaluationResult | null {\n return this.PermissionResult;\n }\n /** @deprecated Use {@link PermissionResult}. */\n public set permissionResult(value: PermissionEvaluationResult | null) {\n this.PermissionResult = value;\n }\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 /** @deprecated Use {@link IsPermissionBlocked}. */\n public get isPermissionBlocked(): boolean {\n return this.IsPermissionBlocked;\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 /** @deprecated Use {@link OnReactComponentInitialized}. */\n onReactComponentInitialized(): void {\n return this.OnReactComponentInitialized();\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 /** @deprecated Use {@link OnComponentEvent}. */\n onComponentEvent(event: unknown): void {\n return this.OnComponentEvent(event);\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 /** @deprecated Use {@link OnOpenEntityRecord}. */\n onOpenEntityRecord(event: {entityName: string; key: CompositeKey}): void {\n return this.OnOpenEntityRecord(event);\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 /** @deprecated Use {@link OnPickerSearchInput}. */\n public async onPickerSearchInput(term: string): Promise<void> {\n return this.OnPickerSearchInput(term);\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 /** @deprecated Use {@link OnPickerSelect}. */\n public async onPickerSelect(item: { ID: string; Label: string }): Promise<void> {\n return this.OnPickerSelect(item);\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 /** @deprecated Use {@link OnApplyClicked}. */\n public async onApplyClicked(): Promise<void> {\n return this.OnApplyClicked();\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"]}
|
package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export declare class ComponentFeedbackPanelComponent extends BaseAngularComponen
|
|
|
55
55
|
ClearTreeItemHover(): void;
|
|
56
56
|
private showHoverOverlay;
|
|
57
57
|
private removeHoverOverlay;
|
|
58
|
-
private
|
|
58
|
+
private highlightComponent;
|
|
59
59
|
private ensureContainerPositioned;
|
|
60
60
|
/**
|
|
61
61
|
* Gets the effective bounding rect for a component marker element.
|
|
@@ -68,7 +68,7 @@ export declare class ComponentFeedbackPanelComponent extends BaseAngularComponen
|
|
|
68
68
|
private removeContainerClickListener;
|
|
69
69
|
private findSpecByName;
|
|
70
70
|
private walkSpecTree;
|
|
71
|
-
private
|
|
71
|
+
private clearHighlight;
|
|
72
72
|
ClosePanel(): void;
|
|
73
73
|
ngOnDestroy(): void;
|
|
74
74
|
static ɵfac: i0.ɵɵFactoryDeclaration<ComponentFeedbackPanelComponent, never>;
|
package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js
CHANGED
|
@@ -259,7 +259,7 @@ export class ComponentFeedbackPanelComponent extends BaseAngularComponent {
|
|
|
259
259
|
SelectComponent(spec) {
|
|
260
260
|
this.SelectedSpec = spec;
|
|
261
261
|
this.ResetForm();
|
|
262
|
-
this.
|
|
262
|
+
this.highlightComponent(spec.name);
|
|
263
263
|
}
|
|
264
264
|
IsSelected(spec) {
|
|
265
265
|
return this.SelectedSpec?.name === spec.name;
|
|
@@ -379,14 +379,14 @@ export class ComponentFeedbackPanelComponent extends BaseAngularComponent {
|
|
|
379
379
|
this.hoverOverlay = null;
|
|
380
380
|
}
|
|
381
381
|
// --- Region Highlighting (solid selection) ---
|
|
382
|
-
|
|
382
|
+
highlightComponent(componentName) {
|
|
383
383
|
if (!this.ReactContainerElement) {
|
|
384
|
-
this.
|
|
384
|
+
this.clearHighlight();
|
|
385
385
|
return;
|
|
386
386
|
}
|
|
387
387
|
const targetEl = this.ReactContainerElement.querySelector(`[data-mj-component="${componentName}"]`);
|
|
388
388
|
if (!targetEl) {
|
|
389
|
-
this.
|
|
389
|
+
this.clearHighlight();
|
|
390
390
|
return;
|
|
391
391
|
}
|
|
392
392
|
this.ensureContainerPositioned();
|
|
@@ -507,7 +507,7 @@ export class ComponentFeedbackPanelComponent extends BaseAngularComponent {
|
|
|
507
507
|
}
|
|
508
508
|
return null;
|
|
509
509
|
}
|
|
510
|
-
|
|
510
|
+
clearHighlight() {
|
|
511
511
|
this.resizeObserver?.disconnect();
|
|
512
512
|
this.resizeObserver = null;
|
|
513
513
|
if (this.highlightOverlay?.parentNode) {
|
|
@@ -518,11 +518,11 @@ export class ComponentFeedbackPanelComponent extends BaseAngularComponent {
|
|
|
518
518
|
this.removeContainerClickListener();
|
|
519
519
|
}
|
|
520
520
|
ClosePanel() {
|
|
521
|
-
this.
|
|
521
|
+
this.clearHighlight();
|
|
522
522
|
this.Closed.emit();
|
|
523
523
|
}
|
|
524
524
|
ngOnDestroy() {
|
|
525
|
-
this.
|
|
525
|
+
this.clearHighlight();
|
|
526
526
|
}
|
|
527
527
|
static ɵfac = /*@__PURE__*/ (() => { let ɵComponentFeedbackPanelComponent_BaseFactory; return function ComponentFeedbackPanelComponent_Factory(__ngFactoryType__) { return (ɵComponentFeedbackPanelComponent_BaseFactory || (ɵComponentFeedbackPanelComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ComponentFeedbackPanelComponent)))(__ngFactoryType__ || ComponentFeedbackPanelComponent); }; })();
|
|
528
528
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentFeedbackPanelComponent, selectors: [["mj-component-feedback-panel"]], inputs: { ComponentSpec: "ComponentSpec", ReactContainerElement: "ReactContainerElement", ConversationId: "ConversationId", ConversationDetailId: "ConversationDetailId" }, outputs: { Closed: "Closed" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 20, vars: 2, consts: [[1, "feedback-panel-overlay", 3, "click"], [1, "feedback-panel", 3, "click"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-magnifying-glass"], [1, "close-button", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [1, "tree-section"], [1, "section-header"], [1, "fa-solid", "fa-sitemap"], [1, "component-tree"], ["Icon", "fa-solid fa-circle-info", "Title", "No component hierarchy available", "Size", "compact"], [1, "feedback-section"], [1, "selected-component-info"], ["Icon", "fa-solid fa-hand-pointer", "Title", "Select a component from the tree to provide feedback", "Size", "compact"], [1, "tree-item", 3, "selected", "padding-left"], [1, "tree-item", 3, "click", "mouseenter", "mouseleave"], [1, "tree-toggle", "fa-solid", 3, "fa-chevron-right", "fa-chevron-down"], [1, "tree-spacer"], [1, "fa-solid", "fa-cube", "component-icon"], [1, "component-info"], [1, "component-name"], [1, "component-badge", "registry"], [1, "tree-toggle", "fa-solid", 3, "click"], [1, "fa-solid", "fa-star"], [1, "component-description", 3, "data"], [1, "star-rating-container"], [1, "rating-label"], [1, "star-rating", 3, "mouseleave"], [1, "star-wrapper"], [1, "rating-text", "placeholder"], [1, "comment-container"], [1, "comment-label"], [1, "optional-label"], ["placeholder", "Share your thoughts about this component...", "rows", "4", "maxlength", "1000", 1, "comment-input", 3, "ngModelChange", "ngModel"], [1, "char-count"], [1, "submit-container"], [1, "submit-button", 3, "click", "disabled"], ["Variant", "success"], ["Variant", "error"], [1, "star-zone", "star-zone-left", 3, "click", "mouseenter"], [1, "star-zone", "star-zone-right", 3, "click", "mouseenter"], [1, "star", "fa-solid", "fa-star"], [1, "star", "fa-solid", "fa-star-half-stroke"], [1, "star", "fa-regular", "fa-star"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-paper-plane"]], template: function ComponentFeedbackPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-feedback-panel.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts","../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\nimport { MJEmptyStateComponent, MJAlertComponent } from '@memberjunction/ng-ui-components';\n\n/**\n * Flattened tree item for rendering the component hierarchy\n */\ninterface TreeItem {\n spec: ComponentSpec;\n depth: number;\n hasChildren: boolean;\n}\n\n/**\n * Component feedback panel that displays component hierarchy tree\n * and allows users to select components and provide star ratings with comments.\n * Registry-agnostic: works with any component registry (Skip, MJ Central, etc.)\n */\n@Component({\n selector: 'mj-component-feedback-panel',\n standalone: true,\n imports: [CommonModule, FormsModule, MarkdownModule, MJEmptyStateComponent, MJAlertComponent],\n templateUrl: './component-feedback-panel.component.html',\n styleUrls: ['./component-feedback-panel.component.css']\n})\nexport class ComponentFeedbackPanelComponent extends BaseAngularComponent implements OnDestroy {\n @Input() ComponentSpec: ComponentSpec | null = null;\n @Input() ReactContainerElement: HTMLElement | null = null;\n @Input() ConversationId: string | null = null;\n @Input() ConversationDetailId: string | null = null;\n\n @Output() Closed = new EventEmitter<void>();\n\n // Feedback form state\n public SelectedSpec: ComponentSpec | null = null;\n public StarRating = 0;\n public HoverRating = 0;\n public FeedbackComments = '';\n public IsSubmitting = false;\n public SubmitSuccess = false;\n public SubmitError = '';\n\n // Tree state\n public ExpandedNodes = new Set<string>();\n\n // Highlight overlays\n private highlightOverlay: HTMLElement | null = null;\n private hoverOverlay: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private containerClickHandler: ((e: MouseEvent) => void) | null = null;\n\n private cdr = inject(ChangeDetectorRef);\n\n // --- Tree Methods ---\n\n GetTreeItems(): TreeItem[] {\n if (!this.ComponentSpec) return [];\n if (!this.ExpandedNodes.has(this.ComponentSpec.name)) {\n this.ExpandedNodes.add(this.ComponentSpec.name);\n }\n return this.buildTree(this.ComponentSpec, 0);\n }\n\n private buildTree(spec: ComponentSpec, depth: number): TreeItem[] {\n const items: TreeItem[] = [{\n spec,\n depth,\n hasChildren: !!(spec.dependencies && spec.dependencies.length > 0)\n }];\n if (this.ExpandedNodes.has(spec.name) && spec.dependencies) {\n for (const child of spec.dependencies) {\n items.push(...this.buildTree(child, depth + 1));\n }\n }\n return items;\n }\n\n ToggleNode(spec: ComponentSpec, event: MouseEvent): void {\n event.stopPropagation();\n if (this.ExpandedNodes.has(spec.name)) {\n this.ExpandedNodes.delete(spec.name);\n } else {\n this.ExpandedNodes.add(spec.name);\n }\n }\n\n IsNodeExpanded(spec: ComponentSpec): boolean {\n return this.ExpandedNodes.has(spec.name);\n }\n\n SelectComponent(spec: ComponentSpec): void {\n this.SelectedSpec = spec;\n this.ResetForm();\n this.HighlightComponent(spec.name);\n }\n\n IsSelected(spec: ComponentSpec): boolean {\n return this.SelectedSpec?.name === spec.name;\n }\n\n GetIndentation(depth: number): string {\n return `${depth * 20}px`;\n }\n\n // --- Star Rating (supports half-star increments) ---\n\n SetRating(value: number): void {\n this.StarRating = value;\n }\n\n SetHoverRating(value: number): void {\n this.HoverRating = value;\n }\n\n ClearHoverRating(): void {\n this.HoverRating = 0;\n }\n\n GetDisplayRating(): number {\n return this.HoverRating || this.StarRating;\n }\n\n /** Returns 'full' | 'half' | 'empty' for the given 1-based star index */\n GetStarState(index: number): 'full' | 'half' | 'empty' {\n const rating = this.GetDisplayRating();\n if (index <= rating) return 'full';\n if (index - 0.5 <= rating) return 'half';\n return 'empty';\n }\n\n IsStarFilled(index: number): boolean {\n return index <= this.GetDisplayRating();\n }\n\n // --- Form ---\n\n ResetForm(): void {\n this.StarRating = 0;\n this.HoverRating = 0;\n this.FeedbackComments = '';\n this.SubmitSuccess = false;\n this.SubmitError = '';\n }\n\n CanSubmit(): boolean {\n return !!this.SelectedSpec && this.StarRating > 0 && !this.IsSubmitting;\n }\n\n async SubmitFeedback(): Promise<void> {\n if (!this.CanSubmit() || !this.SelectedSpec) return;\n\n this.IsSubmitting = true;\n this.SubmitError = '';\n this.SubmitSuccess = false;\n this.cdr.detectChanges();\n\n try {\n // Dynamic import to avoid adding graphql-dataprovider as a package dependency.\n // At runtime in the browser, this.ProviderToUse is always a GraphQLDataProvider.\n const { GraphQLComponentRegistryClient } = await import('@memberjunction/graphql-dataprovider');\n const provider = this.ProviderToUse;\n const client = new GraphQLComponentRegistryClient(provider as ConstructorParameters<typeof GraphQLComponentRegistryClient>[0]);\n\n const response = await client.SendComponentFeedback({\n componentName: this.SelectedSpec.name,\n componentNamespace: this.SelectedSpec.namespace || this.SelectedSpec.registry || '',\n componentVersion: this.SelectedSpec.version,\n registryName: this.SelectedSpec.registry,\n rating: this.StarRating * 20, // 0-5 -> 0-100\n comments: this.FeedbackComments.trim() || undefined,\n conversationID: this.ConversationId || undefined,\n conversationDetailID: this.ConversationDetailId || undefined\n });\n\n if (response.success) {\n this.SubmitSuccess = true;\n setTimeout(() => {\n this.ResetForm();\n this.cdr.detectChanges();\n }, 2000);\n } else {\n this.SubmitError = response.error || 'Failed to submit feedback.';\n }\n } catch (error) {\n this.SubmitError = 'Failed to submit feedback. Please try again.';\n console.error('Error submitting component feedback:', error);\n } finally {\n this.IsSubmitting = false;\n this.cdr.detectChanges();\n }\n }\n\n // --- Hover Highlight (light preview on tree hover) ---\n\n HoverTreeItem(spec: ComponentSpec): void {\n if (!this.ReactContainerElement || this.IsSelected(spec)) return;\n this.showHoverOverlay(spec.name);\n }\n\n ClearTreeItemHover(): void {\n this.removeHoverOverlay();\n }\n\n private showHoverOverlay(componentName: string): void {\n if (!this.ReactContainerElement) return;\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.removeHoverOverlay();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.hoverOverlay) {\n this.hoverOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.hoverOverlay);\n }\n\n this.positionOverlay(this.hoverOverlay, targetEl);\n this.hoverOverlay.style.border = '2px dashed var(--mj-brand-primary, #3B82F6)';\n this.hoverOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 5%, transparent)';\n }\n\n private removeHoverOverlay(): void {\n if (this.hoverOverlay?.parentNode) {\n this.hoverOverlay.parentNode.removeChild(this.hoverOverlay);\n }\n this.hoverOverlay = null;\n }\n\n // --- Region Highlighting (solid selection) ---\n\n private HighlightComponent(componentName: string): void {\n if (!this.ReactContainerElement) {\n this.ClearHighlight();\n return;\n }\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.ClearHighlight();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.highlightOverlay) {\n this.highlightOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.highlightOverlay);\n }\n\n this.positionOverlay(this.highlightOverlay, targetEl);\n this.highlightOverlay.style.border = '2px solid var(--mj-brand-primary, #3B82F6)';\n this.highlightOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, transparent)';\n\n // Watch for resize/layout changes\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.highlightOverlay) {\n this.positionOverlay(this.highlightOverlay, targetEl);\n }\n });\n this.resizeObserver.observe(targetEl);\n this.resizeObserver.observe(this.ReactContainerElement);\n\n // Set up bidirectional click selection on container\n this.installContainerClickListener();\n }\n\n private ensureContainerPositioned(): void {\n if (!this.ReactContainerElement) return;\n const containerStyle = getComputedStyle(this.ReactContainerElement);\n if (containerStyle.position === 'static') {\n this.ReactContainerElement.style.position = 'relative';\n }\n }\n\n /**\n * Gets the effective bounding rect for a component marker element.\n * display:contents elements return zero-size rects, so we compute\n * the union bounding box of their children instead.\n */\n private getEffectiveRect(el: Element): DOMRect {\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) return rect;\n\n // display:contents wrapper — union the bounding rects of all children\n const children = el.children;\n if (children.length === 0) return rect;\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;\n for (let i = 0; i < children.length; i++) {\n const childRect = children[i].getBoundingClientRect();\n if (childRect.width === 0 && childRect.height === 0) continue;\n top = Math.min(top, childRect.top);\n left = Math.min(left, childRect.left);\n bottom = Math.max(bottom, childRect.bottom);\n right = Math.max(right, childRect.right);\n }\n\n if (top === Infinity) return rect; // no visible children\n return new DOMRect(left, top, right - left, bottom - top);\n }\n\n private positionOverlay(overlay: HTMLElement, targetEl: Element): void {\n if (!this.ReactContainerElement) return;\n\n const targetRect = this.getEffectiveRect(targetEl);\n const containerRect = this.ReactContainerElement.getBoundingClientRect();\n\n overlay.style.position = 'absolute';\n overlay.style.top = `${targetRect.top - containerRect.top + this.ReactContainerElement.scrollTop}px`;\n overlay.style.left = `${targetRect.left - containerRect.left + this.ReactContainerElement.scrollLeft}px`;\n overlay.style.width = `${targetRect.width}px`;\n overlay.style.height = `${targetRect.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.zIndex = '10';\n overlay.style.borderRadius = '4px';\n overlay.style.transition = 'all 0.2s ease';\n }\n\n // --- Bidirectional click: clicking a component region selects it in the tree ---\n\n private installContainerClickListener(): void {\n if (this.containerClickHandler || !this.ReactContainerElement) return;\n\n this.containerClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n\n // Walk up from click target to find nearest [data-mj-component]\n const componentEl = target.closest('[data-mj-component]');\n if (!componentEl) return;\n\n const componentName = componentEl.getAttribute('data-mj-component');\n if (!componentName) return;\n\n // Find matching spec in the tree\n const matchingSpec = this.findSpecByName(componentName);\n if (matchingSpec && matchingSpec.name !== this.SelectedSpec?.name) {\n this.SelectComponent(matchingSpec);\n this.cdr.detectChanges();\n }\n };\n\n // Use capture phase so we observe the click without interfering with component handlers\n this.ReactContainerElement.addEventListener('click', this.containerClickHandler, true);\n }\n\n private removeContainerClickListener(): void {\n if (this.containerClickHandler && this.ReactContainerElement) {\n this.ReactContainerElement.removeEventListener('click', this.containerClickHandler, true);\n }\n this.containerClickHandler = null;\n }\n\n private findSpecByName(name: string): ComponentSpec | null {\n if (!this.ComponentSpec) return null;\n return this.walkSpecTree(this.ComponentSpec, name);\n }\n\n private walkSpecTree(spec: ComponentSpec, name: string): ComponentSpec | null {\n if (spec.name === name) return spec;\n if (spec.dependencies) {\n for (const child of spec.dependencies) {\n const found = this.walkSpecTree(child, name);\n if (found) return found;\n }\n }\n return null;\n }\n\n private ClearHighlight(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this.highlightOverlay?.parentNode) {\n this.highlightOverlay.parentNode.removeChild(this.highlightOverlay);\n }\n this.highlightOverlay = null;\n this.removeHoverOverlay();\n this.removeContainerClickListener();\n }\n\n ClosePanel(): void {\n this.ClearHighlight();\n this.Closed.emit();\n }\n\n ngOnDestroy(): void {\n this.ClearHighlight();\n }\n}\n","<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No component hierarchy available\"\n Size=\"compact\" />\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <mj-alert Variant=\"success\">Feedback submitted successfully!</mj-alert>\n }\n @if (SubmitError) {\n <mj-alert Variant=\"error\">{{ SubmitError }}</mj-alert>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-hand-pointer\"\n Title=\"Select a component from the tree to provide feedback\"\n Size=\"compact\" />\n }\n </div>\n </div>\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"component-feedback-panel.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts","../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\nimport { MJEmptyStateComponent, MJAlertComponent } from '@memberjunction/ng-ui-components';\n\n/**\n * Flattened tree item for rendering the component hierarchy\n */\ninterface TreeItem {\n spec: ComponentSpec;\n depth: number;\n hasChildren: boolean;\n}\n\n/**\n * Component feedback panel that displays component hierarchy tree\n * and allows users to select components and provide star ratings with comments.\n * Registry-agnostic: works with any component registry (Skip, MJ Central, etc.)\n */\n@Component({\n selector: 'mj-component-feedback-panel',\n standalone: true,\n imports: [CommonModule, FormsModule, MarkdownModule, MJEmptyStateComponent, MJAlertComponent],\n templateUrl: './component-feedback-panel.component.html',\n styleUrls: ['./component-feedback-panel.component.css']\n})\nexport class ComponentFeedbackPanelComponent extends BaseAngularComponent implements OnDestroy {\n @Input() ComponentSpec: ComponentSpec | null = null;\n @Input() ReactContainerElement: HTMLElement | null = null;\n @Input() ConversationId: string | null = null;\n @Input() ConversationDetailId: string | null = null;\n\n @Output() Closed = new EventEmitter<void>();\n\n // Feedback form state\n public SelectedSpec: ComponentSpec | null = null;\n public StarRating = 0;\n public HoverRating = 0;\n public FeedbackComments = '';\n public IsSubmitting = false;\n public SubmitSuccess = false;\n public SubmitError = '';\n\n // Tree state\n public ExpandedNodes = new Set<string>();\n\n // Highlight overlays\n private highlightOverlay: HTMLElement | null = null;\n private hoverOverlay: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private containerClickHandler: ((e: MouseEvent) => void) | null = null;\n\n private cdr = inject(ChangeDetectorRef);\n\n // --- Tree Methods ---\n\n GetTreeItems(): TreeItem[] {\n if (!this.ComponentSpec) return [];\n if (!this.ExpandedNodes.has(this.ComponentSpec.name)) {\n this.ExpandedNodes.add(this.ComponentSpec.name);\n }\n return this.buildTree(this.ComponentSpec, 0);\n }\n\n private buildTree(spec: ComponentSpec, depth: number): TreeItem[] {\n const items: TreeItem[] = [{\n spec,\n depth,\n hasChildren: !!(spec.dependencies && spec.dependencies.length > 0)\n }];\n if (this.ExpandedNodes.has(spec.name) && spec.dependencies) {\n for (const child of spec.dependencies) {\n items.push(...this.buildTree(child, depth + 1));\n }\n }\n return items;\n }\n\n ToggleNode(spec: ComponentSpec, event: MouseEvent): void {\n event.stopPropagation();\n if (this.ExpandedNodes.has(spec.name)) {\n this.ExpandedNodes.delete(spec.name);\n } else {\n this.ExpandedNodes.add(spec.name);\n }\n }\n\n IsNodeExpanded(spec: ComponentSpec): boolean {\n return this.ExpandedNodes.has(spec.name);\n }\n\n SelectComponent(spec: ComponentSpec): void {\n this.SelectedSpec = spec;\n this.ResetForm();\n this.highlightComponent(spec.name);\n }\n\n IsSelected(spec: ComponentSpec): boolean {\n return this.SelectedSpec?.name === spec.name;\n }\n\n GetIndentation(depth: number): string {\n return `${depth * 20}px`;\n }\n\n // --- Star Rating (supports half-star increments) ---\n\n SetRating(value: number): void {\n this.StarRating = value;\n }\n\n SetHoverRating(value: number): void {\n this.HoverRating = value;\n }\n\n ClearHoverRating(): void {\n this.HoverRating = 0;\n }\n\n GetDisplayRating(): number {\n return this.HoverRating || this.StarRating;\n }\n\n /** Returns 'full' | 'half' | 'empty' for the given 1-based star index */\n GetStarState(index: number): 'full' | 'half' | 'empty' {\n const rating = this.GetDisplayRating();\n if (index <= rating) return 'full';\n if (index - 0.5 <= rating) return 'half';\n return 'empty';\n }\n\n IsStarFilled(index: number): boolean {\n return index <= this.GetDisplayRating();\n }\n\n // --- Form ---\n\n ResetForm(): void {\n this.StarRating = 0;\n this.HoverRating = 0;\n this.FeedbackComments = '';\n this.SubmitSuccess = false;\n this.SubmitError = '';\n }\n\n CanSubmit(): boolean {\n return !!this.SelectedSpec && this.StarRating > 0 && !this.IsSubmitting;\n }\n\n async SubmitFeedback(): Promise<void> {\n if (!this.CanSubmit() || !this.SelectedSpec) return;\n\n this.IsSubmitting = true;\n this.SubmitError = '';\n this.SubmitSuccess = false;\n this.cdr.detectChanges();\n\n try {\n // Dynamic import to avoid adding graphql-dataprovider as a package dependency.\n // At runtime in the browser, this.ProviderToUse is always a GraphQLDataProvider.\n const { GraphQLComponentRegistryClient } = await import('@memberjunction/graphql-dataprovider');\n const provider = this.ProviderToUse;\n const client = new GraphQLComponentRegistryClient(provider as ConstructorParameters<typeof GraphQLComponentRegistryClient>[0]);\n\n const response = await client.SendComponentFeedback({\n componentName: this.SelectedSpec.name,\n componentNamespace: this.SelectedSpec.namespace || this.SelectedSpec.registry || '',\n componentVersion: this.SelectedSpec.version,\n registryName: this.SelectedSpec.registry,\n rating: this.StarRating * 20, // 0-5 -> 0-100\n comments: this.FeedbackComments.trim() || undefined,\n conversationID: this.ConversationId || undefined,\n conversationDetailID: this.ConversationDetailId || undefined\n });\n\n if (response.success) {\n this.SubmitSuccess = true;\n setTimeout(() => {\n this.ResetForm();\n this.cdr.detectChanges();\n }, 2000);\n } else {\n this.SubmitError = response.error || 'Failed to submit feedback.';\n }\n } catch (error) {\n this.SubmitError = 'Failed to submit feedback. Please try again.';\n console.error('Error submitting component feedback:', error);\n } finally {\n this.IsSubmitting = false;\n this.cdr.detectChanges();\n }\n }\n\n // --- Hover Highlight (light preview on tree hover) ---\n\n HoverTreeItem(spec: ComponentSpec): void {\n if (!this.ReactContainerElement || this.IsSelected(spec)) return;\n this.showHoverOverlay(spec.name);\n }\n\n ClearTreeItemHover(): void {\n this.removeHoverOverlay();\n }\n\n private showHoverOverlay(componentName: string): void {\n if (!this.ReactContainerElement) return;\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.removeHoverOverlay();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.hoverOverlay) {\n this.hoverOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.hoverOverlay);\n }\n\n this.positionOverlay(this.hoverOverlay, targetEl);\n this.hoverOverlay.style.border = '2px dashed var(--mj-brand-primary, #3B82F6)';\n this.hoverOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 5%, transparent)';\n }\n\n private removeHoverOverlay(): void {\n if (this.hoverOverlay?.parentNode) {\n this.hoverOverlay.parentNode.removeChild(this.hoverOverlay);\n }\n this.hoverOverlay = null;\n }\n\n // --- Region Highlighting (solid selection) ---\n\n private highlightComponent(componentName: string): void {\n if (!this.ReactContainerElement) {\n this.clearHighlight();\n return;\n }\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.clearHighlight();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.highlightOverlay) {\n this.highlightOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.highlightOverlay);\n }\n\n this.positionOverlay(this.highlightOverlay, targetEl);\n this.highlightOverlay.style.border = '2px solid var(--mj-brand-primary, #3B82F6)';\n this.highlightOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, transparent)';\n\n // Watch for resize/layout changes\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.highlightOverlay) {\n this.positionOverlay(this.highlightOverlay, targetEl);\n }\n });\n this.resizeObserver.observe(targetEl);\n this.resizeObserver.observe(this.ReactContainerElement);\n\n // Set up bidirectional click selection on container\n this.installContainerClickListener();\n }\n\n private ensureContainerPositioned(): void {\n if (!this.ReactContainerElement) return;\n const containerStyle = getComputedStyle(this.ReactContainerElement);\n if (containerStyle.position === 'static') {\n this.ReactContainerElement.style.position = 'relative';\n }\n }\n\n /**\n * Gets the effective bounding rect for a component marker element.\n * display:contents elements return zero-size rects, so we compute\n * the union bounding box of their children instead.\n */\n private getEffectiveRect(el: Element): DOMRect {\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) return rect;\n\n // display:contents wrapper — union the bounding rects of all children\n const children = el.children;\n if (children.length === 0) return rect;\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;\n for (let i = 0; i < children.length; i++) {\n const childRect = children[i].getBoundingClientRect();\n if (childRect.width === 0 && childRect.height === 0) continue;\n top = Math.min(top, childRect.top);\n left = Math.min(left, childRect.left);\n bottom = Math.max(bottom, childRect.bottom);\n right = Math.max(right, childRect.right);\n }\n\n if (top === Infinity) return rect; // no visible children\n return new DOMRect(left, top, right - left, bottom - top);\n }\n\n private positionOverlay(overlay: HTMLElement, targetEl: Element): void {\n if (!this.ReactContainerElement) return;\n\n const targetRect = this.getEffectiveRect(targetEl);\n const containerRect = this.ReactContainerElement.getBoundingClientRect();\n\n overlay.style.position = 'absolute';\n overlay.style.top = `${targetRect.top - containerRect.top + this.ReactContainerElement.scrollTop}px`;\n overlay.style.left = `${targetRect.left - containerRect.left + this.ReactContainerElement.scrollLeft}px`;\n overlay.style.width = `${targetRect.width}px`;\n overlay.style.height = `${targetRect.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.zIndex = '10';\n overlay.style.borderRadius = '4px';\n overlay.style.transition = 'all 0.2s ease';\n }\n\n // --- Bidirectional click: clicking a component region selects it in the tree ---\n\n private installContainerClickListener(): void {\n if (this.containerClickHandler || !this.ReactContainerElement) return;\n\n this.containerClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n\n // Walk up from click target to find nearest [data-mj-component]\n const componentEl = target.closest('[data-mj-component]');\n if (!componentEl) return;\n\n const componentName = componentEl.getAttribute('data-mj-component');\n if (!componentName) return;\n\n // Find matching spec in the tree\n const matchingSpec = this.findSpecByName(componentName);\n if (matchingSpec && matchingSpec.name !== this.SelectedSpec?.name) {\n this.SelectComponent(matchingSpec);\n this.cdr.detectChanges();\n }\n };\n\n // Use capture phase so we observe the click without interfering with component handlers\n this.ReactContainerElement.addEventListener('click', this.containerClickHandler, true);\n }\n\n private removeContainerClickListener(): void {\n if (this.containerClickHandler && this.ReactContainerElement) {\n this.ReactContainerElement.removeEventListener('click', this.containerClickHandler, true);\n }\n this.containerClickHandler = null;\n }\n\n private findSpecByName(name: string): ComponentSpec | null {\n if (!this.ComponentSpec) return null;\n return this.walkSpecTree(this.ComponentSpec, name);\n }\n\n private walkSpecTree(spec: ComponentSpec, name: string): ComponentSpec | null {\n if (spec.name === name) return spec;\n if (spec.dependencies) {\n for (const child of spec.dependencies) {\n const found = this.walkSpecTree(child, name);\n if (found) return found;\n }\n }\n return null;\n }\n\n private clearHighlight(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this.highlightOverlay?.parentNode) {\n this.highlightOverlay.parentNode.removeChild(this.highlightOverlay);\n }\n this.highlightOverlay = null;\n this.removeHoverOverlay();\n this.removeContainerClickListener();\n }\n\n ClosePanel(): void {\n this.clearHighlight();\n this.Closed.emit();\n }\n\n ngOnDestroy(): void {\n this.clearHighlight();\n }\n}\n","<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No component hierarchy available\"\n Size=\"compact\" />\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <mj-alert Variant=\"success\">Feedback submitted successfully!</mj-alert>\n }\n @if (SubmitError) {\n <mj-alert Variant=\"error\">{{ SubmitError }}</mj-alert>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-hand-pointer\"\n Title=\"Select a component from the tree to provide feedback\"\n Size=\"compact\" />\n }\n </div>\n </div>\n </div>\n</div>\n"]}
|
|
@@ -15,5 +15,7 @@ export interface PermissionEvaluationResult {
|
|
|
15
15
|
* Recursively evaluates permissions for a component and all its dependencies.
|
|
16
16
|
* Walks the full dependency tree, deduplicating results.
|
|
17
17
|
*/
|
|
18
|
+
export declare function EvaluateComponentPermissions(spec: ComponentSpec, currentUser: UserInfo, provider?: IMetadataProvider): PermissionEvaluationResult;
|
|
19
|
+
/** @deprecated Use {@link EvaluateComponentPermissions}. */
|
|
18
20
|
export declare function evaluateComponentPermissions(spec: ComponentSpec, currentUser: UserInfo, provider?: IMetadataProvider): PermissionEvaluationResult;
|
|
19
21
|
//# sourceMappingURL=component-permission-evaluation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-permission-evaluation.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-permission-evaluation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,uDAAuD;IACvD,cAAc,EAAE,MAAM,EAAE,CAAC;CAC5B;AAuDD;;;GAGG;AACH,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,0BAA0B,CAe5B"}
|
|
1
|
+
{"version":3,"file":"component-permission-evaluation.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-permission-evaluation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,uDAAuD;IACvD,cAAc,EAAE,MAAM,EAAE,CAAC;CAC5B;AAuDD;;;GAGG;AACH,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,0BAA0B,CAe5B;AAED,4DAA4D;AAC5D,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,0BAA0B,CAE5B"}
|
|
@@ -48,10 +48,10 @@ function evaluateComponentPermissionsSingle(spec, currentUser, provider) {
|
|
|
48
48
|
* Recursively evaluates permissions for a component and all its dependencies.
|
|
49
49
|
* Walks the full dependency tree, deduplicating results.
|
|
50
50
|
*/
|
|
51
|
-
export function
|
|
51
|
+
export function EvaluateComponentPermissions(spec, currentUser, provider) {
|
|
52
52
|
const result = evaluateComponentPermissionsSingle(spec, currentUser, provider);
|
|
53
53
|
for (const dep of spec.dependencies ?? []) {
|
|
54
|
-
const depResult =
|
|
54
|
+
const depResult = EvaluateComponentPermissions(dep, currentUser, provider);
|
|
55
55
|
result.missingEntities.push(...depResult.missingEntities);
|
|
56
56
|
result.missingQueries.push(...depResult.missingQueries);
|
|
57
57
|
}
|
|
@@ -61,4 +61,8 @@ export function evaluateComponentPermissions(spec, currentUser, provider) {
|
|
|
61
61
|
result.canRun = result.missingEntities.length === 0 && result.missingQueries.length === 0;
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
64
|
+
/** @deprecated Use {@link EvaluateComponentPermissions}. */
|
|
65
|
+
export function evaluateComponentPermissions(spec, currentUser, provider) {
|
|
66
|
+
return EvaluateComponentPermissions(spec, currentUser, provider);
|
|
67
|
+
}
|
|
64
68
|
//# sourceMappingURL=component-permission-evaluation.js.map
|