@memberjunction/ng-dashboards 5.21.0 → 5.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +102 -0
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -0
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +583 -0
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -0
  5. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +148 -0
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -0
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +773 -0
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -0
  9. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +241 -0
  10. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -0
  11. package/dist/AI/components/vectors/vector-management-resource.component.js +1782 -0
  12. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -0
  13. package/dist/AI/index.d.ts +3 -0
  14. package/dist/AI/index.d.ts.map +1 -1
  15. package/dist/AI/index.js +6 -0
  16. package/dist/AI/index.js.map +1 -1
  17. package/dist/AI/services/ai-instrumentation.service.d.ts +50 -7
  18. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  19. package/dist/AI/services/ai-instrumentation.service.js +161 -193
  20. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  21. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +11 -0
  22. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  23. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +57 -0
  24. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  25. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +1 -1
  26. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +10 -2
  27. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  28. package/dist/DataExplorer/data-explorer-dashboard.component.js +35 -11
  29. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  30. package/dist/DataExplorer/data-explorer-resource.component.d.ts +1 -0
  31. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  32. package/dist/DataExplorer/data-explorer-resource.component.js +8 -4
  33. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  34. package/dist/Home/home-dashboard.component.d.ts +181 -1
  35. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  36. package/dist/Home/home-dashboard.component.js +1704 -182
  37. package/dist/Home/home-dashboard.component.js.map +1 -1
  38. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +121 -0
  39. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -0
  40. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +1058 -0
  41. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -0
  42. package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts +56 -0
  43. package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts.map +1 -0
  44. package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js +291 -0
  45. package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js.map +1 -0
  46. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +85 -0
  47. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -0
  48. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +461 -0
  49. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -0
  50. package/dist/KnowledgeHub/index.d.ts +4 -0
  51. package/dist/KnowledgeHub/index.d.ts.map +1 -0
  52. package/dist/KnowledgeHub/index.js +5 -0
  53. package/dist/KnowledgeHub/index.js.map +1 -0
  54. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  55. package/dist/QueryBrowser/query-browser-resource.component.js +5 -1
  56. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  57. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  58. package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -0
  59. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  60. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +7 -1
  61. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
  62. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +63 -8
  63. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
  64. package/dist/Testing/components/testing-dashboard-tab.component.d.ts +9 -1
  65. package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -1
  66. package/dist/Testing/components/testing-dashboard-tab.component.js +109 -62
  67. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  68. package/dist/Testing/components/testing-explorer.component.d.ts +2 -1
  69. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  70. package/dist/Testing/components/testing-explorer.component.js +241 -200
  71. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  72. package/dist/Testing/components/testing-runs-resource.component.d.ts +7 -1
  73. package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
  74. package/dist/Testing/components/testing-runs-resource.component.js +63 -8
  75. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
  76. package/dist/Testing/components/testing-runs.component.d.ts.map +1 -1
  77. package/dist/Testing/components/testing-runs.component.js +7 -5
  78. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  79. package/dist/Testing/testing-dashboard.component.d.ts +9 -1
  80. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
  81. package/dist/Testing/testing-dashboard.component.js +128 -59
  82. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  83. package/dist/ai-dashboards.module.d.ts +26 -19
  84. package/dist/ai-dashboards.module.d.ts.map +1 -1
  85. package/dist/ai-dashboards.module.js +40 -5
  86. package/dist/ai-dashboards.module.js.map +1 -1
  87. package/dist/core-dashboards.module.d.ts +1 -0
  88. package/dist/core-dashboards.module.d.ts.map +1 -1
  89. package/dist/core-dashboards.module.js +3 -0
  90. package/dist/core-dashboards.module.js.map +1 -1
  91. package/dist/public-api.d.ts +4 -1
  92. package/dist/public-api.d.ts.map +1 -1
  93. package/dist/public-api.js +5 -1
  94. package/dist/public-api.js.map +1 -1
  95. package/dist/testing-dashboards.module.d.ts +5 -4
  96. package/dist/testing-dashboards.module.d.ts.map +1 -1
  97. package/dist/testing-dashboards.module.js +4 -0
  98. package/dist/testing-dashboards.module.js.map +1 -1
  99. package/package.json +44 -42
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-config-resource.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/config/knowledge-config-resource.component.ts","../../../../src/KnowledgeHub/components/config/knowledge-config-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub Configuration Resource Component\n *\n * Full configuration dashboard for Knowledge Hub infrastructure:\n * Vector DB provider management, vector index CRUD, embedding model selection,\n * pipeline settings, full-text index config, and scoring thresholds.\n */\n\nimport { Component, ChangeDetectorRef, OnDestroy, AfterViewInit, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { BaseEntity, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData, MJVectorDatabaseEntity, MJVectorIndexEntity } from '@memberjunction/core-entities';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\n/** Configuration section definition */\ninterface ConfigSection {\n ID: string;\n Label: string;\n Icon: string;\n Description: string;\n}\n\n/** Pipeline configuration settings */\ninterface PipelineConfig {\n AutotagOnIngest: boolean;\n VectorizeOnIngest: boolean;\n DefaultBatchSize: number;\n MaxConcurrentJobs: number;\n}\n\n/** Threshold settings */\ninterface ThresholdConfig {\n DuplicateAbsolute: number;\n DuplicatePotential: number;\n SearchRelevance: number;\n AutotagConfidence: number;\n}\n\n/** Vector DB provider display record */\ninterface VectorDBRecord {\n ID: string;\n Name: string;\n ClassKey: string;\n Description: string;\n}\n\n/** Vector index display record */\ninterface VectorIndexRecord {\n ID: string;\n Name: string;\n EmbeddingModel: string;\n EmbeddingModelID: string;\n VectorDatabase: string;\n VectorDatabaseID: string;\n}\n\n/** Embedding model display record */\ninterface EmbeddingModelRecord {\n ID: string;\n Name: string;\n}\n\n/** Full-text searchable entity */\ninterface FTSEntityRecord {\n EntityName: string;\n IndexedFields: string[];\n TitleField: string;\n SnippetField: string;\n Enabled: boolean;\n}\n\n@RegisterClass(BaseResourceComponent, 'KnowledgeConfigResource')\n@Component({\n standalone: false,\n selector: 'app-knowledge-config-resource',\n templateUrl: './knowledge-config-resource.component.html',\n styleUrls: ['./knowledge-config-resource.component.css']\n})\nexport class KnowledgeConfigResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Configuration';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-gear';\n }\n\n // --- Navigation ---\n public Sections: ConfigSection[] = [\n { ID: 'pipeline', Label: 'Pipeline', Icon: 'fa-solid fa-diagram-project', Description: 'Configure the knowledge ingestion pipeline stages' },\n { ID: 'vectordb', Label: 'Vector Database', Icon: 'fa-solid fa-database', Description: 'Manage vector database connections and indexes' },\n { ID: 'fulltext', Label: 'Full-Text Indexes', Icon: 'fa-solid fa-text-width', Description: 'Configure SQL full-text search indexes' },\n { ID: 'embedding', Label: 'Embedding Models', Icon: 'fa-solid fa-microchip', Description: 'Select and configure embedding models' },\n { ID: 'thresholds', Label: 'Thresholds', Icon: 'fa-solid fa-sliders', Description: 'Set scoring thresholds for search and deduplication' },\n ];\n\n public ActiveSection = 'pipeline';\n public IsLoading = true;\n public IsSaving = false;\n public HasUnsavedChanges = false;\n\n // --- Pipeline ---\n public PipelineSettings: PipelineConfig = {\n AutotagOnIngest: true,\n VectorizeOnIngest: true,\n DefaultBatchSize: 100,\n MaxConcurrentJobs: 3\n };\n\n // --- Thresholds ---\n public ThresholdSettings: ThresholdConfig = {\n DuplicateAbsolute: 0.95,\n DuplicatePotential: 0.75,\n SearchRelevance: 0.3,\n AutotagConfidence: 0.7\n };\n\n // --- Vector DB Providers ---\n public VectorDBProviders: VectorDBRecord[] = [];\n public get HasVectorDBProvider(): boolean { return this.VectorDBProviders.length > 0; }\n\n // --- Vector Indexes ---\n public VectorIndexes: VectorIndexRecord[] = [];\n public get HasVectorIndex(): boolean { return this.VectorIndexes.length > 0; }\n\n // --- Embedding Models ---\n public EmbeddingModels: EmbeddingModelRecord[] = [];\n public get HasEmbeddingModel(): boolean { return this.EmbeddingModels.length > 0; }\n public get EmbeddingModelName(): string { return this.EmbeddingModels.length > 0 ? this.EmbeddingModels[0].Name : ''; }\n\n // --- Setup Progress ---\n public get SetupStepsCompleted(): number {\n let count = 0;\n if (this.HasVectorDBProvider) count++;\n if (this.HasEmbeddingModel) count++;\n if (this.HasVectorIndex) count++;\n return count;\n }\n public get VectorSetupComplete(): boolean {\n return this.HasVectorDBProvider && this.HasVectorIndex && this.HasEmbeddingModel;\n }\n\n // --- Full-Text Search Entities ---\n public FTSEntities: FTSEntityRecord[] = [];\n public IsLoadingFTSEntities = false;\n public FTSFilterText = '';\n\n public get EnabledFTSCount(): number {\n return this.FTSEntities.filter(e => e.Enabled).length;\n }\n\n public get FilteredFTSEntities(): FTSEntityRecord[] {\n if (!this.FTSFilterText.trim()) return this.FTSEntities;\n const filter = this.FTSFilterText.toLowerCase();\n return this.FTSEntities.filter(e => e.EntityName.toLowerCase().includes(filter));\n }\n\n // --- Create Index Form ---\n public ShowCreateIndexForm = false;\n public IsCreatingIndex = false;\n public NewIndexName = '';\n public NewIndexVectorDBID = '';\n public NewIndexEmbeddingModelID = '';\n\n ngAfterViewInit(): void {\n this.loadConfiguration();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ================================================================\n // Public Methods\n // ================================================================\n\n public SelectSection(sectionId: string): void {\n this.ActiveSection = sectionId;\n this.cdr.detectChanges();\n }\n\n public OnSettingChanged(): void {\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n public async SaveConfiguration(): Promise<void> {\n this.IsSaving = true;\n this.cdr.detectChanges();\n try {\n await new Promise(resolve => setTimeout(resolve, 500));\n this.HasUnsavedChanges = false;\n MJNotificationService.Instance.CreateSimpleNotification('Configuration saved', 'success', 2000);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n public ResetConfiguration(): void {\n this.loadConfiguration();\n this.HasUnsavedChanges = false;\n this.cdr.detectChanges();\n }\n\n /** Handle toggling an FTS entity */\n public OnFTSEntityToggled(entity: FTSEntityRecord): void {\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n public FormatThreshold(value: number): string {\n return `${Math.round(value * 100)}%`;\n }\n\n /** Open the create index inline form */\n public OpenCreateIndexForm(): void {\n this.ShowCreateIndexForm = true;\n this.NewIndexName = 'mj-knowledge-index';\n this.NewIndexVectorDBID = this.VectorDBProviders.length > 0 ? this.VectorDBProviders[0].ID : '';\n this.NewIndexEmbeddingModelID = this.EmbeddingModels.length > 0 ? this.EmbeddingModels[0].ID : '';\n this.cdr.detectChanges();\n }\n\n /** Cancel creating an index */\n public CancelCreateIndex(): void {\n this.ShowCreateIndexForm = false;\n this.cdr.detectChanges();\n }\n\n /** Create a new vector index */\n public async CreateIndex(): Promise<void> {\n if (!this.NewIndexName.trim() || !this.NewIndexVectorDBID || !this.NewIndexEmbeddingModelID) {\n MJNotificationService.Instance.CreateSimpleNotification('Please fill in all fields', 'warning', 3000);\n return;\n }\n\n this.IsCreatingIndex = true;\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const index = await md.GetEntityObject<MJVectorIndexEntity>('MJ: Vector Indexes');\n index.NewRecord();\n index.Name = this.NewIndexName.trim();\n index.VectorDatabaseID = this.NewIndexVectorDBID;\n index.EmbeddingModelID = this.NewIndexEmbeddingModelID;\n index.Description = `Knowledge Hub vector index created ${new Date().toLocaleDateString()}`;\n\n const saved = await index.Save();\n if (saved) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Vector index \"${this.NewIndexName}\" created successfully`,\n 'success', 3000\n );\n this.ShowCreateIndexForm = false;\n await this.loadConfiguration();\n } else {\n const msg = index.LatestResult?.CompleteMessage || 'Unknown error';\n console.error('[KnowledgeConfig] Failed to create index:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(`Failed to create index: ${msg}`, 'error', 5000);\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[KnowledgeConfig] Error creating index:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);\n } finally {\n this.IsCreatingIndex = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Delete a vector index */\n public async DeleteIndex(indexId: string): Promise<void> {\n const idx = this.VectorIndexes.find(i => UUIDsEqual(i.ID, indexId));\n if (!idx) return;\n\n try {\n const md = new Metadata();\n const entity = await md.GetEntityObject<MJVectorIndexEntity>('MJ: Vector Indexes');\n const loaded = await entity.Load(indexId);\n if (!loaded) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Could not load vector index \"${idx.Name}\"`, 'error', 3000\n );\n return;\n }\n const deleted = await entity.Delete();\n if (deleted) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Index \"${idx.Name}\" deleted`, 'success', 2000\n );\n await this.loadConfiguration();\n } else {\n const msg = entity.LatestResult?.CompleteMessage || 'Unknown error';\n console.error('[KnowledgeConfig] Delete failed:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(\n `Delete failed: ${msg}`, 'error', 5000\n );\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[KnowledgeConfig] Error deleting index:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);\n }\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n private async loadConfiguration(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = new RunView();\n const [vdbResult, modelsResult, indexResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Vector Databases',\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: AI Models',\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Vector Indexes',\n ResultType: 'simple'\n }\n ]);\n\n this.loadVectorDBProviders(vdbResult.Success ? vdbResult.Results : []);\n this.loadEmbeddingModels(modelsResult.Success ? modelsResult.Results : []);\n this.loadVectorIndexes(indexResult.Success ? indexResult.Results : []);\n } catch (error) {\n console.error('[KnowledgeConfig] Error loading configuration:', error);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n\n // Load FTS entities in background (doesn't block main config)\n this.loadFTSEntities();\n }\n\n private async loadFTSEntities(): Promise<void> {\n this.IsLoadingFTSEntities = true;\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const allEntities = md.Entities;\n const ftsEntities: FTSEntityRecord[] = [];\n\n for (const entity of allEntities) {\n const textFields = entity.Fields.filter(\n (f: { Name: string; Type: string; MaxLength: number; IsPrimaryKey: boolean }) =>\n !f.IsPrimaryKey &&\n !f.Name.startsWith('__mj') &&\n (f.Type.toLowerCase().includes('varchar') ||\n f.Type.toLowerCase().includes('text') ||\n f.Type.toLowerCase() === 'ntext') &&\n f.MaxLength !== 1\n );\n\n if (textFields.length === 0) continue;\n\n const preferredTitleNames = ['Name', 'Title', 'Subject', 'Label'];\n const preferredSnippetNames = ['Description', 'Summary', 'Body', 'Content', 'Text', 'Notes'];\n\n const titleField = textFields.find((f: { Name: string }) => preferredTitleNames.includes(f.Name))?.Name\n || textFields[0]?.Name || 'Name';\n const snippetField = textFields.find((f: { Name: string }) =>\n preferredSnippetNames.includes(f.Name) && f.Name !== titleField\n )?.Name || titleField;\n\n ftsEntities.push({\n EntityName: entity.Name,\n IndexedFields: textFields.slice(0, 4).map((f: { Name: string }) => f.Name),\n TitleField: titleField,\n SnippetField: snippetField,\n Enabled: true,\n });\n }\n\n ftsEntities.sort((a, b) => a.EntityName.localeCompare(b.EntityName));\n this.FTSEntities = ftsEntities;\n } catch (error) {\n console.error('[KnowledgeConfig] Error loading FTS entities:', error);\n } finally {\n this.IsLoadingFTSEntities = false;\n this.cdr.detectChanges();\n }\n }\n\n private loadVectorDBProviders(records: Record<string, unknown>[]): void {\n this.VectorDBProviders = records.map(r => ({\n ID: String(r['ID'] || ''),\n Name: String(r['Name'] || ''),\n ClassKey: String(r['ClassKey'] || ''),\n Description: String(r['Description'] || '')\n }));\n }\n\n private loadVectorIndexes(records: Record<string, unknown>[]): void {\n this.VectorIndexes = records.map(r => ({\n ID: String(r['ID'] || ''),\n Name: String(r['Name'] || 'Unnamed Index'),\n EmbeddingModel: String(r['EmbeddingModel'] || ''),\n EmbeddingModelID: String(r['EmbeddingModelID'] || ''),\n VectorDatabase: String(r['VectorDatabase'] || ''),\n VectorDatabaseID: String(r['VectorDatabaseID'] || '')\n }));\n }\n\n private loadEmbeddingModels(records: Record<string, unknown>[]): void {\n this.EmbeddingModels = records\n .filter(m =>\n String(m['AIModelType'] || '').toLowerCase().includes('embedding') ||\n String(m['Name'] || '').toLowerCase().includes('embedding') ||\n String(m['Name'] || '').toLowerCase().includes('embed')\n )\n .map(m => ({\n ID: String(m['ID']),\n Name: String(m['Name'])\n }));\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadKnowledgeConfigResource(): void {\n // Prevents tree-shaking\n}\n","@if (IsLoading) {\n <div class=\"config-loading\">\n <mj-loading text=\"Loading configuration...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"config-layout\">\n <!-- Left Navigation -->\n <nav class=\"config-nav\">\n <div class=\"config-nav-header\">\n <i class=\"fa-solid fa-cogs\"></i>\n <span>Configuration</span>\n </div>\n @for (section of Sections; track section.ID) {\n <button\n class=\"config-nav-item\"\n [class.config-nav-item-active]=\"ActiveSection === section.ID\"\n (click)=\"SelectSection(section.ID)\"\n >\n <i [class]=\"section.Icon\"></i>\n <span>{{ section.Label }}</span>\n </button>\n }\n </nav>\n\n <!-- Content Area -->\n <div class=\"config-content\">\n <!-- Pipeline Settings -->\n @if (ActiveSection === 'pipeline') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Pipeline Settings</h2>\n <p class=\"config-section-desc\">Configure how the Knowledge Pipeline processes incoming content.</p>\n\n <div class=\"config-group\">\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Auto-tag on Ingest</span>\n <span class=\"config-hint\">Automatically run autotagging when new content is ingested</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.AutotagOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Vectorize on Ingest</span>\n <span class=\"config-hint\">Automatically create embeddings for new content</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.VectorizeOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Default Batch Size</span>\n <span class=\"config-hint\">Number of items processed per batch</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.DefaultBatchSize\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"10\" max=\"1000\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Max Concurrent Jobs</span>\n <span class=\"config-hint\">Maximum number of pipeline jobs running at once</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.MaxConcurrentJobs\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"1\" max=\"10\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Vector Database Settings -->\n @if (ActiveSection === 'vectordb') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Vector Database</h2>\n <p class=\"config-section-desc\">Manage the shared vector index and database connection.</p>\n\n <!-- Setup Progress -->\n <div class=\"setup-progress\">\n <div class=\"setup-progress-header\">\n <span class=\"setup-progress-label\">Setup Progress</span>\n <span class=\"setup-progress-count\">{{ SetupStepsCompleted }} of 3 complete</span>\n </div>\n <div class=\"setup-progress-bar\">\n <div class=\"setup-progress-fill\" [style.width.%]=\"(SetupStepsCompleted / 3) * 100\"></div>\n </div>\n </div>\n\n <!-- Step 1: Providers -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorDBProvider\" [class.setup-step-pending]=\"!HasVectorDBProvider\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorDBProvider) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">1</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Database Providers</span>\n @if (HasVectorDBProvider) {\n <span class=\"setup-step-status\">{{ VectorDBProviders.length }} provider(s) registered</span>\n } @else {\n <span class=\"setup-step-status\">No providers registered. Add a vector database provider (e.g., Pinecone, Weaviate) via the admin console.</span>\n }\n </div>\n </div>\n @if (HasVectorDBProvider) {\n <div class=\"setup-step-detail\">\n @for (provider of VectorDBProviders; track provider.ID) {\n <div class=\"provider-card\">\n <div class=\"provider-icon\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"provider-info\">\n <span class=\"provider-name\">{{ provider.Name }}</span>\n <span class=\"provider-class\">{{ provider.ClassKey }}</span>\n </div>\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Step 2: Embedding Model -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasEmbeddingModel\" [class.setup-step-pending]=\"!HasEmbeddingModel\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasEmbeddingModel) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">2</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Embedding Models</span>\n @if (HasEmbeddingModel) {\n <span class=\"setup-step-status\">{{ EmbeddingModels.length }} model(s) available</span>\n } @else {\n <span class=\"setup-step-status\">No embedding models found. Configure at least one in the AI app > Models tab.</span>\n }\n </div>\n </div>\n @if (HasEmbeddingModel) {\n <div class=\"setup-step-detail\">\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Step 3: Vector Indexes -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorIndex\" [class.setup-step-pending]=\"!HasVectorIndex\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorIndex) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">3</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Indexes</span>\n @if (HasVectorIndex) {\n <span class=\"setup-step-status\">{{ VectorIndexes.length }} index(es) configured</span>\n } @else if (HasVectorDBProvider && HasEmbeddingModel) {\n <span class=\"setup-step-status\">No indexes yet — create one below.</span>\n } @else {\n <span class=\"setup-step-status\">Complete steps 1 and 2 first.</span>\n }\n </div>\n @if (HasVectorDBProvider && HasEmbeddingModel && !ShowCreateIndexForm) {\n <button class=\"setup-step-action\" (click)=\"OpenCreateIndexForm()\">\n <i class=\"fa-solid fa-plus\"></i> Create Index\n </button>\n }\n </div>\n\n <!-- Existing Indexes -->\n @if (HasVectorIndex) {\n <div class=\"setup-step-detail\">\n @for (idx of VectorIndexes; track idx.ID) {\n <div class=\"index-card\">\n <div class=\"index-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"index-info\">\n <span class=\"index-name\">{{ idx.Name }}</span>\n <span class=\"index-meta\">\n <i class=\"fa-solid fa-database\"></i> {{ idx.VectorDatabase }}\n &nbsp;·&nbsp;\n <i class=\"fa-solid fa-microchip\"></i> {{ idx.EmbeddingModel }}\n </span>\n </div>\n <div class=\"index-actions\">\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n <button class=\"index-delete-btn\" (click)=\"DeleteIndex(idx.ID)\" title=\"Delete index\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Create Index Form -->\n @if (ShowCreateIndexForm) {\n <div class=\"create-index-form\">\n <h4 class=\"create-index-title\">\n <i class=\"fa-solid fa-plus-circle\"></i> Create New Vector Index\n </h4>\n <div class=\"create-index-fields\">\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Index Name</label>\n <input type=\"text\"\n class=\"config-input\"\n [(ngModel)]=\"NewIndexName\"\n placeholder=\"e.g., mj-knowledge-index\" />\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Vector Database</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexVectorDBID\">\n @for (db of VectorDBProviders; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Embedding Model</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexEmbeddingModelID\">\n @for (model of EmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"create-index-actions\">\n <button class=\"create-index-submit\" (click)=\"CreateIndex()\" [disabled]=\"IsCreatingIndex\">\n @if (IsCreatingIndex) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Creating...\n } @else {\n <i class=\"fa-solid fa-plus\"></i> Create Index\n }\n </button>\n <button class=\"create-index-cancel\" (click)=\"CancelCreateIndex()\" [disabled]=\"IsCreatingIndex\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Full-Text Indexes -->\n @if (ActiveSection === 'fulltext') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Full-Text Search Entities</h2>\n <p class=\"config-section-desc\">Configure which entities are included in full-text search. Entities with text fields (Name, Description, etc.) are automatically discovered.</p>\n\n @if (IsLoadingFTSEntities) {\n <mj-loading text=\"Discovering searchable entities...\" size=\"medium\"></mj-loading>\n } @else if (FTSEntities.length === 0) {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-text-width config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Searchable Entities Found</h3>\n <p class=\"config-empty-text\">No entities with text fields were discovered. Ensure your database schema includes entities with varchar/nvarchar columns.</p>\n </div>\n } @else {\n <div class=\"fts-entity-controls\">\n <div class=\"fts-summary\">\n <span class=\"fts-summary-count\">{{ EnabledFTSCount }} of {{ FTSEntities.length }} entities enabled for search</span>\n <input type=\"text\" class=\"config-input fts-filter-input\" placeholder=\"Filter entities...\" [(ngModel)]=\"FTSFilterText\" />\n </div>\n </div>\n\n <div class=\"fts-entity-list\">\n @for (entity of FilteredFTSEntities; track entity.EntityName) {\n <div class=\"fts-entity-card\" [class.fts-entity-enabled]=\"entity.Enabled\">\n <div class=\"fts-entity-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"entity.Enabled\" (change)=\"OnFTSEntityToggled(entity)\" class=\"config-checkbox\" />\n </div>\n <div class=\"fts-entity-info\">\n <span class=\"fts-entity-name\">{{ entity.EntityName }}</span>\n <div class=\"fts-entity-fields\">\n @for (field of entity.IndexedFields; track field) {\n <span class=\"fts-field-tag\">{{ field }}</span>\n }\n </div>\n </div>\n <div class=\"fts-entity-meta\">\n <span class=\"fts-entity-title-field\" title=\"Title field\">\n <i class=\"fa-solid fa-heading\"></i> {{ entity.TitleField }}\n </span>\n @if (entity.SnippetField !== entity.TitleField) {\n <span class=\"fts-entity-snippet-field\" title=\"Snippet field\">\n <i class=\"fa-solid fa-align-left\"></i> {{ entity.SnippetField }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Embedding Models -->\n @if (ActiveSection === 'embedding') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Embedding Models</h2>\n <p class=\"config-section-desc\">AI models used for generating vector embeddings from text.</p>\n\n @if (HasEmbeddingModel) {\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Active Model</span>\n <span class=\"config-hint\">Currently selected embedding model</span>\n </div>\n <span class=\"config-value-display\">{{ EmbeddingModelName }}</span>\n </div>\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Available Models</span>\n <span class=\"config-hint\">{{ EmbeddingModels.length }} embedding model(s) configured</span>\n </div>\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n </div>\n <p class=\"config-section-note\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Manage embedding models in the AI Dashboard > Models tab.\n </p>\n } @else {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-microchip config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Embedding Models Found</h3>\n <p class=\"config-empty-text\">\n Embedding models are required to convert text into vectors for semantic search and duplicate detection.\n Configure at least one embedding model (e.g., text-embedding-3-small) in the AI Dashboard > Models tab.\n </p>\n </div>\n }\n </div>\n }\n\n <!-- Thresholds -->\n @if (ActiveSection === 'thresholds') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Scoring Thresholds</h2>\n <p class=\"config-section-desc\">Set the scoring thresholds used by search, duplicate detection, and autotagging.</p>\n\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Absolute Match</span>\n <span class=\"config-hint\">Score above which duplicates are auto-confirmed ({{ FormatThreshold(ThresholdSettings.DuplicateAbsolute) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicateAbsolute\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.5\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Potential Match</span>\n <span class=\"config-hint\">Score above which duplicates are flagged for review ({{ FormatThreshold(ThresholdSettings.DuplicatePotential) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicatePotential\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Search Relevance</span>\n <span class=\"config-hint\">Minimum score for search results ({{ FormatThreshold(ThresholdSettings.SearchRelevance) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.SearchRelevance\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Autotag Confidence</span>\n <span class=\"config-hint\">Minimum confidence for accepting auto-generated tags ({{ FormatThreshold(ThresholdSettings.AutotagConfidence) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.AutotagConfidence\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Save Bar -->\n @if (HasUnsavedChanges) {\n <div class=\"config-save-bar\">\n <span class=\"config-save-text\">You have unsaved changes</span>\n <button class=\"config-save-btn\" (click)=\"SaveConfiguration()\" [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i> Save Changes\n }\n </button>\n <button class=\"config-reset-btn\" (click)=\"ResetConfiguration()\" [disabled]=\"IsSaving\">\n Reset\n </button>\n </div>\n }\n </div>\n </div>\n}\n"]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Search Result Detail Component (Task 8)
3
+ *
4
+ * Full-page detail view for a search result with breadcrumb navigation
5
+ * back to search, score breakdown visualization, and related items sidebar.
6
+ * Blends mockup results-detail-option-a (side panel) + option-b (full page).
7
+ */
8
+ import { EventEmitter } from '@angular/core';
9
+ import { SearchResultItem } from '@memberjunction/ng-search';
10
+ import * as i0 from "@angular/core";
11
+ /** Related item for the sidebar */
12
+ interface RelatedItem {
13
+ ID: string;
14
+ Title: string;
15
+ EntityName: string;
16
+ Score: number;
17
+ SourceIcon: string;
18
+ }
19
+ export declare class SearchResultDetailComponent {
20
+ private cdr;
21
+ /** The search result to display in detail */
22
+ Result: SearchResultItem | null;
23
+ /** Whether to show in side panel mode (no breadcrumb) */
24
+ SidePanelMode: boolean;
25
+ BackClicked: EventEmitter<void>;
26
+ RelatedItemSelected: EventEmitter<RelatedItem>;
27
+ NavigateToRecord: EventEmitter<{
28
+ EntityName: string;
29
+ RecordID: string;
30
+ }>;
31
+ RelatedItems: RelatedItem[];
32
+ IsLoadingRelated: boolean;
33
+ /** Navigate back to search results */
34
+ GoBack(): void;
35
+ /** Navigate to the source record */
36
+ OpenSourceRecord(): void;
37
+ /** Handle clicking a related item */
38
+ OnRelatedItemClick(item: RelatedItem): void;
39
+ /** Format a score as percentage */
40
+ FormatScore(score: number): string;
41
+ /** Get the width percentage for score bar visualization */
42
+ GetScoreBarWidth(score: number): string;
43
+ /** Get the CSS class for a score level */
44
+ GetScoreClass(score: number): string;
45
+ /** Get score breakdown entries for visualization */
46
+ GetScoreBreakdownEntries(): {
47
+ Label: string;
48
+ Score: number;
49
+ }[];
50
+ /** Get a human-readable source type label */
51
+ GetSourceTypeLabel(sourceType: string): string;
52
+ static ɵfac: i0.ɵɵFactoryDeclaration<SearchResultDetailComponent, never>;
53
+ static ɵcmp: i0.ɵɵComponentDeclaration<SearchResultDetailComponent, "app-search-result-detail", never, { "Result": { "alias": "Result"; "required": false; }; "SidePanelMode": { "alias": "SidePanelMode"; "required": false; }; }, { "BackClicked": "BackClicked"; "RelatedItemSelected": "RelatedItemSelected"; "NavigateToRecord": "NavigateToRecord"; }, never, never, false, never>;
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=search-result-detail.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-result-detail.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/results-detail/search-result-detail.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEH,YAAY,EAKf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAkB,MAAM,2BAA2B,CAAC;;AAE7E,mCAAmC;AACnC,UAAU,WAAW;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAMa,2BAA2B;IACpC,OAAO,CAAC,GAAG,CAA6B;IAExC,6CAA6C;IACpC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAEhD,yDAAyD;IAChD,aAAa,UAAS;IAErB,WAAW,qBAA4B;IACvC,mBAAmB,4BAAmC;IACtD,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAGnF,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,gBAAgB,UAAS;IAEhC,sCAAsC;IAC/B,MAAM,IAAI,IAAI;IAIrB,oCAAoC;IAC7B,gBAAgB,IAAI,IAAI;IAQ/B,qCAAqC;IAC9B,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAIlD,mCAAmC;IAC5B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIzC,2DAA2D;IACpD,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI9C,0CAA0C;IACnC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAM3C,oDAAoD;IAC7C,wBAAwB,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE;IAgBrE,6CAA6C;IACtC,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;yCAvE5C,2BAA2B;2CAA3B,2BAA2B;CAgFvC"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @fileoverview Search Result Detail Component (Task 8)
3
+ *
4
+ * Full-page detail view for a search result with breadcrumb navigation
5
+ * back to search, score breakdown visualization, and related items sidebar.
6
+ * Blends mockup results-detail-option-a (side panel) + option-b (full page).
7
+ */
8
+ import { Component, EventEmitter, Input, Output, ChangeDetectorRef, inject } from '@angular/core';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@memberjunction/ng-shared-generic";
11
+ const _forTrack0 = ($index, $item) => $item.Label;
12
+ const _forTrack1 = ($index, $item) => $item.ID;
13
+ function SearchResultDetailComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
14
+ const _r2 = i0.ɵɵgetCurrentView();
15
+ i0.ɵɵelementStart(0, "nav", 3)(1, "button", 32);
16
+ i0.ɵɵlistener("click", function SearchResultDetailComponent_Conditional_0_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.GoBack()); });
17
+ i0.ɵɵelement(2, "i", 33);
18
+ i0.ɵɵtext(3, " Back to Search Results ");
19
+ i0.ɵɵelementEnd()();
20
+ } }
21
+ function SearchResultDetailComponent_Conditional_0_For_35_Template(rf, ctx) { if (rf & 1) {
22
+ i0.ɵɵelementStart(0, "div", 24)(1, "span", 34);
23
+ i0.ɵɵtext(2);
24
+ i0.ɵɵelementEnd();
25
+ i0.ɵɵelementStart(3, "div", 35);
26
+ i0.ɵɵelement(4, "div", 36);
27
+ i0.ɵɵelementEnd();
28
+ i0.ɵɵelementStart(5, "span", 37);
29
+ i0.ɵɵtext(6);
30
+ i0.ɵɵelementEnd()();
31
+ } if (rf & 2) {
32
+ const entry_r4 = ctx.$implicit;
33
+ const ctx_r2 = i0.ɵɵnextContext(2);
34
+ i0.ɵɵadvance(2);
35
+ i0.ɵɵtextInterpolate(entry_r4.Label);
36
+ i0.ɵɵadvance(2);
37
+ i0.ɵɵclassMap(ctx_r2.GetScoreClass(entry_r4.Score));
38
+ i0.ɵɵstyleProp("width", ctx_r2.GetScoreBarWidth(entry_r4.Score));
39
+ i0.ɵɵadvance(2);
40
+ i0.ɵɵtextInterpolate(ctx_r2.FormatScore(entry_r4.Score));
41
+ } }
42
+ function SearchResultDetailComponent_Conditional_0_Conditional_43_For_6_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "span", 40);
44
+ i0.ɵɵtext(1);
45
+ i0.ɵɵelementEnd();
46
+ } if (rf & 2) {
47
+ const tag_r5 = ctx.$implicit;
48
+ i0.ɵɵadvance();
49
+ i0.ɵɵtextInterpolate(tag_r5);
50
+ } }
51
+ function SearchResultDetailComponent_Conditional_0_Conditional_43_Template(rf, ctx) { if (rf & 1) {
52
+ i0.ɵɵelementStart(0, "div", 16)(1, "h3", 17);
53
+ i0.ɵɵelement(2, "i", 38);
54
+ i0.ɵɵtext(3, " Tags ");
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵelementStart(4, "div", 39);
57
+ i0.ɵɵrepeaterCreate(5, SearchResultDetailComponent_Conditional_0_Conditional_43_For_6_Template, 2, 1, "span", 40, i0.ɵɵrepeaterTrackByIdentity);
58
+ i0.ɵɵelementEnd()();
59
+ } if (rf & 2) {
60
+ const ctx_r2 = i0.ɵɵnextContext(2);
61
+ i0.ɵɵadvance(5);
62
+ i0.ɵɵrepeater(ctx_r2.Result.Tags);
63
+ } }
64
+ function SearchResultDetailComponent_Conditional_0_Conditional_47_Template(rf, ctx) { if (rf & 1) {
65
+ i0.ɵɵelement(0, "mj-loading", 30);
66
+ } }
67
+ function SearchResultDetailComponent_Conditional_0_Conditional_48_Template(rf, ctx) { if (rf & 1) {
68
+ i0.ɵɵelementStart(0, "div", 31);
69
+ i0.ɵɵelement(1, "i", 41);
70
+ i0.ɵɵelementStart(2, "p");
71
+ i0.ɵɵtext(3, "No related items found");
72
+ i0.ɵɵelementEnd()();
73
+ } }
74
+ function SearchResultDetailComponent_Conditional_0_Conditional_49_For_1_Template(rf, ctx) { if (rf & 1) {
75
+ const _r6 = i0.ɵɵgetCurrentView();
76
+ i0.ɵɵelementStart(0, "div", 43);
77
+ i0.ɵɵlistener("click", function SearchResultDetailComponent_Conditional_0_Conditional_49_For_1_Template_div_click_0_listener() { const item_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnRelatedItemClick(item_r7)); });
78
+ i0.ɵɵelement(1, "i");
79
+ i0.ɵɵelementStart(2, "div", 44)(3, "span", 45);
80
+ i0.ɵɵtext(4);
81
+ i0.ɵɵelementEnd();
82
+ i0.ɵɵelementStart(5, "span", 46);
83
+ i0.ɵɵtext(6);
84
+ i0.ɵɵelementEnd()();
85
+ i0.ɵɵelementStart(7, "span", 47);
86
+ i0.ɵɵtext(8);
87
+ i0.ɵɵelementEnd()();
88
+ } if (rf & 2) {
89
+ const item_r7 = ctx.$implicit;
90
+ const ctx_r2 = i0.ɵɵnextContext(3);
91
+ i0.ɵɵadvance();
92
+ i0.ɵɵclassMap(item_r7.SourceIcon + " related-item-icon");
93
+ i0.ɵɵadvance(3);
94
+ i0.ɵɵtextInterpolate(item_r7.Title);
95
+ i0.ɵɵadvance(2);
96
+ i0.ɵɵtextInterpolate(item_r7.EntityName);
97
+ i0.ɵɵadvance(2);
98
+ i0.ɵɵtextInterpolate(ctx_r2.FormatScore(item_r7.Score));
99
+ } }
100
+ function SearchResultDetailComponent_Conditional_0_Conditional_49_Template(rf, ctx) { if (rf & 1) {
101
+ i0.ɵɵrepeaterCreate(0, SearchResultDetailComponent_Conditional_0_Conditional_49_For_1_Template, 9, 5, "div", 42, _forTrack1);
102
+ } if (rf & 2) {
103
+ const ctx_r2 = i0.ɵɵnextContext(2);
104
+ i0.ɵɵrepeater(ctx_r2.RelatedItems);
105
+ } }
106
+ function SearchResultDetailComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
107
+ const _r1 = i0.ɵɵgetCurrentView();
108
+ i0.ɵɵelementStart(0, "div", 2);
109
+ i0.ɵɵconditionalCreate(1, SearchResultDetailComponent_Conditional_0_Conditional_1_Template, 4, 0, "nav", 3);
110
+ i0.ɵɵelementStart(2, "div", 4)(3, "div", 5)(4, "div", 6)(5, "div", 7);
111
+ i0.ɵɵelement(6, "i");
112
+ i0.ɵɵelementEnd();
113
+ i0.ɵɵelementStart(7, "div", 8)(8, "h1", 9);
114
+ i0.ɵɵtext(9);
115
+ i0.ɵɵelementEnd();
116
+ i0.ɵɵelementStart(10, "div", 10)(11, "span", 11);
117
+ i0.ɵɵelement(12, "i", 12);
118
+ i0.ɵɵtext(13);
119
+ i0.ɵɵelementEnd();
120
+ i0.ɵɵelementStart(14, "span", 11);
121
+ i0.ɵɵelement(15, "i");
122
+ i0.ɵɵtext(16);
123
+ i0.ɵɵelementEnd();
124
+ i0.ɵɵelementStart(17, "span", 11);
125
+ i0.ɵɵelement(18, "i", 13);
126
+ i0.ɵɵtext(19);
127
+ i0.ɵɵelementEnd()()();
128
+ i0.ɵɵelementStart(20, "button", 14);
129
+ i0.ɵɵlistener("click", function SearchResultDetailComponent_Conditional_0_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenSourceRecord()); });
130
+ i0.ɵɵelement(21, "i", 15);
131
+ i0.ɵɵtext(22, " Open Record ");
132
+ i0.ɵɵelementEnd()();
133
+ i0.ɵɵelementStart(23, "div", 16)(24, "h3", 17);
134
+ i0.ɵɵelement(25, "i", 18);
135
+ i0.ɵɵtext(26, " Relevance Score ");
136
+ i0.ɵɵelementEnd();
137
+ i0.ɵɵelementStart(27, "div", 19)(28, "div", 20)(29, "span", 21);
138
+ i0.ɵɵtext(30);
139
+ i0.ɵɵelementEnd();
140
+ i0.ɵɵelementStart(31, "span", 22);
141
+ i0.ɵɵtext(32, "Overall Score");
142
+ i0.ɵɵelementEnd()();
143
+ i0.ɵɵelementStart(33, "div", 23);
144
+ i0.ɵɵrepeaterCreate(34, SearchResultDetailComponent_Conditional_0_For_35_Template, 7, 6, "div", 24, _forTrack0);
145
+ i0.ɵɵelementEnd()()();
146
+ i0.ɵɵelementStart(36, "div", 16)(37, "h3", 17);
147
+ i0.ɵɵelement(38, "i", 25);
148
+ i0.ɵɵtext(39, " Content Preview ");
149
+ i0.ɵɵelementEnd();
150
+ i0.ɵɵelementStart(40, "div", 26)(41, "p", 27);
151
+ i0.ɵɵtext(42);
152
+ i0.ɵɵelementEnd()()();
153
+ i0.ɵɵconditionalCreate(43, SearchResultDetailComponent_Conditional_0_Conditional_43_Template, 7, 0, "div", 16);
154
+ i0.ɵɵelementEnd();
155
+ i0.ɵɵelementStart(44, "aside", 28)(45, "h3", 29);
156
+ i0.ɵɵtext(46, "Related Items");
157
+ i0.ɵɵelementEnd();
158
+ i0.ɵɵconditionalCreate(47, SearchResultDetailComponent_Conditional_0_Conditional_47_Template, 1, 0, "mj-loading", 30)(48, SearchResultDetailComponent_Conditional_0_Conditional_48_Template, 4, 0, "div", 31)(49, SearchResultDetailComponent_Conditional_0_Conditional_49_Template, 2, 0);
159
+ i0.ɵɵelementEnd()()();
160
+ } if (rf & 2) {
161
+ const ctx_r2 = i0.ɵɵnextContext();
162
+ i0.ɵɵclassProp("detail-side-panel", ctx_r2.SidePanelMode);
163
+ i0.ɵɵadvance();
164
+ i0.ɵɵconditional(!ctx_r2.SidePanelMode ? 1 : -1);
165
+ i0.ɵɵadvance(5);
166
+ i0.ɵɵclassMap(ctx_r2.Result.SourceIcon);
167
+ i0.ɵɵadvance(3);
168
+ i0.ɵɵtextInterpolate(ctx_r2.Result.Title);
169
+ i0.ɵɵadvance(4);
170
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.Result.EntityName, " ");
171
+ i0.ɵɵadvance(2);
172
+ i0.ɵɵclassMap(ctx_r2.Result.SourceIcon);
173
+ i0.ɵɵadvance();
174
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.GetSourceTypeLabel(ctx_r2.Result.SourceType), " ");
175
+ i0.ɵɵadvance(3);
176
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.Result.RecordID, " ");
177
+ i0.ɵɵadvance(9);
178
+ i0.ɵɵclassMap(ctx_r2.GetScoreClass(ctx_r2.Result.Score));
179
+ i0.ɵɵadvance(2);
180
+ i0.ɵɵtextInterpolate(ctx_r2.FormatScore(ctx_r2.Result.Score));
181
+ i0.ɵɵadvance(4);
182
+ i0.ɵɵrepeater(ctx_r2.GetScoreBreakdownEntries());
183
+ i0.ɵɵadvance(8);
184
+ i0.ɵɵtextInterpolate(ctx_r2.Result.Snippet);
185
+ i0.ɵɵadvance();
186
+ i0.ɵɵconditional(ctx_r2.Result.Tags.length > 0 ? 43 : -1);
187
+ i0.ɵɵadvance(4);
188
+ i0.ɵɵconditional(ctx_r2.IsLoadingRelated ? 47 : ctx_r2.RelatedItems.length === 0 ? 48 : 49);
189
+ } }
190
+ function SearchResultDetailComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
191
+ i0.ɵɵelementStart(0, "div", 1);
192
+ i0.ɵɵelement(1, "i", 48);
193
+ i0.ɵɵelementStart(2, "p");
194
+ i0.ɵɵtext(3, "Select a search result to view details");
195
+ i0.ɵɵelementEnd()();
196
+ } }
197
+ export class SearchResultDetailComponent {
198
+ cdr = inject(ChangeDetectorRef);
199
+ /** The search result to display in detail */
200
+ Result = null;
201
+ /** Whether to show in side panel mode (no breadcrumb) */
202
+ SidePanelMode = false;
203
+ BackClicked = new EventEmitter();
204
+ RelatedItemSelected = new EventEmitter();
205
+ NavigateToRecord = new EventEmitter();
206
+ // --- Component State ---
207
+ RelatedItems = [];
208
+ IsLoadingRelated = false;
209
+ /** Navigate back to search results */
210
+ GoBack() {
211
+ this.BackClicked.emit();
212
+ }
213
+ /** Navigate to the source record */
214
+ OpenSourceRecord() {
215
+ if (!this.Result)
216
+ return;
217
+ this.NavigateToRecord.emit({
218
+ EntityName: this.Result.EntityName,
219
+ RecordID: this.Result.RecordID
220
+ });
221
+ }
222
+ /** Handle clicking a related item */
223
+ OnRelatedItemClick(item) {
224
+ this.RelatedItemSelected.emit(item);
225
+ }
226
+ /** Format a score as percentage */
227
+ FormatScore(score) {
228
+ return `${Math.round(score * 100)}%`;
229
+ }
230
+ /** Get the width percentage for score bar visualization */
231
+ GetScoreBarWidth(score) {
232
+ return `${Math.round(score * 100)}%`;
233
+ }
234
+ /** Get the CSS class for a score level */
235
+ GetScoreClass(score) {
236
+ if (score >= 0.8)
237
+ return 'score-high';
238
+ if (score >= 0.5)
239
+ return 'score-medium';
240
+ return 'score-low';
241
+ }
242
+ /** Get score breakdown entries for visualization */
243
+ GetScoreBreakdownEntries() {
244
+ if (!this.Result?.ScoreBreakdown)
245
+ return [];
246
+ const entries = [];
247
+ const breakdown = this.Result.ScoreBreakdown;
248
+ if (breakdown.Vector !== undefined) {
249
+ entries.push({ Label: 'Vector Similarity', Score: breakdown.Vector });
250
+ }
251
+ if (breakdown.FullText !== undefined) {
252
+ entries.push({ Label: 'Full-Text Match', Score: breakdown.FullText });
253
+ }
254
+ if (breakdown.Entity !== undefined) {
255
+ entries.push({ Label: 'Entity Match', Score: breakdown.Entity });
256
+ }
257
+ return entries;
258
+ }
259
+ /** Get a human-readable source type label */
260
+ GetSourceTypeLabel(sourceType) {
261
+ const labels = {
262
+ 'entity': 'Entity Record',
263
+ 'content-item': 'Content Item',
264
+ 'file': 'Document',
265
+ 'web-page': 'Web Page'
266
+ };
267
+ return labels[sourceType] ?? sourceType;
268
+ }
269
+ static ɵfac = function SearchResultDetailComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SearchResultDetailComponent)(); };
270
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchResultDetailComponent, selectors: [["app-search-result-detail"]], inputs: { Result: "Result", SidePanelMode: "SidePanelMode" }, outputs: { BackClicked: "BackClicked", RelatedItemSelected: "RelatedItemSelected", NavigateToRecord: "NavigateToRecord" }, standalone: false, decls: 2, vars: 1, consts: [[1, "detail-page", 3, "detail-side-panel"], [1, "detail-empty"], [1, "detail-page"], [1, "detail-breadcrumb"], [1, "detail-layout"], [1, "detail-main"], [1, "detail-header"], [1, "detail-header-icon"], [1, "detail-header-info"], [1, "detail-title"], [1, "detail-meta"], [1, "detail-meta-item"], [1, "fa-solid", "fa-table"], [1, "fa-solid", "fa-key"], [1, "detail-open-record-btn", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "detail-section"], [1, "detail-section-title"], [1, "fa-solid", "fa-chart-bar"], [1, "score-overview"], [1, "score-main"], [1, "score-main-value"], [1, "score-main-label"], [1, "score-breakdown"], [1, "score-bar-row"], [1, "fa-solid", "fa-align-left"], [1, "detail-snippet-box"], [1, "detail-snippet"], [1, "detail-sidebar"], [1, "sidebar-title"], ["text", "Loading...", "size", "small"], [1, "sidebar-empty"], [1, "breadcrumb-back", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "score-bar-label"], [1, "score-bar-track"], [1, "score-bar-fill"], [1, "score-bar-value"], [1, "fa-solid", "fa-tags"], [1, "detail-tags"], [1, "detail-tag"], [1, "fa-solid", "fa-link", "sidebar-empty-icon"], [1, "related-item"], [1, "related-item", 3, "click"], [1, "related-item-info"], [1, "related-item-title"], [1, "related-item-entity"], [1, "related-item-score"], [1, "fa-solid", "fa-file-magnifying-glass", "detail-empty-icon"]], template: function SearchResultDetailComponent_Template(rf, ctx) { if (rf & 1) {
271
+ i0.ɵɵconditionalCreate(0, SearchResultDetailComponent_Conditional_0_Template, 50, 17, "div", 0)(1, SearchResultDetailComponent_Conditional_1_Template, 4, 0, "div", 1);
272
+ } if (rf & 2) {
273
+ i0.ɵɵconditional(ctx.Result ? 0 : 1);
274
+ } }, dependencies: [i1.LoadingComponent], styles: ["\n\n\n.detail-page[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.detail-side-panel[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mj-border-default);\n}\n\n.detail-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: var(--mj-text-muted);\n gap: 0.75rem;\n}\n\n.detail-empty-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n\n\n.detail-breadcrumb[_ngcontent-%COMP%] {\n padding: 0.75rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.breadcrumb-back[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n padding: 0.35rem 0.5rem;\n border-radius: 6px;\n transition: all 0.15s ease;\n}\n\n.breadcrumb-back[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n\n.detail-layout[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.detail-main[_ngcontent-%COMP%] {\n flex: 1;\n padding: 1.5rem;\n overflow-y: auto;\n}\n\n\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 1rem;\n margin-bottom: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.detail-header-icon[_ngcontent-%COMP%] {\n width: 3rem;\n height: 3rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.detail-header-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.detail-title[_ngcontent-%COMP%] {\n font-size: 1.4rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.detail-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n}\n\n.detail-meta-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.detail-open-record-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.detail-open-record-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n.detail-section[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.detail-section-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.detail-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n\n\n.score-overview[_ngcontent-%COMP%] {\n display: flex;\n gap: 2rem;\n align-items: flex-start;\n}\n\n.score-main[_ngcontent-%COMP%] {\n width: 5rem;\n height: 5rem;\n border-radius: 50%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: 3px solid;\n}\n\n.score-main.score-high[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success);\n background: var(--mj-status-success-bg);\n}\n\n.score-main.score-medium[_ngcontent-%COMP%] {\n border-color: var(--mj-status-warning);\n background: var(--mj-status-warning-bg);\n}\n\n.score-main.score-low[_ngcontent-%COMP%] {\n border-color: var(--mj-status-error);\n background: var(--mj-status-error-bg);\n}\n\n.score-main-value[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.score-main-label[_ngcontent-%COMP%] {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n}\n\n.score-breakdown[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.score-bar-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.score-bar-label[_ngcontent-%COMP%] {\n width: 120px;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.score-bar-track[_ngcontent-%COMP%] {\n flex: 1;\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.score-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 4px;\n transition: width 0.3s ease;\n}\n\n.score-bar-fill.score-high[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.score-bar-fill.score-medium[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n}\n\n.score-bar-fill.score-low[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n}\n\n.score-bar-value[_ngcontent-%COMP%] {\n width: 40px;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n text-align: right;\n}\n\n\n\n.detail-snippet-box[_ngcontent-%COMP%] {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.detail-snippet[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n line-height: 1.6;\n margin: 0;\n white-space: pre-wrap;\n}\n\n\n\n.detail-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.detail-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 0.25rem 0.65rem;\n border-radius: 9999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 0.8rem;\n border: 1px solid var(--mj-border-subtle);\n}\n\n\n\n.detail-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n border-left: 1px solid var(--mj-border-default);\n padding: 1.5rem 1rem;\n overflow-y: auto;\n flex-shrink: 0;\n}\n\n.sidebar-title[_ngcontent-%COMP%] {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 1rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n padding: 2rem 0;\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.sidebar-empty-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n}\n\n.related-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.6rem;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.related-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.related-item-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 0.82rem;\n flex-shrink: 0;\n}\n\n.related-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.related-item-title[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.82rem;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.related-item-entity[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.related-item-score[_ngcontent-%COMP%] {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n font-weight: 600;\n flex-shrink: 0;\n}\n\n\n\n@media (max-width: 768px) {\n .detail-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .detail-sidebar[_ngcontent-%COMP%] {\n width: 100%;\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n .score-overview[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: center;\n }\n}"] });
275
+ }
276
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SearchResultDetailComponent, [{
277
+ type: Component,
278
+ args: [{ standalone: false, selector: 'app-search-result-detail', template: "@if (Result) {\n <div class=\"detail-page\" [class.detail-side-panel]=\"SidePanelMode\">\n <!-- Breadcrumb (full page mode only) -->\n @if (!SidePanelMode) {\n <nav class=\"detail-breadcrumb\">\n <button class=\"breadcrumb-back\" (click)=\"GoBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Search Results\n </button>\n </nav>\n }\n\n <div class=\"detail-layout\">\n <!-- Main Content -->\n <div class=\"detail-main\">\n <!-- Header -->\n <div class=\"detail-header\">\n <div class=\"detail-header-icon\">\n <i [class]=\"Result.SourceIcon\"></i>\n </div>\n <div class=\"detail-header-info\">\n <h1 class=\"detail-title\">{{ Result.Title }}</h1>\n <div class=\"detail-meta\">\n <span class=\"detail-meta-item\">\n <i class=\"fa-solid fa-table\"></i>\n {{ Result.EntityName }}\n </span>\n <span class=\"detail-meta-item\">\n <i [class]=\"Result.SourceIcon\"></i>\n {{ GetSourceTypeLabel(Result.SourceType) }}\n </span>\n <span class=\"detail-meta-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{ Result.RecordID }}\n </span>\n </div>\n </div>\n <button class=\"detail-open-record-btn\" (click)=\"OpenSourceRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Record\n </button>\n </div>\n\n <!-- Score Section -->\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Relevance Score\n </h3>\n <div class=\"score-overview\">\n <div class=\"score-main\" [class]=\"GetScoreClass(Result.Score)\">\n <span class=\"score-main-value\">{{ FormatScore(Result.Score) }}</span>\n <span class=\"score-main-label\">Overall Score</span>\n </div>\n <div class=\"score-breakdown\">\n @for (entry of GetScoreBreakdownEntries(); track entry.Label) {\n <div class=\"score-bar-row\">\n <span class=\"score-bar-label\">{{ entry.Label }}</span>\n <div class=\"score-bar-track\">\n <div class=\"score-bar-fill\" [style.width]=\"GetScoreBarWidth(entry.Score)\" [class]=\"GetScoreClass(entry.Score)\"></div>\n </div>\n <span class=\"score-bar-value\">{{ FormatScore(entry.Score) }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Snippet Section -->\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Content Preview\n </h3>\n <div class=\"detail-snippet-box\">\n <p class=\"detail-snippet\">{{ Result.Snippet }}</p>\n </div>\n </div>\n\n <!-- Tags Section -->\n @if (Result.Tags.length > 0) {\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-tags\"></i>\n Tags\n </h3>\n <div class=\"detail-tags\">\n @for (tag of Result.Tags; track tag) {\n <span class=\"detail-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Related Items Sidebar -->\n <aside class=\"detail-sidebar\">\n <h3 class=\"sidebar-title\">Related Items</h3>\n @if (IsLoadingRelated) {\n <mj-loading text=\"Loading...\" size=\"small\"></mj-loading>\n } @else if (RelatedItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-link sidebar-empty-icon\"></i>\n <p>No related items found</p>\n </div>\n } @else {\n @for (item of RelatedItems; track item.ID) {\n <div class=\"related-item\" (click)=\"OnRelatedItemClick(item)\">\n <i [class]=\"item.SourceIcon + ' related-item-icon'\"></i>\n <div class=\"related-item-info\">\n <span class=\"related-item-title\">{{ item.Title }}</span>\n <span class=\"related-item-entity\">{{ item.EntityName }}</span>\n </div>\n <span class=\"related-item-score\">{{ FormatScore(item.Score) }}</span>\n </div>\n }\n }\n </aside>\n </div>\n </div>\n} @else {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-file-magnifying-glass detail-empty-icon\"></i>\n <p>Select a search result to view details</p>\n </div>\n}\n", styles: ["/* Search Result Detail */\n\n.detail-page {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.detail-side-panel {\n border-left: 1px solid var(--mj-border-default);\n}\n\n.detail-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: var(--mj-text-muted);\n gap: 0.75rem;\n}\n\n.detail-empty-icon {\n font-size: 2.5rem;\n}\n\n/* Breadcrumb */\n.detail-breadcrumb {\n padding: 0.75rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.breadcrumb-back {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n padding: 0.35rem 0.5rem;\n border-radius: 6px;\n transition: all 0.15s ease;\n}\n\n.breadcrumb-back:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Layout */\n.detail-layout {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.detail-main {\n flex: 1;\n padding: 1.5rem;\n overflow-y: auto;\n}\n\n/* Header */\n.detail-header {\n display: flex;\n align-items: flex-start;\n gap: 1rem;\n margin-bottom: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.detail-header-icon {\n width: 3rem;\n height: 3rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.detail-header-info {\n flex: 1;\n}\n\n.detail-title {\n font-size: 1.4rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.detail-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n}\n\n.detail-meta-item {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.detail-open-record-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.detail-open-record-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Sections */\n.detail-section {\n margin-bottom: 1.5rem;\n}\n\n.detail-section-title {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.detail-section-title i {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n/* Score Visualization */\n.score-overview {\n display: flex;\n gap: 2rem;\n align-items: flex-start;\n}\n\n.score-main {\n width: 5rem;\n height: 5rem;\n border-radius: 50%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: 3px solid;\n}\n\n.score-main.score-high {\n border-color: var(--mj-status-success);\n background: var(--mj-status-success-bg);\n}\n\n.score-main.score-medium {\n border-color: var(--mj-status-warning);\n background: var(--mj-status-warning-bg);\n}\n\n.score-main.score-low {\n border-color: var(--mj-status-error);\n background: var(--mj-status-error-bg);\n}\n\n.score-main-value {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.score-main-label {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n}\n\n.score-breakdown {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.score-bar-row {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.score-bar-label {\n width: 120px;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.score-bar-track {\n flex: 1;\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.score-bar-fill {\n height: 100%;\n border-radius: 4px;\n transition: width 0.3s ease;\n}\n\n.score-bar-fill.score-high {\n background: var(--mj-status-success);\n}\n\n.score-bar-fill.score-medium {\n background: var(--mj-status-warning);\n}\n\n.score-bar-fill.score-low {\n background: var(--mj-status-error);\n}\n\n.score-bar-value {\n width: 40px;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n text-align: right;\n}\n\n/* Content Preview */\n.detail-snippet-box {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.detail-snippet {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n line-height: 1.6;\n margin: 0;\n white-space: pre-wrap;\n}\n\n/* Tags */\n.detail-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.detail-tag {\n display: inline-block;\n padding: 0.25rem 0.65rem;\n border-radius: 9999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 0.8rem;\n border: 1px solid var(--mj-border-subtle);\n}\n\n/* Sidebar */\n.detail-sidebar {\n width: 280px;\n border-left: 1px solid var(--mj-border-default);\n padding: 1.5rem 1rem;\n overflow-y: auto;\n flex-shrink: 0;\n}\n\n.sidebar-title {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 1rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n padding: 2rem 0;\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.sidebar-empty-icon {\n font-size: 1.5rem;\n}\n\n.related-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.6rem;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.related-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.related-item-icon {\n color: var(--mj-brand-primary);\n font-size: 0.82rem;\n flex-shrink: 0;\n}\n\n.related-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.related-item-title {\n display: block;\n font-size: 0.82rem;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.related-item-entity {\n display: block;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.related-item-score {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n font-weight: 600;\n flex-shrink: 0;\n}\n\n/* Mobile responsive */\n@media (max-width: 768px) {\n .detail-layout {\n flex-direction: column;\n }\n\n .detail-sidebar {\n width: 100%;\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n .score-overview {\n flex-direction: column;\n align-items: center;\n }\n}\n"] }]
279
+ }], null, { Result: [{
280
+ type: Input
281
+ }], SidePanelMode: [{
282
+ type: Input
283
+ }], BackClicked: [{
284
+ type: Output
285
+ }], RelatedItemSelected: [{
286
+ type: Output
287
+ }], NavigateToRecord: [{
288
+ type: Output
289
+ }] }); })();
290
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SearchResultDetailComponent, { className: "SearchResultDetailComponent", filePath: "src/KnowledgeHub/components/results-detail/search-result-detail.component.ts", lineNumber: 34 }); })();
291
+ //# sourceMappingURL=search-result-detail.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-result-detail.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/results-detail/search-result-detail.component.ts","../../../../src/KnowledgeHub/components/results-detail/search-result-detail.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Result Detail Component (Task 8)\n *\n * Full-page detail view for a search result with breadcrumb navigation\n * back to search, score breakdown visualization, and related items sidebar.\n * Blends mockup results-detail-option-a (side panel) + option-b (full page).\n */\n\nimport {\n Component,\n EventEmitter,\n Input,\n Output,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { SearchResultItem, ScoreBreakdown } from '@memberjunction/ng-search';\n\n/** Related item for the sidebar */\ninterface RelatedItem {\n ID: string;\n Title: string;\n EntityName: string;\n Score: number;\n SourceIcon: string;\n}\n\n@Component({\n standalone: false,\n selector: 'app-search-result-detail',\n templateUrl: './search-result-detail.component.html',\n styleUrls: ['./search-result-detail.component.css']\n})\nexport class SearchResultDetailComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** The search result to display in detail */\n @Input() Result: SearchResultItem | null = null;\n\n /** Whether to show in side panel mode (no breadcrumb) */\n @Input() SidePanelMode = false;\n\n @Output() BackClicked = new EventEmitter<void>();\n @Output() RelatedItemSelected = new EventEmitter<RelatedItem>();\n @Output() NavigateToRecord = new EventEmitter<{ EntityName: string; RecordID: string }>();\n\n // --- Component State ---\n public RelatedItems: RelatedItem[] = [];\n public IsLoadingRelated = false;\n\n /** Navigate back to search results */\n public GoBack(): void {\n this.BackClicked.emit();\n }\n\n /** Navigate to the source record */\n public OpenSourceRecord(): void {\n if (!this.Result) return;\n this.NavigateToRecord.emit({\n EntityName: this.Result.EntityName,\n RecordID: this.Result.RecordID\n });\n }\n\n /** Handle clicking a related item */\n public OnRelatedItemClick(item: RelatedItem): void {\n this.RelatedItemSelected.emit(item);\n }\n\n /** Format a score as percentage */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Get the width percentage for score bar visualization */\n public GetScoreBarWidth(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Get the CSS class for a score level */\n public GetScoreClass(score: number): string {\n if (score >= 0.8) return 'score-high';\n if (score >= 0.5) return 'score-medium';\n return 'score-low';\n }\n\n /** Get score breakdown entries for visualization */\n public GetScoreBreakdownEntries(): { Label: string; Score: number }[] {\n if (!this.Result?.ScoreBreakdown) return [];\n const entries: { Label: string; Score: number }[] = [];\n const breakdown = this.Result.ScoreBreakdown;\n if (breakdown.Vector !== undefined) {\n entries.push({ Label: 'Vector Similarity', Score: breakdown.Vector });\n }\n if (breakdown.FullText !== undefined) {\n entries.push({ Label: 'Full-Text Match', Score: breakdown.FullText });\n }\n if (breakdown.Entity !== undefined) {\n entries.push({ Label: 'Entity Match', Score: breakdown.Entity });\n }\n return entries;\n }\n\n /** Get a human-readable source type label */\n public GetSourceTypeLabel(sourceType: string): string {\n const labels: Record<string, string> = {\n 'entity': 'Entity Record',\n 'content-item': 'Content Item',\n 'file': 'Document',\n 'web-page': 'Web Page'\n };\n return labels[sourceType] ?? sourceType;\n }\n}\n","@if (Result) {\n <div class=\"detail-page\" [class.detail-side-panel]=\"SidePanelMode\">\n <!-- Breadcrumb (full page mode only) -->\n @if (!SidePanelMode) {\n <nav class=\"detail-breadcrumb\">\n <button class=\"breadcrumb-back\" (click)=\"GoBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Search Results\n </button>\n </nav>\n }\n\n <div class=\"detail-layout\">\n <!-- Main Content -->\n <div class=\"detail-main\">\n <!-- Header -->\n <div class=\"detail-header\">\n <div class=\"detail-header-icon\">\n <i [class]=\"Result.SourceIcon\"></i>\n </div>\n <div class=\"detail-header-info\">\n <h1 class=\"detail-title\">{{ Result.Title }}</h1>\n <div class=\"detail-meta\">\n <span class=\"detail-meta-item\">\n <i class=\"fa-solid fa-table\"></i>\n {{ Result.EntityName }}\n </span>\n <span class=\"detail-meta-item\">\n <i [class]=\"Result.SourceIcon\"></i>\n {{ GetSourceTypeLabel(Result.SourceType) }}\n </span>\n <span class=\"detail-meta-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{ Result.RecordID }}\n </span>\n </div>\n </div>\n <button class=\"detail-open-record-btn\" (click)=\"OpenSourceRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Record\n </button>\n </div>\n\n <!-- Score Section -->\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Relevance Score\n </h3>\n <div class=\"score-overview\">\n <div class=\"score-main\" [class]=\"GetScoreClass(Result.Score)\">\n <span class=\"score-main-value\">{{ FormatScore(Result.Score) }}</span>\n <span class=\"score-main-label\">Overall Score</span>\n </div>\n <div class=\"score-breakdown\">\n @for (entry of GetScoreBreakdownEntries(); track entry.Label) {\n <div class=\"score-bar-row\">\n <span class=\"score-bar-label\">{{ entry.Label }}</span>\n <div class=\"score-bar-track\">\n <div class=\"score-bar-fill\" [style.width]=\"GetScoreBarWidth(entry.Score)\" [class]=\"GetScoreClass(entry.Score)\"></div>\n </div>\n <span class=\"score-bar-value\">{{ FormatScore(entry.Score) }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Snippet Section -->\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Content Preview\n </h3>\n <div class=\"detail-snippet-box\">\n <p class=\"detail-snippet\">{{ Result.Snippet }}</p>\n </div>\n </div>\n\n <!-- Tags Section -->\n @if (Result.Tags.length > 0) {\n <div class=\"detail-section\">\n <h3 class=\"detail-section-title\">\n <i class=\"fa-solid fa-tags\"></i>\n Tags\n </h3>\n <div class=\"detail-tags\">\n @for (tag of Result.Tags; track tag) {\n <span class=\"detail-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Related Items Sidebar -->\n <aside class=\"detail-sidebar\">\n <h3 class=\"sidebar-title\">Related Items</h3>\n @if (IsLoadingRelated) {\n <mj-loading text=\"Loading...\" size=\"small\"></mj-loading>\n } @else if (RelatedItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-link sidebar-empty-icon\"></i>\n <p>No related items found</p>\n </div>\n } @else {\n @for (item of RelatedItems; track item.ID) {\n <div class=\"related-item\" (click)=\"OnRelatedItemClick(item)\">\n <i [class]=\"item.SourceIcon + ' related-item-icon'\"></i>\n <div class=\"related-item-info\">\n <span class=\"related-item-title\">{{ item.Title }}</span>\n <span class=\"related-item-entity\">{{ item.EntityName }}</span>\n </div>\n <span class=\"related-item-score\">{{ FormatScore(item.Score) }}</span>\n </div>\n }\n }\n </aside>\n </div>\n </div>\n} @else {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-file-magnifying-glass detail-empty-icon\"></i>\n <p>Select a search result to view details</p>\n </div>\n}\n"]}