@memberjunction/ng-explorer-core 2.132.0 → 3.0.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 (199) hide show
  1. package/dist/app-routing.module.d.ts.map +1 -1
  2. package/dist/app-routing.module.js +7 -2
  3. package/dist/app-routing.module.js.map +1 -1
  4. package/dist/generic/Events.types.d.ts +174 -0
  5. package/dist/generic/Events.types.d.ts.map +1 -0
  6. package/dist/generic/Events.types.js +220 -0
  7. package/dist/generic/Events.types.js.map +1 -0
  8. package/dist/lib/app-view/application-view.component.d.ts +65 -0
  9. package/dist/lib/app-view/application-view.component.d.ts.map +1 -0
  10. package/dist/lib/app-view/application-view.component.js +611 -0
  11. package/dist/lib/app-view/application-view.component.js.map +1 -0
  12. package/dist/lib/auth-button/auth-button.component.d.ts +13 -0
  13. package/dist/lib/auth-button/auth-button.component.d.ts.map +1 -0
  14. package/dist/lib/auth-button/auth-button.component.js +36 -0
  15. package/dist/lib/auth-button/auth-button.component.js.map +1 -0
  16. package/dist/lib/base-browser-component/base-browser-component.d.ts +44 -0
  17. package/dist/lib/base-browser-component/base-browser-component.d.ts.map +1 -0
  18. package/dist/lib/base-browser-component/base-browser-component.js +195 -0
  19. package/dist/lib/base-browser-component/base-browser-component.js.map +1 -0
  20. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts +54 -0
  21. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts.map +1 -0
  22. package/dist/lib/chat-wrapper/chat-wrapper.component.js +257 -0
  23. package/dist/lib/chat-wrapper/chat-wrapper.component.js.map +1 -0
  24. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts +32 -0
  25. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts.map +1 -0
  26. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +244 -0
  27. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js.map +1 -0
  28. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +2 -2
  29. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  30. package/dist/lib/data-browser-component/data-browser.component.d.ts +23 -0
  31. package/dist/lib/data-browser-component/data-browser.component.d.ts.map +1 -0
  32. package/dist/lib/data-browser-component/data-browser.component.js +267 -0
  33. package/dist/lib/data-browser-component/data-browser.component.js.map +1 -0
  34. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts +21 -0
  35. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts.map +1 -0
  36. package/dist/lib/expansion-panel-component/expansion-panel-component.js +158 -0
  37. package/dist/lib/expansion-panel-component/expansion-panel-component.js.map +1 -0
  38. package/dist/lib/favorites/favorites.component.d.ts +15 -0
  39. package/dist/lib/favorites/favorites.component.d.ts.map +1 -0
  40. package/dist/lib/favorites/favorites.component.js +135 -0
  41. package/dist/lib/favorites/favorites.component.js.map +1 -0
  42. package/dist/lib/files/files.component.d.ts +10 -0
  43. package/dist/lib/files/files.component.d.ts.map +1 -0
  44. package/dist/lib/files/files.component.js +41 -0
  45. package/dist/lib/files/files.component.js.map +1 -0
  46. package/dist/lib/generic/form-toolbar.js +2 -2
  47. package/dist/lib/generic/form-toolbar.js.map +1 -1
  48. package/dist/lib/generic/resource-container-component.js +2 -2
  49. package/dist/lib/generic/resource-container-component.js.map +1 -1
  50. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts +30 -0
  51. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts.map +1 -0
  52. package/dist/lib/generic-browse-list/generic-browse-list.component.js +171 -0
  53. package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +1 -0
  54. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts +120 -0
  55. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts.map +1 -0
  56. package/dist/lib/generic-browser-list/generic-browser-list.component.js +1093 -0
  57. package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +1 -0
  58. package/dist/lib/guards/auth-guard.service.js +1 -1
  59. package/dist/lib/guards/auth-guard.service.js.map +1 -1
  60. package/dist/lib/header/MSFT_UserImageService.d.ts +12 -0
  61. package/dist/lib/header/MSFT_UserImageService.d.ts.map +1 -0
  62. package/dist/lib/header/MSFT_UserImageService.js +25 -0
  63. package/dist/lib/header/MSFT_UserImageService.js.map +1 -0
  64. package/dist/lib/header/header.component.d.ts +69 -0
  65. package/dist/lib/header/header.component.d.ts.map +1 -0
  66. package/dist/lib/header/header.component.js +342 -0
  67. package/dist/lib/header/header.component.js.map +1 -0
  68. package/dist/lib/home-component/home.component.d.ts +22 -0
  69. package/dist/lib/home-component/home.component.d.ts.map +1 -0
  70. package/dist/lib/home-component/home.component.js +194 -0
  71. package/dist/lib/home-component/home.component.js.map +1 -0
  72. package/dist/lib/home-wrapper/home-wrapper.component.d.ts +7 -0
  73. package/dist/lib/home-wrapper/home-wrapper.component.d.ts.map +1 -0
  74. package/dist/lib/home-wrapper/home-wrapper.component.js +30 -0
  75. package/dist/lib/home-wrapper/home-wrapper.component.js.map +1 -0
  76. package/dist/lib/list-view/list-view.component.d.ts +45 -0
  77. package/dist/lib/list-view/list-view.component.d.ts.map +1 -0
  78. package/dist/lib/list-view/list-view.component.js +329 -0
  79. package/dist/lib/list-view/list-view.component.js.map +1 -0
  80. package/dist/lib/navigation/navigation.component.d.ts +142 -0
  81. package/dist/lib/navigation/navigation.component.d.ts.map +1 -0
  82. package/dist/lib/navigation/navigation.component.js +1212 -0
  83. package/dist/lib/navigation/navigation.component.js.map +1 -0
  84. package/dist/lib/query-browser-component/query-browser.component.d.ts +75 -0
  85. package/dist/lib/query-browser-component/query-browser.component.d.ts.map +1 -0
  86. package/dist/lib/query-browser-component/query-browser.component.js +908 -0
  87. package/dist/lib/query-browser-component/query-browser.component.js.map +1 -0
  88. package/dist/lib/report-browser-component/report-browser.component.d.ts +22 -0
  89. package/dist/lib/report-browser-component/report-browser.component.d.ts.map +1 -0
  90. package/dist/lib/report-browser-component/report-browser.component.js +80 -0
  91. package/dist/lib/report-browser-component/report-browser.component.js.map +1 -0
  92. package/dist/lib/resource-browser/resource-browser.component.d.ts +178 -0
  93. package/dist/lib/resource-browser/resource-browser.component.d.ts.map +1 -0
  94. package/dist/lib/resource-browser/resource-browser.component.js +1012 -0
  95. package/dist/lib/resource-browser/resource-browser.component.js.map +1 -0
  96. package/dist/lib/resource-wrappers/artifact-resource.component.js +2 -2
  97. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  98. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +2 -2
  99. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  100. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +2 -2
  101. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  102. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +2 -2
  103. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  104. package/dist/lib/resource-wrappers/dashboard-resource.component.js +2 -2
  105. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  106. package/dist/lib/resource-wrappers/list-detail-resource.component.js +2 -2
  107. package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
  108. package/dist/lib/resource-wrappers/notifications-resource.component.js +2 -2
  109. package/dist/lib/resource-wrappers/notifications-resource.component.js.map +1 -1
  110. package/dist/lib/resource-wrappers/query-resource.component.js +2 -2
  111. package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
  112. package/dist/lib/resource-wrappers/record-resource.component.js +2 -2
  113. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  114. package/dist/lib/resource-wrappers/report-resource.component.d.ts +13 -0
  115. package/dist/lib/resource-wrappers/report-resource.component.d.ts.map +1 -0
  116. package/dist/lib/resource-wrappers/report-resource.component.js +49 -0
  117. package/dist/lib/resource-wrappers/report-resource.component.js.map +1 -0
  118. package/dist/lib/resource-wrappers/search-results-resource.component.js +2 -2
  119. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  120. package/dist/lib/resource-wrappers/view-resource.component.js +2 -2
  121. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  122. package/dist/lib/services/startup-validation.service.js +1 -1
  123. package/dist/lib/services/startup-validation.service.js.map +1 -1
  124. package/dist/lib/services/system-validation.service.js +1 -1
  125. package/dist/lib/services/system-validation.service.js.map +1 -1
  126. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts +11 -0
  127. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts.map +1 -0
  128. package/dist/lib/shared/custom-icon/custom-icon.component.js +44 -0
  129. package/dist/lib/shared/custom-icon/custom-icon.component.js.map +1 -0
  130. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +2 -2
  131. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
  132. package/dist/lib/shell/components/header/app-nav.component.js +2 -2
  133. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  134. package/dist/lib/shell/components/header/app-switcher.component.js +2 -2
  135. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
  136. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
  137. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  138. package/dist/lib/shell/components/tabs/tab-container.component.js +34 -37
  139. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  140. package/dist/lib/shell/services/settings-dialog.service.js +1 -1
  141. package/dist/lib/shell/services/settings-dialog.service.js.map +1 -1
  142. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  143. package/dist/lib/shell/shell.component.js +5 -2
  144. package/dist/lib/shell/shell.component.js.map +1 -1
  145. package/dist/lib/shell/shell.module.js +1 -1
  146. package/dist/lib/shell/shell.module.js.map +1 -1
  147. package/dist/lib/single-application/single-application.component.d.ts +24 -0
  148. package/dist/lib/single-application/single-application.component.d.ts.map +1 -0
  149. package/dist/lib/single-application/single-application.component.js +122 -0
  150. package/dist/lib/single-application/single-application.component.js.map +1 -0
  151. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +2 -2
  152. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  153. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +2 -2
  154. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
  155. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +2 -2
  156. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
  157. package/dist/lib/single-dashboard/single-dashboard.component.js +2 -2
  158. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  159. package/dist/lib/single-entity/single-entity.component.d.ts +34 -0
  160. package/dist/lib/single-entity/single-entity.component.d.ts.map +1 -0
  161. package/dist/lib/single-entity/single-entity.component.js +245 -0
  162. package/dist/lib/single-entity/single-entity.component.js.map +1 -0
  163. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +69 -51
  164. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  165. package/dist/lib/single-list-detail/single-list-detail.component.js +734 -465
  166. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  167. package/dist/lib/single-query/single-query.component.js +2 -2
  168. package/dist/lib/single-query/single-query.component.js.map +1 -1
  169. package/dist/lib/single-record/single-record.component.js +2 -2
  170. package/dist/lib/single-record/single-record.component.js.map +1 -1
  171. package/dist/lib/single-report/single-report.component.d.ts +17 -0
  172. package/dist/lib/single-report/single-report.component.d.ts.map +1 -0
  173. package/dist/lib/single-report/single-report.component.js +55 -0
  174. package/dist/lib/single-report/single-report.component.js.map +1 -0
  175. package/dist/lib/single-search-result/single-search-result.component.js +2 -2
  176. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  177. package/dist/lib/single-view/single-view.component.d.ts +43 -0
  178. package/dist/lib/single-view/single-view.component.d.ts.map +1 -0
  179. package/dist/lib/single-view/single-view.component.js +207 -0
  180. package/dist/lib/single-view/single-view.component.js.map +1 -0
  181. package/dist/lib/style-guide-test/style-guide-test.component.d.ts +70 -0
  182. package/dist/lib/style-guide-test/style-guide-test.component.d.ts.map +1 -0
  183. package/dist/lib/style-guide-test/style-guide-test.component.js +1024 -0
  184. package/dist/lib/style-guide-test/style-guide-test.component.js.map +1 -0
  185. package/dist/lib/system-validation/system-validation-banner.component.js +2 -2
  186. package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
  187. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts +46 -0
  188. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts.map +1 -0
  189. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +547 -0
  190. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +1 -0
  191. package/dist/lib/user-notifications/user-notifications.component.js +2 -2
  192. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  193. package/dist/lib/user-profile/user-profile.component.js +2 -2
  194. package/dist/lib/user-profile/user-profile.component.js.map +1 -1
  195. package/dist/module.d.ts +2 -1
  196. package/dist/module.d.ts.map +1 -1
  197. package/dist/module.js +8 -4
  198. package/dist/module.js.map +1 -1
  199. package/package.json +44 -43
@@ -1,618 +1,887 @@
1
- import { Component, Input } from '@angular/core';
2
- import { EntityFieldTSType, LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
1
+ import { Component, Input, ViewChild } from '@angular/core';
2
+ import { CompositeKey, LogError, LogErrorEx, LogStatus, Metadata, RunView } from '@memberjunction/core';
3
3
  import { Subject, debounceTime } from 'rxjs';
4
4
  import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/router";
6
- import * as i2 from "@memberjunction/ng-shared";
7
- import * as i3 from "@angular/common";
8
- import * as i4 from "@progress/kendo-angular-grid";
9
- import * as i5 from "@progress/kendo-angular-dialog";
10
- import * as i6 from "@progress/kendo-angular-buttons";
11
- import * as i7 from "@progress/kendo-angular-inputs";
12
- import * as i8 from "@progress/kendo-angular-progressbar";
13
- import * as i9 from "@memberjunction/ng-shared-generic";
14
- const _c0 = () => ({ "text-align": "center", "vertical-align": "center" });
15
- const _c1 = () => ({ "font-weight": "bold", "background-color": "white" });
16
- const _c2 = a0 => ({ "list-selected": a0 });
17
- function SingleListDetailComponent_ng_template_12_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelement(0, "span", 13);
5
+ import * as i1 from "@memberjunction/ng-shared";
6
+ import * as i2 from "@angular/common";
7
+ import * as i3 from "@progress/kendo-angular-dialog";
8
+ import * as i4 from "@progress/kendo-angular-buttons";
9
+ import * as i5 from "@progress/kendo-angular-inputs";
10
+ import * as i6 from "@progress/kendo-angular-progressbar";
11
+ import * as i7 from "@memberjunction/ng-shared-generic";
12
+ import * as i8 from "@memberjunction/ng-list-detail-grid";
13
+ const _c0 = ["listDetailGrid"];
14
+ const _forTrack0 = ($index, $item) => $item.ID;
15
+ function SingleListDetailComponent_Conditional_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
16
+ i0.ɵɵelementStart(0, "span", 13);
17
+ i0.ɵɵtext(1);
18
+ i0.ɵɵelementEnd();
19
+ } if (rf & 2) {
20
+ const ctx_r1 = i0.ɵɵnextContext(2);
21
+ i0.ɵɵadvance();
22
+ i0.ɵɵtextInterpolate1("(", ctx_r1.selectedKeys.length, " selected)");
23
+ } }
24
+ function SingleListDetailComponent_Conditional_7_Conditional_6_Template(rf, ctx) { if (rf & 1) {
25
+ const _r3 = i0.ɵɵgetCurrentView();
26
+ i0.ɵɵelementStart(0, "button", 19);
27
+ i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_7_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openRemoveDialog()); });
28
+ i0.ɵɵelement(1, "span", 20);
29
+ i0.ɵɵtext(2, " Remove from List ");
30
+ i0.ɵɵelementEnd();
19
31
  } }
20
- function SingleListDetailComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
21
- i0.ɵɵelement(0, "mj-loading", 9);
32
+ function SingleListDetailComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
33
+ const _r1 = i0.ɵɵgetCurrentView();
34
+ i0.ɵɵelementStart(0, "div", 5)(1, "div", 11)(2, "span", 12);
35
+ i0.ɵɵtext(3);
36
+ i0.ɵɵelementEnd();
37
+ i0.ɵɵtemplate(4, SingleListDetailComponent_Conditional_7_Conditional_4_Template, 2, 1, "span", 13);
38
+ i0.ɵɵelementEnd();
39
+ i0.ɵɵelementStart(5, "div", 14);
40
+ i0.ɵɵtemplate(6, SingleListDetailComponent_Conditional_7_Conditional_6_Template, 3, 0, "button", 15);
41
+ i0.ɵɵelementStart(7, "button", 16);
42
+ i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_7_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRefreshClick()); });
43
+ i0.ɵɵelement(8, "span", 17);
44
+ i0.ɵɵtext(9, " Refresh ");
45
+ i0.ɵɵelementEnd();
46
+ i0.ɵɵelementStart(10, "button", 16);
47
+ i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_7_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onExportClick()); });
48
+ i0.ɵɵelement(11, "span", 18);
49
+ i0.ɵɵtext(12, " Export ");
50
+ i0.ɵɵelementEnd()()();
22
51
  } if (rf & 2) {
23
- i0.ɵɵproperty("showText", false);
52
+ const ctx_r1 = i0.ɵɵnextContext();
53
+ i0.ɵɵadvance(3);
54
+ i0.ɵɵtextInterpolate2("", ctx_r1.rowCount, " row", ctx_r1.rowCount !== 1 ? "s" : "", "");
55
+ i0.ɵɵadvance();
56
+ i0.ɵɵconditional(ctx_r1.selectedKeys.length > 0 ? 4 : -1);
57
+ i0.ɵɵadvance(2);
58
+ i0.ɵɵconditional(ctx_r1.selectedKeys.length > 0 ? 6 : -1);
24
59
  } }
25
- function SingleListDetailComponent_Conditional_14_kendo_grid_checkbox_column_1_Template(rf, ctx) { if (rf & 1) {
26
- i0.ɵɵelement(0, "kendo-grid-checkbox-column", 16);
60
+ function SingleListDetailComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "div", 6);
62
+ i0.ɵɵelement(1, "mj-loading", 21);
63
+ i0.ɵɵelementEnd();
64
+ } }
65
+ function SingleListDetailComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
66
+ const _r4 = i0.ɵɵgetCurrentView();
67
+ i0.ɵɵelementStart(0, "div", 7)(1, "mj-list-detail-grid", 22, 0);
68
+ i0.ɵɵlistener("rowClicked", function SingleListDetailComponent_Conditional_9_Template_mj_list_detail_grid_rowClicked_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRowClicked($event)); })("rowDoubleClicked", function SingleListDetailComponent_Conditional_9_Template_mj_list_detail_grid_rowDoubleClicked_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRowDoubleClicked($event)); })("selectionChange", function SingleListDetailComponent_Conditional_9_Template_mj_list_detail_grid_selectionChange_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSelectionChange($event)); })("dataLoaded", function SingleListDetailComponent_Conditional_9_Template_mj_list_detail_grid_dataLoaded_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDataLoaded($event)); });
69
+ i0.ɵɵelementEnd()();
70
+ } if (rf & 2) {
71
+ const ctx_r1 = i0.ɵɵnextContext();
72
+ i0.ɵɵadvance();
73
+ i0.ɵɵproperty("listId", ctx_r1.ListID)("listEntity", ctx_r1.listRecord)("autoNavigate", true)("height", "auto")("showToolbar", false)("toolbarConfig", ctx_r1.gridToolbarConfig)("selectionMode", "checkbox");
74
+ } }
75
+ function SingleListDetailComponent_kendo_dialog_10_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelement(0, "kendo-progressbar", 30);
77
+ } if (rf & 2) {
78
+ const ctx_r1 = i0.ɵɵnextContext(3);
79
+ i0.ɵɵproperty("min", 0)("max", ctx_r1.removeTotal)("value", ctx_r1.removeProgress)("label", false);
80
+ } }
81
+ function SingleListDetailComponent_kendo_dialog_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
82
+ i0.ɵɵelementStart(0, "div", 25);
83
+ i0.ɵɵelement(1, "mj-loading", 29);
84
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_10_Conditional_2_Conditional_2_Template, 1, 4, "kendo-progressbar", 30);
85
+ i0.ɵɵelementEnd();
27
86
  } if (rf & 2) {
28
- i0.ɵɵstyleMap(i0.ɵɵpureFunction0(4, _c0));
29
- i0.ɵɵproperty("width", 50)("headerStyle", i0.ɵɵpureFunction0(5, _c1));
87
+ const ctx_r1 = i0.ɵɵnextContext(2);
88
+ i0.ɵɵadvance(2);
89
+ i0.ɵɵconditional(ctx_r1.removeTotal > 0 ? 2 : -1);
30
90
  } }
31
- function SingleListDetailComponent_Conditional_14_kendo_grid_column_2_1_ng_template_0_Template(rf, ctx) { if (rf & 1) {
32
- i0.ɵɵtext(0);
33
- i0.ɵɵpipe(1, "number");
34
- i0.ɵɵpipe(2, "number");
35
- i0.ɵɵelement(3, "br");
36
- i0.ɵɵelementStart(4, "span", 20);
91
+ function SingleListDetailComponent_kendo_dialog_10_Conditional_3_Template(rf, ctx) { if (rf & 1) {
92
+ i0.ɵɵelementStart(0, "div", 26);
93
+ i0.ɵɵelement(1, "span", 31);
94
+ i0.ɵɵelementStart(2, "p");
95
+ i0.ɵɵtext(3, "Are you sure you want to remove ");
96
+ i0.ɵɵelementStart(4, "strong");
37
97
  i0.ɵɵtext(5);
38
- i0.ɵɵpipe(6, "number");
39
98
  i0.ɵɵelementEnd();
99
+ i0.ɵɵtext(6);
100
+ i0.ɵɵelementEnd();
101
+ i0.ɵɵelementStart(7, "p", 32);
102
+ i0.ɵɵtext(8, "This will not delete the records, only remove them from this list.");
103
+ i0.ɵɵelementEnd()();
40
104
  } if (rf & 2) {
41
- const ctx_r2 = i0.ɵɵnextContext(4);
42
- i0.ɵɵtextInterpolate2(" ", i0.ɵɵpipeBind1(1, 3, ctx_r2.filteredGridData.length), "", ctx_r2.totalRowCount > ctx_r2.filteredGridData.length ? " of " + i0.ɵɵpipeBind1(2, 5, ctx_r2.totalRowCount) : " rows", "");
105
+ const ctx_r1 = i0.ɵɵnextContext(2);
43
106
  i0.ɵɵadvance(5);
44
- i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(6, 7, ctx_r2.viewExecutionTime, "1.2-2"), " seconds");
107
+ i0.ɵɵtextInterpolate(ctx_r1.selectedKeys.length);
108
+ i0.ɵɵadvance();
109
+ i0.ɵɵtextInterpolate1(" record", ctx_r1.selectedKeys.length !== 1 ? "s" : "", " from this list?");
110
+ } }
111
+ function SingleListDetailComponent_kendo_dialog_10_Template(rf, ctx) { if (rf & 1) {
112
+ const _r5 = i0.ɵɵgetCurrentView();
113
+ i0.ɵɵelementStart(0, "kendo-dialog", 23);
114
+ i0.ɵɵlistener("close", function SingleListDetailComponent_kendo_dialog_10_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeRemoveDialog()); });
115
+ i0.ɵɵelementStart(1, "div", 24);
116
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_10_Conditional_2_Template, 3, 1, "div", 25)(3, SingleListDetailComponent_kendo_dialog_10_Conditional_3_Template, 9, 2, "div", 26);
117
+ i0.ɵɵelementEnd();
118
+ i0.ɵɵelementStart(4, "kendo-dialog-actions")(5, "button", 27);
119
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_10_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmRemoveFromList()); });
120
+ i0.ɵɵtext(6, " Remove ");
121
+ i0.ɵɵelementEnd();
122
+ i0.ɵɵelementStart(7, "button", 28);
123
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_10_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeRemoveDialog()); });
124
+ i0.ɵɵtext(8, " Cancel ");
125
+ i0.ɵɵelementEnd()()();
126
+ } if (rf & 2) {
127
+ const ctx_r1 = i0.ɵɵnextContext();
128
+ i0.ɵɵproperty("minWidth", 350)("width", 450);
129
+ i0.ɵɵadvance(2);
130
+ i0.ɵɵconditional(ctx_r1.isRemoving ? 2 : 3);
131
+ i0.ɵɵadvance(3);
132
+ i0.ɵɵproperty("disabled", ctx_r1.isRemoving);
133
+ i0.ɵɵadvance(2);
134
+ i0.ɵɵproperty("disabled", ctx_r1.isRemoving);
45
135
  } }
46
- function SingleListDetailComponent_Conditional_14_kendo_grid_column_2_1_Template(rf, ctx) { if (rf & 1) {
47
- i0.ɵɵtemplate(0, SingleListDetailComponent_Conditional_14_kendo_grid_column_2_1_ng_template_0_Template, 7, 10, "ng-template", 19);
136
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵelement(0, "kendo-progressbar", 30);
138
+ } if (rf & 2) {
139
+ const ctx_r1 = i0.ɵɵnextContext(3);
140
+ i0.ɵɵproperty("min", 0)("max", ctx_r1.addTotal)("value", ctx_r1.addProgress)("label", false);
48
141
  } }
49
- function SingleListDetailComponent_Conditional_14_kendo_grid_column_2_Template(rf, ctx) { if (rf & 1) {
50
- i0.ɵɵelementStart(0, "kendo-grid-column", 17);
51
- i0.ɵɵtemplate(1, SingleListDetailComponent_Conditional_14_kendo_grid_column_2_1_Template, 1, 0, null, 18);
142
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
143
+ i0.ɵɵelementStart(0, "div", 25);
144
+ i0.ɵɵelement(1, "mj-loading", 36);
145
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_11_Conditional_2_Conditional_2_Template, 1, 4, "kendo-progressbar", 30);
52
146
  i0.ɵɵelementEnd();
53
147
  } if (rf & 2) {
54
- const item_r4 = ctx.$implicit;
55
- const ctx_r2 = i0.ɵɵnextContext(2);
56
- i0.ɵɵstyleMap(ctx_r2.GetColumnCellStyle(item_r4));
57
- i0.ɵɵproperty("field", item_r4.Name || "")("title", ctx_r2.GetColumnTitle(item_r4))("width", item_r4.width ? item_r4.width : 100)("editable", (item_r4.EntityField == null ? null : item_r4.EntityField.AllowUpdateAPI) || false)("editor", ctx_r2.getEditor(item_r4.EntityField))("headerStyle", i0.ɵɵpureFunction0(9, _c1));
58
- i0.ɵɵadvance();
59
- i0.ɵɵproperty("ngIf", item_r4 === ctx_r2.visibleColumns[0]);
148
+ const ctx_r1 = i0.ɵɵnextContext(2);
149
+ i0.ɵɵadvance(2);
150
+ i0.ɵɵconditional(ctx_r1.addTotal > 0 ? 2 : -1);
60
151
  } }
61
- function SingleListDetailComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
62
- i0.ɵɵelementStart(0, "kendo-grid", 10);
63
- i0.ɵɵtemplate(1, SingleListDetailComponent_Conditional_14_kendo_grid_checkbox_column_1_Template, 1, 6, "kendo-grid-checkbox-column", 14)(2, SingleListDetailComponent_Conditional_14_kendo_grid_column_2_Template, 2, 10, "kendo-grid-column", 15);
152
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_ng_template_2_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵelement(0, "span", 44);
154
+ } }
155
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵelementStart(0, "div", 42);
157
+ i0.ɵɵelement(1, "mj-loading", 45);
64
158
  i0.ɵɵelementEnd();
65
159
  } if (rf & 2) {
66
- const ctx_r2 = i0.ɵɵnextContext();
67
- i0.ɵɵproperty("data", ctx_r2.filteredGridData);
68
- i0.ɵɵadvance();
69
- i0.ɵɵproperty("ngIf", ctx_r2.selectModeEnabled);
70
160
  i0.ɵɵadvance();
71
- i0.ɵɵproperty("ngForOf", ctx_r2.visibleColumns);
161
+ i0.ɵɵproperty("showText", false);
72
162
  } }
73
- function SingleListDetailComponent_kendo_dialog_15_Conditional_1_Template(rf, ctx) { if (rf & 1) {
74
- i0.ɵɵelement(0, "mj-loading", 25)(1, "kendo-progressbar", 26);
163
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_7_Template(rf, ctx) { if (rf & 1) {
164
+ i0.ɵɵelementStart(0, "div", 43);
165
+ i0.ɵɵelement(1, "span", 46);
166
+ i0.ɵɵelementStart(2, "p");
167
+ i0.ɵɵtext(3);
168
+ i0.ɵɵelementEnd()();
75
169
  } if (rf & 2) {
76
- const ctx_r2 = i0.ɵɵnextContext(2);
77
- i0.ɵɵproperty("showText", false);
78
- i0.ɵɵadvance();
79
- i0.ɵɵproperty("min", 0)("max", ctx_r2.recordsToSave)("value", ctx_r2.recordsSaved)("indeterminate", ctx_r2.fetchingRecordsToSave);
170
+ const ctx_r1 = i0.ɵɵnextContext(3);
171
+ i0.ɵɵadvance(3);
172
+ i0.ɵɵtextInterpolate1("No records found matching \"", ctx_r1.addRecordsSearchFilter, "\"");
80
173
  } }
81
- function SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_4_Template(rf, ctx) { if (rf & 1) {
82
- const _r6 = i0.ɵɵgetCurrentView();
83
- i0.ɵɵelementStart(0, "button", 34);
84
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const userView_r7 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.removeViewFromSelectedList(userView_r7)); });
85
- i0.ɵɵelement(1, "span", 35);
86
- i0.ɵɵtext(2, " Remove ");
174
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
175
+ i0.ɵɵelementStart(0, "div", 43);
176
+ i0.ɵɵelement(1, "span", 47);
177
+ i0.ɵɵelementStart(2, "p");
178
+ i0.ɵɵtext(3, "Search for records to add to this list");
179
+ i0.ɵɵelementEnd()();
180
+ } }
181
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
182
+ i0.ɵɵelement(0, "span", 55);
183
+ } }
184
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_3_Template(rf, ctx) { if (rf & 1) {
185
+ const _r11 = i0.ɵɵgetCurrentView();
186
+ i0.ɵɵelementStart(0, "input", 59);
187
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_3_Template_input_click_0_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); })("change", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_3_Template_input_change_0_listener() { i0.ɵɵrestoreView(_r11); const record_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleRecordSelection(record_r10)); });
87
188
  i0.ɵɵelementEnd();
189
+ } if (rf & 2) {
190
+ const record_r10 = i0.ɵɵnextContext().$implicit;
191
+ i0.ɵɵproperty("checked", record_r10.isSelected);
88
192
  } }
89
- function SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
90
- const _r8 = i0.ɵɵgetCurrentView();
91
- i0.ɵɵelementStart(0, "button", 36);
92
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const userView_r7 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.addViewToSelectedList(userView_r7)); });
93
- i0.ɵɵelementStart(1, "div", 37);
94
- i0.ɵɵelement(2, "span", 4);
95
- i0.ɵɵtext(3, " Add ");
96
- i0.ɵɵelementEnd()();
193
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_6_Template(rf, ctx) { if (rf & 1) {
194
+ i0.ɵɵelementStart(0, "span", 58);
195
+ i0.ɵɵtext(1, "In List");
196
+ i0.ɵɵelementEnd();
97
197
  } }
98
- function SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
99
- i0.ɵɵelementStart(0, "div", 29)(1, "div", 30)(2, "div", 31);
100
- i0.ɵɵtext(3);
198
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Template(rf, ctx) { if (rf & 1) {
199
+ const _r9 = i0.ɵɵgetCurrentView();
200
+ i0.ɵɵelementStart(0, "div", 53);
201
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Template_div_click_0_listener() { const record_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleRecordSelection(record_r10)); });
202
+ i0.ɵɵelementStart(1, "div", 54);
203
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_2_Template, 1, 0, "span", 55)(3, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_3_Template, 1, 1, "input", 56);
101
204
  i0.ɵɵelementEnd();
102
- i0.ɵɵtemplate(4, SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_4_Template, 3, 0, "button", 32)(5, SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Conditional_5_Template, 4, 0, "button", 33);
205
+ i0.ɵɵelementStart(4, "div", 57);
206
+ i0.ɵɵtext(5);
103
207
  i0.ɵɵelementEnd();
104
- i0.ɵɵelement(6, "hr");
208
+ i0.ɵɵtemplate(6, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Conditional_6_Template, 2, 0, "span", 58);
105
209
  i0.ɵɵelementEnd();
106
210
  } if (rf & 2) {
107
- const userView_r7 = ctx.$implicit;
108
- const ctx_r2 = i0.ɵɵnextContext(3);
211
+ const record_r10 = ctx.$implicit;
212
+ i0.ɵɵclassProp("in-list", record_r10.isInList)("selected", record_r10.isSelected);
109
213
  i0.ɵɵadvance(2);
110
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(3, _c2, ctx_r2.userViewsToAdd.includes(userView_r7)));
111
- i0.ɵɵadvance();
112
- i0.ɵɵtextInterpolate1(" ", userView_r7.Name, " ");
214
+ i0.ɵɵconditional(record_r10.isInList ? 2 : 3);
215
+ i0.ɵɵadvance(3);
216
+ i0.ɵɵtextInterpolate(record_r10.Name);
113
217
  i0.ɵɵadvance();
114
- i0.ɵɵconditional(ctx_r2.userViewsToAdd.includes(userView_r7) ? 4 : 5);
218
+ i0.ɵɵconditional(record_r10.isInList ? 6 : -1);
115
219
  } }
116
- function SingleListDetailComponent_kendo_dialog_15_Conditional_2_Template(rf, ctx) { if (rf & 1) {
117
- i0.ɵɵelementStart(0, "div", 27);
118
- i0.ɵɵelement(1, "kendo-textbox", 28);
220
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
221
+ const _r8 = i0.ɵɵgetCurrentView();
222
+ i0.ɵɵelementStart(0, "div", 48)(1, "button", 49);
223
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectAllAddable()); });
224
+ i0.ɵɵtext(2, "Select All");
225
+ i0.ɵɵelementEnd();
226
+ i0.ɵɵelementStart(3, "button", 49);
227
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.deselectAllAddable()); });
228
+ i0.ɵɵtext(4, "Deselect All");
229
+ i0.ɵɵelementEnd();
230
+ i0.ɵɵelementStart(5, "span", 50);
231
+ i0.ɵɵtext(6);
232
+ i0.ɵɵelementEnd()();
233
+ i0.ɵɵelementStart(7, "div", 51);
234
+ i0.ɵɵrepeaterCreate(8, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_For_9_Template, 7, 7, "div", 52, _forTrack0);
119
235
  i0.ɵɵelementEnd();
120
- i0.ɵɵelement(2, "hr");
121
- i0.ɵɵrepeaterCreate(3, SingleListDetailComponent_kendo_dialog_15_Conditional_2_For_4_Template, 7, 5, "div", 29, i0.ɵɵrepeaterTrackByIdentity);
122
236
  } if (rf & 2) {
123
- const ctx_r2 = i0.ɵɵnextContext(2);
124
- i0.ɵɵadvance();
125
- i0.ɵɵproperty("clearButton", true);
237
+ const ctx_r1 = i0.ɵɵnextContext(3);
238
+ i0.ɵɵadvance(6);
239
+ i0.ɵɵtextInterpolate1("", ctx_r1.selectedAddableRecords.length, " selected");
126
240
  i0.ɵɵadvance(2);
127
- i0.ɵɵrepeater(ctx_r2.userViews);
241
+ i0.ɵɵrepeater(ctx_r1.addableRecords);
128
242
  } }
129
- function SingleListDetailComponent_kendo_dialog_15_Template(rf, ctx) { if (rf & 1) {
130
- const _r5 = i0.ɵɵgetCurrentView();
131
- i0.ɵɵelementStart(0, "kendo-dialog", 21);
132
- i0.ɵɵlistener("close", function SingleListDetailComponent_kendo_dialog_15_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleAddFromViewDialog(false)); });
133
- i0.ɵɵtemplate(1, SingleListDetailComponent_kendo_dialog_15_Conditional_1_Template, 2, 5)(2, SingleListDetailComponent_kendo_dialog_15_Conditional_2_Template, 5, 1);
134
- i0.ɵɵelementStart(3, "kendo-dialog-actions", 22)(4, "button", 23);
135
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_15_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.addTolist()); });
136
- i0.ɵɵtext(5, " Done ");
137
- i0.ɵɵelementEnd();
138
- i0.ɵɵelementStart(6, "button", 24);
139
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_15_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleAddFromViewDialog(false)); });
140
- i0.ɵɵtext(7, " Cancel ");
141
- i0.ɵɵelementEnd()()();
243
+ function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Template(rf, ctx) { if (rf & 1) {
244
+ const _r7 = i0.ɵɵgetCurrentView();
245
+ i0.ɵɵelementStart(0, "div", 37)(1, "kendo-textbox", 38);
246
+ i0.ɵɵlistener("valueChange", function SingleListDetailComponent_kendo_dialog_11_Conditional_3_Template_kendo_textbox_valueChange_1_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onAddRecordsSearchChange($event)); });
247
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_11_Conditional_3_ng_template_2_Template, 1, 0, "ng-template", 39);
248
+ i0.ɵɵelementEnd();
249
+ i0.ɵɵelementStart(3, "span", 40);
250
+ i0.ɵɵtext(4, "Type at least 2 characters to search");
251
+ i0.ɵɵelementEnd()();
252
+ i0.ɵɵelementStart(5, "div", 41);
253
+ i0.ɵɵtemplate(6, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_6_Template, 2, 1, "div", 42)(7, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_7_Template, 4, 1, "div", 43)(8, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_8_Template, 4, 0, "div", 43)(9, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Conditional_9_Template, 10, 1);
254
+ i0.ɵɵelementEnd();
142
255
  } if (rf & 2) {
143
- const ctx_r2 = i0.ɵɵnextContext();
144
- i0.ɵɵproperty("minWidth", 250)("width", 650)("height", 550);
256
+ const ctx_r1 = i0.ɵɵnextContext(2);
145
257
  i0.ɵɵadvance();
146
- i0.ɵɵconditional(ctx_r2.showAddLoader ? 1 : 2);
147
- i0.ɵɵadvance(3);
148
- i0.ɵɵproperty("disabled", ctx_r2.showAddLoader);
149
- i0.ɵɵadvance(2);
150
- i0.ɵɵproperty("disabled", ctx_r2.showAddLoader);
258
+ i0.ɵɵproperty("placeholder", "Search " + ((ctx_r1.listRecord == null ? null : ctx_r1.listRecord.Entity) || "records") + "...")("clearButton", true)("value", ctx_r1.addRecordsSearchFilter);
259
+ i0.ɵɵadvance(5);
260
+ i0.ɵɵconditional(ctx_r1.addDialogLoading ? 6 : ctx_r1.addableRecords.length === 0 && ctx_r1.addRecordsSearchFilter.length >= 2 ? 7 : ctx_r1.addableRecords.length === 0 ? 8 : 9);
151
261
  } }
152
- function SingleListDetailComponent_kendo_dialog_16_Conditional_1_Template(rf, ctx) { if (rf & 1) {
153
- i0.ɵɵelement(0, "mj-loading", 25)(1, "kendo-progressbar", 26);
262
+ function SingleListDetailComponent_kendo_dialog_11_Template(rf, ctx) { if (rf & 1) {
263
+ const _r6 = i0.ɵɵgetCurrentView();
264
+ i0.ɵɵelementStart(0, "kendo-dialog", 33);
265
+ i0.ɵɵlistener("close", function SingleListDetailComponent_kendo_dialog_11_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeAddRecordsDialog()); });
266
+ i0.ɵɵelementStart(1, "div", 34);
267
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_11_Conditional_2_Template, 3, 1, "div", 25)(3, SingleListDetailComponent_kendo_dialog_11_Conditional_3_Template, 10, 4);
268
+ i0.ɵɵelementEnd();
269
+ i0.ɵɵelementStart(4, "kendo-dialog-actions")(5, "button", 35);
270
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmAddRecords()); });
271
+ i0.ɵɵtext(6);
272
+ i0.ɵɵelementEnd();
273
+ i0.ɵɵelementStart(7, "button", 28);
274
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_11_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeAddRecordsDialog()); });
275
+ i0.ɵɵtext(8, " Cancel ");
276
+ i0.ɵɵelementEnd()()();
154
277
  } if (rf & 2) {
155
- const ctx_r2 = i0.ɵɵnextContext(2);
156
- i0.ɵɵproperty("showText", false);
278
+ const ctx_r1 = i0.ɵɵnextContext();
279
+ i0.ɵɵproperty("title", "Add " + ((ctx_r1.listRecord == null ? null : ctx_r1.listRecord.Entity) || "Records") + " to List")("minWidth", 500)("width", 700)("height", 650);
280
+ i0.ɵɵadvance(2);
281
+ i0.ɵɵconditional(ctx_r1.addDialogSaving ? 2 : 3);
282
+ i0.ɵɵadvance(3);
283
+ i0.ɵɵproperty("disabled", ctx_r1.addDialogSaving || ctx_r1.selectedAddableRecords.length === 0);
284
+ i0.ɵɵadvance();
285
+ i0.ɵɵtextInterpolate2(" Add ", ctx_r1.selectedAddableRecords.length > 0 ? ctx_r1.selectedAddableRecords.length : "", " Record", ctx_r1.selectedAddableRecords.length !== 1 ? "s" : "", " ");
157
286
  i0.ɵɵadvance();
158
- i0.ɵɵproperty("min", 0)("max", ctx_r2.recordsToSave)("value", ctx_r2.recordsSaved)("indeterminate", ctx_r2.fetchingRecordsToSave);
287
+ i0.ɵɵproperty("disabled", ctx_r1.addDialogSaving);
288
+ } }
289
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
290
+ i0.ɵɵelementStart(0, "div", 25);
291
+ i0.ɵɵelement(1, "mj-loading", 61);
292
+ i0.ɵɵelementEnd();
159
293
  } }
160
- function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
161
- i0.ɵɵelement(0, "mj-loading", 25);
294
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_3_Template(rf, ctx) { if (rf & 1) {
295
+ i0.ɵɵelementStart(0, "div", 25);
296
+ i0.ɵɵelement(1, "mj-loading", 36)(2, "kendo-progressbar", 30);
297
+ i0.ɵɵelementEnd();
162
298
  } if (rf & 2) {
163
- i0.ɵɵproperty("showText", false);
299
+ const ctx_r1 = i0.ɵɵnextContext(2);
300
+ i0.ɵɵadvance(2);
301
+ i0.ɵɵproperty("min", 0)("max", ctx_r1.addFromViewTotal)("value", ctx_r1.addFromViewProgress)("label", false);
164
302
  } }
165
- function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
166
- const _r11 = i0.ɵɵgetCurrentView();
167
- i0.ɵɵelementStart(0, "div", 29)(1, "div", 30)(2, "div", 40);
168
- i0.ɵɵtext(3);
303
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_4_Template(rf, ctx) { if (rf & 1) {
304
+ i0.ɵɵelementStart(0, "div", 25);
305
+ i0.ɵɵelement(1, "mj-loading", 62);
169
306
  i0.ɵɵelementEnd();
170
- i0.ɵɵelementStart(4, "button", 36);
171
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_4_For_1_Template_button_click_4_listener() { const listRecord_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.addListRecord(listRecord_r12)); });
172
- i0.ɵɵelementStart(5, "div", 37);
173
- i0.ɵɵelement(6, "span", 4);
174
- i0.ɵɵtext(7, " Add ");
175
- i0.ɵɵelementEnd()()();
176
- i0.ɵɵelement(8, "hr");
307
+ } }
308
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
309
+ i0.ɵɵelementStart(0, "div", 43);
310
+ i0.ɵɵelement(1, "span", 65);
311
+ i0.ɵɵelementStart(2, "p");
312
+ i0.ɵɵtext(3, "No saved views found for this entity");
313
+ i0.ɵɵelementEnd()();
314
+ } }
315
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
316
+ const _r13 = i0.ɵɵgetCurrentView();
317
+ i0.ɵɵelementStart(0, "div", 67);
318
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_For_1_Template_div_click_0_listener() { const view_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleViewSelection(view_r14)); });
319
+ i0.ɵɵelementStart(1, "input", 59);
320
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_For_1_Template_input_click_1_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); })("change", function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_For_1_Template_input_change_1_listener() { const view_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleViewSelection(view_r14)); });
177
321
  i0.ɵɵelementEnd();
322
+ i0.ɵɵelement(2, "span", 68);
323
+ i0.ɵɵelementStart(3, "span", 69);
324
+ i0.ɵɵtext(4);
325
+ i0.ɵɵelementEnd()();
178
326
  } if (rf & 2) {
179
- const listRecord_r12 = ctx.$implicit;
327
+ const view_r14 = ctx.$implicit;
328
+ const ctx_r1 = i0.ɵɵnextContext(4);
329
+ i0.ɵɵclassProp("selected", ctx_r1.isViewSelected(view_r14));
330
+ i0.ɵɵadvance();
331
+ i0.ɵɵproperty("checked", ctx_r1.isViewSelected(view_r14));
180
332
  i0.ɵɵadvance(3);
181
- i0.ɵɵtextInterpolate1(" ", listRecord_r12.Name, " ");
333
+ i0.ɵɵtextInterpolate(view_r14.Name);
182
334
  } }
183
- function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
184
- i0.ɵɵrepeaterCreate(0, SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_4_For_1_Template, 9, 1, "div", 29, i0.ɵɵrepeaterTrackByIdentity);
335
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
336
+ i0.ɵɵrepeaterCreate(0, SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_For_1_Template, 5, 4, "div", 66, _forTrack0);
185
337
  } if (rf & 2) {
186
- const ctx_r2 = i0.ɵɵnextContext(3);
187
- i0.ɵɵrepeater(ctx_r2.listRecords);
338
+ const ctx_r1 = i0.ɵɵnextContext(3);
339
+ i0.ɵɵrepeater(ctx_r1.userViews);
188
340
  } }
189
- function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
190
- const _r10 = i0.ɵɵgetCurrentView();
191
- i0.ɵɵelementStart(0, "div", 27)(1, "kendo-textbox", 39);
192
- i0.ɵɵlistener("valueChange", function SingleListDetailComponent_kendo_dialog_16_Conditional_2_Template_kendo_textbox_valueChange_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onListRecordDialogValueChange($event)); });
193
- i0.ɵɵelementEnd()();
194
- i0.ɵɵelement(2, "hr");
195
- i0.ɵɵtemplate(3, SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_3_Template, 1, 1, "mj-loading", 25)(4, SingleListDetailComponent_kendo_dialog_16_Conditional_2_Conditional_4_Template, 2, 0);
341
+ function SingleListDetailComponent_kendo_dialog_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
342
+ i0.ɵɵelementStart(0, "p", 63);
343
+ i0.ɵɵtext(1, "Select views to add their records to this list:");
344
+ i0.ɵɵelementEnd();
345
+ i0.ɵɵelementStart(2, "div", 64);
346
+ i0.ɵɵtemplate(3, SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_3_Template, 4, 0, "div", 43)(4, SingleListDetailComponent_kendo_dialog_12_Conditional_5_Conditional_4_Template, 2, 0);
347
+ i0.ɵɵelementEnd();
196
348
  } if (rf & 2) {
197
- const ctx_r2 = i0.ɵɵnextContext(2);
198
- i0.ɵɵadvance();
199
- i0.ɵɵproperty("placeholder", "Search " + (ctx_r2.listRecord ? ctx_r2.listRecord.Entity : "Records") + "...")("clearButton", true);
200
- i0.ɵɵadvance(2);
201
- i0.ɵɵconditional(ctx_r2.fetchingListRecords ? 3 : 4);
349
+ const ctx_r1 = i0.ɵɵnextContext(2);
350
+ i0.ɵɵadvance(3);
351
+ i0.ɵɵconditional(!ctx_r1.userViews || ctx_r1.userViews.length === 0 ? 3 : 4);
202
352
  } }
203
- function SingleListDetailComponent_kendo_dialog_16_Template(rf, ctx) { if (rf & 1) {
204
- const _r9 = i0.ɵɵgetCurrentView();
205
- i0.ɵɵelementStart(0, "kendo-dialog", 38);
206
- i0.ɵɵlistener("close", function SingleListDetailComponent_kendo_dialog_16_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleAddRecordsDialog(false)); });
207
- i0.ɵɵtemplate(1, SingleListDetailComponent_kendo_dialog_16_Conditional_1_Template, 2, 5)(2, SingleListDetailComponent_kendo_dialog_16_Conditional_2_Template, 5, 3);
208
- i0.ɵɵelementStart(3, "kendo-dialog-actions", 22)(4, "button", 24);
209
- i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_16_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleAddRecordsDialog(false)); });
210
- i0.ɵɵtext(5, " Close ");
353
+ function SingleListDetailComponent_kendo_dialog_12_Template(rf, ctx) { if (rf & 1) {
354
+ const _r12 = i0.ɵɵgetCurrentView();
355
+ i0.ɵɵelementStart(0, "kendo-dialog", 60);
356
+ i0.ɵɵlistener("close", function SingleListDetailComponent_kendo_dialog_12_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeAddFromViewDialog()); });
357
+ i0.ɵɵelementStart(1, "div", 24);
358
+ i0.ɵɵtemplate(2, SingleListDetailComponent_kendo_dialog_12_Conditional_2_Template, 2, 0, "div", 25)(3, SingleListDetailComponent_kendo_dialog_12_Conditional_3_Template, 3, 4, "div", 25)(4, SingleListDetailComponent_kendo_dialog_12_Conditional_4_Template, 2, 0, "div", 25)(5, SingleListDetailComponent_kendo_dialog_12_Conditional_5_Template, 5, 1);
359
+ i0.ɵɵelementEnd();
360
+ i0.ɵɵelementStart(6, "kendo-dialog-actions")(7, "button", 35);
361
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_12_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmAddFromView()); });
362
+ i0.ɵɵtext(8);
363
+ i0.ɵɵelementEnd();
364
+ i0.ɵɵelementStart(9, "button", 28);
365
+ i0.ɵɵlistener("click", function SingleListDetailComponent_kendo_dialog_12_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeAddFromViewDialog()); });
366
+ i0.ɵɵtext(10, " Cancel ");
211
367
  i0.ɵɵelementEnd()()();
212
368
  } if (rf & 2) {
213
- const ctx_r2 = i0.ɵɵnextContext();
214
- i0.ɵɵproperty("title", "Select " + (ctx_r2.listRecord ? ctx_r2.listRecord.Entity : "Records") + " to Add to List")("minWidth", 250)("width", 650)("height", 550);
369
+ const ctx_r1 = i0.ɵɵnextContext();
370
+ i0.ɵɵproperty("minWidth", 400)("width", 600)("height", 500);
371
+ i0.ɵɵadvance(2);
372
+ i0.ɵɵconditional(ctx_r1.showAddFromViewLoader && ctx_r1.fetchingRecordsToSave ? 2 : ctx_r1.showAddFromViewLoader && ctx_r1.addFromViewTotal > 0 ? 3 : ctx_r1.showAddFromViewLoader ? 4 : 5);
373
+ i0.ɵɵadvance(5);
374
+ i0.ɵɵproperty("disabled", ctx_r1.showAddFromViewLoader || ctx_r1.userViewsToAdd.length === 0);
215
375
  i0.ɵɵadvance();
216
- i0.ɵɵconditional(ctx_r2.showDialogLoader ? 1 : 2);
217
- i0.ɵɵadvance(3);
218
- i0.ɵɵproperty("disabled", ctx_r2.showDialogLoader);
376
+ i0.ɵɵtextInterpolate2(" Add from ", ctx_r1.userViewsToAdd.length, " View", ctx_r1.userViewsToAdd.length !== 1 ? "s" : "", " ");
377
+ i0.ɵɵadvance();
378
+ i0.ɵɵproperty("disabled", ctx_r1.showAddFromViewLoader);
219
379
  } }
220
380
  export class SingleListDetailComponent {
221
- router;
222
- route;
223
381
  sharedService;
382
+ cdr;
224
383
  ListID = "";
384
+ listDetailGrid;
385
+ // List record
225
386
  listRecord = null;
226
- sourceEntityInfo = null;
227
387
  showLoader = false;
228
- sourceGridData = [];
229
- filteredGridData = [];
230
- showAddDialog = false;
231
- showAddLoader = false;
232
- showDialogLoader = false;
388
+ // Grid state
389
+ selectedKeys = [];
390
+ rowCount = 0;
391
+ // Toolbar config - hide EDG toolbar, we'll use our own
392
+ gridToolbarConfig = {
393
+ showSearch: false,
394
+ showRefresh: false,
395
+ showAdd: false,
396
+ showDelete: false,
397
+ showExport: false,
398
+ showRowCount: false,
399
+ showSelectionCount: false
400
+ };
401
+ // Remove from list dialog
402
+ showRemoveDialog = false;
403
+ isRemoving = false;
404
+ removeProgress = 0;
405
+ removeTotal = 0;
406
+ // Add records dialog
407
+ showAddRecordsDialog = false;
408
+ addDialogLoading = false;
409
+ addDialogSaving = false;
410
+ addableRecords = [];
411
+ addRecordsSearchFilter = "";
412
+ existingListDetailIds = new Set();
413
+ addProgress = 0;
414
+ addTotal = 0;
415
+ searchSubject = new Subject();
416
+ // Add from view dialog (existing)
417
+ showAddFromViewDialog = false;
418
+ showAddFromViewLoader = false;
233
419
  userViews = null;
234
- filterDebounceTime = 250;
235
- filterItemsSubject = new Subject();
236
- filter = '';
237
420
  userViewsToAdd = [];
238
- page = 0;
239
- pageSize = 50;
240
- gridHeight = 750;
241
- sortSettings = [];
242
- selectedKeys = [];
243
- selectModeEnabled = false;
244
- viewColumns = [];
245
- visibleColumns = [];
246
- totalRowCount = 0;
247
- viewExecutionTime = 0;
248
- recordsToSave = 0;
249
- recordsSaved = 0;
421
+ addFromViewProgress = 0;
422
+ addFromViewTotal = 0;
250
423
  fetchingRecordsToSave = false;
251
- showAddSingleRecordsDialog = false;
252
- fetchingListRecords = false;
253
- listRecords = [];
254
- selectedListRecords = [];
255
- searchFilter = "";
256
- filterListrecordsSubject = new Subject();
424
+ // Dropdown menu options
257
425
  addOptions = [
258
426
  {
259
- Text: 'Add From View',
260
- Description: 'Add all records of a view to this list',
261
- Icon: 'folder',
262
- Action: () => {
263
- this.toggleAddFromViewDialog(true);
264
- }
427
+ Text: 'Add Records',
428
+ Description: 'Search and add specific records to this list',
429
+ Icon: 'search',
430
+ Action: () => this.openAddRecordsDialog()
265
431
  },
266
432
  {
267
- Text: 'Add a Record',
268
- Description: 'Add a specific record to the list',
433
+ Text: 'Add From View',
434
+ Description: 'Add all records from a saved view',
269
435
  Icon: 'folder',
270
- Action: () => {
271
- this.toggleAddRecordsDialog(true);
272
- }
436
+ Action: () => this.openAddFromViewDialog()
273
437
  }
274
438
  ];
275
- constructor(router, route, sharedService) {
276
- this.router = router;
277
- this.route = route;
439
+ constructor(sharedService, cdr) {
278
440
  this.sharedService = sharedService;
279
- this.filterItemsSubject
280
- .pipe(debounceTime(this.filterDebounceTime))
281
- .subscribe(() => this.filterItems(this.filter));
282
- this.filterListrecordsSubject
283
- .pipe(debounceTime(this.filterDebounceTime))
284
- .subscribe(() => this.loadListRecords());
441
+ this.cdr = cdr;
442
+ // Debounce search input
443
+ this.searchSubject
444
+ .pipe(debounceTime(300))
445
+ .subscribe((searchText) => this.searchRecords(searchText));
285
446
  }
286
447
  async ngOnInit() {
287
448
  if (this.ListID) {
288
- await this.loadList(this.ListID);
449
+ await this.loadListRecord();
289
450
  }
290
451
  }
291
- async loadList(listID) {
292
- if (!listID) {
452
+ /**
453
+ * Load the list entity record
454
+ */
455
+ async loadListRecord() {
456
+ if (!this.ListID)
293
457
  return;
294
- }
295
- const startTime = new Date().getTime();
296
458
  this.showLoader = true;
297
- const md = new Metadata();
298
- const rv = new RunView();
299
- this.listRecord = await md.GetEntityObject("Lists");
300
- const loadResult = await this.listRecord.Load(listID);
301
- if (!loadResult) {
302
- LogError("Error loading list with ID " + listID, undefined, this.listRecord.LatestResult);
303
- this.showLoader = false;
304
- return;
459
+ try {
460
+ const md = new Metadata();
461
+ this.listRecord = await md.GetEntityObject("Lists");
462
+ const loadResult = await this.listRecord.Load(this.ListID);
463
+ if (!loadResult) {
464
+ LogError("Error loading list with ID " + this.ListID, undefined, this.listRecord.LatestResult);
465
+ this.listRecord = null;
466
+ }
305
467
  }
306
- this.sourceEntityInfo = md.EntityByID(this.listRecord.EntityID);
307
- this.viewColumns = this.sourceEntityInfo.Fields.filter((field) => field.DefaultInView).map((field) => {
308
- return {
309
- ID: field.ID,
310
- Name: field.CodeName,
311
- DisplayName: field.DisplayName,
312
- EntityField: field,
313
- hidden: false,
314
- orderIndex: field.Sequence,
315
- width: field.DefaultColumnWidth || 100,
316
- };
317
- });
318
- /*make sure there is an entity field linked*/
319
- this.visibleColumns = this.viewColumns.filter(x => x.hidden === false && x.EntityField).sort((a, b) => {
320
- const aOrder = a.orderIndex != null ? a.orderIndex : 9999;
321
- const bOrder = b.orderIndex != null ? b.orderIndex : 9999;
322
- return aOrder - bOrder;
323
- });
324
- const primaryKeyName = this.sourceEntityInfo.FirstPrimaryKey.Name;
325
- const rvResult = await rv.RunView({
326
- EntityName: this.listRecord.Entity,
327
- ExtraFilter: `${primaryKeyName} IN (SELECT [RecordID] FROM ${md.ConfigData.MJCoreSchemaName}.[vwListDetails] WHERE ListID = '${this.listRecord.ID}')`
328
- }, md.CurrentUser);
329
- if (!rvResult.Success) {
330
- LogError(`Error loading ${this.listRecord.Entity} records: ${rvResult.ErrorMessage}`);
468
+ catch (error) {
469
+ LogError("Error loading list", undefined, error);
470
+ this.listRecord = null;
471
+ }
472
+ finally {
331
473
  this.showLoader = false;
332
- return;
474
+ this.cdr.detectChanges();
333
475
  }
334
- this.sourceGridData = this.filteredGridData = rvResult.Results;
335
- this.viewExecutionTime = (new Date().getTime() - startTime) / 1000; // in seconds
336
- this.showLoader = false;
337
476
  }
338
- pageChange(event) {
339
- this.page = event.skip;
340
- this.loadList(this.ListID);
477
+ // ==========================================
478
+ // Grid Event Handlers
479
+ // ==========================================
480
+ onRowClicked(_event) {
481
+ // Selection is handled by the grid
341
482
  }
342
- GetColumnTitle(col) {
343
- if (col.DisplayName) {
344
- // use view's display name first if it exists
345
- return col.DisplayName;
346
- }
347
- else if (col.EntityField && col.EntityField.DisplayName) {
348
- // then use entity display name, if that exist
349
- return col.EntityField.DisplayName;
350
- }
351
- else {
352
- // otherwise just use the column name
353
- return col.Name || '';
354
- }
483
+ onRowDoubleClicked(_event) {
484
+ // Navigation is handled by mj-list-detail-grid
355
485
  }
356
- getEditor(ef) {
357
- if (!ef) {
358
- return "text";
359
- }
360
- switch (ef.TSType) {
361
- case EntityFieldTSType.Boolean:
362
- return "boolean";
363
- case EntityFieldTSType.Date:
364
- return "date";
365
- case EntityFieldTSType.Number:
366
- return "numeric";
367
- default:
368
- return "text";
369
- }
486
+ onSelectionChange(keys) {
487
+ this.selectedKeys = keys;
488
+ }
489
+ onDataLoaded(event) {
490
+ this.rowCount = event.totalCount;
370
491
  }
371
- GetColumnCellStyle(col) {
372
- if (!col || !col.EntityField) {
373
- return { 'text-align': 'left', 'vertical-align': 'top' };
492
+ refreshGrid() {
493
+ if (this.listDetailGrid) {
494
+ this.listDetailGrid.refresh();
374
495
  }
375
- const fieldType = col.EntityField.Type.trim().toLowerCase();
376
- switch (fieldType) {
377
- case "money":
378
- case 'decimal':
379
- case 'real':
380
- case 'float':
381
- case 'int':
382
- // right align numbers,
383
- return { 'text-align': 'right', 'vertical-align': 'top' };
384
- default:
385
- // left align everything else
386
- return { 'text-align': 'left', 'vertical-align': 'top' };
496
+ }
497
+ // ==========================================
498
+ // Toolbar Actions
499
+ // ==========================================
500
+ onRefreshClick() {
501
+ this.refreshGrid();
502
+ }
503
+ onExportClick() {
504
+ // Trigger export on the underlying grid
505
+ if (this.listDetailGrid) {
506
+ this.listDetailGrid.export();
387
507
  }
388
508
  }
389
- async toggleAddFromViewDialog(show) {
390
- this.showAddDialog = show;
391
- if (show && !this.userViews) {
392
- await this.loadEntityViews();
509
+ onDropdownItemClick(item) {
510
+ if (item.Action) {
511
+ item.Action();
393
512
  }
394
513
  }
395
- async loadEntityViews() {
396
- this.showAddLoader = true;
397
- if (!this.listRecord || !this.listRecord.Entity) {
514
+ // ==========================================
515
+ // Remove from List Dialog
516
+ // ==========================================
517
+ openRemoveDialog() {
518
+ if (this.selectedKeys.length === 0) {
519
+ this.sharedService.CreateSimpleNotification("Please select records to remove", 'warning', 2500);
398
520
  return;
399
521
  }
400
- const rv = new RunView();
522
+ this.showRemoveDialog = true;
523
+ }
524
+ closeRemoveDialog() {
525
+ this.showRemoveDialog = false;
526
+ this.isRemoving = false;
527
+ this.removeProgress = 0;
528
+ this.removeTotal = 0;
529
+ }
530
+ async confirmRemoveFromList() {
531
+ if (!this.listRecord || this.selectedKeys.length === 0)
532
+ return;
533
+ this.isRemoving = true;
534
+ this.removeTotal = this.selectedKeys.length;
535
+ this.removeProgress = 0;
401
536
  const md = new Metadata();
402
- const runViewResult = await rv.RunView({
403
- EntityName: "User Views",
404
- ExtraFilter: `UserID = '${md.CurrentUser.ID}' AND EntityID = '${this.listRecord.EntityID}'`,
537
+ const rv = new RunView();
538
+ const entityInfo = md.EntityByID(this.listRecord.EntityID);
539
+ // selectedKeys from grid are in concatenated format (ID|value)
540
+ // For single PK entities, RecordID in DB is just the raw value
541
+ // For composite PK entities, RecordID in DB is the concatenated format
542
+ // Extract the appropriate format for the query
543
+ const selectedRecordIds = this.selectedKeys.map(key => {
544
+ if (entityInfo && entityInfo.PrimaryKeys.length === 1) {
545
+ // Single PK: extract just the value from concatenated format
546
+ const compositeKey = new CompositeKey();
547
+ compositeKey.LoadFromConcatenatedString(key);
548
+ return compositeKey.KeyValuePairs[0]?.Value || key;
549
+ }
550
+ else {
551
+ // Composite PK: use full concatenated format as-is
552
+ return key;
553
+ }
554
+ });
555
+ const listDetailsFilter = `ListID = '${this.listRecord.ID}' AND RecordID IN (${selectedRecordIds.map(id => `'${id}'`).join(',')})`;
556
+ const listDetailsResult = await rv.RunView({
557
+ EntityName: 'List Details',
558
+ ExtraFilter: listDetailsFilter,
405
559
  ResultType: 'entity_object'
406
560
  }, md.CurrentUser);
407
- if (!runViewResult.Success) {
408
- this.showAddLoader = false;
409
- LogError(`Error loading ${this.listRecord.Entity} User View records for user ${md.CurrentUser.ID}`);
561
+ if (!listDetailsResult.Success) {
562
+ LogError("Error loading list details for removal", undefined, listDetailsResult.ErrorMessage);
563
+ this.sharedService.CreateSimpleNotification("Failed to remove records", 'error', 2500);
564
+ this.isRemoving = false;
410
565
  return;
411
566
  }
412
- this.userViews = runViewResult.Results;
413
- this.showAddLoader = false;
414
- }
415
- async addTolist() {
416
- if (!this.listRecord) {
417
- return;
567
+ // Use transaction group for bulk delete
568
+ const tg = await md.CreateTransactionGroup();
569
+ const listDetails = listDetailsResult.Results;
570
+ for (const listDetail of listDetails) {
571
+ listDetail.TransactionGroup = tg;
572
+ await listDetail.Delete();
418
573
  }
419
- if (!this.listRecord.Entity) {
420
- return;
574
+ const success = await tg.Submit();
575
+ if (success) {
576
+ this.removeProgress = this.removeTotal;
577
+ this.sharedService.CreateSimpleNotification(`Removed ${listDetails.length} record${listDetails.length !== 1 ? 's' : ''} from list`, 'success', 2500);
578
+ this.closeRemoveDialog();
579
+ this.listDetailGrid?.clearSelection();
580
+ this.refreshGrid();
421
581
  }
422
- this.showAddLoader = true;
423
- this.fetchingRecordsToSave = true;
424
- const rv = new RunView();
425
- const md = new Metadata();
426
- const hashMap = new Map();
427
- await Promise.all(this.userViewsToAdd.map(async (userView) => {
428
- const runViewResult = await rv.RunView({
429
- EntityName: "User Views",
430
- ViewEntity: userView,
431
- Fields: ["ID"]
432
- }, md.CurrentUser);
433
- if (!runViewResult.Success) {
434
- LogError(`Error loading view ${userView.Name} for user ${md.CurrentUser.ID}`);
435
- return;
436
- }
437
- const records = runViewResult.Results;
438
- for (const record of records) {
439
- hashMap.set(record.ID, record);
440
- }
441
- }));
442
- this.recordsToSave = hashMap.size;
443
- this.recordsSaved = 0;
444
- this.fetchingRecordsToSave = false;
445
- LogStatus(`Adding ${hashMap.size} records to list ${this.listRecord.ID}`);
446
- //now add the records to the list
447
- const recordIDs = [...hashMap.keys()];
448
- const chunkSize = 100;
449
- for (let i = 0; i < recordIDs.length; i += chunkSize) {
450
- const chunk = recordIDs.slice(i, i + chunkSize);
451
- await Promise.all(chunk.map(async (recordID) => {
452
- const listDetail = await md.GetEntityObject("List Details");
453
- listDetail.ListID = this.listRecord.ID;
454
- listDetail.RecordID = recordID.toString();
455
- listDetail.ContextCurrentUser = md.CurrentUser;
456
- const saveResult = await listDetail.Save();
457
- if (!saveResult) {
458
- LogError(`Error adding record ${recordID} to list ${this.listRecord.ID}`, undefined, listDetail.LatestResult);
459
- }
460
- this.recordsSaved++;
461
- }));
582
+ else {
583
+ LogError("Error removing records from list");
584
+ this.sharedService.CreateSimpleNotification("Failed to remove some records", 'error', 2500);
585
+ this.isRemoving = false;
462
586
  }
463
- this.showAddLoader = false;
464
- this.toggleAddFromViewDialog(false);
465
- this.loadList(this.listRecord.ID);
466
587
  }
467
- onListSearchValueChange(Value) {
468
- this.filter = Value;
469
- this.filterItemsSubject.next(true);
588
+ // ==========================================
589
+ // Add Records Dialog
590
+ // ==========================================
591
+ async openAddRecordsDialog() {
592
+ this.showAddRecordsDialog = true;
593
+ this.addableRecords = [];
594
+ this.addRecordsSearchFilter = "";
595
+ this.addDialogLoading = true;
596
+ this.addDialogSaving = false;
597
+ // Load existing list detail IDs to mark which records are already in the list
598
+ await this.loadExistingListDetailIds();
599
+ this.addDialogLoading = false;
470
600
  }
471
- onListRecordDialogValueChange(Value) {
472
- this.searchFilter = Value;
473
- this.filterListrecordsSubject.next(true);
601
+ closeAddRecordsDialog() {
602
+ this.showAddRecordsDialog = false;
603
+ this.addableRecords = [];
604
+ this.addRecordsSearchFilter = "";
605
+ this.existingListDetailIds.clear();
606
+ this.addDialogSaving = false;
607
+ this.addProgress = 0;
608
+ this.addTotal = 0;
474
609
  }
475
- filterItems(filter) {
476
- if (!filter || filter === "") {
477
- this.filteredGridData = this.sourceGridData;
610
+ async loadExistingListDetailIds() {
611
+ if (!this.listRecord)
478
612
  return;
613
+ const md = new Metadata();
614
+ const rv = new RunView();
615
+ const result = await rv.RunView({
616
+ EntityName: 'List Details',
617
+ ExtraFilter: `ListID = '${this.listRecord.ID}'`,
618
+ Fields: ['RecordID'],
619
+ ResultType: 'simple'
620
+ }, md.CurrentUser);
621
+ if (result.Success) {
622
+ this.existingListDetailIds = new Set(result.Results.map(r => r.RecordID));
479
623
  }
480
- if (!this.listRecord) {
624
+ }
625
+ onAddRecordsSearchChange(value) {
626
+ this.addRecordsSearchFilter = value;
627
+ this.searchSubject.next(value);
628
+ }
629
+ async searchRecords(searchText) {
630
+ if (!this.listRecord || !searchText || searchText.length < 2) {
631
+ this.addableRecords = [];
481
632
  return;
482
633
  }
483
- if (!this.sourceGridData) {
484
- this.sourceGridData = [];
485
- }
486
- const toLower = filter.toLowerCase();
487
- const nameField = this.listRecord.EntityInfo.Fields.find((field) => field.IsNameField);
488
- if (!nameField) {
489
- LogError("Unable to filter list: No name field found");
634
+ this.addDialogLoading = true;
635
+ const md = new Metadata();
636
+ const sourceEntityInfo = md.EntityByID(this.listRecord.EntityID);
637
+ if (!sourceEntityInfo) {
638
+ this.addDialogLoading = false;
490
639
  return;
491
640
  }
492
- this.filteredGridData = this.sourceGridData.filter((data) => {
493
- const name = data[nameField.Name];
494
- return name.toLowerCase().includes(toLower);
641
+ const nameField = sourceEntityInfo.Fields.find(field => field.IsNameField);
642
+ const pkField = sourceEntityInfo.FirstPrimaryKey?.Name || 'ID';
643
+ let filter;
644
+ if (nameField) {
645
+ filter = `${nameField.Name} LIKE '%${searchText}%'`;
646
+ }
647
+ const rv = new RunView();
648
+ const result = await rv.RunView({
649
+ EntityName: this.listRecord.Entity,
650
+ ExtraFilter: filter,
651
+ MaxRows: 100,
652
+ ResultType: 'simple'
495
653
  });
654
+ if (result.Success) {
655
+ this.addableRecords = result.Results.map((record) => {
656
+ const recordId = String(record[pkField]);
657
+ return {
658
+ ID: recordId,
659
+ Name: nameField ? String(record[nameField.Name]) : recordId,
660
+ isInList: this.existingListDetailIds.has(recordId),
661
+ isSelected: false
662
+ };
663
+ });
664
+ }
665
+ this.addDialogLoading = false;
666
+ this.cdr.detectChanges();
496
667
  }
497
- addViewToSelectedList(view) {
498
- this.userViewsToAdd.push(view);
668
+ toggleRecordSelection(record) {
669
+ if (record.isInList)
670
+ return; // Can't select records already in list
671
+ record.isSelected = !record.isSelected;
499
672
  }
500
- removeViewFromSelectedList(view) {
501
- this.userViewsToAdd.filter((userView) => userView.ID !== view.ID);
673
+ get selectedAddableRecords() {
674
+ return this.addableRecords.filter(r => r.isSelected);
502
675
  }
503
- onDropdownItemClick(item) {
504
- if (!item.Action) {
676
+ selectAllAddable() {
677
+ this.addableRecords.forEach(r => {
678
+ if (!r.isInList)
679
+ r.isSelected = true;
680
+ });
681
+ }
682
+ deselectAllAddable() {
683
+ this.addableRecords.forEach(r => r.isSelected = false);
684
+ }
685
+ async confirmAddRecords() {
686
+ const recordsToAdd = this.selectedAddableRecords;
687
+ if (recordsToAdd.length === 0 || !this.listRecord)
505
688
  return;
689
+ this.addDialogSaving = true;
690
+ // Reserve 20% of progress for tg.Submit()
691
+ this.addTotal = recordsToAdd.length;
692
+ this.addProgress = 0;
693
+ const progressPerRecord = 0.8 / recordsToAdd.length; // 80% for individual saves
694
+ const md = new Metadata();
695
+ // Use transaction group for bulk insert
696
+ const tg = await md.CreateTransactionGroup();
697
+ for (let i = 0; i < recordsToAdd.length; i++) {
698
+ const record = recordsToAdd[i];
699
+ const listDetail = await md.GetEntityObject("List Details", md.CurrentUser);
700
+ listDetail.ListID = this.listRecord.ID;
701
+ listDetail.RecordID = record.ID;
702
+ listDetail.TransactionGroup = tg;
703
+ const result = await listDetail.Save();
704
+ if (!result) {
705
+ LogErrorEx({
706
+ message: listDetail.LatestResult?.CompleteMessage
707
+ });
708
+ }
709
+ // Update progress (0-80%)
710
+ this.addProgress = Math.round((i + 1) * progressPerRecord * this.addTotal);
711
+ }
712
+ // Show 80% complete before submit
713
+ this.addProgress = Math.round(this.addTotal * 0.8);
714
+ const success = await tg.Submit();
715
+ if (success) {
716
+ this.addProgress = this.addTotal;
717
+ this.sharedService.CreateSimpleNotification(`Added ${recordsToAdd.length} record${recordsToAdd.length !== 1 ? 's' : ''} to list`, 'success', 2500);
718
+ this.closeAddRecordsDialog();
719
+ this.refreshGrid();
720
+ }
721
+ else {
722
+ LogError("Error adding records to list");
723
+ this.sharedService.CreateSimpleNotification("Failed to add some records", 'error', 2500);
724
+ this.addDialogSaving = false;
506
725
  }
507
- item.Action();
508
726
  }
509
- async toggleAddRecordsDialog(show) {
510
- this.showAddSingleRecordsDialog = show;
511
- if (show) {
512
- this.listRecords = [];
513
- this.searchFilter = "";
514
- await this.loadListRecords();
727
+ // ==========================================
728
+ // Add From View Dialog (existing functionality, cleaned up)
729
+ // ==========================================
730
+ async openAddFromViewDialog() {
731
+ this.showAddFromViewDialog = true;
732
+ this.userViewsToAdd = [];
733
+ if (!this.userViews) {
734
+ await this.loadEntityViews();
515
735
  }
516
736
  }
517
- async loadListRecords() {
518
- if (!this.listRecord) {
519
- LogError("Error loading list records. List record is null");
737
+ closeAddFromViewDialog() {
738
+ this.showAddFromViewDialog = false;
739
+ this.userViewsToAdd = [];
740
+ this.showAddFromViewLoader = false;
741
+ this.addFromViewProgress = 0;
742
+ this.addFromViewTotal = 0;
743
+ }
744
+ async loadEntityViews() {
745
+ if (!this.listRecord || !this.listRecord.Entity)
520
746
  return;
747
+ this.showAddFromViewLoader = true;
748
+ const rv = new RunView();
749
+ const md = new Metadata();
750
+ const runViewResult = await rv.RunView({
751
+ EntityName: "User Views",
752
+ ExtraFilter: `UserID = '${md.CurrentUser.ID}' AND EntityID = '${this.listRecord.EntityID}'`,
753
+ ResultType: 'entity_object'
754
+ }, md.CurrentUser);
755
+ if (!runViewResult.Success) {
756
+ LogError(`Error loading User Views for entity ${this.listRecord.Entity}`);
521
757
  }
522
- if (!this.sourceEntityInfo) {
523
- LogError("Error loading list records. Source entity info is null");
524
- return;
758
+ else {
759
+ this.userViews = runViewResult.Results;
525
760
  }
526
- this.fetchingListRecords = true;
527
- const primaryKeyName = this.sourceEntityInfo.FirstPrimaryKey.Name;
528
- let filter = undefined;
529
- const nameField = this.sourceEntityInfo.Fields.find((field) => field.IsNameField);
530
- if (nameField && this.searchFilter) {
531
- filter = `${nameField.Name} LIKE '%${this.searchFilter}%'`;
761
+ this.showAddFromViewLoader = false;
762
+ }
763
+ toggleViewSelection(view) {
764
+ const index = this.userViewsToAdd.findIndex(v => v.ID === view.ID);
765
+ if (index >= 0) {
766
+ this.userViewsToAdd.splice(index, 1);
532
767
  }
533
- const rv = new RunView();
534
- const rvResult = await rv.RunView({
535
- EntityName: this.listRecord.Entity,
536
- ExtraFilter: filter,
537
- MaxRows: 50
538
- });
539
- if (!rvResult.Success) {
540
- LogError(`Error loading list records for list ${this.listRecord.ID}`, undefined, rvResult.ErrorMessage);
541
- this.fetchingListRecords = false;
542
- return;
768
+ else {
769
+ this.userViewsToAdd.push(view);
543
770
  }
544
- this.listRecords = rvResult.Results.filter((record) => {
545
- const alreadyExits = this.sourceGridData.some((selectedRecord) => selectedRecord.ID === record[primaryKeyName]);
546
- return !alreadyExits;
547
- }).map((record) => {
548
- let result = { ID: record[primaryKeyName], Name: record[nameField.Name] };
549
- return result;
550
- });
551
- this.fetchingListRecords = false;
552
771
  }
553
- async addListRecord(listRecord) {
554
- if (!this.listRecord) {
555
- LogError("Error adding list record. List record is null");
556
- this.sharedService.CreateSimpleNotification("Unable to add record to list");
772
+ isViewSelected(view) {
773
+ return this.userViewsToAdd.some(v => v.ID === view.ID);
774
+ }
775
+ async confirmAddFromView() {
776
+ if (!this.listRecord || this.userViewsToAdd.length === 0)
557
777
  return;
558
- }
778
+ this.showAddFromViewLoader = true;
779
+ this.fetchingRecordsToSave = true;
780
+ const rv = new RunView();
559
781
  const md = new Metadata();
560
- const listEntity = await md.GetEntityObject("List Details", md.CurrentUser);
561
- listEntity.ListID = this.listRecord.ID;
562
- listEntity.RecordID = listRecord.ID;
563
- const saveResult = await listEntity.Save();
564
- if (!saveResult) {
565
- LogError(`Error adding record ${listRecord.ID} to list ${this.listRecord.ID}`, undefined, listEntity.LatestResult);
566
- const alreadyExists = listEntity.LatestResult.CompleteMessage.includes("already exists in List");
567
- if (alreadyExists) {
568
- this.sharedService.CreateSimpleNotification("Record already exists in this list", 'error', 2500);
569
- return;
782
+ // Collect all unique record IDs from selected views
783
+ const recordIdSet = new Set();
784
+ for (const userView of this.userViewsToAdd) {
785
+ const runViewResult = await rv.RunView({
786
+ EntityName: "User Views",
787
+ ViewEntity: userView,
788
+ Fields: ["ID"]
789
+ }, md.CurrentUser);
790
+ if (runViewResult.Success) {
791
+ const records = runViewResult.Results;
792
+ records.forEach(r => recordIdSet.add(r.ID));
570
793
  }
571
- this.sharedService.CreateSimpleNotification("Unable to add record to list", 'error', 2500);
794
+ }
795
+ // Filter out records already in the list
796
+ await this.loadExistingListDetailIds();
797
+ const recordsToAdd = [...recordIdSet].filter(id => !this.existingListDetailIds.has(id));
798
+ this.addFromViewTotal = recordsToAdd.length;
799
+ this.addFromViewProgress = 0;
800
+ this.fetchingRecordsToSave = false;
801
+ const progressPerRecord = 0.8 / Math.max(recordsToAdd.length, 1); // 80% for individual saves
802
+ if (recordsToAdd.length === 0) {
803
+ this.sharedService.CreateSimpleNotification("All records already in list", 'info', 2500);
804
+ this.showAddFromViewLoader = false;
572
805
  return;
573
806
  }
574
- this.sharedService.CreateSimpleNotification("Unable to add record to list", 'success', 2500);
807
+ LogStatus(`Adding ${recordsToAdd.length} records to list`);
808
+ // Use transaction group for bulk insert
809
+ const tg = await md.CreateTransactionGroup();
810
+ for (let i = 0; i < recordsToAdd.length; i++) {
811
+ const recordID = recordsToAdd[i];
812
+ const listDetail = await md.GetEntityObject("List Details", md.CurrentUser);
813
+ listDetail.ListID = this.listRecord.ID;
814
+ listDetail.RecordID = recordID;
815
+ listDetail.TransactionGroup = tg;
816
+ const result = await listDetail.Save();
817
+ if (!result) {
818
+ LogErrorEx({
819
+ message: listDetail.LatestResult?.CompleteMessage
820
+ });
821
+ }
822
+ // Update progress (0-80%)
823
+ this.addFromViewProgress = Math.round((i + 1) * progressPerRecord * this.addFromViewTotal);
824
+ }
825
+ // Show 80% complete before submit
826
+ this.addFromViewProgress = Math.round(this.addFromViewTotal * 0.8);
827
+ const success = await tg.Submit();
828
+ if (success) {
829
+ this.addFromViewProgress = this.addFromViewTotal;
830
+ this.sharedService.CreateSimpleNotification(`Added ${recordsToAdd.length} record${recordsToAdd.length !== 1 ? 's' : ''} to list`, 'success', 2500);
831
+ this.closeAddFromViewDialog();
832
+ this.refreshGrid();
833
+ }
834
+ else {
835
+ LogError("Error adding records from view to list");
836
+ this.sharedService.CreateSimpleNotification("Failed to add some records", 'error', 2500);
837
+ this.showAddFromViewLoader = false;
838
+ }
575
839
  }
576
- static ɵfac = function SingleListDetailComponent_Factory(t) { return new (t || SingleListDetailComponent)(i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i2.SharedService)); };
577
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleListDetailComponent, selectors: [["mj-list-detail"]], inputs: { ListID: "ListID" }, decls: 17, vars: 7, consts: [["searchInput", ""], [1, "app-container"], [1, "flex-display-row-header"], ["textField", "Text", "themeColor", "info", 1, "add-btn", 3, "itemClick", "data"], [1, "fa-solid", "fa-plus"], [1, "title-wrapper"], [1, "search"], ["type", "text", "placeholder", "Search in List", "size", "large", "rounded", "large", "fillMode", "solid", 3, "keyup", "clearButton"], ["kendoTextBoxPrefixTemplate", "", 3, "showSeparator"], ["size", "medium", 3, "showText"], [3, "data"], ["class", "dialog-wrapper", "title", "Select Views to Add", 3, "minWidth", "width", "height", "close", 4, "ngIf"], ["class", "dialog-wrapper", 3, "title", "minWidth", "width", "height", "close", 4, "ngIf"], [1, "fa-solid", "fa-magnifying-glass", "margin-left-small"], [3, "width", "headerStyle", "style", 4, "ngIf"], [3, "field", "title", "width", "editable", "editor", "headerStyle", "style", 4, "ngFor", "ngForOf"], [3, "width", "headerStyle"], [3, "field", "title", "width", "editable", "editor", "headerStyle"], [4, "ngIf"], ["kendoGridFooterTemplate", ""], [2, "font-size", "smaller", "font-weight", "normal"], ["title", "Select Views to Add", 1, "dialog-wrapper", 3, "close", "minWidth", "width", "height"], [1, "popup-actions-btn"], ["kendoButton", "", "themeColor", "info", 1, "cancel-btn", 3, "click", "disabled"], ["kendoButton", "", "fillMode", "outline", "themeColor", "info", 1, "yes-btn", 3, "click", "disabled"], ["size", "small", 3, "showText"], [3, "min", "max", "value", "indeterminate"], [1, "search-header"], ["id", "listSearch", "placeholder", "Search Views...", "kendoTextBox", "", 1, "search-bar", 3, "clearButton"], [1, "overflow-y-scroll"], [1, "list-item"], [1, "list-text", 3, "ngClass"], ["kendoButton", "", 1, "btn-no-border", "btn-selected"], ["kendoButton", "", 1, "btn-no-border"], ["kendoButton", "", 1, "btn-no-border", "btn-selected", 3, "click"], [1, "fa-solid", "fa-minus"], ["kendoButton", "", 1, "btn-no-border", 3, "click"], [1, "btn-margin-right"], [1, "dialog-wrapper", 3, "close", "title", "minWidth", "width", "height"], ["id", "listRecordSearch", "kendoTextBox", "", 1, "search-bar", 3, "valueChange", "placeholder", "clearButton"], [1, "list-text"]], template: function SingleListDetailComponent_Template(rf, ctx) { if (rf & 1) {
578
- const _r1 = i0.ɵɵgetCurrentView();
840
+ static ɵfac = function SingleListDetailComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SingleListDetailComponent)(i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
841
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleListDetailComponent, selectors: [["mj-list-detail"]], viewQuery: function SingleListDetailComponent_Query(rf, ctx) { if (rf & 1) {
842
+ i0.ɵɵviewQuery(_c0, 5);
843
+ } if (rf & 2) {
844
+ let _t;
845
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.listDetailGrid = _t.first);
846
+ } }, inputs: { ListID: "ListID" }, decls: 13, vars: 8, consts: [["listDetailGrid", ""], [1, "list-detail-container"], [1, "list-header"], ["textField", "Text", "themeColor", "info", 1, "add-btn", 3, "itemClick", "data"], [1, "fa-solid", "fa-plus"], [1, "custom-toolbar"], [1, "loading-container"], [1, "grid-container"], ["title", "Remove from List", 3, "minWidth", "width", "close", 4, "ngIf"], [3, "title", "minWidth", "width", "height", "close", 4, "ngIf"], ["title", "Add Records from Views", 3, "minWidth", "width", "height", "close", 4, "ngIf"], [1, "toolbar-left"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], ["kendoButton", "", "fillMode", "flat", "themeColor", "error", 1, "toolbar-button", "remove-btn"], ["kendoButton", "", "fillMode", "flat", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-rotate"], [1, "fa-solid", "fa-file-export"], ["kendoButton", "", "fillMode", "flat", "themeColor", "error", 1, "toolbar-button", "remove-btn", 3, "click"], [1, "fa-solid", "fa-trash"], ["text", "Loading list...", "size", "medium"], [3, "rowClicked", "rowDoubleClicked", "selectionChange", "dataLoaded", "listId", "listEntity", "autoNavigate", "height", "showToolbar", "toolbarConfig", "selectionMode"], ["title", "Remove from List", 3, "close", "minWidth", "width"], [1, "dialog-content"], [1, "dialog-loading"], [1, "dialog-message"], ["kendoButton", "", "themeColor", "error", 3, "click", "disabled"], ["kendoButton", "", "fillMode", "outline", 3, "click", "disabled"], ["text", "Removing records...", "size", "small"], [1, "progress-bar", 3, "min", "max", "value", "label"], [1, "fa-solid", "fa-triangle-exclamation", "warning-icon"], [1, "dialog-note"], [3, "close", "title", "minWidth", "width", "height"], [1, "dialog-content", "add-records-dialog"], ["kendoButton", "", "themeColor", "info", 3, "click", "disabled"], ["text", "Adding records to list...", "size", "small"], [1, "search-section"], [1, "search-input", 3, "valueChange", "placeholder", "clearButton", "value"], ["kendoTextBoxPrefixTemplate", ""], [1, "search-hint"], [1, "records-list"], [1, "list-loading"], [1, "empty-results"], [1, "fa-solid", "fa-search", "search-icon"], ["size", "small", 3, "showText"], [1, "fa-solid", "fa-search", "empty-icon"], [1, "fa-solid", "fa-list", "empty-icon"], [1, "selection-controls"], ["kendoButton", "", "fillMode", "flat", "size", "small", 3, "click"], [1, "selection-info"], [1, "records-scroll"], [1, "record-item", 3, "in-list", "selected"], [1, "record-item", 3, "click"], [1, "record-checkbox"], ["title", "Already in list", 1, "fa-solid", "fa-check", "in-list-icon"], ["type", "checkbox", 3, "checked"], [1, "record-name"], [1, "in-list-badge"], ["type", "checkbox", 3, "click", "change", "checked"], ["title", "Add Records from Views", 3, "close", "minWidth", "width", "height"], ["text", "Loading records from views...", "size", "small"], ["text", "Loading views...", "size", "small"], [1, "dialog-instruction"], [1, "views-list"], [1, "fa-solid", "fa-folder-open", "empty-icon"], [1, "view-item", 3, "selected"], [1, "view-item", 3, "click"], [1, "fa-solid", "fa-table-list", "view-icon"], [1, "view-name"]], template: function SingleListDetailComponent_Template(rf, ctx) { if (rf & 1) {
579
847
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h1");
580
848
  i0.ɵɵtext(3);
581
849
  i0.ɵɵelementEnd();
582
850
  i0.ɵɵelementStart(4, "kendo-dropdownbutton", 3);
583
- i0.ɵɵlistener("itemClick", function SingleListDetailComponent_Template_kendo_dropdownbutton_itemClick_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDropdownItemClick($event)); });
851
+ i0.ɵɵlistener("itemClick", function SingleListDetailComponent_Template_kendo_dropdownbutton_itemClick_4_listener($event) { return ctx.onDropdownItemClick($event); });
584
852
  i0.ɵɵelement(5, "span", 4);
585
853
  i0.ɵɵtext(6, " Add to List ");
586
854
  i0.ɵɵelementEnd()();
587
- i0.ɵɵelementStart(7, "div")(8, "div", 5)(9, "div", 6)(10, "kendo-textbox", 7, 0);
588
- i0.ɵɵlistener("keyup", function SingleListDetailComponent_Template_kendo_textbox_keyup_10_listener() { i0.ɵɵrestoreView(_r1); const searchInput_r2 = i0.ɵɵreference(11); return i0.ɵɵresetView(ctx.onListSearchValueChange(searchInput_r2.value)); });
589
- i0.ɵɵtemplate(12, SingleListDetailComponent_ng_template_12_Template, 1, 0, "ng-template", 8);
590
- i0.ɵɵelementEnd()()()();
591
- i0.ɵɵtemplate(13, SingleListDetailComponent_Conditional_13_Template, 1, 1, "mj-loading", 9)(14, SingleListDetailComponent_Conditional_14_Template, 3, 3, "kendo-grid", 10);
855
+ i0.ɵɵtemplate(7, SingleListDetailComponent_Conditional_7_Template, 13, 4, "div", 5)(8, SingleListDetailComponent_Conditional_8_Template, 2, 0, "div", 6)(9, SingleListDetailComponent_Conditional_9_Template, 3, 7, "div", 7);
592
856
  i0.ɵɵelementEnd();
593
- i0.ɵɵtemplate(15, SingleListDetailComponent_kendo_dialog_15_Template, 8, 6, "kendo-dialog", 11)(16, SingleListDetailComponent_kendo_dialog_16_Template, 6, 6, "kendo-dialog", 12);
857
+ i0.ɵɵtemplate(10, SingleListDetailComponent_kendo_dialog_10_Template, 9, 5, "kendo-dialog", 8)(11, SingleListDetailComponent_kendo_dialog_11_Template, 9, 9, "kendo-dialog", 9)(12, SingleListDetailComponent_kendo_dialog_12_Template, 11, 8, "kendo-dialog", 10);
594
858
  } if (rf & 2) {
595
859
  i0.ɵɵadvance(3);
596
860
  i0.ɵɵtextInterpolate(ctx.listRecord ? ctx.listRecord.Name : "List");
597
861
  i0.ɵɵadvance();
598
862
  i0.ɵɵproperty("data", ctx.addOptions);
599
- i0.ɵɵadvance(6);
600
- i0.ɵɵproperty("clearButton", true);
601
- i0.ɵɵadvance(2);
602
- i0.ɵɵproperty("showSeparator", true);
863
+ i0.ɵɵadvance(3);
864
+ i0.ɵɵconditional(!ctx.showLoader && ctx.listRecord ? 7 : -1);
865
+ i0.ɵɵadvance();
866
+ i0.ɵɵconditional(ctx.showLoader ? 8 : -1);
867
+ i0.ɵɵadvance();
868
+ i0.ɵɵconditional(!ctx.showLoader && ctx.listRecord ? 9 : -1);
869
+ i0.ɵɵadvance();
870
+ i0.ɵɵproperty("ngIf", ctx.showRemoveDialog);
603
871
  i0.ɵɵadvance();
604
- i0.ɵɵconditional(ctx.showLoader ? 13 : 14);
605
- i0.ɵɵadvance(2);
606
- i0.ɵɵproperty("ngIf", ctx.showAddDialog);
872
+ i0.ɵɵproperty("ngIf", ctx.showAddRecordsDialog);
607
873
  i0.ɵɵadvance();
608
- i0.ɵɵproperty("ngIf", ctx.showAddSingleRecordsDialog);
609
- } }, dependencies: [i3.NgClass, i3.NgForOf, i3.NgIf, i4.GridComponent, i4.ColumnComponent, i4.FooterTemplateDirective, i4.CheckboxColumnComponent, i5.DialogComponent, i5.DialogActionsComponent, i6.ButtonComponent, i6.DropDownButtonComponent, i7.TextBoxComponent, i7.TextBoxPrefixTemplateDirective, i8.ProgressBarComponent, i9.LoadingComponent, i3.DecimalPipe], styles: [".app-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.flex-display-row-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 10px;\n}\n\n.title-wrapper[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 0;\n border-bottom: 1px solid var(--med-gray);\n}\n\n.title-wrapper[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n line-height: 28px;\n}\n\n.title-wrapper[_ngcontent-%COMP%] .search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n font-size: 16px;\n background: transparent;\n border: none;\n box-sizing: border-box;\n padding-left: 40px;\n}\n\n .title-wrapper[_ngcontent-%COMP%] .search[_ngcontent-%COMP%] {\n background: var(--light-shade);\n width: 360px;\n height: 44px;\n position: relative;\n border-radius: 10px;\n}\n\n.title-wrapper[_ngcontent-%COMP%] .search[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 12px;\n}\n\n.add-btn[_ngcontent-%COMP%] {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--border-blue);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn[_ngcontent-%COMP%]:hover {\n filter: brightness(85%);\n}\n\n.margin-left-small[_ngcontent-%COMP%] {\n margin-left: 10px;\n}\n\n\n.overflow-y-scroll[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 300px;\n}\n\n.padding-bottom-small[_ngcontent-%COMP%] {\n padding-bottom: 10px;\n}\n\n.list-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n padding-bottom: 5px;\n align-items: center;\n}\n\n.btn-no-border[_ngcontent-%COMP%] {\n border: none;\n background: none;\n color: var(--border-blue);\n font-size: 16px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.btn-selected[_ngcontent-%COMP%] {\n font-weight: bold;\n}\n\n.list-text[_ngcontent-%COMP%] {\n font-size: large;\n}\n.list-selected[_ngcontent-%COMP%] {\n font-weight: bold;\n color: var(--border-blue);\n}\n\n.btn-margin-right[_ngcontent-%COMP%] {\n margin-right: 35px;\n}\n\n.divider[_ngcontent-%COMP%] {\n color: lightgray\n}\n\n.search-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 0;\n}\n\n.search-bar[_ngcontent-%COMP%] {\n width: 65%;\n padding-bottom: 10px;\n}\n\n.dialog-wrapper[_ngcontent-%COMP%] {\n padding: 15px 25px;\n}\n\n.btn-outline[_ngcontent-%COMP%] {\n border: 2px solid var(--border-blue);\n border-radius: 8px;\n padding: 5px 30px;\n\n background: none;\n color: var(--border-blue);\n font-size: 16px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.k-dropdown-button[_ngcontent-%COMP%] .k-button[_ngcontent-%COMP%] {\n background: var(--border-blue);\n color: var(--white-color);\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n.k-dropdown-button[_ngcontent-%COMP%] .k-button[_ngcontent-%COMP%] .k-button-text[_ngcontent-%COMP%] .card-header-entity[_ngcontent-%COMP%] .add-item[_ngcontent-%COMP%] .k-button[_ngcontent-%COMP%] .k-button-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.btn-cmn[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n min-width: 44px;\n background: transparent;\n border-radius: 8px;\n border: 1px solid var(--gray-color);\n}\n\n.btn-cmn.active[_ngcontent-%COMP%] {\n border: 1px solid var(--border-blue);\n}"] });
874
+ i0.ɵɵproperty("ngIf", ctx.showAddFromViewDialog);
875
+ } }, dependencies: [i2.NgIf, i3.DialogComponent, i3.DialogActionsComponent, i4.ButtonComponent, i4.DropDownButtonComponent, i5.TextBoxComponent, i5.TextBoxPrefixTemplateDirective, i6.ProgressBarComponent, i7.LoadingComponent, i8.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}"] });
610
876
  }
611
877
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleListDetailComponent, [{
612
878
  type: Component,
613
- args: [{ selector: 'mj-list-detail', template: "<div class=\"app-container\">\n <div class=\"flex-display-row-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 <div>\n <div class=\"title-wrapper\">\n <div class=\"search\">\n <kendo-textbox \n type=\"text\" \n #searchInput \n placeholder=\"Search in List\" \n (keyup)=\"onListSearchValueChange(searchInput.value)\"\n [clearButton]=\"true\"\n size=\"large\"\n rounded=\"large\"\n fillMode=\"solid\"\n >\n <ng-template kendoTextBoxPrefixTemplate [showSeparator]=\"true\">\n <span class=\"fa-solid fa-magnifying-glass margin-left-small\"></span>\n </ng-template>\n </kendo-textbox>\n </div>\n </div>\n </div>\n @if(showLoader){\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n }\n @else{\n <kendo-grid [data]=\"filteredGridData\">\n <kendo-grid-checkbox-column \n *ngIf=\"selectModeEnabled\" \n [width]=\"50\" \n [headerStyle]=\"{ 'font-weight' : 'bold', 'background-color': 'white' }\" \n [style]=\"{'text-align': 'center', 'vertical-align': 'center'}\">\n </kendo-grid-checkbox-column>\n \n <kendo-grid-column \n *ngFor=\"let item of visibleColumns\" \n [field]=\"item.Name || ''\" \n [title]=\"GetColumnTitle(item)\"\n [width]=\"item.width ? item.width : 100\"\n [editable]=\"item.EntityField?.AllowUpdateAPI || false\"\n [editor]=\"getEditor(item.EntityField)\"\n [headerStyle]=\"{ 'font-weight' : 'bold', 'background-color': 'white' }\"\n [style]=\"this.GetColumnCellStyle(item)\"\n >\n <ng-template *ngIf=\"item===visibleColumns[0]\" kendoGridFooterTemplate >\n {{this.filteredGridData.length | number}}{{this.totalRowCount > this.filteredGridData.length ? ' of ' + (this.totalRowCount | number) : ' rows'}}<br/><span style=\"font-size: smaller; font-weight: normal;\">{{viewExecutionTime | number:'1.2-2'}} seconds</span>\n </ng-template>\n </kendo-grid-column>\n\n <!--\n <kendo-excelexport #excelExport [data]=\"exportData\" [fileName]=\"(_viewEntity ? _viewEntity.Get('Name') : _entityInfo?.Name) + '.xlsx'\">\n <kendo-excelexport-column *ngFor=\"let exportCol of exportColumns\" [field]=\"exportCol.Name\" [title]=\"exportCol.Name\">\n </kendo-excelexport-column>\n </kendo-excelexport>\n -->\n </kendo-grid>\n }\n</div>\n\n<kendo-dialog\nclass=\"dialog-wrapper\"\ntitle=\"Select Views to Add\"\n*ngIf=\"showAddDialog\"\n(close)=\"toggleAddFromViewDialog(false)\"\n[minWidth]=\"250\"\n[width]=\"650\"\n[height]=\"550\"\n>\n@if(showAddLoader){\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <kendo-progressbar \n [min]=\"0\"\n [max]=\"recordsToSave\"\n [value]=\"recordsSaved\"\n [indeterminate]=\"fetchingRecordsToSave\"\n />\n}\n@else {\n <div class=\"search-header\">\n <kendo-textbox\n id=\"listSearch\"\n placeholder=\"Search Views...\"\n kendoTextBox\n [clearButton]=\"true\"\n class=\"search-bar\"\n />\n </div>\n <hr>\n @for(userView of userViews; track userView){\n <div class=\"overflow-y-scroll\">\n <div class=\"list-item\">\n <div class=\"list-text\" [ngClass]=\"{'list-selected': userViewsToAdd.includes(userView)}\">\n {{userView.Name}}\n </div>\n @if(userViewsToAdd.includes(userView)){\n <button kendoButton class=\"btn-no-border btn-selected\" (click)=\"removeViewFromSelectedList(userView)\">\n <span class=\"fa-solid fa-minus\"></span>\n Remove\n </button>\n }\n @else {\n <button kendoButton class=\"btn-no-border\" (click)=\"addViewToSelectedList(userView)\">\n <div class=\"btn-margin-right\">\n <span class=\"fa-solid fa-plus\"></span>\n Add\n </div>\n </button>\n }\n </div>\n <hr>\n </div>\n }\n}\n <kendo-dialog-actions class=\"popup-actions-btn\">\n <button class=\"cancel-btn\" (click)=\"addTolist()\" [disabled]=\"showAddLoader\" kendoButton themeColor=\"info\">\n Done\n </button>\n <button class=\"yes-btn\" (click)=\"toggleAddFromViewDialog(false)\" [disabled]=\"showAddLoader\" kendoButton fillMode=\"outline\" themeColor=\"info\">\n Cancel\n </button>\n </kendo-dialog-actions>\n</kendo-dialog>\n\n<kendo-dialog\nclass=\"dialog-wrapper\"\n[title]=\"'Select ' + (listRecord ? listRecord.Entity : 'Records') + ' to Add to List'\"\n*ngIf=\"showAddSingleRecordsDialog\"\n(close)=\"toggleAddRecordsDialog(false)\"\n[minWidth]=\"250\"\n[width]=\"650\"\n[height]=\"550\"\n>\n@if(showDialogLoader){\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <kendo-progressbar \n [min]=\"0\"\n [max]=\"recordsToSave\"\n [value]=\"recordsSaved\"\n [indeterminate]=\"fetchingRecordsToSave\"\n />\n}\n@else {\n <div class=\"search-header\">\n <kendo-textbox\n id=\"listRecordSearch\"\n (valueChange)=\"onListRecordDialogValueChange($event)\"\n [placeholder]=\"'Search ' + (listRecord ? listRecord.Entity : 'Records') + '...'\"\n kendoTextBox\n [clearButton]=\"true\"\n class=\"search-bar\"\n />\n </div>\n <hr>\n @if(fetchingListRecords){\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @else {\n @for(listRecord of listRecords; track listRecord){\n <div class=\"overflow-y-scroll\">\n <div class=\"list-item\">\n <div class=\"list-text\">\n {{listRecord.Name}}\n </div>\n <button kendoButton class=\"btn-no-border\" (click)=\"addListRecord(listRecord)\">\n <div class=\"btn-margin-right\">\n <span class=\"fa-solid fa-plus\"></span>\n Add\n </div>\n </button>\n </div>\n <hr>\n </div>\n }\n }\n}\n <kendo-dialog-actions class=\"popup-actions-btn\">\n <button class=\"yes-btn\" (click)=\"toggleAddRecordsDialog(false)\" [disabled]=\"showDialogLoader\" kendoButton fillMode=\"outline\" themeColor=\"info\">\n Close\n </button>\n </kendo-dialog-actions>\n</kendo-dialog>", styles: [".app-container {\n padding: 20px;\n}\n\n.flex-display-row-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 10px;\n}\n\n.title-wrapper {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 0;\n border-bottom: 1px solid var(--med-gray);\n}\n\n.title-wrapper h4 {\n margin: 0;\n font-size: 24px;\n line-height: 28px;\n}\n\n.title-wrapper .search input {\n width: 100%;\n height: 100%;\n font-size: 16px;\n background: transparent;\n border: none;\n box-sizing: border-box;\n padding-left: 40px;\n}\n\n .title-wrapper .search {\n background: var(--light-shade);\n width: 360px;\n height: 44px;\n position: relative;\n border-radius: 10px;\n}\n\n.title-wrapper .search svg {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 12px;\n}\n\n.add-btn {\n padding: 10px 30px;\n border-radius: 10px;\n color: white;\n background-color: var(--border-blue);\n font-size: initial;\n cursor: pointer;\n}\n\n.add-btn:hover {\n filter: brightness(85%);\n}\n\n.margin-left-small {\n margin-left: 10px;\n}\n\n\n.overflow-y-scroll {\n overflow-y: auto;\n max-height: 300px;\n}\n\n.padding-bottom-small {\n padding-bottom: 10px;\n}\n\n.list-item {\n display: flex;\n justify-content: space-between;\n padding-bottom: 5px;\n align-items: center;\n}\n\n.btn-no-border {\n border: none;\n background: none;\n color: var(--border-blue);\n font-size: 16px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.btn-selected {\n font-weight: bold;\n}\n\n.list-text {\n font-size: large;\n}\n.list-selected {\n font-weight: bold;\n color: var(--border-blue);\n}\n\n.btn-margin-right {\n margin-right: 35px;\n}\n\n.divider {\n color: lightgray\n}\n\n.search-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 0;\n}\n\n.search-bar {\n width: 65%;\n padding-bottom: 10px;\n}\n\n.dialog-wrapper {\n padding: 15px 25px;\n}\n\n.btn-outline {\n border: 2px solid var(--border-blue);\n border-radius: 8px;\n padding: 5px 30px;\n\n background: none;\n color: var(--border-blue);\n font-size: 16px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.k-dropdown-button .k-button {\n background: var(--border-blue);\n color: var(--white-color);\n font-size: 16px;\n border: none;\n padding: 8px 25px;\n border-radius: 10px;\n}\n\n.k-dropdown-button .k-button .k-button-text .card-header-entity .add-item .k-button .k-button-text {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.btn-cmn {\n width: 44px;\n height: 44px;\n min-width: 44px;\n background: transparent;\n border-radius: 8px;\n border: 1px solid var(--gray-color);\n}\n\n.btn-cmn.active {\n border: 1px solid var(--border-blue);\n}"] }]
614
- }], () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.SharedService }], { ListID: [{
879
+ args: [{ 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<kendo-dialog\n *ngIf=\"showRemoveDialog\"\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<!-- Add Records Dialog -->\n<kendo-dialog\n *ngIf=\"showAddRecordsDialog\"\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\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\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<!-- Add From View Dialog -->\n<kendo-dialog\n *ngIf=\"showAddFromViewDialog\"\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\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", 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"] }]
880
+ }], () => [{ type: i1.SharedService }, { type: i0.ChangeDetectorRef }], { ListID: [{
615
881
  type: Input
882
+ }], listDetailGrid: [{
883
+ type: ViewChild,
884
+ args: ['listDetailGrid']
616
885
  }] }); })();
617
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SingleListDetailComponent, { className: "SingleListDetailComponent", filePath: "src/lib/single-list-detail/single-list-detail.component.ts", lineNumber: 15 }); })();
886
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SingleListDetailComponent, { className: "SingleListDetailComponent" }); })();
618
887
  //# sourceMappingURL=single-list-detail.component.js.map