@memberjunction/ng-explorer-core 5.30.0 → 5.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-routing.module.d.ts +9 -0
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +13 -1
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +5 -3
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +2 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +12 -11
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/guards/entities.guard.d.ts +2 -1
- package/dist/lib/guards/entities.guard.d.ts.map +1 -1
- package/dist/lib/guards/entities.guard.js +14 -1
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +2 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +7 -6
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +2 -3
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +4 -4
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +1 -2
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +5 -5
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.d.ts +2 -2
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +8 -7
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts +9 -0
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +13 -1
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +2 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +7 -5
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +5 -2
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +43 -27
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +3 -2
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +8 -6
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +1 -2
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +2 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +18 -16
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +2 -1
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +7 -5
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +2 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +8 -6
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +2 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +9 -7
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.d.ts +2 -1
- package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +6 -5
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/package.json +42 -41
|
@@ -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 { 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} 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 <!-- 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 `]\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 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 // 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 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\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 * 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 = new Metadata();\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 = new RunView();\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 { 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} 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 <!-- 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 `]\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 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 // 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 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\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 * 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"]}
|
|
@@ -33,7 +33,7 @@ export declare class UserViewResource extends BaseResourceComponent {
|
|
|
33
33
|
configuredMapRenderMode: 'point' | 'choropleth' | 'heatmap';
|
|
34
34
|
isExporting: boolean;
|
|
35
35
|
private dataLoaded;
|
|
36
|
-
private metadata;
|
|
36
|
+
private get metadata();
|
|
37
37
|
constructor(cdr: ChangeDetectorRef, exportService: ExportService);
|
|
38
38
|
set Data(value: ResourceData);
|
|
39
39
|
get Data(): ResourceData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAY,MAAM,+BAA+B,CAAC;AAEjG,OAAO,EAA0B,UAAU,EAAW,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAmHa,gBAAiB,SAAQ,qBAAqB;
|
|
1
|
+
{"version":3,"file":"view-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAY,MAAM,+BAA+B,CAAC;AAEjG,OAAO,EAA0B,UAAU,EAAW,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAmHa,gBAAiB,SAAQ,qBAAqB;IAsBnD,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,aAAa;IAtBiB,gBAAgB,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC7D,eAAe,CAAC,EAAE,qBAAqB,CAAC;IAE5D,SAAS,EAAE,OAAO,CAAS;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IACrC,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAQ;IACnD,SAAS,EAAE,aAAa,GAAG,IAAI,CAAQ;IAE9C,uEAAuE;IAChE,kBAAkB,EAAE,cAAc,GAAG,IAAI,CAAQ;IAExD,mDAAmD;IAC5C,uBAAuB,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAAW;IAGtE,WAAW,EAAE,OAAO,CAAS;IAEpC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,KAAK,QAAQ,GAAiC;gBAEzC,GAAG,EAAE,iBAAiB,EACtB,aAAa,EAAE,aAAa;IAKxC,IAAa,IAAI,CAAC,KAAK,EAAE,YAAY,EAiCpC;IAED,IAAa,IAAI,IAAI,YAAY,CAEhC;IAED;;OAEG;YACW,QAAQ;IA2CtB;;OAEG;YACW,YAAY;IAmC1B;;OAEG;YACW,eAAe;IAiB7B;;OAEG;IACI,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAMrD;;OAEG;IACI,YAAY,IAAI,IAAI;IAI3B;;OAEG;IACY,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1E;;OAEG;IACY,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAOhC;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCtC;;OAEG;YACW,cAAc;IAyB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;yCA3Uf,gBAAgB;2CAAhB,gBAAgB;CAuV5B"}
|
|
@@ -8,7 +8,7 @@ import { Component, ViewChild } from '@angular/core';
|
|
|
8
8
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
9
9
|
import { ViewInfo } from '@memberjunction/core-entities';
|
|
10
10
|
import { RegisterClass, MJGlobal, MJEventType, UUIDsEqual } from '@memberjunction/global';
|
|
11
|
-
import { CompositeKey,
|
|
11
|
+
import { CompositeKey, RunView } from '@memberjunction/core';
|
|
12
12
|
import * as i0 from "@angular/core";
|
|
13
13
|
import * as i1 from "@memberjunction/ng-export-service";
|
|
14
14
|
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
@@ -114,7 +114,7 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
114
114
|
// Export state
|
|
115
115
|
isExporting = false;
|
|
116
116
|
dataLoaded = false;
|
|
117
|
-
metadata
|
|
117
|
+
get metadata() { return this.ProviderToUse; }
|
|
118
118
|
constructor(cdr, exportService) {
|
|
119
119
|
super();
|
|
120
120
|
this.cdr = cdr;
|
|
@@ -329,7 +329,7 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
329
329
|
if (!this.entityInfo) {
|
|
330
330
|
throw new Error('No entity selected for export');
|
|
331
331
|
}
|
|
332
|
-
const rv =
|
|
332
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
333
333
|
let filter = '';
|
|
334
334
|
if (this.viewEntity?.WhereClause) {
|
|
335
335
|
filter = this.viewEntity.WhereClause;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts","../../../src/lib/resource-wrappers/view-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJUserViewEntityExtended, ViewInfo } from '@memberjunction/core-entities';\nimport { RegisterClass, MJGlobal, MJEventType , UUIDsEqual } from '@memberjunction/global';\nimport { CompositeKey, Metadata, EntityInfo, RunView } from '@memberjunction/core';\nimport { RecordOpenedEvent, ViewGridState, EntityViewerComponent, EntityViewMode } from '@memberjunction/ng-entity-viewer';\nimport { ExportService } from '@memberjunction/ng-export-service';\nimport { ExportColumn } from '@memberjunction/export-engine';\n/**\n * UserViewResource - Resource wrapper for displaying User Views in tabs\n *\n * This component wraps the EntityViewerComponent to display view data.\n * It loads the view configuration and entity, then renders the data grid/cards.\n *\n * Key features:\n * - Loads view by ID from ResourceRecordID\n * - Supports dynamic views by entity name + extra filter\n * - Applies view's WhereClause, GridState, and SortState\n * - Opens records in new tabs via NavigationService\n */\n@RegisterClass(BaseResourceComponent, 'ViewResource')\n@Component({\n standalone: false,\n selector: 'mj-userview-resource',\n templateUrl: './view-resource.component.html',\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .view-resource-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .view-header {\n padding: 16px 20px 8px 20px;\n flex-shrink: 0;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n }\n .header-left {\n flex: 1;\n min-width: 0;\n }\n .header-right {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n }\n .view-title {\n margin: 0 0 4px 0;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--text-primary, #1a1a1a);\n }\n .view-description {\n margin: 0;\n font-size: 0.875rem;\n color: var(--text-secondary, #666);\n }\n .action-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n .action-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-default);\n }\n .action-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .action-button i {\n font-size: 0.875rem;\n }\n .create-button {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n }\n .create-button:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n }\n .export-button:hover:not(:disabled) {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n .view-loading-state,\n .view-error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 16px;\n }\n .view-error-state {\n color: var(--danger-color, #dc3545);\n }\n .view-error-state i {\n font-size: 2rem;\n }\n .view-error-state p {\n margin: 0;\n font-size: 1rem;\n }\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class UserViewResource extends BaseResourceComponent {\n @ViewChild('container', { static: true }) containerElement!: ElementRef<HTMLDivElement>;\n @ViewChild('entityViewer') entityViewerRef?: EntityViewerComponent;\n\n public isLoading: boolean = false;\n public errorMessage: string | null = null;\n public entityInfo: EntityInfo | null = null;\n public viewEntity: MJUserViewEntityExtended | null = null;\n public gridState: ViewGridState | null = null;\n\n /** View mode from dashboard configuration (grid/cards/timeline/map) */\n public configuredViewMode: EntityViewMode | null = null;\n\n /** Map render mode from dashboard configuration */\n public configuredMapRenderMode: 'point' | 'choropleth' | 'heatmap' = 'point';\n\n // Export state\n public isExporting: boolean = false;\n\n private dataLoaded = false;\n private metadata = new Metadata();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private exportService: ExportService\n ) {\n super();\n }\n\n override set Data(value: ResourceData) {\n const previousRecordId = super.Data?.ResourceRecordID;\n const previousEntity = super.Data?.Configuration?.Entity;\n super.Data = value;\n\n const newRecordId = value?.ResourceRecordID;\n const newEntity = value?.Configuration?.Entity;\n\n // Read view mode and map render mode from configuration if provided\n const viewMode = value?.Configuration?.['viewMode'] as string | undefined;\n if (viewMode && ['grid', 'cards', 'timeline', 'map'].includes(viewMode)) {\n this.configuredViewMode = viewMode as EntityViewMode;\n } else {\n this.configuredViewMode = null;\n }\n\n const mapMode = value?.Configuration?.['mapRenderMode'] as string | undefined;\n if (mapMode && ['point', 'choropleth', 'heatmap'].includes(mapMode)) {\n this.configuredMapRenderMode = mapMode as 'point' | 'choropleth' | 'heatmap';\n } else {\n this.configuredMapRenderMode = 'point';\n }\n\n // Load on first set, or when the view/entity has changed\n if (!this.dataLoaded || newRecordId !== previousRecordId || newEntity !== previousEntity) {\n this.dataLoaded = true;\n // Reset state before loading new view\n this.entityInfo = null;\n this.viewEntity = null;\n this.gridState = null;\n this.errorMessage = null;\n this.loadView();\n }\n }\n\n override get Data(): ResourceData {\n return super.Data;\n }\n\n /**\n * Load the view and entity based on ResourceData\n */\n private async loadView(): Promise<void> {\n const data = this.Data;\n\n if (!data) {\n this.NotifyLoadComplete();\n return;\n }\n\n this.isLoading = true;\n this.errorMessage = null;\n this.NotifyLoadStarted();\n this.cdr.detectChanges();\n\n try {\n // Case 1: Load view by ID\n if (data.ResourceRecordID) {\n await this.loadViewById(data.ResourceRecordID);\n }\n // Case 2: Load dynamic view by entity name\n else if (data.Configuration?.Entity) {\n await this.loadDynamicView(\n data.Configuration.Entity as string,\n data.Configuration.ExtraFilter as string | undefined\n );\n }\n else {\n this.errorMessage = 'No view ID or entity specified';\n }\n } catch (error) {\n console.error('Error loading view:', error);\n this.errorMessage = error instanceof Error ? error.message : 'Failed to load view';\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n\n // If there was an error, notify load complete now\n if (this.errorMessage) {\n this.NotifyLoadComplete();\n }\n // Otherwise, wait for dataLoaded event from entity-viewer\n }\n }\n\n /**\n * Load a saved view by its ID\n */\n private async loadViewById(viewId: string): Promise<void> {\n // Load the view entity\n const view = await ViewInfo.GetViewEntity(viewId);\n\n if (!view) {\n throw new Error(`View with ID ${viewId} not found`);\n }\n\n this.viewEntity = view as MJUserViewEntityExtended;\n\n // Check permissions\n if (!this.viewEntity.UserCanView) {\n throw new Error('You do not have permission to view this view');\n }\n\n // Load the entity info\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, this.viewEntity!.EntityID));\n\n if (!entity) {\n throw new Error(`Entity for view not found`);\n }\n\n this.entityInfo = entity;\n\n // Parse grid state if available\n if (this.viewEntity.GridState) {\n try {\n this.gridState = JSON.parse(this.viewEntity.GridState) as ViewGridState;\n } catch (e) {\n console.warn('Failed to parse GridState:', e);\n this.gridState = null;\n }\n }\n }\n\n /**\n * Load a dynamic view (no saved view, just entity + filter)\n */\n private async loadDynamicView(entityName: string, _extraFilter?: string): Promise<void> {\n const entity = this.metadata.Entities.find(\n e => e.Name.trim().toLowerCase() === entityName.trim().toLowerCase()\n );\n\n if (!entity) {\n throw new Error(`Entity '${entityName}' not found`);\n }\n\n this.entityInfo = entity;\n this.viewEntity = null;\n this.gridState = null;\n\n // For dynamic views, we could create a synthetic viewEntity with just the WhereClause\n // but for now, we'll rely on the entity-viewer's default behavior\n }\n\n /**\n * Handle record opened event - open in new tab\n */\n public onRecordOpened(event: RecordOpenedEvent): void {\n if (event && event.entity && event.compositeKey) {\n this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);\n }\n }\n\n /**\n * Handle data loaded event from entity-viewer\n */\n public onDataLoaded(): void {\n this.NotifyLoadComplete();\n }\n\n /**\n * Get display name for the resource tab\n */\n override async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (data.ResourceRecordID) {\n const compositeKey = new CompositeKey([{ FieldName: 'ID', Value: data.ResourceRecordID }]);\n const name = await this.metadata.GetEntityRecordName('MJ: User Views', compositeKey);\n return name ? name : `View: ${data.ResourceRecordID}`;\n }\n else if (data.Configuration?.Entity) {\n const entityName = data.Configuration.Entity as string;\n const hasFilter = data.Configuration.ExtraFilter;\n return `${entityName} [Dynamic${hasFilter ? ' - Filtered' : ' - All'}]`;\n }\n return 'User Views [Error]';\n }\n\n /**\n * Get icon class for the resource tab\n */\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-table-list';\n }\n\n /**\n * Handle creating a new record for the current entity\n */\n public onCreateNewRecord(): void {\n if (!this.entityInfo) return;\n\n // Use NavigationService to open a new record form\n this.navigationService.OpenNewEntityRecord(this.entityInfo.Name);\n }\n\n /**\n * Handle export to Excel request\n */\n public async onExport(): Promise<void> {\n if (!this.entityInfo) {\n console.error('Cannot export: entity not available');\n return;\n }\n\n this.isExporting = true;\n this.cdr.detectChanges();\n\n try {\n this.showNotification('Working on the export, will notify you when it is complete...', 'info', 2000);\n\n const rows = await this.loadExportRows();\n const columns = this.buildExportColumns();\n const fileName = this.buildExportFileName();\n\n const result = await this.exportService.toExcel(rows, {\n fileName,\n columns,\n includeHeaders: true\n });\n\n if (result.success) {\n this.exportService.downloadResult(result);\n this.showNotification('Excel Export Complete', 'success', 2000);\n } else {\n this.showNotification('Export failed', 'error', 5000);\n }\n }\n catch (e) {\n this.showNotification('Error exporting data', 'error', 5000);\n console.error('Export error:', e);\n }\n finally {\n this.isExporting = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Load all records for the current view/entity for export\n */\n private async loadExportRows(): Promise<Record<string, unknown>[]> {\n if (!this.entityInfo) {\n throw new Error('No entity selected for export');\n }\n\n const rv = new RunView();\n let filter = '';\n if (this.viewEntity?.WhereClause) {\n filter = this.viewEntity.WhereClause;\n }\n\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: this.entityInfo.Name,\n ExtraFilter: filter,\n OrderBy: '',\n ResultType: 'simple'\n });\n\n if (!result.Success) {\n throw new Error(result.ErrorMessage || 'Failed to load data for export');\n }\n\n return result.Results || [];\n }\n\n /**\n * Determine which columns to export based on grid state, view entity, or entity fields\n */\n private buildExportColumns(): ExportColumn[] {\n if (!this.entityInfo) return [];\n\n if (this.gridState?.columnSettings && this.gridState.columnSettings.length > 0) {\n const visibleColumns = this.gridState.columnSettings.filter(col => col.hidden !== true);\n return visibleColumns.map(col => ({\n name: col.Name,\n displayName: col.DisplayName || col.Name\n }));\n }\n\n if (this.viewEntity?.Columns) {\n const visibleColumns = this.viewEntity.Columns.filter(col => !col.hidden);\n return visibleColumns.map(col => ({\n name: col.Name,\n displayName: col.DisplayName || col.Name\n }));\n }\n\n const visibleFields = this.entityInfo.Fields.filter(f => !f.IsVirtual);\n return visibleFields.map(f => ({\n name: f.Name,\n displayName: f.DisplayNameOrName\n }));\n }\n\n /**\n * Build the export file name based on entity and view\n */\n private buildExportFileName(): string {\n const viewName = this.viewEntity?.Name || 'Data';\n return `${this.entityInfo!.Name}_${viewName}_${new Date().toISOString().split('T')[0]}`;\n }\n\n /**\n * Show a notification to the user\n */\n private showNotification(message: string, style: 'info' | 'success' | 'error' | 'warning', duration: number): void {\n MJGlobal.Instance.RaiseEvent({\n component: this,\n event: MJEventType.DisplaySimpleNotificationRequest,\n eventCode: '',\n args: {\n message,\n style,\n DisplayDuration: duration\n }\n });\n }\n}\n","<div #container class=\"view-resource-container\">\n @if (isLoading) {\n <div class=\"view-loading-state\">\n <mj-loading text=\"Loading view...\" size=\"large\"></mj-loading>\n </div>\n } @else if (errorMessage) {\n <div class=\"view-error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <p>{{ errorMessage }}</p>\n </div>\n } @else if (entityInfo) {\n <!-- Header with title and action buttons -->\n <div class=\"view-header\">\n <div class=\"header-left\">\n <h2 class=\"view-title\">{{ viewEntity?.Name || entityInfo.Name }}</h2>\n @if (viewEntity?.Description) {\n <p class=\"view-description\">{{ viewEntity!.Description }}</p>\n }\n </div>\n <div class=\"header-right\">\n <!-- Create New Record Button -->\n <button\n class=\"action-button create-button\"\n (click)=\"onCreateNewRecord()\"\n title=\"Create new {{ entityInfo.Name }} record\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Record</span>\n </button>\n\n <!-- Export Button -->\n <button\n class=\"action-button export-button\"\n (click)=\"onExport()\"\n [disabled]=\"isExporting\"\n title=\"Export to Excel\">\n @if (isExporting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-file-excel\"></i>\n }\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </button>\n </div>\n </div>\n\n <!-- Entity Viewer -->\n <mj-entity-viewer\n #entityViewer\n [entity]=\"entityInfo\"\n [viewEntity]=\"viewEntity\"\n [gridState]=\"gridState\"\n [viewMode]=\"configuredViewMode\"\n [mapRenderMode]=\"configuredMapRenderMode\"\n (recordOpened)=\"onRecordOpened($any($event))\"\n (dataLoaded)=\"onDataLoaded()\">\n </mj-entity-viewer>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"view-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts","../../../src/lib/resource-wrappers/view-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJUserViewEntityExtended, ViewInfo } from '@memberjunction/core-entities';\nimport { RegisterClass, MJGlobal, MJEventType , UUIDsEqual } from '@memberjunction/global';\nimport { CompositeKey, Metadata, EntityInfo, RunView } from '@memberjunction/core';\nimport { RecordOpenedEvent, ViewGridState, EntityViewerComponent, EntityViewMode } from '@memberjunction/ng-entity-viewer';\nimport { ExportService } from '@memberjunction/ng-export-service';\nimport { ExportColumn } from '@memberjunction/export-engine';\n/**\n * UserViewResource - Resource wrapper for displaying User Views in tabs\n *\n * This component wraps the EntityViewerComponent to display view data.\n * It loads the view configuration and entity, then renders the data grid/cards.\n *\n * Key features:\n * - Loads view by ID from ResourceRecordID\n * - Supports dynamic views by entity name + extra filter\n * - Applies view's WhereClause, GridState, and SortState\n * - Opens records in new tabs via NavigationService\n */\n@RegisterClass(BaseResourceComponent, 'ViewResource')\n@Component({\n standalone: false,\n selector: 'mj-userview-resource',\n templateUrl: './view-resource.component.html',\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .view-resource-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .view-header {\n padding: 16px 20px 8px 20px;\n flex-shrink: 0;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n }\n .header-left {\n flex: 1;\n min-width: 0;\n }\n .header-right {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n }\n .view-title {\n margin: 0 0 4px 0;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--text-primary, #1a1a1a);\n }\n .view-description {\n margin: 0;\n font-size: 0.875rem;\n color: var(--text-secondary, #666);\n }\n .action-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n .action-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-default);\n }\n .action-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .action-button i {\n font-size: 0.875rem;\n }\n .create-button {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n }\n .create-button:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n }\n .export-button:hover:not(:disabled) {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n .view-loading-state,\n .view-error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 16px;\n }\n .view-error-state {\n color: var(--danger-color, #dc3545);\n }\n .view-error-state i {\n font-size: 2rem;\n }\n .view-error-state p {\n margin: 0;\n font-size: 1rem;\n }\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class UserViewResource extends BaseResourceComponent {\n @ViewChild('container', { static: true }) containerElement!: ElementRef<HTMLDivElement>;\n @ViewChild('entityViewer') entityViewerRef?: EntityViewerComponent;\n\n public isLoading: boolean = false;\n public errorMessage: string | null = null;\n public entityInfo: EntityInfo | null = null;\n public viewEntity: MJUserViewEntityExtended | null = null;\n public gridState: ViewGridState | null = null;\n\n /** View mode from dashboard configuration (grid/cards/timeline/map) */\n public configuredViewMode: EntityViewMode | null = null;\n\n /** Map render mode from dashboard configuration */\n public configuredMapRenderMode: 'point' | 'choropleth' | 'heatmap' = 'point';\n\n // Export state\n public isExporting: boolean = false;\n\n private dataLoaded = false;\n private get metadata() { return this.ProviderToUse; }\n constructor(\n private cdr: ChangeDetectorRef,\n private exportService: ExportService\n ) {\n super();\n }\n\n override set Data(value: ResourceData) {\n const previousRecordId = super.Data?.ResourceRecordID;\n const previousEntity = super.Data?.Configuration?.Entity;\n super.Data = value;\n\n const newRecordId = value?.ResourceRecordID;\n const newEntity = value?.Configuration?.Entity;\n\n // Read view mode and map render mode from configuration if provided\n const viewMode = value?.Configuration?.['viewMode'] as string | undefined;\n if (viewMode && ['grid', 'cards', 'timeline', 'map'].includes(viewMode)) {\n this.configuredViewMode = viewMode as EntityViewMode;\n } else {\n this.configuredViewMode = null;\n }\n\n const mapMode = value?.Configuration?.['mapRenderMode'] as string | undefined;\n if (mapMode && ['point', 'choropleth', 'heatmap'].includes(mapMode)) {\n this.configuredMapRenderMode = mapMode as 'point' | 'choropleth' | 'heatmap';\n } else {\n this.configuredMapRenderMode = 'point';\n }\n\n // Load on first set, or when the view/entity has changed\n if (!this.dataLoaded || newRecordId !== previousRecordId || newEntity !== previousEntity) {\n this.dataLoaded = true;\n // Reset state before loading new view\n this.entityInfo = null;\n this.viewEntity = null;\n this.gridState = null;\n this.errorMessage = null;\n this.loadView();\n }\n }\n\n override get Data(): ResourceData {\n return super.Data;\n }\n\n /**\n * Load the view and entity based on ResourceData\n */\n private async loadView(): Promise<void> {\n const data = this.Data;\n\n if (!data) {\n this.NotifyLoadComplete();\n return;\n }\n\n this.isLoading = true;\n this.errorMessage = null;\n this.NotifyLoadStarted();\n this.cdr.detectChanges();\n\n try {\n // Case 1: Load view by ID\n if (data.ResourceRecordID) {\n await this.loadViewById(data.ResourceRecordID);\n }\n // Case 2: Load dynamic view by entity name\n else if (data.Configuration?.Entity) {\n await this.loadDynamicView(\n data.Configuration.Entity as string,\n data.Configuration.ExtraFilter as string | undefined\n );\n }\n else {\n this.errorMessage = 'No view ID or entity specified';\n }\n } catch (error) {\n console.error('Error loading view:', error);\n this.errorMessage = error instanceof Error ? error.message : 'Failed to load view';\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n\n // If there was an error, notify load complete now\n if (this.errorMessage) {\n this.NotifyLoadComplete();\n }\n // Otherwise, wait for dataLoaded event from entity-viewer\n }\n }\n\n /**\n * Load a saved view by its ID\n */\n private async loadViewById(viewId: string): Promise<void> {\n // Load the view entity\n const view = await ViewInfo.GetViewEntity(viewId);\n\n if (!view) {\n throw new Error(`View with ID ${viewId} not found`);\n }\n\n this.viewEntity = view as MJUserViewEntityExtended;\n\n // Check permissions\n if (!this.viewEntity.UserCanView) {\n throw new Error('You do not have permission to view this view');\n }\n\n // Load the entity info\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, this.viewEntity!.EntityID));\n\n if (!entity) {\n throw new Error(`Entity for view not found`);\n }\n\n this.entityInfo = entity;\n\n // Parse grid state if available\n if (this.viewEntity.GridState) {\n try {\n this.gridState = JSON.parse(this.viewEntity.GridState) as ViewGridState;\n } catch (e) {\n console.warn('Failed to parse GridState:', e);\n this.gridState = null;\n }\n }\n }\n\n /**\n * Load a dynamic view (no saved view, just entity + filter)\n */\n private async loadDynamicView(entityName: string, _extraFilter?: string): Promise<void> {\n const entity = this.metadata.Entities.find(\n e => e.Name.trim().toLowerCase() === entityName.trim().toLowerCase()\n );\n\n if (!entity) {\n throw new Error(`Entity '${entityName}' not found`);\n }\n\n this.entityInfo = entity;\n this.viewEntity = null;\n this.gridState = null;\n\n // For dynamic views, we could create a synthetic viewEntity with just the WhereClause\n // but for now, we'll rely on the entity-viewer's default behavior\n }\n\n /**\n * Handle record opened event - open in new tab\n */\n public onRecordOpened(event: RecordOpenedEvent): void {\n if (event && event.entity && event.compositeKey) {\n this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);\n }\n }\n\n /**\n * Handle data loaded event from entity-viewer\n */\n public onDataLoaded(): void {\n this.NotifyLoadComplete();\n }\n\n /**\n * Get display name for the resource tab\n */\n override async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (data.ResourceRecordID) {\n const compositeKey = new CompositeKey([{ FieldName: 'ID', Value: data.ResourceRecordID }]);\n const name = await this.metadata.GetEntityRecordName('MJ: User Views', compositeKey);\n return name ? name : `View: ${data.ResourceRecordID}`;\n }\n else if (data.Configuration?.Entity) {\n const entityName = data.Configuration.Entity as string;\n const hasFilter = data.Configuration.ExtraFilter;\n return `${entityName} [Dynamic${hasFilter ? ' - Filtered' : ' - All'}]`;\n }\n return 'User Views [Error]';\n }\n\n /**\n * Get icon class for the resource tab\n */\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-table-list';\n }\n\n /**\n * Handle creating a new record for the current entity\n */\n public onCreateNewRecord(): void {\n if (!this.entityInfo) return;\n\n // Use NavigationService to open a new record form\n this.navigationService.OpenNewEntityRecord(this.entityInfo.Name);\n }\n\n /**\n * Handle export to Excel request\n */\n public async onExport(): Promise<void> {\n if (!this.entityInfo) {\n console.error('Cannot export: entity not available');\n return;\n }\n\n this.isExporting = true;\n this.cdr.detectChanges();\n\n try {\n this.showNotification('Working on the export, will notify you when it is complete...', 'info', 2000);\n\n const rows = await this.loadExportRows();\n const columns = this.buildExportColumns();\n const fileName = this.buildExportFileName();\n\n const result = await this.exportService.toExcel(rows, {\n fileName,\n columns,\n includeHeaders: true\n });\n\n if (result.success) {\n this.exportService.downloadResult(result);\n this.showNotification('Excel Export Complete', 'success', 2000);\n } else {\n this.showNotification('Export failed', 'error', 5000);\n }\n }\n catch (e) {\n this.showNotification('Error exporting data', 'error', 5000);\n console.error('Export error:', e);\n }\n finally {\n this.isExporting = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Load all records for the current view/entity for export\n */\n private async loadExportRows(): Promise<Record<string, unknown>[]> {\n if (!this.entityInfo) {\n throw new Error('No entity selected for export');\n }\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n let filter = '';\n if (this.viewEntity?.WhereClause) {\n filter = this.viewEntity.WhereClause;\n }\n\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: this.entityInfo.Name,\n ExtraFilter: filter,\n OrderBy: '',\n ResultType: 'simple'\n });\n\n if (!result.Success) {\n throw new Error(result.ErrorMessage || 'Failed to load data for export');\n }\n\n return result.Results || [];\n }\n\n /**\n * Determine which columns to export based on grid state, view entity, or entity fields\n */\n private buildExportColumns(): ExportColumn[] {\n if (!this.entityInfo) return [];\n\n if (this.gridState?.columnSettings && this.gridState.columnSettings.length > 0) {\n const visibleColumns = this.gridState.columnSettings.filter(col => col.hidden !== true);\n return visibleColumns.map(col => ({\n name: col.Name,\n displayName: col.DisplayName || col.Name\n }));\n }\n\n if (this.viewEntity?.Columns) {\n const visibleColumns = this.viewEntity.Columns.filter(col => !col.hidden);\n return visibleColumns.map(col => ({\n name: col.Name,\n displayName: col.DisplayName || col.Name\n }));\n }\n\n const visibleFields = this.entityInfo.Fields.filter(f => !f.IsVirtual);\n return visibleFields.map(f => ({\n name: f.Name,\n displayName: f.DisplayNameOrName\n }));\n }\n\n /**\n * Build the export file name based on entity and view\n */\n private buildExportFileName(): string {\n const viewName = this.viewEntity?.Name || 'Data';\n return `${this.entityInfo!.Name}_${viewName}_${new Date().toISOString().split('T')[0]}`;\n }\n\n /**\n * Show a notification to the user\n */\n private showNotification(message: string, style: 'info' | 'success' | 'error' | 'warning', duration: number): void {\n MJGlobal.Instance.RaiseEvent({\n component: this,\n event: MJEventType.DisplaySimpleNotificationRequest,\n eventCode: '',\n args: {\n message,\n style,\n DisplayDuration: duration\n }\n });\n }\n}\n","<div #container class=\"view-resource-container\">\n @if (isLoading) {\n <div class=\"view-loading-state\">\n <mj-loading text=\"Loading view...\" size=\"large\"></mj-loading>\n </div>\n } @else if (errorMessage) {\n <div class=\"view-error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <p>{{ errorMessage }}</p>\n </div>\n } @else if (entityInfo) {\n <!-- Header with title and action buttons -->\n <div class=\"view-header\">\n <div class=\"header-left\">\n <h2 class=\"view-title\">{{ viewEntity?.Name || entityInfo.Name }}</h2>\n @if (viewEntity?.Description) {\n <p class=\"view-description\">{{ viewEntity!.Description }}</p>\n }\n </div>\n <div class=\"header-right\">\n <!-- Create New Record Button -->\n <button\n class=\"action-button create-button\"\n (click)=\"onCreateNewRecord()\"\n title=\"Create new {{ entityInfo.Name }} record\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Record</span>\n </button>\n\n <!-- Export Button -->\n <button\n class=\"action-button export-button\"\n (click)=\"onExport()\"\n [disabled]=\"isExporting\"\n title=\"Export to Excel\">\n @if (isExporting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-file-excel\"></i>\n }\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </button>\n </div>\n </div>\n\n <!-- Entity Viewer -->\n <mj-entity-viewer\n #entityViewer\n [entity]=\"entityInfo\"\n [viewEntity]=\"viewEntity\"\n [gridState]=\"gridState\"\n [viewMode]=\"configuredViewMode\"\n [mapRenderMode]=\"configuredMapRenderMode\"\n (recordOpened)=\"onRecordOpened($any($event))\"\n (dataLoaded)=\"onDataLoaded()\">\n </mj-entity-viewer>\n }\n</div>\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IMetadataProvider } from '@memberjunction/core';
|
|
1
2
|
import { SystemValidationService } from './system-validation.service';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
/**
|
|
@@ -6,6 +7,14 @@ import * as i0 from "@angular/core";
|
|
|
6
7
|
export declare class StartupValidationService {
|
|
7
8
|
private validationService;
|
|
8
9
|
constructor(validationService: SystemValidationService);
|
|
10
|
+
/**
|
|
11
|
+
* Optional explicit metadata provider. Set via `setProvider()` from a caller
|
|
12
|
+
* with provider context (e.g. the shell). Falls back to `Metadata.Provider`
|
|
13
|
+
* when not set, which is fine for single-provider apps.
|
|
14
|
+
*/
|
|
15
|
+
private _provider;
|
|
16
|
+
set Provider(value: IMetadataProvider | null);
|
|
17
|
+
get Provider(): IMetadataProvider;
|
|
9
18
|
/**
|
|
10
19
|
* Runs all validation checks
|
|
11
20
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-validation.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"startup-validation.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;;AAEtE;;GAEG;AACH,qBAGa,wBAAwB;IACvB,OAAO,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,uBAAuB;IAE9D;;;;OAIG;IACH,OAAO,CAAC,SAAS,CAAkC;IAEnD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;IAED,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IAED;;OAEG;IACI,mBAAmB,IAAI,IAAI;IAKlC;;;OAGG;IACI,yBAAyB,IAAI,IAAI;IAUxC;;OAEG;IACH,OAAO,CAAC,iBAAiB;yCA3Cd,wBAAwB;6CAAxB,wBAAwB;CAiFpC"}
|
|
@@ -10,6 +10,18 @@ export class StartupValidationService {
|
|
|
10
10
|
constructor(validationService) {
|
|
11
11
|
this.validationService = validationService;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Optional explicit metadata provider. Set via `setProvider()` from a caller
|
|
15
|
+
* with provider context (e.g. the shell). Falls back to `Metadata.Provider`
|
|
16
|
+
* when not set, which is fine for single-provider apps.
|
|
17
|
+
*/
|
|
18
|
+
_provider = null;
|
|
19
|
+
set Provider(value) {
|
|
20
|
+
this._provider = value;
|
|
21
|
+
}
|
|
22
|
+
get Provider() {
|
|
23
|
+
return this._provider ?? Metadata.Provider;
|
|
24
|
+
}
|
|
13
25
|
/**
|
|
14
26
|
* Runs all validation checks
|
|
15
27
|
*/
|
|
@@ -35,7 +47,7 @@ export class StartupValidationService {
|
|
|
35
47
|
*/
|
|
36
48
|
validateUserRoles() {
|
|
37
49
|
try {
|
|
38
|
-
const md =
|
|
50
|
+
const md = this.Provider;
|
|
39
51
|
const currentUser = md.CurrentUser;
|
|
40
52
|
if (!currentUser) {
|
|
41
53
|
console.log('StartupValidationService: No current user found');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-validation.service.js","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"startup-validation.service.js","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAA+B,MAAM,sBAAsB,CAAC;;;AAG7E;;GAEG;AAIH,MAAM,OAAO,wBAAwB;IACf;IAApB,YAAoB,iBAA0C;QAA1C,sBAAiB,GAAjB,iBAAiB,CAAyB;IAAI,CAAC;IAEnE;;;;OAIG;IACK,SAAS,GAA6B,IAAI,CAAC;IAEnD,IAAW,QAAQ,CAAC,KAA+B;QAC/C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,mBAAmB;QACxB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,4CAA4C;IAC9C,CAAC;IAED;;;OAGG;IACI,yBAAyB;QAC9B,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YAC9B,EAAE,EAAE,eAAe;YACnB,OAAO,EAAE,gDAAgD;YACzD,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,kKAAkK;YAC3K,IAAI,EAAE,mIAAmI;SAC1I,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YACzB,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;YAEnC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;gBAC/D,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;oBAC9B,EAAE,EAAE,gBAAgB;oBACpB,OAAO,EAAE,wBAAwB;oBACjC,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,qDAAqD;oBAC9D,IAAI,EAAE,8EAA8E;iBACrF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjE,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC;gBACtF,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;oBAC9B,EAAE,EAAE,eAAe;oBACnB,OAAO,EAAE,mCAAmC;oBAC5C,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,8GAA8G;oBACvH,IAAI,EAAE,uFAAuF;iBAC9F,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6DAA6D,EAAE,GAAG,CAAC,CAAC;YAClF,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;gBAC9B,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,4BAA4B;gBACrC,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,mDAAmD;gBAC5D,IAAI,EAAE,sFAAsF;aAC7F,CAAC,CAAC;QACL,CAAC;IACH,CAAC;kHAhFU,wBAAwB;gEAAxB,wBAAwB,WAAxB,wBAAwB,mBAFvB,MAAM;;iFAEP,wBAAwB;cAHpC,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Metadata, UserInfo, IMetadataProvider } from '@memberjunction/core';\nimport { SystemValidationService } from './system-validation.service';\n\n/**\n * Service that performs validation checks during application startup\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class StartupValidationService {\n constructor(private validationService: SystemValidationService) { }\n\n /**\n * Optional explicit metadata provider. Set via `setProvider()` from a caller\n * with provider context (e.g. the shell). Falls back to `Metadata.Provider`\n * when not set, which is fine for single-provider apps.\n */\n private _provider: IMetadataProvider | null = null;\n\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n \n /**\n * Runs all validation checks\n */\n public validateSystemSetup(): void {\n this.validateUserRoles();\n // Add more validation checks here as needed\n }\n \n /**\n * Directly adds a validation issue for no user roles\n * This is used when we detect the missing roles error during GraphQL setup\n */\n public addNoRolesValidationIssue(): void {\n this.validationService.addIssue({\n id: 'no-user-roles',\n message: 'Missing User Roles - Cannot Access Application',\n severity: 'error',\n details: 'Your account does not have any roles assigned, which is required to use the application. This is preventing the system from loading core resources and metadata.',\n help: 'Please contact your system administrator to have appropriate roles assigned to your account. At minimum, a \"UI\" role is required.'\n });\n }\n\n /**\n * Validates that the current user has at least one role assigned\n */\n private validateUserRoles(): void {\n try {\n const md = this.Provider;\n const currentUser = md.CurrentUser;\n \n if (!currentUser) {\n console.log('StartupValidationService: No current user found');\n this.validationService.addIssue({\n id: 'user-not-found',\n message: 'User account not found',\n severity: 'error',\n details: 'Your user account could not be found in the system.',\n help: 'Contact your system administrator to ensure your account is properly set up.'\n });\n return;\n }\n \n if (!currentUser.UserRoles || currentUser.UserRoles.length === 0) {\n console.log('StartupValidationService: No user roles found, adding validation issue');\n this.validationService.addIssue({\n id: 'no-user-roles',\n message: 'No roles assigned to your account',\n severity: 'error',\n details: 'Your user account does not have any roles assigned. This will prevent you from accessing most functionality.',\n help: 'Contact your system administrator to have appropriate roles assigned to your account.'\n });\n }\n } catch (err) {\n console.error('StartupValidationService: Error during user role validation', err);\n this.validationService.addIssue({\n id: 'user-roles-check-failed',\n message: 'Failed to check user roles',\n severity: 'error',\n details: 'An error occurred while checking your user roles.',\n help: 'Try refreshing the page. If the problem persists, contact your system administrator.'\n });\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 { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
/**
|
|
5
6
|
* Container for Golden Layout tabs with app-colored styling.
|
|
@@ -11,7 +12,7 @@ import * as i0 from "@angular/core";
|
|
|
11
12
|
* - Context menu for pin/close
|
|
12
13
|
* - Layout persistence
|
|
13
14
|
*/
|
|
14
|
-
export declare class TabContainerComponent implements OnInit, OnDestroy, AfterViewInit {
|
|
15
|
+
export declare class TabContainerComponent extends BaseAngularComponent implements OnInit, OnDestroy, AfterViewInit {
|
|
15
16
|
private layoutManager;
|
|
16
17
|
private workspaceManager;
|
|
17
18
|
private appManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,SAAS,EACT,aAAa,EAEb,UAAU,EACV,cAAc,EACd,mBAAmB,EAInB,iBAAiB,EAGjB,YAAY,EAEb,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAKnB,MAAM,qCAAqC,CAAC;;
|
|
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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"}
|