@memberjunction/ng-list-detail-grid 2.48.0 → 2.50.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.
@@ -1,12 +1,3 @@
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
1
  import { Component, ViewChild, ElementRef, Output, EventEmitter, Input } from '@angular/core';
11
2
  import { Metadata, RunView, EntityFieldTSType, LogError, CompositeKey, PotentialDuplicateRequest } from '@memberjunction/core';
12
3
  import { ViewInfo } from '@memberjunction/core-entities';
@@ -83,6 +74,53 @@ function ListDetailGridComponent_kendo_excelexport_column_8_Template(rf, ctx) {
83
74
  i0.ɵɵproperty("field", exportCol_r5.Name)("title", exportCol_r5.Name);
84
75
  } }
85
76
  export class ListDetailGridComponent {
77
+ formBuilder;
78
+ router;
79
+ renderer;
80
+ title = 'ListDetailGrid';
81
+ Params;
82
+ BottomMargin = 0;
83
+ InEditMode = false;
84
+ EditMode = "None";
85
+ AutoNavigate = true;
86
+ rowClicked = new EventEmitter();
87
+ rowEdited = new EventEmitter();
88
+ kendoGridElement = null;
89
+ kendoGridElementRef = null;
90
+ kendoExcelExport = null;
91
+ recordCompareComponent = null;
92
+ analysisQuestion = null;
93
+ analysisResults = null;
94
+ compareDialogContainer;
95
+ _pendingRecords = [];
96
+ viewData = [];
97
+ totalRowCount = 0;
98
+ formattedData = [];
99
+ viewColumns = [];
100
+ visibleColumns = [];
101
+ sortSettings = [];
102
+ entityRecord = null;
103
+ skip = 0;
104
+ pageSize = 40;
105
+ isLoading = false;
106
+ gridView = { data: [], total: 0 };
107
+ gridHeight = 750;
108
+ _viewEntity;
109
+ _entityInfo;
110
+ _newGridState = {};
111
+ editModeEnded = new Subject();
112
+ recordsToCompare = [];
113
+ compareMode = false;
114
+ mergeMode = false;
115
+ duplicateMode = false;
116
+ selectableSettings = {
117
+ enabled: false
118
+ };
119
+ selectedKeys = [];
120
+ isCompareDialogOpened = false;
121
+ isConfirmDialogOpen = false;
122
+ showRefreshButton = true;
123
+ viewExecutionTime = 0;
86
124
  get PendingRecords() {
87
125
  return this._pendingRecords;
88
126
  }
@@ -100,11 +138,10 @@ export class ListDetailGridComponent {
100
138
  this.editModeEnded.next();
101
139
  }
102
140
  EditingComplete() {
103
- var _a, _b;
104
141
  if (this.InEditMode) {
105
142
  // tell our grid to close the cell that is currently being edited
106
- (_a = this.kendoGridElement) === null || _a === void 0 ? void 0 : _a.closeCell();
107
- (_b = this.kendoGridElement) === null || _b === void 0 ? void 0 : _b.closeRow(); // close the row too
143
+ this.kendoGridElement?.closeCell();
144
+ this.kendoGridElement?.closeRow(); // close the row too
108
145
  // we need to wait for edit mode to end before we can return true
109
146
  return new Promise((resolve, reject) => {
110
147
  const subscription = this.editModeEnded.subscribe(() => {
@@ -123,6 +160,10 @@ export class ListDetailGridComponent {
123
160
  this.skip = event.skip;
124
161
  this.virtualLoadData();
125
162
  }
163
+ data = [
164
+ { text: "Folder" },
165
+ { text: "Report with Skip" },
166
+ ];
126
167
  virtualLoadData() {
127
168
  // check to see if we have already formatted the slice of the data we need right now
128
169
  // we are storing the formattted data in the formattedData array and it has same set
@@ -179,99 +220,48 @@ export class ListDetailGridComponent {
179
220
  this.formBuilder = formBuilder;
180
221
  this.router = router;
181
222
  this.renderer = renderer;
182
- this.title = 'ListDetailGrid';
183
- this.BottomMargin = 0;
184
- this.InEditMode = false;
185
- this.EditMode = "None";
186
- this.AutoNavigate = true;
187
- this.rowClicked = new EventEmitter();
188
- this.rowEdited = new EventEmitter();
189
- this.kendoGridElement = null;
190
- this.kendoGridElementRef = null;
191
- this.kendoExcelExport = null;
192
- this.recordCompareComponent = null;
193
- this.analysisQuestion = null;
194
- this.analysisResults = null;
195
- this._pendingRecords = [];
196
- this.viewData = [];
197
- this.totalRowCount = 0;
198
- this.formattedData = [];
199
- this.viewColumns = [];
200
- this.visibleColumns = [];
201
- this.sortSettings = [];
202
- this.entityRecord = null;
203
- this.skip = 0;
204
- this.pageSize = 40;
205
- this.isLoading = false;
206
- this.gridView = { data: [], total: 0 };
207
- this.gridHeight = 750;
208
- this._newGridState = {};
209
- this.editModeEnded = new Subject();
210
- this.recordsToCompare = [];
211
- this.compareMode = false;
212
- this.mergeMode = false;
213
- this.duplicateMode = false;
214
- this.selectableSettings = {
215
- enabled: false
216
- };
217
- this.selectedKeys = [];
218
- this.isCompareDialogOpened = false;
219
- this.isConfirmDialogOpen = false;
220
- this.showRefreshButton = true;
221
- this.viewExecutionTime = 0;
222
- this.data = [
223
- { text: "Folder" },
224
- { text: "Report with Skip" },
225
- ];
226
- this._viewDirty = false;
227
- this._movedToBody = false;
228
- this._deferLoadCount = 0;
229
- this._allowLoad = true;
230
- // Export Functionality
231
- this.exportColumns = [];
232
- this.exportData = [];
233
223
  }
224
+ _saveTimeout;
234
225
  SaveView() {
235
226
  // debounced outer function...
236
227
  clearTimeout(this._saveTimeout);
237
- this._saveTimeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
228
+ this._saveTimeout = setTimeout(async () => {
238
229
  // when we actually call inner save view we do await
239
- yield this.innerSaveView();
240
- }), 5000); // 5 seconds delay
230
+ await this.innerSaveView();
231
+ }, 5000); // 5 seconds delay
241
232
  }
242
233
  ;
243
- innerSaveView() {
244
- return __awaiter(this, void 0, void 0, function* () {
245
- if (this._viewDirty) {
246
- const md = new Metadata();
247
- if (this._viewEntity &&
248
- this._viewEntity.Get('UserID') === md.CurrentUser.ID) {
249
- // this view is a saved view, AND it belongs to the current user
250
- // update the grid state if we have settings updates for columns and/or sorts
251
- const tempGridState = JSON.parse(this._viewEntity.Get('GridState'));
252
- const tempColSettings = this._newGridState.columnSettings ? this._newGridState.columnSettings : tempGridState.columnSettings;
253
- tempColSettings.forEach((col) => { col.DisplayName, col.ID, col.Name, col.hidden, col.orderIndex, col.width; }); // remove EntityFieldInfo from the column settings
254
- tempGridState.columnSettings = tempColSettings;
255
- tempGridState.sortSettings = this._newGridState.sortSettings ? this._newGridState.sortSettings : tempGridState.sortSettings;
256
- // now stringify the grid state and save it
257
- this._viewEntity.Set('GridState', JSON.stringify(tempGridState));
258
- const newSortState = tempGridState.sortSettings.map((s) => { return { field: s.field, direction: s.dir }; });
259
- const oldSortState = JSON.parse(this._viewEntity.Get('SortState'));
260
- this._viewEntity.Set('SortState', JSON.stringify(newSortState));
261
- if (yield this._viewEntity.Save()) {
262
- // check to see if sort state changed and if so, refresh the grid
263
- if (JSON.stringify(newSortState) !== JSON.stringify(oldSortState)) {
264
- if (this.Params) // makes sure we have params before we refresh
265
- this.Refresh(this.Params);
266
- }
267
- this._viewDirty = false;
268
- }
269
- else {
270
- this.CreateSimpleNotification('Unable to save view settings', 'error', 5000);
234
+ _viewDirty = false;
235
+ async innerSaveView() {
236
+ if (this._viewDirty) {
237
+ const md = new Metadata();
238
+ if (this._viewEntity &&
239
+ this._viewEntity.Get('UserID') === md.CurrentUser.ID) {
240
+ // this view is a saved view, AND it belongs to the current user
241
+ // update the grid state if we have settings updates for columns and/or sorts
242
+ const tempGridState = JSON.parse(this._viewEntity.Get('GridState'));
243
+ const tempColSettings = this._newGridState.columnSettings ? this._newGridState.columnSettings : tempGridState.columnSettings;
244
+ tempColSettings.forEach((col) => { col.DisplayName, col.ID, col.Name, col.hidden, col.orderIndex, col.width; }); // remove EntityFieldInfo from the column settings
245
+ tempGridState.columnSettings = tempColSettings;
246
+ tempGridState.sortSettings = this._newGridState.sortSettings ? this._newGridState.sortSettings : tempGridState.sortSettings;
247
+ // now stringify the grid state and save it
248
+ this._viewEntity.Set('GridState', JSON.stringify(tempGridState));
249
+ const newSortState = tempGridState.sortSettings.map((s) => { return { field: s.field, direction: s.dir }; });
250
+ const oldSortState = JSON.parse(this._viewEntity.Get('SortState'));
251
+ this._viewEntity.Set('SortState', JSON.stringify(newSortState));
252
+ if (await this._viewEntity.Save()) {
253
+ // check to see if sort state changed and if so, refresh the grid
254
+ if (JSON.stringify(newSortState) !== JSON.stringify(oldSortState)) {
255
+ if (this.Params) // makes sure we have params before we refresh
256
+ this.Refresh(this.Params);
271
257
  }
258
+ this._viewDirty = false;
259
+ }
260
+ else {
261
+ this.CreateSimpleNotification('Unable to save view settings', 'error', 5000);
272
262
  }
273
263
  }
274
- });
264
+ }
275
265
  }
276
266
  CreateSimpleNotification(message, style, duration) {
277
267
  const data = {
@@ -286,119 +276,111 @@ export class ListDetailGridComponent {
286
276
  args: data
287
277
  });
288
278
  }
289
- columnReorder(args) {
290
- return __awaiter(this, void 0, void 0, function* () {
291
- // Remove the column from the original position
292
- // need to find the column in the viewColumns array because args.old/new Indexes are from the visibleColumns array
293
- const fieldName = args.column.field;
294
- if (fieldName) {
295
- const vcOldIndex = this.viewColumns.findIndex((vc) => vc.Name === fieldName);
296
- const vcNewIndex = this.viewColumns.findIndex((vc) => vc.orderIndex === args.newIndex);
297
- if (vcOldIndex >= 0) {
298
- // got the index, now remove the element
299
- const element = this.viewColumns.splice(vcOldIndex, 1)[0];
300
- // Insert it at the new position
301
- this.viewColumns.splice(vcNewIndex, 0, element);
302
- // go through all of the columns and set orderIndex as that isn't done automatically
303
- let visColIndex = 0;
304
- for (let i = 0; i < this.viewColumns.length; i++) {
305
- if (!this.viewColumns[i].hidden) {
306
- this.viewColumns[i].orderIndex = visColIndex;
307
- visColIndex++;
308
- }
279
+ async columnReorder(args) {
280
+ // Remove the column from the original position
281
+ // need to find the column in the viewColumns array because args.old/new Indexes are from the visibleColumns array
282
+ const fieldName = args.column.field;
283
+ if (fieldName) {
284
+ const vcOldIndex = this.viewColumns.findIndex((vc) => vc.Name === fieldName);
285
+ const vcNewIndex = this.viewColumns.findIndex((vc) => vc.orderIndex === args.newIndex);
286
+ if (vcOldIndex >= 0) {
287
+ // got the index, now remove the element
288
+ const element = this.viewColumns.splice(vcOldIndex, 1)[0];
289
+ // Insert it at the new position
290
+ this.viewColumns.splice(vcNewIndex, 0, element);
291
+ // go through all of the columns and set orderIndex as that isn't done automatically
292
+ let visColIndex = 0;
293
+ for (let i = 0; i < this.viewColumns.length; i++) {
294
+ if (!this.viewColumns[i].hidden) {
295
+ this.viewColumns[i].orderIndex = visColIndex;
296
+ visColIndex++;
309
297
  }
310
- // now loop through all of the HIDDEN columns and set their orderIndex, done in second loop because we want first loop to give us total number of visible columns
311
- for (let i = 0; i < this.viewColumns.length; i++) {
312
- if (this.viewColumns[i].hidden) {
313
- this.viewColumns[i].orderIndex = visColIndex;
314
- visColIndex++;
315
- }
298
+ }
299
+ // now loop through all of the HIDDEN columns and set their orderIndex, done in second loop because we want first loop to give us total number of visible columns
300
+ for (let i = 0; i < this.viewColumns.length; i++) {
301
+ if (this.viewColumns[i].hidden) {
302
+ this.viewColumns[i].orderIndex = visColIndex;
303
+ visColIndex++;
316
304
  }
317
- // make sure that _newGridState.columnSettings is set
318
- this._newGridState.columnSettings = this.viewColumns;
319
- this._viewDirty = true;
320
- this.SaveView();
321
305
  }
306
+ // make sure that _newGridState.columnSettings is set
307
+ this._newGridState.columnSettings = this.viewColumns;
308
+ this._viewDirty = true;
309
+ this.SaveView();
322
310
  }
323
- });
311
+ }
324
312
  }
325
- columnResize(args) {
326
- return __awaiter(this, void 0, void 0, function* () {
327
- for (const col of args) {
328
- const c = col.column;
329
- const viewCol = this.viewColumns.find(vc => vc.Name === c.field);
330
- const visCol = this.visibleColumns.find(vc => vc.Name === c.field);
331
- const visCols = this.visibleColumns;
332
- if (viewCol)
333
- viewCol.width = col.newWidth;
334
- }
335
- this._newGridState.columnSettings = this.viewColumns.map(vc => {
336
- return {
337
- Name: vc.Name,
338
- DisplayName: vc.DisplayName,
339
- width: vc.width,
340
- orderIndex: vc.orderIndex,
341
- hidden: vc.hidden
342
- };
343
- });
344
- this._viewDirty = true;
345
- this.SaveView();
313
+ async columnResize(args) {
314
+ for (const col of args) {
315
+ const c = col.column;
316
+ const viewCol = this.viewColumns.find(vc => vc.Name === c.field);
317
+ const visCol = this.visibleColumns.find(vc => vc.Name === c.field);
318
+ const visCols = this.visibleColumns;
319
+ if (viewCol)
320
+ viewCol.width = col.newWidth;
321
+ }
322
+ this._newGridState.columnSettings = this.viewColumns.map(vc => {
323
+ return {
324
+ Name: vc.Name,
325
+ DisplayName: vc.DisplayName,
326
+ width: vc.width,
327
+ orderIndex: vc.orderIndex,
328
+ hidden: vc.hidden
329
+ };
346
330
  });
347
- }
348
- sortChanged(sort) {
349
- return __awaiter(this, void 0, void 0, function* () {
350
- if (sort && sort.length > 0) {
351
- // remove any sort settings that don't have a direction
352
- const filterSort = sort.filter((s) => s.dir !== undefined && s.dir !== null && s.dir !== "");
353
- this._newGridState.sortSettings = filterSort;
354
- }
355
- else
356
- this._newGridState.sortSettings = sort;
357
- this.sortSettings = this._newGridState.sortSettings; // for the UI display - grid binding to this shows that the sort is applied via arrows in the column headers
358
- if (this.IsDynamicView()) {
359
- // Dynamic View, we have this.Params and can add an OrderBy and then just Refresh() the entire component
360
- // that will result in going to the server for a refreshed set of data
361
- if (this.Params) {
362
- this.Params.OrderBy = sort[0].field + ' ' + (sort[0].dir);
363
- this.Refresh(this.Params);
364
- }
365
- else {
366
- LogError("sortChanged() called but this.Params is null or undefined"); // should never get here
367
- }
331
+ this._viewDirty = true;
332
+ this.SaveView();
333
+ }
334
+ async sortChanged(sort) {
335
+ if (sort && sort.length > 0) {
336
+ // remove any sort settings that don't have a direction
337
+ const filterSort = sort.filter((s) => s.dir !== undefined && s.dir !== null && s.dir !== "");
338
+ this._newGridState.sortSettings = filterSort;
339
+ }
340
+ else
341
+ this._newGridState.sortSettings = sort;
342
+ this.sortSettings = this._newGridState.sortSettings; // for the UI display - grid binding to this shows that the sort is applied via arrows in the column headers
343
+ if (this.IsDynamicView()) {
344
+ // Dynamic View, we have this.Params and can add an OrderBy and then just Refresh() the entire component
345
+ // that will result in going to the server for a refreshed set of data
346
+ if (this.Params) {
347
+ this.Params.OrderBy = sort[0].field + ' ' + (sort[0].dir);
348
+ this.Refresh(this.Params);
368
349
  }
369
350
  else {
370
- // Saved view - we do this on the server side only
371
- this._viewDirty = true;
372
- this.innerSaveView(); // for sort changes we call innerSaveView() directly, not through SaveView() which is debounced
351
+ LogError("sortChanged() called but this.Params is null or undefined"); // should never get here
373
352
  }
374
- });
353
+ }
354
+ else {
355
+ // Saved view - we do this on the server side only
356
+ this._viewDirty = true;
357
+ this.innerSaveView(); // for sort changes we call innerSaveView() directly, not through SaveView() which is debounced
358
+ }
375
359
  }
376
- cellClickHandler(args) {
377
- return __awaiter(this, void 0, void 0, function* () {
378
- if (this.compareMode || this.mergeMode)
379
- return;
380
- if (this._entityInfo) {
381
- const compositeKey = new CompositeKey();
382
- compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, this.viewData[args.rowIndex]);
383
- this.rowClicked.emit({
384
- entityId: this._entityInfo.ID,
385
- entityName: this._entityInfo.Name,
386
- CompositeKey: compositeKey
387
- });
388
- if (this._entityInfo.AllowUpdateAPI &&
389
- this.EditMode !== "None") {
390
- const perm = this._entityInfo.GetUserPermisions(new Metadata().CurrentUser);
391
- if (perm.CanUpdate) {
392
- this.StartEditMode();
393
- args.sender.editCell(args.rowIndex, args.columnIndex, this.createFormGroup(args.dataItem));
394
- }
395
- }
396
- if (this.EditMode === 'None' && this.AutoNavigate) {
397
- // tell app router to go to this record
398
- this.router.navigate(['resource', 'record', compositeKey.ToURLSegment()], { queryParams: { Entity: this._entityInfo.Name } });
360
+ async cellClickHandler(args) {
361
+ if (this.compareMode || this.mergeMode)
362
+ return;
363
+ if (this._entityInfo) {
364
+ const compositeKey = new CompositeKey();
365
+ compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, this.viewData[args.rowIndex]);
366
+ this.rowClicked.emit({
367
+ entityId: this._entityInfo.ID,
368
+ entityName: this._entityInfo.Name,
369
+ CompositeKey: compositeKey
370
+ });
371
+ if (this._entityInfo.AllowUpdateAPI &&
372
+ this.EditMode !== "None") {
373
+ const perm = this._entityInfo.GetUserPermisions(new Metadata().CurrentUser);
374
+ if (perm.CanUpdate) {
375
+ this.StartEditMode();
376
+ args.sender.editCell(args.rowIndex, args.columnIndex, this.createFormGroup(args.dataItem));
399
377
  }
400
378
  }
401
- });
379
+ if (this.EditMode === 'None' && this.AutoNavigate) {
380
+ // tell app router to go to this record
381
+ this.router.navigate(['resource', 'record', compositeKey.ToURLSegment()], { queryParams: { Entity: this._entityInfo.Name } });
382
+ }
383
+ }
402
384
  }
403
385
  createFormGroup(dataItem) {
404
386
  const groupFields = {};
@@ -422,79 +404,76 @@ export class ListDetailGridComponent {
422
404
  return "text";
423
405
  }
424
406
  }
425
- cellCloseHandler(args) {
426
- return __awaiter(this, void 0, void 0, function* () {
427
- var _a;
428
- try {
429
- if (this._entityInfo && this.EditMode !== "None") {
430
- const { formGroup, dataItem, column } = args;
431
- if (!formGroup.valid) {
432
- // prevent closing the edited cell if there are invalid values.
433
- args.preventDefault();
434
- }
435
- else if (formGroup.dirty) {
436
- if (args.originalEvent && args.originalEvent.keyCode === Keys.Escape)
437
- return; // user hit escape, so don't save their changes
438
- // update the data item with the new values - this drives UI refresh while we save the record...
439
- Object.assign(dataItem, formGroup.value);
440
- const md = new Metadata();
441
- let record;
442
- let bSaved = false;
443
- let compositeKey = new CompositeKey();
444
- compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, dataItem);
445
- if (this.EditMode === "Save") {
446
- record = yield md.GetEntityObject(this._entityInfo.Name);
447
- yield record.InnerLoad(compositeKey);
448
- record.SetMany(formGroup.value);
449
- bSaved = yield record.Save();
450
- if (!bSaved) {
451
- this.CreateSimpleNotification("Error saving record: " + compositeKey.ToString(), 'error', 5000);
452
- }
407
+ async cellCloseHandler(args) {
408
+ try {
409
+ if (this._entityInfo && this.EditMode !== "None") {
410
+ const { formGroup, dataItem, column } = args;
411
+ if (!formGroup.valid) {
412
+ // prevent closing the edited cell if there are invalid values.
413
+ args.preventDefault();
414
+ }
415
+ else if (formGroup.dirty) {
416
+ if (args.originalEvent && args.originalEvent.keyCode === Keys.Escape)
417
+ return; // user hit escape, so don't save their changes
418
+ // update the data item with the new values - this drives UI refresh while we save the record...
419
+ Object.assign(dataItem, formGroup.value);
420
+ const md = new Metadata();
421
+ let record;
422
+ let bSaved = false;
423
+ let compositeKey = new CompositeKey();
424
+ compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, dataItem);
425
+ if (this.EditMode === "Save") {
426
+ record = await md.GetEntityObject(this._entityInfo.Name);
427
+ await record.InnerLoad(compositeKey);
428
+ record.SetMany(formGroup.value);
429
+ bSaved = await record.Save();
430
+ if (!bSaved) {
431
+ this.CreateSimpleNotification("Error saving record: " + compositeKey.ToString(), 'error', 5000);
453
432
  }
454
- else {
455
- record = (_a = this._pendingRecords.find((r) => {
456
- // compare each field in the r.record object with the same fields from data Item
457
- for (const k of r.record.PrimaryKeys) {
458
- if (r.record.Get(k.Name) !== dataItem[k.Name]) {
459
- return false; // not the same record
460
- }
433
+ }
434
+ else {
435
+ record = this._pendingRecords.find((r) => {
436
+ // compare each field in the r.record object with the same fields from data Item
437
+ for (const k of r.record.PrimaryKeys) {
438
+ if (r.record.Get(k.Name) !== dataItem[k.Name]) {
439
+ return false; // not the same record
461
440
  }
462
- // if we get here, all pkeys matches in the above loop
463
- return true;
464
- })) === null || _a === void 0 ? void 0 : _a.record;
465
- if (!record) {
466
- // haven't edited this record before
467
- record = yield md.GetEntityObject(this._viewEntity.Get('Entity'));
468
- yield record.InnerLoad(compositeKey);
469
- this._pendingRecords.push({ record,
470
- row: args.rowIndex,
471
- dataItem }); // don't save - put the changed record on a queue for saving later by our container
472
441
  }
473
- // now, based on the column that we're in, update the record with the new value
474
- record.Set(column.field, formGroup.value[column.field]);
475
- // if a boolean value, modify what is in the grid so it is formatted properly
476
- if (column.field && column.field.length > 0) {
477
- const ef = this._entityInfo.Fields.find(f => f.Name === column.field);
478
- if (ef && ef.TSType === EntityFieldTSType.Boolean) {
479
- dataItem[column.field] = record.Get(column.field) ? '✓' : '';
480
- }
442
+ // if we get here, all pkeys matches in the above loop
443
+ return true;
444
+ })?.record;
445
+ if (!record) {
446
+ // haven't edited this record before
447
+ record = await md.GetEntityObject(this._viewEntity.Get('Entity'));
448
+ await record.InnerLoad(compositeKey);
449
+ this._pendingRecords.push({ record,
450
+ row: args.rowIndex,
451
+ dataItem }); // don't save - put the changed record on a queue for saving later by our container
452
+ }
453
+ // now, based on the column that we're in, update the record with the new value
454
+ record.Set(column.field, formGroup.value[column.field]);
455
+ // if a boolean value, modify what is in the grid so it is formatted properly
456
+ if (column.field && column.field.length > 0) {
457
+ const ef = this._entityInfo.Fields.find(f => f.Name === column.field);
458
+ if (ef && ef.TSType === EntityFieldTSType.Boolean) {
459
+ dataItem[column.field] = record.Get(column.field) ? '✓' : '';
481
460
  }
482
461
  }
483
- this.rowEdited.emit({
484
- record: record,
485
- row: args.rowIndex,
486
- saved: bSaved
487
- });
488
462
  }
463
+ this.rowEdited.emit({
464
+ record: record,
465
+ row: args.rowIndex,
466
+ saved: bSaved
467
+ });
489
468
  }
490
469
  }
491
- catch (e) {
492
- console.error(e);
493
- }
494
- finally {
495
- this.EndEditMode();
496
- }
497
- });
470
+ }
471
+ catch (e) {
472
+ console.error(e);
473
+ }
474
+ finally {
475
+ this.EndEditMode();
476
+ }
498
477
  }
499
478
  // this handles reverting pending cahnges to records WITHIN the grid, not the user view settings, unrelated to that.
500
479
  RevertPendingChanges() {
@@ -515,6 +494,7 @@ export class ListDetailGridComponent {
515
494
  if (this.Params)
516
495
  this.Refresh(this.Params);
517
496
  }
497
+ _movedToBody = false;
518
498
  moveDialogToBody() {
519
499
  if (this._movedToBody)
520
500
  return;
@@ -522,6 +502,8 @@ export class ListDetailGridComponent {
522
502
  this.renderer.appendChild(document.body, dialogElement);
523
503
  this._movedToBody = true;
524
504
  }
505
+ _deferLoadCount = 0;
506
+ _allowLoad = true;
525
507
  get AllowLoad() {
526
508
  return this._allowLoad;
527
509
  }
@@ -534,119 +516,114 @@ export class ListDetailGridComponent {
534
516
  return;
535
517
  }
536
518
  }
537
- RefreshFromSavedParams() {
538
- return __awaiter(this, void 0, void 0, function* () {
539
- if (this.Params)
540
- this.Refresh(this.Params);
541
- });
519
+ async RefreshFromSavedParams() {
520
+ if (this.Params)
521
+ this.Refresh(this.Params);
542
522
  }
543
- Refresh(params) {
544
- return __awaiter(this, void 0, void 0, function* () {
545
- var _a, _b, _c;
546
- this.Params = params;
547
- if (this.AllowLoad === false) {
548
- return;
523
+ async Refresh(params) {
524
+ this.Params = params;
525
+ if (this.AllowLoad === false) {
526
+ return;
527
+ }
528
+ if (params && (params.ViewEntity || params.ViewID || params.ViewName || (params.EntityName && params.ExtraFilter))) {
529
+ const startTime = new Date().getTime();
530
+ this.isLoading = true;
531
+ const md = new Metadata();
532
+ const rv = new RunView();
533
+ // get the view entity first so we can pass it in, otherwise it will end up getting loaded inside of RunView() which is inefficient as we need it too
534
+ // this is done for performance purposes
535
+ if (params.ViewEntity) {
536
+ // When we receive the .ViewEntity via our params that is a time saver as we don't need to load it again, so ALWAYS use that instance of the entity object for the view entity
537
+ this._viewEntity = params.ViewEntity;
538
+ const e = md.Entities.find(x => x.ID === this._viewEntity?.EntityID);
539
+ if (e)
540
+ this._entityInfo = e;
541
+ else
542
+ throw new Error("Unable to get entity info for view: " + this._viewEntity?.Name);
549
543
  }
550
- if (params && (params.ViewEntity || params.ViewID || params.ViewName || (params.EntityName && params.ExtraFilter))) {
551
- const startTime = new Date().getTime();
552
- this.isLoading = true;
553
- const md = new Metadata();
554
- const rv = new RunView();
555
- // get the view entity first so we can pass it in, otherwise it will end up getting loaded inside of RunView() which is inefficient as we need it too
556
- // this is done for performance purposes
557
- if (params.ViewEntity) {
558
- // When we receive the .ViewEntity via our params that is a time saver as we don't need to load it again, so ALWAYS use that instance of the entity object for the view entity
559
- this._viewEntity = params.ViewEntity;
560
- const e = md.Entities.find(x => { var _a; return x.ID === ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.EntityID); });
561
- if (e)
562
- this._entityInfo = e;
563
- else
564
- throw new Error("Unable to get entity info for view: " + ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.Name));
565
- }
566
- else if (!params.ViewEntity && (params.ViewID || params.ViewName)) {
567
- // this is NOT a dyamic view as we got either the ViewID or ViewName, so we can get the ViewEntity
568
- if (params.ViewID && params.ViewID.length > 0) {
569
- this._viewEntity = (yield ViewInfo.GetViewEntity(params.ViewID));
570
- }
571
- else if (params.ViewName) {
572
- this._viewEntity = (yield ViewInfo.GetViewEntityByName(params.ViewName));
573
- }
574
- params.ViewEntity = this._viewEntity;
575
- const e = md.Entities.find(x => { var _a; return x.ID === ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.EntityID); });
576
- if (e)
577
- this._entityInfo = e;
578
- else
579
- throw new Error("Unable to get entity info for view: " + ((_b = this._viewEntity) === null || _b === void 0 ? void 0 : _b.Name));
544
+ else if (!params.ViewEntity && (params.ViewID || params.ViewName)) {
545
+ // this is NOT a dyamic view as we got either the ViewID or ViewName, so we can get the ViewEntity
546
+ if (params.ViewID && params.ViewID.length > 0) {
547
+ this._viewEntity = await ViewInfo.GetViewEntity(params.ViewID);
580
548
  }
581
- else if (params.EntityName) {
582
- // we don't have a ViewEntity because we're doing a dynamic view, so we need to get the entity info from the Entity Name
583
- const e = md.Entities.find(x => x.Name === params.EntityName);
584
- if (e)
585
- this._entityInfo = e;
549
+ else if (params.ViewName) {
550
+ this._viewEntity = await ViewInfo.GetViewEntityByName(params.ViewName);
586
551
  }
552
+ params.ViewEntity = this._viewEntity;
553
+ const e = md.Entities.find(x => x.ID === this._viewEntity?.EntityID);
554
+ if (e)
555
+ this._entityInfo = e;
587
556
  else
588
- throw new Error("Invalid configuration, we need to receive either a ViewEntity, ViewID, ViewName, or EntityName and ExtraFilter in order to run a view");
589
- const rvResult = yield rv.RunView(params);
590
- if (!rvResult.Success) {
591
- // it failed
592
- this.CreateSimpleNotification("Error running view:\n\n" + rvResult.ErrorMessage, 'error', 5000);
593
- }
594
- else {
595
- // it worked
596
- this.viewData = rvResult.Results;
597
- this.totalRowCount = rvResult.TotalRowCount;
598
- this.formattedData = new Array(this.viewData.length);
599
- let cols;
600
- if (this._viewEntity)
601
- cols = this._viewEntity.Columns;
602
- else
603
- cols = (_c = this._entityInfo) === null || _c === void 0 ? void 0 : _c.Fields.filter((f) => f.DefaultInView).map((f) => {
604
- return {
605
- ID: f.ID,
606
- Name: f.Name,
607
- DisplayName: f.DisplayName,
608
- EntityField: f,
609
- hidden: false,
610
- orderIndex: f.Sequence,
611
- width: f.DefaultColumnWidth ? f.DefaultColumnWidth : 100,
612
- };
613
- });
614
- if (cols) {
615
- this.viewColumns = cols;
616
- const tempCols = cols.filter(x => x.hidden === false).sort((a, b) => {
617
- const aOrder = a.orderIndex != null ? a.orderIndex : 9999;
618
- const bOrder = b.orderIndex != null ? b.orderIndex : 9999;
619
- return aOrder - bOrder;
620
- });
621
- this.visibleColumns = tempCols;
622
- }
623
- // sorting setup
624
- if (this._viewEntity) {
625
- const temp = this._viewEntity.ViewSortInfo;
626
- const kendoSortSettings = temp.map((s) => {
627
- let dir;
628
- if (typeof s.direction === 'string')
629
- dir = s.direction.trim().toLowerCase();
630
- else if (typeof s.direction === 'number' && s.direction === 1)
631
- dir = 'asc';
632
- else if (typeof s.direction === 'number' && s.direction === 2)
633
- dir = 'desc';
634
- else
635
- dir = '';
636
- return { field: s.field, dir: dir };
637
- });
638
- this.sortSettings = kendoSortSettings;
639
- }
640
- this.skip = 0;
641
- this.virtualLoadData();
642
- }
643
- this.viewExecutionTime = (new Date().getTime() - startTime) / 1000; // in seconds
644
- this.isLoading = false;
557
+ throw new Error("Unable to get entity info for view: " + this._viewEntity?.Name);
558
+ }
559
+ else if (params.EntityName) {
560
+ // we don't have a ViewEntity because we're doing a dynamic view, so we need to get the entity info from the Entity Name
561
+ const e = md.Entities.find(x => x.Name === params.EntityName);
562
+ if (e)
563
+ this._entityInfo = e;
564
+ }
565
+ else
566
+ throw new Error("Invalid configuration, we need to receive either a ViewEntity, ViewID, ViewName, or EntityName and ExtraFilter in order to run a view");
567
+ const rvResult = await rv.RunView(params);
568
+ if (!rvResult.Success) {
569
+ // it failed
570
+ this.CreateSimpleNotification("Error running view:\n\n" + rvResult.ErrorMessage, 'error', 5000);
645
571
  }
646
572
  else {
647
- LogError("Refresh(params) must have ViewID or ViewName or (EntityName and ExtraFilter)");
573
+ // it worked
574
+ this.viewData = rvResult.Results;
575
+ this.totalRowCount = rvResult.TotalRowCount;
576
+ this.formattedData = new Array(this.viewData.length);
577
+ let cols;
578
+ if (this._viewEntity)
579
+ cols = this._viewEntity.Columns;
580
+ else
581
+ cols = this._entityInfo?.Fields.filter((f) => f.DefaultInView).map((f) => {
582
+ return {
583
+ ID: f.ID,
584
+ Name: f.Name,
585
+ DisplayName: f.DisplayName,
586
+ EntityField: f,
587
+ hidden: false,
588
+ orderIndex: f.Sequence,
589
+ width: f.DefaultColumnWidth ? f.DefaultColumnWidth : 100,
590
+ };
591
+ });
592
+ if (cols) {
593
+ this.viewColumns = cols;
594
+ const tempCols = cols.filter(x => x.hidden === false).sort((a, b) => {
595
+ const aOrder = a.orderIndex != null ? a.orderIndex : 9999;
596
+ const bOrder = b.orderIndex != null ? b.orderIndex : 9999;
597
+ return aOrder - bOrder;
598
+ });
599
+ this.visibleColumns = tempCols;
600
+ }
601
+ // sorting setup
602
+ if (this._viewEntity) {
603
+ const temp = this._viewEntity.ViewSortInfo;
604
+ const kendoSortSettings = temp.map((s) => {
605
+ let dir;
606
+ if (typeof s.direction === 'string')
607
+ dir = s.direction.trim().toLowerCase();
608
+ else if (typeof s.direction === 'number' && s.direction === 1)
609
+ dir = 'asc';
610
+ else if (typeof s.direction === 'number' && s.direction === 2)
611
+ dir = 'desc';
612
+ else
613
+ dir = '';
614
+ return { field: s.field, dir: dir };
615
+ });
616
+ this.sortSettings = kendoSortSettings;
617
+ }
618
+ this.skip = 0;
619
+ this.virtualLoadData();
648
620
  }
649
- });
621
+ this.viewExecutionTime = (new Date().getTime() - startTime) / 1000; // in seconds
622
+ this.isLoading = false;
623
+ }
624
+ else {
625
+ LogError("Refresh(params) must have ViewID or ViewName or (EntityName and ExtraFilter)");
626
+ }
650
627
  }
651
628
  GetColumnTitle(col) {
652
629
  if (col.DisplayName)
@@ -724,194 +701,191 @@ export class ListDetailGridComponent {
724
701
  }
725
702
  }
726
703
  }
727
- closeConfirmMergeDialog(event) {
728
- return __awaiter(this, void 0, void 0, function* () {
729
- if (event === 'yes') {
730
- if (this._entityInfo && this.recordCompareComponent) {
731
- const md = new Metadata();
732
- const pkeys = this._entityInfo.PrimaryKeys;
733
- const result = yield md.MergeRecords({
734
- EntityName: this._entityInfo.Name,
735
- RecordsToMerge: this.recordsToCompare.map((r) => {
736
- return r.PrimaryKey;
737
- }).filter((compositeKey) => {
738
- if (!this.recordCompareComponent) {
739
- return false;
740
- }
741
- return this.recordCompareComponent.selectedRecordCompositeKey.Equals(compositeKey);
742
- }),
743
- SurvivingRecordCompositeKey: this.recordCompareComponent.selectedRecordCompositeKey,
744
- FieldMap: this.recordCompareComponent.fieldMap.map((fm) => {
745
- return {
746
- FieldName: fm.fieldName,
747
- Value: fm.value
748
- };
749
- })
750
- });
751
- if (result.Success) {
752
- // merge was successful, so refresh the grid
753
- this.selectedKeys = [];
754
- this.recordsToCompare = [];
755
- this.mergeMode = false;
756
- this.compareMode = false;
757
- // close the dialogs
758
- this.isCompareDialogOpened = false;
759
- this.isConfirmDialogOpen = false;
760
- // refresh the grid
761
- this.Refresh(this.Params);
762
- }
763
- else {
764
- // the merge failed, so show an error message
765
- this.isConfirmDialogOpen = false;
766
- this.CreateSimpleNotification("Error merging records: " + result.OverallStatus, 'error', 5000);
767
- }
768
- }
769
- }
770
- else {
771
- this.isConfirmDialogOpen = false;
772
- // close the dialog and let the user continue to work on the merge, so don't close the compare dialog
773
- }
774
- });
775
- }
776
- closeCompareDialog(event) {
777
- return __awaiter(this, void 0, void 0, function* () {
778
- console.log(event);
779
- switch (event) {
780
- case 'merge':
781
- // user has requested to merge the records and retain the selected record from the compare records component, so run the merge
782
- // first, confirm with the user to make 100% sure they want to do this as it is irreversible
783
- this.isConfirmDialogOpen = true;
784
- break;
785
- default: // close and cancel
704
+ async closeConfirmMergeDialog(event) {
705
+ if (event === 'yes') {
706
+ if (this._entityInfo && this.recordCompareComponent) {
707
+ const md = new Metadata();
708
+ const pkeys = this._entityInfo.PrimaryKeys;
709
+ const result = await md.MergeRecords({
710
+ EntityName: this._entityInfo.Name,
711
+ RecordsToMerge: this.recordsToCompare.map((r) => {
712
+ return r.PrimaryKey;
713
+ }).filter((compositeKey) => {
714
+ if (!this.recordCompareComponent) {
715
+ return false;
716
+ }
717
+ return this.recordCompareComponent.selectedRecordCompositeKey.Equals(compositeKey);
718
+ }),
719
+ SurvivingRecordCompositeKey: this.recordCompareComponent.selectedRecordCompositeKey,
720
+ FieldMap: this.recordCompareComponent.fieldMap.map((fm) => {
721
+ return {
722
+ FieldName: fm.fieldName,
723
+ Value: fm.value
724
+ };
725
+ })
726
+ });
727
+ if (result.Success) {
728
+ // merge was successful, so refresh the grid
786
729
  this.selectedKeys = [];
787
730
  this.recordsToCompare = [];
788
731
  this.mergeMode = false;
789
732
  this.compareMode = false;
790
- this.duplicateMode = false;
733
+ // close the dialogs
791
734
  this.isCompareDialogOpened = false;
792
- break;
793
- }
794
- });
795
- }
796
- findDuplicateRecords() {
797
- return __awaiter(this, void 0, void 0, function* () {
798
- var _a;
799
- if (!this._entityInfo) {
800
- console.error("Entity Info is not available");
801
- this.closeCompareDialog('duplicate');
802
- return;
803
- }
804
- const md = new Metadata();
805
- const list = yield md.GetEntityObject('Lists');
806
- list.NewRecord();
807
- list.Name = `Potential Duplicate Run`;
808
- list.Description = `Potential Duplicate Run for ${this._entityInfo.Name} Entity`;
809
- list.EntityID = this._entityInfo.ID;
810
- list.UserID = md.CurrentUser.ID;
811
- const saveResult = yield list.Save();
812
- if (!saveResult) {
813
- console.error(`Failed to save list for Potential Duplicate Run`);
814
- return;
815
- }
816
- let params = new PotentialDuplicateRequest();
817
- params.EntityID = (_a = this._entityInfo) === null || _a === void 0 ? void 0 : _a.ID;
818
- params.ListID = list.ID;
819
- params.RecordIDs = [];
820
- for (const index of this.selectedKeys) {
821
- const viewData = this.viewData[index];
822
- const idField = viewData.ID;
823
- const listDetail = yield md.GetEntityObject('List Details');
824
- listDetail.NewRecord();
825
- listDetail.ListID = list.ID;
826
- listDetail.RecordID = idField.toString();
827
- yield listDetail.Save();
735
+ this.isConfirmDialogOpen = false;
736
+ // refresh the grid
737
+ this.Refresh(this.Params);
738
+ }
739
+ else {
740
+ // the merge failed, so show an error message
741
+ this.isConfirmDialogOpen = false;
742
+ this.CreateSimpleNotification("Error merging records: " + result.OverallStatus, 'error', 5000);
743
+ }
828
744
  }
829
- this.closeCompareDialog('duplicate');
830
- this.CreateSimpleNotification("Working on finding duplicates, will notify you when it is complete...", 'info', 2000);
831
- let response = yield md.GetRecordDuplicates(params, md.CurrentUser);
832
- console.log(response);
833
- });
745
+ }
746
+ else {
747
+ this.isConfirmDialogOpen = false;
748
+ // close the dialog and let the user continue to work on the merge, so don't close the compare dialog
749
+ }
834
750
  }
835
- doExcelExport() {
836
- return __awaiter(this, void 0, void 0, function* () {
837
- if (this.kendoExcelExport === null)
838
- throw new Error("kendoExcelExport is null, cannot export data");
839
- try {
840
- this.CreateSimpleNotification("Working on the export, will notify you when it is complete...", 'info', 2000);
841
- const data = yield this.getExportData();
842
- // we have the data.
843
- const cols = this.viewColumns.filter((vc) => vc.hidden === false);
844
- this.exportColumns = cols;
845
- this.exportData = data;
846
- // before we call the save, we need to let Angular do its thing that will result in the kendoExcelExport component binding properly to
847
- // the exportColumns and exportData arrays. So we wait for the next tick before we call save()
848
- setTimeout(() => {
849
- this.kendoExcelExport.save();
850
- this.CreateSimpleNotification("Excel Export Complete", 'success', 2000);
851
- }, 100);
852
- }
853
- catch (e) {
854
- this.CreateSimpleNotification("Error exporting data", 'error', 5000);
855
- LogError(e);
856
- }
857
- });
751
+ async closeCompareDialog(event) {
752
+ console.log(event);
753
+ switch (event) {
754
+ case 'merge':
755
+ // user has requested to merge the records and retain the selected record from the compare records component, so run the merge
756
+ // first, confirm with the user to make 100% sure they want to do this as it is irreversible
757
+ this.isConfirmDialogOpen = true;
758
+ break;
759
+ default: // close and cancel
760
+ this.selectedKeys = [];
761
+ this.recordsToCompare = [];
762
+ this.mergeMode = false;
763
+ this.compareMode = false;
764
+ this.duplicateMode = false;
765
+ this.isCompareDialogOpened = false;
766
+ break;
767
+ }
858
768
  }
859
- getExportData() {
860
- return __awaiter(this, void 0, void 0, function* () {
861
- // Get the data for the ENTIRE view, not just the current page
862
- const md = new Metadata();
863
- const rv = new RunView();
864
- const p = Object.assign(Object.assign({}, this.Params), { IgnoreMaxRows: true, ForceAuditLog: true, AuditLogDescription: `Export of Data From ${this._viewEntity ? '"' + this._viewEntity.Get('Name') + '"' : ''} View for User ${md.CurrentUser.Email}` });
865
- const result = yield rv.RunView(p);
866
- if (result && result.Success) {
867
- return result.Results;
868
- }
869
- else
870
- throw new Error("Unable to get export data");
871
- });
769
+ async findDuplicateRecords() {
770
+ if (!this._entityInfo) {
771
+ console.error("Entity Info is not available");
772
+ this.closeCompareDialog('duplicate');
773
+ return;
774
+ }
775
+ const md = new Metadata();
776
+ const list = await md.GetEntityObject('Lists');
777
+ list.NewRecord();
778
+ list.Name = `Potential Duplicate Run`;
779
+ list.Description = `Potential Duplicate Run for ${this._entityInfo.Name} Entity`;
780
+ list.EntityID = this._entityInfo.ID;
781
+ list.UserID = md.CurrentUser.ID;
782
+ const saveResult = await list.Save();
783
+ if (!saveResult) {
784
+ console.error(`Failed to save list for Potential Duplicate Run`);
785
+ return;
786
+ }
787
+ let params = new PotentialDuplicateRequest();
788
+ params.EntityID = this._entityInfo?.ID;
789
+ params.ListID = list.ID;
790
+ params.RecordIDs = [];
791
+ for (const index of this.selectedKeys) {
792
+ const viewData = this.viewData[index];
793
+ const idField = viewData.ID;
794
+ const listDetail = await md.GetEntityObject('List Details');
795
+ listDetail.NewRecord();
796
+ listDetail.ListID = list.ID;
797
+ listDetail.RecordID = idField.toString();
798
+ await listDetail.Save();
799
+ }
800
+ this.closeCompareDialog('duplicate');
801
+ this.CreateSimpleNotification("Working on finding duplicates, will notify you when it is complete...", 'info', 2000);
802
+ let response = await md.GetRecordDuplicates(params, md.CurrentUser);
803
+ console.log(response);
804
+ }
805
+ // Export Functionality
806
+ exportColumns = [];
807
+ exportData = [];
808
+ async doExcelExport() {
809
+ if (this.kendoExcelExport === null)
810
+ throw new Error("kendoExcelExport is null, cannot export data");
811
+ try {
812
+ this.CreateSimpleNotification("Working on the export, will notify you when it is complete...", 'info', 2000);
813
+ const data = await this.getExportData();
814
+ // we have the data.
815
+ const cols = this.viewColumns.filter((vc) => vc.hidden === false);
816
+ this.exportColumns = cols;
817
+ this.exportData = data;
818
+ // before we call the save, we need to let Angular do its thing that will result in the kendoExcelExport component binding properly to
819
+ // the exportColumns and exportData arrays. So we wait for the next tick before we call save()
820
+ setTimeout(() => {
821
+ this.kendoExcelExport.save();
822
+ this.CreateSimpleNotification("Excel Export Complete", 'success', 2000);
823
+ }, 100);
824
+ }
825
+ catch (e) {
826
+ this.CreateSimpleNotification("Error exporting data", 'error', 5000);
827
+ LogError(e);
828
+ }
872
829
  }
830
+ async getExportData() {
831
+ // Get the data for the ENTIRE view, not just the current page
832
+ const md = new Metadata();
833
+ const rv = new RunView();
834
+ const p = {
835
+ ...this.Params,
836
+ IgnoreMaxRows: true,
837
+ ForceAuditLog: true,
838
+ AuditLogDescription: `Export of Data From ${this._viewEntity ? '"' + this._viewEntity.Get('Name') + '"' : ''} View for User ${md.CurrentUser.Email}`
839
+ };
840
+ const result = await rv.RunView(p);
841
+ if (result && result.Success) {
842
+ return result.Results;
843
+ }
844
+ else
845
+ throw new Error("Unable to get export data");
846
+ }
847
+ static ɵfac = function ListDetailGridComponent_Factory(t) { return new (t || ListDetailGridComponent)(i0.ɵɵdirectiveInject(i1.FormBuilder), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i0.Renderer2)); };
848
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ListDetailGridComponent, selectors: [["mj-list-detail-grid"]], viewQuery: function ListDetailGridComponent_Query(rf, ctx) { if (rf & 1) {
849
+ i0.ɵɵviewQuery(_c0, 5, GridComponent);
850
+ i0.ɵɵviewQuery(_c0, 5, ElementRef);
851
+ i0.ɵɵviewQuery(_c1, 5, ExcelExportComponent);
852
+ i0.ɵɵviewQuery(_c2, 5);
853
+ i0.ɵɵviewQuery(_c3, 5, TextAreaComponent);
854
+ i0.ɵɵviewQuery(_c4, 5, ElementRef);
855
+ i0.ɵɵviewQuery(_c5, 5);
856
+ } if (rf & 2) {
857
+ let _t;
858
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElement = _t.first);
859
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElementRef = _t.first);
860
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoExcelExport = _t.first);
861
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.recordCompareComponent = _t.first);
862
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisQuestion = _t.first);
863
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisResults = _t.first);
864
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.compareDialogContainer = _t.first);
865
+ } }, inputs: { Params: "Params", BottomMargin: "BottomMargin", InEditMode: "InEditMode", EditMode: "EditMode", AutoNavigate: "AutoNavigate", AllowLoad: "AllowLoad" }, outputs: { rowClicked: "rowClicked", rowEdited: "rowEdited" }, decls: 9, vars: 18, consts: [["kendoGrid", ""], ["excelExport", ""], ["mjFillContainer", "", 1, "list-detail-grid-wrap"], ["mjFillContainer", "", "scrollable", "virtual", "kendoGridSelectBy", "", 3, "pageChange", "selectedKeysChange", "cellClick", "cellClose", "columnReorder", "columnResize", "selectionChange", "sortChange", "resizable", "data", "skip", "pageSize", "rowHeight", "loading", "height", "sortable", "sort", "reorderable", "selectable", "selectedKeys"], ["kendoGridToolbarTemplate", ""], [3, "width", "headerStyle", "style", 4, "ngIf"], [3, "field", "title", "width", "editable", "editor", "headerStyle", "style", 4, "ngFor", "ngForOf"], [3, "data", "fileName"], [3, "field", "title", 4, "ngFor", "ngForOf"], ["kendoButton", "", 3, "click"], [1, "fa-regular", "fa-file-excel"], [3, "width", "headerStyle"], [3, "field", "title", "width", "editable", "editor", "headerStyle"], [4, "ngIf"], ["kendoGridFooterTemplate", ""], [2, "font-size", "smaller", "font-weight", "normal"], [3, "field", "title"]], template: function ListDetailGridComponent_Template(rf, ctx) { if (rf & 1) {
866
+ const _r1 = i0.ɵɵgetCurrentView();
867
+ i0.ɵɵelementStart(0, "div", 2)(1, "kendo-grid", 3, 0);
868
+ i0.ɵɵlistener("pageChange", function ListDetailGridComponent_Template_kendo_grid_pageChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.pageChange($event)); });
869
+ i0.ɵɵtwoWayListener("selectedKeysChange", function ListDetailGridComponent_Template_kendo_grid_selectedKeysChange_1_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.selectedKeys, $event) || (ctx.selectedKeys = $event); return i0.ɵɵresetView($event); });
870
+ i0.ɵɵlistener("cellClick", function ListDetailGridComponent_Template_kendo_grid_cellClick_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.cellClickHandler($event)); })("cellClose", function ListDetailGridComponent_Template_kendo_grid_cellClose_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.cellCloseHandler($event)); })("columnReorder", function ListDetailGridComponent_Template_kendo_grid_columnReorder_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.columnReorder($event)); })("columnResize", function ListDetailGridComponent_Template_kendo_grid_columnResize_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.columnResize($event)); })("selectionChange", function ListDetailGridComponent_Template_kendo_grid_selectionChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.selectionChange($event)); })("sortChange", function ListDetailGridComponent_Template_kendo_grid_sortChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.sortChanged($event)); });
871
+ i0.ɵɵtemplate(3, ListDetailGridComponent_ng_template_3_Template, 3, 0, "ng-template", 4)(4, ListDetailGridComponent_kendo_grid_checkbox_column_4_Template, 1, 6, "kendo-grid-checkbox-column", 5)(5, ListDetailGridComponent_kendo_grid_column_5_Template, 2, 10, "kendo-grid-column", 6);
872
+ i0.ɵɵelementStart(6, "kendo-excelexport", 7, 1);
873
+ i0.ɵɵtemplate(8, ListDetailGridComponent_kendo_excelexport_column_8_Template, 1, 2, "kendo-excelexport-column", 8);
874
+ i0.ɵɵelementEnd()()();
875
+ } if (rf & 2) {
876
+ i0.ɵɵadvance();
877
+ i0.ɵɵproperty("resizable", true)("data", ctx.gridView)("skip", ctx.skip)("pageSize", ctx.pageSize)("rowHeight", 36)("loading", ctx.isLoading)("height", ctx.gridHeight)("sortable", true)("sort", ctx.sortSettings)("resizable", true)("reorderable", true)("selectable", true);
878
+ i0.ɵɵtwoWayProperty("selectedKeys", ctx.selectedKeys);
879
+ i0.ɵɵadvance(3);
880
+ i0.ɵɵproperty("ngIf", ctx.compareMode || ctx.mergeMode || ctx.duplicateMode);
881
+ i0.ɵɵadvance();
882
+ i0.ɵɵproperty("ngForOf", ctx.visibleColumns);
883
+ i0.ɵɵadvance();
884
+ i0.ɵɵproperty("data", ctx.exportData)("fileName", (ctx._viewEntity ? ctx._viewEntity.Get("Name") : ctx._entityInfo == null ? null : ctx._entityInfo.Name) + ".xlsx");
885
+ i0.ɵɵadvance(2);
886
+ i0.ɵɵproperty("ngForOf", ctx.exportColumns);
887
+ } }, dependencies: [i3.NgForOf, i3.NgIf, i4.GridComponent, i4.ToolbarTemplateDirective, i4.SelectionDirective, i4.ColumnComponent, i4.FooterTemplateDirective, i4.CheckboxColumnComponent, i5.ExcelExportComponent, i5.ColumnComponent, i6.ButtonComponent, i7.FillContainer, i3.DecimalPipe], styles: [".list-detail-grid-wrap[_ngcontent-%COMP%] {\n height: calc(100vh - 20px);\n}\n\n.list-detail-grid-column-header[_ngcontent-%COMP%] {\n background-color: #fff;\n font-size: 20pt;\n font-weight: bold;\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 .title-wrapper[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n line-height: 28px;\n }\n .main-fav-wrapper[_ngcontent-%COMP%] {\n background: #fff;\n padding: 20px;\n }\n .filter-wrapper[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 14px;\n align-items: center;\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 .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.k-table-td[_ngcontent-%COMP%] {\n border-right: none !important;\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.btn-cmn.active[_ngcontent-%COMP%] {\n border: 1px solid var(--border-blue);\n}\n .title-wrapper .filter-wrapper .k-dropdown-button .k-button {\n border: 1px solid var(--gray-color);\n border-radius: 8px; padding: 10px 25px;\n background: var(--white-color);\n color: var(--sideNav);\n}\n .list-detail-grid-wrap .k-grid-aria-root .k-grid-header .k-grid-header-table thead tr th {\n border-right: none;\n border-inline-start-width: 0;\n color: var(--thead-color);\n}\n .list-detail-grid-wrap .k-grid-aria-root kendo-grid-list .k-grid-table tbody tr td { \n border-inline-start-width: 0;\n color: var(--tdata-color);\n font-weight: 500;\n border-bottom-width: 1px;\n}"] });
873
888
  }
874
- ListDetailGridComponent.ɵfac = function ListDetailGridComponent_Factory(t) { return new (t || ListDetailGridComponent)(i0.ɵɵdirectiveInject(i1.FormBuilder), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i0.Renderer2)); };
875
- ListDetailGridComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ListDetailGridComponent, selectors: [["mj-list-detail-grid"]], viewQuery: function ListDetailGridComponent_Query(rf, ctx) { if (rf & 1) {
876
- i0.ɵɵviewQuery(_c0, 5, GridComponent);
877
- i0.ɵɵviewQuery(_c0, 5, ElementRef);
878
- i0.ɵɵviewQuery(_c1, 5, ExcelExportComponent);
879
- i0.ɵɵviewQuery(_c2, 5);
880
- i0.ɵɵviewQuery(_c3, 5, TextAreaComponent);
881
- i0.ɵɵviewQuery(_c4, 5, ElementRef);
882
- i0.ɵɵviewQuery(_c5, 5);
883
- } if (rf & 2) {
884
- let _t;
885
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElement = _t.first);
886
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElementRef = _t.first);
887
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoExcelExport = _t.first);
888
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.recordCompareComponent = _t.first);
889
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisQuestion = _t.first);
890
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisResults = _t.first);
891
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.compareDialogContainer = _t.first);
892
- } }, inputs: { Params: "Params", BottomMargin: "BottomMargin", InEditMode: "InEditMode", EditMode: "EditMode", AutoNavigate: "AutoNavigate", AllowLoad: "AllowLoad" }, outputs: { rowClicked: "rowClicked", rowEdited: "rowEdited" }, decls: 9, vars: 18, consts: [["kendoGrid", ""], ["excelExport", ""], ["mjFillContainer", "", 1, "list-detail-grid-wrap"], ["mjFillContainer", "", "scrollable", "virtual", "kendoGridSelectBy", "", 3, "pageChange", "selectedKeysChange", "cellClick", "cellClose", "columnReorder", "columnResize", "selectionChange", "sortChange", "resizable", "data", "skip", "pageSize", "rowHeight", "loading", "height", "sortable", "sort", "reorderable", "selectable", "selectedKeys"], ["kendoGridToolbarTemplate", ""], [3, "width", "headerStyle", "style", 4, "ngIf"], [3, "field", "title", "width", "editable", "editor", "headerStyle", "style", 4, "ngFor", "ngForOf"], [3, "data", "fileName"], [3, "field", "title", 4, "ngFor", "ngForOf"], ["kendoButton", "", 3, "click"], [1, "fa-regular", "fa-file-excel"], [3, "width", "headerStyle"], [3, "field", "title", "width", "editable", "editor", "headerStyle"], [4, "ngIf"], ["kendoGridFooterTemplate", ""], [2, "font-size", "smaller", "font-weight", "normal"], [3, "field", "title"]], template: function ListDetailGridComponent_Template(rf, ctx) { if (rf & 1) {
893
- const _r1 = i0.ɵɵgetCurrentView();
894
- i0.ɵɵelementStart(0, "div", 2)(1, "kendo-grid", 3, 0);
895
- i0.ɵɵlistener("pageChange", function ListDetailGridComponent_Template_kendo_grid_pageChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.pageChange($event)); });
896
- i0.ɵɵtwoWayListener("selectedKeysChange", function ListDetailGridComponent_Template_kendo_grid_selectedKeysChange_1_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.selectedKeys, $event) || (ctx.selectedKeys = $event); return i0.ɵɵresetView($event); });
897
- i0.ɵɵlistener("cellClick", function ListDetailGridComponent_Template_kendo_grid_cellClick_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.cellClickHandler($event)); })("cellClose", function ListDetailGridComponent_Template_kendo_grid_cellClose_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.cellCloseHandler($event)); })("columnReorder", function ListDetailGridComponent_Template_kendo_grid_columnReorder_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.columnReorder($event)); })("columnResize", function ListDetailGridComponent_Template_kendo_grid_columnResize_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.columnResize($event)); })("selectionChange", function ListDetailGridComponent_Template_kendo_grid_selectionChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.selectionChange($event)); })("sortChange", function ListDetailGridComponent_Template_kendo_grid_sortChange_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.sortChanged($event)); });
898
- i0.ɵɵtemplate(3, ListDetailGridComponent_ng_template_3_Template, 3, 0, "ng-template", 4)(4, ListDetailGridComponent_kendo_grid_checkbox_column_4_Template, 1, 6, "kendo-grid-checkbox-column", 5)(5, ListDetailGridComponent_kendo_grid_column_5_Template, 2, 10, "kendo-grid-column", 6);
899
- i0.ɵɵelementStart(6, "kendo-excelexport", 7, 1);
900
- i0.ɵɵtemplate(8, ListDetailGridComponent_kendo_excelexport_column_8_Template, 1, 2, "kendo-excelexport-column", 8);
901
- i0.ɵɵelementEnd()()();
902
- } if (rf & 2) {
903
- i0.ɵɵadvance();
904
- i0.ɵɵproperty("resizable", true)("data", ctx.gridView)("skip", ctx.skip)("pageSize", ctx.pageSize)("rowHeight", 36)("loading", ctx.isLoading)("height", ctx.gridHeight)("sortable", true)("sort", ctx.sortSettings)("resizable", true)("reorderable", true)("selectable", true);
905
- i0.ɵɵtwoWayProperty("selectedKeys", ctx.selectedKeys);
906
- i0.ɵɵadvance(3);
907
- i0.ɵɵproperty("ngIf", ctx.compareMode || ctx.mergeMode || ctx.duplicateMode);
908
- i0.ɵɵadvance();
909
- i0.ɵɵproperty("ngForOf", ctx.visibleColumns);
910
- i0.ɵɵadvance();
911
- i0.ɵɵproperty("data", ctx.exportData)("fileName", (ctx._viewEntity ? ctx._viewEntity.Get("Name") : ctx._entityInfo == null ? null : ctx._entityInfo.Name) + ".xlsx");
912
- i0.ɵɵadvance(2);
913
- i0.ɵɵproperty("ngForOf", ctx.exportColumns);
914
- } }, dependencies: [i3.NgForOf, i3.NgIf, i4.GridComponent, i4.ToolbarTemplateDirective, i4.SelectionDirective, i4.ColumnComponent, i4.FooterTemplateDirective, i4.CheckboxColumnComponent, i5.ExcelExportComponent, i5.ColumnComponent, i6.ButtonComponent, i7.FillContainer, i3.DecimalPipe], styles: [".list-detail-grid-wrap[_ngcontent-%COMP%] {\n height: calc(100vh - 20px);\n}\n\n.list-detail-grid-column-header[_ngcontent-%COMP%] {\n background-color: #fff;\n font-size: 20pt;\n font-weight: bold;\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 .title-wrapper[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n line-height: 28px;\n }\n .main-fav-wrapper[_ngcontent-%COMP%] {\n background: #fff;\n padding: 20px;\n }\n .filter-wrapper[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 14px;\n align-items: center;\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 .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.k-table-td[_ngcontent-%COMP%] {\n border-right: none !important;\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.btn-cmn.active[_ngcontent-%COMP%] {\n border: 1px solid var(--border-blue);\n}\n .title-wrapper .filter-wrapper .k-dropdown-button .k-button {\n border: 1px solid var(--gray-color);\n border-radius: 8px; padding: 10px 25px;\n background: var(--white-color);\n color: var(--sideNav);\n}\n .list-detail-grid-wrap .k-grid-aria-root .k-grid-header .k-grid-header-table thead tr th {\n border-right: none;\n border-inline-start-width: 0;\n color: var(--thead-color);\n}\n .list-detail-grid-wrap .k-grid-aria-root kendo-grid-list .k-grid-table tbody tr td { \n border-inline-start-width: 0;\n color: var(--tdata-color);\n font-weight: 500;\n border-bottom-width: 1px;\n}"] });
915
889
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListDetailGridComponent, [{
916
890
  type: Component,
917
891
  args: [{ selector: 'mj-list-detail-grid', template: "<div class=\"list-detail-grid-wrap\" mjFillContainer>\n <kendo-grid #kendoGrid\n mjFillContainer\n [resizable]=\"true\"\n [data]=\"gridView\" \n [skip]=\"skip\"\n [pageSize]=\"pageSize\"\n scrollable=\"virtual\"\n [rowHeight]=\"36\"\n (pageChange)=\"pageChange($event)\"\n [loading]=\"isLoading\"\n [height]=\"gridHeight\"\n [sortable]=\"true\"\n [sort]=\"sortSettings\" \n [resizable]=\"true\"\n [reorderable]=\"true\"\n [selectable]=\"true\"\n kendoGridSelectBy\n [(selectedKeys)]=\"selectedKeys\"\n (cellClick)=\"cellClickHandler($event)\"\n (cellClose)=\"cellCloseHandler($event)\"\n (columnReorder)=\"columnReorder($event)\"\n (columnResize)=\"columnResize($event)\"\n (selectionChange)=\"selectionChange($event)\"\n (sortChange)=\"sortChanged($event)\"\n >\n <ng-template kendoGridToolbarTemplate>\n <button kendoButton (click)=\"doExcelExport()\" >\n <span class=\"fa-regular fa-file-excel\"></span>\n Export to Excel\n </button>\n </ng-template>\n <kendo-grid-checkbox-column \n *ngIf=\"compareMode || mergeMode || duplicateMode\" \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 <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\"\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.viewData.length | number}}{{this.totalRowCount > this.viewData.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 <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 </kendo-grid>\n</div> ", styles: [".list-detail-grid-wrap {\n height: calc(100vh - 20px);\n}\n\n.list-detail-grid-column-header {\n background-color: #fff;\n font-size: 20pt;\n font-weight: bold;\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 .title-wrapper h4 {\n margin: 0;\n font-size: 24px;\n line-height: 28px;\n }\n .main-fav-wrapper {\n background: #fff;\n padding: 20px;\n }\n .filter-wrapper {\n display: flex;\n justify-content: flex-start;\n gap: 14px;\n align-items: center;\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 .title-wrapper .search svg {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 12px;\n}\n.k-table-td {\n border-right: none !important;\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.btn-cmn.active {\n border: 1px solid var(--border-blue);\n}\n::ng-deep .title-wrapper .filter-wrapper .k-dropdown-button .k-button {\n border: 1px solid var(--gray-color);\n border-radius: 8px; padding: 10px 25px;\n background: var(--white-color);\n color: var(--sideNav);\n}\n::ng-deep .list-detail-grid-wrap .k-grid-aria-root .k-grid-header .k-grid-header-table thead tr th {\n border-right: none;\n border-inline-start-width: 0;\n color: var(--thead-color);\n}\n::ng-deep .list-detail-grid-wrap .k-grid-aria-root kendo-grid-list .k-grid-table tbody tr td { \n border-inline-start-width: 0;\n color: var(--tdata-color);\n font-weight: 500;\n border-bottom-width: 1px;\n} "] }]