@cleavelandprice/ngx-lib 4.7.13 → 4.7.15
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.
- package/fesm2022/cleavelandprice-ngx-lib-active-directory-material.mjs +184 -175
- package/fesm2022/cleavelandprice-ngx-lib-active-directory-material.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-active-directory.mjs +7 -7
- package/fesm2022/cleavelandprice-ngx-lib-active-directory.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-authentication-material.mjs +35 -34
- package/fesm2022/cleavelandprice-ngx-lib-authentication-material.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-authentication-object.mjs +7 -7
- package/fesm2022/cleavelandprice-ngx-lib-authentication-object.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-authentication-sso.mjs +35 -21
- package/fesm2022/cleavelandprice-ngx-lib-authentication-sso.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-authentication-token.mjs +7 -7
- package/fesm2022/cleavelandprice-ngx-lib-authentication-token.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-authentication.mjs +4 -4
- package/fesm2022/cleavelandprice-ngx-lib-authentication.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-dialog.mjs +63 -61
- package/fesm2022/cleavelandprice-ngx-lib-dialog.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-msgraph.mjs +4 -4
- package/fesm2022/cleavelandprice-ngx-lib-msgraph.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-quill-mention.mjs +41 -25
- package/fesm2022/cleavelandprice-ngx-lib-quill-mention.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-quill.mjs +141 -84
- package/fesm2022/cleavelandprice-ngx-lib-quill.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-sharepoint.mjs +28 -26
- package/fesm2022/cleavelandprice-ngx-lib-sharepoint.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-table.mjs +78 -54
- package/fesm2022/cleavelandprice-ngx-lib-table.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-upload.mjs +31 -30
- package/fesm2022/cleavelandprice-ngx-lib-upload.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib-url-utilities.mjs +13 -13
- package/fesm2022/cleavelandprice-ngx-lib-url-utilities.mjs.map +1 -1
- package/fesm2022/cleavelandprice-ngx-lib.mjs +7 -7
- package/fesm2022/cleavelandprice-ngx-lib.mjs.map +1 -1
- package/package.json +5 -4
- package/types/cleavelandprice-ngx-lib-active-directory-material.d.ts +1 -1
- package/types/cleavelandprice-ngx-lib-table.d.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActiveDirectoryService, ActiveDirectoryServiceOptionsToken } from '@cleavelandprice/ngx-lib/active-directory';
|
|
2
2
|
export * from '@cleavelandprice/ngx-lib/active-directory';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, viewChild, ViewChild, Component, output, input, forwardRef, Optional, SkipSelf, NgModule } from '@angular/core';
|
|
4
|
+
import { inject, viewChild, ViewChild, ChangeDetectionStrategy, Component, output, input, forwardRef, Optional, SkipSelf, NgModule } from '@angular/core';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { FormGroup, FormControl, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
7
7
|
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogActions, MatDialogClose, MatDialogContent, MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
@@ -56,15 +56,16 @@ class UserChooserComponent {
|
|
|
56
56
|
dialogRef: inject((MatDialogRef)),
|
|
57
57
|
activeDirectory: inject(ActiveDirectoryService),
|
|
58
58
|
sharePoint: inject(SharePointService),
|
|
59
|
-
data: inject(MAT_DIALOG_DATA)
|
|
59
|
+
data: inject(MAT_DIALOG_DATA),
|
|
60
60
|
};
|
|
61
61
|
this._data = { ...DefaultUserChooserData, ...this.#services.data };
|
|
62
62
|
//#region Fields
|
|
63
63
|
//@ViewChild(MatSelectionList) selectionList?: MatSelectionList;
|
|
64
|
-
this.selectionList = viewChild(MatSelectionList,
|
|
64
|
+
this.selectionList = viewChild(MatSelectionList, /* @ts-ignore */
|
|
65
|
+
...(ngDevMode ? [{ debugName: "selectionList" }] : /* istanbul ignore next */ []));
|
|
65
66
|
//filterInput = viewChild<ElementRef>('filterInput');
|
|
66
67
|
this.filterForm = new FormGroup({
|
|
67
|
-
filter: new FormControl()
|
|
68
|
+
filter: new FormControl(),
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
71
|
#services;
|
|
@@ -73,30 +74,29 @@ class UserChooserComponent {
|
|
|
73
74
|
elRef.nativeElement.focus();
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
;
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region Properties
|
|
79
79
|
get isMultiMode() {
|
|
80
80
|
return this._data.mode === UserChooserMode.Multiple;
|
|
81
81
|
}
|
|
82
82
|
get selectedOptions() {
|
|
83
|
-
return this.selectionList()?.options.filter(o => o.selected) ?? [];
|
|
83
|
+
return this.selectionList()?.options.filter((o) => o.selected) ?? [];
|
|
84
84
|
}
|
|
85
85
|
get selectedUsers() {
|
|
86
|
-
return this.dataSource?.data?.filter(d => d.selected) ?? [];
|
|
86
|
+
return this.dataSource?.data?.filter((d) => d.selected) ?? [];
|
|
87
87
|
}
|
|
88
88
|
get filterValue() {
|
|
89
89
|
return this.filterForm.value.filter;
|
|
90
90
|
}
|
|
91
91
|
get adGroupsNeeded() {
|
|
92
92
|
// If any are these are true, then we need to pull AD groups for use later
|
|
93
|
-
return (this._data.showGroupMembershipTooltips ?? false) ||
|
|
93
|
+
return ((this._data.showGroupMembershipTooltips ?? false) ||
|
|
94
94
|
(this._data.exclusions?.groups?.length ?? 0) > 0 ||
|
|
95
95
|
(this._data.inclusions?.groups?.length ?? 0) > 0 ||
|
|
96
96
|
(this._data.preSelections?.groups?.length ?? 0) > 0 ||
|
|
97
97
|
this._data.filterOptions?.groupMembership ||
|
|
98
98
|
(this._data.selectableGroupNames?.length ?? 0) > 0 ||
|
|
99
|
-
(this._data.groups?.length ?? 0) > 0;
|
|
99
|
+
(this._data.groups?.length ?? 0) > 0);
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region Lifecycle
|
|
@@ -114,20 +114,23 @@ class UserChooserComponent {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
optionSelectionChanged(option) {
|
|
117
|
-
const user = this.dataSource?.data
|
|
118
|
-
|
|
117
|
+
const user = this.dataSource?.data.find((u) => u.sAMAccountName.toLocaleLowerCase() ===
|
|
118
|
+
option.value.sAMAccountName.toLowerCase());
|
|
119
119
|
if (user) {
|
|
120
120
|
// If we are in single user selection mode, deselect any existing selections first
|
|
121
121
|
if (!this.isMultiMode && option.selected) {
|
|
122
122
|
this.dataSource?.data
|
|
123
|
-
.filter(u => u.sAMAccountName.toLowerCase() !==
|
|
124
|
-
.
|
|
123
|
+
.filter((u) => u.sAMAccountName.toLowerCase() !==
|
|
124
|
+
option.value.sAMAccountName.toLowerCase())
|
|
125
|
+
.forEach((u) => (u.selected = false));
|
|
125
126
|
}
|
|
126
127
|
user.selected = option.selected;
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
hideUnselectedChanged(selected) {
|
|
130
|
-
this.filterForm
|
|
131
|
+
this.filterForm
|
|
132
|
+
.get('filter')
|
|
133
|
+
?.setValue(selected ? '{selected:true}' : null);
|
|
131
134
|
}
|
|
132
135
|
selectAll() {
|
|
133
136
|
this.selectionList()?.selectAll();
|
|
@@ -148,34 +151,32 @@ class UserChooserComponent {
|
|
|
148
151
|
}
|
|
149
152
|
#getData() {
|
|
150
153
|
const observables$ = [
|
|
151
|
-
this._data.users?.length
|
|
152
|
-
// Users were passed in
|
|
153
|
-
|
|
154
|
-
// Users need to be retrieved
|
|
155
|
-
|
|
156
|
-
this._data.photos?.length
|
|
157
|
-
// Photos were passed in
|
|
158
|
-
|
|
159
|
-
// Photos need to be retrieved
|
|
160
|
-
|
|
154
|
+
this._data.users?.length
|
|
155
|
+
? // Users were passed in
|
|
156
|
+
of(this._data.users)
|
|
157
|
+
: // Users need to be retrieved
|
|
158
|
+
this.#services.activeDirectory.getUsers(this._data.appName ?? 'ngxlibADUserChooser', this._data.includeDisabledUsers, this._data.parentOu),
|
|
159
|
+
this._data.photos?.length
|
|
160
|
+
? // Photos were passed in
|
|
161
|
+
of(this._data.photos)
|
|
162
|
+
: // Photos need to be retrieved
|
|
163
|
+
this.#services.sharePoint.getPhotos(),
|
|
161
164
|
];
|
|
162
165
|
// Do we need AD groups?
|
|
163
166
|
if (this.adGroupsNeeded) {
|
|
164
|
-
observables$.push(this._data.groups?.length
|
|
165
|
-
// Groups were passed in
|
|
166
|
-
|
|
167
|
-
// Groups need to be retrieved
|
|
168
|
-
|
|
167
|
+
observables$.push(this._data.groups?.length
|
|
168
|
+
? // Groups were passed in
|
|
169
|
+
of(this._data.groups)
|
|
170
|
+
: // Groups need to be retrieved
|
|
171
|
+
this.#services.activeDirectory.getGroups());
|
|
169
172
|
}
|
|
170
173
|
forkJoin(observables$)
|
|
171
174
|
//.subscribe(([users, photos]) => {
|
|
172
|
-
.subscribe(data => {
|
|
175
|
+
.subscribe((data) => {
|
|
173
176
|
// Need groups in place before we handle exclusions/inclusions/pre-selections
|
|
174
|
-
this.groups = this.adGroupsNeeded ?
|
|
175
|
-
data[2] :
|
|
176
|
-
null;
|
|
177
|
+
this.groups = this.adGroupsNeeded ? data[2] : null;
|
|
177
178
|
let users = data[0];
|
|
178
|
-
users.forEach(u => u.selected = false); // In case existing data was re-used
|
|
179
|
+
users.forEach((u) => (u.selected = false)); // In case existing data was re-used
|
|
179
180
|
users = this.#includeUsersByAccountName(users);
|
|
180
181
|
users = this.#includeUsersByGroupName(users);
|
|
181
182
|
users = this.#includeUsersByDepartment(users);
|
|
@@ -201,13 +202,12 @@ class UserChooserComponent {
|
|
|
201
202
|
usersAndGroups.push(...this.groups);
|
|
202
203
|
}
|
|
203
204
|
else {
|
|
204
|
-
this._data.selectableGroupNames
|
|
205
|
-
.
|
|
206
|
-
const group = this.groups.find(g => g.displayName === groupName);
|
|
205
|
+
this._data.selectableGroupNames.forEach((groupName) => {
|
|
206
|
+
const group = this.groups.find((g) => g.displayName === groupName);
|
|
207
207
|
if (group) {
|
|
208
208
|
usersAndGroups.push({
|
|
209
209
|
...group,
|
|
210
|
-
selected: group.selected
|
|
210
|
+
selected: group.selected,
|
|
211
211
|
});
|
|
212
212
|
}
|
|
213
213
|
});
|
|
@@ -224,26 +224,26 @@ class UserChooserComponent {
|
|
|
224
224
|
this.#services.dialogRef.close(this._data.allowCloseWithoutSelections ? [] : undefined);
|
|
225
225
|
return;
|
|
226
226
|
}
|
|
227
|
-
const value = this.selectedUsers
|
|
228
|
-
|
|
229
|
-
this.#services.dialogRef.close(this._data.mode === UserChooserMode.Multiple ?
|
|
230
|
-
value :
|
|
231
|
-
value[0]);
|
|
227
|
+
const value = this.selectedUsers.map((u) => this._data.returnUserObjects ? u : u.sAMAccountName);
|
|
228
|
+
this.#services.dialogRef.close(this._data.mode === UserChooserMode.Multiple ? value : value[0]);
|
|
232
229
|
}
|
|
233
230
|
getPhoto(user) {
|
|
234
231
|
if (!this.isUser(user)) {
|
|
235
232
|
return;
|
|
236
233
|
}
|
|
237
|
-
return this.photos?.find(p => (p.employeeNumber &&
|
|
234
|
+
return this.photos?.find((p) => (p.employeeNumber &&
|
|
235
|
+
p.employeeNumber.toString() ===
|
|
236
|
+
user.employeeNumber) ||
|
|
238
237
|
p.accountName?.toLowerCase() === user.sAMAccountName.toLowerCase() ||
|
|
239
|
-
p.displayName?.toLowerCase() ===
|
|
240
|
-
|
|
238
|
+
p.displayName?.toLowerCase() ===
|
|
239
|
+
(user.displayName ?? user.name).toLowerCase() ||
|
|
240
|
+
p.title?.toLowerCase() ===
|
|
241
|
+
(user.displayName ?? user.name).toLowerCase())?.encodedAbsUrl;
|
|
241
242
|
}
|
|
242
243
|
//#region Exclusions - won't be included in the dataSource at all
|
|
243
244
|
#excludeUsersByAccountName(users) {
|
|
244
|
-
this._data.exclusions?.accountNames
|
|
245
|
-
|
|
246
|
-
const index = users.findIndex(u => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
245
|
+
this._data.exclusions?.accountNames?.forEach((accountName) => {
|
|
246
|
+
const index = users.findIndex((u) => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
247
247
|
if (index === -1) {
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
@@ -252,14 +252,13 @@ class UserChooserComponent {
|
|
|
252
252
|
return users;
|
|
253
253
|
}
|
|
254
254
|
#excludeUsersByGroupName(users) {
|
|
255
|
-
this._data.exclusions?.groups
|
|
256
|
-
?.
|
|
257
|
-
const group = this.groups?.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
255
|
+
this._data.exclusions?.groups?.forEach((groupName) => {
|
|
256
|
+
const group = this.groups?.find((g) => g.name.toLowerCase() === groupName.toLowerCase());
|
|
258
257
|
if (!group) {
|
|
259
258
|
return;
|
|
260
259
|
}
|
|
261
|
-
group.member.forEach(groupMemberDn => {
|
|
262
|
-
const index = users.findIndex(u => u.distinguishedName === groupMemberDn);
|
|
260
|
+
group.member.forEach((groupMemberDn) => {
|
|
261
|
+
const index = users.findIndex((u) => u.distinguishedName === groupMemberDn);
|
|
263
262
|
if (index === -1) {
|
|
264
263
|
return;
|
|
265
264
|
}
|
|
@@ -269,10 +268,9 @@ class UserChooserComponent {
|
|
|
269
268
|
return users;
|
|
270
269
|
}
|
|
271
270
|
#excludeUsersByDepartment(users) {
|
|
272
|
-
this._data.exclusions?.departments
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
excludedUsers.forEach(user => {
|
|
271
|
+
this._data.exclusions?.departments?.forEach((department) => {
|
|
272
|
+
const excludedUsers = users.filter((u) => u.department?.toLowerCase() === department.toLowerCase());
|
|
273
|
+
excludedUsers.forEach((user) => {
|
|
276
274
|
const index = users.indexOf(user);
|
|
277
275
|
users.splice(index, 1);
|
|
278
276
|
});
|
|
@@ -280,10 +278,9 @@ class UserChooserComponent {
|
|
|
280
278
|
return users;
|
|
281
279
|
}
|
|
282
280
|
#excludeUsersByTitle(users) {
|
|
283
|
-
this._data.exclusions?.titles
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
excludedUsers.forEach(user => {
|
|
281
|
+
this._data.exclusions?.titles?.forEach((title) => {
|
|
282
|
+
const excludedUsers = users.filter((u) => u.title?.toLowerCase() === title.toLowerCase());
|
|
283
|
+
excludedUsers.forEach((user) => {
|
|
287
284
|
const index = users.indexOf(user);
|
|
288
285
|
users.splice(index, 1);
|
|
289
286
|
});
|
|
@@ -293,16 +290,16 @@ class UserChooserComponent {
|
|
|
293
290
|
//#endregion
|
|
294
291
|
//#region Inclusions - only these will be included in the dataSource
|
|
295
292
|
#includeUsersByAccountName(users) {
|
|
296
|
-
return users.filter(user => !this._data.inclusions?.accountNames?.length || // No account inclusions specified
|
|
297
|
-
this._data.inclusions.accountNames.find(accountName => accountName.toLowerCase() === user.sAMAccountName.toLowerCase()));
|
|
293
|
+
return users.filter((user) => !this._data.inclusions?.accountNames?.length || // No account inclusions specified
|
|
294
|
+
this._data.inclusions.accountNames.find((accountName) => accountName.toLowerCase() === user.sAMAccountName.toLowerCase()));
|
|
298
295
|
}
|
|
299
296
|
#includeUsersByDepartment(users) {
|
|
300
|
-
return users.filter(user => !this._data.inclusions?.departments?.length || // No department inclusions specified
|
|
301
|
-
this._data.inclusions.departments.find(department => department.toLowerCase() === user.department?.toLowerCase()));
|
|
297
|
+
return users.filter((user) => !this._data.inclusions?.departments?.length || // No department inclusions specified
|
|
298
|
+
this._data.inclusions.departments.find((department) => department.toLowerCase() === user.department?.toLowerCase()));
|
|
302
299
|
}
|
|
303
300
|
#includeUsersByTitle(users) {
|
|
304
|
-
return users.filter(user => !this._data.inclusions?.titles?.length || // No title inclusions specified
|
|
305
|
-
this._data.inclusions.titles.find(title => title.toLowerCase() === user.title?.toLowerCase()));
|
|
301
|
+
return users.filter((user) => !this._data.inclusions?.titles?.length || // No title inclusions specified
|
|
302
|
+
this._data.inclusions.titles.find((title) => title.toLowerCase() === user.title?.toLowerCase()));
|
|
306
303
|
}
|
|
307
304
|
#includeUsersByGroupName(users) {
|
|
308
305
|
if (!this._data.inclusions?.groups?.length) {
|
|
@@ -310,28 +307,26 @@ class UserChooserComponent {
|
|
|
310
307
|
}
|
|
311
308
|
// Cheating a bit and leveraging the 'selected' property to keep track of who should be included
|
|
312
309
|
// Since inclusions happen befor pre-selections, we can do that, as long as we set 'selected' back to false when we're done
|
|
313
|
-
this._data.inclusions.groups
|
|
314
|
-
.
|
|
315
|
-
const group = this.groups?.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
310
|
+
this._data.inclusions.groups.forEach((groupName) => {
|
|
311
|
+
const group = this.groups?.find((g) => g.name.toLowerCase() === groupName.toLowerCase());
|
|
316
312
|
if (!group) {
|
|
317
313
|
return;
|
|
318
314
|
}
|
|
319
315
|
users
|
|
320
|
-
.filter(user => group.member.find(groupMemberDn => groupMemberDn === user.distinguishedName))
|
|
321
|
-
.forEach(user => user.selected = true);
|
|
316
|
+
.filter((user) => group.member.find((groupMemberDn) => groupMemberDn === user.distinguishedName))
|
|
317
|
+
.forEach((user) => (user.selected = true));
|
|
322
318
|
});
|
|
323
319
|
// At this point, all of the appropriate users should have 'selected' set to true
|
|
324
|
-
const selectedUsers = users.filter(user => user.selected); // Subset of the original list
|
|
320
|
+
const selectedUsers = users.filter((user) => user.selected); // Subset of the original list
|
|
325
321
|
// Reset 'selected' to false, and return
|
|
326
|
-
selectedUsers.forEach(user => user.selected = false);
|
|
322
|
+
selectedUsers.forEach((user) => (user.selected = false));
|
|
327
323
|
return selectedUsers;
|
|
328
324
|
}
|
|
329
325
|
//#endregion
|
|
330
326
|
//#region Pre-Selections
|
|
331
327
|
#preSelectUsersByAccountName(users) {
|
|
332
|
-
this._data.preSelections?.accountNames
|
|
333
|
-
|
|
334
|
-
const user = users.find(u => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
328
|
+
this._data.preSelections?.accountNames?.forEach((accountName) => {
|
|
329
|
+
const user = users.find((u) => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
335
330
|
if (!user) {
|
|
336
331
|
return;
|
|
337
332
|
}
|
|
@@ -340,39 +335,34 @@ class UserChooserComponent {
|
|
|
340
335
|
return users;
|
|
341
336
|
}
|
|
342
337
|
#preSelectGroupsByAccountName() {
|
|
343
|
-
this._data.preSelections?.accountNames
|
|
344
|
-
?.
|
|
345
|
-
const group = this.groups?.find(g => g.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
338
|
+
this._data.preSelections?.accountNames?.forEach((accountName) => {
|
|
339
|
+
const group = this.groups?.find((g) => g.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
346
340
|
if (!group) {
|
|
347
341
|
return;
|
|
348
342
|
}
|
|
349
343
|
group.selected = true;
|
|
350
344
|
});
|
|
351
|
-
;
|
|
352
345
|
}
|
|
353
346
|
#preSelectUsersByDepartment(users) {
|
|
354
|
-
this._data.preSelections?.departments
|
|
355
|
-
|
|
356
|
-
.
|
|
357
|
-
.forEach(user => user.selected = true));
|
|
347
|
+
this._data.preSelections?.departments?.forEach((department) => users
|
|
348
|
+
.filter((u) => u.department?.toLowerCase() === department.toLowerCase())
|
|
349
|
+
.forEach((user) => (user.selected = true)));
|
|
358
350
|
return users;
|
|
359
351
|
}
|
|
360
352
|
#preSelectUsersByTitle(users) {
|
|
361
|
-
this._data.preSelections?.titles
|
|
362
|
-
|
|
363
|
-
.
|
|
364
|
-
.forEach(user => user.selected = true));
|
|
353
|
+
this._data.preSelections?.titles?.forEach((title) => users
|
|
354
|
+
.filter((u) => u.title?.toLowerCase() === title.toLowerCase())
|
|
355
|
+
.forEach((user) => (user.selected = true)));
|
|
365
356
|
return users;
|
|
366
357
|
}
|
|
367
358
|
#preSelectUsersByGroupName(users) {
|
|
368
|
-
this._data.preSelections?.groups
|
|
369
|
-
?.
|
|
370
|
-
const group = this.groups?.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
359
|
+
this._data.preSelections?.groups?.forEach((groupName) => {
|
|
360
|
+
const group = this.groups?.find((g) => g.name.toLowerCase() === groupName.toLowerCase());
|
|
371
361
|
if (!group) {
|
|
372
362
|
return;
|
|
373
363
|
}
|
|
374
|
-
group.member.forEach(groupMemberDn => {
|
|
375
|
-
const user = users.find(u => u.distinguishedName === groupMemberDn);
|
|
364
|
+
group.member.forEach((groupMemberDn) => {
|
|
365
|
+
const user = users.find((u) => u.distinguishedName === groupMemberDn);
|
|
376
366
|
if (!user) {
|
|
377
367
|
return;
|
|
378
368
|
}
|
|
@@ -407,8 +397,7 @@ class UserChooserComponent {
|
|
|
407
397
|
filterProperties.push('telephoneNumber');
|
|
408
398
|
}
|
|
409
399
|
// Match on the properties configured above
|
|
410
|
-
filterProperties
|
|
411
|
-
.forEach(field => {
|
|
400
|
+
filterProperties.forEach((field) => {
|
|
412
401
|
// @ts-ignore
|
|
413
402
|
if (user[field] && user[field].match(regex)) {
|
|
414
403
|
match = true;
|
|
@@ -416,8 +405,8 @@ class UserChooserComponent {
|
|
|
416
405
|
});
|
|
417
406
|
// Match on group membership (group name)
|
|
418
407
|
if (this._data.filterOptions?.groupMembership) {
|
|
419
|
-
user.memberOf.forEach(groupDn => {
|
|
420
|
-
const group = this.groups?.find(group => group.distinguishedName === groupDn && group.name.match(regex));
|
|
408
|
+
user.memberOf.forEach((groupDn) => {
|
|
409
|
+
const group = this.groups?.find((group) => group.distinguishedName === groupDn && group.name.match(regex));
|
|
421
410
|
if (group) {
|
|
422
411
|
match = true;
|
|
423
412
|
}
|
|
@@ -428,23 +417,26 @@ class UserChooserComponent {
|
|
|
428
417
|
};
|
|
429
418
|
}
|
|
430
419
|
#listenForFilterChanges() {
|
|
431
|
-
this.filterForm
|
|
432
|
-
.
|
|
433
|
-
.
|
|
420
|
+
this.filterForm
|
|
421
|
+
.get('filter')
|
|
422
|
+
?.valueChanges.pipe(debounceTime(250))
|
|
423
|
+
.subscribe(() => (this.dataSource.filter = this.filterForm.value.filter
|
|
424
|
+
?.trim()
|
|
425
|
+
.toLowerCase()));
|
|
434
426
|
}
|
|
435
427
|
tooltip(user) {
|
|
436
|
-
return this._data.showGroupMembershipTooltips
|
|
437
|
-
user.memberOf
|
|
438
|
-
.map(groupDn => this.groups
|
|
439
|
-
?.
|
|
440
|
-
.sort((a, b) => a > b ? 1 : -1)
|
|
441
|
-
.join('\n')
|
|
442
|
-
'';
|
|
443
|
-
}
|
|
444
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
445
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
428
|
+
return this._data.showGroupMembershipTooltips
|
|
429
|
+
? user.memberOf
|
|
430
|
+
.map((groupDn) => this.groups?.find((group) => group.distinguishedName === groupDn)
|
|
431
|
+
?.name)
|
|
432
|
+
.sort((a, b) => (a > b ? 1 : -1))
|
|
433
|
+
.join('\n')
|
|
434
|
+
: '';
|
|
435
|
+
}
|
|
436
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: UserChooserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
437
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: UserChooserComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "selectionList", first: true, predicate: MatSelectionList, descendants: true, isSignal: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], ngImport: i0, template: "<div id=\"dialog-title\">\r\n <h2 mat-dialog-title>{{ _data.title }}</h2>\r\n\r\n <div id=\"num-selected\">\r\n {{ selectedOptions.length }} selected\r\n </div>\r\n</div>\r\n\r\n<mat-dialog-content>\r\n @if (dataSource && photos) {\r\n <form [formGroup]=\"filterForm\">\r\n @if (dataSource) {\r\n <mat-form-field>\r\n <input matInput placeholder=\"Search\" formControlName=\"filter\" #filterInput>\r\n @if (filterForm.value.filter) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"filterForm.get('filter')?.setValue('')\">\r\n <mat-icon fontIcon=\"close\"/>\r\n </button>\r\n }\r\n </mat-form-field>\r\n }\r\n </form>\r\n <mat-selection-list [multiple]=\"isMultiMode\"\r\n (selectionChange)=\"listSelectionChanged($event.options)\">\r\n @for (user of dataSource.filteredData; track user) {\r\n <mat-list-option [value]=\"user\" [selected]=\"user.selected\"\r\n (selectedChange)=\"optionSelectionChanged(option)\" #option>\r\n @if (getPhoto(user)) {\r\n <img matListItemAvatar alt=\"\" [src]=\"getPhoto(user)\">\r\n } @else {\r\n <mat-icon matListItemAvatar class=\"no-photo\"\r\n [fontIcon]=\"isUser(user) ? 'account_circle' : 'group'\"/>\r\n }\r\n <div class=\"user\">\r\n <div [matTooltip]=\"tooltip(user)\" class=\"user-name\">\r\n {{ user.displayName ?? user.name }}\r\n @if (isUser(user) && _data.showPhone && castUser(user).telephoneNumber) {\r\n <div>{{ castUser(user).telephoneNumber }}</div>\r\n }\r\n </div>\r\n @if (isUser(user)) {\r\n <div>{{ castUser(user).department }}</div>\r\n <div class=\"title\">{{ castUser(user).title }}</div>\r\n }\r\n </div>\r\n </mat-list-option>\r\n }\r\n </mat-selection-list>\r\n } @else {\r\n <div>\r\n <mat-spinner [diameter]=\"50\"/>\r\n <h2 id=\"spinner-message\">Getting users and photos...</h2>\r\n </div>\r\n }\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions>\r\n @if (dataSource && photos) {\r\n @if (selectedOptions.length) {\r\n <mat-slide-toggle (change)=\"hideUnselectedChanged($event.checked)\">\r\n Hide Unselected\r\n </mat-slide-toggle>\r\n }\r\n @if (isMultiMode) {\r\n <button mat-raised-button color=\"primary\" (click)=\"selectAll()\"\r\n >\r\n <mat-icon fontIcon=\"select_all\"/>\r\n <span class=\"hide-mobile\">Select All</span>\r\n </button>\r\n }\r\n @if (isMultiMode && selectedOptions.length) {\r\n <button mat-raised-button color=\"primary\" (click)=\"deselectAll()\"\r\n >\r\n <mat-icon fontIcon=\"clear_all\"/>\r\n <span class=\"hide-mobile\">Clear All</span>\r\n </button>\r\n }\r\n @if (isMultiMode || !_data.closeWhenSelectionMade) {\r\n <button mat-raised-button color=\"primary\" (click)=\"close()\" matTooltip=\"Accept your selection\"\r\n [disabled]=\"!_data.allowCloseWithoutSelections && !selectedOptions.length\">\r\n <mat-icon fontIcon=\"check\"/>\r\n <span class=\"hide-mobile\">Ok</span>\r\n </button>\r\n }\r\n }\r\n\r\n <button mat-raised-button color=\"warn\" mat-dialog-close matTooltip=\"Close this window\">\r\n <mat-icon fontIcon=\"close\"/>\r\n <span class=\"hide-mobile\">Cancel</span>\r\n </button>\r\n</mat-dialog-actions>", styles: ["::ng-deep .mat-tooltip{font-size:1em!important;white-space:pre-line}mat-dialog-content{min-width:50vw}#dialog-title{display:flex;justify-content:space-between}#num-selected{margin:1em 1em 0 0}mat-spinner{margin:0 auto}#spinner-message{text-align:center;padding:.5em}mat-form-field{width:100%}.title{font-style:italic;color:#757575}img,.no-photo{width:2rem;height:2rem;font-size:2.3rem!important;border-radius:100%}.hide-mobile{display:none}mat-dialog-actions{display:grid;grid-auto-flow:column;grid-gap:1em;justify-content:center}.user-name{display:flex;justify-content:space-between}.user-name>div:last-child{margin-right:10rem;font-weight:400;font-style:italic;color:#757575}@media(min-width:801px){.user{display:grid;grid-template-columns:1fr 1fr 1fr}.user>div:first-child{font-weight:700}.hide-mobile{display:initial}}\n", ".material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatListItemAvatar, selector: "[matListItemAvatar]" }, { kind: "component", type: MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "fullWidth", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
446
438
|
}
|
|
447
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: UserChooserComponent, decorators: [{
|
|
448
440
|
type: Component,
|
|
449
441
|
args: [{ imports: [
|
|
450
442
|
MatButton,
|
|
@@ -462,7 +454,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
|
|
|
462
454
|
MatSlideToggle,
|
|
463
455
|
MatTooltip,
|
|
464
456
|
ReactiveFormsModule,
|
|
465
|
-
], standalone: true, template: "<div id=\"dialog-title\">\r\n <h2 mat-dialog-title>{{ _data.title }}</h2>\r\n\r\n <div id=\"num-selected\">\r\n {{ selectedOptions.length }} selected\r\n </div>\r\n</div>\r\n\r\n<mat-dialog-content>\r\n @if (dataSource && photos) {\r\n <form [formGroup]=\"filterForm\">\r\n @if (dataSource) {\r\n <mat-form-field>\r\n <input matInput placeholder=\"Search\" formControlName=\"filter\" #filterInput>\r\n @if (filterForm.value.filter) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"filterForm.get('filter')?.setValue('')\">\r\n <mat-icon fontIcon=\"close\"/>\r\n </button>\r\n }\r\n </mat-form-field>\r\n }\r\n </form>\r\n <mat-selection-list [multiple]=\"isMultiMode\"\r\n (selectionChange)=\"listSelectionChanged($event.options)\">\r\n @for (user of dataSource.filteredData; track user) {\r\n <mat-list-option [value]=\"user\" [selected]=\"user.selected\"\r\n (selectedChange)=\"optionSelectionChanged(option)\" #option>\r\n @if (getPhoto(user)) {\r\n <img matListItemAvatar alt=\"\" [src]=\"getPhoto(user)\">\r\n } @else {\r\n <mat-icon matListItemAvatar class=\"no-photo\"\r\n [fontIcon]=\"isUser(user) ? 'account_circle' : 'group'\"/>\r\n }\r\n <div class=\"user\">\r\n <div [matTooltip]=\"tooltip(user)\" class=\"user-name\">\r\n {{ user.displayName ?? user.name }}\r\n @if (isUser(user) && _data.showPhone && castUser(user).telephoneNumber) {\r\n <div>{{ castUser(user).telephoneNumber }}</div>\r\n }\r\n </div>\r\n @if (isUser(user)) {\r\n <div>{{ castUser(user).department }}</div>\r\n <div class=\"title\">{{ castUser(user).title }}</div>\r\n }\r\n </div>\r\n </mat-list-option>\r\n }\r\n </mat-selection-list>\r\n } @else {\r\n <div>\r\n <mat-spinner [diameter]=\"50\"/>\r\n <h2 id=\"spinner-message\">Getting users and photos...</h2>\r\n </div>\r\n }\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions>\r\n @if (dataSource && photos) {\r\n @if (selectedOptions.length) {\r\n <mat-slide-toggle (change)=\"hideUnselectedChanged($event.checked)\">\r\n Hide Unselected\r\n </mat-slide-toggle>\r\n }\r\n @if (isMultiMode) {\r\n <button mat-raised-button color=\"primary\" (click)=\"selectAll()\"\r\n >\r\n <mat-icon fontIcon=\"select_all\"/>\r\n <span class=\"hide-mobile\">Select All</span>\r\n </button>\r\n }\r\n @if (isMultiMode && selectedOptions.length) {\r\n <button mat-raised-button color=\"primary\" (click)=\"deselectAll()\"\r\n >\r\n <mat-icon fontIcon=\"clear_all\"/>\r\n <span class=\"hide-mobile\">Clear All</span>\r\n </button>\r\n }\r\n @if (isMultiMode || !_data.closeWhenSelectionMade) {\r\n <button mat-raised-button color=\"primary\" (click)=\"close()\" matTooltip=\"Accept your selection\"\r\n [disabled]=\"!_data.allowCloseWithoutSelections && !selectedOptions.length\">\r\n <mat-icon fontIcon=\"check\"/>\r\n <span class=\"hide-mobile\">Ok</span>\r\n </button>\r\n }\r\n }\r\n\r\n <button mat-raised-button color=\"warn\" mat-dialog-close matTooltip=\"Close this window\">\r\n <mat-icon fontIcon=\"close\"/>\r\n <span class=\"hide-mobile\">Cancel</span>\r\n </button>\r\n</mat-dialog-actions>", styles: ["::ng-deep .mat-tooltip{font-size:1em!important;white-space:pre-line}mat-dialog-content{min-width:50vw}#dialog-title{display:flex;justify-content:space-between}#num-selected{margin:1em 1em 0 0}mat-spinner{margin:0 auto}#spinner-message{text-align:center;padding:.5em}mat-form-field{width:100%}.title{font-style:italic;color:#757575}img,.no-photo{width:2rem;height:2rem;font-size:2.3rem!important;border-radius:100%}.hide-mobile{display:none}mat-dialog-actions{display:grid;grid-auto-flow:column;grid-gap:1em;justify-content:center}.user-name{display:flex;justify-content:space-between}.user-name>div:last-child{margin-right:10rem;font-weight:400;font-style:italic;color:#757575}@media(min-width:801px){.user{display:grid;grid-template-columns:1fr 1fr 1fr}.user>div:first-child{font-weight:700}.hide-mobile{display:initial}}\n", ".material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}\n"] }]
|
|
457
|
+
], standalone: true, changeDetection: ChangeDetectionStrategy.Eager, template: "<div id=\"dialog-title\">\r\n <h2 mat-dialog-title>{{ _data.title }}</h2>\r\n\r\n <div id=\"num-selected\">\r\n {{ selectedOptions.length }} selected\r\n </div>\r\n</div>\r\n\r\n<mat-dialog-content>\r\n @if (dataSource && photos) {\r\n <form [formGroup]=\"filterForm\">\r\n @if (dataSource) {\r\n <mat-form-field>\r\n <input matInput placeholder=\"Search\" formControlName=\"filter\" #filterInput>\r\n @if (filterForm.value.filter) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"filterForm.get('filter')?.setValue('')\">\r\n <mat-icon fontIcon=\"close\"/>\r\n </button>\r\n }\r\n </mat-form-field>\r\n }\r\n </form>\r\n <mat-selection-list [multiple]=\"isMultiMode\"\r\n (selectionChange)=\"listSelectionChanged($event.options)\">\r\n @for (user of dataSource.filteredData; track user) {\r\n <mat-list-option [value]=\"user\" [selected]=\"user.selected\"\r\n (selectedChange)=\"optionSelectionChanged(option)\" #option>\r\n @if (getPhoto(user)) {\r\n <img matListItemAvatar alt=\"\" [src]=\"getPhoto(user)\">\r\n } @else {\r\n <mat-icon matListItemAvatar class=\"no-photo\"\r\n [fontIcon]=\"isUser(user) ? 'account_circle' : 'group'\"/>\r\n }\r\n <div class=\"user\">\r\n <div [matTooltip]=\"tooltip(user)\" class=\"user-name\">\r\n {{ user.displayName ?? user.name }}\r\n @if (isUser(user) && _data.showPhone && castUser(user).telephoneNumber) {\r\n <div>{{ castUser(user).telephoneNumber }}</div>\r\n }\r\n </div>\r\n @if (isUser(user)) {\r\n <div>{{ castUser(user).department }}</div>\r\n <div class=\"title\">{{ castUser(user).title }}</div>\r\n }\r\n </div>\r\n </mat-list-option>\r\n }\r\n </mat-selection-list>\r\n } @else {\r\n <div>\r\n <mat-spinner [diameter]=\"50\"/>\r\n <h2 id=\"spinner-message\">Getting users and photos...</h2>\r\n </div>\r\n }\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions>\r\n @if (dataSource && photos) {\r\n @if (selectedOptions.length) {\r\n <mat-slide-toggle (change)=\"hideUnselectedChanged($event.checked)\">\r\n Hide Unselected\r\n </mat-slide-toggle>\r\n }\r\n @if (isMultiMode) {\r\n <button mat-raised-button color=\"primary\" (click)=\"selectAll()\"\r\n >\r\n <mat-icon fontIcon=\"select_all\"/>\r\n <span class=\"hide-mobile\">Select All</span>\r\n </button>\r\n }\r\n @if (isMultiMode && selectedOptions.length) {\r\n <button mat-raised-button color=\"primary\" (click)=\"deselectAll()\"\r\n >\r\n <mat-icon fontIcon=\"clear_all\"/>\r\n <span class=\"hide-mobile\">Clear All</span>\r\n </button>\r\n }\r\n @if (isMultiMode || !_data.closeWhenSelectionMade) {\r\n <button mat-raised-button color=\"primary\" (click)=\"close()\" matTooltip=\"Accept your selection\"\r\n [disabled]=\"!_data.allowCloseWithoutSelections && !selectedOptions.length\">\r\n <mat-icon fontIcon=\"check\"/>\r\n <span class=\"hide-mobile\">Ok</span>\r\n </button>\r\n }\r\n }\r\n\r\n <button mat-raised-button color=\"warn\" mat-dialog-close matTooltip=\"Close this window\">\r\n <mat-icon fontIcon=\"close\"/>\r\n <span class=\"hide-mobile\">Cancel</span>\r\n </button>\r\n</mat-dialog-actions>", styles: ["::ng-deep .mat-tooltip{font-size:1em!important;white-space:pre-line}mat-dialog-content{min-width:50vw}#dialog-title{display:flex;justify-content:space-between}#num-selected{margin:1em 1em 0 0}mat-spinner{margin:0 auto}#spinner-message{text-align:center;padding:.5em}mat-form-field{width:100%}.title{font-style:italic;color:#757575}img,.no-photo{width:2rem;height:2rem;font-size:2.3rem!important;border-radius:100%}.hide-mobile{display:none}mat-dialog-actions{display:grid;grid-auto-flow:column;grid-gap:1em;justify-content:center}.user-name{display:flex;justify-content:space-between}.user-name>div:last-child{margin-right:10rem;font-weight:400;font-style:italic;color:#757575}@media(min-width:801px){.user{display:grid;grid-template-columns:1fr 1fr 1fr}.user>div:first-child{font-weight:700}.hide-mobile{display:initial}}\n", ".material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}\n"] }]
|
|
466
458
|
}], propDecorators: { selectionList: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSelectionList), { isSignal: true }] }], filterInput: [{
|
|
467
459
|
type: ViewChild,
|
|
468
460
|
args: ['filterInput']
|
|
@@ -474,13 +466,16 @@ class UserFormFieldComponent {
|
|
|
474
466
|
this.#services = {
|
|
475
467
|
dialog: inject(MatDialog),
|
|
476
468
|
activeDirectory: inject(ActiveDirectoryService),
|
|
477
|
-
sharePoint: inject(SharePointService)
|
|
469
|
+
sharePoint: inject(SharePointService),
|
|
478
470
|
};
|
|
479
471
|
this.usersSelected = output(); // string for Single mode, string[] for multi
|
|
480
472
|
this.userUnSelected = output();
|
|
481
|
-
this.placeholder = input('Select User(s)',
|
|
482
|
-
|
|
483
|
-
this.
|
|
473
|
+
this.placeholder = input('Select User(s)', /* @ts-ignore */
|
|
474
|
+
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
475
|
+
this.clickable = input(true, /* @ts-ignore */
|
|
476
|
+
...(ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []));
|
|
477
|
+
this.userChooserData = input.required(/* @ts-ignore */
|
|
478
|
+
...(ngDevMode ? [{ debugName: "userChooserData" }] : /* istanbul ignore next */ []));
|
|
484
479
|
this.onChange = (_) => { }; // Invoked when the model has been changed
|
|
485
480
|
this.onTouched = () => { }; // Invoked when the model has been touched
|
|
486
481
|
}
|
|
@@ -493,19 +488,24 @@ class UserFormFieldComponent {
|
|
|
493
488
|
return window.navigator.userAgent.indexOf('Edge') > -1;
|
|
494
489
|
}*/
|
|
495
490
|
get class() {
|
|
496
|
-
return this._userChooserData?.mode === UserChooserMode.Single
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
491
|
+
return this._userChooserData?.mode === UserChooserMode.Single
|
|
492
|
+
? ''
|
|
493
|
+
: (this.accountNames?.length ?? 0) > 4
|
|
494
|
+
? 'grid five'
|
|
495
|
+
: (this.accountNames?.length ?? 0) > 3
|
|
496
|
+
? 'grid four'
|
|
497
|
+
: (this.accountNames?.length ?? 0) > 2
|
|
498
|
+
? 'grid three'
|
|
499
|
+
: (this.accountNames?.length ?? 0) > 1
|
|
500
|
+
? 'grid two'
|
|
501
|
+
: '';
|
|
502
502
|
}
|
|
503
503
|
//#endregion
|
|
504
504
|
//#region Lifecycle
|
|
505
505
|
ngOnInit() {
|
|
506
506
|
this._userChooserData = {
|
|
507
507
|
...DefaultUserChooserData,
|
|
508
|
-
...this.userChooserData()
|
|
508
|
+
...this.userChooserData(),
|
|
509
509
|
};
|
|
510
510
|
// If users have been pre-selected in the config, store those in accountNames, which drives the UI of this component
|
|
511
511
|
this.accountNames = this._userChooserData.preSelections?.accountNames;
|
|
@@ -522,26 +522,28 @@ class UserFormFieldComponent {
|
|
|
522
522
|
users: this.users,
|
|
523
523
|
photos: this.photos,
|
|
524
524
|
};
|
|
525
|
-
this.#services.dialog
|
|
526
|
-
|
|
525
|
+
this.#services.dialog
|
|
526
|
+
.open(UserChooserComponent, {
|
|
527
|
+
data: data,
|
|
527
528
|
})
|
|
528
529
|
.afterClosed()
|
|
529
530
|
.subscribe((selected) => {
|
|
530
531
|
if (!selected) {
|
|
531
532
|
return;
|
|
532
533
|
}
|
|
533
|
-
this.accountNames = Array.isArray(selected)
|
|
534
|
-
selected.map(s => typeof
|
|
535
|
-
[selected].map(s => typeof
|
|
534
|
+
this.accountNames = Array.isArray(selected)
|
|
535
|
+
? selected.map((s) => typeof s === 'string' ? s : s.sAMAccountName)
|
|
536
|
+
: [selected].map((s) => typeof s === 'string' ? s : s.sAMAccountName);
|
|
536
537
|
// Overwrite what may have been passed in, for subsequent launches of UserChooserComponent - otherwise it just keeps getting fed stale data
|
|
537
538
|
if (this._userChooserData.preSelections) {
|
|
538
|
-
this._userChooserData.preSelections.accountNames =
|
|
539
|
+
this._userChooserData.preSelections.accountNames =
|
|
540
|
+
this.accountNames;
|
|
539
541
|
}
|
|
540
542
|
this.usersSelected.emit(selected);
|
|
541
543
|
});
|
|
542
544
|
}
|
|
543
545
|
unSelectUser(accountName) {
|
|
544
|
-
const index = this.accountNames?.findIndex(a => a === accountName);
|
|
546
|
+
const index = this.accountNames?.findIndex((a) => a === accountName);
|
|
545
547
|
this.accountNames?.splice(index ?? -1, 1);
|
|
546
548
|
if (this._userChooserData.preSelections) {
|
|
547
549
|
this._userChooserData.preSelections.accountNames = this.accountNames;
|
|
@@ -552,51 +554,54 @@ class UserFormFieldComponent {
|
|
|
552
554
|
//#region Utilities
|
|
553
555
|
#getData() {
|
|
554
556
|
forkJoin([
|
|
555
|
-
this._userChooserData.users
|
|
556
|
-
// Users were passed in
|
|
557
|
-
|
|
558
|
-
// Users need to be retrieved
|
|
559
|
-
|
|
560
|
-
this._userChooserData.groups
|
|
561
|
-
// Groups were passed in
|
|
562
|
-
|
|
563
|
-
// Groups need to be retrieved
|
|
564
|
-
|
|
565
|
-
this._userChooserData.photos
|
|
566
|
-
// Photos were passed in
|
|
567
|
-
|
|
568
|
-
// Photos need to be retrieved
|
|
569
|
-
|
|
570
|
-
])
|
|
571
|
-
.subscribe(([users, groups, photos]) => {
|
|
557
|
+
this._userChooserData.users
|
|
558
|
+
? // Users were passed in
|
|
559
|
+
of(this._userChooserData.users)
|
|
560
|
+
: // Users need to be retrieved
|
|
561
|
+
this.#services.activeDirectory.getUsers(this._userChooserData.appName ?? 'ngxlibADUserFormField', this._userChooserData.includeDisabledUsers, this._userChooserData.parentOu),
|
|
562
|
+
this._userChooserData.groups
|
|
563
|
+
? // Groups were passed in
|
|
564
|
+
of(this._userChooserData.groups)
|
|
565
|
+
: // Groups need to be retrieved
|
|
566
|
+
this.#services.activeDirectory.getGroups(this._userChooserData.parentOu),
|
|
567
|
+
this._userChooserData.photos
|
|
568
|
+
? // Photos were passed in
|
|
569
|
+
of(this._userChooserData.photos)
|
|
570
|
+
: // Photos need to be retrieved
|
|
571
|
+
this.#services.sharePoint.getPhotos(),
|
|
572
|
+
]).subscribe(([users, groups, photos]) => {
|
|
572
573
|
this.users = users;
|
|
573
574
|
this.groups = groups;
|
|
574
575
|
this.photos = photos;
|
|
575
576
|
});
|
|
576
577
|
}
|
|
577
578
|
getUser(user) {
|
|
578
|
-
user =
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
579
|
+
user =
|
|
580
|
+
typeof user === 'string'
|
|
581
|
+
? this.users?.find((u) => u.sAMAccountName.toLowerCase() === user?.toString().toLowerCase())
|
|
582
|
+
: user;
|
|
583
|
+
return !user ? undefined : 'groupType' in user ? undefined : user;
|
|
583
584
|
}
|
|
584
585
|
getGroup(group) {
|
|
585
|
-
group =
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
586
|
+
group =
|
|
587
|
+
typeof group === 'string'
|
|
588
|
+
? this.groups?.find((g) => g.sAMAccountName.toLowerCase() ===
|
|
589
|
+
group?.toString().toLowerCase())
|
|
590
|
+
: group;
|
|
591
|
+
return !group ? undefined : 'groupType' in group ? group : undefined;
|
|
590
592
|
}
|
|
591
593
|
getPhoto(accountName) {
|
|
592
594
|
const user = this.getUser(accountName);
|
|
593
595
|
if (!user) {
|
|
594
596
|
return undefined;
|
|
595
597
|
}
|
|
596
|
-
return this.photos?.find(p => (p.employeeNumber &&
|
|
598
|
+
return this.photos?.find((p) => (p.employeeNumber &&
|
|
599
|
+
p.employeeNumber.toString() === user.employeeNumber) ||
|
|
597
600
|
p.accountName?.toLowerCase() === user.sAMAccountName.toLowerCase() ||
|
|
598
|
-
p.displayName?.toLowerCase() ===
|
|
599
|
-
|
|
601
|
+
p.displayName?.toLowerCase() ===
|
|
602
|
+
(user.displayName ?? user.name).toLowerCase() ||
|
|
603
|
+
p.title?.toLowerCase() ===
|
|
604
|
+
(user.displayName ?? user.name).toLowerCase())?.encodedAbsUrl;
|
|
600
605
|
}
|
|
601
606
|
//#endregion
|
|
602
607
|
//#region ControlValueAccessor methods
|
|
@@ -618,14 +623,16 @@ class UserFormFieldComponent {
|
|
|
618
623
|
registerOnTouched(fn) {
|
|
619
624
|
this.onTouched = fn;
|
|
620
625
|
}
|
|
621
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
622
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
626
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: UserFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
627
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: UserFormFieldComponent, isStandalone: true, selector: "cp-user-field", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, userChooserData: { classPropertyName: "userChooserData", publicName: "userChooserData", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { usersSelected: "usersSelected", userUnSelected: "userUnSelected" }, providers: [
|
|
628
|
+
{
|
|
623
629
|
provide: NG_VALUE_ACCESSOR,
|
|
624
630
|
useExisting: forwardRef(() => UserFormFieldComponent),
|
|
625
|
-
multi: true
|
|
626
|
-
}
|
|
631
|
+
multi: true,
|
|
632
|
+
},
|
|
633
|
+
], ngImport: i0, template: "\r\n<!-- In Microsoft Edge, selectUser() never gets called if the input fields are disabled\r\nSo... I'm dynamically setting the disabled property based on whether or not the browser is Edge.\r\nIt's definitely a better experience if the field IS disabled.\r\nOtherwise, it's confusing - especially because Edge is SO SLOW to display the resulting dialog window.\r\n-->\r\n<!-- Update 8/24/2023:\r\nThe above problem also exists in Chrome now.\r\nSo instead of dynamically setting [disabled] based on browser type,\r\nI'm applying CSS to suppress mouse events on the input - thus making it bubble up to the parent control, which responds the way we want/\r\n-->\r\n\r\n@if (users && photos) {\r\n <div (click)=\"selectUser()\" [class.clickable]=\"clickable()\">\r\n @if (accountNames?.length) {\r\n <div [ngClass]=\"class\">\r\n @for (accountName of accountNames; track accountName; let i = $index) {\r\n <div class=\"user\">\r\n <!--<img *ngIf=\"accountName && empUtils.getEmployee(accountName)\" alt=\"\" [src]=\"empUtils.getEmployee(accountName) | employeePhotoUrl:cacheService.photos\">-->\r\n @if (getPhoto(accountName)) {\r\n <img matListItemAvatar alt=\"\" [src]=\"getPhoto(accountName)\">\r\n }\r\n @if (getGroup(accountName)) {\r\n <mat-icon>group</mat-icon>\r\n }\r\n <mat-form-field>\r\n <!-- [disabled]=\"!isEdge\" -->\r\n <input matInput disabled [placeholder]=\"i === 0 ? placeholder() : ''\"\r\n [value]=\"getUser(accountName)?.displayName ?? getGroup(accountName)?.displayName ?? accountName\">\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"$event.stopPropagation(); unSelectUser(accountName)\">\r\n <mat-icon fontIcon=\"close\"/>\r\n </button>\r\n </mat-form-field>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <mat-form-field>\r\n <input matInput disabled [placeholder]=\"placeholder()\"> <!-- [disabled]=\"!isEdge\" -->\r\n </mat-form-field>\r\n }\r\n </div>\r\n} @else {\r\n <mat-progress-bar mode=\"indeterminate\"/>\r\n}", styles: [".user{display:grid;grid-template-columns:auto 1fr;grid-gap:.5em;align-items:center}.clickable,.clickable input{cursor:pointer!important}img{width:2em;height:2em;border-radius:100%}@media(min-width:801px){.grid{display:grid;grid-template-columns:repeat(2,1fr);grid-gap:1em}.three{grid-template-columns:repeat(3,1fr)}.four{grid-template-columns:repeat(4,1fr)}.five{grid-template-columns:repeat(5,1fr)}::ng-deep .grid mat-form-field{width:15vw}}input[disabled]{pointer-events:none}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
627
634
|
}
|
|
628
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
635
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: UserFormFieldComponent, decorators: [{
|
|
629
636
|
type: Component,
|
|
630
637
|
args: [{ selector: 'cp-user-field', imports: [
|
|
631
638
|
MatFormField,
|
|
@@ -634,12 +641,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
|
|
|
634
641
|
MatInput,
|
|
635
642
|
MatProgressBar,
|
|
636
643
|
MatSuffix,
|
|
637
|
-
NgClass
|
|
638
|
-
], providers: [
|
|
644
|
+
NgClass,
|
|
645
|
+
], providers: [
|
|
646
|
+
{
|
|
639
647
|
provide: NG_VALUE_ACCESSOR,
|
|
640
648
|
useExisting: forwardRef(() => UserFormFieldComponent),
|
|
641
|
-
multi: true
|
|
642
|
-
}
|
|
649
|
+
multi: true,
|
|
650
|
+
},
|
|
651
|
+
], standalone: true, changeDetection: ChangeDetectionStrategy.Eager, template: "\r\n<!-- In Microsoft Edge, selectUser() never gets called if the input fields are disabled\r\nSo... I'm dynamically setting the disabled property based on whether or not the browser is Edge.\r\nIt's definitely a better experience if the field IS disabled.\r\nOtherwise, it's confusing - especially because Edge is SO SLOW to display the resulting dialog window.\r\n-->\r\n<!-- Update 8/24/2023:\r\nThe above problem also exists in Chrome now.\r\nSo instead of dynamically setting [disabled] based on browser type,\r\nI'm applying CSS to suppress mouse events on the input - thus making it bubble up to the parent control, which responds the way we want/\r\n-->\r\n\r\n@if (users && photos) {\r\n <div (click)=\"selectUser()\" [class.clickable]=\"clickable()\">\r\n @if (accountNames?.length) {\r\n <div [ngClass]=\"class\">\r\n @for (accountName of accountNames; track accountName; let i = $index) {\r\n <div class=\"user\">\r\n <!--<img *ngIf=\"accountName && empUtils.getEmployee(accountName)\" alt=\"\" [src]=\"empUtils.getEmployee(accountName) | employeePhotoUrl:cacheService.photos\">-->\r\n @if (getPhoto(accountName)) {\r\n <img matListItemAvatar alt=\"\" [src]=\"getPhoto(accountName)\">\r\n }\r\n @if (getGroup(accountName)) {\r\n <mat-icon>group</mat-icon>\r\n }\r\n <mat-form-field>\r\n <!-- [disabled]=\"!isEdge\" -->\r\n <input matInput disabled [placeholder]=\"i === 0 ? placeholder() : ''\"\r\n [value]=\"getUser(accountName)?.displayName ?? getGroup(accountName)?.displayName ?? accountName\">\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"$event.stopPropagation(); unSelectUser(accountName)\">\r\n <mat-icon fontIcon=\"close\"/>\r\n </button>\r\n </mat-form-field>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <mat-form-field>\r\n <input matInput disabled [placeholder]=\"placeholder()\"> <!-- [disabled]=\"!isEdge\" -->\r\n </mat-form-field>\r\n }\r\n </div>\r\n} @else {\r\n <mat-progress-bar mode=\"indeterminate\"/>\r\n}", styles: [".user{display:grid;grid-template-columns:auto 1fr;grid-gap:.5em;align-items:center}.clickable,.clickable input{cursor:pointer!important}img{width:2em;height:2em;border-radius:100%}@media(min-width:801px){.grid{display:grid;grid-template-columns:repeat(2,1fr);grid-gap:1em}.three{grid-template-columns:repeat(3,1fr)}.four{grid-template-columns:repeat(4,1fr)}.five{grid-template-columns:repeat(5,1fr)}::ng-deep .grid mat-form-field{width:15vw}}input[disabled]{pointer-events:none}\n"] }]
|
|
643
652
|
}], propDecorators: { usersSelected: [{ type: i0.Output, args: ["usersSelected"] }], userUnSelected: [{ type: i0.Output, args: ["userUnSelected"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], userChooserData: [{ type: i0.Input, args: [{ isSignal: true, alias: "userChooserData", required: true }] }] } });
|
|
644
653
|
|
|
645
654
|
class MatActiveDirectoryModule {
|
|
@@ -659,8 +668,8 @@ class MatActiveDirectoryModule {
|
|
|
659
668
|
throw new Error('MatActiveDirectoryModule is already loaded. Import it in the AppModule only');
|
|
660
669
|
}
|
|
661
670
|
}
|
|
662
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
663
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
671
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: MatActiveDirectoryModule, deps: [{ token: MatActiveDirectoryModule, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
672
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.1", ngImport: i0, type: MatActiveDirectoryModule, imports: [CommonModule,
|
|
664
673
|
ReactiveFormsModule,
|
|
665
674
|
MatButtonModule,
|
|
666
675
|
MatDialogModule,
|
|
@@ -676,7 +685,7 @@ class MatActiveDirectoryModule {
|
|
|
676
685
|
UserChooserComponent,
|
|
677
686
|
UserFormFieldComponent], exports: [UserChooserComponent,
|
|
678
687
|
UserFormFieldComponent] }); }
|
|
679
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
688
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: MatActiveDirectoryModule, imports: [CommonModule,
|
|
680
689
|
ReactiveFormsModule,
|
|
681
690
|
MatButtonModule,
|
|
682
691
|
MatDialogModule,
|
|
@@ -692,7 +701,7 @@ class MatActiveDirectoryModule {
|
|
|
692
701
|
UserChooserComponent,
|
|
693
702
|
UserFormFieldComponent] }); }
|
|
694
703
|
}
|
|
695
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
704
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: MatActiveDirectoryModule, decorators: [{
|
|
696
705
|
type: NgModule,
|
|
697
706
|
args: [{
|
|
698
707
|
declarations: [],
|