@memberjunction/ng-list-detail-grid 1.4.1

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.
@@ -0,0 +1,127 @@
1
+ import { ElementRef, EventEmitter, OnInit, AfterViewInit, Renderer2 } from '@angular/core';
2
+ import { FormBuilder, FormGroup } from '@angular/forms';
3
+ import { Router } from '@angular/router';
4
+ import { BaseEntity, RunViewParams, EntityFieldInfo, EntityInfo, CompositeKey } from '@memberjunction/core';
5
+ import { ViewColumnInfo, UserViewEntityExtended } from '@memberjunction/core-entities';
6
+ import { CellClickEvent, GridDataResult, PageChangeEvent, GridComponent, CellCloseEvent, ColumnReorderEvent, ColumnResizeArgs, SelectionEvent, SelectableSettings } from "@progress/kendo-angular-grid";
7
+ import { ExcelExportComponent } from '@progress/kendo-angular-excel-export';
8
+ import { CompareRecordsComponent } from '@memberjunction/ng-compare-records';
9
+ import { TextAreaComponent } from '@progress/kendo-angular-inputs';
10
+ import * as i0 from "@angular/core";
11
+ export type GridRowClickedEvent = {
12
+ entityId: number;
13
+ entityName: string;
14
+ CompositeKey: CompositeKey;
15
+ };
16
+ export type GridRowEditedEvent = {
17
+ record: BaseEntity;
18
+ row: number;
19
+ saved: boolean;
20
+ };
21
+ export type GridPendingRecordItem = {
22
+ record: BaseEntity;
23
+ row: number;
24
+ dataItem: any;
25
+ };
26
+ export declare class ListDetailGridComponent implements OnInit, AfterViewInit {
27
+ private formBuilder;
28
+ private router;
29
+ private renderer;
30
+ title: string;
31
+ Params: RunViewParams | undefined;
32
+ BottomMargin: number;
33
+ InEditMode: boolean;
34
+ EditMode: "None" | "Save" | "Queue";
35
+ AutoNavigate: boolean;
36
+ rowClicked: EventEmitter<GridRowClickedEvent>;
37
+ rowEdited: EventEmitter<GridRowEditedEvent>;
38
+ kendoGridElement: GridComponent | null;
39
+ kendoGridElementRef: ElementRef | null;
40
+ kendoExcelExport: ExcelExportComponent | null;
41
+ recordCompareComponent: CompareRecordsComponent | null;
42
+ analysisQuestion: TextAreaComponent | null;
43
+ analysisResults: ElementRef | null;
44
+ private compareDialogContainer;
45
+ private _pendingRecords;
46
+ viewData: any[];
47
+ totalRowCount: number;
48
+ formattedData: {
49
+ [key: string]: any;
50
+ }[];
51
+ viewColumns: ViewColumnInfo[];
52
+ visibleColumns: ViewColumnInfo[];
53
+ sortSettings: any[];
54
+ entityRecord: BaseEntity | null;
55
+ skip: number;
56
+ pageSize: number;
57
+ isLoading: boolean;
58
+ gridView: GridDataResult;
59
+ gridHeight: number;
60
+ _viewEntity: UserViewEntityExtended | undefined;
61
+ _entityInfo: EntityInfo | undefined;
62
+ private _newGridState;
63
+ private editModeEnded;
64
+ recordsToCompare: any[];
65
+ compareMode: boolean;
66
+ mergeMode: boolean;
67
+ duplicateMode: boolean;
68
+ selectableSettings: SelectableSettings;
69
+ selectedKeys: any[];
70
+ isCompareDialogOpened: boolean;
71
+ isConfirmDialogOpen: boolean;
72
+ showRefreshButton: boolean;
73
+ viewExecutionTime: number;
74
+ get PendingRecords(): GridPendingRecordItem[];
75
+ get ViewID(): number;
76
+ protected StartEditMode(): void;
77
+ protected EndEditMode(): void;
78
+ EditingComplete(): Promise<boolean>;
79
+ IsDynamicView(): boolean;
80
+ pageChange(event: PageChangeEvent): void;
81
+ data: {
82
+ text: string;
83
+ }[];
84
+ private virtualLoadData;
85
+ constructor(formBuilder: FormBuilder, router: Router, renderer: Renderer2);
86
+ private _saveTimeout;
87
+ private SaveView;
88
+ private _viewDirty;
89
+ innerSaveView(): Promise<void>;
90
+ protected CreateSimpleNotification(message: string, style: "none" | "success" | "error" | "warning" | "info", duration: number): void;
91
+ columnReorder(args: ColumnReorderEvent): Promise<void>;
92
+ columnResize(args: ColumnResizeArgs[]): Promise<void>;
93
+ sortChanged(sort: any): Promise<void>;
94
+ cellClickHandler(args: CellClickEvent): Promise<void>;
95
+ createFormGroup(dataItem: any): FormGroup;
96
+ getEditor(ef: EntityFieldInfo): "boolean" | "text" | "numeric" | "date";
97
+ cellCloseHandler(args: CellCloseEvent): Promise<void>;
98
+ RevertPendingChanges(): void;
99
+ ngOnInit(): void;
100
+ ngAfterViewInit(): void;
101
+ private _movedToBody;
102
+ moveDialogToBody(): void;
103
+ private _deferLoadCount;
104
+ private _allowLoad;
105
+ get AllowLoad(): boolean;
106
+ set AllowLoad(value: boolean);
107
+ RefreshFromSavedParams(): Promise<void>;
108
+ Refresh(params: RunViewParams): Promise<void>;
109
+ GetColumnTitle(col: ViewColumnInfo): string;
110
+ GetColumnCellStyle(col: ViewColumnInfo): {
111
+ 'text-align': string;
112
+ 'vertical-align': string;
113
+ };
114
+ selectionChange(args: SelectionEvent): void;
115
+ enableMergeOrCompare(cancel: boolean | undefined, type: 'merge' | 'compare'): void;
116
+ enableCheckbox(cancel: boolean | undefined, type: 'merge' | 'compare' | 'duplicate' | ''): void;
117
+ closeConfirmMergeDialog(event: 'cancel' | 'yes' | 'no'): Promise<void>;
118
+ closeCompareDialog(event: 'close' | 'cancel' | 'merge' | 'duplicate'): Promise<void>;
119
+ findDuplicateRecords(): Promise<void>;
120
+ exportColumns: ViewColumnInfo[];
121
+ exportData: any[];
122
+ doExcelExport(): Promise<void>;
123
+ protected getExportData(): Promise<any[]>;
124
+ static ɵfac: i0.ɵɵFactoryDeclaration<ListDetailGridComponent, never>;
125
+ static ɵcmp: i0.ɵɵComponentDeclaration<ListDetailGridComponent, "mj-list-detail-grid", never, { "Params": { "alias": "Params"; "required": false; }; "BottomMargin": { "alias": "BottomMargin"; "required": false; }; "InEditMode": { "alias": "InEditMode"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; "AutoNavigate": { "alias": "AutoNavigate"; "required": false; }; "AllowLoad": { "alias": "AllowLoad"; "required": false; }; }, { "rowClicked": "rowClicked"; "rowEdited": "rowEdited"; }, never, never, false, never>;
126
+ }
127
+ //# sourceMappingURL=ng-list-detail-grid.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-list-detail-grid.component.d.ts","sourceRoot":"","sources":["../../src/lib/ng-list-detail-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAU,YAAY,EAAE,MAAM,EAAS,aAAa,EAAE,SAAS,EAAC,MAAM,eAAe,CAAC;AAC/H,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,OAAO,EAAY,UAAU,EAAW,aAAa,EAAE,eAAe,EAAqB,UAAU,EAA0B,YAAY,EAA6B,MAAM,sBAAsB,CAAC;AACrM,OAAO,EAA2B,cAAc,EAAE,sBAAsB,EAAgC,MAAM,+BAA+B,CAAC;AAE9I,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAC9E,kBAAkB,EAAE,gBAAgB,EAAmB,cAAc,EAAE,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAKxI,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;;AAGnE,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;CAC5B,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,GAAG,CAAC;CACf,CAAA;AAED,qBAKa,uBAAwB,YAAW,MAAM,EAAE,aAAa;IAkKvD,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAnK5B,KAAK,SAAoB;IAChB,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,YAAY,EAAE,MAAM,CAAK;IACzB,UAAU,EAAE,OAAO,CAAS;IAC5B,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAS;IAC5C,YAAY,EAAE,OAAO,CAAQ;IAE5B,UAAU,oCAA2C;IACrD,SAAS,mCAA0C;IAEZ,gBAAgB,EAAE,aAAa,GAAG,IAAI,CAAQ;IACjD,mBAAmB,EAAE,UAAU,GAAG,IAAI,CAAQ;IAClC,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IAC7D,sBAAsB,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IAEpD,gBAAgB,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC1D,eAAe,EAAE,UAAU,GAAG,IAAI,CAAQ;IAEzD,OAAO,CAAC,sBAAsB,CAAc;IAEjF,OAAO,CAAC,eAAe,CAA+B;IAE/C,QAAQ,EAAE,GAAG,EAAE,CAAM;IACrB,aAAa,EAAE,MAAM,CAAK;IAC1B,aAAa,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,CAAM;IAC7C,WAAW,EAAE,cAAc,EAAE,CAAM;IACnC,cAAc,EAAE,cAAc,EAAE,CAAM;IACtC,YAAY,EAAE,GAAG,EAAE,CAAM;IACzB,YAAY,EAAE,UAAU,GAAG,IAAI,CAAQ;IACvC,IAAI,EAAE,MAAM,CAAK;IACjB,QAAQ,EAAE,MAAM,CAAM;IACtB,SAAS,EAAE,OAAO,CAAS;IAC3B,QAAQ,EAAE,cAAc,CAA0B;IAClD,UAAU,EAAE,MAAM,CAAO;IAEzB,WAAW,EAAE,sBAAsB,GAAG,SAAS,CAAA;IAC9C,WAAW,EAAE,UAAU,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,aAAa,CAAqB;IAE1C,OAAO,CAAC,aAAa,CAAuB;IAErC,gBAAgB,EAAE,GAAG,EAAE,CAAM;IAE7B,WAAW,EAAE,OAAO,CAAS;IAC7B,SAAS,EAAE,OAAO,CAAS;IAC3B,aAAa,EAAE,OAAO,CAAS;IAE/B,kBAAkB,EAAE,kBAAkB,CAE3C;IACK,YAAY,EAAE,GAAG,EAAE,CAAM;IACzB,qBAAqB,EAAE,OAAO,CAAS;IACvC,mBAAmB,EAAE,OAAO,CAAS;IACrC,iBAAiB,EAAE,OAAO,CAAQ;IAElC,iBAAiB,EAAE,MAAM,CAAK;IAErC,IAAW,cAAc,IAAI,qBAAqB,EAAE,CAEnD;IAED,IAAW,MAAM,IAAI,MAAM,CAK1B;IAED,SAAS,CAAC,aAAa;IAGvB,SAAS,CAAC,WAAW;IAId,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBnC,aAAa,IAAI,OAAO;IAIxB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI/C,IAAI;;QAGF;IACF,OAAO,CAAC,eAAe;gBAwDH,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS;IAIvC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,UAAU,CAAkB;IACvB,aAAa;IAmC1B,SAAS,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;IAcjH,aAAa,CAAC,IAAI,EAAE,kBAAkB;IAyCtC,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE;IAuBrC,WAAW,CAAC,IAAI,EAAE,GAAG;IA8BrB,gBAAgB,CAAC,IAAI,EAAE,cAAc;IA4B3C,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS;IAazC,SAAS,CAAC,EAAE,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM;IAajE,gBAAgB,CAAC,IAAI,EAAE,cAAc;IA4E3C,oBAAoB,IAAI,IAAI;IAanC,QAAQ,IAAI,IAAI;IAIhB,eAAe,IAAI,IAAI;IAMvB,OAAO,CAAC,YAAY,CAAkB;IACtC,gBAAgB;IAShB,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,UAAU,CAAiB;IACnC,IAAoB,SAAS,IAAI,OAAO,CAEvC;IACD,IAAW,SAAS,CAAC,KAAK,EAAE,OAAO,EAQlC;IAEK,sBAAsB;IAItB,OAAO,CAAC,MAAM,EAAE,aAAa;IAsHnC,cAAc,CAAC,GAAG,EAAE,cAAc;IASlC,kBAAkB,CAAC,GAAG,EAAE,cAAc;;;;IAatC,eAAe,CAAC,IAAI,EAAE,cAAc;IAOpC,oBAAoB,CAAC,MAAM,qBAAiB,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS;IAyBvE,cAAc,CAAC,MAAM,qBAAiB,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,EAAE;IA4B9E,uBAAuB,CAAC,KAAK,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI;IAmDtD,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW;IAmB7D,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C3C,aAAa,EAAE,cAAc,EAAE,CAAM;IACrC,UAAU,EAAE,GAAG,EAAE,CAAM;IACjB,aAAa;cAwBV,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;yCA/0BpC,uBAAuB;2CAAvB,uBAAuB;CAg2BnC"}
@@ -0,0 +1,950 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Component, ViewChild, ElementRef, Output, EventEmitter, Input } from '@angular/core';
11
+ import { Metadata, RunView, EntityFieldTSType, LogError, CompositeKey, PotentialDuplicateRequest } from '@memberjunction/core';
12
+ import { ViewInfo } from '@memberjunction/core-entities';
13
+ import { GridComponent } from "@progress/kendo-angular-grid";
14
+ import { Keys } from '@progress/kendo-angular-common';
15
+ import { Subject } from 'rxjs';
16
+ import { ExcelExportComponent } from '@progress/kendo-angular-excel-export';
17
+ import { MJEventType, MJGlobal } from '@memberjunction/global';
18
+ import { TextAreaComponent } from '@progress/kendo-angular-inputs';
19
+ import * as i0 from "@angular/core";
20
+ import * as i1 from "@angular/forms";
21
+ import * as i2 from "@angular/router";
22
+ import * as i3 from "@angular/common";
23
+ import * as i4 from "@progress/kendo-angular-grid";
24
+ import * as i5 from "@progress/kendo-angular-excel-export";
25
+ import * as i6 from "@progress/kendo-angular-buttons";
26
+ import * as i7 from "@memberjunction/ng-container-directives";
27
+ const _c0 = ["kendoGrid"];
28
+ const _c1 = ["excelExport"];
29
+ const _c2 = ["recordCompareRef"];
30
+ const _c3 = ["analysisQuestion"];
31
+ const _c4 = ["analysisResults"];
32
+ const _c5 = ["compareDialogContainer"];
33
+ function ListDetailGridComponent_ng_template_3_Template(rf, ctx) { if (rf & 1) {
34
+ const _r7 = i0.ɵɵgetCurrentView();
35
+ i0.ɵɵelementStart(0, "button", 9);
36
+ i0.ɵɵlistener("click", function ListDetailGridComponent_ng_template_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r6 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r6.doExcelExport()); });
37
+ i0.ɵɵelement(1, "span", 10);
38
+ i0.ɵɵtext(2, " Export to Excel ");
39
+ i0.ɵɵelementEnd();
40
+ } }
41
+ const _c6 = () => ({ "text-align": "center", "vertical-align": "center" });
42
+ const _c7 = () => ({ "font-weight": "bold", "background-color": "white" });
43
+ function ListDetailGridComponent_kendo_grid_checkbox_column_4_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelement(0, "kendo-grid-checkbox-column", 11);
45
+ } if (rf & 2) {
46
+ i0.ɵɵstyleMap(i0.ɵɵpureFunction0(4, _c6));
47
+ i0.ɵɵproperty("width", 50)("headerStyle", i0.ɵɵpureFunction0(5, _c7));
48
+ } }
49
+ function ListDetailGridComponent_kendo_grid_column_5_1_ng_template_0_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵtext(0);
51
+ i0.ɵɵpipe(1, "number");
52
+ i0.ɵɵpipe(2, "number");
53
+ i0.ɵɵelement(3, "br");
54
+ i0.ɵɵelementStart(4, "span", 15);
55
+ i0.ɵɵtext(5);
56
+ i0.ɵɵpipe(6, "number");
57
+ i0.ɵɵelementEnd();
58
+ } if (rf & 2) {
59
+ const ctx_r10 = i0.ɵɵnextContext(3);
60
+ i0.ɵɵtextInterpolate2(" ", i0.ɵɵpipeBind1(1, 3, ctx_r10.viewData.length), "", ctx_r10.totalRowCount > ctx_r10.viewData.length ? " of " + i0.ɵɵpipeBind1(2, 5, ctx_r10.totalRowCount) : " rows", "");
61
+ i0.ɵɵadvance(5);
62
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(6, 7, ctx_r10.viewExecutionTime, "1.2-2"), " seconds");
63
+ } }
64
+ function ListDetailGridComponent_kendo_grid_column_5_1_Template(rf, ctx) { if (rf & 1) {
65
+ i0.ɵɵtemplate(0, ListDetailGridComponent_kendo_grid_column_5_1_ng_template_0_Template, 7, 10, "ng-template", 14);
66
+ } }
67
+ function ListDetailGridComponent_kendo_grid_column_5_Template(rf, ctx) { if (rf & 1) {
68
+ i0.ɵɵelementStart(0, "kendo-grid-column", 12);
69
+ i0.ɵɵtemplate(1, ListDetailGridComponent_kendo_grid_column_5_1_Template, 1, 0, null, 13);
70
+ i0.ɵɵelementEnd();
71
+ } if (rf & 2) {
72
+ const item_r8 = ctx.$implicit;
73
+ const ctx_r3 = i0.ɵɵnextContext();
74
+ i0.ɵɵstyleMap(ctx_r3.GetColumnCellStyle(item_r8));
75
+ i0.ɵɵproperty("field", item_r8.Name)("title", ctx_r3.GetColumnTitle(item_r8))("width", item_r8.width ? item_r8.width : 100)("editable", item_r8.EntityField.AllowUpdateAPI)("editor", ctx_r3.getEditor(item_r8.EntityField))("headerStyle", i0.ɵɵpureFunction0(9, _c7));
76
+ i0.ɵɵadvance();
77
+ i0.ɵɵproperty("ngIf", item_r8 === ctx_r3.visibleColumns[0]);
78
+ } }
79
+ function ListDetailGridComponent_kendo_excelexport_column_8_Template(rf, ctx) { if (rf & 1) {
80
+ i0.ɵɵelement(0, "kendo-excelexport-column", 16);
81
+ } if (rf & 2) {
82
+ const exportCol_r11 = ctx.$implicit;
83
+ i0.ɵɵproperty("field", exportCol_r11.Name)("title", exportCol_r11.Name);
84
+ } }
85
+ export class ListDetailGridComponent {
86
+ get PendingRecords() {
87
+ return this._pendingRecords;
88
+ }
89
+ get ViewID() {
90
+ if (this.Params && this.Params.ViewID)
91
+ return this.Params.ViewID;
92
+ else
93
+ return 0;
94
+ }
95
+ StartEditMode() {
96
+ this.InEditMode = true;
97
+ }
98
+ EndEditMode() {
99
+ this.InEditMode = false;
100
+ this.editModeEnded.next();
101
+ }
102
+ EditingComplete() {
103
+ var _a, _b;
104
+ if (this.InEditMode) {
105
+ // 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
108
+ // we need to wait for edit mode to end before we can return true
109
+ return new Promise((resolve, reject) => {
110
+ const subscription = this.editModeEnded.subscribe(() => {
111
+ resolve(true);
112
+ subscription.unsubscribe();
113
+ });
114
+ });
115
+ }
116
+ else
117
+ return Promise.resolve(true); // not in edit mode, so editing is complete!
118
+ }
119
+ IsDynamicView() {
120
+ return !this._viewEntity; // if we have a viewEntity it is a stored view
121
+ }
122
+ pageChange(event) {
123
+ this.skip = event.skip;
124
+ this.virtualLoadData();
125
+ }
126
+ virtualLoadData() {
127
+ // check to see if we have already formatted the slice of the data we need right now
128
+ // we are storing the formattted data in the formattedData array and it has same set
129
+ // of indexes as the viewData array (raw unformatted data). When we first get viewData
130
+ // from the server we create an array of the same length as viewData, but have nulls in all of the
131
+ // indexes. As we format each row of viewData we store the formatted row in the same index
132
+ // in the formattedData array. So if we have already formatted the data we need for the current
133
+ // page, we just use that data, otherwise we format the data we need for the current page
134
+ try {
135
+ // check to see if we have already formatted the data we need for the current page
136
+ for (let i = this.skip; (i < (this.skip + this.pageSize)) && (i < this.viewData.length); i++) {
137
+ if (!this.formattedData[i]) {
138
+ // we have not formatted this row yet, so format it
139
+ const r = this.viewColumns.map((c) => {
140
+ if (c && c.EntityField && this.viewData[i] && this.viewData[i][c.EntityField.Name]) {
141
+ if (!c.hidden && c.EntityField.Name !== 'ID') {
142
+ const ef = c.EntityField;
143
+ let formattedValue = null;
144
+ if (c.EntityField.TSType === EntityFieldTSType.Boolean) {
145
+ formattedValue = this.viewData[i][c.EntityField.Name] ? '✓' : ''; // show a check mark if true, nothing if false
146
+ }
147
+ else {
148
+ formattedValue = ef.FormatValue(this.viewData[i][c.EntityField.Name], 0, undefined, 300);
149
+ }
150
+ return { field: c.EntityField.Name, value: formattedValue };
151
+ }
152
+ else
153
+ return { field: c.EntityField.Name, value: this.viewData[i][c.EntityField.Name] }; // hidden column, so just return the value, don't bother formatting
154
+ }
155
+ else
156
+ return { field: c.Name, value: null };
157
+ });
158
+ // now r is an array of {field: string, value: any} objects, so we need to convert it to an object
159
+ // with the field names as the keys and the values as the values
160
+ const row = {};
161
+ for (let j = 0; j < r.length; j++) {
162
+ if (r[j] && r[j].field && r[j].field.length > 0)
163
+ row[r[j].field] = r[j].value;
164
+ }
165
+ this.formattedData[i] = row;
166
+ }
167
+ }
168
+ // now that we have made sure current page of data is formatted, we can return it
169
+ this.gridView = {
170
+ data: this.formattedData.slice(this.skip, this.skip + this.pageSize),
171
+ total: this.viewData.length,
172
+ };
173
+ }
174
+ catch (e) {
175
+ LogError(e);
176
+ }
177
+ }
178
+ constructor(formBuilder, router, renderer) {
179
+ this.formBuilder = formBuilder;
180
+ this.router = router;
181
+ 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
+ }
234
+ SaveView() {
235
+ // debounced outer function...
236
+ clearTimeout(this._saveTimeout);
237
+ this._saveTimeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
238
+ // when we actually call inner save view we do await
239
+ yield this.innerSaveView();
240
+ }), 5000); // 5 seconds delay
241
+ }
242
+ ;
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);
271
+ }
272
+ }
273
+ }
274
+ });
275
+ }
276
+ CreateSimpleNotification(message, style, duration) {
277
+ const data = {
278
+ message: message,
279
+ style: style,
280
+ DisplayDuration: duration
281
+ };
282
+ MJGlobal.Instance.RaiseEvent({
283
+ component: this,
284
+ event: MJEventType.DisplaySimpleNotificationRequest,
285
+ eventCode: "",
286
+ args: data
287
+ });
288
+ }
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
+ }
309
+ }
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
+ }
316
+ }
317
+ // make sure that _newGridState.columnSettings is set
318
+ this._newGridState.columnSettings = this.viewColumns;
319
+ this._viewDirty = true;
320
+ this.SaveView();
321
+ }
322
+ }
323
+ });
324
+ }
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();
346
+ });
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
+ }
368
+ }
369
+ 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
373
+ }
374
+ });
375
+ }
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 } });
399
+ }
400
+ }
401
+ });
402
+ }
403
+ createFormGroup(dataItem) {
404
+ const groupFields = {};
405
+ this.viewColumns.forEach((vc) => {
406
+ if (vc.EntityField.AllowUpdateAPI &&
407
+ vc.EntityField.IsVirtual === false &&
408
+ vc.EntityField.AllowUpdateInView)
409
+ groupFields[vc.Name] = dataItem[vc.Name];
410
+ });
411
+ return this.formBuilder.group(groupFields);
412
+ }
413
+ getEditor(ef) {
414
+ switch (ef.TSType) {
415
+ case EntityFieldTSType.Boolean:
416
+ return "boolean";
417
+ case EntityFieldTSType.Date:
418
+ return "date";
419
+ case EntityFieldTSType.Number:
420
+ return "numeric";
421
+ default:
422
+ return "text";
423
+ }
424
+ }
425
+ cellCloseHandler(args) {
426
+ return __awaiter(this, void 0, void 0, function* () {
427
+ try {
428
+ if (this._entityInfo && this.EditMode !== "None") {
429
+ const { formGroup, dataItem, column } = args;
430
+ if (!formGroup.valid) {
431
+ // prevent closing the edited cell if there are invalid values.
432
+ args.preventDefault();
433
+ }
434
+ else if (formGroup.dirty) {
435
+ if (args.originalEvent && args.originalEvent.keyCode === Keys.Escape)
436
+ return; // user hit escape, so don't save their changes
437
+ // update the data item with the new values - this drives UI refresh while we save the record...
438
+ Object.assign(dataItem, formGroup.value);
439
+ const md = new Metadata();
440
+ // JONATHAN - TO DO
441
+ // @JS-BC - PLEASE FIX
442
+ alert('Jonathan fix this code where pkey and below are using a SINGLE valued primary key, must support multi-valued keys everywhere - COMMENTED OUT BROKEN STUFF FOR YOU TO FIX');
443
+ // const pkey = this._entityInfo.PrimaryKey.Name;
444
+ let record;
445
+ let bSaved = false;
446
+ if (this.EditMode === "Save") {
447
+ let compositeKey = new CompositeKey();
448
+ compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, dataItem);
449
+ record = yield md.GetEntityObject(this._entityInfo.Name);
450
+ yield record.InnerLoad(compositeKey);
451
+ record.SetMany(formGroup.value);
452
+ bSaved = yield record.Save();
453
+ // if (!bSaved)
454
+ // this.CreateSimpleNotification("Error saving record: " + record.Get(pkey), 'error', 5000)
455
+ }
456
+ else {
457
+ // JONATHAN - FIX THIS HERE TOO - SAME ISSUE AS ABOVE
458
+ // record = this._pendingRecords.find((r: GridPendingRecordItem) => r.record.Get(pkey) === dataItem[pkey])?.record;
459
+ if (!record) { // haven't edited this one before
460
+ record = yield md.GetEntityObject(this._viewEntity.Get('Entity'));
461
+ let compositeKey = new CompositeKey();
462
+ compositeKey.LoadFromEntityInfoAndRecord(this._entityInfo, dataItem);
463
+ yield record.InnerLoad(compositeKey);
464
+ this._pendingRecords.push({ record,
465
+ row: args.rowIndex,
466
+ dataItem }); // don't save - put the changed record on a queue for saving later by our container
467
+ }
468
+ // now, based on the column that we're in, update the record with the new value
469
+ record.Set(column.field, formGroup.value[column.field]);
470
+ // if a boolean value, modify what is in the grid so it is formatted properly
471
+ if (column.field && column.field.length > 0) {
472
+ const ef = this._entityInfo.Fields.find(f => f.Name === column.field);
473
+ if (ef && ef.TSType === EntityFieldTSType.Boolean) {
474
+ dataItem[column.field] = record.Get(column.field) ? '✓' : '';
475
+ }
476
+ }
477
+ }
478
+ this.rowEdited.emit({
479
+ record: record,
480
+ row: args.rowIndex,
481
+ saved: bSaved
482
+ });
483
+ }
484
+ }
485
+ }
486
+ catch (e) {
487
+ console.error(e);
488
+ }
489
+ finally {
490
+ this.EndEditMode();
491
+ }
492
+ });
493
+ }
494
+ // this handles reverting pending cahnges to records WITHIN the grid, not the user view settings, unrelated to that.
495
+ RevertPendingChanges() {
496
+ if (this._pendingRecords && this._pendingRecords.length > 0) {
497
+ this._pendingRecords.forEach((r) => {
498
+ r.record.Revert();
499
+ Object.assign(r.dataItem, r.record.GetAll()); // copy the original values back to the data Item which gets the grid to display the old values again...
500
+ });
501
+ this._pendingRecords = [];
502
+ if (this.Params)
503
+ this.Refresh(this.Params);
504
+ }
505
+ }
506
+ ngOnInit() {
507
+ }
508
+ ngAfterViewInit() {
509
+ //this.setGridHeight();
510
+ if (this.Params)
511
+ this.Refresh(this.Params);
512
+ }
513
+ moveDialogToBody() {
514
+ if (this._movedToBody)
515
+ return;
516
+ const dialogElement = this.compareDialogContainer.nativeElement;
517
+ this.renderer.appendChild(document.body, dialogElement);
518
+ this._movedToBody = true;
519
+ }
520
+ get AllowLoad() {
521
+ return this._allowLoad;
522
+ }
523
+ set AllowLoad(value) {
524
+ this._allowLoad = value;
525
+ if (value === true && this._deferLoadCount === 0) {
526
+ this._deferLoadCount++; // only do this one time
527
+ if (this.Params)
528
+ this.Refresh(this.Params);
529
+ return;
530
+ }
531
+ }
532
+ RefreshFromSavedParams() {
533
+ return __awaiter(this, void 0, void 0, function* () {
534
+ if (this.Params)
535
+ this.Refresh(this.Params);
536
+ });
537
+ }
538
+ Refresh(params) {
539
+ var _a, _b, _c;
540
+ return __awaiter(this, void 0, void 0, function* () {
541
+ this.Params = params;
542
+ if (this.AllowLoad === false) {
543
+ return;
544
+ }
545
+ if (params && (params.ViewEntity || params.ViewID || params.ViewName || (params.EntityName && params.ExtraFilter))) {
546
+ const startTime = new Date().getTime();
547
+ this.isLoading = true;
548
+ const md = new Metadata();
549
+ const rv = new RunView();
550
+ // 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
551
+ // this is done for performance purposes
552
+ if (params.ViewEntity) {
553
+ // 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
554
+ this._viewEntity = params.ViewEntity;
555
+ const e = md.Entities.find(x => { var _a; return x.ID === ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.EntityID); });
556
+ if (e)
557
+ this._entityInfo = e;
558
+ else
559
+ throw new Error("Unable to get entity info for view: " + ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.Name));
560
+ }
561
+ else if (!params.ViewEntity && (params.ViewID || params.ViewName)) {
562
+ // this is NOT a dyamic view as we got either the ViewID or ViewName, so we can get the ViewEntity
563
+ if (params.ViewID && params.ViewID > 0) {
564
+ this._viewEntity = (yield ViewInfo.GetViewEntity(params.ViewID));
565
+ }
566
+ else if (params.ViewName) {
567
+ this._viewEntity = (yield ViewInfo.GetViewEntityByName(params.ViewName));
568
+ }
569
+ params.ViewEntity = this._viewEntity;
570
+ const e = md.Entities.find(x => { var _a; return x.ID === ((_a = this._viewEntity) === null || _a === void 0 ? void 0 : _a.EntityID); });
571
+ if (e)
572
+ this._entityInfo = e;
573
+ else
574
+ throw new Error("Unable to get entity info for view: " + ((_b = this._viewEntity) === null || _b === void 0 ? void 0 : _b.Name));
575
+ }
576
+ else if (params.EntityName) {
577
+ // 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
578
+ const e = md.Entities.find(x => x.Name === params.EntityName);
579
+ if (e)
580
+ this._entityInfo = e;
581
+ }
582
+ else
583
+ throw new Error("Invalid configuration, we need to receive either a ViewEntity, ViewID, ViewName, or EntityName and ExtraFilter in order to run a view");
584
+ const rvResult = yield rv.RunView(params);
585
+ if (!rvResult.Success) {
586
+ // it failed
587
+ this.CreateSimpleNotification("Error running view:\n\n" + rvResult.ErrorMessage, 'error', 5000);
588
+ }
589
+ else {
590
+ // it worked
591
+ this.viewData = rvResult.Results;
592
+ this.totalRowCount = rvResult.TotalRowCount;
593
+ this.formattedData = new Array(this.viewData.length);
594
+ let cols;
595
+ if (this._viewEntity)
596
+ cols = this._viewEntity.Columns;
597
+ else
598
+ cols = (_c = this._entityInfo) === null || _c === void 0 ? void 0 : _c.Fields.filter((f) => f.DefaultInView).map((f) => {
599
+ return {
600
+ ID: f.ID,
601
+ Name: f.Name,
602
+ DisplayName: f.DisplayName,
603
+ EntityField: f,
604
+ hidden: false,
605
+ orderIndex: f.Sequence,
606
+ width: f.DefaultColumnWidth ? f.DefaultColumnWidth : 100,
607
+ };
608
+ });
609
+ if (cols) {
610
+ this.viewColumns = cols;
611
+ const tempCols = cols.filter(x => x.hidden === false).sort((a, b) => {
612
+ const aOrder = a.orderIndex != null ? a.orderIndex : 9999;
613
+ const bOrder = b.orderIndex != null ? b.orderIndex : 9999;
614
+ return aOrder - bOrder;
615
+ });
616
+ this.visibleColumns = tempCols;
617
+ }
618
+ // sorting setup
619
+ if (this._viewEntity) {
620
+ const temp = this._viewEntity.ViewSortInfo;
621
+ const kendoSortSettings = temp.map((s) => {
622
+ let dir;
623
+ if (typeof s.direction === 'string')
624
+ dir = s.direction.trim().toLowerCase();
625
+ else if (typeof s.direction === 'number' && s.direction === 1)
626
+ dir = 'asc';
627
+ else if (typeof s.direction === 'number' && s.direction === 2)
628
+ dir = 'desc';
629
+ else
630
+ dir = '';
631
+ return { field: s.field, dir: dir };
632
+ });
633
+ this.sortSettings = kendoSortSettings;
634
+ }
635
+ this.skip = 0;
636
+ this.virtualLoadData();
637
+ }
638
+ this.viewExecutionTime = (new Date().getTime() - startTime) / 1000; // in seconds
639
+ this.isLoading = false;
640
+ }
641
+ else {
642
+ LogError("Refresh(params) must have ViewID or ViewName or (EntityName and ExtraFilter)");
643
+ }
644
+ });
645
+ }
646
+ GetColumnTitle(col) {
647
+ if (col.DisplayName)
648
+ return col.DisplayName; // use view's display name first if it exists
649
+ else if (col.EntityField.DisplayName)
650
+ return col.EntityField.DisplayName; // then use entity display name, if that exist
651
+ else
652
+ return col.Name; // otherwise just use the column name
653
+ }
654
+ GetColumnCellStyle(col) {
655
+ switch (col.EntityField.Type.trim().toLowerCase()) {
656
+ case "money":
657
+ case 'decimal':
658
+ case 'real':
659
+ case 'float':
660
+ case 'int':
661
+ return { 'text-align': 'right', 'vertical-align': 'top' }; // right align numbers,
662
+ default:
663
+ return { 'text-align': 'left', 'vertical-align': 'top' }; // left align everything else
664
+ }
665
+ }
666
+ selectionChange(args) {
667
+ // update recordsToCompare based on the this.selectedKeys property that is bound
668
+ // selectedKeys is an array of indexes in the this.viewData, and we need to make our
669
+ // this.recordsToCompare an array of records from this.viewData so just map() the selectedKeys for this
670
+ this.recordsToCompare = this.selectedKeys.map((i) => this.viewData[i]);
671
+ }
672
+ enableMergeOrCompare(cancel = false, type) {
673
+ if (!cancel && this.recordsToCompare.length >= 2) {
674
+ // this scenario occurs when we've already started the merge/compare and the user has selected records, then clicked the merge/compare button again
675
+ this.isCompareDialogOpened = true;
676
+ this.moveDialogToBody();
677
+ }
678
+ else if (cancel) {
679
+ // the user clicked cancel in our toolbar
680
+ if (type === 'merge')
681
+ this.mergeMode = false;
682
+ else
683
+ this.compareMode = false;
684
+ this.selectedKeys = [];
685
+ this.recordsToCompare = [];
686
+ }
687
+ else {
688
+ // just turning on merge mode from the merge/compare button, so just turn it on and let the user select records
689
+ if (type === 'merge')
690
+ this.mergeMode = true;
691
+ else
692
+ this.compareMode = true;
693
+ }
694
+ }
695
+ enableCheckbox(cancel = false, type) {
696
+ if (!cancel && this.recordsToCompare.length >= 2) {
697
+ // this scenario occurs when we've already started the merge/compare/duplicate and the user has selected records, then clicked the merge/compare button again
698
+ this.isCompareDialogOpened = true;
699
+ this.moveDialogToBody();
700
+ }
701
+ else if (cancel) {
702
+ // the user clicked cancel in our toolbar
703
+ this.mergeMode = false;
704
+ this.compareMode = false;
705
+ this.duplicateMode = false;
706
+ this.selectedKeys = [];
707
+ this.recordsToCompare = [];
708
+ }
709
+ else {
710
+ // just turning on the checkbox from the merge/compare/duplicate button, so just turn it on and let the user select records
711
+ if (type === 'merge') {
712
+ this.mergeMode = true;
713
+ }
714
+ else if (type === 'compare') {
715
+ this.compareMode = true;
716
+ }
717
+ else if (type === 'duplicate') {
718
+ this.duplicateMode = true;
719
+ }
720
+ }
721
+ }
722
+ closeConfirmMergeDialog(event) {
723
+ return __awaiter(this, void 0, void 0, function* () {
724
+ if (event === 'yes') {
725
+ if (this._entityInfo && this.recordCompareComponent) {
726
+ const md = new Metadata();
727
+ const pkeys = this._entityInfo.PrimaryKeys;
728
+ const result = yield md.MergeRecords({
729
+ EntityName: this._entityInfo.Name,
730
+ RecordsToMerge: this.recordsToCompare.map((r) => {
731
+ return r.PrimaryKey;
732
+ }).filter((compositeKey) => {
733
+ if (!this.recordCompareComponent) {
734
+ return false;
735
+ }
736
+ return this.recordCompareComponent.selectedRecordCompositeKey.Equals(compositeKey);
737
+ }),
738
+ SurvivingRecordCompositeKey: this.recordCompareComponent.selectedRecordCompositeKey,
739
+ FieldMap: this.recordCompareComponent.fieldMap.map((fm) => {
740
+ return {
741
+ FieldName: fm.fieldName,
742
+ Value: fm.value
743
+ };
744
+ })
745
+ });
746
+ if (result.Success) {
747
+ // merge was successful, so refresh the grid
748
+ this.selectedKeys = [];
749
+ this.recordsToCompare = [];
750
+ this.mergeMode = false;
751
+ this.compareMode = false;
752
+ // close the dialogs
753
+ this.isCompareDialogOpened = false;
754
+ this.isConfirmDialogOpen = false;
755
+ // refresh the grid
756
+ this.Refresh(this.Params);
757
+ }
758
+ else {
759
+ // the merge failed, so show an error message
760
+ this.isConfirmDialogOpen = false;
761
+ this.CreateSimpleNotification("Error merging records: " + result.OverallStatus, 'error', 5000);
762
+ }
763
+ }
764
+ }
765
+ else {
766
+ this.isConfirmDialogOpen = false;
767
+ // close the dialog and let the user continue to work on the merge, so don't close the compare dialog
768
+ }
769
+ });
770
+ }
771
+ closeCompareDialog(event) {
772
+ return __awaiter(this, void 0, void 0, function* () {
773
+ console.log(event);
774
+ switch (event) {
775
+ case 'merge':
776
+ // user has requested to merge the records and retain the selected record from the compare records component, so run the merge
777
+ // first, confirm with the user to make 100% sure they want to do this as it is irreversible
778
+ this.isConfirmDialogOpen = true;
779
+ break;
780
+ default: // close and cancel
781
+ this.selectedKeys = [];
782
+ this.recordsToCompare = [];
783
+ this.mergeMode = false;
784
+ this.compareMode = false;
785
+ this.duplicateMode = false;
786
+ this.isCompareDialogOpened = false;
787
+ break;
788
+ }
789
+ });
790
+ }
791
+ findDuplicateRecords() {
792
+ var _a;
793
+ return __awaiter(this, void 0, void 0, function* () {
794
+ if (!this._entityInfo) {
795
+ console.error("Entity Info is not available");
796
+ this.closeCompareDialog('duplicate');
797
+ return;
798
+ }
799
+ const md = new Metadata();
800
+ const list = yield md.GetEntityObject('Lists');
801
+ list.NewRecord();
802
+ list.Name = `Potential Duplicate Run`;
803
+ list.Description = `Potential Duplicate Run for ${this._entityInfo.Name} Entity`;
804
+ list.EntityID = this._entityInfo.ID;
805
+ list.UserID = md.CurrentUser.ID;
806
+ const saveResult = yield list.Save();
807
+ if (!saveResult) {
808
+ console.error(`Failed to save list for Potential Duplicate Run`);
809
+ return;
810
+ }
811
+ let params = new PotentialDuplicateRequest();
812
+ params.EntityID = (_a = this._entityInfo) === null || _a === void 0 ? void 0 : _a.ID;
813
+ params.ListID = list.ID;
814
+ params.RecordIDs = [];
815
+ for (const index of this.selectedKeys) {
816
+ const viewData = this.viewData[index];
817
+ const idField = viewData.ID;
818
+ const listDetail = yield md.GetEntityObject('List Details');
819
+ listDetail.NewRecord();
820
+ listDetail.ListID = list.ID;
821
+ listDetail.RecordID = idField.toString();
822
+ yield listDetail.Save();
823
+ }
824
+ this.closeCompareDialog('duplicate');
825
+ this.CreateSimpleNotification("Working on finding duplicates, will notify you when it is complete...", 'info', 2000);
826
+ let response = yield md.GetRecordDuplicates(params, md.CurrentUser);
827
+ console.log(response);
828
+ });
829
+ }
830
+ doExcelExport() {
831
+ return __awaiter(this, void 0, void 0, function* () {
832
+ if (this.kendoExcelExport === null)
833
+ throw new Error("kendoExcelExport is null, cannot export data");
834
+ try {
835
+ this.CreateSimpleNotification("Working on the export, will notify you when it is complete...", 'info', 2000);
836
+ const data = yield this.getExportData();
837
+ // we have the data.
838
+ const cols = this.viewColumns.filter((vc) => vc.hidden === false);
839
+ this.exportColumns = cols;
840
+ this.exportData = data;
841
+ // before we call the save, we need to let Angular do its thing that will result in the kendoExcelExport component binding properly to
842
+ // the exportColumns and exportData arrays. So we wait for the next tick before we call save()
843
+ setTimeout(() => {
844
+ this.kendoExcelExport.save();
845
+ this.CreateSimpleNotification("Excel Export Complete", 'success', 2000);
846
+ }, 100);
847
+ }
848
+ catch (e) {
849
+ this.CreateSimpleNotification("Error exporting data", 'error', 5000);
850
+ LogError(e);
851
+ }
852
+ });
853
+ }
854
+ getExportData() {
855
+ return __awaiter(this, void 0, void 0, function* () {
856
+ // Get the data for the ENTIRE view, not just the current page
857
+ const md = new Metadata();
858
+ const rv = new RunView();
859
+ 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}` });
860
+ const result = yield rv.RunView(p);
861
+ if (result && result.Success) {
862
+ return result.Results;
863
+ }
864
+ else
865
+ throw new Error("Unable to get export data");
866
+ });
867
+ }
868
+ }
869
+ ListDetailGridComponent.ɵfac = function ListDetailGridComponent_Factory(t) { return new (t || ListDetailGridComponent)(i0.ɵɵdirectiveInject(i1.FormBuilder), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i0.Renderer2)); };
870
+ ListDetailGridComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ListDetailGridComponent, selectors: [["mj-list-detail-grid"]], viewQuery: function ListDetailGridComponent_Query(rf, ctx) { if (rf & 1) {
871
+ i0.ɵɵviewQuery(_c0, 5, GridComponent);
872
+ i0.ɵɵviewQuery(_c0, 5, ElementRef);
873
+ i0.ɵɵviewQuery(_c1, 5, ExcelExportComponent);
874
+ i0.ɵɵviewQuery(_c2, 5);
875
+ i0.ɵɵviewQuery(_c3, 5, TextAreaComponent);
876
+ i0.ɵɵviewQuery(_c4, 5, ElementRef);
877
+ i0.ɵɵviewQuery(_c5, 5);
878
+ } if (rf & 2) {
879
+ let _t;
880
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElement = _t.first);
881
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoGridElementRef = _t.first);
882
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.kendoExcelExport = _t.first);
883
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.recordCompareComponent = _t.first);
884
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisQuestion = _t.first);
885
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.analysisResults = _t.first);
886
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.compareDialogContainer = _t.first);
887
+ } }, inputs: { Params: "Params", BottomMargin: "BottomMargin", InEditMode: "InEditMode", EditMode: "EditMode", AutoNavigate: "AutoNavigate", AllowLoad: "AllowLoad" }, outputs: { rowClicked: "rowClicked", rowEdited: "rowEdited" }, decls: 9, vars: 18, consts: [["mjFillContainer", "", 1, "list-detail-grid-wrap"], ["mjFillContainer", "", "scrollable", "virtual", "kendoGridSelectBy", "", 3, "resizable", "data", "skip", "pageSize", "rowHeight", "loading", "height", "sortable", "sort", "reorderable", "selectable", "selectedKeys", "pageChange", "selectedKeysChange", "cellClick", "cellClose", "columnReorder", "columnResize", "selectionChange", "sortChange"], ["kendoGrid", ""], ["kendoGridToolbarTemplate", ""], [3, "width", "headerStyle", "style", 4, "ngIf"], [3, "field", "title", "width", "editable", "editor", "headerStyle", "style", 4, "ngFor", "ngForOf"], [3, "data", "fileName"], ["excelExport", ""], [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) {
888
+ i0.ɵɵelementStart(0, "div", 0)(1, "kendo-grid", 1, 2);
889
+ i0.ɵɵlistener("pageChange", function ListDetailGridComponent_Template_kendo_grid_pageChange_1_listener($event) { return ctx.pageChange($event); });
890
+ i0.ɵɵtwoWayListener("selectedKeysChange", function ListDetailGridComponent_Template_kendo_grid_selectedKeysChange_1_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.selectedKeys, $event) || (ctx.selectedKeys = $event); return $event; });
891
+ i0.ɵɵlistener("cellClick", function ListDetailGridComponent_Template_kendo_grid_cellClick_1_listener($event) { return ctx.cellClickHandler($event); })("cellClose", function ListDetailGridComponent_Template_kendo_grid_cellClose_1_listener($event) { return ctx.cellCloseHandler($event); })("columnReorder", function ListDetailGridComponent_Template_kendo_grid_columnReorder_1_listener($event) { return ctx.columnReorder($event); })("columnResize", function ListDetailGridComponent_Template_kendo_grid_columnResize_1_listener($event) { return ctx.columnResize($event); })("selectionChange", function ListDetailGridComponent_Template_kendo_grid_selectionChange_1_listener($event) { return ctx.selectionChange($event); })("sortChange", function ListDetailGridComponent_Template_kendo_grid_sortChange_1_listener($event) { return ctx.sortChanged($event); });
892
+ i0.ɵɵtemplate(3, ListDetailGridComponent_ng_template_3_Template, 3, 0, "ng-template", 3)(4, ListDetailGridComponent_kendo_grid_checkbox_column_4_Template, 1, 6, "kendo-grid-checkbox-column", 4)(5, ListDetailGridComponent_kendo_grid_column_5_Template, 2, 10, "kendo-grid-column", 5);
893
+ i0.ɵɵelementStart(6, "kendo-excelexport", 6, 7);
894
+ i0.ɵɵtemplate(8, ListDetailGridComponent_kendo_excelexport_column_8_Template, 1, 2, "kendo-excelexport-column", 8);
895
+ i0.ɵɵelementEnd()()();
896
+ } if (rf & 2) {
897
+ i0.ɵɵadvance();
898
+ 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);
899
+ i0.ɵɵtwoWayProperty("selectedKeys", ctx.selectedKeys);
900
+ i0.ɵɵadvance(3);
901
+ i0.ɵɵproperty("ngIf", ctx.compareMode || ctx.mergeMode || ctx.duplicateMode);
902
+ i0.ɵɵadvance();
903
+ i0.ɵɵproperty("ngForOf", ctx.visibleColumns);
904
+ i0.ɵɵadvance();
905
+ i0.ɵɵproperty("data", ctx.exportData)("fileName", (ctx._viewEntity ? ctx._viewEntity.Get("Name") : ctx._entityInfo == null ? null : ctx._entityInfo.Name) + ".xlsx");
906
+ i0.ɵɵadvance(2);
907
+ i0.ɵɵproperty("ngForOf", ctx.exportColumns);
908
+ } }, 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}"] });
909
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListDetailGridComponent, [{
910
+ type: Component,
911
+ 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} "] }]
912
+ }], () => [{ type: i1.FormBuilder }, { type: i2.Router }, { type: i0.Renderer2 }], { Params: [{
913
+ type: Input
914
+ }], BottomMargin: [{
915
+ type: Input
916
+ }], InEditMode: [{
917
+ type: Input
918
+ }], EditMode: [{
919
+ type: Input
920
+ }], AutoNavigate: [{
921
+ type: Input
922
+ }], rowClicked: [{
923
+ type: Output
924
+ }], rowEdited: [{
925
+ type: Output
926
+ }], kendoGridElement: [{
927
+ type: ViewChild,
928
+ args: ['kendoGrid', { read: GridComponent }]
929
+ }], kendoGridElementRef: [{
930
+ type: ViewChild,
931
+ args: ['kendoGrid', { read: ElementRef }]
932
+ }], kendoExcelExport: [{
933
+ type: ViewChild,
934
+ args: ['excelExport', { read: ExcelExportComponent }]
935
+ }], recordCompareComponent: [{
936
+ type: ViewChild,
937
+ args: ['recordCompareRef', { static: false }]
938
+ }], analysisQuestion: [{
939
+ type: ViewChild,
940
+ args: ['analysisQuestion', { read: TextAreaComponent }]
941
+ }], analysisResults: [{
942
+ type: ViewChild,
943
+ args: ['analysisResults', { read: ElementRef }]
944
+ }], compareDialogContainer: [{
945
+ type: ViewChild,
946
+ args: ['compareDialogContainer']
947
+ }], AllowLoad: [{
948
+ type: Input
949
+ }] }); })();
950
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ListDetailGridComponent, { className: "ListDetailGridComponent", filePath: "src/lib/ng-list-detail-grid.component.ts", lineNumber: 43 }); })();
@@ -0,0 +1,19 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./lib/ng-list-detail-grid.component";
3
+ import * as i2 from "@angular/common";
4
+ import * as i3 from "@angular/forms";
5
+ import * as i4 from "@angular/router";
6
+ import * as i5 from "@progress/kendo-angular-grid";
7
+ import * as i6 from "@progress/kendo-angular-dialog";
8
+ import * as i7 from "@progress/kendo-angular-excel-export";
9
+ import * as i8 from "@progress/kendo-angular-buttons";
10
+ import * as i9 from "@memberjunction/ng-compare-records";
11
+ import * as i10 from "@memberjunction/ng-container-directives";
12
+ import * as i11 from "@progress/kendo-angular-layout";
13
+ import * as i12 from "@progress/kendo-angular-inputs";
14
+ export declare class ListDetailGridModule {
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<ListDetailGridModule, never>;
16
+ static ɵmod: i0.ɵɵNgModuleDeclaration<ListDetailGridModule, [typeof i1.ListDetailGridComponent], [typeof i2.CommonModule, typeof i3.FormsModule, typeof i3.ReactiveFormsModule, typeof i4.RouterModule, typeof i5.GridModule, typeof i6.DialogsModule, typeof i7.ExcelExportModule, typeof i8.ButtonsModule, typeof i9.CompareRecordsModule, typeof i10.ContainerDirectivesModule, typeof i11.LayoutModule, typeof i12.InputsModule], [typeof i1.ListDetailGridComponent]>;
17
+ static ɵinj: i0.ɵɵInjectorDeclaration<ListDetailGridModule>;
18
+ }
19
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAkBA,qBAsBa,oBAAoB;yCAApB,oBAAoB;0CAApB,oBAAoB;0CAApB,oBAAoB;CAAI"}
package/dist/module.js ADDED
@@ -0,0 +1,68 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4
+ import { RouterModule } from '@angular/router';
5
+ // Kendo UI Angular imports
6
+ import { GridModule } from '@progress/kendo-angular-grid';
7
+ import { ExcelExportModule } from '@progress/kendo-angular-excel-export';
8
+ import { DialogsModule } from "@progress/kendo-angular-dialog";
9
+ import { ButtonsModule } from '@progress/kendo-angular-buttons';
10
+ import { LayoutModule } from '@progress/kendo-angular-layout';
11
+ import { InputsModule } from '@progress/kendo-angular-inputs';
12
+ import { CompareRecordsModule } from '@memberjunction/ng-compare-records';
13
+ import { ContainerDirectivesModule } from '@memberjunction/ng-container-directives';
14
+ import { ListDetailGridComponent } from './lib/ng-list-detail-grid.component';
15
+ import * as i0 from "@angular/core";
16
+ export class ListDetailGridModule {
17
+ }
18
+ ListDetailGridModule.ɵfac = function ListDetailGridModule_Factory(t) { return new (t || ListDetailGridModule)(); };
19
+ ListDetailGridModule.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: ListDetailGridModule });
20
+ ListDetailGridModule.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
21
+ FormsModule,
22
+ ReactiveFormsModule,
23
+ RouterModule,
24
+ GridModule,
25
+ DialogsModule,
26
+ ExcelExportModule,
27
+ ButtonsModule,
28
+ CompareRecordsModule,
29
+ ContainerDirectivesModule,
30
+ LayoutModule,
31
+ InputsModule] });
32
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListDetailGridModule, [{
33
+ type: NgModule,
34
+ args: [{
35
+ declarations: [
36
+ ListDetailGridComponent
37
+ ],
38
+ imports: [
39
+ CommonModule,
40
+ FormsModule,
41
+ ReactiveFormsModule,
42
+ RouterModule,
43
+ GridModule,
44
+ DialogsModule,
45
+ ExcelExportModule,
46
+ ButtonsModule,
47
+ CompareRecordsModule,
48
+ ContainerDirectivesModule,
49
+ LayoutModule,
50
+ InputsModule,
51
+ ],
52
+ exports: [
53
+ ListDetailGridComponent
54
+ ]
55
+ }]
56
+ }], null, null); })();
57
+ (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(ListDetailGridModule, { declarations: [ListDetailGridComponent], imports: [CommonModule,
58
+ FormsModule,
59
+ ReactiveFormsModule,
60
+ RouterModule,
61
+ GridModule,
62
+ DialogsModule,
63
+ ExcelExportModule,
64
+ ButtonsModule,
65
+ CompareRecordsModule,
66
+ ContainerDirectivesModule,
67
+ LayoutModule,
68
+ InputsModule], exports: [ListDetailGridComponent] }); })();
@@ -0,0 +1,3 @@
1
+ export * from './module';
2
+ export * from './lib/ng-list-detail-grid.component';
3
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,UAAU,CAAC;AACzB,cAAc,qCAAqC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Public API Surface of ng-user-view-grid
3
+ */
4
+ export * from './module';
5
+ export * from './lib/ng-list-detail-grid.component';
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@memberjunction/ng-list-detail-grid",
3
+ "version": "1.4.1",
4
+ "description": "MemberJunction: Angular Grid to display dynamic and saved List Details for any entity in MemberJunction.",
5
+ "main": "./dist/public-api.js",
6
+ "typings": "./dist/public-api.d.ts",
7
+ "files": [
8
+ "/dist"
9
+ ],
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "build": "ngc"
13
+ },
14
+ "keywords": [],
15
+ "author": "",
16
+ "license": "ISC",
17
+ "devDependencies": {
18
+ "@angular/compiler": "~17.2.2",
19
+ "@angular/compiler-cli": "~17.2.2"
20
+ },
21
+ "peerDependencies": {
22
+ "@angular/common": "~17.2.2",
23
+ "@angular/core": "~17.2.2",
24
+ "@angular/forms": "~17.2.2",
25
+ "@angular/router": "~17.2.2"
26
+ },
27
+ "dependencies": {
28
+ "@memberjunction/core-entities": "~1.4.1",
29
+ "@memberjunction/global": "~1.4.1",
30
+ "@memberjunction/core": "~1.4.1",
31
+ "@memberjunction/ng-shared": "~1.4.1",
32
+ "@memberjunction/ng-compare-records": "~1.4.1",
33
+ "@memberjunction/ng-container-directives": "~1.4.1",
34
+ "@progress/kendo-angular-grid": "~15.1.0",
35
+ "@progress/kendo-angular-layout": "~15.1.0",
36
+ "@progress/kendo-angular-inputs": "~15.1.0",
37
+ "@progress/kendo-angular-buttons": "~15.1.0",
38
+ "tslib": "^2.3.0"
39
+ },
40
+ "sideEffects": false
41
+ }