@memberjunction/ng-explorer-core 5.34.0 → 5.35.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 (23) hide show
  1. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
  2. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +9 -2
  3. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  4. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +8 -0
  5. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  6. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +25 -0
  7. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  8. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +6 -0
  9. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  10. package/dist/lib/resource-wrappers/search-results-resource.component.js +21 -0
  11. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  12. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +11 -0
  13. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  14. package/dist/lib/shell/components/tabs/component-cache-manager.js +26 -0
  15. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  16. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +26 -0
  17. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  18. package/dist/lib/shell/components/tabs/tab-container.component.js +75 -3
  19. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  20. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  21. package/dist/lib/shell/shell.component.js +42 -7
  22. package/dist/lib/shell/shell.component.js.map +1 -1
  23. package/package.json +42 -42
@@ -1 +1 @@
1
- {"version":3,"file":"search-results-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/search-results-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { FileOpenService } from '@memberjunction/ng-file-storage';\nimport {\n SearchService,\n SearchResultItem,\n SearchFilter,\n SearchFilterChangeEvent,\n SearchRequest,\n SearchResponse,\n SearchResultSelectedEvent,\n StreamingProviderStatus,\n} from '@memberjunction/ng-search';\nimport { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';\n\n@RegisterClass(BaseResourceComponent, 'SearchResultsResource')\n@Component({\n standalone: false,\n selector: 'mj-search-results-resource',\n template: `\n <div class=\"search-results-page\">\n <!-- Streaming status strip — visible while streamScopedSearch is in flight -->\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ p.ElapsedMs }}ms</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n @if (IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Streaming…</span>\n </span>\n }\n </div>\n }\n\n <!-- Header bar (always visible when we have server results) -->\n @if (HasSearched && ServerResultCount > 0) {\n <div class=\"search-header\">\n <div class=\"search-header-left\">\n @if (!ShowFilterPanel) {\n <button class=\"sr-icon-btn\" title=\"Show filters\" (click)=\"ToggleFilterPanel()\">\n <i class=\"fa-solid fa-filter\"></i>\n </button>\n }\n <span class=\"search-meta\">\n {{ FilteredResults.length }} of {{ ServerResultCount }} result{{ ServerResultCount !== 1 ? 's' : '' }}\n for \"{{ CurrentQuery }}\" in {{ ElapsedMs }}ms\n </span>\n </div>\n <div class=\"search-header-right\">\n <!-- Search within results -->\n <div class=\"sr-refine-wrapper\">\n <i class=\"fa-solid fa-filter-list sr-refine-icon\"></i>\n <input class=\"mj-input sr-refine-input\"\n placeholder=\"Filter within results...\"\n [value]=\"ClientFilterText\"\n (input)=\"OnClientFilterTextChange($any($event.target).value)\" />\n @if (ClientFilterText) {\n <button class=\"sr-refine-clear\" (click)=\"OnClientFilterTextChange('')\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n <!-- Sort -->\n <select class=\"mj-input sr-sort-select\" [value]=\"SortField\" (change)=\"OnSortChange($any($event.target).value)\">\n <option value=\"score\">Sort: Relevance</option>\n <option value=\"title\">Sort: Name</option>\n <option value=\"entity\">Sort: Entity</option>\n </select>\n <!-- View mode toggle -->\n <div class=\"sr-view-toggle\">\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'list'\"\n title=\"List view\"\n (click)=\"SetViewMode('list')\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'cloud'\"\n title=\"Tag cloud view\"\n (click)=\"SetViewMode('cloud')\">\n <i class=\"fa-solid fa-cloud\"></i>\n </button>\n </div>\n <!-- Refresh -->\n <button class=\"sr-icon-btn\" title=\"Refresh search\" (click)=\"OnRefresh()\" [disabled]=\"IsSearching\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsSearching\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Initial loading (first search) -->\n @if (IsSearching && ServerResultCount === 0) {\n <div class=\"search-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- No server results -->\n @if (!IsSearching && ServerResultCount === 0 && HasSearched) {\n <div class=\"search-no-results\">\n <i class=\"fa-solid fa-magnifying-glass-minus\"></i>\n <h3>No results found</h3>\n <p>Try different keywords or broaden your search.</p>\n </div>\n }\n <!-- Results body (visible when server returned results) -->\n @if (ServerResultCount > 0) {\n <div class=\"search-results-body-wrapper\">\n <!-- Semi-opaque loading overlay for re-queries (slider lowered, etc.) -->\n @if (IsSearching) {\n <div class=\"search-requery-overlay\">\n <mj-loading text=\"Updating results...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (ViewMode === 'cloud') {\n <div class=\"search-cloud-wrapper\">\n @if (IsLoadingCloud) {\n <mj-loading text=\"Loading tag cloud...\" size=\"medium\"></mj-loading>\n } @else {\n <mj-word-cloud\n [Items]=\"CloudItems\"\n [MaxItems]=\"80\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnCloudItemClick($event)\">\n </mj-word-cloud>\n }\n </div>\n } @else {\n <div class=\"search-body\">\n @if (ShowFilterPanel) {\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n [ShowRelevanceSlider]=\"true\"\n [MinScorePercent]=\"MinScorePercent\"\n [ServerMinScorePercent]=\"serverMinScorePercent\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n (CloseRequested)=\"ToggleFilterPanel()\"\n (MinScoreChanged)=\"OnMinScoreChanged($any($event))\">\n </mj-search-filter>\n }\n @if (FilteredResults.length > 0) {\n <mj-search-results\n [FlatResults]=\"FilteredResults\"\n [HighlightText]=\"ClientFilterText\"\n [ShowScores]=\"true\"\n [ShowTags]=\"true\"\n [ShowSummary]=\"false\"\n [PageSize]=\"20\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\">\n </mj-search-results>\n } @else {\n <div class=\"search-no-results-inline\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n <p>No results match current filters. Try lowering the minimum relevance.</p>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [`\n .search-results-page {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n .search-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n .search-header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-meta {\n color: var(--mj-text-muted);\n font-size: 13px;\n white-space: nowrap;\n }\n .sr-icon-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n font-size: 13px;\n flex-shrink: 0;\n }\n .sr-icon-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .sr-icon-btn:disabled { opacity: 0.4; cursor: default; }\n .sr-refine-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n }\n .sr-refine-icon {\n position: absolute;\n left: 8px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n }\n .sr-refine-input {\n padding: 5px 28px 5px 26px;\n font-size: 12px;\n width: 180px;\n border-radius: 6px;\n }\n .sr-refine-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 2px;\n }\n .sr-refine-clear:hover { color: var(--mj-text-primary); }\n .sr-sort-select {\n padding: 5px 24px 5px 8px;\n font-size: 12px;\n border-radius: 6px;\n min-width: 130px;\n }\n .search-loading {\n display: flex;\n justify-content: center;\n padding: 60px 0;\n }\n .search-body {\n flex: 1;\n display: flex;\n gap: 16px;\n padding: 16px 24px;\n overflow: hidden;\n }\n .search-body mj-search-filter {\n flex-shrink: 0;\n width: 240px;\n overflow-y: auto;\n }\n .search-body mj-search-results {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n }\n .search-no-results {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n }\n .search-no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.4;\n }\n .search-no-results h3 {\n font-size: 18px;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n }\n .search-no-results p {\n font-size: 14px;\n margin: 0;\n }\n .search-results-body-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .search-requery-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 75%, transparent);\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-no-results-inline {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: var(--mj-text-muted);\n padding: 40px 20px;\n }\n .search-no-results-inline i {\n font-size: 32px;\n opacity: 0.4;\n }\n .search-no-results-inline p {\n font-size: 13px;\n margin: 0;\n }\n .sr-view-toggle {\n display: flex;\n gap: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n padding: 2px;\n background: var(--mj-bg-surface-sunken);\n }\n .sr-view-toggle .sr-icon-btn {\n border: none;\n border-radius: 4px;\n width: 28px;\n height: 26px;\n font-size: 12px;\n background: transparent;\n }\n .sr-view-toggle .sr-icon-btn.sr-view-active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 10%, transparent);\n }\n .search-cloud-wrapper {\n flex: 1;\n padding: 24px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-cloud-wrapper mj-word-cloud {\n width: 100%;\n height: 100%;\n max-height: 600px;\n }\n .streaming-status-strip {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .streaming-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n }\n .streaming-chip-pending {\n color: var(--mj-text-muted);\n }\n .streaming-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n }\n .streaming-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n }\n .streaming-chip-name { font-weight: 500; }\n .streaming-chip-count { opacity: 0.7; }\n .streaming-chip-time { opacity: 0.6; font-size: 0.7rem; }\n `]\n})\nexport class SearchResultsResource extends BaseResourceComponent {\n private cdr = inject(ChangeDetectorRef);\n private searchService = inject(SearchService);\n private fileOpenService = inject(FileOpenService);\n\n CurrentQuery = '';\n IsSearching = false;\n HasSearched = false;\n TotalCount = 0;\n ElapsedMs = 0;\n Filters: SearchFilter[] = [];\n ActiveFilters: Record<string, string[]> = {};\n FilteredResults: SearchResultItem[] = [];\n MinScorePercent = 30;\n /** The MinScore that was sent to the server on the last search. If the user\n * slides below this, we need to re-query the server to get more results. */\n serverMinScorePercent = 30;\n /** How many results the server returned (before client-side filtering) */\n ServerResultCount = 0;\n ShowFilterPanel = true;\n SortField: 'score' | 'title' | 'entity' = 'score';\n ClientFilterText = '';\n ViewMode: 'list' | 'cloud' = 'list';\n CloudItems: WordCloudItem[] = [];\n IsLoadingCloud = false;\n\n /** All results from the last search (before client-side filtering) */\n private allResults: SearchResultItem[] = [];\n\n /** Selected scope IDs from the search bar (empty = unscoped/global). */\n private ScopeIDs: string[] = [];\n\n /**\n * Phase 2C streaming opt-in. Off by default to preserve Phase 1 request-response UX.\n * Enable per-resource via `Data.Configuration.EnableStreaming` or per-tab via the\n * `?stream=1` query param (mostly for engineering verification before flipping the\n * default).\n */\n EnableStreaming = false;\n\n /** Per-provider stream status displayed above results while a stream is in flight. */\n StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n private dataLoaded = false;\n\n // Override Data setter to trigger search when tab container provides the data\n // (ngOnInit fires before Data is set, so we can't rely on it)\n override set Data(value: ResourceData) {\n super.Data = value;\n if (!this.dataLoaded) {\n this.dataLoaded = true;\n this.loadFromData();\n }\n }\n override get Data(): ResourceData {\n return super.Data;\n }\n\n private async loadFromData(): Promise<void> {\n this.registerAgentTools();\n\n // Load filter panel preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n const pref = UserInfoEngine.Instance.GetSetting('search.showFilterPanel');\n if (pref === 'false') this.ShowFilterPanel = false;\n } catch { /* ignore */ }\n\n const config = this.Data?.Configuration;\n if (config?.Query) {\n this.CurrentQuery = config.Query as string;\n } else if (config?.SearchInput) {\n this.CurrentQuery = config.SearchInput as string;\n }\n\n // Apply min relevance from the search bar dropdown if provided\n if (config?.MinRelevance != null) {\n const mr = Number(config.MinRelevance);\n if (!isNaN(mr) && mr >= 0 && mr <= 100) {\n this.MinScorePercent = mr;\n }\n }\n\n // Carry scope selection from the search bar through into the initial query.\n if (Array.isArray(config?.ScopeIDs)) {\n this.ScopeIDs = (config.ScopeIDs as unknown[]).filter((x): x is string => typeof x === 'string');\n }\n\n // Streaming opt-in: resource config wins; URL query param `?stream=1` is the\n // engineering-verification override (cleared once the default flips). Read the\n // URL directly because the resource's tab config doesn't always mirror URL params\n // into `Configuration.queryParams` at the moment loadFromData() runs.\n if (config?.EnableStreaming === true) {\n this.EnableStreaming = true;\n }\n try {\n const streamParam = new URL(window.location.href).searchParams.get('stream');\n if (streamParam === '1' || streamParam === 'true') {\n this.EnableStreaming = true;\n }\n } catch { /* ignore — server-side render or odd URL */ }\n\n // Sync min relevance to URL query param\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(this.MinScorePercent) });\n\n if (this.CurrentQuery) {\n await this.ExecuteSearch(this.CurrentQuery);\n }\n\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n super.ngOnDestroy();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n const query = (data.Configuration?.Query ?? data.Configuration?.SearchInput ?? 'Search') as string;\n return `Search: ${query}`;\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-magnifying-glass';\n }\n\n async OnRefineSearch(query: string): Promise<void> {\n const trimmed = query?.trim();\n if (trimmed && trimmed.length >= 2) {\n this.CurrentQuery = trimmed;\n this.ActiveFilters = {};\n await this.ExecuteSearch(trimmed);\n }\n }\n\n OnFilterChanged(event: SearchFilterChangeEvent): void {\n this.ActiveFilters = {\n ...this.ActiveFilters,\n [event.Category]: event.SelectedValues\n };\n this.applyClientFilters();\n }\n\n OnFiltersCleared(): void {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: '30' });\n this.applyClientFilters();\n }\n\n OnMinScoreChanged(percent: number): void {\n this.MinScorePercent = percent;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(percent) });\n if (percent < this.serverMinScorePercent && this.CurrentQuery) {\n // User lowered below what server filtered — need to re-query with lower threshold\n this.ExecuteSearch(this.CurrentQuery);\n } else {\n // User raised or stayed at/above server threshold — client-side filter is sufficient\n this.applyClientFilters();\n }\n }\n\n OnResultSelected(event: SearchResultSelectedEvent): void {\n this.navigateToResult(event.Result);\n }\n\n OnOpenRecord(result: SearchResultItem): void {\n this.navigateToResult(result);\n }\n\n async OnRefresh(): Promise<void> {\n if (this.CurrentQuery) {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.ClientFilterText = '';\n await this.ExecuteSearch(this.CurrentQuery);\n }\n }\n\n ToggleFilterPanel(): void {\n this.ShowFilterPanel = !this.ShowFilterPanel;\n // Persist preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n UserInfoEngine.Instance.SetSettingDebounced(\n 'search.showFilterPanel',\n this.ShowFilterPanel ? 'true' : 'false'\n );\n } catch { /* ignore if UserInfoEngine not available */ }\n this.cdr.detectChanges();\n }\n\n OnSortChange(field: string): void {\n this.SortField = field as 'score' | 'title' | 'entity';\n this.applyClientFilters();\n }\n\n OnClientFilterTextChange(text: string): void {\n this.ClientFilterText = text;\n this.applyClientFilters();\n }\n\n SetViewMode(mode: 'list' | 'cloud'): void {\n this.ViewMode = mode;\n if (mode === 'cloud') {\n this.buildCloudItems();\n }\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n OnCloudItemClick(_event: WordCloudItemEvent): void {\n // No-op for now — tag filtering in the filter panel is not yet implemented.\n // Future: clicking a tag could filter results to only those with that tag.\n }\n\n /**\n * Navigate to a search result based on its ResultType discriminator.\n * - entity-record: opens the MJ entity record viewer\n * - storage-file: opens the file via pre-authenticated URL in new tab\n * - content-item: opens the MJ entity record viewer (content items are entity records)\n */\n private navigateToResult(result: SearchResultItem): void {\n if (result.ResultType === 'storage-file') {\n // Try preview first (opens in provider's web viewer), fall back to download\n if (!this.fileOpenService.OpenPreviewFromSearchResult(result.RawMetadata)) {\n this.fileOpenService.OpenFileFromSearchResult(result.RawMetadata);\n }\n return;\n }\n\n if (!result.EntityName || !result.RecordID) return;\n\n // entity-record, content-item, or unset — navigate to entity record\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: result.RecordID }]);\n this.navigationService.OpenEntityRecord(result.EntityName, pkey);\n }\n\n private async ExecuteSearch(query: string): Promise<void> {\n this.IsSearching = true;\n this.HasSearched = false;\n this.cdr.detectChanges();\n\n this.serverMinScorePercent = this.MinScorePercent;\n const request: SearchRequest = {\n Query: query,\n MaxResults: 50,\n ActiveFilters: {},\n IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],\n MinScore: this.MinScorePercent / 100\n };\n if (this.ScopeIDs.length > 0) {\n request.ScopeIDs = [...this.ScopeIDs];\n }\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request);\n return;\n }\n\n const response: SearchResponse = await this.searchService.ExecuteSearch(request);\n\n this.allResults = [...response.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.Filters = response.Filters;\n this.FilteredResults = [...this.allResults];\n\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /**\n * Phase 2C streaming variant. Subscribes to `streamScopedSearch` and progressively\n * populates the result list as each provider reports back. The 'final' event carries\n * the canonical fused/reranked list, which replaces any partials the user already saw.\n *\n * Cancellation: a new query starts by tearing down the in-flight stream so events\n * from a stale search do not bleed into the current view.\n */\n private executeStreamingSearch(query: string, request: SearchRequest): void {\n // Cancel any prior stream so events from a stale query don't leak in.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible streaming state.\n this.StreamingProviders = [];\n this.allResults = [];\n this.FilteredResults = [];\n this.ServerResultCount = 0;\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n this.allResults = [...this.allResults, ...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.applyClientFilters();\n }\n } else if (event.Phase === 'final' && event.Results) {\n this.allResults = [...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.Filters = this.searchService.BuildFilters(this.allResults);\n this.applyClientFilters();\n this.HasSearched = true;\n }\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.IsSearching = false;\n this.HasSearched = true;\n this.cdr.detectChanges();\n },\n complete: () => {\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n },\n });\n }\n\n /**\n * Apply active filter selections to the full result set.\n */\n private applyClientFilters(): void {\n let results = this.allResults;\n\n // Apply min score filter FIRST (this determines what's \"available\")\n if (this.MinScorePercent > 0) {\n const minScore = this.MinScorePercent / 100;\n results = results.filter(r => r.Score >= minScore);\n }\n\n // Rebuild filters from score-filtered results so counts are accurate\n this.Filters = this.searchService.BuildFilters(results);\n this.TotalCount = results.length;\n\n // Apply facet filters\n if (this.hasActiveFilters()) {\n results = results.filter(r => this.matchesActiveFilters(r));\n }\n\n // Apply client text filter (search within results)\n if (this.ClientFilterText.trim()) {\n const term = this.ClientFilterText.trim().toLowerCase();\n results = results.filter(r =>\n (r.Title?.toLowerCase().includes(term)) ||\n (r.Snippet?.toLowerCase().includes(term)) ||\n (r.EntityName?.toLowerCase().includes(term)) ||\n (r.RecordName?.toLowerCase().includes(term)) ||\n (r.Tags?.some(t => t.toLowerCase().includes(term)))\n );\n }\n\n // Sort\n switch (this.SortField) {\n case 'title':\n results = [...results].sort((a, b) => (a.Title || '').localeCompare(b.Title || ''));\n break;\n case 'entity':\n results = [...results].sort((a, b) => a.EntityName.localeCompare(b.EntityName) || b.Score - a.Score);\n break;\n case 'score':\n default:\n results = [...results].sort((a, b) => b.Score - a.Score);\n break;\n }\n\n this.FilteredResults = results;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n private hasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n private matchesActiveFilters(result: SearchResultItem): boolean {\n const entityFilter = this.ActiveFilters['Entity'];\n if (entityFilter?.length) {\n const matchesEntity = entityFilter.includes(result.EntityName);\n const matchesFiles = entityFilter.includes('__storage-files__') && result.ResultType === 'storage-file';\n if (!matchesEntity && !matchesFiles) return false;\n }\n\n const sourceFilter = this.ActiveFilters['Source'];\n if (sourceFilter?.length && !sourceFilter.includes(result.SourceType)) {\n return false;\n }\n\n const tagFilter = this.ActiveFilters['Tags'];\n if (tagFilter?.length && !tagFilter.some(t => result.Tags.includes(t))) {\n return false;\n }\n\n const fileTypeFilter = this.ActiveFilters['File Type'];\n if (fileTypeFilter?.length) {\n if (result.ResultType !== 'storage-file') return false;\n const ext = result.Title?.split('.').pop()?.toUpperCase() ?? '';\n if (!fileTypeFilter.includes(ext)) return false;\n }\n\n return true;\n }\n\n /**\n * Build WordCloudItem[] from search results by extracting entity names and tags,\n * weighted by their frequency across all results.\n */\n /**\n * Build word cloud items from MJ: Tagged Items linked to the search results.\n * Queries the TaggedItem entity for all records in the result set, aggregates\n * tag names by count and weight, and builds WordCloudItem[] for the cloud.\n */\n private async buildCloudItems(): Promise<void> {\n this.IsLoadingCloud = true;\n this.cdr.detectChanges();\n\n try {\n // Group results by entity to build efficient queries\n const byEntity = new Map<string, string[]>();\n for (const result of this.allResults) {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === result.EntityName);\n if (!entity) continue;\n const list = byEntity.get(entity.ID) || [];\n list.push(result.RecordID);\n byEntity.set(entity.ID, list);\n }\n\n // Query Tagged Items for all record IDs across all entities\n const tagAggregates = new Map<string, { count: number; totalWeight: number }>();\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n for (const [entityID, recordIDs] of byEntity) {\n if (recordIDs.length === 0) continue;\n\n // Build IN clause (batch in groups of 50 to avoid huge queries)\n for (let i = 0; i < recordIDs.length; i += 50) {\n const batch = recordIDs.slice(i, i + 50);\n const inClause = batch.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n\n const result = await rv.RunView<{ Tag: string; Weight: number }>({\n EntityName: 'MJ: Tagged Items',\n ExtraFilter: `EntityID = '${entityID}' AND RecordID IN (${inClause})`,\n Fields: ['Tag', 'Weight'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const tagName = row.Tag;\n if (!tagName) continue;\n const existing = tagAggregates.get(tagName) || { count: 0, totalWeight: 0 };\n existing.count++;\n existing.totalWeight += (row.Weight ?? 1);\n tagAggregates.set(tagName, existing);\n }\n }\n }\n }\n\n // Build cloud items from aggregated tags\n if (tagAggregates.size === 0) {\n this.CloudItems = [{ Text: 'No tags found', Weight: 1, Category: 'empty' }];\n } else {\n const maxWeight = Math.max(...Array.from(tagAggregates.values()).map(v => v.totalWeight), 1);\n this.CloudItems = Array.from(tagAggregates.entries())\n .sort((a, b) => b[1].totalWeight - a[1].totalWeight)\n .map(([tagName, agg]) => ({\n Text: tagName,\n Weight: agg.totalWeight / maxWeight,\n Category: 'tag',\n Metadata: { type: 'tag', count: agg.count, totalWeight: agg.totalWeight }\n }));\n }\n } catch (err) {\n this.CloudItems = [{ Text: 'Error loading tags', Weight: 1, Category: 'error' }];\n }\n\n this.IsLoadingCloud = false;\n this.cdr.detectChanges();\n }\n\n /** Report current search state to the AI agent */\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n CurrentQuery: this.CurrentQuery || null,\n ResultCount: this.TotalCount,\n FilteredCount: this.FilteredResults.length,\n ElapsedMs: this.ElapsedMs,\n HasSearched: this.HasSearched,\n ShowFilterPanel: this.ShowFilterPanel,\n ViewMode: this.ViewMode,\n SortField: this.SortField,\n MinScorePercent: this.MinScorePercent,\n ClientFilterText: this.ClientFilterText,\n ActiveFilterCount: Object.values(this.ActiveFilters).filter(v => v.length > 0).length,\n TopResults: this.FilteredResults.slice(0, 50).map(r => ({\n Title: r.Title || r.RecordName,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n Score: Math.round(r.Score * 100),\n SourceType: r.SourceType,\n Snippet: r.Snippet?.substring(0, 100)\n })),\n });\n }\n\n /** Register client tools the agent can invoke on the search results */\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunSearch',\n Description: 'Execute a search query and display results',\n ParameterSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query text' }\n },\n required: ['query']\n },\n Handler: async (params: Record<string, unknown>) => {\n const query = String(params['query'] ?? '');\n this.CurrentQuery = query;\n await this.ExecuteSearch(query);\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n },\n {\n Name: 'SortResults',\n Description: 'Change the sort order of search results',\n ParameterSchema: {\n type: 'object',\n properties: {\n field: { type: 'string', enum: ['score', 'title', 'entity'], description: 'Sort field' }\n },\n required: ['field']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnSortChange(String(params['field']));\n return { Success: true, Data: { SortField: this.SortField } };\n }\n },\n {\n Name: 'FilterWithinResults',\n Description: 'Filter the current results by a keyword (client-side text filter)',\n ParameterSchema: {\n type: 'object',\n properties: {\n text: { type: 'string', description: 'Filter text (empty string to clear)' }\n },\n required: ['text']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnClientFilterTextChange(String(params['text'] ?? ''));\n return { Success: true, Data: { FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'SetViewMode',\n Description: 'Switch between list view and tag cloud visualization',\n ParameterSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: ['list', 'cloud'], description: 'View mode' }\n },\n required: ['mode']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.SetViewMode((params['mode'] as 'list' | 'cloud') ?? 'list');\n return { Success: true, Data: { ViewMode: this.ViewMode } };\n }\n },\n {\n Name: 'ToggleFilterPanel',\n Description: 'Show or hide the filter panel on the left',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.ToggleFilterPanel();\n return { Success: true, Data: { ShowFilterPanel: this.ShowFilterPanel } };\n }\n },\n {\n Name: 'SetMinRelevance',\n Description: 'Set the minimum relevance score filter (0-100 percent)',\n ParameterSchema: {\n type: 'object',\n properties: {\n percent: { type: 'number', description: 'Minimum relevance percentage (0-100)' }\n },\n required: ['percent']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnMinScoreChanged(Number(params['percent'] ?? 0));\n return { Success: true, Data: { MinScorePercent: this.MinScorePercent, FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'RefreshSearch',\n Description: 'Re-execute the current search query',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.OnRefresh();\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n }\n ]);\n }\n}\n\nexport function LoadSearchResultsResource() {\n // Tree-shaking prevention\n}\n"]}
1
+ {"version":3,"file":"search-results-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/search-results-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { FileOpenService } from '@memberjunction/ng-file-storage';\nimport {\n SearchService,\n SearchResultItem,\n SearchFilter,\n SearchFilterChangeEvent,\n SearchRequest,\n SearchResponse,\n SearchResultSelectedEvent,\n StreamingProviderStatus,\n} from '@memberjunction/ng-search';\nimport { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';\n\n@RegisterClass(BaseResourceComponent, 'SearchResultsResource')\n@Component({\n standalone: false,\n selector: 'mj-search-results-resource',\n template: `\n <div class=\"search-results-page\">\n <!-- Streaming status strip — visible while streamScopedSearch is in flight -->\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ p.ElapsedMs }}ms</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n @if (IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Streaming…</span>\n </span>\n }\n </div>\n }\n\n <!-- Header bar (always visible when we have server results) -->\n @if (HasSearched && ServerResultCount > 0) {\n <div class=\"search-header\">\n <div class=\"search-header-left\">\n @if (!ShowFilterPanel) {\n <button class=\"sr-icon-btn\" title=\"Show filters\" (click)=\"ToggleFilterPanel()\">\n <i class=\"fa-solid fa-filter\"></i>\n </button>\n }\n <span class=\"search-meta\">\n {{ FilteredResults.length }} of {{ ServerResultCount }} result{{ ServerResultCount !== 1 ? 's' : '' }}\n for \"{{ CurrentQuery }}\" in {{ ElapsedMs }}ms\n </span>\n </div>\n <div class=\"search-header-right\">\n <!-- Search within results -->\n <div class=\"sr-refine-wrapper\">\n <i class=\"fa-solid fa-filter-list sr-refine-icon\"></i>\n <input class=\"mj-input sr-refine-input\"\n placeholder=\"Filter within results...\"\n [value]=\"ClientFilterText\"\n (input)=\"OnClientFilterTextChange($any($event.target).value)\" />\n @if (ClientFilterText) {\n <button class=\"sr-refine-clear\" (click)=\"OnClientFilterTextChange('')\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n <!-- Sort -->\n <select class=\"mj-input sr-sort-select\" [value]=\"SortField\" (change)=\"OnSortChange($any($event.target).value)\">\n <option value=\"score\">Sort: Relevance</option>\n <option value=\"title\">Sort: Name</option>\n <option value=\"entity\">Sort: Entity</option>\n </select>\n <!-- View mode toggle -->\n <div class=\"sr-view-toggle\">\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'list'\"\n title=\"List view\"\n (click)=\"SetViewMode('list')\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'cloud'\"\n title=\"Tag cloud view\"\n (click)=\"SetViewMode('cloud')\">\n <i class=\"fa-solid fa-cloud\"></i>\n </button>\n </div>\n <!-- Refresh -->\n <button class=\"sr-icon-btn\" title=\"Refresh search\" (click)=\"OnRefresh()\" [disabled]=\"IsSearching\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsSearching\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Initial loading (first search) -->\n @if (IsSearching && ServerResultCount === 0) {\n <div class=\"search-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- No server results -->\n @if (!IsSearching && ServerResultCount === 0 && HasSearched) {\n <div class=\"search-no-results\">\n <i class=\"fa-solid fa-magnifying-glass-minus\"></i>\n <h3>No results found</h3>\n <p>Try different keywords or broaden your search.</p>\n </div>\n }\n <!-- Results body (visible when server returned results) -->\n @if (ServerResultCount > 0) {\n <div class=\"search-results-body-wrapper\">\n <!-- Semi-opaque loading overlay for re-queries (slider lowered, etc.) -->\n @if (IsSearching) {\n <div class=\"search-requery-overlay\">\n <mj-loading text=\"Updating results...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (ViewMode === 'cloud') {\n <div class=\"search-cloud-wrapper\">\n @if (IsLoadingCloud) {\n <mj-loading text=\"Loading tag cloud...\" size=\"medium\"></mj-loading>\n } @else {\n <mj-word-cloud\n [Items]=\"CloudItems\"\n [MaxItems]=\"80\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnCloudItemClick($event)\">\n </mj-word-cloud>\n }\n </div>\n } @else {\n <div class=\"search-body\">\n @if (ShowFilterPanel) {\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n [ShowRelevanceSlider]=\"true\"\n [MinScorePercent]=\"MinScorePercent\"\n [ServerMinScorePercent]=\"serverMinScorePercent\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n (CloseRequested)=\"ToggleFilterPanel()\"\n (MinScoreChanged)=\"OnMinScoreChanged($any($event))\">\n </mj-search-filter>\n }\n @if (FilteredResults.length > 0) {\n <mj-search-results\n [FlatResults]=\"FilteredResults\"\n [HighlightText]=\"ClientFilterText\"\n [ShowScores]=\"true\"\n [ShowTags]=\"true\"\n [ShowSummary]=\"false\"\n [PageSize]=\"20\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\">\n </mj-search-results>\n } @else {\n <div class=\"search-no-results-inline\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n <p>No results match current filters. Try lowering the minimum relevance.</p>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [`\n .search-results-page {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n .search-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n .search-header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-meta {\n color: var(--mj-text-muted);\n font-size: 13px;\n white-space: nowrap;\n }\n .sr-icon-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n font-size: 13px;\n flex-shrink: 0;\n }\n .sr-icon-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .sr-icon-btn:disabled { opacity: 0.4; cursor: default; }\n .sr-refine-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n }\n .sr-refine-icon {\n position: absolute;\n left: 8px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n }\n .sr-refine-input {\n padding: 5px 28px 5px 26px;\n font-size: 12px;\n width: 180px;\n border-radius: 6px;\n }\n .sr-refine-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 2px;\n }\n .sr-refine-clear:hover { color: var(--mj-text-primary); }\n .sr-sort-select {\n padding: 5px 24px 5px 8px;\n font-size: 12px;\n border-radius: 6px;\n min-width: 130px;\n }\n .search-loading {\n display: flex;\n justify-content: center;\n padding: 60px 0;\n }\n .search-body {\n flex: 1;\n display: flex;\n gap: 16px;\n padding: 16px 24px;\n overflow: hidden;\n }\n .search-body mj-search-filter {\n flex-shrink: 0;\n width: 240px;\n overflow-y: auto;\n }\n .search-body mj-search-results {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n }\n .search-no-results {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n }\n .search-no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.4;\n }\n .search-no-results h3 {\n font-size: 18px;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n }\n .search-no-results p {\n font-size: 14px;\n margin: 0;\n }\n .search-results-body-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .search-requery-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 75%, transparent);\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-no-results-inline {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: var(--mj-text-muted);\n padding: 40px 20px;\n }\n .search-no-results-inline i {\n font-size: 32px;\n opacity: 0.4;\n }\n .search-no-results-inline p {\n font-size: 13px;\n margin: 0;\n }\n .sr-view-toggle {\n display: flex;\n gap: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n padding: 2px;\n background: var(--mj-bg-surface-sunken);\n }\n .sr-view-toggle .sr-icon-btn {\n border: none;\n border-radius: 4px;\n width: 28px;\n height: 26px;\n font-size: 12px;\n background: transparent;\n }\n .sr-view-toggle .sr-icon-btn.sr-view-active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 10%, transparent);\n }\n .search-cloud-wrapper {\n flex: 1;\n padding: 24px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-cloud-wrapper mj-word-cloud {\n width: 100%;\n height: 100%;\n max-height: 600px;\n }\n .streaming-status-strip {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .streaming-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n }\n .streaming-chip-pending {\n color: var(--mj-text-muted);\n }\n .streaming-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n }\n .streaming-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n }\n .streaming-chip-name { font-weight: 500; }\n .streaming-chip-count { opacity: 0.7; }\n .streaming-chip-time { opacity: 0.6; font-size: 0.7rem; }\n `]\n})\nexport class SearchResultsResource extends BaseResourceComponent {\n private cdr = inject(ChangeDetectorRef);\n private searchService = inject(SearchService);\n private fileOpenService = inject(FileOpenService);\n\n CurrentQuery = '';\n IsSearching = false;\n HasSearched = false;\n TotalCount = 0;\n ElapsedMs = 0;\n Filters: SearchFilter[] = [];\n ActiveFilters: Record<string, string[]> = {};\n FilteredResults: SearchResultItem[] = [];\n MinScorePercent = 30;\n /** The MinScore that was sent to the server on the last search. If the user\n * slides below this, we need to re-query the server to get more results. */\n serverMinScorePercent = 30;\n /** How many results the server returned (before client-side filtering) */\n ServerResultCount = 0;\n ShowFilterPanel = true;\n SortField: 'score' | 'title' | 'entity' = 'score';\n ClientFilterText = '';\n ViewMode: 'list' | 'cloud' = 'list';\n CloudItems: WordCloudItem[] = [];\n IsLoadingCloud = false;\n\n /** All results from the last search (before client-side filtering) */\n private allResults: SearchResultItem[] = [];\n\n /** Selected scope IDs from the search bar (empty = unscoped/global). */\n private ScopeIDs: string[] = [];\n\n /**\n * Phase 2C streaming opt-in. Off by default to preserve Phase 1 request-response UX.\n * Enable per-resource via `Data.Configuration.EnableStreaming` or per-tab via the\n * `?stream=1` query param (mostly for engineering verification before flipping the\n * default).\n */\n EnableStreaming = false;\n\n /** Per-provider stream status displayed above results while a stream is in flight. */\n StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n private dataLoaded = false;\n\n // Override Data setter to trigger search when tab container provides the data\n // (ngOnInit fires before Data is set, so we can't rely on it)\n override set Data(value: ResourceData) {\n super.Data = value;\n if (!this.dataLoaded) {\n this.dataLoaded = true;\n this.loadFromData();\n }\n }\n override get Data(): ResourceData {\n return super.Data;\n }\n\n private async loadFromData(): Promise<void> {\n this.registerAgentTools();\n\n // Load filter panel preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n const pref = UserInfoEngine.Instance.GetSetting('search.showFilterPanel');\n if (pref === 'false') this.ShowFilterPanel = false;\n } catch { /* ignore */ }\n\n const config = this.Data?.Configuration;\n if (config?.Query) {\n this.CurrentQuery = config.Query as string;\n } else if (config?.SearchInput) {\n this.CurrentQuery = config.SearchInput as string;\n }\n\n // Apply min relevance from the search bar dropdown if provided\n if (config?.MinRelevance != null) {\n const mr = Number(config.MinRelevance);\n if (!isNaN(mr) && mr >= 0 && mr <= 100) {\n this.MinScorePercent = mr;\n }\n }\n\n // Carry scope selection from the search bar through into the initial query.\n if (Array.isArray(config?.ScopeIDs)) {\n this.ScopeIDs = (config.ScopeIDs as unknown[]).filter((x): x is string => typeof x === 'string');\n }\n\n // Streaming opt-in: resource config wins; URL query param `?stream=1` is the\n // engineering-verification override (cleared once the default flips). Read the\n // URL directly because the resource's tab config doesn't always mirror URL params\n // into `Configuration.queryParams` at the moment loadFromData() runs.\n if (config?.EnableStreaming === true) {\n this.EnableStreaming = true;\n }\n try {\n const streamParam = new URL(window.location.href).searchParams.get('stream');\n if (streamParam === '1' || streamParam === 'true') {\n this.EnableStreaming = true;\n }\n } catch { /* ignore — server-side render or odd URL */ }\n\n // Sync min relevance to URL query param\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(this.MinScorePercent) });\n\n if (this.CurrentQuery) {\n await this.ExecuteSearch(this.CurrentQuery);\n }\n\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n super.ngOnDestroy();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n const query = (data.Configuration?.Query ?? data.Configuration?.SearchInput ?? 'Search') as string;\n return `Search: ${query}`;\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-magnifying-glass';\n }\n\n async OnRefineSearch(query: string): Promise<void> {\n const trimmed = query?.trim();\n if (trimmed && trimmed.length >= 2) {\n this.CurrentQuery = trimmed;\n this.ActiveFilters = {};\n await this.ExecuteSearch(trimmed);\n }\n }\n\n OnFilterChanged(event: SearchFilterChangeEvent): void {\n this.ActiveFilters = {\n ...this.ActiveFilters,\n [event.Category]: event.SelectedValues\n };\n this.applyClientFilters();\n }\n\n OnFiltersCleared(): void {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: '30' });\n this.applyClientFilters();\n }\n\n OnMinScoreChanged(percent: number): void {\n this.MinScorePercent = percent;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(percent) });\n if (percent < this.serverMinScorePercent && this.CurrentQuery) {\n // User lowered below what server filtered — need to re-query with lower threshold\n this.ExecuteSearch(this.CurrentQuery);\n } else {\n // User raised or stayed at/above server threshold — client-side filter is sufficient\n this.applyClientFilters();\n }\n }\n\n /**\n * React to ?minRelevance= changes that arrive after initial load — e.g. a Home pin or\n * deep link to a specific relevance threshold, or browser back/forward — when this tab\n * is re-focused rather than freshly loaded (so loadFromData() does not run again).\n */\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const minRelevance = params['minRelevance'];\n if (minRelevance == null) return;\n const mr = Number(minRelevance);\n if (isNaN(mr) || mr < 0 || mr > 100 || mr === this.MinScorePercent) return;\n\n this.MinScorePercent = mr;\n if (mr < this.serverMinScorePercent && this.CurrentQuery) {\n // Below what the server filtered — re-query with the lower threshold.\n void this.ExecuteSearch(this.CurrentQuery);\n } else {\n this.applyClientFilters();\n }\n }\n\n OnResultSelected(event: SearchResultSelectedEvent): void {\n this.navigateToResult(event.Result);\n }\n\n OnOpenRecord(result: SearchResultItem): void {\n this.navigateToResult(result);\n }\n\n async OnRefresh(): Promise<void> {\n if (this.CurrentQuery) {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.ClientFilterText = '';\n await this.ExecuteSearch(this.CurrentQuery);\n }\n }\n\n ToggleFilterPanel(): void {\n this.ShowFilterPanel = !this.ShowFilterPanel;\n // Persist preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n UserInfoEngine.Instance.SetSettingDebounced(\n 'search.showFilterPanel',\n this.ShowFilterPanel ? 'true' : 'false'\n );\n } catch { /* ignore if UserInfoEngine not available */ }\n this.cdr.detectChanges();\n }\n\n OnSortChange(field: string): void {\n this.SortField = field as 'score' | 'title' | 'entity';\n this.applyClientFilters();\n }\n\n OnClientFilterTextChange(text: string): void {\n this.ClientFilterText = text;\n this.applyClientFilters();\n }\n\n SetViewMode(mode: 'list' | 'cloud'): void {\n this.ViewMode = mode;\n if (mode === 'cloud') {\n this.buildCloudItems();\n }\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n OnCloudItemClick(_event: WordCloudItemEvent): void {\n // No-op for now — tag filtering in the filter panel is not yet implemented.\n // Future: clicking a tag could filter results to only those with that tag.\n }\n\n /**\n * Navigate to a search result based on its ResultType discriminator.\n * - entity-record: opens the MJ entity record viewer\n * - storage-file: opens the file via pre-authenticated URL in new tab\n * - content-item: opens the MJ entity record viewer (content items are entity records)\n */\n private navigateToResult(result: SearchResultItem): void {\n if (result.ResultType === 'storage-file') {\n // Try preview first (opens in provider's web viewer), fall back to download\n if (!this.fileOpenService.OpenPreviewFromSearchResult(result.RawMetadata)) {\n this.fileOpenService.OpenFileFromSearchResult(result.RawMetadata);\n }\n return;\n }\n\n if (!result.EntityName || !result.RecordID) return;\n\n // entity-record, content-item, or unset — navigate to entity record\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: result.RecordID }]);\n this.navigationService.OpenEntityRecord(result.EntityName, pkey);\n }\n\n private async ExecuteSearch(query: string): Promise<void> {\n this.IsSearching = true;\n this.HasSearched = false;\n this.cdr.detectChanges();\n\n this.serverMinScorePercent = this.MinScorePercent;\n const request: SearchRequest = {\n Query: query,\n MaxResults: 50,\n ActiveFilters: {},\n IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],\n MinScore: this.MinScorePercent / 100\n };\n if (this.ScopeIDs.length > 0) {\n request.ScopeIDs = [...this.ScopeIDs];\n }\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request);\n return;\n }\n\n const response: SearchResponse = await this.searchService.ExecuteSearch(request);\n\n this.allResults = [...response.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.Filters = response.Filters;\n this.FilteredResults = [...this.allResults];\n\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /**\n * Phase 2C streaming variant. Subscribes to `streamScopedSearch` and progressively\n * populates the result list as each provider reports back. The 'final' event carries\n * the canonical fused/reranked list, which replaces any partials the user already saw.\n *\n * Cancellation: a new query starts by tearing down the in-flight stream so events\n * from a stale search do not bleed into the current view.\n */\n private executeStreamingSearch(query: string, request: SearchRequest): void {\n // Cancel any prior stream so events from a stale query don't leak in.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible streaming state.\n this.StreamingProviders = [];\n this.allResults = [];\n this.FilteredResults = [];\n this.ServerResultCount = 0;\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n this.allResults = [...this.allResults, ...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.applyClientFilters();\n }\n } else if (event.Phase === 'final' && event.Results) {\n this.allResults = [...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.Filters = this.searchService.BuildFilters(this.allResults);\n this.applyClientFilters();\n this.HasSearched = true;\n }\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.IsSearching = false;\n this.HasSearched = true;\n this.cdr.detectChanges();\n },\n complete: () => {\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n },\n });\n }\n\n /**\n * Apply active filter selections to the full result set.\n */\n private applyClientFilters(): void {\n let results = this.allResults;\n\n // Apply min score filter FIRST (this determines what's \"available\")\n if (this.MinScorePercent > 0) {\n const minScore = this.MinScorePercent / 100;\n results = results.filter(r => r.Score >= minScore);\n }\n\n // Rebuild filters from score-filtered results so counts are accurate\n this.Filters = this.searchService.BuildFilters(results);\n this.TotalCount = results.length;\n\n // Apply facet filters\n if (this.hasActiveFilters()) {\n results = results.filter(r => this.matchesActiveFilters(r));\n }\n\n // Apply client text filter (search within results)\n if (this.ClientFilterText.trim()) {\n const term = this.ClientFilterText.trim().toLowerCase();\n results = results.filter(r =>\n (r.Title?.toLowerCase().includes(term)) ||\n (r.Snippet?.toLowerCase().includes(term)) ||\n (r.EntityName?.toLowerCase().includes(term)) ||\n (r.RecordName?.toLowerCase().includes(term)) ||\n (r.Tags?.some(t => t.toLowerCase().includes(term)))\n );\n }\n\n // Sort\n switch (this.SortField) {\n case 'title':\n results = [...results].sort((a, b) => (a.Title || '').localeCompare(b.Title || ''));\n break;\n case 'entity':\n results = [...results].sort((a, b) => a.EntityName.localeCompare(b.EntityName) || b.Score - a.Score);\n break;\n case 'score':\n default:\n results = [...results].sort((a, b) => b.Score - a.Score);\n break;\n }\n\n this.FilteredResults = results;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n private hasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n private matchesActiveFilters(result: SearchResultItem): boolean {\n const entityFilter = this.ActiveFilters['Entity'];\n if (entityFilter?.length) {\n const matchesEntity = entityFilter.includes(result.EntityName);\n const matchesFiles = entityFilter.includes('__storage-files__') && result.ResultType === 'storage-file';\n if (!matchesEntity && !matchesFiles) return false;\n }\n\n const sourceFilter = this.ActiveFilters['Source'];\n if (sourceFilter?.length && !sourceFilter.includes(result.SourceType)) {\n return false;\n }\n\n const tagFilter = this.ActiveFilters['Tags'];\n if (tagFilter?.length && !tagFilter.some(t => result.Tags.includes(t))) {\n return false;\n }\n\n const fileTypeFilter = this.ActiveFilters['File Type'];\n if (fileTypeFilter?.length) {\n if (result.ResultType !== 'storage-file') return false;\n const ext = result.Title?.split('.').pop()?.toUpperCase() ?? '';\n if (!fileTypeFilter.includes(ext)) return false;\n }\n\n return true;\n }\n\n /**\n * Build WordCloudItem[] from search results by extracting entity names and tags,\n * weighted by their frequency across all results.\n */\n /**\n * Build word cloud items from MJ: Tagged Items linked to the search results.\n * Queries the TaggedItem entity for all records in the result set, aggregates\n * tag names by count and weight, and builds WordCloudItem[] for the cloud.\n */\n private async buildCloudItems(): Promise<void> {\n this.IsLoadingCloud = true;\n this.cdr.detectChanges();\n\n try {\n // Group results by entity to build efficient queries\n const byEntity = new Map<string, string[]>();\n for (const result of this.allResults) {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === result.EntityName);\n if (!entity) continue;\n const list = byEntity.get(entity.ID) || [];\n list.push(result.RecordID);\n byEntity.set(entity.ID, list);\n }\n\n // Query Tagged Items for all record IDs across all entities\n const tagAggregates = new Map<string, { count: number; totalWeight: number }>();\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n for (const [entityID, recordIDs] of byEntity) {\n if (recordIDs.length === 0) continue;\n\n // Build IN clause (batch in groups of 50 to avoid huge queries)\n for (let i = 0; i < recordIDs.length; i += 50) {\n const batch = recordIDs.slice(i, i + 50);\n const inClause = batch.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n\n const result = await rv.RunView<{ Tag: string; Weight: number }>({\n EntityName: 'MJ: Tagged Items',\n ExtraFilter: `EntityID = '${entityID}' AND RecordID IN (${inClause})`,\n Fields: ['Tag', 'Weight'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const tagName = row.Tag;\n if (!tagName) continue;\n const existing = tagAggregates.get(tagName) || { count: 0, totalWeight: 0 };\n existing.count++;\n existing.totalWeight += (row.Weight ?? 1);\n tagAggregates.set(tagName, existing);\n }\n }\n }\n }\n\n // Build cloud items from aggregated tags\n if (tagAggregates.size === 0) {\n this.CloudItems = [{ Text: 'No tags found', Weight: 1, Category: 'empty' }];\n } else {\n const maxWeight = Math.max(...Array.from(tagAggregates.values()).map(v => v.totalWeight), 1);\n this.CloudItems = Array.from(tagAggregates.entries())\n .sort((a, b) => b[1].totalWeight - a[1].totalWeight)\n .map(([tagName, agg]) => ({\n Text: tagName,\n Weight: agg.totalWeight / maxWeight,\n Category: 'tag',\n Metadata: { type: 'tag', count: agg.count, totalWeight: agg.totalWeight }\n }));\n }\n } catch (err) {\n this.CloudItems = [{ Text: 'Error loading tags', Weight: 1, Category: 'error' }];\n }\n\n this.IsLoadingCloud = false;\n this.cdr.detectChanges();\n }\n\n /** Report current search state to the AI agent */\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n CurrentQuery: this.CurrentQuery || null,\n ResultCount: this.TotalCount,\n FilteredCount: this.FilteredResults.length,\n ElapsedMs: this.ElapsedMs,\n HasSearched: this.HasSearched,\n ShowFilterPanel: this.ShowFilterPanel,\n ViewMode: this.ViewMode,\n SortField: this.SortField,\n MinScorePercent: this.MinScorePercent,\n ClientFilterText: this.ClientFilterText,\n ActiveFilterCount: Object.values(this.ActiveFilters).filter(v => v.length > 0).length,\n TopResults: this.FilteredResults.slice(0, 50).map(r => ({\n Title: r.Title || r.RecordName,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n Score: Math.round(r.Score * 100),\n SourceType: r.SourceType,\n Snippet: r.Snippet?.substring(0, 100)\n })),\n });\n }\n\n /** Register client tools the agent can invoke on the search results */\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunSearch',\n Description: 'Execute a search query and display results',\n ParameterSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query text' }\n },\n required: ['query']\n },\n Handler: async (params: Record<string, unknown>) => {\n const query = String(params['query'] ?? '');\n this.CurrentQuery = query;\n await this.ExecuteSearch(query);\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n },\n {\n Name: 'SortResults',\n Description: 'Change the sort order of search results',\n ParameterSchema: {\n type: 'object',\n properties: {\n field: { type: 'string', enum: ['score', 'title', 'entity'], description: 'Sort field' }\n },\n required: ['field']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnSortChange(String(params['field']));\n return { Success: true, Data: { SortField: this.SortField } };\n }\n },\n {\n Name: 'FilterWithinResults',\n Description: 'Filter the current results by a keyword (client-side text filter)',\n ParameterSchema: {\n type: 'object',\n properties: {\n text: { type: 'string', description: 'Filter text (empty string to clear)' }\n },\n required: ['text']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnClientFilterTextChange(String(params['text'] ?? ''));\n return { Success: true, Data: { FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'SetViewMode',\n Description: 'Switch between list view and tag cloud visualization',\n ParameterSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: ['list', 'cloud'], description: 'View mode' }\n },\n required: ['mode']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.SetViewMode((params['mode'] as 'list' | 'cloud') ?? 'list');\n return { Success: true, Data: { ViewMode: this.ViewMode } };\n }\n },\n {\n Name: 'ToggleFilterPanel',\n Description: 'Show or hide the filter panel on the left',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.ToggleFilterPanel();\n return { Success: true, Data: { ShowFilterPanel: this.ShowFilterPanel } };\n }\n },\n {\n Name: 'SetMinRelevance',\n Description: 'Set the minimum relevance score filter (0-100 percent)',\n ParameterSchema: {\n type: 'object',\n properties: {\n percent: { type: 'number', description: 'Minimum relevance percentage (0-100)' }\n },\n required: ['percent']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnMinScoreChanged(Number(params['percent'] ?? 0));\n return { Success: true, Data: { MinScorePercent: this.MinScorePercent, FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'RefreshSearch',\n Description: 'Re-execute the current search query',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.OnRefresh();\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n }\n ]);\n }\n}\n\nexport function LoadSearchResultsResource() {\n // Tree-shaking prevention\n}\n"]}
@@ -110,6 +110,17 @@ export declare class ComponentCacheManager {
110
110
  * Call this on user logout or app shutdown.
111
111
  */
112
112
  clearCache(): void;
113
+ /**
114
+ * Selectively clear cached components matching a predicate.
115
+ * Components that match are destroyed; those that don't are kept.
116
+ *
117
+ * Use this for tenant switching: clear org-scoped components while
118
+ * keeping system/global components alive.
119
+ *
120
+ * @param predicate Return true for components that should be destroyed.
121
+ * @returns Number of components destroyed.
122
+ */
123
+ ClearCacheByPredicate(predicate: (info: CachedComponentInfo) => boolean): number;
113
124
  /**
114
125
  * Get cache statistics for debugging.
115
126
  */
@@ -1 +1 @@
1
- {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAElC,YAAY,EAAE,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAGlD,cAAc,EAAE,WAAW,CAAC;IAG5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IAGtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAG/B,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAGhB,YAAY,EAAE,YAAY,CAAC;IAK3B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI1C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIvC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAC;CACtK;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,qBAAqB;IAUpB,OAAO,CAAC,MAAM;IAT1B,OAAO,CAAC,KAAK,CAA0C;IAEvD;;;;OAIG;IACH,OAAc,qBAAqB,EAAE,MAAM,CAAM;gBAE7B,MAAM,EAAE,cAAc;IAE1C;;;OAGG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAMrF;;;OAGG;IACH,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAgBrG;;OAEG;IACH,cAAc,CACZ,YAAY,EAAE,YAAY,CAAC,qBAAqB,CAAC,EACjD,cAAc,EAAE,WAAW,EAC3B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,GACZ,IAAI;IA6BP;;OAEG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAW1F;;;;;OAKG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAYjG;;;;;OAKG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAU/D;;;OAGG;IACH,OAAO,CAAC,aAAa;IAerB;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAO9D;;OAEG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAW7E;;OAEG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY5C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAQlB;;;;;;;;;OASG;IACH,qBAAqB,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,GAAG,MAAM;IAoBhF;;OAEG;IACH,aAAa,IAAI;QACf,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACrC;CAqBF"}
@@ -189,6 +189,32 @@ export class ComponentCacheManager {
189
189
  });
190
190
  this.cache.clear();
191
191
  }
192
+ /**
193
+ * Selectively clear cached components matching a predicate.
194
+ * Components that match are destroyed; those that don't are kept.
195
+ *
196
+ * Use this for tenant switching: clear org-scoped components while
197
+ * keeping system/global components alive.
198
+ *
199
+ * @param predicate Return true for components that should be destroyed.
200
+ * @returns Number of components destroyed.
201
+ */
202
+ ClearCacheByPredicate(predicate) {
203
+ let destroyed = 0;
204
+ const toRemove = [];
205
+ this.cache.forEach((info, key) => {
206
+ if (predicate(info)) {
207
+ this.appRef.detachView(info.componentRef.hostView);
208
+ info.componentRef.destroy();
209
+ toRemove.push(key);
210
+ destroyed++;
211
+ }
212
+ });
213
+ for (const key of toRemove) {
214
+ this.cache.delete(key);
215
+ }
216
+ return destroyed;
217
+ }
192
218
  /**
193
219
  * Get cache statistics for debugging.
194
220
  */
@@ -1 +1 @@
1
- {"version":3,"file":"component-cache-manager.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { ComponentRef, ApplicationRef } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\n\n/**\n * Metadata about a cached component\n */\nexport interface CachedComponentInfo {\n // The Angular component reference\n componentRef: ComponentRef<BaseResourceComponent>;\n\n // The wrapper DOM element (for detaching/reattaching)\n wrapperElement: HTMLElement;\n\n // Resource identity (the ONLY key used for cache operations)\n resourceType: string;\n resourceRecordId: string;\n applicationId: string;\n\n // Usage tracking\n isAttached: boolean; // Currently attached to a tab/container?\n attachedToTabId: string | null; // Which tab is it attached to? (metadata only, NOT used for lookup)\n\n // Lifecycle tracking\n lastUsed: Date;\n createdAt: Date;\n\n // Resource data snapshot (for comparison)\n resourceData: ResourceData;\n\n // Saved query params from the tab config at detach time.\n // Restored to the tab config when the component is reattached,\n // so the URL reflects the component's preserved state.\n savedQueryParams?: Record<string, string>;\n\n // Agent context reported by this component via NavigationService.SetAgentContext()\n // Cached so it can be restored when the component becomes active again.\n AgentContext?: Record<string, unknown>;\n\n // Agent client tools registered by this component via NavigationService.SetAgentClientTools()\n // Cached so they can be re-registered when the component becomes active again.\n AgentClientTools?: { Name: string; Description: string; ParameterSchema: Record<string, unknown>; Handler: (params: Record<string, unknown>) => Promise<unknown> }[];\n}\n\n/**\n * Smart component cache manager that preserves component state across tab switches.\n *\n * ALL cache operations use a consistent identity key: `appId::resourceType::recordId`.\n * This key is the same regardless of whether the component is in Golden Layout (tabbed)\n * mode or Single Resource mode, ensuring components are reusable across both modes.\n *\n * The `attachedToTabId` field is metadata for debugging/display — it is NEVER used\n * as a lookup key. This prevents bugs where multiple resources sharing the same tab ID\n * (e.g., nav items within a single-resource app) interfere with each other's cache state.\n *\n * Features:\n * - Caches components by resource identity (appId + resourceType + recordId)\n * - Tracks component usage to prevent double-attachment\n * - Detaches/reattaches DOM elements without destroying Angular components\n * - LRU eviction when detached component count exceeds MaxDetachedComponents\n */\nexport class ComponentCacheManager {\n private cache = new Map<string, CachedComponentInfo>();\n\n /**\n * Maximum number of detached (not currently visible) components to keep\n * cached. When exceeded, least-recently-used detached components are\n * evicted. Set to 0 to disable eviction (legacy behavior). Default: 20.\n */\n public static MaxDetachedComponents: number = 20;\n\n constructor(private appRef: ApplicationRef) {}\n\n /**\n * Generate a unique cache key from resource identity.\n * This is the ONE canonical key format used by ALL cache operations.\n */\n private getCacheKey(resourceType: string, recordId: string, appId: string): string {\n const normalizedRecordId = recordId || '__no_record__';\n return `${appId}::${resourceType}::${normalizedRecordId}`;\n }\n\n /**\n * Check if a component exists in cache and is available for reuse.\n */\n hasAvailableComponent(resourceType: string, recordId: string, appId: string): boolean {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n return info !== undefined && !info.isAttached;\n }\n\n /**\n * Get a cached component if available (not currently attached).\n * Lookup is by resource identity, not tab ID.\n */\n getCachedComponent(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (!info) {\n return null;\n }\n\n // Can only reuse if not currently attached elsewhere\n if (info.isAttached) {\n return null;\n }\n\n return info;\n }\n\n /**\n * Store a component in the cache and mark as attached.\n */\n cacheComponent(\n componentRef: ComponentRef<BaseResourceComponent>,\n wrapperElement: HTMLElement,\n resourceData: ResourceData,\n tabId: string\n ): void {\n // Use driverClass (the actual component class name) as the resourceType for the cache key,\n // NOT resourceData.ResourceType (which is often just \"Custom\" for dashboard resources).\n // This must match the lookup key used in getCachedComponent/markAsAttached/markAsDetached.\n const resolvedResourceType = resourceData.Configuration?.resourceTypeDriverClass\n || resourceData.Configuration?.driverClass\n || resourceData.ResourceType;\n const key = this.getCacheKey(\n resolvedResourceType,\n resourceData.ResourceRecordID || '',\n resourceData.Configuration?.applicationId || ''\n );\n\n const info: CachedComponentInfo = {\n componentRef,\n wrapperElement,\n resourceType: resolvedResourceType,\n resourceRecordId: resourceData.ResourceRecordID || '',\n applicationId: resourceData.Configuration?.applicationId || '',\n isAttached: true,\n attachedToTabId: tabId,\n lastUsed: new Date(),\n createdAt: new Date(),\n resourceData\n };\n\n this.cache.set(key, info);\n }\n\n /**\n * Mark a component as attached. Lookup by resource identity.\n */\n markAsAttached(resourceType: string, recordId: string, appId: string, tabId: string): void {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (info) {\n info.isAttached = true;\n info.attachedToTabId = tabId;\n info.lastUsed = new Date();\n }\n }\n\n /**\n * Mark a component as detached (available for reuse). Lookup by resource identity.\n *\n * This is the ONLY way to detach a component. Both single-resource mode and\n * Golden Layout mode use this same method to ensure consistent cache behavior.\n */\n markAsDetached(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n if (!info) return null;\n\n info.isAttached = false;\n info.attachedToTabId = null;\n info.lastUsed = new Date();\n this.EvictIfNeeded();\n return info;\n }\n\n /**\n * Find a cached component by tab ID and detach it.\n * This is a convenience wrapper for callers that only know the tab ID\n * (e.g., Golden Layout tab close events). It resolves the tab ID to\n * resource identity, then delegates to the identity-based markAsDetached.\n */\n findAndDetachByTabId(tabId: string): CachedComponentInfo | null {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n if (!entry) return null;\n\n const [_, info] = entry;\n return this.markAsDetached(info.resourceType, info.resourceRecordId, info.applicationId);\n }\n\n /**\n * Evict least-recently-used detached components when over the limit.\n * Only evicts components that are not currently attached.\n */\n private EvictIfNeeded(): void {\n if (ComponentCacheManager.MaxDetachedComponents <= 0) return;\n\n const detached = Array.from(this.cache.entries())\n .filter(([_, info]) => !info.isAttached)\n .sort((a, b) => a[1].lastUsed.getTime() - b[1].lastUsed.getTime());\n\n while (detached.length > ComponentCacheManager.MaxDetachedComponents) {\n const [key, info] = detached.shift()!;\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n }\n\n /**\n * Get component info by tab ID (for finding what's attached to a tab).\n * Uses linear scan since tabId is metadata, not a key.\n */\n getComponentByTabId(tabId: string): CachedComponentInfo | null {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n return entry ? entry[1] : null;\n }\n\n /**\n * Remove and destroy a specific component from cache by resource identity.\n */\n destroyComponent(resourceType: string, recordId: string, appId: string): void {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (!info) return;\n\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n\n /**\n * Remove and destroy component by tab ID (convenience for Golden Layout tab close).\n */\n destroyComponentByTabId(tabId: string): void {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n if (!entry) return;\n\n const [key, info] = entry;\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n\n /**\n * Clear the entire cache, destroying all components.\n * Call this on user logout or app shutdown.\n */\n clearCache(): void {\n this.cache.forEach(info => {\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n });\n this.cache.clear();\n }\n\n /**\n * Get cache statistics for debugging.\n */\n getCacheStats(): {\n total: number;\n attached: number;\n detached: number;\n byResourceType: Map<string, number>;\n } {\n const stats = {\n total: this.cache.size,\n attached: 0,\n detached: 0,\n byResourceType: new Map<string, number>()\n };\n\n this.cache.forEach(info => {\n if (info.isAttached) {\n stats.attached++;\n } else {\n stats.detached++;\n }\n\n const count = stats.byResourceType.get(info.resourceType) || 0;\n stats.byResourceType.set(info.resourceType, count + 1);\n });\n\n return stats;\n }\n}\n"]}
1
+ {"version":3,"file":"component-cache-manager.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { ComponentRef, ApplicationRef } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\n\n/**\n * Metadata about a cached component\n */\nexport interface CachedComponentInfo {\n // The Angular component reference\n componentRef: ComponentRef<BaseResourceComponent>;\n\n // The wrapper DOM element (for detaching/reattaching)\n wrapperElement: HTMLElement;\n\n // Resource identity (the ONLY key used for cache operations)\n resourceType: string;\n resourceRecordId: string;\n applicationId: string;\n\n // Usage tracking\n isAttached: boolean; // Currently attached to a tab/container?\n attachedToTabId: string | null; // Which tab is it attached to? (metadata only, NOT used for lookup)\n\n // Lifecycle tracking\n lastUsed: Date;\n createdAt: Date;\n\n // Resource data snapshot (for comparison)\n resourceData: ResourceData;\n\n // Saved query params from the tab config at detach time.\n // Restored to the tab config when the component is reattached,\n // so the URL reflects the component's preserved state.\n savedQueryParams?: Record<string, string>;\n\n // Agent context reported by this component via NavigationService.SetAgentContext()\n // Cached so it can be restored when the component becomes active again.\n AgentContext?: Record<string, unknown>;\n\n // Agent client tools registered by this component via NavigationService.SetAgentClientTools()\n // Cached so they can be re-registered when the component becomes active again.\n AgentClientTools?: { Name: string; Description: string; ParameterSchema: Record<string, unknown>; Handler: (params: Record<string, unknown>) => Promise<unknown> }[];\n}\n\n/**\n * Smart component cache manager that preserves component state across tab switches.\n *\n * ALL cache operations use a consistent identity key: `appId::resourceType::recordId`.\n * This key is the same regardless of whether the component is in Golden Layout (tabbed)\n * mode or Single Resource mode, ensuring components are reusable across both modes.\n *\n * The `attachedToTabId` field is metadata for debugging/display — it is NEVER used\n * as a lookup key. This prevents bugs where multiple resources sharing the same tab ID\n * (e.g., nav items within a single-resource app) interfere with each other's cache state.\n *\n * Features:\n * - Caches components by resource identity (appId + resourceType + recordId)\n * - Tracks component usage to prevent double-attachment\n * - Detaches/reattaches DOM elements without destroying Angular components\n * - LRU eviction when detached component count exceeds MaxDetachedComponents\n */\nexport class ComponentCacheManager {\n private cache = new Map<string, CachedComponentInfo>();\n\n /**\n * Maximum number of detached (not currently visible) components to keep\n * cached. When exceeded, least-recently-used detached components are\n * evicted. Set to 0 to disable eviction (legacy behavior). Default: 20.\n */\n public static MaxDetachedComponents: number = 20;\n\n constructor(private appRef: ApplicationRef) {}\n\n /**\n * Generate a unique cache key from resource identity.\n * This is the ONE canonical key format used by ALL cache operations.\n */\n private getCacheKey(resourceType: string, recordId: string, appId: string): string {\n const normalizedRecordId = recordId || '__no_record__';\n return `${appId}::${resourceType}::${normalizedRecordId}`;\n }\n\n /**\n * Check if a component exists in cache and is available for reuse.\n */\n hasAvailableComponent(resourceType: string, recordId: string, appId: string): boolean {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n return info !== undefined && !info.isAttached;\n }\n\n /**\n * Get a cached component if available (not currently attached).\n * Lookup is by resource identity, not tab ID.\n */\n getCachedComponent(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (!info) {\n return null;\n }\n\n // Can only reuse if not currently attached elsewhere\n if (info.isAttached) {\n return null;\n }\n\n return info;\n }\n\n /**\n * Store a component in the cache and mark as attached.\n */\n cacheComponent(\n componentRef: ComponentRef<BaseResourceComponent>,\n wrapperElement: HTMLElement,\n resourceData: ResourceData,\n tabId: string\n ): void {\n // Use driverClass (the actual component class name) as the resourceType for the cache key,\n // NOT resourceData.ResourceType (which is often just \"Custom\" for dashboard resources).\n // This must match the lookup key used in getCachedComponent/markAsAttached/markAsDetached.\n const resolvedResourceType = resourceData.Configuration?.resourceTypeDriverClass\n || resourceData.Configuration?.driverClass\n || resourceData.ResourceType;\n const key = this.getCacheKey(\n resolvedResourceType,\n resourceData.ResourceRecordID || '',\n resourceData.Configuration?.applicationId || ''\n );\n\n const info: CachedComponentInfo = {\n componentRef,\n wrapperElement,\n resourceType: resolvedResourceType,\n resourceRecordId: resourceData.ResourceRecordID || '',\n applicationId: resourceData.Configuration?.applicationId || '',\n isAttached: true,\n attachedToTabId: tabId,\n lastUsed: new Date(),\n createdAt: new Date(),\n resourceData\n };\n\n this.cache.set(key, info);\n }\n\n /**\n * Mark a component as attached. Lookup by resource identity.\n */\n markAsAttached(resourceType: string, recordId: string, appId: string, tabId: string): void {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (info) {\n info.isAttached = true;\n info.attachedToTabId = tabId;\n info.lastUsed = new Date();\n }\n }\n\n /**\n * Mark a component as detached (available for reuse). Lookup by resource identity.\n *\n * This is the ONLY way to detach a component. Both single-resource mode and\n * Golden Layout mode use this same method to ensure consistent cache behavior.\n */\n markAsDetached(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n if (!info) return null;\n\n info.isAttached = false;\n info.attachedToTabId = null;\n info.lastUsed = new Date();\n this.EvictIfNeeded();\n return info;\n }\n\n /**\n * Find a cached component by tab ID and detach it.\n * This is a convenience wrapper for callers that only know the tab ID\n * (e.g., Golden Layout tab close events). It resolves the tab ID to\n * resource identity, then delegates to the identity-based markAsDetached.\n */\n findAndDetachByTabId(tabId: string): CachedComponentInfo | null {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n if (!entry) return null;\n\n const [_, info] = entry;\n return this.markAsDetached(info.resourceType, info.resourceRecordId, info.applicationId);\n }\n\n /**\n * Evict least-recently-used detached components when over the limit.\n * Only evicts components that are not currently attached.\n */\n private EvictIfNeeded(): void {\n if (ComponentCacheManager.MaxDetachedComponents <= 0) return;\n\n const detached = Array.from(this.cache.entries())\n .filter(([_, info]) => !info.isAttached)\n .sort((a, b) => a[1].lastUsed.getTime() - b[1].lastUsed.getTime());\n\n while (detached.length > ComponentCacheManager.MaxDetachedComponents) {\n const [key, info] = detached.shift()!;\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n }\n\n /**\n * Get component info by tab ID (for finding what's attached to a tab).\n * Uses linear scan since tabId is metadata, not a key.\n */\n getComponentByTabId(tabId: string): CachedComponentInfo | null {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n return entry ? entry[1] : null;\n }\n\n /**\n * Remove and destroy a specific component from cache by resource identity.\n */\n destroyComponent(resourceType: string, recordId: string, appId: string): void {\n const key = this.getCacheKey(resourceType, recordId, appId);\n const info = this.cache.get(key);\n\n if (!info) return;\n\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n\n /**\n * Remove and destroy component by tab ID (convenience for Golden Layout tab close).\n */\n destroyComponentByTabId(tabId: string): void {\n const entry = Array.from(this.cache.entries())\n .find(([_, info]) => info.attachedToTabId === tabId);\n\n if (!entry) return;\n\n const [key, info] = entry;\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n this.cache.delete(key);\n }\n\n /**\n * Clear the entire cache, destroying all components.\n * Call this on user logout or app shutdown.\n */\n clearCache(): void {\n this.cache.forEach(info => {\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n });\n this.cache.clear();\n }\n\n /**\n * Selectively clear cached components matching a predicate.\n * Components that match are destroyed; those that don't are kept.\n *\n * Use this for tenant switching: clear org-scoped components while\n * keeping system/global components alive.\n *\n * @param predicate Return true for components that should be destroyed.\n * @returns Number of components destroyed.\n */\n ClearCacheByPredicate(predicate: (info: CachedComponentInfo) => boolean): number {\n let destroyed = 0;\n const toRemove: string[] = [];\n\n this.cache.forEach((info, key) => {\n if (predicate(info)) {\n this.appRef.detachView(info.componentRef.hostView);\n info.componentRef.destroy();\n toRemove.push(key);\n destroyed++;\n }\n });\n\n for (const key of toRemove) {\n this.cache.delete(key);\n }\n\n return destroyed;\n }\n\n /**\n * Get cache statistics for debugging.\n */\n getCacheStats(): {\n total: number;\n attached: number;\n detached: number;\n byResourceType: Map<string, number>;\n } {\n const stats = {\n total: this.cache.size,\n attached: 0,\n detached: 0,\n byResourceType: new Map<string, number>()\n };\n\n this.cache.forEach(info => {\n if (info.isAttached) {\n stats.attached++;\n } else {\n stats.detached++;\n }\n\n const count = stats.byResourceType.get(info.resourceType) || 0;\n stats.byResourceType.set(info.resourceType, count + 1);\n });\n\n return stats;\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { OnInit, OnDestroy, AfterViewInit, ElementRef, ApplicationRef, EnvironmentInjector, ChangeDetectorRef, EventEmitter } from '@angular/core';
2
2
  import { GoldenLayoutManager, WorkspaceStateManager, ApplicationManager } from '@memberjunction/ng-base-application';
3
+ import { CachedComponentInfo } from './component-cache-manager';
3
4
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
5
  import * as i0 from "@angular/core";
5
6
  /**
@@ -60,6 +61,31 @@ export declare class TabContainerComponent extends BaseAngularComponent implemen
60
61
  * @param forceCreateTabs - If true, always creates tabs fresh from config.tabs instead of restoring saved layout
61
62
  */
62
63
  private initializeGoldenLayout;
64
+ /**
65
+ * Clear cached components matching a predicate. Components that match are
66
+ * destroyed; others are kept. Use for tenant switching — clear org-scoped
67
+ * components while keeping system/global components alive.
68
+ *
69
+ * @param predicate Return true for components that should be destroyed.
70
+ * If omitted, clears ALL cached components.
71
+ * @returns Number of components destroyed.
72
+ */
73
+ ClearComponentCache(predicate?: (info: CachedComponentInfo) => boolean): number;
74
+ /**
75
+ * Destroy all cached components and reload open tabs.
76
+ *
77
+ * In single-resource mode: clears the signature to force a reload, then
78
+ * re-invokes loadSingleResourceContent().
79
+ *
80
+ * In multi-tab mode: destroys all cached components, marks all tabs as
81
+ * not-loaded, then reloads the currently active tab immediately. Other
82
+ * tabs reload lazily when the user switches to them (onTabShown fires
83
+ * with isFirstShow=true after MarkTabNotLoaded).
84
+ *
85
+ * Use this for tenant switching — tabs stay open but their components
86
+ * are recreated fresh with the new org context.
87
+ */
88
+ ReloadAllTabs(): Promise<void>;
63
89
  ngOnDestroy(): void;
64
90
  /**
65
91
  * Handle window resize events as a fallback safety mechanism.
@@ -1 +1 @@
1
- {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}