@memberjunction/ng-explorer-core 5.11.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/lib/command-palette/command-palette.component.js +2 -2
  2. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +2 -2
  3. package/dist/lib/oauth/oauth-callback.component.js +2 -2
  4. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +2 -2
  5. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  6. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +2 -2
  7. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  8. package/dist/lib/resource-wrappers/dashboard-resource.component.js +2 -2
  9. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  10. package/dist/lib/resource-wrappers/view-resource.component.js +2 -2
  11. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  12. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +4 -4
  13. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
  14. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  15. package/dist/lib/shell/components/header/app-nav.component.js +5 -5
  16. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  17. package/dist/lib/shell/components/header/app-switcher.component.js +22 -21
  18. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
  19. package/dist/lib/shell/components/tabs/tab-container.component.js +2 -2
  20. package/dist/lib/shell/loading-themes.js +1 -1
  21. package/dist/lib/shell/loading-themes.js.map +1 -1
  22. package/dist/lib/shell/shell.component.js +3 -3
  23. package/dist/lib/shell/shell.component.js.map +1 -1
  24. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +2 -2
  25. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +2 -2
  26. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +2 -2
  27. package/dist/lib/single-dashboard/single-dashboard.component.js +2 -2
  28. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  29. package/dist/lib/single-list-detail/single-list-detail.component.js +11 -7
  30. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  31. package/dist/lib/single-search-result/single-search-result.component.js +2 -2
  32. package/dist/lib/system-validation/system-validation-banner.component.js +2 -2
  33. package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
  34. package/dist/lib/user-notifications/user-notifications.component.d.ts +15 -2
  35. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  36. package/dist/lib/user-notifications/user-notifications.component.js +76 -8
  37. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  38. package/dist/lib/user-profile/user-profile.component.js +2 -2
  39. package/package.json +34 -34
@@ -229,11 +229,11 @@ export class AddItemComponent {
229
229
  i0.ɵɵtwoWayProperty("ngModel", ctx.resourceType);
230
230
  i0.ɵɵadvance(2);
231
231
  i0.ɵɵconditional((tmp_8_0 = ctx.resourceType.Entity) === "MJ: User Views" ? 7 : tmp_8_0 === "Reports" ? 8 : -1);
232
- } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.WindowComponent, i4.ButtonComponent, i5.LabelComponent, i6.DropDownListComponent, i7.LoadingComponent], styles: [".popup-actions[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n}\n .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n}\n.resource-wrap[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n.user-view-wrap[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n .resource-wrap .k-label {\n color: #424242;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n}\n .customBtn button {\n flex: 1;\n border-radius: 10px;\n line-height: 34px;\n}\n\n.no-items-message[_ngcontent-%COMP%], .no-views-message[_ngcontent-%COMP%] {\n padding: 12px;\n background-color: #f8f9fa;\n border-radius: 4px;\n color: #6c757d;\n text-align: center;\n font-size: 14px;\n margin-top: 5px;\n border: 1px dashed #dee2e6;\n}"] });
232
+ } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.WindowComponent, i4.ButtonComponent, i5.LabelComponent, i6.DropDownListComponent, i7.LoadingComponent], styles: [".popup-actions[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n}\n .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n}\n.resource-wrap[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n.user-view-wrap[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n .resource-wrap .k-label {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n}\n .customBtn button {\n flex: 1;\n border-radius: 10px;\n line-height: 34px;\n}\n\n.no-items-message[_ngcontent-%COMP%], .no-views-message[_ngcontent-%COMP%] {\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 4px;\n color: var(--mj-text-muted);\n text-align: center;\n font-size: 14px;\n margin-top: 5px;\n border: 1px dashed var(--mj-border-default);\n}"] });
233
233
  }
234
234
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AddItemComponent, [{
235
235
  type: Component,
236
- args: [{ standalone: false, selector: 'app-add-item-dialog', template: "<div class=\"k-overlay\"></div>\n<kendo-window class=\"modal-body-wrap\" [width]=\"500\" [minHeight]=\"300\" [minWidth]=\"400\" [resizable]=\"true\" (close)=\"closeDialog()\"\n title=\"Add Item to Dashboard\">\n <div class=\"k-d-flex k-flex-col resource-wrap\">\n <kendo-label text=\"Resource Type\">\n <br />\n <kendo-dropdownlist [data]=\"ResourceTypes\" [textField]=\"'DisplayName'\" [valueField]=\"'ID'\"\n (valueChange)=\"onResourceTypeChange($event)\" [(ngModel)]=\"resourceType\">\n </kendo-dropdownlist>\n </kendo-label>\n <div class=\"user-view-wrap\">\n @switch (resourceType.Entity ) {\n @case ('MJ: User Views') {\n <kendo-label text=\"Entity\">\n <br />\n <kendo-dropdownlist [data]=\"Entities\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onEntityChange($event)\" [(ngModel)]=\"selectedEntity\">\n </kendo-dropdownlist>\n </kendo-label>\n @if (selectedEntity && Views.length) {\n <kendo-label text=\"Views\">\n <br />\n <kendo-dropdownlist [data]=\"Views\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onViewChange($event)\" [(ngModel)]=\"selectedView\">\n </kendo-dropdownlist>\n </kendo-label>\n }\n @if (selectedEntity && !Views.length && showloader) {\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n }\n @if (selectedEntity && !Views.length && !showloader) {\n <div class=\"no-views-message\">\n No views available for this entity\n </div>\n }\n }\n @case ('Reports') {\n @if (Reports.length) {\n <kendo-label text=\"Reports\">\n <br />\n <kendo-dropdownlist [data]=\"Reports\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onViewChange($event)\" [(ngModel)]=\"selectedReport\">\n </kendo-dropdownlist>\n </kendo-label>\n }\n @if (!Reports.length && showloader) {\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n }\n @if (!Reports.length && !showloader) {\n <div class=\"no-items-message\">\n No reports available\n </div>\n }\n }\n }\n </div>\n </div>\n <div class=\"k-actions k-actions-end popup-actions customBtn\">\n <button themeColor=\"info\" kendoButton (click)=\"addItem()\">\n <span class=\"fa-solid fa-check\"></span> Add\n </button>\n <button themeColor=\"info\" kendoButton fillMode=\"outline\" (click)=\"closeDialog()\">Cancel</button>\n </div>\n</kendo-window>", styles: [".popup-actions {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n}\n::ng-deep .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n}\n.resource-wrap {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n.user-view-wrap {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n::ng-deep .resource-wrap .k-label {\n color: #424242;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n::ng-deep .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n}\n::ng-deep .customBtn button {\n flex: 1;\n border-radius: 10px;\n line-height: 34px;\n}\n\n.no-items-message, .no-views-message {\n padding: 12px;\n background-color: #f8f9fa;\n border-radius: 4px;\n color: #6c757d;\n text-align: center;\n font-size: 14px;\n margin-top: 5px;\n border: 1px dashed #dee2e6;\n}"] }]
236
+ args: [{ standalone: false, selector: 'app-add-item-dialog', template: "<div class=\"k-overlay\"></div>\n<kendo-window class=\"modal-body-wrap\" [width]=\"500\" [minHeight]=\"300\" [minWidth]=\"400\" [resizable]=\"true\" (close)=\"closeDialog()\"\n title=\"Add Item to Dashboard\">\n <div class=\"k-d-flex k-flex-col resource-wrap\">\n <kendo-label text=\"Resource Type\">\n <br />\n <kendo-dropdownlist [data]=\"ResourceTypes\" [textField]=\"'DisplayName'\" [valueField]=\"'ID'\"\n (valueChange)=\"onResourceTypeChange($event)\" [(ngModel)]=\"resourceType\">\n </kendo-dropdownlist>\n </kendo-label>\n <div class=\"user-view-wrap\">\n @switch (resourceType.Entity ) {\n @case ('MJ: User Views') {\n <kendo-label text=\"Entity\">\n <br />\n <kendo-dropdownlist [data]=\"Entities\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onEntityChange($event)\" [(ngModel)]=\"selectedEntity\">\n </kendo-dropdownlist>\n </kendo-label>\n @if (selectedEntity && Views.length) {\n <kendo-label text=\"Views\">\n <br />\n <kendo-dropdownlist [data]=\"Views\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onViewChange($event)\" [(ngModel)]=\"selectedView\">\n </kendo-dropdownlist>\n </kendo-label>\n }\n @if (selectedEntity && !Views.length && showloader) {\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n }\n @if (selectedEntity && !Views.length && !showloader) {\n <div class=\"no-views-message\">\n No views available for this entity\n </div>\n }\n }\n @case ('Reports') {\n @if (Reports.length) {\n <kendo-label text=\"Reports\">\n <br />\n <kendo-dropdownlist [data]=\"Reports\" [textField]=\"'Name'\" [valueField]=\"'ID'\"\n (valueChange)=\"onViewChange($event)\" [(ngModel)]=\"selectedReport\">\n </kendo-dropdownlist>\n </kendo-label>\n }\n @if (!Reports.length && showloader) {\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n }\n @if (!Reports.length && !showloader) {\n <div class=\"no-items-message\">\n No reports available\n </div>\n }\n }\n }\n </div>\n </div>\n <div class=\"k-actions k-actions-end popup-actions customBtn\">\n <button themeColor=\"info\" kendoButton (click)=\"addItem()\">\n <span class=\"fa-solid fa-check\"></span> Add\n </button>\n <button themeColor=\"info\" kendoButton fillMode=\"outline\" (click)=\"closeDialog()\">Cancel</button>\n </div>\n</kendo-window>", styles: [".popup-actions {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n}\n::ng-deep .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n}\n.resource-wrap {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n.user-view-wrap {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n::ng-deep .resource-wrap .k-label {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n::ng-deep .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n}\n::ng-deep .customBtn button {\n flex: 1;\n border-radius: 10px;\n line-height: 34px;\n}\n\n.no-items-message, .no-views-message {\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 4px;\n color: var(--mj-text-muted);\n text-align: center;\n font-size: 14px;\n margin-top: 5px;\n border: 1px dashed var(--mj-border-default);\n}\n"] }]
237
237
  }], () => [{ type: i1.SharedService }], { onClose: [{
238
238
  type: Output
239
239
  }], selectedResource: [{
@@ -44,11 +44,11 @@ export class DeleteItemComponent {
44
44
  } if (rf & 2) {
45
45
  i0.ɵɵadvance(4);
46
46
  i0.ɵɵtextInterpolate(ctx.dashboardItem == null ? null : ctx.dashboardItem.title);
47
- } }, dependencies: [i1.DialogComponent, i2.ButtonComponent], styles: [".popup-actions[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n }\n .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n }\n .resource-wrap[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .user-view-wrap[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .resource-wrap .k-label {\n color: #424242;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n }\n .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n }"] });
47
+ } }, dependencies: [i1.DialogComponent, i2.ButtonComponent], styles: [".popup-actions[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n }\n .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n }\n .resource-wrap[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .user-view-wrap[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .resource-wrap .k-label {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n }\n .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n }"] });
48
48
  }
49
49
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DeleteItemComponent, [{
50
50
  type: Component,
51
- args: [{ standalone: false, selector: 'app-delete-item-dialog', template: "<kendo-dialog class=\"modal-body-wrap\" (close)=\"closeDialog()\">\n <p class=\"k-m-7.5 k-text-center\">\n Are you sure you want to delete <b>{{dashboardItem?.title}}</b>?\n </p>\n <div class=\"k-actions k-actions-end popup-actions\">\n <button kendoButton (click)=\"confirmDeleteItem()\" themeColor=\"primary\">\n <span class=\"fa-solid fa-check\"></span> Yes\n </button>\n <button kendoButton (click)=\"closeDialog()\">\n <span class=\"fa-solid fa-xmark\"></span> No\n </button>\n </div>\n</kendo-dialog>", styles: [".popup-actions {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n }\n ::ng-deep .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n }\n .resource-wrap {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .user-view-wrap {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n ::ng-deep .resource-wrap .k-label {\n color: #424242;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n }\n ::ng-deep .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n }\n "] }]
51
+ args: [{ standalone: false, selector: 'app-delete-item-dialog', template: "<kendo-dialog class=\"modal-body-wrap\" (close)=\"closeDialog()\">\n <p class=\"k-m-7.5 k-text-center\">\n Are you sure you want to delete <b>{{dashboardItem?.title}}</b>?\n </p>\n <div class=\"k-actions k-actions-end popup-actions\">\n <button kendoButton (click)=\"confirmDeleteItem()\" themeColor=\"primary\">\n <span class=\"fa-solid fa-check\"></span> Yes\n </button>\n <button kendoButton (click)=\"closeDialog()\">\n <span class=\"fa-solid fa-xmark\"></span> No\n </button>\n </div>\n</kendo-dialog>", styles: [".popup-actions {\n width: 100%;\n padding: 10px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n }\n ::ng-deep .modal-body-wrap .k-window-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n padding: 0;\n }\n .resource-wrap {\n flex: 1;\n padding: 24px;\n margin: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n .user-view-wrap {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n ::ng-deep .resource-wrap .k-label {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n }\n ::ng-deep .resource-wrap .k-dropdownlist {\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n background: transparent;\n line-height: 32px;\n margin: 0;\n }\n"] }]
52
52
  }], null, { onClose: [{
53
53
  type: Output
54
54
  }], removeDashboardItem: [{
@@ -133,11 +133,11 @@ export class EditDashboardComponent {
133
133
  i0.ɵɵproperty("columns", ctx.config.columns)("rowHeight", ctx.config.rowHeight)("resizable", true)("reorderable", true);
134
134
  i0.ɵɵadvance();
135
135
  i0.ɵɵrepeater(ctx._items);
136
- } }, dependencies: [i1.WindowComponent, i2.ButtonComponent, i2.DropDownButtonComponent, i3.TileLayoutComponent, i3.TileLayoutItemBodyComponent, i3.TileLayoutItemComponent, i3.TileLayoutItemHeaderComponent], styles: [".dialog-content[_ngcontent-%COMP%] .dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n}\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n width: auto;\n height: 40px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n background: #FFF;\n padding: 8px 16px;\n}\n.custom-dialog-body[_ngcontent-%COMP%] {\nflex: 1;\n}\n.custom-dialog-body[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 16px;\n box-sizing: border-box;\n}\n.dialog-footer[_ngcontent-%COMP%] .k-card-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 0;\n}\n .kendo-window-hide-restore .k-window-content {\n padding: 0;\n}\n.custom-dialog-body[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] .k-tilelayout[_ngcontent-%COMP%] {\n background: #fff;\n}"] });
136
+ } }, dependencies: [i1.WindowComponent, i2.ButtonComponent, i2.DropDownButtonComponent, i3.TileLayoutComponent, i3.TileLayoutItemBodyComponent, i3.TileLayoutItemComponent, i3.TileLayoutItemHeaderComponent], styles: [".dialog-content[_ngcontent-%COMP%] .dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n}\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n width: auto;\n height: 40px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n background: var(--mj-bg-surface);\n padding: 8px 16px;\n}\n.custom-dialog-body[_ngcontent-%COMP%] {\nflex: 1;\n}\n.custom-dialog-body[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 16px;\n box-sizing: border-box;\n}\n.dialog-footer[_ngcontent-%COMP%] .k-card-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 0;\n}\n .kendo-window-hide-restore .k-window-content {\n padding: 0;\n}\n.custom-dialog-body[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] .k-tilelayout[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n}"] });
137
137
  }
138
138
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EditDashboardComponent, [{
139
139
  type: Component,
140
- args: [{ standalone: false, selector: 'app-edit-dashboard', template: "<div class=\"k-overlay\"></div>\n<kendo-window\n class=\"kendo-window-hide-restore\"\n [width]=\"500\"\n [minHeight]=\"300\"\n [minWidth]=\"400\"\n [resizable]=\"true\"\n (close)=\"closeDialog($event)\"\n [state]=\"'maximized'\"\n title=\"Customize Dashboard\">\n <div class=\"k-d-flex k-flex-col k-justify-content-between k-h-full custom-dialog-body\">\n <div class=\"dialog-content \">\n <div class=\"dialog-actions\">\n <kendo-dropdownbutton class=\"k-m-2\" themeColor=\"primary\" [data]=\"ResourceTypes\" [textField]=\"'DisplayName'\" (itemClick)=\"onItemSelect($event)\">\n <span class=\"fa-solid fa-plus\"></span> Add item\n </kendo-dropdownbutton>\n </div>\n <kendo-tilelayout\n [columns]=\"config.columns\"\n [rowHeight]=\"config.rowHeight\"\n [resizable]=\"true\"\n [reorderable]=\"true\"\n (resize)=\"onResize($event)\"\n (reorder)=\"onReorder($event)\"\n >\n @for (item of _items; track item) {\n <kendo-tilelayout-item [col]=\"item.col\" [colSpan]=\"item.colSpan\" [rowSpan]=\"item.rowSpan\" [id]=\"item.uniqueId\">\n <kendo-tilelayout-item-header>\n {{item.title}}\n <button kendoButton class=\"k-float-right\" (click)=\"removeItem(item)\">X</button>\n </kendo-tilelayout-item-header>\n <kendo-tilelayout-item-body>\n <!-- <div class=\"overlay\"></div> -->\n <!-- <app-resource [Data]=\"item.ResourceData\" [isVisible]=\"false\"></app-resource> -->\n </kendo-tilelayout-item-body>\n </kendo-tilelayout-item>\n }\n </kendo-tilelayout>\n\n </div>\n <div class=\"dialog-footer\">\n <div class=\"k-card-footer !k-border-none\">\n <button kendoButton (click)=\"closeDialog($event)\" >\n <span class=\"fa-solid fa-xmark\"></span>\n Cancel\n </button>\n <button kendoButton (click)=\"saveChanges()\">\n <span class=\"fa-solid fa-check\"></span>\n Save\n </button>\n </div>\n </div>\n </div>\n</kendo-window>", styles: [".dialog-content .dialog-actions {\n display: flex;\n justify-content: flex-end;\n}\n.dialog-footer {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n width: auto;\n height: 40px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n background: #FFF;\n padding: 8px 16px;\n}\n.custom-dialog-body {\nflex: 1;\n}\n.custom-dialog-body .dialog-content {\n flex: 1;\n overflow: auto;\n padding: 16px;\n box-sizing: border-box;\n}\n.dialog-footer .k-card-footer {\n display: flex;\n gap: 8px;\n padding: 0;\n}\n::ng-deep .kendo-window-hide-restore .k-window-content {\n padding: 0;\n}\n.custom-dialog-body .dialog-content .k-tilelayout {\n background: #fff;\n}"] }]
140
+ args: [{ standalone: false, selector: 'app-edit-dashboard', template: "<div class=\"k-overlay\"></div>\n<kendo-window\n class=\"kendo-window-hide-restore\"\n [width]=\"500\"\n [minHeight]=\"300\"\n [minWidth]=\"400\"\n [resizable]=\"true\"\n (close)=\"closeDialog($event)\"\n [state]=\"'maximized'\"\n title=\"Customize Dashboard\">\n <div class=\"k-d-flex k-flex-col k-justify-content-between k-h-full custom-dialog-body\">\n <div class=\"dialog-content \">\n <div class=\"dialog-actions\">\n <kendo-dropdownbutton class=\"k-m-2\" themeColor=\"primary\" [data]=\"ResourceTypes\" [textField]=\"'DisplayName'\" (itemClick)=\"onItemSelect($event)\">\n <span class=\"fa-solid fa-plus\"></span> Add item\n </kendo-dropdownbutton>\n </div>\n <kendo-tilelayout\n [columns]=\"config.columns\"\n [rowHeight]=\"config.rowHeight\"\n [resizable]=\"true\"\n [reorderable]=\"true\"\n (resize)=\"onResize($event)\"\n (reorder)=\"onReorder($event)\"\n >\n @for (item of _items; track item) {\n <kendo-tilelayout-item [col]=\"item.col\" [colSpan]=\"item.colSpan\" [rowSpan]=\"item.rowSpan\" [id]=\"item.uniqueId\">\n <kendo-tilelayout-item-header>\n {{item.title}}\n <button kendoButton class=\"k-float-right\" (click)=\"removeItem(item)\">X</button>\n </kendo-tilelayout-item-header>\n <kendo-tilelayout-item-body>\n <!-- <div class=\"overlay\"></div> -->\n <!-- <app-resource [Data]=\"item.ResourceData\" [isVisible]=\"false\"></app-resource> -->\n </kendo-tilelayout-item-body>\n </kendo-tilelayout-item>\n }\n </kendo-tilelayout>\n\n </div>\n <div class=\"dialog-footer\">\n <div class=\"k-card-footer !k-border-none\">\n <button kendoButton (click)=\"closeDialog($event)\" >\n <span class=\"fa-solid fa-xmark\"></span>\n Cancel\n </button>\n <button kendoButton (click)=\"saveChanges()\">\n <span class=\"fa-solid fa-check\"></span>\n Save\n </button>\n </div>\n </div>\n </div>\n</kendo-window>", styles: [".dialog-content .dialog-actions {\n display: flex;\n justify-content: flex-end;\n}\n.dialog-footer {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n width: auto;\n height: 40px;\n border-top: 1px solid rgba(0, 0, 0, 0.08);\n background: var(--mj-bg-surface);\n padding: 8px 16px;\n}\n.custom-dialog-body {\nflex: 1;\n}\n.custom-dialog-body .dialog-content {\n flex: 1;\n overflow: auto;\n padding: 16px;\n box-sizing: border-box;\n}\n.dialog-footer .k-card-footer {\n display: flex;\n gap: 8px;\n padding: 0;\n}\n::ng-deep .kendo-window-hide-restore .k-window-content {\n padding: 0;\n}\n.custom-dialog-body .dialog-content .k-tilelayout {\n background: var(--mj-bg-surface);\n}\n"] }]
141
141
  }], null, { onSave: [{
142
142
  type: Output
143
143
  }], onClose: [{
@@ -502,11 +502,11 @@ export class SingleDashboardComponent extends BaseDashboard {
502
502
  i0.ɵɵconditional(ctx.items.length === 0 && !ctx.isEditingDashboard ? 12 : -1);
503
503
  i0.ɵɵadvance();
504
504
  i0.ɵɵconditional(ctx.items.length > 0 || ctx.isEditingDashboard ? 13 : -1);
505
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n padding: 20px;\n height: 100%;\n box-sizing: border-box;\n}\n\n.dashboard-container[_ngcontent-%COMP%] {\n height: calc(100% - 60px);\n overflow: auto;\n}\n\n.dashboard-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 15px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] .k-icon[_ngcontent-%COMP%] {\n color: var(--border-blue);\n font-size: 25px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: #424242;\n font-size: 28px;\n font-style: normal;\n font-weight: 300;\n line-height: 28px;\n margin: 0;\n cursor: pointer;\n}\n\n.dashboard-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n .dashboard-header .k-button-solid-base {\n border: 1px solid var(--border-blue) !important;\n color: var(--border-blue) !important;\n border-radius: 10px;\n line-height: 34px;\n background: var(--white-color);\n}\n\n .dashboard-header .k-button-solid-primary {\n background: var(--border-blue) !important;\n color: var(--white-color) !important;\n border-radius: 10px;\n line-height: 34px;\n border-color: var(--border-blue);\n}\n\n .dashboard-header .btn-ref .k-button-text {\n display: flex;\n gap: 10px;\n}\n\n.dashboard-header[_ngcontent-%COMP%] .btn-ref[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n}\n\n.main-head-dashboard[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 20px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n}\n\n.tile-resource-container[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding: 15px;\n border-radius: 8px;\n background-color: #f9f9f9;\n}\n\n.tile-resource-container[_ngcontent-%COMP%] .k-tilelayout[_ngcontent-%COMP%] {\n background: #fff;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n border-radius: 8px;\n padding: 10px;\n}\n\n\n\n kendo-tilelayout-item {\n border-radius: 6px;\n overflow: hidden;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 5px;\n}\n\n.bg-light-grey[_ngcontent-%COMP%] {\n background-color: #f0f0f0;\n}\n\n.bg-dark-grey[_ngcontent-%COMP%] {\n background-color: #5a5a5a;\n color: white;\n}\n\n.bg-blue[_ngcontent-%COMP%] {\n background-color: #4250AD;\n color: white;\n}\n\n.dashboard-item-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 15px;\n font-weight: 500;\n}\n\n.dashboard-item-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.button-spacing[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.btn-wrapper[_ngcontent-%COMP%] {\n display: flex;\n gap: 5px;\n}\n\n.btn-wrapper[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n margin-left: 5px;\n}\n\n\n\n.empty-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: #666;\n background-color: #f9f9f9;\n border-radius: 8px;\n margin-top: 20px;\n}\n\n.empty-dashboard[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 20px;\n color: #ccc;\n}\n\n.empty-dashboard[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-bottom: 10px;\n}\n\n.empty-dashboard[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}"] });
505
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n padding: 20px;\n height: 100%;\n box-sizing: border-box;\n}\n\n.dashboard-container[_ngcontent-%COMP%] {\n height: calc(100% - 60px);\n overflow: auto;\n}\n\n.dashboard-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 15px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] .k-icon[_ngcontent-%COMP%] {\n color: var(--border-blue);\n font-size: 25px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 28px;\n font-style: normal;\n font-weight: 300;\n line-height: 28px;\n margin: 0;\n cursor: pointer;\n}\n\n.dashboard-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n .dashboard-header .k-button-solid-base {\n border: 1px solid var(--border-blue) !important;\n color: var(--border-blue) !important;\n border-radius: 10px;\n line-height: 34px;\n background: var(--white-color);\n}\n\n .dashboard-header .k-button-solid-primary {\n background: var(--border-blue) !important;\n color: var(--white-color) !important;\n border-radius: 10px;\n line-height: 34px;\n border-color: var(--border-blue);\n}\n\n .dashboard-header .btn-ref .k-button-text {\n display: flex;\n gap: 10px;\n}\n\n.dashboard-header[_ngcontent-%COMP%] .btn-ref[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n}\n\n.main-head-dashboard[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 20px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n}\n\n.tile-resource-container[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding: 15px;\n border-radius: 8px;\n background-color: var(--mj-bg-surface-card);\n}\n\n.tile-resource-container[_ngcontent-%COMP%] .k-tilelayout[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n border-radius: 8px;\n padding: 10px;\n}\n\n\n\n kendo-tilelayout-item {\n border-radius: 6px;\n overflow: hidden;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 5px;\n}\n\n.bg-light-grey[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.bg-dark-grey[_ngcontent-%COMP%] {\n background-color: var(--mj-text-secondary);\n color: white;\n}\n\n.bg-blue[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary);\n color: white;\n}\n\n.dashboard-item-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 15px;\n font-weight: 500;\n}\n\n.dashboard-item-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.button-spacing[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.btn-wrapper[_ngcontent-%COMP%] {\n display: flex;\n gap: 5px;\n}\n\n.btn-wrapper[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n margin-left: 5px;\n}\n\n\n\n.empty-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-secondary);\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-top: 20px;\n}\n\n.empty-dashboard[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 20px;\n color: var(--mj-border-strong);\n}\n\n.empty-dashboard[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-bottom: 10px;\n}\n\n.empty-dashboard[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}"] });
506
506
  }
507
507
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleDashboardComponent, [{
508
508
  type: Component,
509
- args: [{ standalone: false, selector: 'mj-single-dashboard', template: "@if (isItemDialogOpened) {\n <app-add-item-dialog (onClose)=\"closeDialog($event)\" [selectedResource]=\"selectedResource\"></app-add-item-dialog>\n}\n@if (isEditDialogOpened) {\n <div>\n <app-edit-dashboard (onClose)=\"closeDashboardDialog($event)\" (triggerAddItem)=\"addItem($event)\" [items]=\"items\" [config]=\"config\" (onSave)=\"saveChanges($event)\"></app-edit-dashboard>\n </div>\n}\n\n@if (isDeletingDashboardItem) {\n <app-delete-item-dialog [dashboardItem]=\"selectedDashboardItem\" (removeDashboardItem)=\"deleteDashboardItem($event)\" (onClose)=\"closeDeleteItemComponent()\"></app-delete-item-dialog>\n}\n\n<div class=\"dashboard-container\">\n <div class=\"main-head-dashboard\">\n <div class=\"dashboard-title\">\n @if (isEditDashboardNameDialogOpened) {\n <div class=\"dashboard-header k-d-flex k-flex-row k-justify-content-flex-end\">\n <input class=\"k-textbox k-input k-input-md k-rounded-md k-input-solid\" (keydown.enter)=\"saveDashboardName()\" type=\"text\" placeholder=\"Enter name here\" id=\"txtDashboardName\" #dashboardNameInput>\n <button kendoButton (click)=\"saveDashboardName()\">\n <span class=\"k-i-check k-button-icon k-icon ng-star-inserted\"></span>\n Save\n </button>\n <button kendoButton (click)=\"cancelNameChange()\" >\n <span class=\"k-icon k-i-cancel\"></span>\n Cancel\n </button>\n </div>\n } @else {\n <span class=\"k-icon k-i-star\"></span>\n <h3 (click)=\"toggleInlineNameEdit(true)\">{{dashboardEntity ? dashboardEntity.Name : ''}}</h3>\n }\n </div>\n <div class=\"dashboard-header k-d-flex k-flex-row k-justify-content-flex-end\">\n @if (isEditingDashboard) {\n <div>\n <button kendoButton (click)=\"onClickSaveDashboard()\">\n <span class=\"fa-solid fa-check\"></span>\n Save\n </button>\n <button kendoButton (click)=\"onclickCancelChanges()\">\n <span class=\"fa-solid fa-xmark\"></span>\n Cancel\n </button>\n </div>\n } @else {\n <button kendoButton (click)=\"addItem()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add Item\n </button>\n <button kendoButton (click)=\"toggleEditDashboard(true)\" >\n <span class=\"fa-solid fa-gear\"></span>\n Edit Dashboard\n </button>\n }\n </div>\n </div>\n <div class=\"tile-resource-container\">\n <!-- Show empty state if no items -->\n @if (items.length === 0 && !isEditingDashboard) {\n <div class=\"empty-dashboard\">\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n <h3>This dashboard is empty</h3>\n <p>Start by adding reports or user views to your dashboard</p>\n <button kendoButton themeColor=\"primary\" (click)=\"addItem()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add Item\n </button>\n </div>\n }\n\n <!-- Show tile layout if there are items or if editing -->\n @if (items.length > 0 || isEditingDashboard) {\n <kendo-tilelayout\n [columns]=\"config.columns\"\n [rowHeight]=\"config.rowHeight\"\n [resizable]=\"allowResize\"\n [reorderable]=\"allowReorder\"\n (reorder)=\"onReorder($event)\"\n (resize)=\"onResize($event)\"\n >\n @for(item of items; track item.uniqueId) {\n <kendo-tilelayout-item (mouseenter)=\"onMouseEnter($event)\" (mouseleave)=\"onMouseOut($event)\" [ngClass]=\"[getSelectedComponentStyle(this)]\" [col]=\"item.col\" [colSpan]=\"item.colSpan\" [rowSpan]=\"item.rowSpan\" [id]=\"item.uniqueId\">\n <kendo-tilelayout-item-header [ngClass]=\"['dashboard-item-header', getIsEditingItemHeaderStyle()]\">\n <div class=\"item-title\">\n <i [class]=\"getResourceIcon(item.ResourceData.ResourceType)\" aria-hidden=\"true\"></i>\n {{item.title}}\n </div>\n @if(!isEditingDashboard) {\n <div>\n <div class=\"btn-wrapper\">\n <button kendoButton title=\"Edit dashboard\" (click)=\"toggleEditDashboard(true)\">\n <span class=\"fa-solid fa-pen-to-square\"></span>\n </button>\n <button kendoButton title=\"Remove item\" (click)=\"showConfirmDeleteDashboardItem(item)\">\n <span class=\"fa-solid fa-trash\"></span>\n </button>\n </div>\n </div>\n }\n </kendo-tilelayout-item-header>\n <kendo-tilelayout-item-body [ngClass]=\"[getIsEditingItemBodyStyle()]\">\n <mj-resource [Data]=\"item.ResourceData\" [isVisible]=\"true\" (ContentLoadingStarted)=\"loadingStarted($event)\" (ContentLoadingComplete)=\"loadingComplete($event)\"></mj-resource>\n </kendo-tilelayout-item-body>\n </kendo-tilelayout-item>\n }\n </kendo-tilelayout>\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n padding: 20px;\n height: 100%;\n box-sizing: border-box;\n}\n\n.dashboard-container {\n height: calc(100% - 60px);\n overflow: auto;\n}\n\n.dashboard-title {\n display: flex;\n align-items: center;\n gap: 15px;\n}\n\n.dashboard-title .k-icon {\n color: var(--border-blue);\n font-size: 25px;\n}\n\n.dashboard-title h3 {\n color: #424242;\n font-size: 28px;\n font-style: normal;\n font-weight: 300;\n line-height: 28px;\n margin: 0;\n cursor: pointer;\n}\n\n.dashboard-title h3:hover {\n text-decoration: underline;\n}\n\n.dashboard-header {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n::ng-deep .dashboard-header .k-button-solid-base {\n border: 1px solid var(--border-blue) !important;\n color: var(--border-blue) !important;\n border-radius: 10px;\n line-height: 34px;\n background: var(--white-color);\n}\n\n::ng-deep .dashboard-header .k-button-solid-primary {\n background: var(--border-blue) !important;\n color: var(--white-color) !important;\n border-radius: 10px;\n line-height: 34px;\n border-color: var(--border-blue);\n}\n\n::ng-deep .dashboard-header .btn-ref .k-button-text {\n display: flex;\n gap: 10px;\n}\n\n.dashboard-header .btn-ref {\n border: none;\n background: transparent;\n}\n\n.main-head-dashboard {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 20px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n}\n\n.tile-resource-container {\n margin-top: 20px;\n padding: 15px;\n border-radius: 8px;\n background-color: #f9f9f9;\n}\n\n.tile-resource-container .k-tilelayout {\n background: #fff;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n border-radius: 8px;\n padding: 10px;\n}\n\n/* Dashboard item styling */\n::ng-deep kendo-tilelayout-item {\n border-radius: 6px;\n overflow: hidden;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 5px;\n}\n\n.bg-light-grey {\n background-color: #f0f0f0;\n}\n\n.bg-dark-grey {\n background-color: #5a5a5a;\n color: white;\n}\n\n.bg-blue {\n background-color: #4250AD;\n color: white;\n}\n\n.dashboard-item-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 15px;\n font-weight: 500;\n}\n\n.dashboard-item-header i {\n margin-right: 8px;\n}\n\n.button-spacing {\n margin-right: 8px;\n}\n\n.btn-wrapper {\n display: flex;\n gap: 5px;\n}\n\n.btn-wrapper > button {\n margin-left: 5px;\n}\n\n/* Empty dashboard state */\n.empty-dashboard {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: #666;\n background-color: #f9f9f9;\n border-radius: 8px;\n margin-top: 20px;\n}\n\n.empty-dashboard i {\n font-size: 48px;\n margin-bottom: 20px;\n color: #ccc;\n}\n\n.empty-dashboard h3 {\n margin-bottom: 10px;\n}\n\n.empty-dashboard p {\n margin-bottom: 20px;\n}"] }]
509
+ args: [{ standalone: false, selector: 'mj-single-dashboard', template: "@if (isItemDialogOpened) {\n <app-add-item-dialog (onClose)=\"closeDialog($event)\" [selectedResource]=\"selectedResource\"></app-add-item-dialog>\n}\n@if (isEditDialogOpened) {\n <div>\n <app-edit-dashboard (onClose)=\"closeDashboardDialog($event)\" (triggerAddItem)=\"addItem($event)\" [items]=\"items\" [config]=\"config\" (onSave)=\"saveChanges($event)\"></app-edit-dashboard>\n </div>\n}\n\n@if (isDeletingDashboardItem) {\n <app-delete-item-dialog [dashboardItem]=\"selectedDashboardItem\" (removeDashboardItem)=\"deleteDashboardItem($event)\" (onClose)=\"closeDeleteItemComponent()\"></app-delete-item-dialog>\n}\n\n<div class=\"dashboard-container\">\n <div class=\"main-head-dashboard\">\n <div class=\"dashboard-title\">\n @if (isEditDashboardNameDialogOpened) {\n <div class=\"dashboard-header k-d-flex k-flex-row k-justify-content-flex-end\">\n <input class=\"k-textbox k-input k-input-md k-rounded-md k-input-solid\" (keydown.enter)=\"saveDashboardName()\" type=\"text\" placeholder=\"Enter name here\" id=\"txtDashboardName\" #dashboardNameInput>\n <button kendoButton (click)=\"saveDashboardName()\">\n <span class=\"k-i-check k-button-icon k-icon ng-star-inserted\"></span>\n Save\n </button>\n <button kendoButton (click)=\"cancelNameChange()\" >\n <span class=\"k-icon k-i-cancel\"></span>\n Cancel\n </button>\n </div>\n } @else {\n <span class=\"k-icon k-i-star\"></span>\n <h3 (click)=\"toggleInlineNameEdit(true)\">{{dashboardEntity ? dashboardEntity.Name : ''}}</h3>\n }\n </div>\n <div class=\"dashboard-header k-d-flex k-flex-row k-justify-content-flex-end\">\n @if (isEditingDashboard) {\n <div>\n <button kendoButton (click)=\"onClickSaveDashboard()\">\n <span class=\"fa-solid fa-check\"></span>\n Save\n </button>\n <button kendoButton (click)=\"onclickCancelChanges()\">\n <span class=\"fa-solid fa-xmark\"></span>\n Cancel\n </button>\n </div>\n } @else {\n <button kendoButton (click)=\"addItem()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add Item\n </button>\n <button kendoButton (click)=\"toggleEditDashboard(true)\" >\n <span class=\"fa-solid fa-gear\"></span>\n Edit Dashboard\n </button>\n }\n </div>\n </div>\n <div class=\"tile-resource-container\">\n <!-- Show empty state if no items -->\n @if (items.length === 0 && !isEditingDashboard) {\n <div class=\"empty-dashboard\">\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n <h3>This dashboard is empty</h3>\n <p>Start by adding reports or user views to your dashboard</p>\n <button kendoButton themeColor=\"primary\" (click)=\"addItem()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add Item\n </button>\n </div>\n }\n\n <!-- Show tile layout if there are items or if editing -->\n @if (items.length > 0 || isEditingDashboard) {\n <kendo-tilelayout\n [columns]=\"config.columns\"\n [rowHeight]=\"config.rowHeight\"\n [resizable]=\"allowResize\"\n [reorderable]=\"allowReorder\"\n (reorder)=\"onReorder($event)\"\n (resize)=\"onResize($event)\"\n >\n @for(item of items; track item.uniqueId) {\n <kendo-tilelayout-item (mouseenter)=\"onMouseEnter($event)\" (mouseleave)=\"onMouseOut($event)\" [ngClass]=\"[getSelectedComponentStyle(this)]\" [col]=\"item.col\" [colSpan]=\"item.colSpan\" [rowSpan]=\"item.rowSpan\" [id]=\"item.uniqueId\">\n <kendo-tilelayout-item-header [ngClass]=\"['dashboard-item-header', getIsEditingItemHeaderStyle()]\">\n <div class=\"item-title\">\n <i [class]=\"getResourceIcon(item.ResourceData.ResourceType)\" aria-hidden=\"true\"></i>\n {{item.title}}\n </div>\n @if(!isEditingDashboard) {\n <div>\n <div class=\"btn-wrapper\">\n <button kendoButton title=\"Edit dashboard\" (click)=\"toggleEditDashboard(true)\">\n <span class=\"fa-solid fa-pen-to-square\"></span>\n </button>\n <button kendoButton title=\"Remove item\" (click)=\"showConfirmDeleteDashboardItem(item)\">\n <span class=\"fa-solid fa-trash\"></span>\n </button>\n </div>\n </div>\n }\n </kendo-tilelayout-item-header>\n <kendo-tilelayout-item-body [ngClass]=\"[getIsEditingItemBodyStyle()]\">\n <mj-resource [Data]=\"item.ResourceData\" [isVisible]=\"true\" (ContentLoadingStarted)=\"loadingStarted($event)\" (ContentLoadingComplete)=\"loadingComplete($event)\"></mj-resource>\n </kendo-tilelayout-item-body>\n </kendo-tilelayout-item>\n }\n </kendo-tilelayout>\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n padding: 20px;\n height: 100%;\n box-sizing: border-box;\n}\n\n.dashboard-container {\n height: calc(100% - 60px);\n overflow: auto;\n}\n\n.dashboard-title {\n display: flex;\n align-items: center;\n gap: 15px;\n}\n\n.dashboard-title .k-icon {\n color: var(--border-blue);\n font-size: 25px;\n}\n\n.dashboard-title h3 {\n color: var(--mj-text-secondary);\n font-size: 28px;\n font-style: normal;\n font-weight: 300;\n line-height: 28px;\n margin: 0;\n cursor: pointer;\n}\n\n.dashboard-title h3:hover {\n text-decoration: underline;\n}\n\n.dashboard-header {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n::ng-deep .dashboard-header .k-button-solid-base {\n border: 1px solid var(--border-blue) !important;\n color: var(--border-blue) !important;\n border-radius: 10px;\n line-height: 34px;\n background: var(--white-color);\n}\n\n::ng-deep .dashboard-header .k-button-solid-primary {\n background: var(--border-blue) !important;\n color: var(--white-color) !important;\n border-radius: 10px;\n line-height: 34px;\n border-color: var(--border-blue);\n}\n\n::ng-deep .dashboard-header .btn-ref .k-button-text {\n display: flex;\n gap: 10px;\n}\n\n.dashboard-header .btn-ref {\n border: none;\n background: transparent;\n}\n\n.main-head-dashboard {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 20px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n}\n\n.tile-resource-container {\n margin-top: 20px;\n padding: 15px;\n border-radius: 8px;\n background-color: var(--mj-bg-surface-card);\n}\n\n.tile-resource-container .k-tilelayout {\n background: var(--mj-bg-surface);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n border-radius: 8px;\n padding: 10px;\n}\n\n/* Dashboard item styling */\n::ng-deep kendo-tilelayout-item {\n border-radius: 6px;\n overflow: hidden;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 5px;\n}\n\n.bg-light-grey {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.bg-dark-grey {\n background-color: var(--mj-text-secondary);\n color: white;\n}\n\n.bg-blue {\n background-color: var(--mj-brand-primary);\n color: white;\n}\n\n.dashboard-item-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 15px;\n font-weight: 500;\n}\n\n.dashboard-item-header i {\n margin-right: 8px;\n}\n\n.button-spacing {\n margin-right: 8px;\n}\n\n.btn-wrapper {\n display: flex;\n gap: 5px;\n}\n\n.btn-wrapper > button {\n margin-left: 5px;\n}\n\n/* Empty dashboard state */\n.empty-dashboard {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-secondary);\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-top: 20px;\n}\n\n.empty-dashboard i {\n font-size: 48px;\n margin-bottom: 20px;\n color: var(--mj-border-strong);\n}\n\n.empty-dashboard h3 {\n margin-bottom: 10px;\n}\n\n.empty-dashboard p {\n margin-bottom: 20px;\n}\n"] }]
510
510
  }], () => [{ type: i1.ActivatedRoute }, { type: i2.SharedService }], { dashboardNameInput: [{
511
511
  type: ViewChild,
512
512
  args: ['dashboardNameInput']
@@ -1 +1 @@
1
- {"version":3,"file":"single-list-detail.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-list-detail/single-list-detail.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"single-list-detail.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-list-detail/single-list-detail.component.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { Component, Input, ViewChild } from '@angular/core';
2
2
  import { CompositeKey, LogError, LogErrorEx, LogStatus, Metadata, RunView } from '@memberjunction/core';
3
3
  import { Subject, debounceTime } from 'rxjs';
4
- import { UUIDsEqual } from '@memberjunction/global';
4
+ import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
5
5
  import * as i0 from "@angular/core";
6
6
  import * as i1 from "@memberjunction/ng-shared";
7
7
  import * as i2 from "@progress/kendo-angular-dialog";
@@ -619,7 +619,7 @@ export class SingleListDetailComponent {
619
619
  ResultType: 'simple'
620
620
  }, md.CurrentUser);
621
621
  if (result.Success) {
622
- this.existingListDetailIds = new Set(result.Results.map(r => r.RecordID));
622
+ this.existingListDetailIds = new Set(result.Results.map(r => NormalizeUUID(r.RecordID)));
623
623
  }
624
624
  }
625
625
  onAddRecordsSearchChange(value) {
@@ -657,7 +657,7 @@ export class SingleListDetailComponent {
657
657
  return {
658
658
  ID: recordId,
659
659
  Name: nameField ? String(record[nameField.Name]) : recordId,
660
- isInList: this.existingListDetailIds.has(recordId),
660
+ isInList: this.existingListDetailIds.has(NormalizeUUID(recordId)),
661
661
  isSelected: false
662
662
  };
663
663
  });
@@ -759,6 +759,7 @@ export class SingleListDetailComponent {
759
759
  this.userViews = runViewResult.Results;
760
760
  }
761
761
  this.showAddFromViewLoader = false;
762
+ this.cdr.detectChanges();
762
763
  }
763
764
  toggleViewSelection(view) {
764
765
  const index = this.userViewsToAdd.findIndex(v => UUIDsEqual(v.ID, view.ID));
@@ -777,19 +778,20 @@ export class SingleListDetailComponent {
777
778
  return;
778
779
  this.showAddFromViewLoader = true;
779
780
  this.fetchingRecordsToSave = true;
781
+ this.cdr.detectChanges();
780
782
  const rv = new RunView();
781
783
  const md = new Metadata();
782
784
  // Collect all unique record IDs from selected views
783
785
  const recordIdSet = new Set();
784
786
  for (const userView of this.userViewsToAdd) {
785
787
  const runViewResult = await rv.RunView({
786
- EntityName: "MJ: User Views",
788
+ ViewID: userView.ID,
787
789
  ViewEntity: userView,
788
790
  Fields: ["ID"]
789
791
  }, md.CurrentUser);
790
792
  if (runViewResult.Success) {
791
793
  const records = runViewResult.Results;
792
- records.forEach(r => recordIdSet.add(r.ID));
794
+ records.forEach(r => recordIdSet.add(NormalizeUUID(r.ID)));
793
795
  }
794
796
  }
795
797
  // Filter out records already in the list
@@ -798,10 +800,12 @@ export class SingleListDetailComponent {
798
800
  this.addFromViewTotal = recordsToAdd.length;
799
801
  this.addFromViewProgress = 0;
800
802
  this.fetchingRecordsToSave = false;
803
+ this.cdr.detectChanges();
801
804
  const progressPerRecord = 0.8 / Math.max(recordsToAdd.length, 1); // 80% for individual saves
802
805
  if (recordsToAdd.length === 0) {
803
806
  this.sharedService.CreateSimpleNotification("All records already in list", 'info', 2500);
804
807
  this.showAddFromViewLoader = false;
808
+ this.cdr.detectChanges();
805
809
  return;
806
810
  }
807
811
  LogStatus(`Adding ${recordsToAdd.length} records to list`);
@@ -876,11 +880,11 @@ export class SingleListDetailComponent {
876
880
  i0.ɵɵconditional(ctx.showAddRecordsDialog ? 11 : -1);
877
881
  i0.ɵɵadvance();
878
882
  i0.ɵɵconditional(ctx.showAddFromViewDialog ? 12 : -1);
879
- } }, dependencies: [i2.DialogComponent, i2.DialogActionsComponent, i3.ButtonComponent, i3.DropDownButtonComponent, i4.TextBoxComponent, i4.TextBoxPrefixTemplateDirective, i5.ProgressBarComponent, i6.LoadingComponent, i7.ListDetailGridComponent], styles: [".list-detail-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: #fafafa;\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n}\n\n.list-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #333;\n}\n\n\n\n.custom-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: white;\n border: 1px solid #e0e0e0;\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n}\n\n.selection-count[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #666;\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.remove-btn[_ngcontent-%COMP%] {\n color: #d32f2f;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n\n\n.add-btn[_ngcontent-%COMP%] {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--border-blue, #0078d4);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn[_ngcontent-%COMP%]:hover {\n filter: brightness(85%);\n}\n\n .k-dropdown-button .k-button {\n background: var(--border-blue, #0078d4) !important;\n color: white !important;\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n .k-dropdown-button .k-button:hover {\n background: var(--border-blue, #0078d4) !important;\n filter: brightness(85%);\n}\n\n .k-dropdown-button .k-button .k-button-text {\n color: white !important;\n}\n\n .k-dropdown-button .k-button .fa-plus {\n color: white !important;\n}\n\n\n\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 8px 0;\n}\n\n.dialog-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: #f57c00;\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 8px 0;\n font-size: 15px;\n color: #333;\n}\n\n.dialog-note[_ngcontent-%COMP%] {\n color: #666 !important;\n font-size: 13px !important;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n}\n\n\n\n\n\n\n.add-records-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section[_ngcontent-%COMP%] {\n padding-bottom: 12px;\n border-bottom: 1px solid #eee;\n margin-bottom: 12px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: #999;\n padding-left: 8px;\n}\n\n.search-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: #999;\n margin-top: 6px;\n}\n\n.records-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #999;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n color: #ccc;\n}\n\n.empty-results[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid #eee;\n margin-bottom: 8px;\n}\n\n.selection-info[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 13px;\n color: #666;\n}\n\n.records-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item[_ngcontent-%COMP%]:hover:not(.in-list) {\n background: #f5f5f5;\n}\n\n.record-item.selected[_ngcontent-%COMP%] {\n background: #e3f2fd;\n}\n\n.record-item.in-list[_ngcontent-%COMP%] {\n background: #f9f9f9;\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox[_ngcontent-%COMP%] {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon[_ngcontent-%COMP%] {\n color: #4caf50;\n font-size: 14px;\n}\n\n.record-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: #333;\n}\n\n.in-list-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 2px 8px;\n background: #e8f5e9;\n color: #2e7d32;\n border-radius: 10px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.dialog-instruction[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: #666;\n}\n\n.views-list[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n\n.view-item.selected[_ngcontent-%COMP%] {\n background: #e3f2fd;\n}\n\n.view-item[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon[_ngcontent-%COMP%] {\n color: #666;\n font-size: 16px;\n}\n\n.view-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: #333;\n}"] });
883
+ } }, dependencies: [i2.DialogComponent, i2.DialogActionsComponent, i3.ButtonComponent, i3.DropDownButtonComponent, i4.TextBoxComponent, i4.TextBoxPrefixTemplateDirective, i5.ProgressBarComponent, i6.LoadingComponent, i7.ListDetailGridComponent], styles: [".list-detail-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n}\n\n.list-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.custom-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.remove-btn[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n\n\n.add-btn[_ngcontent-%COMP%] {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--mj-brand-primary);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn[_ngcontent-%COMP%]:hover {\n filter: brightness(85%);\n}\n\n .k-dropdown-button .k-button {\n background: var(--mj-brand-primary) !important;\n color: white !important;\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n .k-dropdown-button .k-button:hover {\n background: var(--mj-brand-primary) !important;\n filter: brightness(85%);\n}\n\n .k-dropdown-button .k-button .k-button-text {\n color: white !important;\n}\n\n .k-dropdown-button .k-button .fa-plus {\n color: white !important;\n}\n\n\n\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 8px 0;\n}\n\n.dialog-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n}\n\n\n\n\n\n\n.add-records-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section[_ngcontent-%COMP%] {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n padding-left: 8px;\n}\n\n.search-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n color: var(--mj-border-strong);\n}\n\n.empty-results[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item[_ngcontent-%COMP%]:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox[_ngcontent-%COMP%] {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.dialog-instruction[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}"] });
880
884
  }
881
885
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleListDetailComponent, [{
882
886
  type: Component,
883
- args: [{ standalone: false, selector: 'mj-list-detail', template: "<div class=\"list-detail-container\">\n <!-- Header with title and Add button -->\n <div class=\"list-header\">\n <h1>{{ listRecord ? listRecord.Name : \"List\" }}</h1>\n <kendo-dropdownbutton\n class=\"add-btn\"\n (itemClick)=\"onDropdownItemClick($event)\"\n [data]=\"addOptions\"\n textField=\"Text\"\n themeColor=\"info\">\n <span class=\"fa-solid fa-plus\"></span>\n Add to List\n </kendo-dropdownbutton>\n </div>\n\n <!-- Custom Toolbar -->\n @if (!showLoader && listRecord) {\n <div class=\"custom-toolbar\">\n <div class=\"toolbar-left\">\n <span class=\"row-count\">{{ rowCount }} row{{ rowCount !== 1 ? 's' : '' }}</span>\n @if (selectedKeys.length > 0) {\n <span class=\"selection-count\">({{ selectedKeys.length }} selected)</span>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedKeys.length > 0) {\n <button kendoButton\n (click)=\"openRemoveDialog()\"\n fillMode=\"flat\"\n themeColor=\"error\"\n class=\"toolbar-button remove-btn\">\n <span class=\"fa-solid fa-trash\"></span>\n Remove from List\n </button>\n }\n <button kendoButton\n (click)=\"onRefreshClick()\"\n fillMode=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-rotate\"></span>\n Refresh\n </button>\n <button kendoButton\n (click)=\"onExportClick()\"\n fillMode=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-file-export\"></span>\n Export\n </button>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (showLoader) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading list...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Grid -->\n @if (!showLoader && listRecord) {\n <div class=\"grid-container\">\n <mj-list-detail-grid\n #listDetailGrid\n [listId]=\"ListID\"\n [listEntity]=\"listRecord\"\n [autoNavigate]=\"true\"\n [height]=\"'auto'\"\n [showToolbar]=\"false\"\n [toolbarConfig]=\"gridToolbarConfig\"\n [selectionMode]=\"'checkbox'\"\n (rowClicked)=\"onRowClicked($event)\"\n (rowDoubleClicked)=\"onRowDoubleClicked($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n (dataLoaded)=\"onDataLoaded($event)\">\n </mj-list-detail-grid>\n </div>\n }\n</div>\n\n<!-- Remove from List Confirmation Dialog -->\n@if (showRemoveDialog) {\n <kendo-dialog\n title=\"Remove from List\"\n (close)=\"closeRemoveDialog()\"\n [minWidth]=\"350\"\n [width]=\"450\">\n <div class=\"dialog-content\">\n @if (isRemoving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Removing records...\" size=\"small\"></mj-loading>\n @if (removeTotal > 0) {\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"removeTotal\"\n [value]=\"removeProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n }\n </div>\n } @else {\n <div class=\"dialog-message\">\n <span class=\"fa-solid fa-triangle-exclamation warning-icon\"></span>\n <p>Are you sure you want to remove <strong>{{ selectedKeys.length }}</strong> record{{ selectedKeys.length !== 1 ? 's' : '' }} from this list?</p>\n <p class=\"dialog-note\">This will not delete the records, only remove them from this list.</p>\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmRemoveFromList()\"\n [disabled]=\"isRemoving\"\n themeColor=\"error\">\n Remove\n </button>\n <button kendoButton\n (click)=\"closeRemoveDialog()\"\n [disabled]=\"isRemoving\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n\n<!-- Add Records Dialog -->\n@if (showAddRecordsDialog) {\n <kendo-dialog\n [title]=\"'Add ' + (listRecord?.Entity || 'Records') + ' to List'\"\n (close)=\"closeAddRecordsDialog()\"\n [minWidth]=\"500\"\n [width]=\"700\"\n [height]=\"650\">\n <div class=\"dialog-content add-records-dialog\">\n @if (addDialogSaving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n @if (addTotal > 0) {\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"addTotal\"\n [value]=\"addProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n }\n </div>\n } @else {\n <!-- Search Input -->\n <div class=\"search-section\">\n <kendo-textbox\n [placeholder]=\"'Search ' + (listRecord?.Entity || 'records') + '...'\"\n [clearButton]=\"true\"\n (valueChange)=\"onAddRecordsSearchChange($event)\"\n [value]=\"addRecordsSearchFilter\"\n class=\"search-input\">\n <ng-template kendoTextBoxPrefixTemplate>\n <span class=\"fa-solid fa-search search-icon\"></span>\n </ng-template>\n </kendo-textbox>\n <span class=\"search-hint\">Type at least 2 characters to search</span>\n </div>\n <!-- Records List -->\n <div class=\"records-list\">\n @if (addDialogLoading) {\n <div class=\"list-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n </div>\n } @else if (addableRecords.length === 0 && addRecordsSearchFilter.length >= 2) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-search empty-icon\"></span>\n <p>No records found matching \"{{ addRecordsSearchFilter }}\"</p>\n </div>\n } @else if (addableRecords.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-list empty-icon\"></span>\n <p>Search for records to add to this list</p>\n </div>\n } @else {\n <!-- Selection controls -->\n <div class=\"selection-controls\">\n <button kendoButton fillMode=\"flat\" size=\"small\" (click)=\"selectAllAddable()\">Select All</button>\n <button kendoButton fillMode=\"flat\" size=\"small\" (click)=\"deselectAllAddable()\">Deselect All</button>\n <span class=\"selection-info\">{{ selectedAddableRecords.length }} selected</span>\n </div>\n <!-- Records -->\n <div class=\"records-scroll\">\n @for (record of addableRecords; track record.ID) {\n <div class=\"record-item\"\n [class.in-list]=\"record.isInList\"\n [class.selected]=\"record.isSelected\"\n (click)=\"toggleRecordSelection(record)\">\n <div class=\"record-checkbox\">\n @if (record.isInList) {\n <span class=\"fa-solid fa-check in-list-icon\" title=\"Already in list\"></span>\n } @else {\n <input type=\"checkbox\"\n [checked]=\"record.isSelected\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRecordSelection(record)\">\n }\n </div>\n <div class=\"record-name\">{{ record.Name }}</div>\n @if (record.isInList) {\n <span class=\"in-list-badge\">In List</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmAddRecords()\"\n [disabled]=\"addDialogSaving || selectedAddableRecords.length === 0\"\n themeColor=\"info\">\n Add {{ selectedAddableRecords.length > 0 ? selectedAddableRecords.length : '' }} Record{{ selectedAddableRecords.length !== 1 ? 's' : '' }}\n </button>\n <button kendoButton\n (click)=\"closeAddRecordsDialog()\"\n [disabled]=\"addDialogSaving\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n\n<!-- Add From View Dialog -->\n@if (showAddFromViewDialog) {\n <kendo-dialog\n title=\"Add Records from Views\"\n (close)=\"closeAddFromViewDialog()\"\n [minWidth]=\"400\"\n [width]=\"600\"\n [height]=\"500\">\n <div class=\"dialog-content\">\n @if (showAddFromViewLoader && fetchingRecordsToSave) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading records from views...\" size=\"small\"></mj-loading>\n </div>\n } @else if (showAddFromViewLoader && addFromViewTotal > 0) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"addFromViewTotal\"\n [value]=\"addFromViewProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n </div>\n } @else if (showAddFromViewLoader) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading views...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <p class=\"dialog-instruction\">Select views to add their records to this list:</p>\n <div class=\"views-list\">\n @if (!userViews || userViews.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-folder-open empty-icon\"></span>\n <p>No saved views found for this entity</p>\n </div>\n } @else {\n @for (view of userViews; track view.ID) {\n <div class=\"view-item\"\n [class.selected]=\"isViewSelected(view)\"\n (click)=\"toggleViewSelection(view)\">\n <input type=\"checkbox\"\n [checked]=\"isViewSelected(view)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleViewSelection(view)\">\n <span class=\"fa-solid fa-table-list view-icon\"></span>\n <span class=\"view-name\">{{ view.Name }}</span>\n </div>\n }\n }\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmAddFromView()\"\n [disabled]=\"showAddFromViewLoader || userViewsToAdd.length === 0\"\n themeColor=\"info\">\n Add from {{ userViewsToAdd.length }} View{{ userViewsToAdd.length !== 1 ? 's' : '' }}\n </button>\n <button kendoButton\n (click)=\"closeAddFromViewDialog()\"\n [disabled]=\"showAddFromViewLoader\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: [".list-detail-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: #fafafa;\n}\n\n.list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n}\n\n.list-header h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #333;\n}\n\n/* Custom Toolbar */\n.custom-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: white;\n border: 1px solid #e0e0e0;\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n}\n\n.selection-count {\n font-size: 14px;\n color: #666;\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button span {\n font-size: 14px;\n}\n\n.remove-btn {\n color: #d32f2f;\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container {\n flex: 1;\n min-height: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n/* Add Button */\n.add-btn {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--border-blue, #0078d4);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn:hover {\n filter: brightness(85%);\n}\n\n::ng-deep .k-dropdown-button .k-button {\n background: var(--border-blue, #0078d4) !important;\n color: white !important;\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n::ng-deep .k-dropdown-button .k-button:hover {\n background: var(--border-blue, #0078d4) !important;\n filter: brightness(85%);\n}\n\n::ng-deep .k-dropdown-button .k-button .k-button-text {\n color: white !important;\n}\n\n::ng-deep .k-dropdown-button .k-button .fa-plus {\n color: white !important;\n}\n\n/* ==========================================\n Dialog Styles\n ========================================== */\n\n.dialog-content {\n padding: 8px 0;\n}\n\n.dialog-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon {\n font-size: 48px;\n color: #f57c00;\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message p {\n margin: 8px 0;\n font-size: 15px;\n color: #333;\n}\n\n.dialog-note {\n color: #666 !important;\n font-size: 13px !important;\n}\n\n.progress-bar {\n width: 100%;\n max-width: 300px;\n}\n\n/* ==========================================\n Add Records Dialog\n ========================================== */\n\n.add-records-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section {\n padding-bottom: 12px;\n border-bottom: 1px solid #eee;\n margin-bottom: 12px;\n}\n\n.search-input {\n width: 100%;\n}\n\n.search-icon {\n color: #999;\n padding-left: 8px;\n}\n\n.search-hint {\n display: block;\n font-size: 12px;\n color: #999;\n margin-top: 6px;\n}\n\n.records-list {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #999;\n}\n\n.empty-icon {\n font-size: 32px;\n margin-bottom: 12px;\n color: #ccc;\n}\n\n.empty-results p {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid #eee;\n margin-bottom: 8px;\n}\n\n.selection-info {\n margin-left: auto;\n font-size: 13px;\n color: #666;\n}\n\n.records-scroll {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item:hover:not(.in-list) {\n background: #f5f5f5;\n}\n\n.record-item.selected {\n background: #e3f2fd;\n}\n\n.record-item.in-list {\n background: #f9f9f9;\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon {\n color: #4caf50;\n font-size: 14px;\n}\n\n.record-name {\n flex: 1;\n font-size: 14px;\n color: #333;\n}\n\n.in-list-badge {\n font-size: 11px;\n padding: 2px 8px;\n background: #e8f5e9;\n color: #2e7d32;\n border-radius: 10px;\n font-weight: 500;\n}\n\n/* ==========================================\n Add From View Dialog\n ========================================== */\n\n.dialog-instruction {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: #666;\n}\n\n.views-list {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item:hover {\n background: #f5f5f5;\n}\n\n.view-item.selected {\n background: #e3f2fd;\n}\n\n.view-item input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon {\n color: #666;\n font-size: 16px;\n}\n\n.view-name {\n flex: 1;\n font-size: 14px;\n color: #333;\n}\n"] }]
887
+ args: [{ standalone: false, selector: 'mj-list-detail', template: "<div class=\"list-detail-container\">\n <!-- Header with title and Add button -->\n <div class=\"list-header\">\n <h1>{{ listRecord ? listRecord.Name : \"List\" }}</h1>\n <kendo-dropdownbutton\n class=\"add-btn\"\n (itemClick)=\"onDropdownItemClick($event)\"\n [data]=\"addOptions\"\n textField=\"Text\"\n themeColor=\"info\">\n <span class=\"fa-solid fa-plus\"></span>\n Add to List\n </kendo-dropdownbutton>\n </div>\n\n <!-- Custom Toolbar -->\n @if (!showLoader && listRecord) {\n <div class=\"custom-toolbar\">\n <div class=\"toolbar-left\">\n <span class=\"row-count\">{{ rowCount }} row{{ rowCount !== 1 ? 's' : '' }}</span>\n @if (selectedKeys.length > 0) {\n <span class=\"selection-count\">({{ selectedKeys.length }} selected)</span>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedKeys.length > 0) {\n <button kendoButton\n (click)=\"openRemoveDialog()\"\n fillMode=\"flat\"\n themeColor=\"error\"\n class=\"toolbar-button remove-btn\">\n <span class=\"fa-solid fa-trash\"></span>\n Remove from List\n </button>\n }\n <button kendoButton\n (click)=\"onRefreshClick()\"\n fillMode=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-rotate\"></span>\n Refresh\n </button>\n <button kendoButton\n (click)=\"onExportClick()\"\n fillMode=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-file-export\"></span>\n Export\n </button>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (showLoader) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading list...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Grid -->\n @if (!showLoader && listRecord) {\n <div class=\"grid-container\">\n <mj-list-detail-grid\n #listDetailGrid\n [listId]=\"ListID\"\n [listEntity]=\"listRecord\"\n [autoNavigate]=\"true\"\n [height]=\"'auto'\"\n [showToolbar]=\"false\"\n [toolbarConfig]=\"gridToolbarConfig\"\n [selectionMode]=\"'checkbox'\"\n (rowClicked)=\"onRowClicked($event)\"\n (rowDoubleClicked)=\"onRowDoubleClicked($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n (dataLoaded)=\"onDataLoaded($event)\">\n </mj-list-detail-grid>\n </div>\n }\n</div>\n\n<!-- Remove from List Confirmation Dialog -->\n@if (showRemoveDialog) {\n <kendo-dialog\n title=\"Remove from List\"\n (close)=\"closeRemoveDialog()\"\n [minWidth]=\"350\"\n [width]=\"450\">\n <div class=\"dialog-content\">\n @if (isRemoving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Removing records...\" size=\"small\"></mj-loading>\n @if (removeTotal > 0) {\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"removeTotal\"\n [value]=\"removeProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n }\n </div>\n } @else {\n <div class=\"dialog-message\">\n <span class=\"fa-solid fa-triangle-exclamation warning-icon\"></span>\n <p>Are you sure you want to remove <strong>{{ selectedKeys.length }}</strong> record{{ selectedKeys.length !== 1 ? 's' : '' }} from this list?</p>\n <p class=\"dialog-note\">This will not delete the records, only remove them from this list.</p>\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmRemoveFromList()\"\n [disabled]=\"isRemoving\"\n themeColor=\"error\">\n Remove\n </button>\n <button kendoButton\n (click)=\"closeRemoveDialog()\"\n [disabled]=\"isRemoving\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n\n<!-- Add Records Dialog -->\n@if (showAddRecordsDialog) {\n <kendo-dialog\n [title]=\"'Add ' + (listRecord?.Entity || 'Records') + ' to List'\"\n (close)=\"closeAddRecordsDialog()\"\n [minWidth]=\"500\"\n [width]=\"700\"\n [height]=\"650\">\n <div class=\"dialog-content add-records-dialog\">\n @if (addDialogSaving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n @if (addTotal > 0) {\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"addTotal\"\n [value]=\"addProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n }\n </div>\n } @else {\n <!-- Search Input -->\n <div class=\"search-section\">\n <kendo-textbox\n [placeholder]=\"'Search ' + (listRecord?.Entity || 'records') + '...'\"\n [clearButton]=\"true\"\n (valueChange)=\"onAddRecordsSearchChange($event)\"\n [value]=\"addRecordsSearchFilter\"\n class=\"search-input\">\n <ng-template kendoTextBoxPrefixTemplate>\n <span class=\"fa-solid fa-search search-icon\"></span>\n </ng-template>\n </kendo-textbox>\n <span class=\"search-hint\">Type at least 2 characters to search</span>\n </div>\n <!-- Records List -->\n <div class=\"records-list\">\n @if (addDialogLoading) {\n <div class=\"list-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n </div>\n } @else if (addableRecords.length === 0 && addRecordsSearchFilter.length >= 2) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-search empty-icon\"></span>\n <p>No records found matching \"{{ addRecordsSearchFilter }}\"</p>\n </div>\n } @else if (addableRecords.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-list empty-icon\"></span>\n <p>Search for records to add to this list</p>\n </div>\n } @else {\n <!-- Selection controls -->\n <div class=\"selection-controls\">\n <button kendoButton fillMode=\"flat\" size=\"small\" (click)=\"selectAllAddable()\">Select All</button>\n <button kendoButton fillMode=\"flat\" size=\"small\" (click)=\"deselectAllAddable()\">Deselect All</button>\n <span class=\"selection-info\">{{ selectedAddableRecords.length }} selected</span>\n </div>\n <!-- Records -->\n <div class=\"records-scroll\">\n @for (record of addableRecords; track record.ID) {\n <div class=\"record-item\"\n [class.in-list]=\"record.isInList\"\n [class.selected]=\"record.isSelected\"\n (click)=\"toggleRecordSelection(record)\">\n <div class=\"record-checkbox\">\n @if (record.isInList) {\n <span class=\"fa-solid fa-check in-list-icon\" title=\"Already in list\"></span>\n } @else {\n <input type=\"checkbox\"\n [checked]=\"record.isSelected\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRecordSelection(record)\">\n }\n </div>\n <div class=\"record-name\">{{ record.Name }}</div>\n @if (record.isInList) {\n <span class=\"in-list-badge\">In List</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmAddRecords()\"\n [disabled]=\"addDialogSaving || selectedAddableRecords.length === 0\"\n themeColor=\"info\">\n Add {{ selectedAddableRecords.length > 0 ? selectedAddableRecords.length : '' }} Record{{ selectedAddableRecords.length !== 1 ? 's' : '' }}\n </button>\n <button kendoButton\n (click)=\"closeAddRecordsDialog()\"\n [disabled]=\"addDialogSaving\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n\n<!-- Add From View Dialog -->\n@if (showAddFromViewDialog) {\n <kendo-dialog\n title=\"Add Records from Views\"\n (close)=\"closeAddFromViewDialog()\"\n [minWidth]=\"400\"\n [width]=\"600\"\n [height]=\"500\">\n <div class=\"dialog-content\">\n @if (showAddFromViewLoader && fetchingRecordsToSave) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading records from views...\" size=\"small\"></mj-loading>\n </div>\n } @else if (showAddFromViewLoader && addFromViewTotal > 0) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n <kendo-progressbar\n [min]=\"0\"\n [max]=\"addFromViewTotal\"\n [value]=\"addFromViewProgress\"\n [label]=\"false\"\n class=\"progress-bar\">\n </kendo-progressbar>\n </div>\n } @else if (showAddFromViewLoader) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading views...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <p class=\"dialog-instruction\">Select views to add their records to this list:</p>\n <div class=\"views-list\">\n @if (!userViews || userViews.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-folder-open empty-icon\"></span>\n <p>No saved views found for this entity</p>\n </div>\n } @else {\n @for (view of userViews; track view.ID) {\n <div class=\"view-item\"\n [class.selected]=\"isViewSelected(view)\"\n (click)=\"toggleViewSelection(view)\">\n <input type=\"checkbox\"\n [checked]=\"isViewSelected(view)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleViewSelection(view)\">\n <span class=\"fa-solid fa-table-list view-icon\"></span>\n <span class=\"view-name\">{{ view.Name }}</span>\n </div>\n }\n }\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton\n (click)=\"confirmAddFromView()\"\n [disabled]=\"showAddFromViewLoader || userViewsToAdd.length === 0\"\n themeColor=\"info\">\n Add from {{ userViewsToAdd.length }} View{{ userViewsToAdd.length !== 1 ? 's' : '' }}\n </button>\n <button kendoButton\n (click)=\"closeAddFromViewDialog()\"\n [disabled]=\"showAddFromViewLoader\"\n fillMode=\"outline\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: [".list-detail-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n}\n\n.list-header h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Custom Toolbar */\n.custom-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button span {\n font-size: 14px;\n}\n\n.remove-btn {\n color: var(--mj-status-error);\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n/* Add Button */\n.add-btn {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--mj-brand-primary);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn:hover {\n filter: brightness(85%);\n}\n\n::ng-deep .k-dropdown-button .k-button {\n background: var(--mj-brand-primary) !important;\n color: white !important;\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n::ng-deep .k-dropdown-button .k-button:hover {\n background: var(--mj-brand-primary) !important;\n filter: brightness(85%);\n}\n\n::ng-deep .k-dropdown-button .k-button .k-button-text {\n color: white !important;\n}\n\n::ng-deep .k-dropdown-button .k-button .fa-plus {\n color: white !important;\n}\n\n/* ==========================================\n Dialog Styles\n ========================================== */\n\n.dialog-content {\n padding: 8px 0;\n}\n\n.dialog-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message p {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar {\n width: 100%;\n max-width: 300px;\n}\n\n/* ==========================================\n Add Records Dialog\n ========================================== */\n\n.add-records-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input {\n width: 100%;\n}\n\n.search-icon {\n color: var(--mj-text-disabled);\n padding-left: 8px;\n}\n\n.search-hint {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon {\n font-size: 32px;\n margin-bottom: 12px;\n color: var(--mj-border-strong);\n}\n\n.empty-results p {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n/* ==========================================\n Add From View Dialog\n ========================================== */\n\n.dialog-instruction {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n"] }]
884
888
  }], () => [{ type: i1.SharedService }, { type: i0.ChangeDetectorRef }], { ListID: [{
885
889
  type: Input
886
890
  }], listDetailGrid: [{