@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.
- package/dist/lib/command-palette/command-palette.component.js +2 -2
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +2 -2
- package/dist/lib/oauth/oauth-callback.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +4 -4
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +5 -5
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +22 -21
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +2 -2
- package/dist/lib/shell/loading-themes.js +1 -1
- package/dist/lib/shell/loading-themes.js.map +1 -1
- package/dist/lib/shell/shell.component.js +3 -3
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +2 -2
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +2 -2
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +2 -2
- package/dist/lib/single-dashboard/single-dashboard.component.js +2 -2
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +11 -7
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +2 -2
- package/dist/lib/system-validation/system-validation-banner.component.js +2 -2
- package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +15 -2
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +76 -8
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +2 -2
- package/package.json +34 -34
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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":"AAAA,OAAO,EAAoB,MAAM,EAAa,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvF,OAAO,EAAkD,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACvI,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;;AAGzD;;GAEG;AACH,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,qBAMa,yBAA0B,YAAW,MAAM;IAoEpD,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IAnEG,MAAM,EAAE,MAAM,CAAM;IAEP,cAAc,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAG1E,UAAU,EAAE,YAAY,GAAG,IAAI,CAAQ;IACvC,UAAU,EAAE,OAAO,CAAS;IAG5B,YAAY,EAAE,MAAM,EAAE,CAAM;IAC5B,QAAQ,EAAE,MAAM,CAAK;IAGrB,iBAAiB,EAAE,iBAAiB,CAQzC;IAGK,gBAAgB,EAAE,OAAO,CAAS;IAClC,UAAU,EAAE,OAAO,CAAS;IAC5B,cAAc,EAAE,MAAM,CAAK;IAC3B,WAAW,EAAE,MAAM,CAAK;IAGxB,oBAAoB,EAAE,OAAO,CAAS;IACtC,gBAAgB,EAAE,OAAO,CAAS;IAClC,eAAe,EAAE,OAAO,CAAS;IACjC,cAAc,EAAE,aAAa,EAAE,CAAM;IACrC,sBAAsB,EAAE,MAAM,CAAM;IACpC,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAC/C,WAAW,EAAE,MAAM,CAAK;IACxB,QAAQ,EAAE,MAAM,CAAK;IAC5B,OAAO,CAAC,aAAa,CAAkC;IAGhD,qBAAqB,EAAE,OAAO,CAAS;IACvC,qBAAqB,EAAE,OAAO,CAAS;IACvC,SAAS,EAAE,wBAAwB,EAAE,GAAG,IAAI,CAAQ;IACpD,cAAc,EAAE,wBAAwB,EAAE,CAAM;IAChD,mBAAmB,EAAE,MAAM,CAAK;IAChC,gBAAgB,EAAE,MAAM,CAAK;IAC7B,qBAAqB,EAAE,OAAO,CAAS;IAGvC,UAAU,EAAE,aAAa,EAAE,CAahC;gBAGQ,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,iBAAiB;IAQnB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtC;;OAEG;YACW,cAAc;IA2B5B,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAInD,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAIzD,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAIvC,YAAY,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIjD,WAAW,IAAI,IAAI;IAUnB,cAAc,IAAI,IAAI;IAItB,aAAa,IAAI,IAAI;IAOrB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAU9C,gBAAgB,IAAI,IAAI;IAQxB,iBAAiB,IAAI,IAAI;IAOnB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0EtC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3C,qBAAqB,IAAI,IAAI;YAUf,yBAAyB;IAkBvC,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;YAK/B,aAAa;IA+C3B,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAKlD,IAAI,sBAAsB,IAAI,aAAa,EAAE,CAE5C;IAED,gBAAgB,IAAI,IAAI;IAMxB,kBAAkB,IAAI,IAAI;IAIpB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwDlC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5C,sBAAsB,IAAI,IAAI;YAQhB,eAAe;
|
|
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
|
-
|
|
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:
|
|
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: [{
|