@memberjunction/ng-explorer-core 5.11.0 → 5.12.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/lib/command-palette/command-palette.component.js +2 -2
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +2 -2
- package/dist/lib/oauth/oauth-callback.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +4 -4
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +5 -5
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +22 -21
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +2 -2
- package/dist/lib/shell/loading-themes.js +1 -1
- package/dist/lib/shell/loading-themes.js.map +1 -1
- package/dist/lib/shell/shell.component.js +3 -3
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +2 -2
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +2 -2
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +2 -2
- package/dist/lib/single-dashboard/single-dashboard.component.js +2 -2
- package/dist/lib/single-list-detail/single-list-detail.component.js +2 -2
- package/dist/lib/single-search-result/single-search-result.component.js +2 -2
- package/dist/lib/system-validation/system-validation-banner.component.js +2 -2
- package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +15 -2
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +76 -8
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +2 -2
- package/package.json +34 -34
|
@@ -308,11 +308,11 @@ export class CommandPaletteComponent {
|
|
|
308
308
|
i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
|
|
309
309
|
i0.ɵɵadvance();
|
|
310
310
|
i0.ɵɵconditional(ctx.IsOpen ? 1 : -1);
|
|
311
|
-
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent], styles: ["\n\n.command-palette-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n.command-palette-modal[_ngcontent-%COMP%] {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background:
|
|
311
|
+
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent], styles: ["\n\n.command-palette-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n.command-palette-modal[_ngcontent-%COMP%] {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: _ngcontent-%COMP%_slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.results-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item[_ngcontent-%COMP%]:hover, \n.result-item.selected[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.result-item.selected[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n\n\n@media (max-width: 768px) {\n .command-palette-modal[_ngcontent-%COMP%] {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .result-description[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n}"] });
|
|
312
312
|
}
|
|
313
313
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CommandPaletteComponent, [{
|
|
314
314
|
type: Component,
|
|
315
|
-
args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background:
|
|
315
|
+
args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Container */\n.search-container {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Results List */\n.results-list {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n/* Section Header (for \"Recent\") */\n.section-header {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Result Item */\n.result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item:hover,\n.result-item.selected {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected {\n position: relative;\n}\n\n.result-item.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n/* Scrollbar Styling (Webkit browsers) */\n.results-list::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .command-palette-modal {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input {\n font-size: 14px;\n }\n\n .result-name {\n font-size: 13px;\n }\n\n .result-description {\n font-size: 11px;\n }\n}\n"] }]
|
|
316
316
|
}], () => [{ type: i1.CommandPaletteService }, { type: i2.ApplicationManager }, { type: i0.ChangeDetectorRef }], { SearchInput: [{
|
|
317
317
|
type: ViewChild,
|
|
318
318
|
args: ['searchInput']
|
|
@@ -556,11 +556,11 @@ export class DashboardPreferencesDialogComponent {
|
|
|
556
556
|
i0.ɵɵproperty("disabled", !ctx.hasChanges || ctx.saving);
|
|
557
557
|
i0.ɵɵadvance();
|
|
558
558
|
i0.ɵɵconditional(ctx.saving ? 19 : 20);
|
|
559
|
-
} }, dependencies: [i1.DefaultValueAccessor, i1.RadioControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.DialogComponent, i3.CdkDropList, i3.CdkDrag, i4.LoadingComponent], styles: [".dashboard-preferences-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dialog-header[_ngcontent-%COMP%] {\n padding: 20px 24px 16px;\n border-bottom: 1px solid
|
|
559
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.RadioControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.DialogComponent, i3.CdkDropList, i3.CdkDrag, i4.LoadingComponent], styles: [".dashboard-preferences-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dialog-header[_ngcontent-%COMP%] {\n padding: 20px 24px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n color: var(--mj-text-secondary);\n}\n\n.scope-indicator[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.scope-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n.preference-mode-selector[_ngcontent-%COMP%] {\n margin-top: 12px;\n display: flex;\n gap: 20px;\n}\n\n.preference-mode-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preference-mode-selector[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n padding: 20px 24px;\n}\n\n.loading-container[_ngcontent-%COMP%], .error-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 200px;\n flex-direction: column;\n gap: 12px;\n}\n\n.error-container[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.error-container[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 8px;\n}\n\n.preferences-panels[_ngcontent-%COMP%] {\n display: flex;\n gap: 20px;\n height: 100%;\n}\n\n.panel[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.panel[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.panel[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n color: var(--mj-text-muted);\n}\n\n.dashboard-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100px;\n color: var(--mj-text-muted);\n font-style: italic;\n flex-direction: column;\n gap: 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n opacity: 0.5;\n}\n\n.dashboard-item[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n transition: all 0.2s ease;\n cursor: move;\n}\n\n.dashboard-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.dashboard-item.cdk-drag-preview[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n transform: rotate(2deg);\n}\n\n.dashboard-item.cdk-drag-placeholder[_ngcontent-%COMP%] {\n opacity: 0.3;\n border-style: dashed;\n}\n\n.dashboard-item-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px;\n gap: 12px;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n cursor: move;\n font-size: 14px;\n}\n\n.order-number[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n background: var(--mj-brand-primary);\n color: white;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.dashboard-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.dashboard-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.dashboard-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n line-height: 1.3;\n}\n\n.add-button[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-status-success);\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n opacity: 0.7;\n}\n\n.add-button[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n opacity: 1;\n}\n\n.remove-button[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-status-error);\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n}\n\n.remove-button[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n}\n\n.cdk-drop-list-dragging[_ngcontent-%COMP%] .dashboard-item[_ngcontent-%COMP%]:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.dialog-footer[_ngcontent-%COMP%] {\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n}\n\n.btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n border: 1px solid transparent;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-color: var(--mj-text-muted);\n color: var(--mj-text-muted);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-text-muted);\n color: white;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n\n@media (max-width: 768px) {\n .dashboard-preferences-dialog[_ngcontent-%COMP%] {\n width: 95vw;\n max-height: 90vh;\n }\n\n .preferences-panels[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .panel[_ngcontent-%COMP%] {\n min-height: 200px;\n }\n\n .dashboard-list[_ngcontent-%COMP%] {\n min-height: 150px;\n }\n}"] });
|
|
560
560
|
}
|
|
561
561
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DashboardPreferencesDialogComponent, [{
|
|
562
562
|
type: Component,
|
|
563
|
-
args: [{ standalone: false, selector: 'mj-dashboard-preferences-dialog', template: "<kendo-dialog title=\"Dashboard Preferences\" \n [width]=\"800\" \n [height]=\"600\"\n [minWidth]=\"600\"\n [minHeight]=\"400\"\n (close)=\"onCancel()\">\n<div class=\"dashboard-preferences-dialog\">\n <div class=\"dialog-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Dashboard Preferences</h3>\n <p class=\"scope-indicator\">\n @if (scope === 'Global') {\n <i class=\"fa-solid fa-globe\"></i> Global Scope\n } @else {\n <i class=\"fa-solid fa-layer-group\"></i> Application: {{ applicationName }}\n }\n </p>\n @if (isSysAdmin && scope === 'Global') {\n <div class=\"preference-mode-selector\">\n <label>\n <input type=\"radio\" \n name=\"preferenceMode\" \n value=\"personal\" \n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n Personal Preferences\n </label>\n <label>\n <input type=\"radio\" \n name=\"preferenceMode\" \n value=\"system\" \n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n System Defaults\n </label>\n </div>\n }\n </div>\n\n <div class=\"dialog-content\">\n @if (loading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading preferences...\" size=\"large\"></mj-loading>\n </div>\n }\n\n @if (error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </div>\n }\n\n @if (!loading && !error) {\n <div class=\"preferences-panels\">\n <!-- Available Dashboards Panel -->\n <div class=\"panel available-panel\">\n <h4><i class=\"fa-solid fa-list\"></i> Available Dashboards</h4>\n <div class=\"dashboard-list\" \n cdkDropList \n #availableList=\"cdkDropList\"\n [cdkDropListData]=\"availableDashboards\"\n [cdkDropListConnectedTo]=\"[configuredList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n \n @if (availableDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n All dashboards are configured\n </div>\n }\n\n @for (dashboard of availableDashboards; track dashboard.ID) {\n <div class=\"dashboard-item available-item\" \n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\" \n class=\"add-button\"\n (click)=\"addDashboard(dashboard)\"\n title=\"Add to configured dashboards\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Configured Dashboards Panel -->\n <div class=\"panel configured-panel\">\n <h4><i class=\"fa-solid fa-list-ol\"></i> Configured Dashboards</h4>\n <div class=\"dashboard-list\" \n cdkDropList \n #configuredList=\"cdkDropList\"\n [cdkDropListData]=\"configuredDashboards\"\n [cdkDropListConnectedTo]=\"[availableList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n \n @if (configuredDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No dashboards configured\n </div>\n }\n\n @for (dashboard of configuredDashboards; track dashboard.ID; let i = $index) {\n <div class=\"dashboard-item configured-item\" \n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <span class=\"order-number\">{{ i + 1 }}</span>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\" \n class=\"remove-button\"\n (click)=\"removeDashboard(dashboard)\"\n title=\"Remove from configured dashboards\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"dialog-footer\">\n <button type=\"button\" \n class=\"btn btn-secondary\" \n (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i> Cancel\n </button>\n <button type=\"button\" \n class=\"btn btn-primary\" \n [disabled]=\"!hasChanges || saving\"\n (click)=\"onSave()\">\n @if (saving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Save Changes\n }\n </button>\n </div>\n</div>\n</kendo-dialog>", styles: [".dashboard-preferences-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dialog-header {\n padding: 20px 24px 16px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.dialog-header h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #333;\n}\n\n.dialog-header h3 i {\n margin-right: 8px;\n color: #666;\n}\n\n.scope-indicator {\n margin: 0;\n font-size: 14px;\n color: #666;\n}\n\n.scope-indicator i {\n margin-right: 6px;\n}\n\n.preference-mode-selector {\n margin-top: 12px;\n display: flex;\n gap: 20px;\n}\n\n.preference-mode-selector label {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #495057;\n}\n\n.preference-mode-selector input[type=\"radio\"] {\n margin: 0;\n}\n\n.dialog-content {\n flex: 1;\n overflow: hidden;\n padding: 20px 24px;\n}\n\n.loading-container, .error-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 200px;\n flex-direction: column;\n gap: 12px;\n}\n\n.error-container {\n color: #dc3545;\n}\n\n.error-container i {\n font-size: 24px;\n margin-bottom: 8px;\n}\n\n.preferences-panels {\n display: flex;\n gap: 20px;\n height: 100%;\n}\n\n.panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.panel h4 {\n margin: 0;\n padding: 12px 16px;\n background: #f8f9fa;\n border-bottom: 1px solid #e0e0e0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n}\n\n.panel h4 i {\n margin-right: 8px;\n color: #6c757d;\n}\n\n.dashboard-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100px;\n color: #6c757d;\n font-style: italic;\n flex-direction: column;\n gap: 8px;\n}\n\n.empty-state i {\n font-size: 24px;\n opacity: 0.5;\n}\n\n.dashboard-item {\n margin-bottom: 8px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n transition: all 0.2s ease;\n cursor: move;\n}\n\n.dashboard-item:hover {\n border-color: #007bff;\n box-shadow: 0 2px 4px rgba(0, 123, 255, 0.1);\n}\n\n.dashboard-item.cdk-drag-preview {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n transform: rotate(2deg);\n}\n\n.dashboard-item.cdk-drag-placeholder {\n opacity: 0.3;\n border-style: dashed;\n}\n\n.dashboard-item-content {\n display: flex;\n align-items: center;\n padding: 12px;\n gap: 12px;\n}\n\n.drag-handle {\n color: #adb5bd;\n cursor: move;\n font-size: 14px;\n}\n\n.order-number {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n background: #007bff;\n color: white;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.dashboard-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.dashboard-name {\n font-weight: 500;\n color: #333;\n font-size: 14px;\n}\n\n.dashboard-description {\n font-size: 12px;\n color: #6c757d;\n line-height: 1.3;\n}\n\n.add-button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #28a745;\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n opacity: 0.7;\n}\n\n.add-button:hover {\n background-color: rgba(40, 167, 69, 0.1);\n opacity: 1;\n}\n\n.remove-button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #dc3545;\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n}\n\n.remove-button:hover {\n background-color: rgba(220, 53, 69, 0.1);\n}\n\n.cdk-drop-list-dragging .dashboard-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.dialog-footer {\n padding: 16px 24px;\n border-top: 1px solid #e0e0e0;\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n background: #f8f9fa;\n}\n\n.btn {\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n border: 1px solid transparent;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn-secondary {\n background: white;\n border-color: #6c757d;\n color: #6c757d;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #6c757d;\n color: white;\n}\n\n.btn-primary {\n background: #007bff;\n color: white;\n border-color: #007bff;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #0056b3;\n border-color: #0056b3;\n}\n\n/* Responsive design */\n@media (max-width: 768px) {\n .dashboard-preferences-dialog {\n width: 95vw;\n max-height: 90vh;\n }\n \n .preferences-panels {\n flex-direction: column;\n gap: 16px;\n }\n \n .panel {\n min-height: 200px;\n }\n \n .dashboard-list {\n min-height: 150px;\n }\n}"] }]
|
|
563
|
+
args: [{ standalone: false, selector: 'mj-dashboard-preferences-dialog', template: "<kendo-dialog title=\"Dashboard Preferences\" \n [width]=\"800\" \n [height]=\"600\"\n [minWidth]=\"600\"\n [minHeight]=\"400\"\n (close)=\"onCancel()\">\n<div class=\"dashboard-preferences-dialog\">\n <div class=\"dialog-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Dashboard Preferences</h3>\n <p class=\"scope-indicator\">\n @if (scope === 'Global') {\n <i class=\"fa-solid fa-globe\"></i> Global Scope\n } @else {\n <i class=\"fa-solid fa-layer-group\"></i> Application: {{ applicationName }}\n }\n </p>\n @if (isSysAdmin && scope === 'Global') {\n <div class=\"preference-mode-selector\">\n <label>\n <input type=\"radio\" \n name=\"preferenceMode\" \n value=\"personal\" \n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n Personal Preferences\n </label>\n <label>\n <input type=\"radio\" \n name=\"preferenceMode\" \n value=\"system\" \n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n System Defaults\n </label>\n </div>\n }\n </div>\n\n <div class=\"dialog-content\">\n @if (loading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading preferences...\" size=\"large\"></mj-loading>\n </div>\n }\n\n @if (error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </div>\n }\n\n @if (!loading && !error) {\n <div class=\"preferences-panels\">\n <!-- Available Dashboards Panel -->\n <div class=\"panel available-panel\">\n <h4><i class=\"fa-solid fa-list\"></i> Available Dashboards</h4>\n <div class=\"dashboard-list\" \n cdkDropList \n #availableList=\"cdkDropList\"\n [cdkDropListData]=\"availableDashboards\"\n [cdkDropListConnectedTo]=\"[configuredList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n \n @if (availableDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n All dashboards are configured\n </div>\n }\n\n @for (dashboard of availableDashboards; track dashboard.ID) {\n <div class=\"dashboard-item available-item\" \n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\" \n class=\"add-button\"\n (click)=\"addDashboard(dashboard)\"\n title=\"Add to configured dashboards\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Configured Dashboards Panel -->\n <div class=\"panel configured-panel\">\n <h4><i class=\"fa-solid fa-list-ol\"></i> Configured Dashboards</h4>\n <div class=\"dashboard-list\" \n cdkDropList \n #configuredList=\"cdkDropList\"\n [cdkDropListData]=\"configuredDashboards\"\n [cdkDropListConnectedTo]=\"[availableList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n \n @if (configuredDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No dashboards configured\n </div>\n }\n\n @for (dashboard of configuredDashboards; track dashboard.ID; let i = $index) {\n <div class=\"dashboard-item configured-item\" \n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <span class=\"order-number\">{{ i + 1 }}</span>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\" \n class=\"remove-button\"\n (click)=\"removeDashboard(dashboard)\"\n title=\"Remove from configured dashboards\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"dialog-footer\">\n <button type=\"button\" \n class=\"btn btn-secondary\" \n (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i> Cancel\n </button>\n <button type=\"button\" \n class=\"btn btn-primary\" \n [disabled]=\"!hasChanges || saving\"\n (click)=\"onSave()\">\n @if (saving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Save Changes\n }\n </button>\n </div>\n</div>\n</kendo-dialog>", styles: [".dashboard-preferences-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dialog-header {\n padding: 20px 24px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.dialog-header h3 i {\n margin-right: 8px;\n color: var(--mj-text-secondary);\n}\n\n.scope-indicator {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.scope-indicator i {\n margin-right: 6px;\n}\n\n.preference-mode-selector {\n margin-top: 12px;\n display: flex;\n gap: 20px;\n}\n\n.preference-mode-selector label {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preference-mode-selector input[type=\"radio\"] {\n margin: 0;\n}\n\n.dialog-content {\n flex: 1;\n overflow: hidden;\n padding: 20px 24px;\n}\n\n.loading-container, .error-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 200px;\n flex-direction: column;\n gap: 12px;\n}\n\n.error-container {\n color: var(--mj-status-error);\n}\n\n.error-container i {\n font-size: 24px;\n margin-bottom: 8px;\n}\n\n.preferences-panels {\n display: flex;\n gap: 20px;\n height: 100%;\n}\n\n.panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.panel h4 {\n margin: 0;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.panel h4 i {\n margin-right: 8px;\n color: var(--mj-text-muted);\n}\n\n.dashboard-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100px;\n color: var(--mj-text-muted);\n font-style: italic;\n flex-direction: column;\n gap: 8px;\n}\n\n.empty-state i {\n font-size: 24px;\n opacity: 0.5;\n}\n\n.dashboard-item {\n margin-bottom: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n transition: all 0.2s ease;\n cursor: move;\n}\n\n.dashboard-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.dashboard-item.cdk-drag-preview {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n transform: rotate(2deg);\n}\n\n.dashboard-item.cdk-drag-placeholder {\n opacity: 0.3;\n border-style: dashed;\n}\n\n.dashboard-item-content {\n display: flex;\n align-items: center;\n padding: 12px;\n gap: 12px;\n}\n\n.drag-handle {\n color: var(--mj-text-disabled);\n cursor: move;\n font-size: 14px;\n}\n\n.order-number {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n background: var(--mj-brand-primary);\n color: white;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.dashboard-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.dashboard-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.dashboard-description {\n font-size: 12px;\n color: var(--mj-text-muted);\n line-height: 1.3;\n}\n\n.add-button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-status-success);\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n opacity: 0.7;\n}\n\n.add-button:hover {\n background-color: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n opacity: 1;\n}\n\n.remove-button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-status-error);\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n}\n\n.remove-button:hover {\n background-color: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n}\n\n.cdk-drop-list-dragging .dashboard-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.dialog-footer {\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n}\n\n.btn {\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n border: 1px solid transparent;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n border-color: var(--mj-text-muted);\n color: var(--mj-text-muted);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-text-muted);\n color: white;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* Responsive design */\n@media (max-width: 768px) {\n .dashboard-preferences-dialog {\n width: 95vw;\n max-height: 90vh;\n }\n\n .preferences-panels {\n flex-direction: column;\n gap: 16px;\n }\n\n .panel {\n min-height: 200px;\n }\n\n .dashboard-list {\n min-height: 150px;\n }\n}\n"] }]
|
|
564
564
|
}], null, { applicationId: [{
|
|
565
565
|
type: Input
|
|
566
566
|
}], scope: [{
|
|
@@ -398,11 +398,11 @@ export class OAuthCallbackComponent {
|
|
|
398
398
|
i0.ɵɵconditional(ctx.HasError ? 3 : -1);
|
|
399
399
|
i0.ɵɵadvance();
|
|
400
400
|
i0.ɵɵconditional(!ctx.IsLoading && !ctx.HasError ? 4 : -1);
|
|
401
|
-
} }, dependencies: [i2.ButtonComponent, i3.LoadingComponent], styles: [".oauth-callback-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background:
|
|
401
|
+
} }, dependencies: [i2.ButtonComponent, i3.LoadingComponent], styles: [".oauth-callback-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-brand-primary);\n padding: 1rem;\n}\n\n.oauth-callback-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n max-width: 450px;\n width: 100%;\n}\n\n.oauth-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.oauth-status[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n}\n\n.oauth-status[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n\n\n.icon-container[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.icon-container[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 3rem;\n}\n\n.success-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.success-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.error-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.error-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.oauth-status.success[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n.oauth-status.error[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.error-code[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.875rem;\n}\n\n.error-message[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 1rem;\n border-radius: 0.5rem;\n font-size: 0.9rem;\n color: var(--mj-text-secondary);\n width: 100%;\n}\n\n\n\n.button-group[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.button-group[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n\n\n.oauth-status.loading[_ngcontent-%COMP%] {\n padding: 2rem 0;\n}\n\n\n\n@media (max-width: 480px) {\n .oauth-callback-card[_ngcontent-%COMP%] {\n padding: 2rem 1.5rem;\n }\n\n .button-group[_ngcontent-%COMP%] {\n flex-direction: column;\n width: 100%;\n }\n\n .button-group[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}"] });
|
|
402
402
|
}
|
|
403
403
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(OAuthCallbackComponent, [{
|
|
404
404
|
type: Component,
|
|
405
|
-
args: [{ standalone: false, selector: 'mj-oauth-callback', template: "<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button kendoButton (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button kendoButton [look]=\"IsRetryable ? 'outline' : 'default'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [".oauth-callback-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background:
|
|
405
|
+
args: [{ standalone: false, selector: 'mj-oauth-callback', template: "<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button kendoButton (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button kendoButton [look]=\"IsRetryable ? 'outline' : 'default'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [".oauth-callback-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-brand-primary);\n padding: 1rem;\n}\n\n.oauth-callback-card {\n background: var(--mj-bg-surface);\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n max-width: 450px;\n width: 100%;\n}\n\n.oauth-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.oauth-status h2 {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n}\n\n.oauth-status p {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n/* Icon containers */\n.icon-container {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.icon-container i {\n font-size: 3rem;\n}\n\n.success-icon {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.success-icon i {\n color: var(--mj-status-success);\n}\n\n.error-icon {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.error-icon i {\n color: var(--mj-status-error);\n}\n\n/* Success state */\n.oauth-status.success h2 {\n color: var(--mj-status-success);\n}\n\n/* Error state */\n.oauth-status.error h2 {\n color: var(--mj-status-error);\n}\n\n.error-code {\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.875rem;\n}\n\n.error-message {\n background: var(--mj-bg-surface-sunken);\n padding: 1rem;\n border-radius: 0.5rem;\n font-size: 0.9rem;\n color: var(--mj-text-secondary);\n width: 100%;\n}\n\n/* Buttons */\n.button-group {\n display: flex;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.button-group button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Loading state */\n.oauth-status.loading {\n padding: 2rem 0;\n}\n\n/* Responsive */\n@media (max-width: 480px) {\n .oauth-callback-card {\n padding: 2rem 1.5rem;\n }\n\n .button-group {\n flex-direction: column;\n width: 100%;\n }\n\n .button-group button {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
|
|
406
406
|
}], () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i0.ChangeDetectorRef }], null); })();
|
|
407
407
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OAuthCallbackComponent, { className: "OAuthCallbackComponent", filePath: "src/lib/oauth/oauth-callback.component.ts", lineNumber: 51 }); })();
|
|
408
408
|
//# sourceMappingURL=oauth-callback.component.js.map
|
|
@@ -445,7 +445,7 @@ let ChatCollectionsResource = class ChatCollectionsResource extends BaseResource
|
|
|
445
445
|
i0.ɵɵconditional(ctx.currentUser ? 2 : -1);
|
|
446
446
|
i0.ɵɵadvance();
|
|
447
447
|
i0.ɵɵconditional(ctx.isArtifactPanelOpen && ctx.activeArtifactId ? 3 : -1);
|
|
448
|
-
} }, dependencies: [i1.CollectionsFullViewComponent, i4.ArtifactViewerPanelComponent], styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background:
|
|
448
|
+
} }, dependencies: [i1.CollectionsFullViewComponent, i4.ArtifactViewerPanelComponent], styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background: var(--mj-brand-primary);\n }\n\n .artifact-panel-resize-handle:active {\n background: var(--mj-brand-primary-hover);\n }\n\n .artifact-panel {\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n transition: width 0.2s ease;\n }\n\n .artifact-panel.maximized {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n }\n "], encapsulation: 2 });
|
|
449
449
|
};
|
|
450
450
|
ChatCollectionsResource = __decorate([
|
|
451
451
|
RegisterClass(BaseResourceComponent, 'ChatCollectionsResource')
|
|
@@ -493,7 +493,7 @@ export { ChatCollectionsResource };
|
|
|
493
493
|
</div>
|
|
494
494
|
}
|
|
495
495
|
</div>
|
|
496
|
-
`, encapsulation: ViewEncapsulation.None, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background:
|
|
496
|
+
`, encapsulation: ViewEncapsulation.None, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background: var(--mj-brand-primary);\n }\n\n .artifact-panel-resize-handle:active {\n background: var(--mj-brand-primary-hover);\n }\n\n .artifact-panel {\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n transition: width 0.2s ease;\n }\n\n .artifact-panel.maximized {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n }\n "] }]
|
|
497
497
|
}], () => [{ type: i1.ArtifactStateService }, { type: i1.ArtifactPermissionService }, { type: i1.CollectionStateService }, { type: i2.NavigationService }, { type: i3.Router }], null); })();
|
|
498
498
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ChatCollectionsResource, { className: "ChatCollectionsResource", filePath: "src/lib/resource-wrappers/chat-collections-resource.component.ts", lineNumber: 122 }); })();
|
|
499
499
|
//# sourceMappingURL=chat-collections-resource.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-collections-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/chat-collections-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewEncapsulation, OnInit, OnDestroy } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { Metadata, CompositeKey } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { ArtifactStateService, ArtifactPermissionService, CollectionStateService } from '@memberjunction/ng-conversations';\nimport { Subject, takeUntil, distinctUntilChanged, combineLatest, filter } from 'rxjs';\n/**\n * Chat Collections Resource - displays the collections full view for tab-based display\n * Extends BaseResourceComponent to work with the resource type system\n * Shows all collections and their artifacts in a comprehensive view\n * Includes artifact panel support for viewing selected artifacts\n */\n@RegisterClass(BaseResourceComponent, 'ChatCollectionsResource')\n@Component({\n standalone: false,\n selector: 'mj-chat-collections-resource',\n template: `\n <div class=\"chat-collections-container\">\n <!-- Collections view -->\n <div class=\"collections-main\" [class.with-artifact-panel]=\"isArtifactPanelOpen && activeArtifactId\">\n @if (currentUser) {\n <mj-collections-full-view\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\">\n </mj-collections-full-view>\n }\n </div>\n \n <!-- Artifact Panel -->\n @if (isArtifactPanelOpen && activeArtifactId) {\n @if (!isArtifactPanelMaximized) {\n <div class=\"artifact-panel-resize-handle\"\n (mousedown)=\"onResizeStart($event)\"></div>\n }\n <div class=\"artifact-panel\"\n [style.width.%]=\"artifactPanelWidth\"\n [class.maximized]=\"isArtifactPanelMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"activeArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"activeVersionNumber ?? undefined\"\n [showSaveToCollection]=\"false\"\n [viewContext]=\"'collection'\"\n [contextCollectionId]=\"collectionState.activeCollectionId ?? undefined\"\n [canShare]=\"canShareActiveArtifact\"\n [canEdit]=\"canEditActiveArtifact\"\n [isMaximized]=\"isArtifactPanelMaximized\"\n (closed)=\"closeArtifactPanel()\"\n (maximizeToggled)=\"toggleMaximizeArtifactPanel()\"\n (navigateToLink)=\"onNavigateToLink($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background: #0076B6;\n }\n\n .artifact-panel-resize-handle:active {\n background: #005a8c;\n }\n\n .artifact-panel {\n border-left: 1px solid #e0e0e0;\n background: white;\n transition: width 0.2s ease;\n }\n\n .artifact-panel.maximized {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ChatCollectionsResource extends BaseResourceComponent implements OnInit, OnDestroy {\n public currentUser: any = null;\n\n // Artifact panel state\n public isArtifactPanelOpen: boolean = false;\n public activeArtifactId: string | null = null;\n public activeVersionNumber: number | null = null;\n public canShareActiveArtifact: boolean = false;\n public canEditActiveArtifact: boolean = false;\n public artifactPanelWidth: number = 40; // Default 40% width (percentage-based)\n public isArtifactPanelMaximized: boolean = false;\n private artifactPanelWidthBeforeMaximize: number = 40; // Store width before maximizing\n\n // Resize state\n private isResizing: boolean = false;\n private resizeStartX: number = 0;\n private resizeStartWidth: number = 0;\n\n private destroy$ = new Subject<void>();\n private skipUrlUpdate = true; // Skip URL updates during initialization\n private lastNavigatedUrl: string = ''; // Track URL to avoid reacting to our own navigation\n\n constructor(\n private artifactState: ArtifactStateService,\n private artifactPermissionService: ArtifactPermissionService,\n public collectionState: CollectionStateService,\n private navigationService: NavigationService,\n private router: Router\n ) {\n super();\n }\n\n ngOnInit() {\n const md = new Metadata();\n this.currentUser = md.CurrentUser;\n\n // Subscribe to artifact state changes\n this.subscribeToArtifactState();\n\n // Setup resize listeners\n this.setupResizeListeners();\n\n // Parse URL first and apply state\n const urlState = this.parseUrlState();\n if (urlState) {\n this.applyUrlState(urlState);\n } else {\n // Check if we have navigation params from config (e.g., from Conversations linking here)\n this.applyNavigationParams();\n }\n\n // Subscribe to state changes to update URL\n this.subscribeToUrlStateChanges();\n\n // Subscribe to router NavigationEnd events for back/forward button support\n this.router.events\n .pipe(\n filter((event): event is NavigationEnd => event instanceof NavigationEnd),\n takeUntil(this.destroy$)\n )\n .subscribe(event => {\n const currentUrl = event.urlAfterRedirects || event.url;\n if (currentUrl !== this.lastNavigatedUrl) {\n this.onExternalNavigation(currentUrl);\n }\n });\n\n // Enable URL updates after initialization\n this.skipUrlUpdate = false;\n\n // Update URL to reflect current state\n this.updateUrl();\n\n // Notify load complete after user is set\n setTimeout(() => {\n this.NotifyLoadComplete();\n }, 100);\n }\n\n /**\n * Parse URL query string for collection state.\n * Query params: collectionId, artifactId, versionNumber\n */\n private parseUrlState(): { collectionId?: string; artifactId?: string; versionNumber?: number } | null {\n const url = this.router.url;\n const queryIndex = url.indexOf('?');\n if (queryIndex === -1) return null;\n\n const queryString = url.substring(queryIndex + 1);\n const params = new URLSearchParams(queryString);\n const collectionId = params.get('collectionId');\n const artifactId = params.get('artifactId');\n const versionNumber = params.get('versionNumber');\n\n if (!collectionId && !artifactId) return null;\n\n return {\n collectionId: collectionId || undefined,\n artifactId: artifactId || undefined,\n versionNumber: versionNumber ? parseInt(versionNumber, 10) : undefined\n };\n }\n\n /**\n * Apply URL state to collection services.\n */\n private applyUrlState(state: { collectionId?: string; artifactId?: string; versionNumber?: number }): void {\n // Set active collection if specified\n if (state.collectionId) {\n this.collectionState.setActiveCollection(state.collectionId);\n }\n\n // Open artifact if specified\n if (state.artifactId) {\n this.artifactState.openArtifact(state.artifactId, state.versionNumber);\n }\n }\n\n /**\n * Apply navigation parameters from configuration.\n * This handles deep-linking from other resources (e.g., clicking a link in Conversations).\n */\n private applyNavigationParams(): void {\n const config = this.Data?.Configuration;\n if (!config) return;\n\n // Set active collection if specified\n if (config.collectionId) {\n this.collectionState.setActiveCollection(config.collectionId as string);\n }\n\n // Open artifact if specified\n if (config.artifactId) {\n const versionNumber = config.versionNumber ? (config.versionNumber as number) : undefined;\n this.artifactState.openArtifact(config.artifactId as string, versionNumber);\n }\n }\n\n /**\n * Subscribe to state changes for URL updates.\n */\n private subscribeToUrlStateChanges(): void {\n // Combine collection and artifact state changes\n combineLatest([\n this.collectionState.activeCollectionId$.pipe(distinctUntilChanged()),\n this.artifactState.activeArtifactId$.pipe(distinctUntilChanged()),\n this.artifactState.activeVersionNumber$.pipe(distinctUntilChanged())\n ])\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (!this.skipUrlUpdate) {\n this.updateUrl();\n }\n });\n }\n\n /**\n * Update URL query string to reflect current state.\n * Uses NavigationService for proper URL management that respects app-scoped routes.\n */\n private updateUrl(): void {\n const queryParams: Record<string, string | null> = {};\n\n // Add collection ID\n const collectionId = this.collectionState.activeCollectionId;\n if (collectionId) {\n queryParams['collectionId'] = collectionId;\n } else {\n queryParams['collectionId'] = null;\n }\n\n // Add artifact ID if panel is open\n if (this.activeArtifactId) {\n queryParams['artifactId'] = this.activeArtifactId;\n if (this.activeVersionNumber) {\n queryParams['versionNumber'] = this.activeVersionNumber.toString();\n }\n } else {\n queryParams['artifactId'] = null;\n queryParams['versionNumber'] = null;\n }\n\n // Use NavigationService to update query params properly\n this.navigationService.UpdateActiveTabQueryParams(queryParams);\n }\n\n /**\n * Handle external navigation (back/forward buttons).\n * Parses the URL and applies the state without triggering a new navigation.\n */\n private onExternalNavigation(url: string): void {\n // Check if this URL is for our component (contains our base path)\n const currentPath = this.router.url.split('?')[0];\n const newPath = url.split('?')[0];\n\n // Only handle if we're still on the same base path (same component instance)\n if (currentPath !== newPath) {\n return; // Different route entirely, shell will handle it\n }\n\n // Parse the new URL state\n const urlState = this.parseUrlFromString(url);\n\n // Apply the state without triggering URL updates\n this.skipUrlUpdate = true;\n if (urlState) {\n this.applyUrlState(urlState);\n } else {\n // No params means clear state\n this.collectionState.setActiveCollection(null as unknown as string);\n this.artifactState.closeArtifact();\n }\n this.skipUrlUpdate = false;\n\n // Update the tracked URL\n this.lastNavigatedUrl = url;\n }\n\n /**\n * Parse URL state from a URL string (used for external navigation).\n */\n private parseUrlFromString(url: string): { collectionId?: string; artifactId?: string; versionNumber?: number } | null {\n const queryIndex = url.indexOf('?');\n if (queryIndex === -1) return null;\n\n const queryString = url.substring(queryIndex + 1);\n const params = new URLSearchParams(queryString);\n const collectionId = params.get('collectionId');\n const artifactId = params.get('artifactId');\n const versionNumber = params.get('versionNumber');\n\n if (!collectionId && !artifactId) return null;\n\n return {\n collectionId: collectionId || undefined,\n artifactId: artifactId || undefined,\n versionNumber: versionNumber ? parseInt(versionNumber, 10) : undefined\n };\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n this.removeResizeListeners();\n }\n\n /**\n * Subscribe to artifact state service for panel open/close\n */\n private subscribeToArtifactState(): void {\n // Subscribe to panel open state\n this.artifactState.isPanelOpen$\n .pipe(takeUntil(this.destroy$))\n .subscribe(isOpen => {\n this.isArtifactPanelOpen = isOpen;\n });\n\n // Subscribe to active artifact ID\n this.artifactState.activeArtifactId$\n .pipe(takeUntil(this.destroy$))\n .subscribe(async id => {\n this.activeArtifactId = id;\n if (id) {\n await this.loadArtifactPermissions(id);\n } else {\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n }\n });\n\n // Subscribe to active version number\n this.artifactState.activeVersionNumber$\n .pipe(takeUntil(this.destroy$))\n .subscribe(versionNumber => {\n this.activeVersionNumber = versionNumber;\n });\n }\n\n /**\n * Load permissions for the active artifact\n */\n private async loadArtifactPermissions(artifactId: string): Promise<void> {\n if (!artifactId || !this.currentUser) {\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n return;\n }\n\n try {\n const permissions = await this.artifactPermissionService.getUserPermissions(artifactId, this.currentUser);\n this.canShareActiveArtifact = permissions.canShare;\n this.canEditActiveArtifact = permissions.canEdit;\n } catch (error) {\n console.error('Failed to load artifact permissions:', error);\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n }\n }\n\n /**\n * Close the artifact panel\n */\n closeArtifactPanel(): void {\n this.artifactState.closeArtifact();\n }\n\n /**\n * Toggle maximize/restore state for artifact panel\n */\n toggleMaximizeArtifactPanel(): void {\n if (this.isArtifactPanelMaximized) {\n // Restore to previous width\n this.artifactPanelWidth = this.artifactPanelWidthBeforeMaximize;\n this.isArtifactPanelMaximized = false;\n } else {\n // Maximize - store current width and set to 100%\n this.artifactPanelWidthBeforeMaximize = this.artifactPanelWidth;\n this.artifactPanelWidth = 100;\n this.isArtifactPanelMaximized = true;\n }\n }\n\n /**\n * Handle navigation request from artifact viewer panel.\n * Converts the link event to a generic navigation request and uses NavigationService.\n */\n onNavigateToLink(event: {\n type: 'conversation' | 'collection';\n id: string;\n artifactId?: string;\n versionNumber?: number;\n versionId?: string;\n }): void {\n // Map the link type to the nav item name\n const navItemName = event.type === 'conversation' ? 'Conversations' : 'Collections';\n\n // Build configuration params to pass to the target resource\n const params: Record<string, unknown> = {};\n if (event.type === 'conversation') {\n params['conversationId'] = event.id;\n } else {\n params['collectionId'] = event.id;\n }\n\n // Include artifact info so destination can open it\n if (event.artifactId) {\n params['artifactId'] = event.artifactId;\n if (event.versionNumber) {\n params['versionNumber'] = event.versionNumber;\n }\n }\n\n // Navigate using the generic nav item method\n this.navigationService.OpenNavItemByName(navItemName, params);\n }\n\n /**\n * Handle entity record open request from artifact viewer (from React component grids).\n * Uses NavigationService to open the record in a new tab.\n */\n onOpenEntityRecord(event: {entityName: string; compositeKey: CompositeKey}): void {\n this.navigationService.OpenEntityRecord(event.entityName, event.compositeKey);\n }\n\n /**\n * Get the environment ID from configuration or use default\n */\n get environmentId(): string {\n return this.Data?.Configuration?.environmentId || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n\n /**\n * Get the display name for chat collections\n */\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Collections';\n }\n\n /**\n * Get the icon class for chat collections\n */\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-folder-open';\n }\n\n // Resize handling\n private setupResizeListeners(): void {\n this.boundOnResizeMove = this.onResizeMove.bind(this);\n this.boundOnResizeEnd = this.onResizeEnd.bind(this);\n }\n\n private removeResizeListeners(): void {\n window.removeEventListener('mousemove', this.boundOnResizeMove);\n window.removeEventListener('mouseup', this.boundOnResizeEnd);\n }\n\n private boundOnResizeMove: (e: MouseEvent) => void = () => {};\n private boundOnResizeEnd: (e: MouseEvent) => void = () => {};\n\n onResizeStart(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.artifactPanelWidth;\n window.addEventListener('mousemove', this.boundOnResizeMove);\n window.addEventListener('mouseup', this.boundOnResizeEnd);\n event.preventDefault();\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n private onResizeMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const container = document.querySelector('.chat-collections-container') as HTMLElement;\n if (!container) return;\n\n const containerWidth = container.offsetWidth;\n const deltaX = event.clientX - this.resizeStartX;\n const deltaPercent = (deltaX / containerWidth) * -100; // Negative because we're pulling from the right\n let newWidth = this.resizeStartWidth + deltaPercent;\n\n // Constrain between 20% and 80%\n newWidth = Math.max(20, Math.min(80, newWidth));\n this.artifactPanelWidth = newWidth;\n }\n\n private onResizeEnd(event: MouseEvent): void {\n this.isResizing = false;\n window.removeEventListener('mousemove', this.boundOnResizeMove);\n window.removeEventListener('mouseup', this.boundOnResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat-collections-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/chat-collections-resource.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AAChF,OAAO,EAAU,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAgB,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAgB,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE1F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;;;;;;;IAgB7E,8CAG2B;;;IADzB,AADA,oDAA+B,mCACJ;;;;IAQ7B,8BACoC;IAApC,qNAAa,4BAAqB,KAAC;IAAC,iBAAM;;;;IAF5C,uGAAiC;IAO/B,AAHF,8BAE+C,kCAeK;IAAhD,AADA,AADA,AADA,+MAAU,2BAAoB,KAAC,oNACZ,oCAA6B,KAAC,wNAC/B,+BAAwB,KAAC,4NACvB,iCAA0B,KAAC;IAEnD,AADE,iBAA2B,EACvB;;;IAvBN,2DAGC;IAEC,cAAoC;IAApC,uDAAoC;IACpC,4DAA4C;IAE1C,cAA+B;IAS/B,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,oDAA+B,mCACJ,uCACI,0DACmB,+BACpB,6BACF,+EAC2C,2CACpC,yCACF,gDACO;;AAzCpD;;;;;GAKG;AA4GI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,qBAAqB;IAuBtD;IACA;IACD;IACC;IACA;IA1BH,WAAW,GAAQ,IAAI,CAAC;IAE/B,uBAAuB;IAChB,mBAAmB,GAAY,KAAK,CAAC;IACrC,gBAAgB,GAAkB,IAAI,CAAC;IACvC,mBAAmB,GAAkB,IAAI,CAAC;IAC1C,sBAAsB,GAAY,KAAK,CAAC;IACxC,qBAAqB,GAAY,KAAK,CAAC;IACvC,kBAAkB,GAAW,EAAE,CAAC,CAAC,uCAAuC;IACxE,wBAAwB,GAAY,KAAK,CAAC;IACzC,gCAAgC,GAAW,EAAE,CAAC,CAAC,gCAAgC;IAEvF,eAAe;IACP,UAAU,GAAY,KAAK,CAAC;IAC5B,YAAY,GAAW,CAAC,CAAC;IACzB,gBAAgB,GAAW,CAAC,CAAC;IAE7B,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,aAAa,GAAG,IAAI,CAAC,CAAC,yCAAyC;IAC/D,gBAAgB,GAAW,EAAE,CAAC,CAAC,oDAAoD;IAE3F,YACU,aAAmC,EACnC,yBAAoD,EACrD,eAAuC,EACtC,iBAAoC,EACpC,MAAc;QAEtB,KAAK,EAAE,CAAC;QANA,kBAAa,GAAb,aAAa,CAAsB;QACnC,8BAAyB,GAAzB,yBAAyB,CAA2B;QACrD,oBAAe,GAAf,eAAe,CAAwB;QACtC,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,WAAM,GAAN,MAAM,CAAQ;IAGxB,CAAC;IAED,QAAQ;QACN,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;QAElC,sCAAsC;QACtC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,yBAAyB;QACzB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5B,kCAAkC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,yFAAyF;YACzF,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAElC,2EAA2E;QAC3E,IAAI,CAAC,MAAM,CAAC,MAAM;aACf,IAAI,CACH,MAAM,CAAC,CAAC,KAAK,EAA0B,EAAE,CAAC,KAAK,YAAY,aAAa,CAAC,EACzE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB;aACA,SAAS,CAAC,KAAK,CAAC,EAAE;YACjB,MAAM,UAAU,GAAG,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,GAAG,CAAC;YACxD,IAAI,UAAU,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACzC,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,0CAA0C;QAC1C,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAE3B,sCAAsC;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjB,yCAAyC;QACzC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED;;;OAGG;IACK,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAElD,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAE9C,OAAO;YACL,YAAY,EAAE,YAAY,IAAI,SAAS;YACvC,UAAU,EAAE,UAAU,IAAI,SAAS;YACnC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,KAA6E;QACjG,qCAAqC;QACrC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC/D,CAAC;QAED,6BAA6B;QAC7B,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,qBAAqB;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,qCAAqC;QACrC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,MAAM,CAAC,YAAsB,CAAC,CAAC;QAC1E,CAAC;QAED,6BAA6B;QAC7B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAE,MAAM,CAAC,aAAwB,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,UAAoB,EAAE,aAAa,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,gDAAgD;QAChD,aAAa,CAAC;YACZ,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACrE,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACjE,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;SACrE,CAAC;aACC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACK,SAAS;QACf,MAAM,WAAW,GAAkC,EAAE,CAAC;QAEtD,oBAAoB;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;QAC7D,IAAI,YAAY,EAAE,CAAC;YACjB,WAAW,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;QACrC,CAAC;QAED,mCAAmC;QACnC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,WAAW,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAClD,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,WAAW,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC;YACrE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;YACjC,WAAW,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;QACtC,CAAC;QAED,wDAAwD;QACxD,IAAI,CAAC,iBAAiB,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACjE,CAAC;IAED;;;OAGG;IACK,oBAAoB,CAAC,GAAW;QACtC,kEAAkE;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAElC,6EAA6E;QAC7E,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,iDAAiD;QAC3D,CAAC;QAED,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE9C,iDAAiD;QACjD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,8BAA8B;YAC9B,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,IAAyB,CAAC,CAAC;YACpE,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAE3B,yBAAyB;QACzB,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,GAAW;QACpC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAElD,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAE9C,OAAO;YACL,YAAY,EAAE,YAAY,IAAI,SAAS;YACvC,UAAU,EAAE,UAAU,IAAI,SAAS;YACnC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC9B,gCAAgC;QAChC,IAAI,CAAC,aAAa,CAAC,YAAY;aAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,MAAM,CAAC,EAAE;YAClB,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC;QACpC,CAAC,CAAC,CAAC;QAEL,kCAAkC;QAClC,IAAI,CAAC,aAAa,CAAC,iBAAiB;aACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;YACpB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC3B,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;gBACpC,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,qCAAqC;QACrC,IAAI,CAAC,aAAa,CAAC,oBAAoB;aACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,aAAa,CAAC,EAAE;YACzB,IAAI,CAAC,mBAAmB,GAAG,aAAa,CAAC;QAC3C,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB,CAAC,UAAkB;QACtD,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;YACpC,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1G,IAAI,CAAC,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC;YACnD,IAAI,CAAC,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAC7D,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;YACpC,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,2BAA2B;QACzB,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,4BAA4B;YAC5B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,gCAAgC,CAAC;YAChE,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,IAAI,CAAC,gCAAgC,GAAG,IAAI,CAAC,kBAAkB,CAAC;YAChE,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC;YAC9B,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,KAMhB;QACC,yCAAyC;QACzC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC;QAEpF,4DAA4D;QAC5D,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,MAAM,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QACpC,CAAC;QAED,mDAAmD;QACnD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;YACxC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACxB,MAAM,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC;YAChD,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,KAAuD;QACxE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACH,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,aAAa,IAAI,2BAA2B,CAAC,oBAAoB,CAAC;IACrG,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC7C,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QAC3C,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,kBAAkB;IACV,oBAAoB;QAC1B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAEO,qBAAqB;QAC3B,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/D,CAAC;IAEO,iBAAiB,GAA4B,GAAG,EAAE,GAAE,CAAC,CAAC;IACtD,gBAAgB,GAA4B,GAAG,EAAE,GAAE,CAAC,CAAC;IAE7D,aAAa,CAAC,KAAiB;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7D,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1D,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAC1C,CAAC;IAEO,YAAY,CAAC,KAAiB;QACpC,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,6BAA6B,CAAgB,CAAC;QACvF,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,CAAC;QAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QACjD,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,gDAAgD;QACvG,IAAI,QAAQ,GAAG,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC;QAEpD,gCAAgC;QAChC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACrC,CAAC;IAEO,WAAW,CAAC,KAAiB;QACnC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;IACtC,CAAC;iHAhbU,uBAAuB;6DAAvB,uBAAuB;YApG9B,AAFF,8BAAwC,aAE8D;YAClG,8GAAmB;YAMrB,iBAAM;YAGN,gFAA+C;YA0BjD,iBAAM;;YApC0B,cAAqE;YAArE,sFAAqE;YACjG,cAKC;YALD,0CAKC;YAIH,cAyBC;YAzBD,0EAyBC;;;AAiEM,uBAAuB;IA3GnC,aAAa,CAAC,qBAAqB,EAAE,yBAAyB,CAAC;GA2GnD,uBAAuB,CAibnC;;iFAjbY,uBAAuB;cA1GnC,SAAS;6BACI,KAAK,YACP,8BAA8B,YAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwCP,iBA6DY,iBAAiB,CAAC,IAAI;;kFAE1B,uBAAuB","sourcesContent":["import { Component, ViewEncapsulation, OnInit, OnDestroy } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { Metadata, CompositeKey } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { ArtifactStateService, ArtifactPermissionService, CollectionStateService } from '@memberjunction/ng-conversations';\nimport { Subject, takeUntil, distinctUntilChanged, combineLatest, filter } from 'rxjs';\n/**\n * Chat Collections Resource - displays the collections full view for tab-based display\n * Extends BaseResourceComponent to work with the resource type system\n * Shows all collections and their artifacts in a comprehensive view\n * Includes artifact panel support for viewing selected artifacts\n */\n@RegisterClass(BaseResourceComponent, 'ChatCollectionsResource')\n@Component({\n standalone: false,\n selector: 'mj-chat-collections-resource',\n template: `\n <div class=\"chat-collections-container\">\n <!-- Collections view -->\n <div class=\"collections-main\" [class.with-artifact-panel]=\"isArtifactPanelOpen && activeArtifactId\">\n @if (currentUser) {\n <mj-collections-full-view\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\">\n </mj-collections-full-view>\n }\n </div>\n \n <!-- Artifact Panel -->\n @if (isArtifactPanelOpen && activeArtifactId) {\n @if (!isArtifactPanelMaximized) {\n <div class=\"artifact-panel-resize-handle\"\n (mousedown)=\"onResizeStart($event)\"></div>\n }\n <div class=\"artifact-panel\"\n [style.width.%]=\"artifactPanelWidth\"\n [class.maximized]=\"isArtifactPanelMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"activeArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"activeVersionNumber ?? undefined\"\n [showSaveToCollection]=\"false\"\n [viewContext]=\"'collection'\"\n [contextCollectionId]=\"collectionState.activeCollectionId ?? undefined\"\n [canShare]=\"canShareActiveArtifact\"\n [canEdit]=\"canEditActiveArtifact\"\n [isMaximized]=\"isArtifactPanelMaximized\"\n (closed)=\"closeArtifactPanel()\"\n (maximizeToggled)=\"toggleMaximizeArtifactPanel()\"\n (navigateToLink)=\"onNavigateToLink($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-collections-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative; /* Required for absolute positioning of maximized panel */\n }\n\n .collections-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .collections-main.with-artifact-panel {\n /* When artifact panel is open, main area shrinks */\n }\n\n .artifact-panel-resize-handle {\n width: 8px;\n cursor: col-resize;\n background: transparent;\n transition: background 150ms ease;\n flex-shrink: 0;\n }\n\n .artifact-panel-resize-handle:hover {\n background: var(--mj-brand-primary);\n }\n\n .artifact-panel-resize-handle:active {\n background: var(--mj-brand-primary-hover);\n }\n\n .artifact-panel {\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n transition: width 0.2s ease;\n }\n\n .artifact-panel.maximized {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ChatCollectionsResource extends BaseResourceComponent implements OnInit, OnDestroy {\n public currentUser: any = null;\n\n // Artifact panel state\n public isArtifactPanelOpen: boolean = false;\n public activeArtifactId: string | null = null;\n public activeVersionNumber: number | null = null;\n public canShareActiveArtifact: boolean = false;\n public canEditActiveArtifact: boolean = false;\n public artifactPanelWidth: number = 40; // Default 40% width (percentage-based)\n public isArtifactPanelMaximized: boolean = false;\n private artifactPanelWidthBeforeMaximize: number = 40; // Store width before maximizing\n\n // Resize state\n private isResizing: boolean = false;\n private resizeStartX: number = 0;\n private resizeStartWidth: number = 0;\n\n private destroy$ = new Subject<void>();\n private skipUrlUpdate = true; // Skip URL updates during initialization\n private lastNavigatedUrl: string = ''; // Track URL to avoid reacting to our own navigation\n\n constructor(\n private artifactState: ArtifactStateService,\n private artifactPermissionService: ArtifactPermissionService,\n public collectionState: CollectionStateService,\n private navigationService: NavigationService,\n private router: Router\n ) {\n super();\n }\n\n ngOnInit() {\n const md = new Metadata();\n this.currentUser = md.CurrentUser;\n\n // Subscribe to artifact state changes\n this.subscribeToArtifactState();\n\n // Setup resize listeners\n this.setupResizeListeners();\n\n // Parse URL first and apply state\n const urlState = this.parseUrlState();\n if (urlState) {\n this.applyUrlState(urlState);\n } else {\n // Check if we have navigation params from config (e.g., from Conversations linking here)\n this.applyNavigationParams();\n }\n\n // Subscribe to state changes to update URL\n this.subscribeToUrlStateChanges();\n\n // Subscribe to router NavigationEnd events for back/forward button support\n this.router.events\n .pipe(\n filter((event): event is NavigationEnd => event instanceof NavigationEnd),\n takeUntil(this.destroy$)\n )\n .subscribe(event => {\n const currentUrl = event.urlAfterRedirects || event.url;\n if (currentUrl !== this.lastNavigatedUrl) {\n this.onExternalNavigation(currentUrl);\n }\n });\n\n // Enable URL updates after initialization\n this.skipUrlUpdate = false;\n\n // Update URL to reflect current state\n this.updateUrl();\n\n // Notify load complete after user is set\n setTimeout(() => {\n this.NotifyLoadComplete();\n }, 100);\n }\n\n /**\n * Parse URL query string for collection state.\n * Query params: collectionId, artifactId, versionNumber\n */\n private parseUrlState(): { collectionId?: string; artifactId?: string; versionNumber?: number } | null {\n const url = this.router.url;\n const queryIndex = url.indexOf('?');\n if (queryIndex === -1) return null;\n\n const queryString = url.substring(queryIndex + 1);\n const params = new URLSearchParams(queryString);\n const collectionId = params.get('collectionId');\n const artifactId = params.get('artifactId');\n const versionNumber = params.get('versionNumber');\n\n if (!collectionId && !artifactId) return null;\n\n return {\n collectionId: collectionId || undefined,\n artifactId: artifactId || undefined,\n versionNumber: versionNumber ? parseInt(versionNumber, 10) : undefined\n };\n }\n\n /**\n * Apply URL state to collection services.\n */\n private applyUrlState(state: { collectionId?: string; artifactId?: string; versionNumber?: number }): void {\n // Set active collection if specified\n if (state.collectionId) {\n this.collectionState.setActiveCollection(state.collectionId);\n }\n\n // Open artifact if specified\n if (state.artifactId) {\n this.artifactState.openArtifact(state.artifactId, state.versionNumber);\n }\n }\n\n /**\n * Apply navigation parameters from configuration.\n * This handles deep-linking from other resources (e.g., clicking a link in Conversations).\n */\n private applyNavigationParams(): void {\n const config = this.Data?.Configuration;\n if (!config) return;\n\n // Set active collection if specified\n if (config.collectionId) {\n this.collectionState.setActiveCollection(config.collectionId as string);\n }\n\n // Open artifact if specified\n if (config.artifactId) {\n const versionNumber = config.versionNumber ? (config.versionNumber as number) : undefined;\n this.artifactState.openArtifact(config.artifactId as string, versionNumber);\n }\n }\n\n /**\n * Subscribe to state changes for URL updates.\n */\n private subscribeToUrlStateChanges(): void {\n // Combine collection and artifact state changes\n combineLatest([\n this.collectionState.activeCollectionId$.pipe(distinctUntilChanged()),\n this.artifactState.activeArtifactId$.pipe(distinctUntilChanged()),\n this.artifactState.activeVersionNumber$.pipe(distinctUntilChanged())\n ])\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (!this.skipUrlUpdate) {\n this.updateUrl();\n }\n });\n }\n\n /**\n * Update URL query string to reflect current state.\n * Uses NavigationService for proper URL management that respects app-scoped routes.\n */\n private updateUrl(): void {\n const queryParams: Record<string, string | null> = {};\n\n // Add collection ID\n const collectionId = this.collectionState.activeCollectionId;\n if (collectionId) {\n queryParams['collectionId'] = collectionId;\n } else {\n queryParams['collectionId'] = null;\n }\n\n // Add artifact ID if panel is open\n if (this.activeArtifactId) {\n queryParams['artifactId'] = this.activeArtifactId;\n if (this.activeVersionNumber) {\n queryParams['versionNumber'] = this.activeVersionNumber.toString();\n }\n } else {\n queryParams['artifactId'] = null;\n queryParams['versionNumber'] = null;\n }\n\n // Use NavigationService to update query params properly\n this.navigationService.UpdateActiveTabQueryParams(queryParams);\n }\n\n /**\n * Handle external navigation (back/forward buttons).\n * Parses the URL and applies the state without triggering a new navigation.\n */\n private onExternalNavigation(url: string): void {\n // Check if this URL is for our component (contains our base path)\n const currentPath = this.router.url.split('?')[0];\n const newPath = url.split('?')[0];\n\n // Only handle if we're still on the same base path (same component instance)\n if (currentPath !== newPath) {\n return; // Different route entirely, shell will handle it\n }\n\n // Parse the new URL state\n const urlState = this.parseUrlFromString(url);\n\n // Apply the state without triggering URL updates\n this.skipUrlUpdate = true;\n if (urlState) {\n this.applyUrlState(urlState);\n } else {\n // No params means clear state\n this.collectionState.setActiveCollection(null as unknown as string);\n this.artifactState.closeArtifact();\n }\n this.skipUrlUpdate = false;\n\n // Update the tracked URL\n this.lastNavigatedUrl = url;\n }\n\n /**\n * Parse URL state from a URL string (used for external navigation).\n */\n private parseUrlFromString(url: string): { collectionId?: string; artifactId?: string; versionNumber?: number } | null {\n const queryIndex = url.indexOf('?');\n if (queryIndex === -1) return null;\n\n const queryString = url.substring(queryIndex + 1);\n const params = new URLSearchParams(queryString);\n const collectionId = params.get('collectionId');\n const artifactId = params.get('artifactId');\n const versionNumber = params.get('versionNumber');\n\n if (!collectionId && !artifactId) return null;\n\n return {\n collectionId: collectionId || undefined,\n artifactId: artifactId || undefined,\n versionNumber: versionNumber ? parseInt(versionNumber, 10) : undefined\n };\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n this.removeResizeListeners();\n }\n\n /**\n * Subscribe to artifact state service for panel open/close\n */\n private subscribeToArtifactState(): void {\n // Subscribe to panel open state\n this.artifactState.isPanelOpen$\n .pipe(takeUntil(this.destroy$))\n .subscribe(isOpen => {\n this.isArtifactPanelOpen = isOpen;\n });\n\n // Subscribe to active artifact ID\n this.artifactState.activeArtifactId$\n .pipe(takeUntil(this.destroy$))\n .subscribe(async id => {\n this.activeArtifactId = id;\n if (id) {\n await this.loadArtifactPermissions(id);\n } else {\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n }\n });\n\n // Subscribe to active version number\n this.artifactState.activeVersionNumber$\n .pipe(takeUntil(this.destroy$))\n .subscribe(versionNumber => {\n this.activeVersionNumber = versionNumber;\n });\n }\n\n /**\n * Load permissions for the active artifact\n */\n private async loadArtifactPermissions(artifactId: string): Promise<void> {\n if (!artifactId || !this.currentUser) {\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n return;\n }\n\n try {\n const permissions = await this.artifactPermissionService.getUserPermissions(artifactId, this.currentUser);\n this.canShareActiveArtifact = permissions.canShare;\n this.canEditActiveArtifact = permissions.canEdit;\n } catch (error) {\n console.error('Failed to load artifact permissions:', error);\n this.canShareActiveArtifact = false;\n this.canEditActiveArtifact = false;\n }\n }\n\n /**\n * Close the artifact panel\n */\n closeArtifactPanel(): void {\n this.artifactState.closeArtifact();\n }\n\n /**\n * Toggle maximize/restore state for artifact panel\n */\n toggleMaximizeArtifactPanel(): void {\n if (this.isArtifactPanelMaximized) {\n // Restore to previous width\n this.artifactPanelWidth = this.artifactPanelWidthBeforeMaximize;\n this.isArtifactPanelMaximized = false;\n } else {\n // Maximize - store current width and set to 100%\n this.artifactPanelWidthBeforeMaximize = this.artifactPanelWidth;\n this.artifactPanelWidth = 100;\n this.isArtifactPanelMaximized = true;\n }\n }\n\n /**\n * Handle navigation request from artifact viewer panel.\n * Converts the link event to a generic navigation request and uses NavigationService.\n */\n onNavigateToLink(event: {\n type: 'conversation' | 'collection';\n id: string;\n artifactId?: string;\n versionNumber?: number;\n versionId?: string;\n }): void {\n // Map the link type to the nav item name\n const navItemName = event.type === 'conversation' ? 'Conversations' : 'Collections';\n\n // Build configuration params to pass to the target resource\n const params: Record<string, unknown> = {};\n if (event.type === 'conversation') {\n params['conversationId'] = event.id;\n } else {\n params['collectionId'] = event.id;\n }\n\n // Include artifact info so destination can open it\n if (event.artifactId) {\n params['artifactId'] = event.artifactId;\n if (event.versionNumber) {\n params['versionNumber'] = event.versionNumber;\n }\n }\n\n // Navigate using the generic nav item method\n this.navigationService.OpenNavItemByName(navItemName, params);\n }\n\n /**\n * Handle entity record open request from artifact viewer (from React component grids).\n * Uses NavigationService to open the record in a new tab.\n */\n onOpenEntityRecord(event: {entityName: string; compositeKey: CompositeKey}): void {\n this.navigationService.OpenEntityRecord(event.entityName, event.compositeKey);\n }\n\n /**\n * Get the environment ID from configuration or use default\n */\n get environmentId(): string {\n return this.Data?.Configuration?.environmentId || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n\n /**\n * Get the display name for chat collections\n */\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Collections';\n }\n\n /**\n * Get the icon class for chat collections\n */\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-folder-open';\n }\n\n // Resize handling\n private setupResizeListeners(): void {\n this.boundOnResizeMove = this.onResizeMove.bind(this);\n this.boundOnResizeEnd = this.onResizeEnd.bind(this);\n }\n\n private removeResizeListeners(): void {\n window.removeEventListener('mousemove', this.boundOnResizeMove);\n window.removeEventListener('mouseup', this.boundOnResizeEnd);\n }\n\n private boundOnResizeMove: (e: MouseEvent) => void = () => {};\n private boundOnResizeEnd: (e: MouseEvent) => void = () => {};\n\n onResizeStart(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.artifactPanelWidth;\n window.addEventListener('mousemove', this.boundOnResizeMove);\n window.addEventListener('mouseup', this.boundOnResizeEnd);\n event.preventDefault();\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n private onResizeMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const container = document.querySelector('.chat-collections-container') as HTMLElement;\n if (!container) return;\n\n const containerWidth = container.offsetWidth;\n const deltaX = event.clientX - this.resizeStartX;\n const deltaPercent = (deltaX / containerWidth) * -100; // Negative because we're pulling from the right\n let newWidth = this.resizeStartWidth + deltaPercent;\n\n // Constrain between 20% and 80%\n newWidth = Math.max(20, Math.min(80, newWidth));\n this.artifactPanelWidth = newWidth;\n }\n\n private onResizeEnd(event: MouseEvent): void {\n this.isResizing = false;\n window.removeEventListener('mousemove', this.boundOnResizeMove);\n window.removeEventListener('mouseup', this.boundOnResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n}\n"]}
|
|
@@ -859,7 +859,7 @@ let ChatConversationsResource = class ChatConversationsResource extends BaseReso
|
|
|
859
859
|
i0.ɵɵelement(2, "mj-toast");
|
|
860
860
|
} if (rf & 2) {
|
|
861
861
|
i0.ɵɵconditional(ctx.isReady ? 0 : 1);
|
|
862
|
-
} }, dependencies: [i2.ConversationListComponent, i2.ConversationChatAreaComponent, i2.ToastComponent, i4.LoadingComponent], styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-conversations-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative;\n }\n\n .conversation-sidebar {\n flex-shrink: 0;\n border-right: 1px solid
|
|
862
|
+
} }, dependencies: [i2.ConversationListComponent, i2.ConversationChatAreaComponent, i2.ToastComponent, i4.LoadingComponent], styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-conversations-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative;\n }\n\n .conversation-sidebar {\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n background: var(--mj-bg-surface-sunken);\n transition: width 0.3s ease;\n }\n\n /* Disable transitions during initial load to prevent jarring animation */\n .conversation-sidebar.no-transition {\n transition: none !important;\n }\n\n .conversation-sidebar.collapsed {\n width: 0 !important;\n min-width: 0;\n border-right: none;\n overflow: hidden;\n }\n\n /* Resize handle for sidebar */\n .sidebar-resize-handle {\n width: 4px;\n background: transparent;\n cursor: ew-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n }\n\n .sidebar-resize-handle:hover {\n background: var(--mj-brand-primary);\n }\n\n .sidebar-resize-handle:active {\n background: var(--mj-brand-primary-hover);\n }\n\n .sidebar-resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n cursor: ew-resize;\n }\n\n .conversation-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .initializing-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n flex: 1;\n }\n "], encapsulation: 2 });
|
|
863
863
|
};
|
|
864
864
|
ChatConversationsResource = __decorate([
|
|
865
865
|
RegisterClass(BaseResourceComponent, 'ChatConversationsResource')
|
|
@@ -939,7 +939,7 @@ export { ChatConversationsResource };
|
|
|
939
939
|
|
|
940
940
|
<!-- Toast notifications container -->
|
|
941
941
|
<mj-toast></mj-toast>
|
|
942
|
-
`, encapsulation: ViewEncapsulation.None, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-conversations-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative;\n }\n\n .conversation-sidebar {\n flex-shrink: 0;\n border-right: 1px solid
|
|
942
|
+
`, encapsulation: ViewEncapsulation.None, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .chat-conversations-container {\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n overflow: hidden;\n position: relative;\n }\n\n .conversation-sidebar {\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n background: var(--mj-bg-surface-sunken);\n transition: width 0.3s ease;\n }\n\n /* Disable transitions during initial load to prevent jarring animation */\n .conversation-sidebar.no-transition {\n transition: none !important;\n }\n\n .conversation-sidebar.collapsed {\n width: 0 !important;\n min-width: 0;\n border-right: none;\n overflow: hidden;\n }\n\n /* Resize handle for sidebar */\n .sidebar-resize-handle {\n width: 4px;\n background: transparent;\n cursor: ew-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n }\n\n .sidebar-resize-handle:hover {\n background: var(--mj-brand-primary);\n }\n\n .sidebar-resize-handle:active {\n background: var(--mj-brand-primary-hover);\n }\n\n .sidebar-resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n cursor: ew-resize;\n }\n\n .conversation-main {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .initializing-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n flex: 1;\n }\n "] }]
|
|
943
943
|
}], () => [{ type: i1.NavigationService }, { type: i2.ConversationDataService }, { type: i3.Router }, { type: i2.MentionAutocompleteService }, { type: i0.ChangeDetectorRef }, { type: i2.ConversationStreamingService }, { type: i2.ActiveTasksService }, { type: i2.UICommandHandlerService }], { conversationList: [{
|
|
944
944
|
type: ViewChild,
|
|
945
945
|
args: ['conversationList']
|