@memberjunction/ng-explorer-core 0.9.79 → 0.9.96

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 (105) hide show
  1. package/dist/lib/ask-skip/ask-skip.component.d.ts +87 -86
  2. package/dist/lib/ask-skip/ask-skip.component.js +615 -580
  3. package/dist/lib/ask-skip/skip-dynamic-report-wrapper.d.ts +12 -12
  4. package/dist/lib/ask-skip/skip-dynamic-report-wrapper.js +40 -39
  5. package/dist/lib/auth-button/auth-button.component.d.ts +12 -12
  6. package/dist/lib/auth-button/auth-button.component.js +44 -43
  7. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts +18 -18
  8. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +117 -117
  9. package/dist/lib/data-browser-component/data-browser.component.d.ts +16 -14
  10. package/dist/lib/data-browser-component/data-browser.component.js +96 -91
  11. package/dist/lib/favorites/favorites.component.d.ts +14 -14
  12. package/dist/lib/favorites/favorites.component.js +114 -114
  13. package/dist/lib/generic/base-form-component.d.ts +76 -76
  14. package/dist/lib/generic/base-form-component.js +436 -436
  15. package/dist/lib/generic/base-form-section-component.d.ts +6 -6
  16. package/dist/lib/generic/base-form-section-component.js +9 -9
  17. package/dist/lib/generic/base-record-component.d.ts +6 -6
  18. package/dist/lib/generic/base-record-component.js +15 -15
  19. package/dist/lib/generic/base-resource-component.d.ts +34 -34
  20. package/dist/lib/generic/base-resource-component.js +75 -75
  21. package/dist/lib/generic/dynamic-chart.d.ts +33 -33
  22. package/dist/lib/generic/dynamic-chart.js +236 -235
  23. package/dist/lib/generic/dynamic-grid.d.ts +25 -25
  24. package/dist/lib/generic/dynamic-grid.js +120 -119
  25. package/dist/lib/generic/dynamic-report.d.ts +38 -38
  26. package/dist/lib/generic/dynamic-report.js +353 -347
  27. package/dist/lib/generic/form-toolbar.d.ts +7 -7
  28. package/dist/lib/generic/form-toolbar.js +85 -89
  29. package/dist/lib/generic/resource-container-component.d.ts +25 -25
  30. package/dist/lib/generic/resource-container-component.js +104 -103
  31. package/dist/lib/generic/section-loader-component.d.ts +17 -17
  32. package/dist/lib/generic/section-loader-component.js +66 -65
  33. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts +26 -24
  34. package/dist/lib/generic-browse-list/generic-browse-list.component.js +145 -143
  35. package/dist/lib/guards/auth-guard.service.d.ts +11 -11
  36. package/dist/lib/guards/auth-guard.service.js +24 -24
  37. package/dist/lib/guards/entities.guard.d.ts +3 -3
  38. package/dist/lib/guards/entities.guard.js +38 -38
  39. package/dist/lib/header/MSFT_UserImageService.d.ts +11 -11
  40. package/dist/lib/header/MSFT_UserImageService.js +23 -23
  41. package/dist/lib/header/header.component.d.ts +51 -51
  42. package/dist/lib/header/header.component.js +220 -208
  43. package/dist/lib/home-component/home.component.d.ts +11 -9
  44. package/dist/lib/home-component/home.component.js +77 -54
  45. package/dist/lib/join-grid/join-grid.component.d.ts +30 -30
  46. package/dist/lib/join-grid/join-grid.component.js +222 -225
  47. package/dist/lib/navigation/navigation.component.d.ts +104 -103
  48. package/dist/lib/navigation/navigation.component.js +1026 -1004
  49. package/dist/lib/query-browser-component/query-browser.component.d.ts +14 -0
  50. package/dist/lib/query-browser-component/query-browser.component.js +55 -0
  51. package/dist/lib/report-browser-component/report-browser.component.d.ts +14 -14
  52. package/dist/lib/report-browser-component/report-browser.component.js +55 -55
  53. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +8 -8
  54. package/dist/lib/resource-wrappers/dashboard-resource.component.js +51 -50
  55. package/dist/lib/resource-wrappers/query-resource.component.d.ts +10 -0
  56. package/dist/lib/resource-wrappers/query-resource.component.js +55 -0
  57. package/dist/lib/resource-wrappers/record-resource.component.d.ts +10 -10
  58. package/dist/lib/resource-wrappers/record-resource.component.js +71 -70
  59. package/dist/lib/resource-wrappers/report-resource.component.d.ts +10 -10
  60. package/dist/lib/resource-wrappers/report-resource.component.js +55 -54
  61. package/dist/lib/resource-wrappers/resource-wrappers-loader.d.ts +1 -1
  62. package/dist/lib/resource-wrappers/resource-wrappers-loader.js +14 -12
  63. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +10 -10
  64. package/dist/lib/resource-wrappers/search-results-resource.component.js +52 -51
  65. package/dist/lib/resource-wrappers/view-resource.component.d.ts +8 -8
  66. package/dist/lib/resource-wrappers/view-resource.component.js +61 -60
  67. package/dist/lib/settings/settings.component.d.ts +5 -5
  68. package/dist/lib/settings/settings.component.js +15 -14
  69. package/dist/lib/single-application/single-application.component.d.ts +20 -20
  70. package/dist/lib/single-application/single-application.component.js +113 -113
  71. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +28 -28
  72. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +210 -212
  73. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts +13 -13
  74. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +60 -59
  75. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +26 -26
  76. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +170 -169
  77. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +75 -75
  78. package/dist/lib/single-dashboard/single-dashboard.component.js +464 -456
  79. package/dist/lib/single-entity/single-entity.component.d.ts +33 -33
  80. package/dist/lib/single-entity/single-entity.component.js +258 -252
  81. package/dist/lib/single-query/single-query.component.d.ts +16 -0
  82. package/dist/lib/single-query/single-query.component.js +70 -0
  83. package/dist/lib/single-record/single-record.component.d.ts +21 -21
  84. package/dist/lib/single-record/single-record.component.js +95 -95
  85. package/dist/lib/single-report/single-report.component.d.ts +22 -22
  86. package/dist/lib/single-report/single-report.component.js +88 -87
  87. package/dist/lib/single-search-result/single-search-result.component.d.ts +15 -15
  88. package/dist/lib/single-search-result/single-search-result.component.js +61 -60
  89. package/dist/lib/single-view/single-view.component.d.ts +38 -38
  90. package/dist/lib/single-view/single-view.component.js +201 -201
  91. package/dist/lib/user-notifications/user-notifications.component.d.ts +32 -32
  92. package/dist/lib/user-notifications/user-notifications.component.js +282 -282
  93. package/dist/lib/user-profile/user-profile.component.d.ts +10 -10
  94. package/dist/lib/user-profile/user-profile.component.js +42 -41
  95. package/dist/lib/user-view-properties/view-properties-dialog.component.d.ts +71 -71
  96. package/dist/lib/user-view-properties/view-properties-dialog.component.js +591 -581
  97. package/dist/module.d.ts +69 -65
  98. package/dist/module.js +356 -338
  99. package/dist/public-api.d.ts +46 -47
  100. package/dist/public-api.js +49 -50
  101. package/dist/shared/shared.service.d.ts +94 -92
  102. package/dist/shared/shared.service.js +324 -318
  103. package/dist/shared/urlPipe.d.ts +7 -7
  104. package/dist/shared/urlPipe.js +16 -16
  105. package/package.json +23 -15
@@ -1,436 +1,436 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Directive, ViewChildren, ViewChild } from '@angular/core';
11
- import { Subject, debounceTime, fromEvent } from 'rxjs';
12
- import { EntityInfo, EntityPermissionType, Metadata, LogError } from '@memberjunction/core';
13
- import { UserViewGridComponent } from '@memberjunction/ng-user-view-grid';
14
- import { BaseRecordComponent } from './base-record-component';
15
- import { TabStripComponent } from '@progress/kendo-angular-layout';
16
- import * as i0 from "@angular/core";
17
- import * as i1 from "../../shared/shared.service";
18
- import * as i2 from "@angular/router";
19
- export class BaseFormComponent extends BaseRecordComponent {
20
- constructor(elementRef, sharedService, router, route) {
21
- super();
22
- this.elementRef = elementRef;
23
- this.sharedService = sharedService;
24
- this.router = router;
25
- this.route = route;
26
- this.activeTabIndex = 0;
27
- this.selectedTab = 0;
28
- this.EditMode = false;
29
- this.BottomMargin = 53;
30
- this.TabHeight = '500px';
31
- this.GridBottomMargin = 100;
32
- this.FavoriteInitDone = false;
33
- this.isHistoryDialogOpen = false;
34
- this.splitterLayoutChangeSubject = new Subject();
35
- this._pendingRecords = [];
36
- this._updatingBrowserUrl = false;
37
- this.resizeSub = null;
38
- this._isFavorite = false;
39
- this._tabIndexes = [];
40
- this._tabMargin = 10;
41
- this.setupSplitterLayoutDebounce();
42
- }
43
- ngOnInit() {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- if (this.record) {
46
- const md = new Metadata();
47
- this._isFavorite = yield md.GetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKeys.map(pk => { return { FieldName: pk.Name, Value: pk.Value }; }));
48
- this.FavoriteInitDone = true;
49
- }
50
- });
51
- }
52
- ngAfterViewInit() {
53
- this.setTabHeight();
54
- this.route.queryParams.subscribe(params => {
55
- if (!this._updatingBrowserUrl) {
56
- // only do this if WE didn't invoke the browser URL update
57
- const tabName = params['tab'];
58
- if (tabName && tabName.length > 0) {
59
- // Select the proper tab based on the tabName
60
- const tabIndex = this.GetTabIndex(tabName);
61
- if (tabIndex >= 0) {
62
- // found the tab index, if we don't find it, do nothing
63
- this.activeTabIndex = tabIndex;
64
- this.tabComponent.selectTab(tabIndex);
65
- // now resize after a pause to allow the UI to settle
66
- setTimeout(() => {
67
- this.sharedService.InvokeManualResize();
68
- }, 100);
69
- }
70
- }
71
- }
72
- });
73
- }
74
- ngOnDestroy() {
75
- if (this.resizeSub) {
76
- this.resizeSub.unsubscribe();
77
- }
78
- }
79
- get PendingRecords() {
80
- return this._pendingRecords;
81
- }
82
- onTabSelect(e) {
83
- this.activeTabIndex = e.index;
84
- this.sharedService.InvokeManualResize();
85
- // now that we've updated our state and re-sized, also update the browser URL to add the tab name as a query parameter to the URL
86
- const tabName = this._tabIndexes[this.activeTabIndex];
87
- this._updatingBrowserUrl = true;
88
- this.router.navigate([], { queryParams: { tab: tabName }, queryParamsHandling: 'merge' });
89
- this._updatingBrowserUrl = true;
90
- }
91
- StartEditMode() {
92
- this.EditMode = true;
93
- }
94
- handleHistoryDialog() {
95
- this.isHistoryDialogOpen = !this.isHistoryDialogOpen;
96
- }
97
- RemoveFavorite() {
98
- return __awaiter(this, void 0, void 0, function* () {
99
- return this.SetFavoriteStatus(false);
100
- });
101
- }
102
- MakeFavorite() {
103
- return __awaiter(this, void 0, void 0, function* () {
104
- return this.SetFavoriteStatus(true);
105
- });
106
- }
107
- SetFavoriteStatus(isFavorite) {
108
- return __awaiter(this, void 0, void 0, function* () {
109
- const md = new Metadata();
110
- yield md.SetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKeys.map(pk => { return { FieldName: pk.Name, Value: pk.Value }; }), isFavorite);
111
- this._isFavorite = isFavorite;
112
- });
113
- }
114
- get IsFavorite() {
115
- return this._isFavorite;
116
- }
117
- CheckUserPermission(type) {
118
- try {
119
- if (this.record)
120
- return this.record.CheckPermissions(type, false);
121
- else
122
- return false;
123
- }
124
- catch (e) {
125
- LogError(e);
126
- return false;
127
- }
128
- }
129
- get UserCanEdit() {
130
- return this.CheckUserPermission(EntityPermissionType.Update);
131
- }
132
- get UserCanRead() {
133
- return this.CheckUserPermission(EntityPermissionType.Read);
134
- }
135
- get UserCanCreate() {
136
- return this.CheckUserPermission(EntityPermissionType.Create);
137
- }
138
- get UserCanDelete() {
139
- return this.CheckUserPermission(EntityPermissionType.Delete);
140
- }
141
- GridEditMode() {
142
- return this.EditMode ? "Queue" : "None";
143
- }
144
- GetTabIndex(tabName) {
145
- return this._tabIndexes.indexOf(tabName);
146
- }
147
- RegisterTabs(tabs) {
148
- // copy the array, clear existing array and copy all elements
149
- this._tabIndexes.splice(0, this._tabIndexes.length);
150
- for (let i = 0; i < tabs.length; i++)
151
- this.RegisterTab(tabs[i]);
152
- }
153
- RegisterTab(tabName) {
154
- const currentIndex = this._tabIndexes.indexOf(tabName);
155
- if (currentIndex === -1) {
156
- this._tabIndexes.push(tabName);
157
- return this._tabIndexes.length - 1;
158
- }
159
- else
160
- return currentIndex;
161
- }
162
- IsCurrentTab(tabName) {
163
- if (this._tabIndexes.length === 0 || this._tabIndexes.indexOf(tabName) === -1)
164
- return false;
165
- else
166
- return this.activeTabIndex === this.GetTabIndex(tabName);
167
- }
168
- RegisterAndCheckIfCurrentTab(tabName) {
169
- this.RegisterTab(tabName);
170
- return this.IsCurrentTab(tabName);
171
- }
172
- BuildRelationshipViewParams(item) {
173
- return EntityInfo.BuildRelationshipViewParams(this.record, item); // new helper method in EntityInfo
174
- }
175
- BuildRelationshipViewParamsByEntityName(relatedEntityName) {
176
- if (this.record) {
177
- const eri = this.record.EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);
178
- if (eri)
179
- return this.BuildRelationshipViewParams(eri);
180
- }
181
- return {};
182
- }
183
- GetRelatedEntityTabDisplayName(relatedEntityName) {
184
- if (this.record) {
185
- const eri = this.record.EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);
186
- if (eri)
187
- return eri.DisplayName;
188
- }
189
- return relatedEntityName;
190
- }
191
- ValidatePendingRecords() {
192
- const results = [];
193
- for (let i = 0; i < this._pendingRecords.length; i++) {
194
- const pendingRecord = this._pendingRecords[i];
195
- results.push(pendingRecord.Validate());
196
- }
197
- return results;
198
- }
199
- Validate() {
200
- const valResults = this.record.Validate();
201
- const pendingValResults = this.ValidatePendingRecords();
202
- for (let i = 0; i < pendingValResults.length; i++) {
203
- const pendingValResult = pendingValResults[i];
204
- if (!pendingValResult.Success) {
205
- valResults.Success = false;
206
- valResults.Errors.push(...pendingValResult.Errors);
207
- }
208
- }
209
- return valResults;
210
- }
211
- SaveRecord(StopEditModeAfterSave) {
212
- return __awaiter(this, void 0, void 0, function* () {
213
- try {
214
- if (this.record) {
215
- yield this.PopulatePendingRecords(); // do this before we validate as we must validate pending records too
216
- const valResults = this.Validate();
217
- if (valResults.Success) {
218
- const result = yield this.InternalSaveRecord();
219
- if (result) {
220
- // we have saved the record, so clear the pending records
221
- this._pendingRecords = [];
222
- if (StopEditModeAfterSave)
223
- this.EditMode = false;
224
- this.sharedService.CreateSimpleNotification('Record saved succesfully', 'success', 2500);
225
- return true;
226
- }
227
- else
228
- this.sharedService.CreateSimpleNotification('Error saving record', 'error', 5000);
229
- }
230
- else {
231
- this.sharedService.CreateSimpleNotification('Validation Errors\n' + valResults.Errors.map(x => x.Message).join('\n'), 'warning', 10000);
232
- }
233
- }
234
- return false; // if we get here, we have failed/validation error/etc
235
- }
236
- catch (e) {
237
- this.sharedService.CreateSimpleNotification('Error saving record: ' + e, 'error', 5000);
238
- return false;
239
- }
240
- });
241
- }
242
- Wait(duration) {
243
- return __awaiter(this, void 0, void 0, function* () {
244
- return new Promise(resolve => setTimeout(resolve, duration));
245
- });
246
- }
247
- CancelEdit() {
248
- if (this.record) {
249
- const r = this.record;
250
- if (r.Dirty || this.PendingRecordsDirty()) {
251
- // ask the user to make sure they want to throw out changes
252
- if (!confirm('Are you sure you want to cancel your changes?')) {
253
- return;
254
- }
255
- r.Revert();
256
- const pendingRecords = this.PendingRecords;
257
- if (pendingRecords && pendingRecords.length > 0) {
258
- // we have pending records, so we need to revert them as well
259
- pendingRecords.forEach(p => {
260
- p.Revert();
261
- });
262
- }
263
- if (this.userViewGridComponents && this.userViewGridComponents.length > 0) {
264
- // we have grids, so we need to revert them as well
265
- this.userViewGridComponents.forEach(grid => {
266
- grid.RevertPendingChanges();
267
- });
268
- }
269
- }
270
- // if we get here we are good to go
271
- this.EditMode = false;
272
- }
273
- }
274
- PendingRecordsDirty() {
275
- this.PopulatePendingRecords();
276
- const pendingRecords = this.PendingRecords;
277
- if (pendingRecords && pendingRecords.length > 0) {
278
- for (let i = 0; i < pendingRecords.length; i++) {
279
- if (pendingRecords[i].Dirty)
280
- return true;
281
- }
282
- }
283
- return false;
284
- }
285
- PopulatePendingRecords() {
286
- return __awaiter(this, void 0, void 0, function* () {
287
- // this method is called by the parent class at the right time to populate all of the pending records for a transaction
288
- // all we do is talk to all of our grids and get their pending records and xfer them over to the PendingRecords array
289
- // the parent class will then take care of the rest...
290
- this._pendingRecords = []; // wipe out our array first
291
- const grids = this.userViewGridComponents;
292
- if (grids && grids.length > 0) {
293
- for (let i = 0; i < grids.length; i++) {
294
- const grid = grids.get(i);
295
- if (grid) {
296
- yield grid.EditingComplete(); // need to check this and wait for it to make sure grid editing is done before we try to save
297
- grid.PendingRecords.forEach(p => {
298
- // populate our pending grids array from the composite of all the grids
299
- this.PendingRecords.push(p.record);
300
- });
301
- }
302
- }
303
- }
304
- });
305
- }
306
- InternalSaveRecord() {
307
- return __awaiter(this, void 0, void 0, function* () {
308
- if (this.record) {
309
- // save the record, but first create a transaction group if we have any other stuf to submit
310
- yield this.PopulatePendingRecords();
311
- if (this._pendingRecords.length > 0) {
312
- // we need to create a transaction group
313
- const md = new Metadata();
314
- const tg = yield md.CreateTransactionGroup();
315
- this.record.TransactionGroup = tg;
316
- this.record.Save(); // DO NOT USE await - trans group.submit() is where we await
317
- // now add to the rest of the pending records
318
- for (let i = 0; i < this._pendingRecords.length; i++) {
319
- const x = this._pendingRecords[i];
320
- x.TransactionGroup = tg;
321
- x.Save(); // DO NOT USE await - trans group.submit() is where we await
322
- }
323
- // finally submit the TG
324
- return yield tg.Submit();
325
- }
326
- else
327
- return yield this.record.Save();
328
- }
329
- else
330
- return false;
331
- });
332
- }
333
- GetTabTopPosition() {
334
- if (this.elementRef && this.elementRef.nativeElement) {
335
- const tabs = this.elementRef.nativeElement.getElementsByClassName('k-tabstrip');
336
- if (tabs && tabs.length > 0) {
337
- const tabElement = tabs[0];
338
- const tabRect = tabElement.getBoundingClientRect();
339
- const bodyRect = document.body.getBoundingClientRect();
340
- return tabRect.top - bodyRect.top;
341
- }
342
- }
343
- return 0;
344
- }
345
- setTabHeight() {
346
- // Subscribe to the window resize event
347
- this.resizeSub = fromEvent(window, 'resize').pipe(debounceTime(100) // Debounce the resize event to avoid frequent updates
348
- ).subscribe(() => {
349
- // Update the grid height when the window is resized
350
- this.ResizeTab();
351
- });
352
- // Set the initial grid height with a slight delay to allow stuff to get set
353
- setTimeout(() => {
354
- this.ResizeTab();
355
- }, 100);
356
- }
357
- get ContainerObjectHeight() {
358
- return window.innerHeight; // default, can be overriden by subclasses
359
- }
360
- ResizeTab() {
361
- this._tabMargin = this.GetTabTopPosition();
362
- const height = this.ContainerObjectHeight - this._tabMargin - this.BottomMargin;
363
- this.TabHeight = height.toString() + 'px';
364
- this.GridBottomMargin = 40;
365
- }
366
- setupSplitterLayoutDebounce() {
367
- this.splitterLayoutChangeSubject.pipe(debounceTime(300)).subscribe(() => {
368
- this.setTabHeight(); // set the height of the tab first
369
- // then wait through the timeout so the tab height change actually takes effect in the DOM - that's why we have the timeout
370
- setTimeout(() => {
371
- this.sharedService.InvokeManualResize();
372
- }, 100);
373
- });
374
- }
375
- splitterLayoutChange() {
376
- this.splitterLayoutChangeSubject.next();
377
- }
378
- ResizeGrids() {
379
- // do with a little timeout to let the visible grid show up and the DOM settle
380
- setTimeout(() => {
381
- if (this.userViewGridComponents && this.userViewGridComponents.length > 0) {
382
- this.userViewGridComponents.forEach(grid => {
383
- //grid.ResizeGrid(); // automatic now via mjFillContainer
384
- });
385
- }
386
- }, 10);
387
- }
388
- ShowDependencies() {
389
- return __awaiter(this, void 0, void 0, function* () {
390
- // for now dump to console
391
- const md = new Metadata();
392
- const dep = yield md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey.Value);
393
- console.log('Dependencies for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.Value);
394
- console.log(dep);
395
- // if (confirm('Do you want to merge records test?') == true) {
396
- // const mergeResult = await md.MergeRecords({
397
- // EntityName: this.record.EntityInfo.Name,
398
- // SurvivingRecordID: this.record.PrimaryKey.Value,
399
- // RecordsToMerge: [4],
400
- // })
401
- // console.log(mergeResult);
402
- // }
403
- });
404
- }
405
- get EntityInfo() {
406
- try {
407
- const r = this.record;
408
- if (r)
409
- return r.EntityInfo;
410
- else
411
- return undefined;
412
- }
413
- catch (e) {
414
- LogError(e);
415
- return undefined;
416
- }
417
- }
418
- }
419
- BaseFormComponent.ɵfac = function BaseFormComponent_Factory(t) { return new (t || BaseFormComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i2.ActivatedRoute)); };
420
- BaseFormComponent.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: BaseFormComponent, viewQuery: function BaseFormComponent_Query(rf, ctx) { if (rf & 1) {
421
- i0.ɵɵviewQuery(TabStripComponent, 5);
422
- i0.ɵɵviewQuery(UserViewGridComponent, 5);
423
- } if (rf & 2) {
424
- let _t;
425
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabComponent = _t.first);
426
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.userViewGridComponents = _t);
427
- } }, features: [i0.ɵɵInheritDefinitionFeature] });
428
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(BaseFormComponent, [{
429
- type: Directive
430
- }], function () { return [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }]; }, { tabComponent: [{
431
- type: ViewChild,
432
- args: [TabStripComponent, { static: false }]
433
- }], userViewGridComponents: [{
434
- type: ViewChildren,
435
- args: [UserViewGridComponent]
436
- }] }); })();
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Directive, ViewChildren, ViewChild } from '@angular/core';
11
+ import { Subject, debounceTime, fromEvent } from 'rxjs';
12
+ import { EntityInfo, EntityPermissionType, Metadata, LogError } from '@memberjunction/core';
13
+ import { UserViewGridComponent } from '@memberjunction/ng-user-view-grid';
14
+ import { BaseRecordComponent } from './base-record-component';
15
+ import { TabStripComponent } from '@progress/kendo-angular-layout';
16
+ import * as i0 from "@angular/core";
17
+ import * as i1 from "../../shared/shared.service";
18
+ import * as i2 from "@angular/router";
19
+ export class BaseFormComponent extends BaseRecordComponent {
20
+ constructor(elementRef, sharedService, router, route) {
21
+ super();
22
+ this.elementRef = elementRef;
23
+ this.sharedService = sharedService;
24
+ this.router = router;
25
+ this.route = route;
26
+ this.activeTabIndex = 0;
27
+ this.selectedTab = 0;
28
+ this.EditMode = false;
29
+ this.BottomMargin = 53;
30
+ this.TabHeight = '500px';
31
+ this.GridBottomMargin = 100;
32
+ this.FavoriteInitDone = false;
33
+ this.isHistoryDialogOpen = false;
34
+ this.splitterLayoutChangeSubject = new Subject();
35
+ this._pendingRecords = [];
36
+ this._updatingBrowserUrl = false;
37
+ this.resizeSub = null;
38
+ this._isFavorite = false;
39
+ this._tabIndexes = [];
40
+ this._tabMargin = 10;
41
+ this.setupSplitterLayoutDebounce();
42
+ }
43
+ ngOnInit() {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ if (this.record) {
46
+ const md = new Metadata();
47
+ this._isFavorite = yield md.GetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKeys.map(pk => { return { FieldName: pk.Name, Value: pk.Value }; }));
48
+ this.FavoriteInitDone = true;
49
+ }
50
+ });
51
+ }
52
+ ngAfterViewInit() {
53
+ this.setTabHeight();
54
+ this.route.queryParams.subscribe(params => {
55
+ if (!this._updatingBrowserUrl) {
56
+ // only do this if WE didn't invoke the browser URL update
57
+ const tabName = params['tab'];
58
+ if (tabName && tabName.length > 0) {
59
+ // Select the proper tab based on the tabName
60
+ const tabIndex = this.GetTabIndex(tabName);
61
+ if (tabIndex >= 0) {
62
+ // found the tab index, if we don't find it, do nothing
63
+ this.activeTabIndex = tabIndex;
64
+ this.tabComponent.selectTab(tabIndex);
65
+ // now resize after a pause to allow the UI to settle
66
+ setTimeout(() => {
67
+ this.sharedService.InvokeManualResize();
68
+ }, 100);
69
+ }
70
+ }
71
+ }
72
+ });
73
+ }
74
+ ngOnDestroy() {
75
+ if (this.resizeSub) {
76
+ this.resizeSub.unsubscribe();
77
+ }
78
+ }
79
+ get PendingRecords() {
80
+ return this._pendingRecords;
81
+ }
82
+ onTabSelect(e) {
83
+ this.activeTabIndex = e.index;
84
+ this.sharedService.InvokeManualResize();
85
+ // now that we've updated our state and re-sized, also update the browser URL to add the tab name as a query parameter to the URL
86
+ const tabName = this._tabIndexes[this.activeTabIndex];
87
+ this._updatingBrowserUrl = true;
88
+ this.router.navigate([], { queryParams: { tab: tabName }, queryParamsHandling: 'merge' });
89
+ this._updatingBrowserUrl = true;
90
+ }
91
+ StartEditMode() {
92
+ this.EditMode = true;
93
+ }
94
+ handleHistoryDialog() {
95
+ this.isHistoryDialogOpen = !this.isHistoryDialogOpen;
96
+ }
97
+ RemoveFavorite() {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ return this.SetFavoriteStatus(false);
100
+ });
101
+ }
102
+ MakeFavorite() {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ return this.SetFavoriteStatus(true);
105
+ });
106
+ }
107
+ SetFavoriteStatus(isFavorite) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ const md = new Metadata();
110
+ yield md.SetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKeys.map(pk => { return { FieldName: pk.Name, Value: pk.Value }; }), isFavorite);
111
+ this._isFavorite = isFavorite;
112
+ });
113
+ }
114
+ get IsFavorite() {
115
+ return this._isFavorite;
116
+ }
117
+ CheckUserPermission(type) {
118
+ try {
119
+ if (this.record)
120
+ return this.record.CheckPermissions(type, false);
121
+ else
122
+ return false;
123
+ }
124
+ catch (e) {
125
+ LogError(e);
126
+ return false;
127
+ }
128
+ }
129
+ get UserCanEdit() {
130
+ return this.CheckUserPermission(EntityPermissionType.Update);
131
+ }
132
+ get UserCanRead() {
133
+ return this.CheckUserPermission(EntityPermissionType.Read);
134
+ }
135
+ get UserCanCreate() {
136
+ return this.CheckUserPermission(EntityPermissionType.Create);
137
+ }
138
+ get UserCanDelete() {
139
+ return this.CheckUserPermission(EntityPermissionType.Delete);
140
+ }
141
+ GridEditMode() {
142
+ return this.EditMode ? "Queue" : "None";
143
+ }
144
+ GetTabIndex(tabName) {
145
+ return this._tabIndexes.indexOf(tabName);
146
+ }
147
+ RegisterTabs(tabs) {
148
+ // copy the array, clear existing array and copy all elements
149
+ this._tabIndexes.splice(0, this._tabIndexes.length);
150
+ for (let i = 0; i < tabs.length; i++)
151
+ this.RegisterTab(tabs[i]);
152
+ }
153
+ RegisterTab(tabName) {
154
+ const currentIndex = this._tabIndexes.indexOf(tabName);
155
+ if (currentIndex === -1) {
156
+ this._tabIndexes.push(tabName);
157
+ return this._tabIndexes.length - 1;
158
+ }
159
+ else
160
+ return currentIndex;
161
+ }
162
+ IsCurrentTab(tabName) {
163
+ if (this._tabIndexes.length === 0 || this._tabIndexes.indexOf(tabName) === -1)
164
+ return false;
165
+ else
166
+ return this.activeTabIndex === this.GetTabIndex(tabName);
167
+ }
168
+ RegisterAndCheckIfCurrentTab(tabName) {
169
+ this.RegisterTab(tabName);
170
+ return this.IsCurrentTab(tabName);
171
+ }
172
+ BuildRelationshipViewParams(item) {
173
+ return EntityInfo.BuildRelationshipViewParams(this.record, item); // new helper method in EntityInfo
174
+ }
175
+ BuildRelationshipViewParamsByEntityName(relatedEntityName) {
176
+ if (this.record) {
177
+ const eri = this.record.EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);
178
+ if (eri)
179
+ return this.BuildRelationshipViewParams(eri);
180
+ }
181
+ return {};
182
+ }
183
+ GetRelatedEntityTabDisplayName(relatedEntityName) {
184
+ if (this.record) {
185
+ const eri = this.record.EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);
186
+ if (eri)
187
+ return eri.DisplayName;
188
+ }
189
+ return relatedEntityName;
190
+ }
191
+ ValidatePendingRecords() {
192
+ const results = [];
193
+ for (let i = 0; i < this._pendingRecords.length; i++) {
194
+ const pendingRecord = this._pendingRecords[i];
195
+ results.push(pendingRecord.Validate());
196
+ }
197
+ return results;
198
+ }
199
+ Validate() {
200
+ const valResults = this.record.Validate();
201
+ const pendingValResults = this.ValidatePendingRecords();
202
+ for (let i = 0; i < pendingValResults.length; i++) {
203
+ const pendingValResult = pendingValResults[i];
204
+ if (!pendingValResult.Success) {
205
+ valResults.Success = false;
206
+ valResults.Errors.push(...pendingValResult.Errors);
207
+ }
208
+ }
209
+ return valResults;
210
+ }
211
+ SaveRecord(StopEditModeAfterSave) {
212
+ return __awaiter(this, void 0, void 0, function* () {
213
+ try {
214
+ if (this.record) {
215
+ yield this.PopulatePendingRecords(); // do this before we validate as we must validate pending records too
216
+ const valResults = this.Validate();
217
+ if (valResults.Success) {
218
+ const result = yield this.InternalSaveRecord();
219
+ if (result) {
220
+ // we have saved the record, so clear the pending records
221
+ this._pendingRecords = [];
222
+ if (StopEditModeAfterSave)
223
+ this.EditMode = false;
224
+ this.sharedService.CreateSimpleNotification('Record saved succesfully', 'success', 2500);
225
+ return true;
226
+ }
227
+ else
228
+ this.sharedService.CreateSimpleNotification('Error saving record', 'error', 5000);
229
+ }
230
+ else {
231
+ this.sharedService.CreateSimpleNotification('Validation Errors\n' + valResults.Errors.map(x => x.Message).join('\n'), 'warning', 10000);
232
+ }
233
+ }
234
+ return false; // if we get here, we have failed/validation error/etc
235
+ }
236
+ catch (e) {
237
+ this.sharedService.CreateSimpleNotification('Error saving record: ' + e, 'error', 5000);
238
+ return false;
239
+ }
240
+ });
241
+ }
242
+ Wait(duration) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ return new Promise(resolve => setTimeout(resolve, duration));
245
+ });
246
+ }
247
+ CancelEdit() {
248
+ if (this.record) {
249
+ const r = this.record;
250
+ if (r.Dirty || this.PendingRecordsDirty()) {
251
+ // ask the user to make sure they want to throw out changes
252
+ if (!confirm('Are you sure you want to cancel your changes?')) {
253
+ return;
254
+ }
255
+ r.Revert();
256
+ const pendingRecords = this.PendingRecords;
257
+ if (pendingRecords && pendingRecords.length > 0) {
258
+ // we have pending records, so we need to revert them as well
259
+ pendingRecords.forEach(p => {
260
+ p.Revert();
261
+ });
262
+ }
263
+ if (this.userViewGridComponents && this.userViewGridComponents.length > 0) {
264
+ // we have grids, so we need to revert them as well
265
+ this.userViewGridComponents.forEach(grid => {
266
+ grid.RevertPendingChanges();
267
+ });
268
+ }
269
+ }
270
+ // if we get here we are good to go
271
+ this.EditMode = false;
272
+ }
273
+ }
274
+ PendingRecordsDirty() {
275
+ this.PopulatePendingRecords();
276
+ const pendingRecords = this.PendingRecords;
277
+ if (pendingRecords && pendingRecords.length > 0) {
278
+ for (let i = 0; i < pendingRecords.length; i++) {
279
+ if (pendingRecords[i].Dirty)
280
+ return true;
281
+ }
282
+ }
283
+ return false;
284
+ }
285
+ PopulatePendingRecords() {
286
+ return __awaiter(this, void 0, void 0, function* () {
287
+ // this method is called by the parent class at the right time to populate all of the pending records for a transaction
288
+ // all we do is talk to all of our grids and get their pending records and xfer them over to the PendingRecords array
289
+ // the parent class will then take care of the rest...
290
+ this._pendingRecords = []; // wipe out our array first
291
+ const grids = this.userViewGridComponents;
292
+ if (grids && grids.length > 0) {
293
+ for (let i = 0; i < grids.length; i++) {
294
+ const grid = grids.get(i);
295
+ if (grid) {
296
+ yield grid.EditingComplete(); // need to check this and wait for it to make sure grid editing is done before we try to save
297
+ grid.PendingRecords.forEach(p => {
298
+ // populate our pending grids array from the composite of all the grids
299
+ this.PendingRecords.push(p.record);
300
+ });
301
+ }
302
+ }
303
+ }
304
+ });
305
+ }
306
+ InternalSaveRecord() {
307
+ return __awaiter(this, void 0, void 0, function* () {
308
+ if (this.record) {
309
+ // save the record, but first create a transaction group if we have any other stuf to submit
310
+ yield this.PopulatePendingRecords();
311
+ if (this._pendingRecords.length > 0) {
312
+ // we need to create a transaction group
313
+ const md = new Metadata();
314
+ const tg = yield md.CreateTransactionGroup();
315
+ this.record.TransactionGroup = tg;
316
+ this.record.Save(); // DO NOT USE await - trans group.submit() is where we await
317
+ // now add to the rest of the pending records
318
+ for (let i = 0; i < this._pendingRecords.length; i++) {
319
+ const x = this._pendingRecords[i];
320
+ x.TransactionGroup = tg;
321
+ x.Save(); // DO NOT USE await - trans group.submit() is where we await
322
+ }
323
+ // finally submit the TG
324
+ return yield tg.Submit();
325
+ }
326
+ else
327
+ return yield this.record.Save();
328
+ }
329
+ else
330
+ return false;
331
+ });
332
+ }
333
+ GetTabTopPosition() {
334
+ if (this.elementRef && this.elementRef.nativeElement) {
335
+ const tabs = this.elementRef.nativeElement.getElementsByClassName('k-tabstrip');
336
+ if (tabs && tabs.length > 0) {
337
+ const tabElement = tabs[0];
338
+ const tabRect = tabElement.getBoundingClientRect();
339
+ const bodyRect = document.body.getBoundingClientRect();
340
+ return tabRect.top - bodyRect.top;
341
+ }
342
+ }
343
+ return 0;
344
+ }
345
+ setTabHeight() {
346
+ // Subscribe to the window resize event
347
+ this.resizeSub = fromEvent(window, 'resize').pipe(debounceTime(100) // Debounce the resize event to avoid frequent updates
348
+ ).subscribe(() => {
349
+ // Update the grid height when the window is resized
350
+ this.ResizeTab();
351
+ });
352
+ // Set the initial grid height with a slight delay to allow stuff to get set
353
+ setTimeout(() => {
354
+ this.ResizeTab();
355
+ }, 100);
356
+ }
357
+ get ContainerObjectHeight() {
358
+ return window.innerHeight; // default, can be overriden by subclasses
359
+ }
360
+ ResizeTab() {
361
+ this._tabMargin = this.GetTabTopPosition();
362
+ const height = this.ContainerObjectHeight - this._tabMargin - this.BottomMargin;
363
+ this.TabHeight = height.toString() + 'px';
364
+ this.GridBottomMargin = 40;
365
+ }
366
+ setupSplitterLayoutDebounce() {
367
+ this.splitterLayoutChangeSubject.pipe(debounceTime(300)).subscribe(() => {
368
+ this.setTabHeight(); // set the height of the tab first
369
+ // then wait through the timeout so the tab height change actually takes effect in the DOM - that's why we have the timeout
370
+ setTimeout(() => {
371
+ this.sharedService.InvokeManualResize();
372
+ }, 100);
373
+ });
374
+ }
375
+ splitterLayoutChange() {
376
+ this.splitterLayoutChangeSubject.next();
377
+ }
378
+ ResizeGrids() {
379
+ // do with a little timeout to let the visible grid show up and the DOM settle
380
+ setTimeout(() => {
381
+ if (this.userViewGridComponents && this.userViewGridComponents.length > 0) {
382
+ this.userViewGridComponents.forEach(grid => {
383
+ //grid.ResizeGrid(); // automatic now via mjFillContainer
384
+ });
385
+ }
386
+ }, 10);
387
+ }
388
+ ShowDependencies() {
389
+ return __awaiter(this, void 0, void 0, function* () {
390
+ // for now dump to console
391
+ const md = new Metadata();
392
+ const dep = yield md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey.Value);
393
+ console.log('Dependencies for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.Value);
394
+ console.log(dep);
395
+ // if (confirm('Do you want to merge records test?') == true) {
396
+ // const mergeResult = await md.MergeRecords({
397
+ // EntityName: this.record.EntityInfo.Name,
398
+ // SurvivingRecordID: this.record.PrimaryKey.Value,
399
+ // RecordsToMerge: [4],
400
+ // })
401
+ // console.log(mergeResult);
402
+ // }
403
+ });
404
+ }
405
+ get EntityInfo() {
406
+ try {
407
+ const r = this.record;
408
+ if (r)
409
+ return r.EntityInfo;
410
+ else
411
+ return undefined;
412
+ }
413
+ catch (e) {
414
+ LogError(e);
415
+ return undefined;
416
+ }
417
+ }
418
+ }
419
+ BaseFormComponent.ɵfac = function BaseFormComponent_Factory(t) { return new (t || BaseFormComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i2.ActivatedRoute)); };
420
+ BaseFormComponent.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: BaseFormComponent, viewQuery: function BaseFormComponent_Query(rf, ctx) { if (rf & 1) {
421
+ i0.ɵɵviewQuery(TabStripComponent, 5);
422
+ i0.ɵɵviewQuery(UserViewGridComponent, 5);
423
+ } if (rf & 2) {
424
+ let _t;
425
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabComponent = _t.first);
426
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.userViewGridComponents = _t);
427
+ } }, features: [i0.ɵɵInheritDefinitionFeature] });
428
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(BaseFormComponent, [{
429
+ type: Directive
430
+ }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }], { tabComponent: [{
431
+ type: ViewChild,
432
+ args: [TabStripComponent, { static: false }]
433
+ }], userViewGridComponents: [{
434
+ type: ViewChildren,
435
+ args: [UserViewGridComponent]
436
+ }] }); })();