@cleavelandprice/ngx-lib 3.1.9 → 3.1.11
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/active-directory/gui/components/user-chooser/user-chooser.component.d.ts +54 -0
- package/active-directory/gui/components/user-form-field/user-form-field.component.d.ts +27 -0
- package/active-directory/gui/gui.module.d.ts +20 -0
- package/active-directory/gui/index.d.ts +5 -0
- package/active-directory/gui/model/default-user-chooser-config.d.ts +2 -0
- package/active-directory/gui/model/default-user-chooser-filter-options-config.d.ts +2 -0
- package/active-directory/gui/model/default-user-chooser-pre-processing-group-config.d.ts +2 -0
- package/active-directory/gui/model/selectable-user.d.ts +5 -0
- package/active-directory/gui/model/user-chooser-data.d.ts +21 -0
- package/active-directory/gui/model/user-chooser-filter-options.d.ts +7 -0
- package/active-directory/gui/model/user-chooser-mode.d.ts +4 -0
- package/active-directory/gui/model/user-chooser-pre-processing-group.d.ts +6 -0
- package/active-directory/gui/public_api.d.ts +10 -0
- package/authentication/token/gui/token-gui.module.d.ts +6 -6
- package/esm2020/active-directory/active-directory.module.mjs +3 -2
- package/esm2020/active-directory/gui/cleavelandprice-ngx-lib-active-directory-gui.mjs +5 -0
- package/esm2020/active-directory/gui/components/user-chooser/user-chooser.component.mjs +352 -0
- package/esm2020/active-directory/gui/components/user-form-field/user-form-field.component.mjs +118 -0
- package/esm2020/active-directory/gui/gui.module.mjs +73 -0
- package/esm2020/active-directory/gui/model/default-user-chooser-config.mjs +18 -0
- package/esm2020/active-directory/gui/model/default-user-chooser-filter-options-config.mjs +8 -0
- package/esm2020/active-directory/gui/model/default-user-chooser-pre-processing-group-config.mjs +7 -0
- package/esm2020/active-directory/gui/model/selectable-user.mjs +2 -0
- package/esm2020/active-directory/gui/model/user-chooser-data.mjs +2 -0
- package/esm2020/active-directory/gui/model/user-chooser-filter-options.mjs +2 -0
- package/esm2020/active-directory/gui/model/user-chooser-mode.mjs +6 -0
- package/esm2020/active-directory/gui/model/user-chooser-pre-processing-group.mjs +2 -0
- package/esm2020/active-directory/gui/public_api.mjs +11 -0
- package/esm2020/authentication/token/gui/token-gui.module.mjs +9 -9
- package/fesm2015/cleavelandprice-ngx-lib-active-directory-gui.mjs +574 -0
- package/fesm2015/cleavelandprice-ngx-lib-active-directory-gui.mjs.map +1 -0
- package/fesm2015/cleavelandprice-ngx-lib-active-directory.mjs +2 -1
- package/fesm2015/cleavelandprice-ngx-lib-active-directory.mjs.map +1 -1
- package/fesm2015/cleavelandprice-ngx-lib-authentication-token-gui.mjs +9 -9
- package/fesm2015/cleavelandprice-ngx-lib-authentication-token-gui.mjs.map +1 -1
- package/fesm2020/cleavelandprice-ngx-lib-active-directory-gui.mjs +564 -0
- package/fesm2020/cleavelandprice-ngx-lib-active-directory-gui.mjs.map +1 -0
- package/fesm2020/cleavelandprice-ngx-lib-active-directory.mjs +2 -1
- package/fesm2020/cleavelandprice-ngx-lib-active-directory.mjs.map +1 -1
- package/fesm2020/cleavelandprice-ngx-lib-authentication-token-gui.mjs +9 -9
- package/fesm2020/cleavelandprice-ngx-lib-authentication-token-gui.mjs.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, Inject, ViewChild, EventEmitter, Output, Input, NgModule } from '@angular/core';
|
|
3
|
+
import * as i5 from '@angular/forms';
|
|
4
|
+
import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
5
|
+
import * as i1 from '@angular/material/dialog';
|
|
6
|
+
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
7
|
+
import * as i10 from '@angular/material/list';
|
|
8
|
+
import { MatSelectionList, MatListModule } from '@angular/material/list';
|
|
9
|
+
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
10
|
+
import { of, forkJoin, debounceTime } from 'rxjs';
|
|
11
|
+
import * as i2 from '@cleavelandprice/ngx-lib/active-directory';
|
|
12
|
+
import * as i3 from '@cleavelandprice/ngx-lib/sharepoint';
|
|
13
|
+
import * as i4 from '@angular/common';
|
|
14
|
+
import { CommonModule } from '@angular/common';
|
|
15
|
+
import * as i6 from '@angular/material/button';
|
|
16
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
17
|
+
import * as i7 from '@angular/material/form-field';
|
|
18
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
19
|
+
import * as i8 from '@angular/material/icon';
|
|
20
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
21
|
+
import * as i9 from '@angular/material/input';
|
|
22
|
+
import { MatInputModule } from '@angular/material/input';
|
|
23
|
+
import * as i11 from '@angular/material/progress-spinner';
|
|
24
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
25
|
+
import * as i12 from '@angular/material/slide-toggle';
|
|
26
|
+
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
27
|
+
import * as i13 from '@angular/material/tooltip';
|
|
28
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
29
|
+
|
|
30
|
+
const defaultUserChooserFilterOptionsConfig = {
|
|
31
|
+
accountName: true,
|
|
32
|
+
department: true,
|
|
33
|
+
groupMembership: false,
|
|
34
|
+
phoneNumber: true,
|
|
35
|
+
title: true
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const defaultUserChooserPreProcessingGroupConfig = {
|
|
39
|
+
accountNames: [],
|
|
40
|
+
departments: [],
|
|
41
|
+
groups: [],
|
|
42
|
+
titles: []
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
var UserChooserMode;
|
|
46
|
+
(function (UserChooserMode) {
|
|
47
|
+
UserChooserMode[UserChooserMode["Single"] = 0] = "Single";
|
|
48
|
+
UserChooserMode[UserChooserMode["Multiple"] = 1] = "Multiple";
|
|
49
|
+
})(UserChooserMode || (UserChooserMode = {}));
|
|
50
|
+
|
|
51
|
+
const defaultUserChooserConfig = {
|
|
52
|
+
closeWhenSelectionMade: false,
|
|
53
|
+
includeDisabledUsers: false,
|
|
54
|
+
parentOu: undefined,
|
|
55
|
+
showGroupMembershipTooltips: false,
|
|
56
|
+
showPhone: true,
|
|
57
|
+
title: 'Select User(s)',
|
|
58
|
+
mode: UserChooserMode.Single,
|
|
59
|
+
returnUserObjects: false,
|
|
60
|
+
filterOptions: defaultUserChooserFilterOptionsConfig,
|
|
61
|
+
exclusions: defaultUserChooserPreProcessingGroupConfig,
|
|
62
|
+
inclusions: defaultUserChooserPreProcessingGroupConfig,
|
|
63
|
+
preSelections: defaultUserChooserPreProcessingGroupConfig
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
class UserChooserComponent {
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region Lifecycle
|
|
69
|
+
constructor(data, dialogRef, activeDirectoryService, sharePointService) {
|
|
70
|
+
this.data = data;
|
|
71
|
+
this.dialogRef = dialogRef;
|
|
72
|
+
this.activeDirectoryService = activeDirectoryService;
|
|
73
|
+
this.sharePointService = sharePointService;
|
|
74
|
+
//#region Fields
|
|
75
|
+
this.selectionList = null;
|
|
76
|
+
this.filterForm = new FormGroup({
|
|
77
|
+
filter: new FormControl()
|
|
78
|
+
});
|
|
79
|
+
this.dataSource = null;
|
|
80
|
+
this.photos = null;
|
|
81
|
+
this.groups = null; // May or may not get populated, depending on config data sent in
|
|
82
|
+
this.data = Object.assign(Object.assign({}, defaultUserChooserConfig), data);
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region Properties
|
|
86
|
+
get isMultiMode() {
|
|
87
|
+
return this.data.mode === UserChooserMode.Multiple;
|
|
88
|
+
}
|
|
89
|
+
get selectedOptions() {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
return (_b = (_a = this.selectionList) === null || _a === void 0 ? void 0 : _a.options.filter(o => o.selected)) !== null && _b !== void 0 ? _b : [];
|
|
92
|
+
}
|
|
93
|
+
get filterValue() {
|
|
94
|
+
return this.filterForm.value.filter;
|
|
95
|
+
}
|
|
96
|
+
get adGroupsNeeded() {
|
|
97
|
+
// If any are these are true, then we need to pull AD groups for use later
|
|
98
|
+
return this.data.showGroupMembershipTooltips ||
|
|
99
|
+
this.data.exclusions.groups.length > 0 ||
|
|
100
|
+
this.data.inclusions.groups.length > 0 ||
|
|
101
|
+
this.data.preSelections.groups.length > 0 ||
|
|
102
|
+
this.data.filterOptions.groupMembership;
|
|
103
|
+
}
|
|
104
|
+
ngOnInit() {
|
|
105
|
+
this.getData();
|
|
106
|
+
this.listenForFilterChanges();
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region Events
|
|
110
|
+
listSelectionChanged(options) {
|
|
111
|
+
if (this.data.mode === UserChooserMode.Single &&
|
|
112
|
+
this.selectedOptions.length &&
|
|
113
|
+
this.data.closeWhenSelectionMade) {
|
|
114
|
+
this.close();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
optionSelectionChanged(option) {
|
|
118
|
+
var _a;
|
|
119
|
+
const user = (_a = this.dataSource) === null || _a === void 0 ? void 0 : _a.data.find(u => u.sAMAccountName.toLocaleLowerCase() === option.value.sAMAccountName.toLowerCase());
|
|
120
|
+
if (user) {
|
|
121
|
+
user.selected = option.selected;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
hideUnselectedChanged(selected) {
|
|
125
|
+
var _a;
|
|
126
|
+
(_a = this.filterForm.get('filter')) === null || _a === void 0 ? void 0 : _a.setValue(selected ? '{selected:true}' : null);
|
|
127
|
+
}
|
|
128
|
+
selectAll() {
|
|
129
|
+
var _a, _b, _c;
|
|
130
|
+
(_a = this.selectionList) === null || _a === void 0 ? void 0 : _a.selectAll();
|
|
131
|
+
if ((_b = this.selectionList) === null || _b === void 0 ? void 0 : _b.options) {
|
|
132
|
+
this.listSelectionChanged((_c = this.selectionList) === null || _c === void 0 ? void 0 : _c.options.toArray());
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
deselectAll() {
|
|
136
|
+
var _a;
|
|
137
|
+
(_a = this.selectionList) === null || _a === void 0 ? void 0 : _a.deselectAll();
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region Utilities
|
|
141
|
+
getData() {
|
|
142
|
+
const dataObservables = [
|
|
143
|
+
this.data.users ?
|
|
144
|
+
// Users were passed in
|
|
145
|
+
of(this.data.users) :
|
|
146
|
+
// Users need to be retrieved
|
|
147
|
+
this.activeDirectoryService.getUsers(false, this.data.includeDisabledUsers, this.data.parentOu),
|
|
148
|
+
this.data.photos ?
|
|
149
|
+
// Photos were passed in
|
|
150
|
+
of(this.data.photos) :
|
|
151
|
+
// Photos need to be retrieved
|
|
152
|
+
this.sharePointService.getPhotos()
|
|
153
|
+
];
|
|
154
|
+
// Do we need AD groups?
|
|
155
|
+
if (this.adGroupsNeeded) {
|
|
156
|
+
dataObservables.push(this.activeDirectoryService.getGroups());
|
|
157
|
+
}
|
|
158
|
+
forkJoin(dataObservables)
|
|
159
|
+
//.subscribe(([users, photos]) => {
|
|
160
|
+
.subscribe(data => {
|
|
161
|
+
// Need groups in place before we handle exclusions/inclusions/pre-selections
|
|
162
|
+
this.groups = this.adGroupsNeeded ? data[2] : null;
|
|
163
|
+
let users = data[0];
|
|
164
|
+
users = this.includeUsersByAccountName(users);
|
|
165
|
+
users = this.includeUsersByGroupName(users);
|
|
166
|
+
users = this.includeUsersByDepartment(users);
|
|
167
|
+
users = this.includeUsersByTitle(users);
|
|
168
|
+
users = this.excludeUsersByAccountName(users);
|
|
169
|
+
users = this.excludeUsersByGroupName(users);
|
|
170
|
+
users = this.excludeUsersByDepartment(users);
|
|
171
|
+
users = this.excludeUsersByTitle(users);
|
|
172
|
+
users = this.preSelectUsersByAccountName(users);
|
|
173
|
+
users = this.preSelectUsersByGroupName(users);
|
|
174
|
+
users = this.preSelectUsersByDepartment(users);
|
|
175
|
+
users = this.preSelectUsersByTitle(users);
|
|
176
|
+
this.dataSource = new MatTableDataSource(users);
|
|
177
|
+
this.photos = data[1];
|
|
178
|
+
this.setFilterPredicate();
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
close() {
|
|
182
|
+
this.dialogRef.close(this.selectedOptions
|
|
183
|
+
.map(o => o.value)
|
|
184
|
+
.map(u => this.data.returnUserObjects ? u : u.sAMAccountName));
|
|
185
|
+
}
|
|
186
|
+
getPhoto(user) {
|
|
187
|
+
var _a, _b;
|
|
188
|
+
return (_b = (_a = this.photos) === null || _a === void 0 ? void 0 : _a.find(p => {
|
|
189
|
+
var _a, _b, _c;
|
|
190
|
+
return (p.employeeNumber && p.employeeNumber.toString() === user.employeeNumber) ||
|
|
191
|
+
((_a = p.accountName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === user.sAMAccountName.toLowerCase() ||
|
|
192
|
+
((_b = p.displayName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === user.displayName.toLowerCase() ||
|
|
193
|
+
((_c = p.title) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === user.displayName.toLowerCase();
|
|
194
|
+
})) === null || _b === void 0 ? void 0 : _b.encodedAbsUrl;
|
|
195
|
+
}
|
|
196
|
+
//#region Exclusions - won't be included in the dataSource at all
|
|
197
|
+
excludeUsersByAccountName(users) {
|
|
198
|
+
this.data.exclusions.accountNames
|
|
199
|
+
.forEach(accountName => {
|
|
200
|
+
const index = users.findIndex(u => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
201
|
+
if (index === -1) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
users.splice(index, 1);
|
|
205
|
+
});
|
|
206
|
+
return users;
|
|
207
|
+
}
|
|
208
|
+
excludeUsersByGroupName(users) {
|
|
209
|
+
this.data.exclusions.groups
|
|
210
|
+
.forEach(groupName => {
|
|
211
|
+
var _a;
|
|
212
|
+
const group = (_a = this.groups) === null || _a === void 0 ? void 0 : _a.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
213
|
+
if (!group) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
group.member.forEach(groupMemberDn => {
|
|
217
|
+
const index = users.findIndex(u => u.distinguishedName === groupMemberDn);
|
|
218
|
+
if (index === -1) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
users.splice(index, 1);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
return users;
|
|
225
|
+
}
|
|
226
|
+
excludeUsersByDepartment(users) {
|
|
227
|
+
this.data.exclusions.departments
|
|
228
|
+
.forEach(department => {
|
|
229
|
+
const excludedUsers = users.filter(u => { var _a; return ((_a = u.department) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === department.toLowerCase(); });
|
|
230
|
+
excludedUsers.forEach(user => {
|
|
231
|
+
const index = users.indexOf(user);
|
|
232
|
+
users.splice(index, 1);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
return users;
|
|
236
|
+
}
|
|
237
|
+
excludeUsersByTitle(users) {
|
|
238
|
+
this.data.exclusions.titles
|
|
239
|
+
.forEach(title => {
|
|
240
|
+
const excludedUsers = users.filter(u => { var _a; return ((_a = u.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === title.toLowerCase(); });
|
|
241
|
+
excludedUsers.forEach(user => {
|
|
242
|
+
const index = users.indexOf(user);
|
|
243
|
+
users.splice(index, 1);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
return users;
|
|
247
|
+
}
|
|
248
|
+
//#endregion
|
|
249
|
+
//#region Inclusions - only these will be included in the dataSource
|
|
250
|
+
includeUsersByAccountName(users) {
|
|
251
|
+
return users.filter(user => this.data.inclusions.accountNames.length === 0 || // No account inclusions specified
|
|
252
|
+
this.data.inclusions.accountNames.find(accountName => accountName.toLowerCase() === user.sAMAccountName.toLowerCase()));
|
|
253
|
+
}
|
|
254
|
+
includeUsersByDepartment(users) {
|
|
255
|
+
return users.filter(user => this.data.inclusions.departments.length === 0 || // No department inclusions specified
|
|
256
|
+
this.data.inclusions.departments.find(department => { var _a; return department.toLowerCase() === ((_a = user.department) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }));
|
|
257
|
+
}
|
|
258
|
+
includeUsersByTitle(users) {
|
|
259
|
+
return users.filter(user => this.data.inclusions.titles.length === 0 || // No title inclusions specified
|
|
260
|
+
this.data.inclusions.titles.find(title => { var _a; return title.toLowerCase() === ((_a = user.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }));
|
|
261
|
+
}
|
|
262
|
+
includeUsersByGroupName(users) {
|
|
263
|
+
if (!this.data.inclusions.groups.length) {
|
|
264
|
+
return users; // No group inclusions specified
|
|
265
|
+
}
|
|
266
|
+
// Cheating a bit and leveraging the 'selected' property to keep track of who should be included
|
|
267
|
+
// Since inclusions happen befor pre-selections, we can do that, as long as we set 'selected' back to false when we're done
|
|
268
|
+
this.data.inclusions.groups
|
|
269
|
+
.forEach(groupName => {
|
|
270
|
+
var _a;
|
|
271
|
+
const group = (_a = this.groups) === null || _a === void 0 ? void 0 : _a.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
272
|
+
if (!group) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
users
|
|
276
|
+
.filter(user => group.member.find(groupMemberDn => groupMemberDn === user.distinguishedName))
|
|
277
|
+
.forEach(user => user.selected = true);
|
|
278
|
+
});
|
|
279
|
+
// At this point, all of the appropriate users should have 'selected' set to true
|
|
280
|
+
const selectedUsers = users.filter(user => user.selected); // Subset of the original list
|
|
281
|
+
// Reset 'selected' to false, and return
|
|
282
|
+
selectedUsers.forEach(user => user.selected = false);
|
|
283
|
+
return selectedUsers;
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region Pre-Selections
|
|
287
|
+
preSelectUsersByAccountName(users) {
|
|
288
|
+
this.data.preSelections.accountNames
|
|
289
|
+
.forEach(accountName => {
|
|
290
|
+
const user = users.find(u => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
291
|
+
if (!user) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
user.selected = true;
|
|
295
|
+
});
|
|
296
|
+
return users;
|
|
297
|
+
}
|
|
298
|
+
preSelectUsersByDepartment(users) {
|
|
299
|
+
this.data.preSelections.departments
|
|
300
|
+
.forEach(department => users
|
|
301
|
+
.filter(u => { var _a; return ((_a = u.department) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === department.toLowerCase(); })
|
|
302
|
+
.forEach(user => user.selected = true));
|
|
303
|
+
return users;
|
|
304
|
+
}
|
|
305
|
+
preSelectUsersByTitle(users) {
|
|
306
|
+
this.data.preSelections.titles
|
|
307
|
+
.forEach(title => users
|
|
308
|
+
.filter(u => { var _a; return ((_a = u.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === title.toLowerCase(); })
|
|
309
|
+
.forEach(user => user.selected = true));
|
|
310
|
+
return users;
|
|
311
|
+
}
|
|
312
|
+
preSelectUsersByGroupName(users) {
|
|
313
|
+
this.data.preSelections.groups
|
|
314
|
+
.forEach(groupName => {
|
|
315
|
+
var _a;
|
|
316
|
+
const group = (_a = this.groups) === null || _a === void 0 ? void 0 : _a.find(g => g.name.toLowerCase() === groupName.toLowerCase());
|
|
317
|
+
if (!group) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
group.member.forEach(groupMemberDn => {
|
|
321
|
+
const user = users.find(u => u.distinguishedName === groupMemberDn);
|
|
322
|
+
if (!user) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
user.selected = true;
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
return users;
|
|
329
|
+
}
|
|
330
|
+
//#endregion
|
|
331
|
+
setFilterPredicate() {
|
|
332
|
+
if (!this.dataSource) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
this.dataSource.filterPredicate = (user, filter) => {
|
|
336
|
+
if (filter === '{selected:true}') {
|
|
337
|
+
return user.selected;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
const regex = new RegExp(filter, 'i'); // Case-insensitive
|
|
341
|
+
let match = false; // The end result - whether or not a employee matches the filter
|
|
342
|
+
const filterProperties = ['displayName'];
|
|
343
|
+
if (this.data.filterOptions.accountName) {
|
|
344
|
+
filterProperties.push('sAMAccountName');
|
|
345
|
+
}
|
|
346
|
+
if (this.data.filterOptions.title) {
|
|
347
|
+
filterProperties.push('title');
|
|
348
|
+
}
|
|
349
|
+
if (this.data.filterOptions.department) {
|
|
350
|
+
filterProperties.push('department');
|
|
351
|
+
}
|
|
352
|
+
if (this.data.filterOptions.phoneNumber) {
|
|
353
|
+
filterProperties.push('telephoneNumber');
|
|
354
|
+
}
|
|
355
|
+
// Match on the properties configured above
|
|
356
|
+
filterProperties
|
|
357
|
+
.forEach(field => {
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
if (user[field] && user[field].match(regex)) {
|
|
360
|
+
match = true;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
// Match on group membership (group name)
|
|
364
|
+
if (this.data.filterOptions.groupMembership) {
|
|
365
|
+
user.memberOf.forEach(groupDn => {
|
|
366
|
+
var _a;
|
|
367
|
+
const group = (_a = this.groups) === null || _a === void 0 ? void 0 : _a.find(group => group.distinguishedName === groupDn && group.name.match(regex));
|
|
368
|
+
if (group) {
|
|
369
|
+
match = true;
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
return match;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
listenForFilterChanges() {
|
|
378
|
+
var _a;
|
|
379
|
+
(_a = this.filterForm.get('filter')) === null || _a === void 0 ? void 0 : _a.valueChanges.pipe(debounceTime(500)).subscribe(() => { var _a; return this.dataSource.filter = (_a = this.filterForm.value.filter) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase(); });
|
|
380
|
+
}
|
|
381
|
+
tooltip(user) {
|
|
382
|
+
return this.data.showGroupMembershipTooltips ?
|
|
383
|
+
user.memberOf
|
|
384
|
+
.map(groupDn => {
|
|
385
|
+
var _a, _b;
|
|
386
|
+
return (_b = (_a = this.groups) === null || _a === void 0 ? void 0 : _a.find(group => group.distinguishedName === groupDn)) === null || _b === void 0 ? void 0 : _b.name;
|
|
387
|
+
})
|
|
388
|
+
.sort((a, b) => a > b ? 1 : -1)
|
|
389
|
+
.join('\n') :
|
|
390
|
+
'';
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
UserChooserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: UserChooserComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.ActiveDirectoryService }, { token: i3.SharePointService }], target: i0.ɵɵFactoryTarget.Component });
|
|
394
|
+
UserChooserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.1", type: UserChooserComponent, selector: "user-chooser", viewQueries: [{ propertyName: "selectionList", first: true, predicate: MatSelectionList, descendants: true }], ngImport: i0, template: "<div id=\"dialog-title\">\n <h2 mat-dialog-title>{{ data.title }}</h2>\n\n <div>\n {{ selectedOptions.length }} selected\n </div>\n</div>\n\n<mat-dialog-content>\n <div *ngIf=\"!(dataSource && photos)\">\n <mat-spinner [diameter]=\"50\"></mat-spinner>\n <h2 id=\"spinner-message\">Getting users and photos...</h2>\n </div>\n\n <ng-container *ngIf=\"dataSource && photos\">\n <form [formGroup]=\"filterForm\">\n <mat-form-field *ngIf=\"dataSource\">\n <input matInput placeholder=\"Search\" formControlName=\"filter\">\n\n <button *ngIf=\"filterForm.value.filter\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"filterForm.get('filter')?.setValue('')\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </button>\n </mat-form-field>\n </form>\n\n <mat-selection-list [multiple]=\"isMultiMode\"\n (selectionChange)=\"listSelectionChanged($event.options)\">\n\n <mat-list-option *ngFor=\"let user of dataSource?.filteredData\" [value]=\"user\" [selected]=\"user.selected\"\n (selectedChange)=\"optionSelectionChanged(option)\" #option>\n\n <img *ngIf=\"getPhoto(user)\" matListAvatar alt=\"\" [src]=\"getPhoto(user)\">\n\n <mat-icon *ngIf=\"!getPhoto(user)\" matListAvatar class=\"no-photo\"\n fontIcon=\"account_circle\">\n </mat-icon>\n \n <div class=\"user\">\n <div [matTooltip]=\"tooltip(user)\" class=\"user-name\">\n {{ user.displayName }}\n <div *ngIf=\"data.showPhone && user.telephoneNumber\">{{ user.telephoneNumber }}</div>\n </div>\n \n <div>{{ user.department }}</div>\n \n <div class=\"title\">{{ user.title }}</div>\n </div>\n </mat-list-option>\n </mat-selection-list>\n </ng-container>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"dataSource && photos\">\n <mat-slide-toggle *ngIf=\"selectedOptions.length\" (change)=\"hideUnselectedChanged($event.checked)\">\n Hide Unselected\n </mat-slide-toggle>\n\n <button mat-raised-button color=\"primary\" (click)=\"selectAll()\"\n *ngIf=\"isMultiMode\">\n <mat-icon fontIcon=\"select_all\"></mat-icon>\n <span class=\"hide-mobile\">Select All</span>\n </button>\n \n <button mat-raised-button color=\"primary\" (click)=\"deselectAll()\"\n *ngIf=\"isMultiMode && selectedOptions.length\">\n <mat-icon fontIcon=\"clear_all\"></mat-icon>\n <span class=\"hide-mobile\">Clear All</span>\n </button>\n\n <button mat-raised-button color=\"primary\" (click)=\"close()\" matTooltip=\"Accept your selection\"\n [disabled]=\"!selectedOptions.length\">\n <mat-icon fontIcon=\"check\"></mat-icon>\n <span class=\"hide-mobile\">Ok</span>\n </button>\n </ng-container>\n\n <button mat-raised-button color=\"warn\" mat-dialog-close matTooltip=\"Close this window\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n <span class=\"hide-mobile\">Cancel</span>\n </button>\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}.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: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix]" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i10.MatListAvatarCssMatStyler, selector: "[mat-list-avatar], [matListAvatar]" }, { kind: "component", type: i10.MatSelectionList, selector: "mat-selection-list", inputs: ["disableRipple", "color", "compareWith", "disabled", "multiple"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i10.MatListOption, selector: "mat-list-option", inputs: ["disableRipple", "checkboxPosition", "color", "value", "disabled", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: i11.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i12.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
395
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: UserChooserComponent, decorators: [{
|
|
396
|
+
type: Component,
|
|
397
|
+
args: [{ selector: 'user-chooser', template: "<div id=\"dialog-title\">\n <h2 mat-dialog-title>{{ data.title }}</h2>\n\n <div>\n {{ selectedOptions.length }} selected\n </div>\n</div>\n\n<mat-dialog-content>\n <div *ngIf=\"!(dataSource && photos)\">\n <mat-spinner [diameter]=\"50\"></mat-spinner>\n <h2 id=\"spinner-message\">Getting users and photos...</h2>\n </div>\n\n <ng-container *ngIf=\"dataSource && photos\">\n <form [formGroup]=\"filterForm\">\n <mat-form-field *ngIf=\"dataSource\">\n <input matInput placeholder=\"Search\" formControlName=\"filter\">\n\n <button *ngIf=\"filterForm.value.filter\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"filterForm.get('filter')?.setValue('')\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </button>\n </mat-form-field>\n </form>\n\n <mat-selection-list [multiple]=\"isMultiMode\"\n (selectionChange)=\"listSelectionChanged($event.options)\">\n\n <mat-list-option *ngFor=\"let user of dataSource?.filteredData\" [value]=\"user\" [selected]=\"user.selected\"\n (selectedChange)=\"optionSelectionChanged(option)\" #option>\n\n <img *ngIf=\"getPhoto(user)\" matListAvatar alt=\"\" [src]=\"getPhoto(user)\">\n\n <mat-icon *ngIf=\"!getPhoto(user)\" matListAvatar class=\"no-photo\"\n fontIcon=\"account_circle\">\n </mat-icon>\n \n <div class=\"user\">\n <div [matTooltip]=\"tooltip(user)\" class=\"user-name\">\n {{ user.displayName }}\n <div *ngIf=\"data.showPhone && user.telephoneNumber\">{{ user.telephoneNumber }}</div>\n </div>\n \n <div>{{ user.department }}</div>\n \n <div class=\"title\">{{ user.title }}</div>\n </div>\n </mat-list-option>\n </mat-selection-list>\n </ng-container>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"dataSource && photos\">\n <mat-slide-toggle *ngIf=\"selectedOptions.length\" (change)=\"hideUnselectedChanged($event.checked)\">\n Hide Unselected\n </mat-slide-toggle>\n\n <button mat-raised-button color=\"primary\" (click)=\"selectAll()\"\n *ngIf=\"isMultiMode\">\n <mat-icon fontIcon=\"select_all\"></mat-icon>\n <span class=\"hide-mobile\">Select All</span>\n </button>\n \n <button mat-raised-button color=\"primary\" (click)=\"deselectAll()\"\n *ngIf=\"isMultiMode && selectedOptions.length\">\n <mat-icon fontIcon=\"clear_all\"></mat-icon>\n <span class=\"hide-mobile\">Clear All</span>\n </button>\n\n <button mat-raised-button color=\"primary\" (click)=\"close()\" matTooltip=\"Accept your selection\"\n [disabled]=\"!selectedOptions.length\">\n <mat-icon fontIcon=\"check\"></mat-icon>\n <span class=\"hide-mobile\">Ok</span>\n </button>\n </ng-container>\n\n <button mat-raised-button color=\"warn\" mat-dialog-close matTooltip=\"Close this window\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n <span class=\"hide-mobile\">Cancel</span>\n </button>\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}.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"] }]
|
|
398
|
+
}], ctorParameters: function () {
|
|
399
|
+
return [{ type: undefined, decorators: [{
|
|
400
|
+
type: Inject,
|
|
401
|
+
args: [MAT_DIALOG_DATA]
|
|
402
|
+
}] }, { type: i1.MatDialogRef }, { type: i2.ActiveDirectoryService }, { type: i3.SharePointService }];
|
|
403
|
+
}, propDecorators: { selectionList: [{
|
|
404
|
+
type: ViewChild,
|
|
405
|
+
args: [MatSelectionList]
|
|
406
|
+
}] } });
|
|
407
|
+
|
|
408
|
+
class UserFormFieldComponent {
|
|
409
|
+
//#endregion
|
|
410
|
+
//#region Lifecycle
|
|
411
|
+
constructor(dialog, activeDirectoryService, sharePointService) {
|
|
412
|
+
this.dialog = dialog;
|
|
413
|
+
this.activeDirectoryService = activeDirectoryService;
|
|
414
|
+
this.sharePointService = sharePointService;
|
|
415
|
+
//#region Fields
|
|
416
|
+
this.usersSelected = new EventEmitter();
|
|
417
|
+
this.placeholder = 'Select User(s)';
|
|
418
|
+
this.clickable = true;
|
|
419
|
+
/*
|
|
420
|
+
@Input() mode = UserChooserMode.Multiple;
|
|
421
|
+
@Input() preSelectAccountNames = true;
|
|
422
|
+
@Input() includeDisabledUsers = false;
|
|
423
|
+
@Input() parentOu = undefined;*/
|
|
424
|
+
this.accountNames = [];
|
|
425
|
+
this.users = undefined;
|
|
426
|
+
this.photos = undefined;
|
|
427
|
+
}
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region Properties
|
|
430
|
+
get isEdge() {
|
|
431
|
+
return window.navigator.userAgent.indexOf('Edge') > -1;
|
|
432
|
+
}
|
|
433
|
+
ngOnInit() {
|
|
434
|
+
this.userChooserData = Object.assign(Object.assign({}, defaultUserChooserConfig), this.userChooserData);
|
|
435
|
+
// If users have been pre-selected in the config, store those in accountNames, which drives the UI of this component
|
|
436
|
+
this.accountNames = this.userChooserData.preSelections.accountNames;
|
|
437
|
+
this.getData();
|
|
438
|
+
}
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region Events
|
|
441
|
+
selectUser() {
|
|
442
|
+
if (!this.clickable) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const data = Object.assign(Object.assign({}, this.userChooserData), { users: this.users, photos: this.photos });
|
|
446
|
+
this.dialog.open(UserChooserComponent, {
|
|
447
|
+
data: data
|
|
448
|
+
})
|
|
449
|
+
.afterClosed()
|
|
450
|
+
.subscribe(accountNames => {
|
|
451
|
+
if (!accountNames) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
this.accountNames = accountNames;
|
|
455
|
+
this.usersSelected.emit(accountNames);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region Utilities
|
|
460
|
+
getData() {
|
|
461
|
+
forkJoin([
|
|
462
|
+
this.userChooserData.users ?
|
|
463
|
+
// Users were passed in
|
|
464
|
+
of(this.userChooserData.users) :
|
|
465
|
+
// Users need to be retrieved
|
|
466
|
+
this.activeDirectoryService.getUsers(false, this.userChooserData.includeDisabledUsers, this.userChooserData.parentOu),
|
|
467
|
+
this.userChooserData.photos ?
|
|
468
|
+
// Photos were passed in
|
|
469
|
+
of(this.userChooserData.photos) :
|
|
470
|
+
// Photos need to be retrieved
|
|
471
|
+
this.sharePointService.getPhotos()
|
|
472
|
+
])
|
|
473
|
+
.subscribe(([users, photos]) => {
|
|
474
|
+
this.users = users;
|
|
475
|
+
this.photos = photos;
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
getUser(accountName) {
|
|
479
|
+
var _a;
|
|
480
|
+
return (_a = this.users) === null || _a === void 0 ? void 0 : _a.find(u => u.sAMAccountName.toLowerCase() === accountName.toLowerCase());
|
|
481
|
+
}
|
|
482
|
+
getPhoto(accountName) {
|
|
483
|
+
var _a, _b;
|
|
484
|
+
const user = this.getUser(accountName);
|
|
485
|
+
if (!user) {
|
|
486
|
+
return undefined;
|
|
487
|
+
}
|
|
488
|
+
return (_b = (_a = this.photos) === null || _a === void 0 ? void 0 : _a.find(p => {
|
|
489
|
+
var _a, _b, _c;
|
|
490
|
+
return (p.employeeNumber && p.employeeNumber.toString() === user.employeeNumber) ||
|
|
491
|
+
((_a = p.accountName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === user.sAMAccountName.toLowerCase() ||
|
|
492
|
+
((_b = p.displayName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === user.displayName.toLowerCase() ||
|
|
493
|
+
((_c = p.title) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === user.displayName.toLowerCase();
|
|
494
|
+
})) === null || _b === void 0 ? void 0 : _b.encodedAbsUrl;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
UserFormFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: UserFormFieldComponent, deps: [{ token: i1.MatDialog }, { token: i2.ActiveDirectoryService }, { token: i3.SharePointService }], target: i0.ɵɵFactoryTarget.Component });
|
|
498
|
+
UserFormFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.1", type: UserFormFieldComponent, selector: "user-form-field", inputs: { placeholder: "placeholder", clickable: "clickable", userChooserData: "userChooserData" }, outputs: { usersSelected: "usersSelected" }, ngImport: i0, template: "<!-- In Microsoft Edge, selectEmployee() never gets called if the input fields are disabled\n So... I'm dynamically setting the disabled property based on whether or not the browser is Edge.\n It's definitely a better experience if the field IS disabled.\n Otherwise, it's confusing - especially because Edge is SO SLOW to display the resulting dialog window.\n-->\n\n<div (click)=\"selectUser()\" [class.clickable]=\"clickable\">\n <mat-form-field *ngIf=\"!accountNames?.length\">\n <input matInput [disabled]=\"!isEdge\" [placeholder]=\"placeholder\">\n </mat-form-field>\n \n <div *ngIf=\"accountNames?.length\"\n [class.grid]=\"accountNames.length > 1\"\n [class.three]=\"accountNames.length > 2\"\n [class.four]=\"accountNames.length > 3\"\n [class.five]=\"accountNames.length > 4\">\n\n <div *ngFor=\"let accountName of accountNames; let i=index\" class=\"user\">\n <!--<img *ngIf=\"accountName && empUtils.getEmployee(accountName)\" alt=\"\" [src]=\"empUtils.getEmployee(accountName) | employeePhotoUrl:cacheService.photos\">-->\n <img *ngIf=\"getPhoto(accountName)\" matListAvatar alt=\"\" [src]=\"getPhoto(accountName)\">\n \n <mat-form-field>\n <input matInput [disabled]=\"!isEdge\" [placeholder]=\"i === 0 ? placeholder : ''\"\n [value]=\"accountName ? getUser(accountName)?.displayName : accountName\">\n </mat-form-field>\n </div>\n </div>\n </div>", 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}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i10.MatListAvatarCssMatStyler, selector: "[mat-list-avatar], [matListAvatar]" }] });
|
|
499
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: UserFormFieldComponent, decorators: [{
|
|
500
|
+
type: Component,
|
|
501
|
+
args: [{ selector: 'user-form-field', template: "<!-- In Microsoft Edge, selectEmployee() never gets called if the input fields are disabled\n So... I'm dynamically setting the disabled property based on whether or not the browser is Edge.\n It's definitely a better experience if the field IS disabled.\n Otherwise, it's confusing - especially because Edge is SO SLOW to display the resulting dialog window.\n-->\n\n<div (click)=\"selectUser()\" [class.clickable]=\"clickable\">\n <mat-form-field *ngIf=\"!accountNames?.length\">\n <input matInput [disabled]=\"!isEdge\" [placeholder]=\"placeholder\">\n </mat-form-field>\n \n <div *ngIf=\"accountNames?.length\"\n [class.grid]=\"accountNames.length > 1\"\n [class.three]=\"accountNames.length > 2\"\n [class.four]=\"accountNames.length > 3\"\n [class.five]=\"accountNames.length > 4\">\n\n <div *ngFor=\"let accountName of accountNames; let i=index\" class=\"user\">\n <!--<img *ngIf=\"accountName && empUtils.getEmployee(accountName)\" alt=\"\" [src]=\"empUtils.getEmployee(accountName) | employeePhotoUrl:cacheService.photos\">-->\n <img *ngIf=\"getPhoto(accountName)\" matListAvatar alt=\"\" [src]=\"getPhoto(accountName)\">\n \n <mat-form-field>\n <input matInput [disabled]=\"!isEdge\" [placeholder]=\"i === 0 ? placeholder : ''\"\n [value]=\"accountName ? getUser(accountName)?.displayName : accountName\">\n </mat-form-field>\n </div>\n </div>\n </div>", 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}}\n"] }]
|
|
502
|
+
}], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i2.ActiveDirectoryService }, { type: i3.SharePointService }]; }, propDecorators: { usersSelected: [{
|
|
503
|
+
type: Output
|
|
504
|
+
}], placeholder: [{
|
|
505
|
+
type: Input
|
|
506
|
+
}], clickable: [{
|
|
507
|
+
type: Input
|
|
508
|
+
}], userChooserData: [{
|
|
509
|
+
type: Input
|
|
510
|
+
}] } });
|
|
511
|
+
|
|
512
|
+
class GuiModule {
|
|
513
|
+
}
|
|
514
|
+
GuiModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: GuiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
515
|
+
GuiModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.1", ngImport: i0, type: GuiModule, declarations: [UserChooserComponent,
|
|
516
|
+
UserFormFieldComponent], imports: [CommonModule,
|
|
517
|
+
ReactiveFormsModule,
|
|
518
|
+
MatButtonModule,
|
|
519
|
+
MatDialogModule,
|
|
520
|
+
MatFormFieldModule,
|
|
521
|
+
MatIconModule,
|
|
522
|
+
MatInputModule,
|
|
523
|
+
MatListModule,
|
|
524
|
+
MatProgressSpinnerModule,
|
|
525
|
+
MatSlideToggleModule,
|
|
526
|
+
MatTableModule,
|
|
527
|
+
MatTooltipModule], exports: [UserChooserComponent,
|
|
528
|
+
UserFormFieldComponent] });
|
|
529
|
+
GuiModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: GuiModule, imports: [CommonModule,
|
|
530
|
+
ReactiveFormsModule,
|
|
531
|
+
MatButtonModule,
|
|
532
|
+
MatDialogModule,
|
|
533
|
+
MatFormFieldModule,
|
|
534
|
+
MatIconModule,
|
|
535
|
+
MatInputModule,
|
|
536
|
+
MatListModule,
|
|
537
|
+
MatProgressSpinnerModule,
|
|
538
|
+
MatSlideToggleModule,
|
|
539
|
+
MatTableModule,
|
|
540
|
+
MatTooltipModule] });
|
|
541
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: GuiModule, decorators: [{
|
|
542
|
+
type: NgModule,
|
|
543
|
+
args: [{
|
|
544
|
+
declarations: [
|
|
545
|
+
UserChooserComponent,
|
|
546
|
+
UserFormFieldComponent
|
|
547
|
+
],
|
|
548
|
+
imports: [
|
|
549
|
+
CommonModule,
|
|
550
|
+
ReactiveFormsModule,
|
|
551
|
+
MatButtonModule,
|
|
552
|
+
MatDialogModule,
|
|
553
|
+
MatFormFieldModule,
|
|
554
|
+
MatIconModule,
|
|
555
|
+
MatInputModule,
|
|
556
|
+
MatListModule,
|
|
557
|
+
MatProgressSpinnerModule,
|
|
558
|
+
MatSlideToggleModule,
|
|
559
|
+
MatTableModule,
|
|
560
|
+
MatTooltipModule
|
|
561
|
+
],
|
|
562
|
+
exports: [
|
|
563
|
+
UserChooserComponent,
|
|
564
|
+
UserFormFieldComponent
|
|
565
|
+
]
|
|
566
|
+
}]
|
|
567
|
+
}] });
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Generated bundle index. Do not edit.
|
|
571
|
+
*/
|
|
572
|
+
|
|
573
|
+
export { GuiModule, UserChooserComponent, UserChooserMode, UserFormFieldComponent, defaultUserChooserConfig, defaultUserChooserFilterOptionsConfig, defaultUserChooserPreProcessingGroupConfig };
|
|
574
|
+
//# sourceMappingURL=cleavelandprice-ngx-lib-active-directory-gui.mjs.map
|