@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
|
-
|
|
107
|
-
|
|
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(() =>
|
|
228
|
+
this._saveTimeout = setTimeout(async () => {
|
|
238
229
|
// when we actually call inner save view we do await
|
|
239
|
-
|
|
240
|
-
}
|
|
230
|
+
await this.innerSaveView();
|
|
231
|
+
}, 5000); // 5 seconds delay
|
|
241
232
|
}
|
|
242
233
|
;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
this.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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
|
-
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
this.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
//
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
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
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
this.Refresh(this.Params);
|
|
541
|
-
});
|
|
519
|
+
async RefreshFromSavedParams() {
|
|
520
|
+
if (this.Params)
|
|
521
|
+
this.Refresh(this.Params);
|
|
542
522
|
}
|
|
543
|
-
Refresh(params) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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.
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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.
|
|
582
|
-
|
|
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("
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
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
|
-
|
|
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
|
-
|
|
729
|
-
if (
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
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
|
-
|
|
733
|
+
// close the dialogs
|
|
791
734
|
this.isCompareDialogOpened = false;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
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
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
this.
|
|
845
|
-
this.
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
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
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
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} "] }]
|