@memberjunction/ng-join-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,153 @@
1
+ import { AfterViewInit, ChangeDetectorRef } from '@angular/core';
2
+ import { BaseEntity, EntityInfo } from '@memberjunction/core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class JoinGridCell {
5
+ index: number;
6
+ RowForeignKeyValue: any;
7
+ ColumnForeignKeyValue: any;
8
+ data: BaseEntity | undefined;
9
+ }
10
+ export declare class JoinGridRow {
11
+ FirstColValue: any;
12
+ JoinExists: boolean;
13
+ RowForeignKeyValue: any;
14
+ ColumnData: JoinGridCell[];
15
+ }
16
+ export declare class JoinGridComponent implements AfterViewInit {
17
+ private cdr;
18
+ /**
19
+ * Required: the name of the entity that will be used for displaying data for rows. This means that each row in the RowsEntity will be shown as a row in the grid
20
+ * where the RowsEntityDisplayField will be used in the first column of the grid.
21
+ */
22
+ RowsEntityName: string;
23
+ /**
24
+ * Required: the field name in the RowsEntityName that will be shown in the first column in the grid
25
+ */
26
+ RowsEntityDisplayField: string;
27
+ /**
28
+ * Determines how the row data will be fetched.
29
+ * * When set to FullEntity, all rows in the specified RowEntityName will be used.
30
+ * * When set to ViewName, the RowsEntityViewName will be used to fetch the rows from a defined User View
31
+ * * When set to Array, the RowsEntityData array will be used to fetch the rows
32
+ */
33
+ RowsEntityDataSource: 'FullEntity' | 'ViewName' | 'Array';
34
+ /**
35
+ * For RowsEntityDataSource = FullEntity or ViewName, this is the extra filter to apply to the rows entity when fetching data. This is optional.
36
+ */
37
+ RowsExtraFilter?: string;
38
+ /**
39
+ * For RowsEntityDataSource = FullEntity or ViewName, this is the order by clause to apply to the rows entity when fetching data. This is optional.
40
+ */
41
+ RowsOrderBy?: string;
42
+ /**
43
+ * Used when RowsEntityDataSource = ViewName, this will be the name of the User View for the specified RowsEntity to run to get data
44
+ */
45
+ RowsEntityViewName?: string;
46
+ /**
47
+ * Required: provide an array of BaseEntity objects that will be used to display the rows in the grid.
48
+ */
49
+ RowsEntityArray?: BaseEntity[];
50
+ /**
51
+ * When set to Entity, the ColumnsEntity and related settings will be used to build the columns in the grid. When set to Fields, fields from the JoinEntity will be used to build the columns in the grid.
52
+ */
53
+ ColumnsMode: 'Entity' | 'Fields';
54
+ /**
55
+ * Required when ColumnsMode is set to Entity: the name of the entity that will be used for displaying data for columns. This means that each row in the ColumnsEntity will be shown as a column in the grid
56
+ */
57
+ ColumnsEntityName: string;
58
+ /**
59
+ * Required when ColumnsMode is set to Entity: the field name in the ColumnsEntityName that will be shown as columns in the grid
60
+ */
61
+ ColumnsEntityDisplayField: string;
62
+ /**
63
+ * Determines how the column data will be fetched.
64
+ * * When set to FullEntity, all columns in the specified ColumnsEntityName will be used.
65
+ * * When set to ViewName, the ColumnsEntityViewName will be used to fetch the columns from a defined User View
66
+ * * When set to Array, the ColumnsEntityArray array will be used to fetch the columns
67
+ */
68
+ ColumnsEntityDataSource: 'FullEntity' | 'ViewName' | 'Array';
69
+ /**
70
+ * For ColumnsEntityDataSource = FullEntity or ViewName, this is the extra filter to apply to the columns entity when fetching data. This is optional.
71
+ */
72
+ ColumnsExtraFilter?: string;
73
+ /**
74
+ * For ColumnsEntityDataSource = FullEntity or ViewName, this is the order by clause to apply to the columns entity when fetching data. This is optional.
75
+ */
76
+ ColumnsOrderBy?: string;
77
+ /**
78
+ * Used when ColumnsEntityDataSource = ViewName, this will be the name of the User View for the specified ColumnsEntity to run to get data
79
+ */
80
+ ColumnsEntityViewName?: string;
81
+ /**
82
+ * Required when ColumnsMode is set to Entity: provide an array of BaseEntity objects that will be used to display the columns in the grid.
83
+ */
84
+ ColumnsEntityArray?: BaseEntity[];
85
+ /**
86
+ * The name of the entity that will be used for joining the RowsEntity and ColumnsEntity. Or, in the case of ColumnsMode = Fields, there is no true "joining" happening but we are joining the data from the RowsEntity and JoinEntity together.
87
+ */
88
+ JoinEntityName: string;
89
+ /**
90
+ * The name of the foreign key field in the JoinEntity that will be used to link to the Primary Key field in the RowsEntity
91
+ */
92
+ JoinEntityRowForeignKey: string;
93
+ /**
94
+ * The name of the foreign key field in the JoinEntity that will be used to link to the Primary Key field in the ColumnsEntity
95
+ */
96
+ JoinEntityColumnForeignKey: string;
97
+ /**
98
+ * The names of the columns from the JoinEntity to display as columns in the grid. This is only used when ColumnsMode is set to Fields.
99
+ */
100
+ JoinEntityDisplayColumns?: string[];
101
+ /**
102
+ * When this property is set to JoinRecordExists the grid will operate as follows:
103
+ * * When a user checks the checkbox in the grid, a record will be created in the JoinEntity with the Row and Column foreign keys.
104
+ * * When a user unchecks the checkbox in the grid, the record in the JoinEntity will be deleted.
105
+ * In comparison, when the CheckBoxValueMode is set to ColumnValue, the grid will operate as follows:
106
+ * * When a user checks the checkbox in the grid, a value in the JoinEntity will be set to true in the CheckBoxValueField field.
107
+ * * When a user unchecks the checkbox in the grid, the value in the JoinEntity will be set to false in the CheckBoxValueField field.
108
+ */
109
+ CheckBoxValueMode: 'RecordExists' | 'ColumnValue';
110
+ /**
111
+ * Required when CheckBoxValueMode is set to ColumnValue: the name of the field in the JoinEntity that will be used to store the value of the checkbox.
112
+ */
113
+ CheckBoxValueField: string;
114
+ /**
115
+ * When the CheckBoxValueMode is set to RecordExists this means the grid will be adding and removing records from the JoinEntity. In some cases, entities require additional values
116
+ * beyond the foreign keys that are automatically set, in those cases, use this property to provide additional default values for the new records that are created.
117
+ */
118
+ NewRecordDefaultValues?: {
119
+ [key: string]: any;
120
+ };
121
+ ngAfterViewInit(): void;
122
+ constructor(cdr: ChangeDetectorRef);
123
+ _GridData: JoinGridRow[];
124
+ _IsLoading: boolean;
125
+ protected _rowsEntityInfo: EntityInfo | null;
126
+ protected _columnsEntityInfo: EntityInfo | null;
127
+ protected _columnsEntityData: BaseEntity[] | undefined;
128
+ protected _rowsEntityData: BaseEntity[] | undefined;
129
+ /**
130
+ * Saves all of the changes made in the grid. This includes adding new records, updating existing records, and deleting records.
131
+ */
132
+ Save(): Promise<boolean>;
133
+ /**
134
+ * Cancels any changes and reverts to the prior state of the grid that reflects the last saved state.
135
+ */
136
+ CancelEdit(): Promise<void>;
137
+ get NumDirtyRecords(): number;
138
+ IsRecordReallyDirty(row: JoinGridRow): boolean;
139
+ IsCellReallyDirty(cell: JoinGridCell): boolean;
140
+ /**
141
+ * This method is called automatically when the component is first loaded. Call the method anytime if you want to refresh the grid.
142
+ */
143
+ Refresh(): Promise<void>;
144
+ protected PopulateRowsAndColsData(): Promise<void>;
145
+ protected RunColumnsOrRowsView(dataSource: 'FullEntity' | 'ViewName', entityName: string, viewName?: string, extraFilter?: string, orderBy?: string): Promise<BaseEntity[]>;
146
+ protected PopulateGridData(joinEntityData: BaseEntity[]): Promise<void>;
147
+ protected _pendingDeletes: BaseEntity[];
148
+ protected _pendingInserts: BaseEntity[];
149
+ _FlipRecord(event: MouseEvent, row: JoinGridRow, cell: JoinGridCell, stopPropagation?: boolean): Promise<void>;
150
+ _IsColumnChecked(cell: JoinGridCell): boolean;
151
+ static ɵfac: i0.ɵɵFactoryDeclaration<JoinGridComponent, never>;
152
+ static ɵcmp: i0.ɵɵComponentDeclaration<JoinGridComponent, "mj-join-grid", never, { "RowsEntityName": { "alias": "RowsEntityName"; "required": false; }; "RowsEntityDisplayField": { "alias": "RowsEntityDisplayField"; "required": false; }; "RowsEntityDataSource": { "alias": "RowsEntityDataSource"; "required": false; }; "RowsExtraFilter": { "alias": "RowsExtraFilter"; "required": false; }; "RowsOrderBy": { "alias": "RowsOrderBy"; "required": false; }; "RowsEntityViewName": { "alias": "RowsEntityViewName"; "required": false; }; "RowsEntityArray": { "alias": "RowsEntityArray"; "required": false; }; "ColumnsMode": { "alias": "ColumnsMode"; "required": false; }; "ColumnsEntityName": { "alias": "ColumnsEntityName"; "required": false; }; "ColumnsEntityDisplayField": { "alias": "ColumnsEntityDisplayField"; "required": false; }; "ColumnsEntityDataSource": { "alias": "ColumnsEntityDataSource"; "required": false; }; "ColumnsExtraFilter": { "alias": "ColumnsExtraFilter"; "required": false; }; "ColumnsOrderBy": { "alias": "ColumnsOrderBy"; "required": false; }; "ColumnsEntityViewName": { "alias": "ColumnsEntityViewName"; "required": false; }; "ColumnsEntityArray": { "alias": "ColumnsEntityArray"; "required": false; }; "JoinEntityName": { "alias": "JoinEntityName"; "required": false; }; "JoinEntityRowForeignKey": { "alias": "JoinEntityRowForeignKey"; "required": false; }; "JoinEntityColumnForeignKey": { "alias": "JoinEntityColumnForeignKey"; "required": false; }; "JoinEntityDisplayColumns": { "alias": "JoinEntityDisplayColumns"; "required": false; }; "CheckBoxValueMode": { "alias": "CheckBoxValueMode"; "required": false; }; "CheckBoxValueField": { "alias": "CheckBoxValueField"; "required": false; }; "NewRecordDefaultValues": { "alias": "NewRecordDefaultValues"; "required": false; }; }, {}, never, never, false, never>;
153
+ }
@@ -0,0 +1,483 @@
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, Input } from '@angular/core';
11
+ import { Metadata, RunView } from '@memberjunction/core';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/common";
14
+ import * as i2 from "@progress/kendo-angular-buttons";
15
+ import * as i3 from "@progress/kendo-angular-indicators";
16
+ import * as i4 from "@memberjunction/ng-container-directives";
17
+ function JoinGridComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
18
+ i0.ɵɵelementStart(0, "div");
19
+ i0.ɵɵelement(1, "kendo-loader");
20
+ i0.ɵɵelementEnd();
21
+ } }
22
+ function JoinGridComponent_Conditional_6_Conditional_5_For_1_Template(rf, ctx) { if (rf & 1) {
23
+ i0.ɵɵelementStart(0, "th");
24
+ i0.ɵɵtext(1);
25
+ i0.ɵɵelementEnd();
26
+ } if (rf & 2) {
27
+ const colRecord_r6 = ctx.$implicit;
28
+ const ctx_r5 = i0.ɵɵnextContext(3);
29
+ i0.ɵɵadvance();
30
+ i0.ɵɵtextInterpolate(colRecord_r6.Get(ctx_r5.ColumnsEntityDisplayField));
31
+ } }
32
+ function JoinGridComponent_Conditional_6_Conditional_5_Template(rf, ctx) { if (rf & 1) {
33
+ i0.ɵɵrepeaterCreate(0, JoinGridComponent_Conditional_6_Conditional_5_For_1_Template, 2, 1, "th", null, i0.ɵɵrepeaterTrackByIdentity);
34
+ } if (rf & 2) {
35
+ const ctx_r2 = i0.ɵɵnextContext(2);
36
+ i0.ɵɵrepeater(ctx_r2._columnsEntityData);
37
+ } }
38
+ function JoinGridComponent_Conditional_6_Conditional_6_For_1_Template(rf, ctx) { if (rf & 1) {
39
+ i0.ɵɵelementStart(0, "th");
40
+ i0.ɵɵtext(1);
41
+ i0.ɵɵelementEnd();
42
+ } if (rf & 2) {
43
+ const colName_r12 = ctx.$implicit;
44
+ i0.ɵɵadvance();
45
+ i0.ɵɵtextInterpolate(colName_r12);
46
+ } }
47
+ function JoinGridComponent_Conditional_6_Conditional_6_Template(rf, ctx) { if (rf & 1) {
48
+ i0.ɵɵrepeaterCreate(0, JoinGridComponent_Conditional_6_Conditional_6_For_1_Template, 2, 1, "th", null, i0.ɵɵrepeaterTrackByIdentity);
49
+ } if (rf & 2) {
50
+ const ctx_r3 = i0.ɵɵnextContext(2);
51
+ i0.ɵɵrepeater(ctx_r3.JoinEntityDisplayColumns);
52
+ } }
53
+ function JoinGridComponent_Conditional_6_For_9_Conditional_4_td_0_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵelementStart(0, "td");
55
+ i0.ɵɵelement(1, "input", 7);
56
+ i0.ɵɵelementEnd();
57
+ } }
58
+ function JoinGridComponent_Conditional_6_For_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
59
+ i0.ɵɵtemplate(0, JoinGridComponent_Conditional_6_For_9_Conditional_4_td_0_Template, 2, 0, "td", 6);
60
+ } if (rf & 2) {
61
+ const ctx_r22 = i0.ɵɵnextContext(3);
62
+ i0.ɵɵproperty("ngForOf", ctx_r22.JoinEntityDisplayColumns);
63
+ } }
64
+ function JoinGridComponent_Conditional_6_For_9_Conditional_5_For_1_Template(rf, ctx) { if (rf & 1) {
65
+ const _r34 = i0.ɵɵgetCurrentView();
66
+ i0.ɵɵelementStart(0, "td", 8);
67
+ i0.ɵɵlistener("click", function JoinGridComponent_Conditional_6_For_9_Conditional_5_For_1_Template_td_click_0_listener($event) { const restoredCtx = i0.ɵɵrestoreView(_r34); const cell_r27 = restoredCtx.$implicit; const row_r17 = i0.ɵɵnextContext(2).$implicit; const ctx_r32 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r32._FlipRecord($event, row_r17, cell_r27)); });
68
+ i0.ɵɵelementStart(1, "input", 9);
69
+ i0.ɵɵlistener("click", function JoinGridComponent_Conditional_6_For_9_Conditional_5_For_1_Template_input_click_1_listener($event) { const restoredCtx = i0.ɵɵrestoreView(_r34); const cell_r27 = restoredCtx.$implicit; const row_r17 = i0.ɵɵnextContext(2).$implicit; const ctx_r35 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r35._FlipRecord($event, row_r17, cell_r27, true)); });
70
+ i0.ɵɵelementEnd()();
71
+ } if (rf & 2) {
72
+ const cell_r27 = ctx.$implicit;
73
+ const ctx_r26 = i0.ɵɵnextContext(4);
74
+ i0.ɵɵproperty("ngClass", ctx_r26.IsCellReallyDirty(cell_r27) ? "dirty-cell" : "");
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵproperty("checked", ctx_r26._IsColumnChecked(cell_r27));
77
+ } }
78
+ function JoinGridComponent_Conditional_6_For_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
79
+ i0.ɵɵrepeaterCreate(0, JoinGridComponent_Conditional_6_For_9_Conditional_5_For_1_Template, 2, 2, "td", 4, i0.ɵɵrepeaterTrackByIdentity);
80
+ } if (rf & 2) {
81
+ const row_r17 = i0.ɵɵnextContext().$implicit;
82
+ i0.ɵɵrepeater(row_r17.ColumnData);
83
+ } }
84
+ function JoinGridComponent_Conditional_6_For_9_Template(rf, ctx) { if (rf & 1) {
85
+ i0.ɵɵelementStart(0, "tr", 4)(1, "td", 5)(2, "span");
86
+ i0.ɵɵtext(3);
87
+ i0.ɵɵelementEnd()();
88
+ i0.ɵɵtemplate(4, JoinGridComponent_Conditional_6_For_9_Conditional_4_Template, 1, 1, "td")(5, JoinGridComponent_Conditional_6_For_9_Conditional_5_Template, 2, 0);
89
+ i0.ɵɵelementEnd();
90
+ } if (rf & 2) {
91
+ const row_r17 = ctx.$implicit;
92
+ const ctx_r4 = i0.ɵɵnextContext(2);
93
+ i0.ɵɵproperty("ngClass", ctx_r4.IsRecordReallyDirty(row_r17) ? "dirty-row" : "");
94
+ i0.ɵɵadvance(3);
95
+ i0.ɵɵtextInterpolate(row_r17.FirstColValue);
96
+ i0.ɵɵadvance();
97
+ i0.ɵɵconditional(4, ctx_r4.ColumnsMode === "Fields" ? 4 : 5);
98
+ } }
99
+ function JoinGridComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
100
+ i0.ɵɵelementStart(0, "table", 3)(1, "thead")(2, "tr")(3, "th");
101
+ i0.ɵɵtext(4);
102
+ i0.ɵɵelementEnd();
103
+ i0.ɵɵtemplate(5, JoinGridComponent_Conditional_6_Conditional_5_Template, 2, 0)(6, JoinGridComponent_Conditional_6_Conditional_6_Template, 2, 0);
104
+ i0.ɵɵelementEnd()();
105
+ i0.ɵɵelementStart(7, "tbody");
106
+ i0.ɵɵrepeaterCreate(8, JoinGridComponent_Conditional_6_For_9_Template, 6, 3, "tr", 4, i0.ɵɵrepeaterTrackByIdentity);
107
+ i0.ɵɵelementEnd()();
108
+ } if (rf & 2) {
109
+ const ctx_r1 = i0.ɵɵnextContext();
110
+ i0.ɵɵadvance(4);
111
+ i0.ɵɵtextInterpolate(ctx_r1.RowsEntityName);
112
+ i0.ɵɵadvance();
113
+ i0.ɵɵconditional(5, ctx_r1.ColumnsMode === "Entity" ? 5 : 6);
114
+ i0.ɵɵadvance(3);
115
+ i0.ɵɵrepeater(ctx_r1._GridData);
116
+ } }
117
+ export class JoinGridCell {
118
+ }
119
+ export class JoinGridRow {
120
+ constructor() {
121
+ this.JoinExists = false;
122
+ this.ColumnData = [];
123
+ }
124
+ }
125
+ export class JoinGridComponent {
126
+ ngAfterViewInit() {
127
+ // load up the grid
128
+ this.Refresh();
129
+ }
130
+ constructor(cdr) {
131
+ this.cdr = cdr;
132
+ /**
133
+ * Determines how the row data will be fetched.
134
+ * * When set to FullEntity, all rows in the specified RowEntityName will be used.
135
+ * * When set to ViewName, the RowsEntityViewName will be used to fetch the rows from a defined User View
136
+ * * When set to Array, the RowsEntityData array will be used to fetch the rows
137
+ */
138
+ this.RowsEntityDataSource = 'FullEntity';
139
+ /**
140
+ * When set to Entity, the ColumnsEntity and related settings will be used to build the columns in the grid. When set to Fields, fields from the JoinEntity will be used to build the columns in the grid.
141
+ */
142
+ this.ColumnsMode = 'Entity';
143
+ /**
144
+ * Determines how the column data will be fetched.
145
+ * * When set to FullEntity, all columns in the specified ColumnsEntityName will be used.
146
+ * * When set to ViewName, the ColumnsEntityViewName will be used to fetch the columns from a defined User View
147
+ * * When set to Array, the ColumnsEntityArray array will be used to fetch the columns
148
+ */
149
+ this.ColumnsEntityDataSource = 'FullEntity';
150
+ /**
151
+ * When this property is set to JoinRecordExists the grid will operate as follows:
152
+ * * When a user checks the checkbox in the grid, a record will be created in the JoinEntity with the Row and Column foreign keys.
153
+ * * When a user unchecks the checkbox in the grid, the record in the JoinEntity will be deleted.
154
+ * In comparison, when the CheckBoxValueMode is set to ColumnValue, the grid will operate as follows:
155
+ * * When a user checks the checkbox in the grid, a value in the JoinEntity will be set to true in the CheckBoxValueField field.
156
+ * * When a user unchecks the checkbox in the grid, the value in the JoinEntity will be set to false in the CheckBoxValueField field.
157
+ */
158
+ this.CheckBoxValueMode = 'RecordExists';
159
+ /*The below members are public because the Angular template needs access to them, but by naming convention we prefix with an _ so that it is clear they are not to be used outside of the component */
160
+ this._GridData = [];
161
+ this._IsLoading = false;
162
+ /* protected internal members */
163
+ this._rowsEntityInfo = null;
164
+ this._columnsEntityInfo = null;
165
+ this._columnsEntityData = undefined;
166
+ this._rowsEntityData = undefined;
167
+ this._pendingDeletes = [];
168
+ this._pendingInserts = [];
169
+ }
170
+ /**
171
+ * Saves all of the changes made in the grid. This includes adding new records, updating existing records, and deleting records.
172
+ */
173
+ Save() {
174
+ return __awaiter(this, void 0, void 0, function* () {
175
+ // for each pending delete, we need to delete the record
176
+ // for each pending insert, we need to save the record
177
+ // do it all in one transaction
178
+ const md = new Metadata();
179
+ const tg = yield md.CreateTransactionGroup();
180
+ let validated = true;
181
+ const valErrors = [];
182
+ this._pendingDeletes.forEach(obj => {
183
+ obj.TransactionGroup = tg;
184
+ obj.Delete();
185
+ });
186
+ this._pendingInserts.forEach(obj => {
187
+ obj.TransactionGroup = tg;
188
+ const valResult = obj.Validate();
189
+ validated = validated && valResult.Success;
190
+ valErrors.push(valResult.Errors);
191
+ obj.Save();
192
+ });
193
+ if (validated) {
194
+ if (!(yield tg.Submit())) {
195
+ alert('Error saving changes');
196
+ return false;
197
+ }
198
+ else {
199
+ yield this.Refresh(); // refresh afterwards
200
+ return true;
201
+ }
202
+ }
203
+ else {
204
+ alert('Error validating changes, details in console');
205
+ console.log(valErrors);
206
+ return false;
207
+ }
208
+ });
209
+ }
210
+ /**
211
+ * Cancels any changes and reverts to the prior state of the grid that reflects the last saved state.
212
+ */
213
+ CancelEdit() {
214
+ return __awaiter(this, void 0, void 0, function* () {
215
+ // go through all of the pending deletes and remove them from the array
216
+ // and go through all of the pending inserts and remove them from the array
217
+ // before removing stuff from arrays we need to go back through all of hte grid cells and restore to original data
218
+ this._GridData.forEach(row => {
219
+ row.ColumnData.forEach(cell => {
220
+ // for each cell, if we have a data object, look for a match in the pending inserts array, that means it is a NEW record
221
+ if (cell.data) {
222
+ const match = this._pendingInserts.find(obj => obj.Get(this.JoinEntityColumnForeignKey) === cell.ColumnForeignKeyValue && obj.Get(this.JoinEntityRowForeignKey) === row.RowForeignKeyValue);
223
+ if (match) {
224
+ // means that the current cell is a new record, so we need to remove it
225
+ cell.data = undefined;
226
+ this._pendingInserts.splice(this._pendingInserts.indexOf(match), 1);
227
+ }
228
+ }
229
+ else {
230
+ // we need to check if a match exists in the pending deletes array, if so, we need to restore the data
231
+ const match = this._pendingDeletes.find(obj => obj.Get(this.JoinEntityColumnForeignKey) === cell.ColumnForeignKeyValue && obj.Get(this.JoinEntityRowForeignKey) === row.RowForeignKeyValue);
232
+ if (match) {
233
+ cell.data = match;
234
+ this._pendingDeletes.splice(this._pendingDeletes.indexOf(match), 1);
235
+ }
236
+ }
237
+ });
238
+ });
239
+ });
240
+ }
241
+ get NumDirtyRecords() {
242
+ return this._pendingDeletes.length + this._pendingInserts.length;
243
+ }
244
+ IsRecordReallyDirty(row) {
245
+ return false;
246
+ }
247
+ IsCellReallyDirty(cell) {
248
+ if (cell.data) {
249
+ // we have a record here, check if it is dirty or not as step 1
250
+ if (cell.data.Dirty)
251
+ return true;
252
+ }
253
+ else {
254
+ // we need to see if we previoulsy HAD a data element in the cell but we removed it and it is located in the pendingDeletes array
255
+ const record = this._pendingDeletes.find(obj => obj.Get(this.JoinEntityColumnForeignKey) === cell.ColumnForeignKeyValue &&
256
+ obj.Get(this.JoinEntityRowForeignKey) === cell.RowForeignKeyValue);
257
+ if (record)
258
+ return true; // found a pending delete, we're dirty
259
+ }
260
+ return false;
261
+ }
262
+ /**
263
+ * This method is called automatically when the component is first loaded. Call the method anytime if you want to refresh the grid.
264
+ */
265
+ Refresh() {
266
+ return __awaiter(this, void 0, void 0, function* () {
267
+ this._IsLoading = true; // turn on the loading spinner
268
+ this.cdr.detectChanges(); // let angular know we have changes
269
+ this._pendingDeletes = [];
270
+ this._pendingInserts = [];
271
+ // we are provided an array of Column and Row objects. We need to get the rows from the JoinEntity that link them up.
272
+ const md = new Metadata();
273
+ this._rowsEntityInfo = md.EntityByName(this.RowsEntityName);
274
+ this._columnsEntityInfo = md.EntityByName(this.ColumnsEntityName);
275
+ if (!this._rowsEntityInfo)
276
+ throw new Error('Invalid entity name provided for rows entity.');
277
+ if (!this._columnsEntityInfo)
278
+ throw new Error('Invalid entity name provided for columns entity.');
279
+ yield this.PopulateRowsAndColsData();
280
+ const rowQuotes = this._rowsEntityInfo.FirstPrimaryKey.NeedsQuotes ? "'" : "";
281
+ let filter = `${this.JoinEntityRowForeignKey} IN (${this._rowsEntityData.map(obj => `${rowQuotes}${obj.Get(this._rowsEntityInfo.FirstPrimaryKey.Name)}${rowQuotes}`).join(',')})`;
282
+ if (this.ColumnsMode === 'Entity') {
283
+ const colQuotes = this._columnsEntityInfo.FirstPrimaryKey.NeedsQuotes ? "'" : "";
284
+ filter += ` AND ${this.JoinEntityColumnForeignKey} IN (${this._columnsEntityData.map(obj => `${colQuotes}${obj.Get(this._columnsEntityInfo.FirstPrimaryKey.Name)}${colQuotes}`).join(',')})`;
285
+ }
286
+ const rv = new RunView();
287
+ const result = yield rv.RunView({
288
+ EntityName: this.JoinEntityName,
289
+ ExtraFilter: filter,
290
+ ResultType: 'entity_object'
291
+ });
292
+ if (result && result.Success) {
293
+ // we have the data, now we need to build the grid
294
+ this.PopulateGridData(result.Results);
295
+ }
296
+ this._IsLoading = false; // turn off the loading spinner
297
+ this.cdr.detectChanges(); // let Angular know we have changes
298
+ });
299
+ }
300
+ PopulateRowsAndColsData() {
301
+ return __awaiter(this, void 0, void 0, function* () {
302
+ const rv = new RunView();
303
+ if (this.ColumnsEntityDataSource === 'Array') {
304
+ this._columnsEntityData = this.ColumnsEntityArray;
305
+ }
306
+ else {
307
+ this._columnsEntityData = yield this.RunColumnsOrRowsView(this.ColumnsEntityDataSource, this.ColumnsEntityName, this.ColumnsEntityViewName, this.ColumnsExtraFilter, this.ColumnsOrderBy);
308
+ }
309
+ if (this.RowsEntityDataSource === 'Array') {
310
+ this._rowsEntityData = this.RowsEntityArray;
311
+ }
312
+ else {
313
+ this._rowsEntityData = yield this.RunColumnsOrRowsView(this.RowsEntityDataSource, this.RowsEntityName, this.RowsEntityViewName, this.RowsExtraFilter, this.RowsOrderBy);
314
+ }
315
+ });
316
+ }
317
+ RunColumnsOrRowsView(dataSource, entityName, viewName, extraFilter, orderBy) {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ const rv = new RunView();
320
+ const params = dataSource === 'FullEntity' ? { EntityName: entityName } : { ViewName: viewName };
321
+ if (extraFilter)
322
+ params.ExtraFilter = extraFilter;
323
+ if (orderBy)
324
+ params.OrderBy = orderBy;
325
+ params.ResultType = 'entity_object';
326
+ const data = yield rv.RunView(params);
327
+ if (data && data.Success) {
328
+ return data.Results;
329
+ }
330
+ else {
331
+ return [];
332
+ }
333
+ });
334
+ }
335
+ PopulateGridData(joinEntityData) {
336
+ return __awaiter(this, void 0, void 0, function* () {
337
+ // we have the data, now we need to build the grid
338
+ // we need to build the grid data
339
+ const gridData = [];
340
+ this._rowsEntityData.forEach(row => {
341
+ let rowData = {
342
+ FirstColValue: row.Get(this.RowsEntityDisplayField),
343
+ JoinExists: false,
344
+ RowForeignKeyValue: row.Get(this._rowsEntityInfo.FirstPrimaryKey.Name),
345
+ ColumnData: [] // start off with an empty array
346
+ };
347
+ // for the mode where we are using columns, do the following
348
+ if (this.ColumnsMode === 'Entity') {
349
+ for (let i = 0; i < this._columnsEntityData.length; i++) {
350
+ const column = this._columnsEntityData[i];
351
+ const join = joinEntityData.find(j => j.Get(this.JoinEntityRowForeignKey) === row.Get(this._rowsEntityInfo.FirstPrimaryKey.Name) &&
352
+ j.Get(this.JoinEntityColumnForeignKey) === column.Get(this._columnsEntityInfo.FirstPrimaryKey.Name));
353
+ rowData.ColumnData.push({
354
+ index: i,
355
+ ColumnForeignKeyValue: column.Get(this._columnsEntityInfo.FirstPrimaryKey.Name),
356
+ RowForeignKeyValue: rowData.RowForeignKeyValue,
357
+ data: join
358
+ });
359
+ }
360
+ }
361
+ else {
362
+ // we are display the values from the JoinEntity as columns from the JoinEntityDisplayColumns array
363
+ }
364
+ gridData.push(rowData);
365
+ });
366
+ this._GridData = gridData;
367
+ });
368
+ }
369
+ _FlipRecord(event, row, cell, stopPropagation = false) {
370
+ return __awaiter(this, void 0, void 0, function* () {
371
+ if (stopPropagation)
372
+ event.stopPropagation();
373
+ if (!cell)
374
+ throw new Error('cell is a required parameter');
375
+ if (cell.data) {
376
+ if (cell.data.IsSaved) {
377
+ // If this is a record that is saved, put into an array of pending deletes
378
+ this._pendingDeletes.push(cell.data);
379
+ }
380
+ else {
381
+ // we need to find the record in the pending inserts and remove it from that array
382
+ const index = this._pendingInserts.indexOf(cell.data);
383
+ if (index >= 0)
384
+ this._pendingInserts.splice(index, 1);
385
+ }
386
+ // Now take data off the item
387
+ cell.data = undefined;
388
+ }
389
+ else {
390
+ // We need to add the record, first see if the record is in the _pendingDeletes array
391
+ let record = this._pendingDeletes.find(obj => obj.Get(this.JoinEntityColumnForeignKey) === cell.ColumnForeignKeyValue && obj.Get(this.JoinEntityRowForeignKey) === row.RowForeignKeyValue);
392
+ if (!record) {
393
+ const md = new Metadata();
394
+ record = yield md.GetEntityObject(this.JoinEntityName);
395
+ record.Set(this.JoinEntityRowForeignKey, row.RowForeignKeyValue);
396
+ record.Set(this.JoinEntityColumnForeignKey, cell.ColumnForeignKeyValue);
397
+ for (const key in this.NewRecordDefaultValues) {
398
+ record.Set(key, this.NewRecordDefaultValues[key]);
399
+ }
400
+ this._pendingInserts.push(record);
401
+ }
402
+ cell.data = record;
403
+ }
404
+ this.cdr.detectChanges();
405
+ });
406
+ }
407
+ _IsColumnChecked(cell) {
408
+ return (cell === null || cell === void 0 ? void 0 : cell.data) !== undefined;
409
+ }
410
+ }
411
+ JoinGridComponent.ɵfac = function JoinGridComponent_Factory(t) { return new (t || JoinGridComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
412
+ JoinGridComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: JoinGridComponent, selectors: [["mj-join-grid"]], inputs: { RowsEntityName: "RowsEntityName", RowsEntityDisplayField: "RowsEntityDisplayField", RowsEntityDataSource: "RowsEntityDataSource", RowsExtraFilter: "RowsExtraFilter", RowsOrderBy: "RowsOrderBy", RowsEntityViewName: "RowsEntityViewName", RowsEntityArray: "RowsEntityArray", ColumnsMode: "ColumnsMode", ColumnsEntityName: "ColumnsEntityName", ColumnsEntityDisplayField: "ColumnsEntityDisplayField", ColumnsEntityDataSource: "ColumnsEntityDataSource", ColumnsExtraFilter: "ColumnsExtraFilter", ColumnsOrderBy: "ColumnsOrderBy", ColumnsEntityViewName: "ColumnsEntityViewName", ColumnsEntityArray: "ColumnsEntityArray", JoinEntityName: "JoinEntityName", JoinEntityRowForeignKey: "JoinEntityRowForeignKey", JoinEntityColumnForeignKey: "JoinEntityColumnForeignKey", JoinEntityDisplayColumns: "JoinEntityDisplayColumns", CheckBoxValueMode: "CheckBoxValueMode", CheckBoxValueField: "CheckBoxValueField", NewRecordDefaultValues: "NewRecordDefaultValues" }, decls: 7, vars: 4, consts: [["mjFillContainer", "", 1, "wrapper"], ["kendoButton", "", 3, "disabled", "click"], ["class", "grid"], [1, "grid"], [3, "ngClass"], [1, "first-column"], [4, "ngFor", "ngForOf"], ["type", "checkbox", "kendoCheckBox", ""], [3, "ngClass", "click"], ["type", "checkbox", "kendoCheckBox", "", 3, "checked", "click"]], template: function JoinGridComponent_Template(rf, ctx) { if (rf & 1) {
413
+ i0.ɵɵelementStart(0, "div", 0);
414
+ i0.ɵɵtemplate(1, JoinGridComponent_Conditional_1_Template, 2, 0, "div");
415
+ i0.ɵɵelementStart(2, "button", 1);
416
+ i0.ɵɵlistener("click", function JoinGridComponent_Template_button_click_2_listener() { return ctx.Save(); });
417
+ i0.ɵɵtext(3, "Save");
418
+ i0.ɵɵelementEnd();
419
+ i0.ɵɵelementStart(4, "button", 1);
420
+ i0.ɵɵlistener("click", function JoinGridComponent_Template_button_click_4_listener() { return ctx.CancelEdit(); });
421
+ i0.ɵɵtext(5, "Cancel");
422
+ i0.ɵɵelementEnd();
423
+ i0.ɵɵtemplate(6, JoinGridComponent_Conditional_6_Template, 10, 2, "table", 2);
424
+ i0.ɵɵelementEnd();
425
+ } if (rf & 2) {
426
+ i0.ɵɵadvance();
427
+ i0.ɵɵconditional(1, ctx._IsLoading ? 1 : -1);
428
+ i0.ɵɵadvance();
429
+ i0.ɵɵproperty("disabled", ctx.NumDirtyRecords === 0);
430
+ i0.ɵɵadvance(2);
431
+ i0.ɵɵproperty("disabled", ctx.NumDirtyRecords === 0);
432
+ i0.ɵɵadvance(2);
433
+ i0.ɵɵconditional(6, !ctx._IsLoading ? 6 : -1);
434
+ } }, dependencies: [i1.NgClass, i1.NgForOf, i2.ButtonComponent, i3.LoaderComponent, i4.FillContainer], styles: [".wrapper[_ngcontent-%COMP%] {\n overflow: auto;\n}\n\n\n\ntable[_ngcontent-%COMP%] {\n margin-left: 5px;\n margin-top: 5px;\n border-collapse: collapse; \n\n}\n\nbutton[_ngcontent-%COMP%] {\n margin-left: 5px;\n margin-top: 5px;\n width: 125px;\n}\n \ntable[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: #f2f2f2; \n\n color: black; \n\n font-weight: bold; \n\n cursor: pointer;\n}\n\n.permission-left-col[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n\n\ntable[_ngcontent-%COMP%] th[_ngcontent-%COMP%], table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n border: 1px solid gray; \n\n height: 36px; \n\n text-align: center;\n padding: 0 8px; \n\n}\n\n\n\ntable[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:first-child, table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]:first-child {\n min-width: 150px; \n\n text-align: left;\n}\n\n\n\ntable[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:not(:first-child), table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]:not(:first-child) {\n width: 100px; \n\n}\n\n\n\ntable[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:nth-child(odd) {\n background-color: white; \n\n}\n\ntable[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:nth-child(even) {\n background-color: #e7f4ff; \n\n}\n\ntable[_ngcontent-%COMP%] tr.dirty-row[_ngcontent-%COMP%] {\n font-style: italic;\n background-color: #ffcccc;\n}\n\ntable[_ngcontent-%COMP%] td.dirty-cell[_ngcontent-%COMP%] {\n font-style: italic;\n background-color: #ffcccc;\n}"] });
435
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(JoinGridComponent, [{
436
+ type: Component,
437
+ args: [{ selector: 'mj-join-grid', template: "<div mjFillContainer class=\"wrapper\"> \n @if (_IsLoading) {\n <div><kendo-loader></kendo-loader></div>\n }\n <button [disabled]=\"NumDirtyRecords === 0\" kendoButton (click)=\"Save()\">Save</button>\n <button [disabled]=\"NumDirtyRecords === 0\" kendoButton (click)=\"CancelEdit()\">Cancel</button>\n @if (!_IsLoading) {\n <table class=\"grid\">\n <thead>\n <tr>\n <!-- First column is the name of the Rows Entity -->\n <th>{{RowsEntityName}}</th>\n @if (ColumnsMode === 'Entity') {\n @for (colRecord of this._columnsEntityData; track colRecord) {\n <th>{{colRecord.Get(this.ColumnsEntityDisplayField)}}</th>\n }\n }\n @else {\n <!-- we need one column for each of the fields in the JoinEntityDisplayColumns array -->\n @for (colName of JoinEntityDisplayColumns; track colName) {\n <th>{{colName}}</th>\n }\n }\n </tr>\n </thead>\n <tbody>\n @for (row of _GridData; track row) {\n <tr [ngClass]=\"IsRecordReallyDirty(row) ? 'dirty-row' : ''\">\n <td class=\"first-column\">\n <span>{{row.FirstColValue}}</span>\n </td>\n @if (ColumnsMode === 'Fields') {\n <td *ngFor=\"let colName of JoinEntityDisplayColumns\">\n <input type=\"checkbox\" kendoCheckBox>\n </td>\n }\n @else {\n @for (cell of row.ColumnData; track cell) {\n <!-- loop through all the columns and display a checkbox and check it if we have a match in the current row -->\n <td (click)=\"_FlipRecord($event, row, cell)\"\n [ngClass]=\"IsCellReallyDirty(cell) ? 'dirty-cell' : ''\">\n <input type=\"checkbox\" \n kendoCheckBox \n [checked]=\"_IsColumnChecked(cell)\" \n (click)=\"_FlipRecord($event, row, cell, true)\">\n </td>\n }\n }\n </tr> \n } \n </tbody>\n </table>\n }\n</div>", styles: [".wrapper {\n overflow: auto;\n}\n\n/* Style for the whole table */\ntable {\n margin-left: 5px;\n margin-top: 5px;\n border-collapse: collapse; /* Ensures border collapse for a cleaner look */\n}\n\nbutton {\n margin-left: 5px;\n margin-top: 5px;\n width: 125px;\n}\n \ntable th {\n background-color: #f2f2f2; /* Light gray background for headers */\n color: black; /* Black text color for headers */\n font-weight: bold; /* Bold font weight for headers */\n cursor: pointer;\n}\n\n.permission-left-col {\n cursor: pointer;\n}\n\n/* Style for all table cells */\ntable th, table td {\n border: 1px solid gray; /* Gray border for cells */\n height: 36px; /* Fixed height for all rows */\n text-align: center;\n padding: 0 8px; /* Add some padding inside cells */\n}\n\n/* Specific styles for the first column */\ntable th:first-child, table td:first-child {\n min-width: 150px; /* Set width for the first column */\n text-align: left;\n}\n\n/* Specific styles for the \"Can\" columns */\ntable th:not(:first-child), table td:not(:first-child) {\n width: 100px; /* Set width for \"Can\" columns */\n}\n\n/* Alternating row background colors */\ntable tr:nth-child(odd) {\n background-color: white; /* Light color for odd rows */\n}\n\ntable tr:nth-child(even) {\n background-color: #e7f4ff; /* Light blue for even rows */\n}\n\ntable tr.dirty-row {\n font-style: italic;\n background-color: #ffcccc;\n}\n\ntable td.dirty-cell {\n font-style: italic;\n background-color: #ffcccc;\n}"] }]
438
+ }], () => [{ type: i0.ChangeDetectorRef }], { RowsEntityName: [{
439
+ type: Input
440
+ }], RowsEntityDisplayField: [{
441
+ type: Input
442
+ }], RowsEntityDataSource: [{
443
+ type: Input
444
+ }], RowsExtraFilter: [{
445
+ type: Input
446
+ }], RowsOrderBy: [{
447
+ type: Input
448
+ }], RowsEntityViewName: [{
449
+ type: Input
450
+ }], RowsEntityArray: [{
451
+ type: Input
452
+ }], ColumnsMode: [{
453
+ type: Input
454
+ }], ColumnsEntityName: [{
455
+ type: Input
456
+ }], ColumnsEntityDisplayField: [{
457
+ type: Input
458
+ }], ColumnsEntityDataSource: [{
459
+ type: Input
460
+ }], ColumnsExtraFilter: [{
461
+ type: Input
462
+ }], ColumnsOrderBy: [{
463
+ type: Input
464
+ }], ColumnsEntityViewName: [{
465
+ type: Input
466
+ }], ColumnsEntityArray: [{
467
+ type: Input
468
+ }], JoinEntityName: [{
469
+ type: Input
470
+ }], JoinEntityRowForeignKey: [{
471
+ type: Input
472
+ }], JoinEntityColumnForeignKey: [{
473
+ type: Input
474
+ }], JoinEntityDisplayColumns: [{
475
+ type: Input
476
+ }], CheckBoxValueMode: [{
477
+ type: Input
478
+ }], CheckBoxValueField: [{
479
+ type: Input
480
+ }], NewRecordDefaultValues: [{
481
+ type: Input
482
+ }] }); })();
483
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(JoinGridComponent, { className: "JoinGridComponent", filePath: "src/lib/join-grid/join-grid.component.ts", lineNumber: 24 }); })();
@@ -0,0 +1,15 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./join-grid/join-grid.component";
3
+ import * as i2 from "@angular/common";
4
+ import * as i3 from "@angular/forms";
5
+ import * as i4 from "@progress/kendo-angular-dialog";
6
+ import * as i5 from "@progress/kendo-angular-grid";
7
+ import * as i6 from "@progress/kendo-angular-buttons";
8
+ import * as i7 from "@progress/kendo-angular-dropdowns";
9
+ import * as i8 from "@progress/kendo-angular-indicators";
10
+ import * as i9 from "@memberjunction/ng-container-directives";
11
+ export declare class JoinGridModule {
12
+ static ɵfac: i0.ɵɵFactoryDeclaration<JoinGridModule, never>;
13
+ static ɵmod: i0.ɵɵNgModuleDeclaration<JoinGridModule, [typeof i1.JoinGridComponent], [typeof i2.CommonModule, typeof i3.FormsModule, typeof i4.DialogsModule, typeof i5.GridModule, typeof i6.ButtonsModule, typeof i7.DropDownsModule, typeof i4.DialogsModule, typeof i8.IndicatorsModule, typeof i9.ContainerDirectivesModule], [typeof i1.JoinGridComponent]>;
14
+ static ɵinj: i0.ɵɵInjectorDeclaration<JoinGridModule>;
15
+ }
@@ -0,0 +1,57 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ // Kendo UI Angular imports
5
+ import { DialogsModule } from "@progress/kendo-angular-dialog";
6
+ import { ButtonsModule } from '@progress/kendo-angular-buttons';
7
+ import { DropDownsModule } from '@progress/kendo-angular-dropdowns';
8
+ import { IndicatorsModule } from '@progress/kendo-angular-indicators';
9
+ // LOCAL
10
+ import { JoinGridComponent } from './join-grid/join-grid.component';
11
+ import { GridModule } from '@progress/kendo-angular-grid';
12
+ import { ContainerDirectivesModule } from '@memberjunction/ng-container-directives';
13
+ import * as i0 from "@angular/core";
14
+ export class JoinGridModule {
15
+ }
16
+ JoinGridModule.ɵfac = function JoinGridModule_Factory(t) { return new (t || JoinGridModule)(); };
17
+ JoinGridModule.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: JoinGridModule });
18
+ JoinGridModule.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
19
+ FormsModule,
20
+ DialogsModule,
21
+ GridModule,
22
+ ButtonsModule,
23
+ DropDownsModule,
24
+ DialogsModule,
25
+ IndicatorsModule,
26
+ ContainerDirectivesModule] });
27
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(JoinGridModule, [{
28
+ type: NgModule,
29
+ args: [{
30
+ declarations: [
31
+ JoinGridComponent
32
+ ],
33
+ imports: [
34
+ CommonModule,
35
+ FormsModule,
36
+ DialogsModule,
37
+ GridModule,
38
+ ButtonsModule,
39
+ DropDownsModule,
40
+ DialogsModule,
41
+ IndicatorsModule,
42
+ ContainerDirectivesModule
43
+ ],
44
+ exports: [
45
+ JoinGridComponent
46
+ ]
47
+ }]
48
+ }], null, null); })();
49
+ (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(JoinGridModule, { declarations: [JoinGridComponent], imports: [CommonModule,
50
+ FormsModule,
51
+ DialogsModule,
52
+ GridModule,
53
+ ButtonsModule,
54
+ DropDownsModule,
55
+ DialogsModule,
56
+ IndicatorsModule,
57
+ ContainerDirectivesModule], exports: [JoinGridComponent] }); })();
@@ -0,0 +1,2 @@
1
+ export * from './lib/join-grid/join-grid.component';
2
+ export * from './lib/module';
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Public API Surface
3
+ */
4
+ export * from './lib/join-grid/join-grid.component';
5
+ export * from './lib/module';
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@memberjunction/ng-join-grid",
3
+ "version": "1.4.1",
4
+ "description": "MemberJunction: Grid component that is able to display/edit the relationship between two entities. For example being able to edit Users + Roles in a single grid.",
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-container-directives": "~1.4.1",
33
+ "@progress/kendo-angular-buttons": "~15.1.0",
34
+ "@progress/kendo-angular-dialog": "~15.1.0",
35
+ "@progress/kendo-angular-layout": "~15.1.0",
36
+ "@progress/kendo-angular-grid": "~15.1.0",
37
+ "@progress/kendo-angular-indicators": "~15.1.0",
38
+ "tslib": "^2.3.0"
39
+ },
40
+ "sideEffects": false
41
+ }