@memberjunction/ng-explorer-core 5.23.0 → 5.25.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.map +1 -1
- package/dist/app-routing.module.js +15 -22
- 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 +6 -4
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +1 -0
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +16 -17
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +56 -62
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +2 -4
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +9 -13
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +2 -15
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +18 -52
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +2 -3
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +7 -9
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.d.ts +3 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +4 -0
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/notifications-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/notifications-resource.component.js +2 -0
- package/dist/lib/resource-wrappers/notifications-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +1 -0
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +74 -4
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +786 -25
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +7 -4
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +30 -14
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +0 -3
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +7 -0
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -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 +10 -4
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +28 -8
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +416 -219
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/shell/shell.module.d.ts +2 -1
- package/dist/lib/shell/shell.module.d.ts.map +1 -1
- package/dist/lib/shell/shell.module.js +7 -3
- package/dist/lib/shell/shell.module.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +6 -0
- 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 +63 -38
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +1 -0
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/user-menu/base-user-menu.d.ts +7 -7
- package/dist/lib/user-menu/base-user-menu.d.ts.map +1 -1
- package/dist/lib/user-menu/base-user-menu.js +8 -1
- package/dist/lib/user-menu/base-user-menu.js.map +1 -1
- package/dist/lib/user-menu/user-menu.types.d.ts +15 -0
- package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
- package/dist/lib/user-menu/user-menu.types.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +6 -3
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +46 -19
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/module.d.ts +53 -52
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +11 -7
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +0 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +0 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +40 -37
- package/dist/lib/generic/form-toolbar.d.ts +0 -8
- package/dist/lib/generic/form-toolbar.d.ts.map +0 -1
- package/dist/lib/generic/form-toolbar.js +0 -114
- package/dist/lib/generic/form-toolbar.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-results-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/search-results-resource.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;;;AAOzC,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,qBAAqB;IAC5D,QAAQ;IAER,CAAC;IACD,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC3C,OAAO,WAAW,IAAI,CAAC,aAAa,CAAC,MAAM,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;IACtF,CAAC;IACD,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QACzC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAC,CAAC;YAC5B,OAAO,EAAE,CAAA;QACb,CAAC;aACI,CAAC;YACF,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YAChH,IAAI,CAAC;gBACD,OAAO,CAAC,EAAE,IAAI,CAAC;;gBAEf,OAAO,EAAE,CAAC;QAClB,CAAC;IACL,CAAC;iQAnBQ,qBAAqB,yBAArB,qBAAqB;6DAArB,qBAAqB;YAFnB,kDAAuL;YAApC,AAAtC,iIAAgB,wBAAoB,IAAC,kHAAgB,uBAAmB,IAAC;YAAC,iBAA0B;;YAAnJ,AAArC,sDAAoC,mDAA+C;;;AAE9G,qBAAqB;IANjC,aAAa,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;GAMjD,qBAAqB,CAoBjC;;iFApBY,qBAAqB;cALjC,SAAS;eAAC;gBACT,UAAU,EAAE,KAAK;gBACf,QAAQ,EAAE,4BAA4B;gBACtC,QAAQ,EAAE,mNAAmN;aAChO;;kFACY,qBAAqB","sourcesContent":["import { Component, OnInit } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Metadata } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'SearchResultsResource')\n@Component({\n standalone: false,\n selector: 'mj-search-results-resource',\n template: `<mj-single-search-result [entity]=\"Data.Configuration.Entity\" [searchInput]=\"Data.Configuration.SearchInput\" (loadComplete)=\"NotifyLoadComplete()\" (loadStarted)=\"NotifyLoadStarted()\"></mj-single-search-result>`\n})\nexport class SearchResultsResource extends BaseResourceComponent implements OnInit {\n ngOnInit(): void {\n\n }\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return `Search (${data.Configuration.Entity}): ${data.Configuration.SearchInput}`;\n }\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity){\n return ''\n }\n else {\n const md = new Metadata();\n const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (e)\n return e?.Icon;\n else\n return '';\n }\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 = 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,8 +1,8 @@
|
|
|
1
1
|
import { ElementRef, ChangeDetectorRef } from '@angular/core';
|
|
2
|
-
import { BaseResourceComponent
|
|
2
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
3
3
|
import { ResourceData, MJUserViewEntityExtended } from '@memberjunction/core-entities';
|
|
4
4
|
import { EntityInfo } from '@memberjunction/core';
|
|
5
|
-
import { RecordOpenedEvent, ViewGridState, EntityViewerComponent } from '@memberjunction/ng-entity-viewer';
|
|
5
|
+
import { RecordOpenedEvent, ViewGridState, EntityViewerComponent, EntityViewMode } from '@memberjunction/ng-entity-viewer';
|
|
6
6
|
import { ExportService } from '@memberjunction/ng-export-service';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
/**
|
|
@@ -18,7 +18,6 @@ import * as i0 from "@angular/core";
|
|
|
18
18
|
* - Opens records in new tabs via NavigationService
|
|
19
19
|
*/
|
|
20
20
|
export declare class UserViewResource extends BaseResourceComponent {
|
|
21
|
-
private navigationService;
|
|
22
21
|
private cdr;
|
|
23
22
|
private exportService;
|
|
24
23
|
containerElement: ElementRef<HTMLDivElement>;
|
|
@@ -28,10 +27,14 @@ export declare class UserViewResource extends BaseResourceComponent {
|
|
|
28
27
|
entityInfo: EntityInfo | null;
|
|
29
28
|
viewEntity: MJUserViewEntityExtended | null;
|
|
30
29
|
gridState: ViewGridState | null;
|
|
30
|
+
/** View mode from dashboard configuration (grid/cards/timeline/map) */
|
|
31
|
+
configuredViewMode: EntityViewMode | null;
|
|
32
|
+
/** Map render mode from dashboard configuration */
|
|
33
|
+
configuredMapRenderMode: 'point' | 'choropleth' | 'heatmap';
|
|
31
34
|
isExporting: boolean;
|
|
32
35
|
private dataLoaded;
|
|
33
36
|
private metadata;
|
|
34
|
-
constructor(
|
|
37
|
+
constructor(cdr: ChangeDetectorRef, exportService: ExportService);
|
|
35
38
|
set Data(value: ResourceData);
|
|
36
39
|
get Data(): ResourceData;
|
|
37
40
|
/**
|
|
@@ -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,
|
|
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;IAuBnD,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,aAAa;IAvBiB,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,CAAC,QAAQ,CAAkB;gBAGtB,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;yCA5Uf,gBAAgB;2CAAhB,gBAAgB;CAwV5B"}
|
|
@@ -10,10 +10,9 @@ import { ViewInfo } from '@memberjunction/core-entities';
|
|
|
10
10
|
import { RegisterClass, MJGlobal, MJEventType, UUIDsEqual } from '@memberjunction/global';
|
|
11
11
|
import { CompositeKey, Metadata, RunView } from '@memberjunction/core';
|
|
12
12
|
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "@memberjunction/ng-
|
|
14
|
-
import * as i2 from "@memberjunction/ng-
|
|
15
|
-
import * as i3 from "@memberjunction/ng-
|
|
16
|
-
import * as i4 from "@memberjunction/ng-entity-viewer";
|
|
13
|
+
import * as i1 from "@memberjunction/ng-export-service";
|
|
14
|
+
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
15
|
+
import * as i3 from "@memberjunction/ng-entity-viewer";
|
|
17
16
|
const _c0 = ["container"];
|
|
18
17
|
const _c1 = ["entityViewer"];
|
|
19
18
|
function UserViewResource_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -84,7 +83,7 @@ function UserViewResource_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
|
84
83
|
i0.ɵɵadvance(3);
|
|
85
84
|
i0.ɵɵtextInterpolate(ctx_r0.isExporting ? "Exporting..." : "Export");
|
|
86
85
|
i0.ɵɵadvance();
|
|
87
|
-
i0.ɵɵproperty("entity", ctx_r0.entityInfo)("viewEntity", ctx_r0.viewEntity)("gridState", ctx_r0.gridState);
|
|
86
|
+
i0.ɵɵproperty("entity", ctx_r0.entityInfo)("viewEntity", ctx_r0.viewEntity)("gridState", ctx_r0.gridState)("viewMode", ctx_r0.configuredViewMode)("mapRenderMode", ctx_r0.configuredMapRenderMode);
|
|
88
87
|
} }
|
|
89
88
|
/**
|
|
90
89
|
* UserViewResource - Resource wrapper for displaying User Views in tabs
|
|
@@ -99,7 +98,6 @@ function UserViewResource_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
|
99
98
|
* - Opens records in new tabs via NavigationService
|
|
100
99
|
*/
|
|
101
100
|
let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
102
|
-
navigationService;
|
|
103
101
|
cdr;
|
|
104
102
|
exportService;
|
|
105
103
|
containerElement;
|
|
@@ -109,13 +107,16 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
109
107
|
entityInfo = null;
|
|
110
108
|
viewEntity = null;
|
|
111
109
|
gridState = null;
|
|
110
|
+
/** View mode from dashboard configuration (grid/cards/timeline/map) */
|
|
111
|
+
configuredViewMode = null;
|
|
112
|
+
/** Map render mode from dashboard configuration */
|
|
113
|
+
configuredMapRenderMode = 'point';
|
|
112
114
|
// Export state
|
|
113
115
|
isExporting = false;
|
|
114
116
|
dataLoaded = false;
|
|
115
117
|
metadata = new Metadata();
|
|
116
|
-
constructor(
|
|
118
|
+
constructor(cdr, exportService) {
|
|
117
119
|
super();
|
|
118
|
-
this.navigationService = navigationService;
|
|
119
120
|
this.cdr = cdr;
|
|
120
121
|
this.exportService = exportService;
|
|
121
122
|
}
|
|
@@ -125,6 +126,21 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
125
126
|
super.Data = value;
|
|
126
127
|
const newRecordId = value?.ResourceRecordID;
|
|
127
128
|
const newEntity = value?.Configuration?.Entity;
|
|
129
|
+
// Read view mode and map render mode from configuration if provided
|
|
130
|
+
const viewMode = value?.Configuration?.['viewMode'];
|
|
131
|
+
if (viewMode && ['grid', 'cards', 'timeline', 'map'].includes(viewMode)) {
|
|
132
|
+
this.configuredViewMode = viewMode;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.configuredViewMode = null;
|
|
136
|
+
}
|
|
137
|
+
const mapMode = value?.Configuration?.['mapRenderMode'];
|
|
138
|
+
if (mapMode && ['point', 'choropleth', 'heatmap'].includes(mapMode)) {
|
|
139
|
+
this.configuredMapRenderMode = mapMode;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.configuredMapRenderMode = 'point';
|
|
143
|
+
}
|
|
128
144
|
// Load on first set, or when the view/entity has changed
|
|
129
145
|
if (!this.dataLoaded || newRecordId !== previousRecordId || newEntity !== previousEntity) {
|
|
130
146
|
this.dataLoaded = true;
|
|
@@ -377,21 +393,21 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
377
393
|
}
|
|
378
394
|
});
|
|
379
395
|
}
|
|
380
|
-
static ɵfac = function UserViewResource_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserViewResource)(i0.ɵɵdirectiveInject(
|
|
396
|
+
static ɵfac = function UserViewResource_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserViewResource)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.ExportService)); };
|
|
381
397
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserViewResource, selectors: [["mj-userview-resource"]], viewQuery: function UserViewResource_Query(rf, ctx) { if (rf & 1) {
|
|
382
398
|
i0.ɵɵviewQuery(_c0, 7)(_c1, 5);
|
|
383
399
|
} if (rf & 2) {
|
|
384
400
|
let _t;
|
|
385
401
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.containerElement = _t.first);
|
|
386
402
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.entityViewerRef = _t.first);
|
|
387
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 1, consts: [["container", ""], ["entityViewer", ""], [1, "view-resource-container"], [1, "view-loading-state"], [1, "view-error-state"], ["text", "Loading view...", "size", "large"], [1, "fas", "fa-exclamation-triangle"], [1, "view-header"], [1, "header-left"], [1, "view-title"], [1, "view-description"], [1, "header-right"], [1, "action-button", "create-button", 3, "click", "title"], [1, "fa-solid", "fa-plus"], ["title", "Export to Excel", 1, "action-button", "export-button", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-file-excel"], [3, "recordOpened", "dataLoaded", "entity", "viewEntity", "gridState"]], template: function UserViewResource_Template(rf, ctx) { if (rf & 1) {
|
|
403
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 1, consts: [["container", ""], ["entityViewer", ""], [1, "view-resource-container"], [1, "view-loading-state"], [1, "view-error-state"], ["text", "Loading view...", "size", "large"], [1, "fas", "fa-exclamation-triangle"], [1, "view-header"], [1, "header-left"], [1, "view-title"], [1, "view-description"], [1, "header-right"], [1, "action-button", "create-button", 3, "click", "title"], [1, "fa-solid", "fa-plus"], ["title", "Export to Excel", 1, "action-button", "export-button", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-file-excel"], [3, "recordOpened", "dataLoaded", "entity", "viewEntity", "gridState", "viewMode", "mapRenderMode"]], template: function UserViewResource_Template(rf, ctx) { if (rf & 1) {
|
|
388
404
|
i0.ɵɵelementStart(0, "div", 2, 0);
|
|
389
|
-
i0.ɵɵconditionalCreate(2, UserViewResource_Conditional_2_Template, 2, 0, "div", 3)(3, UserViewResource_Conditional_3_Template, 4, 1, "div", 4)(4, UserViewResource_Conditional_4_Template, 17,
|
|
405
|
+
i0.ɵɵconditionalCreate(2, UserViewResource_Conditional_2_Template, 2, 0, "div", 3)(3, UserViewResource_Conditional_3_Template, 4, 1, "div", 4)(4, UserViewResource_Conditional_4_Template, 17, 12);
|
|
390
406
|
i0.ɵɵelementEnd();
|
|
391
407
|
} if (rf & 2) {
|
|
392
408
|
i0.ɵɵadvance(2);
|
|
393
409
|
i0.ɵɵconditional(ctx.isLoading ? 2 : ctx.errorMessage ? 3 : ctx.entityInfo ? 4 : -1);
|
|
394
|
-
} }, dependencies: [
|
|
410
|
+
} }, dependencies: [i2.LoadingComponent, i3.EntityViewerComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .view-resource-container[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n .header-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n }\n .view-title[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--text-secondary, #666);\n }\n .action-button[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-default);\n }\n .action-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .action-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .create-button[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n }\n .create-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n }\n .export-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n .view-loading-state[_ngcontent-%COMP%], \n .view-error-state[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n color: var(--danger-color, #dc3545);\n }\n .view-error-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n .view-error-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n }\n mj-entity-viewer[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n }"] });
|
|
395
411
|
};
|
|
396
412
|
UserViewResource = __decorate([
|
|
397
413
|
RegisterClass(BaseResourceComponent, 'ViewResource')
|
|
@@ -399,8 +415,8 @@ UserViewResource = __decorate([
|
|
|
399
415
|
export { UserViewResource };
|
|
400
416
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserViewResource, [{
|
|
401
417
|
type: Component,
|
|
402
|
-
args: [{ standalone: false, selector: 'mj-userview-resource', template: "<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 (recordOpened)=\"onRecordOpened($any($event))\"\n (dataLoaded)=\"onDataLoaded()\">\n </mj-entity-viewer>\n }\n</div>\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 "] }]
|
|
403
|
-
}], () => [{ type:
|
|
418
|
+
args: [{ standalone: false, selector: 'mj-userview-resource', template: "<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", 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 "] }]
|
|
419
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.ExportService }], { containerElement: [{
|
|
404
420
|
type: ViewChild,
|
|
405
421
|
args: ['container', { static: true }]
|
|
406
422
|
}], entityViewerRef: [{
|
|
@@ -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":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAiC,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAA0C,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAG,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAc,OAAO,EAAE,MAAM,sBAAsB,CAAC;;;;;;;;;ICF3E,8BAAgC;IAC5B,gCAA6D;IACjE,iBAAM;;;IAEN,8BAA8B;IAC1B,uBAA2C;IAC3C,yBAAG;IAAA,YAAkB;IACzB,AADyB,iBAAI,EACvB;;;IADC,eAAkB;IAAlB,yCAAkB;;;IAQb,6BAA4B;IAAA,YAA6B;IAAA,iBAAI;;;IAAjC,cAA6B;IAA7B,mDAA6B;;;IAoBrD,wBAA2C;;;IAE3C,wBAAsC;;;;IAxB9C,AADJ,AADJ,8BAAyB,aACI,YACE;IAAA,YAAyC;IAAA,iBAAK;IACrE,+FAA+B;IAGnC,iBAAM;IAGF,AAFJ,+BAA0B,iBAK8B;IADhD,oLAAS,0BAAmB,KAAC;IAE7B,wBAAgC;IAChC,4BAAM;IAAA,0BAAU;IACpB,AADoB,iBAAO,EAClB;IAGT,mCAI4B;IAFxB,qLAAS,iBAAU,KAAC;IAKlB,AAFF,iGAAmB,2EAEV;IAGT,6BAAM;IAAA,aAA6C;IAG/D,AADI,AADI,AADuD,iBAAO,EACrD,EACP,EACJ;IAGN,gDAMkC;IAA9B,AADA,mNAAgB,6BAA4B,KAAC,4LAC/B,qBAAc,KAAC;IACjC,iBAAmB;;;IAvCY,eAAyC;IAAzC,2GAAyC;IAChE,cAEC;IAFD,6FAEC;IAOG,eAA+C;IAA/C,uBAAA,mEAA+C,CAAA;IAS/C,eAAwB;IAAxB,6CAAwB;IAExB,cAIC;IAJD,8CAIC;IACK,eAA6C;IAA7C,oEAA6C;IAQ3D,cAAqB;IAErB,AADA,AADA,0CAAqB,iCACI,+BACF;;AD1CnC;;;;;;;;;;;GAWG;AAoHI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,qBAAqB;IAiB3C;IACA;IACA;IAlB8B,gBAAgB,CAA8B;IAC7D,eAAe,CAAyB;IAE5D,SAAS,GAAY,KAAK,CAAC;IAC3B,YAAY,GAAkB,IAAI,CAAC;IACnC,UAAU,GAAsB,IAAI,CAAC;IACrC,UAAU,GAAoC,IAAI,CAAC;IACnD,SAAS,GAAyB,IAAI,CAAC;IAE9C,eAAe;IACR,WAAW,GAAY,KAAK,CAAC;IAE5B,UAAU,GAAG,KAAK,CAAC;IACnB,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAElC,YACY,iBAAoC,EACpC,GAAsB,EACtB,aAA4B;QAEpC,KAAK,EAAE,CAAC;QAJA,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,QAAG,GAAH,GAAG,CAAmB;QACtB,kBAAa,GAAb,aAAa,CAAe;IAGxC,CAAC;IAED,IAAa,IAAI,CAAC,KAAmB;QACjC,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,EAAE,gBAAgB,CAAC;QACtD,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC;QACzD,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QAEnB,MAAM,WAAW,GAAG,KAAK,EAAE,gBAAgB,CAAC;QAC5C,MAAM,SAAS,GAAG,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC;QAE/C,yDAAyD;QACzD,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,KAAK,gBAAgB,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;YACvF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,sCAAsC;YACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpB,CAAC;IACL,CAAC;IAED,IAAa,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,QAAQ;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEvB,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO;QACX,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,0BAA0B;YAC1B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACnD,CAAC;YACD,2CAA2C;iBACtC,IAAI,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,eAAe,CACtB,IAAI,CAAC,aAAa,CAAC,MAAgB,EACnC,IAAI,CAAC,aAAa,CAAC,WAAiC,CACvD,CAAC;YACN,CAAC;iBACI,CAAC;gBACF,IAAI,CAAC,YAAY,GAAG,gCAAgC,CAAC;YACzD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;QACvF,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAEzB,kDAAkD;YAClD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC9B,CAAC;YACD,0DAA0D;QAC9D,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,MAAc;QACrC,uBAAuB;QACvB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAElD,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,YAAY,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAgC,CAAC;QAEnD,oBAAoB;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACpE,CAAC;QAED,uBAAuB;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE7F,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QAEzB,gCAAgC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAkB,CAAC;YAC5E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC;gBAC9C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,YAAqB;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CACvE,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,sFAAsF;QACtF,kEAAkE;IACtE,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,KAAwB;QAC1C,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YAC9C,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QACnF,CAAC;IACL,CAAC;IAED;;OAEG;IACI,YAAY;QACf,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACM,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QACpD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YAC3F,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;YACrF,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1D,CAAC;aACI,IAAI,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,MAAgB,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;YACjD,OAAO,GAAG,UAAU,YAAY,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC;QAC5E,CAAC;QACD,OAAO,oBAAoB,CAAC;IAChC,CAAC;IAED;;OAEG;IACM,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QACnD,OAAO,wBAAwB,CAAC;IACpC,CAAC;IAED;;OAEG;IACI,iBAAiB;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,kDAAkD;QAClD,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACrD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,+DAA+D,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAErG,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE;gBAClD,QAAQ;gBACR,OAAO;gBACP,cAAc,EAAE,IAAI;aACvB,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC1D,CAAC;QACL,CAAC;QACD,OAAO,CAAC,EAAE,CAAC;YACP,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;gBACO,CAAC;YACL,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc;QACxB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC;YAC/B,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QACzC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA0B;YACrD,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;YAChC,WAAW,EAAE,MAAM;YACnB,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,QAAQ;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,IAAI,gCAAgC,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACK,kBAAkB;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAEhC,IAAI,IAAI,CAAC,SAAS,EAAE,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7E,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;YACxF,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI;aAC3C,CAAC,CAAC,CAAC;QACR,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1E,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI;aAC3C,CAAC,CAAC,CAAC;QACR,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,iBAAiB;SACnC,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;OAEG;IACK,mBAAmB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,MAAM,CAAC;QACjD,OAAO,GAAG,IAAI,CAAC,UAAW,CAAC,IAAI,IAAI,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,OAAe,EAAE,KAA+C,EAAE,QAAgB;QACvG,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;YACzB,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,WAAW,CAAC,gCAAgC;YACnD,SAAS,EAAE,EAAE;YACb,IAAI,EAAE;gBACF,OAAO;gBACP,KAAK;gBACL,eAAe,EAAE,QAAQ;aAC5B;SACJ,CAAC,CAAC;IACP,CAAC;0GAnUQ,gBAAgB;6DAAhB,gBAAgB;;;;;;;YCvI7B,iCAAgD;YAU1C,AALA,AAJF,kFAAiB,4DAIU,oDAKF;YA6C7B,iBAAM;;YAtDF,eAqDC;YArDD,oFAqDC;;;ADiFQ,gBAAgB;IAnH5B,aAAa,CAAC,qBAAqB,EAAE,cAAc,CAAC;GAmHxC,gBAAgB,CAoU5B;;iFApUY,gBAAgB;cAlH5B,SAAS;6BACI,KAAK,YACL,sBAAsB;;kBAiH/B,SAAS;mBAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;;kBACvC,SAAS;mBAAC,cAAc;;kFAFhB,gBAAgB","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 } 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 // Export state\n public isExporting: boolean = false;\n\n private dataLoaded = false;\n private metadata = new Metadata();\n\n constructor(\n private navigationService: NavigationService,\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 // 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 (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 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-validation.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;;AAEtE;;GAEG;AACH,qBAGa,wBAAwB;IACvB,OAAO,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,uBAAuB;IAE9D;;OAEG;IACI,mBAAmB,IAAI,IAAI;IAKlC;;;OAGG;IACI,yBAAyB,IAAI,IAAI;IAUxC;;OAEG;IACH,OAAO,CAAC,iBAAiB;yCA5Bd,wBAAwB;6CAAxB,wBAAwB;
|
|
1
|
+
{"version":3,"file":"startup-validation.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/startup-validation.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;;AAEtE;;GAEG;AACH,qBAGa,wBAAwB;IACvB,OAAO,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,uBAAuB;IAE9D;;OAEG;IACI,mBAAmB,IAAI,IAAI;IAKlC;;;OAGG;IACI,yBAAyB,IAAI,IAAI;IAUxC;;OAEG;IACH,OAAO,CAAC,iBAAiB;yCA5Bd,wBAAwB;6CAAxB,wBAAwB;CAkEpC"}
|
|
@@ -35,10 +35,8 @@ export class StartupValidationService {
|
|
|
35
35
|
*/
|
|
36
36
|
validateUserRoles() {
|
|
37
37
|
try {
|
|
38
|
-
console.log('StartupValidationService: Validating user roles');
|
|
39
38
|
const md = new Metadata();
|
|
40
39
|
const currentUser = md.CurrentUser;
|
|
41
|
-
console.log('StartupValidationService: Current user:', currentUser);
|
|
42
40
|
if (!currentUser) {
|
|
43
41
|
console.log('StartupValidationService: No current user found');
|
|
44
42
|
this.validationService.addIssue({
|
|
@@ -50,7 +48,6 @@ export class StartupValidationService {
|
|
|
50
48
|
});
|
|
51
49
|
return;
|
|
52
50
|
}
|
|
53
|
-
console.log('StartupValidationService: User roles:', currentUser.UserRoles);
|
|
54
51
|
if (!currentUser.UserRoles || currentUser.UserRoles.length === 0) {
|
|
55
52
|
console.log('StartupValidationService: No user roles found, adding validation issue');
|
|
56
53
|
this.validationService.addIssue({
|
|
@@ -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,EAAY,MAAM,sBAAsB,CAAC;;;AAG1D;;GAEG;AAIH,MAAM,OAAO,wBAAwB;IACf;IAApB,YAAoB,iBAA0C;QAA1C,sBAAiB,GAAjB,iBAAiB,CAAyB;IAAI,CAAC;IAEnE;;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,
|
|
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,EAAY,MAAM,sBAAsB,CAAC;;;AAG1D;;GAEG;AAIH,MAAM,OAAO,wBAAwB;IACf;IAApB,YAAoB,iBAA0C;QAA1C,sBAAiB,GAAjB,iBAAiB,CAAyB;IAAI,CAAC;IAEnE;;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,QAAQ,EAAE,CAAC;YAC1B,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;kHAjEU,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 } 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 * 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 = new Metadata();\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}"]}
|
|
@@ -16,6 +16,13 @@ export interface CachedComponentInfo {
|
|
|
16
16
|
createdAt: Date;
|
|
17
17
|
resourceData: ResourceData;
|
|
18
18
|
savedQueryParams?: Record<string, string>;
|
|
19
|
+
AgentContext?: Record<string, unknown>;
|
|
20
|
+
AgentClientTools?: {
|
|
21
|
+
Name: string;
|
|
22
|
+
Description: string;
|
|
23
|
+
ParameterSchema: Record<string, unknown>;
|
|
24
|
+
Handler: (params: Record<string, unknown>) => Promise<unknown>;
|
|
25
|
+
}[];
|
|
19
26
|
}
|
|
20
27
|
/**
|
|
21
28
|
* Smart component cache manager that preserves component state across tab switches.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAElC,YAAY,EAAE,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAGlD,cAAc,EAAE,WAAW,CAAC;IAG5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IAGtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAG/B,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAGhB,YAAY,EAAE,YAAY,CAAC;IAK3B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
|