@tuki-io/tuki-widgets 0.0.213 → 0.0.214
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/esm2020/user-creation/src/utils/device-default-prefix.mjs +19 -2
- package/esm2020/user-creation/src/utils/device-name-dynamic-tokens.mjs +18 -0
- package/esm2020/user-creation/src/utils/parse-device-name-rule.mjs +6 -3
- package/esm2020/user-creation/src/widgets/user-creation-wizard/components/user-details-step/user-details-step.component.mjs +65 -12
- package/esm2020/user-creation/src/widgets/user-creation-wizard/user-creation-wizard.service.mjs +47 -11
- package/fesm2015/tuki-io-tuki-widgets-user-creation.mjs +151 -26
- package/fesm2015/tuki-io-tuki-widgets-user-creation.mjs.map +1 -1
- package/fesm2020/tuki-io-tuki-widgets-user-creation.mjs +149 -24
- package/fesm2020/tuki-io-tuki-widgets-user-creation.mjs.map +1 -1
- package/package.json +1 -1
- package/user-creation/src/utils/device-default-prefix.d.ts +7 -2
- package/user-creation/src/utils/device-name-dynamic-tokens.d.ts +5 -0
- package/user-creation/src/utils/parse-device-name-rule.d.ts +1 -0
- package/user-creation/src/widgets/user-creation-wizard/components/user-details-step/user-details-step.component.d.ts +3 -0
- package/user-creation/src/widgets/user-creation-wizard/user-creation-wizard.service.d.ts +2 -0
|
@@ -556,6 +556,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
556
556
|
}]
|
|
557
557
|
}] });
|
|
558
558
|
|
|
559
|
+
function deviceNameHasDynamicTokens(name) {
|
|
560
|
+
return /\[DN\]|\[LN\]|\[FN\]/i.test(name ?? '');
|
|
561
|
+
}
|
|
562
|
+
/** Device name field stays readonly while the template in `newName` contains placeholders. */
|
|
563
|
+
function isDeviceNameReadonlyFromTemplate(newName) {
|
|
564
|
+
return deviceNameHasDynamicTokens(newName);
|
|
565
|
+
}
|
|
566
|
+
/** Form field value without a separate `matPrefix` when `prefix` is already part of the resolved name. */
|
|
567
|
+
function stripDeviceNamePrefix(resolvedName, prefix) {
|
|
568
|
+
const trimmedPrefix = prefix?.trim();
|
|
569
|
+
if (!trimmedPrefix) {
|
|
570
|
+
return resolvedName;
|
|
571
|
+
}
|
|
572
|
+
return resolvedName.toUpperCase().startsWith(trimmedPrefix.toUpperCase())
|
|
573
|
+
? resolvedName.substring(trimmedPrefix.length)
|
|
574
|
+
: resolvedName;
|
|
575
|
+
}
|
|
576
|
+
|
|
559
577
|
function deviceNameValidator(options) {
|
|
560
578
|
return (control) => {
|
|
561
579
|
const raw = String(control.value ?? '').trim();
|
|
@@ -1016,10 +1034,27 @@ function buildSavableEndUser(endUser, lines, devices, deviceProfiles, form, opti
|
|
|
1016
1034
|
/** Matches device types like `Cisco 8851`. */
|
|
1017
1035
|
const CISCO_DIGIT_DEVICE_TYPE_PATTERN = /^Cisco\s+\d+$/i;
|
|
1018
1036
|
const DEFAULT_SEP_DEVICE_PREFIX = 'SEP';
|
|
1019
|
-
|
|
1037
|
+
/**
|
|
1038
|
+
* Extracts a literal prefix from `deviceNameExplained` patterns such as
|
|
1039
|
+
* `SEP[mac]`, `TCT[0-9A-Z._-]{1,12}`, or `[A-Z0-9]{1,15}` (no prefix).
|
|
1040
|
+
*/
|
|
1041
|
+
function extractDevicePrefixFromNameExplained(deviceNameExplained) {
|
|
1042
|
+
const explained = deviceNameExplained?.trim() ?? '';
|
|
1043
|
+
if (!explained) {
|
|
1044
|
+
return null;
|
|
1045
|
+
}
|
|
1046
|
+
const match = explained.match(/^([A-Za-z]+)\[/);
|
|
1047
|
+
return match?.[1] ?? null;
|
|
1048
|
+
}
|
|
1049
|
+
function applyDefaultDevicePrefixIfMissing(device, defaults) {
|
|
1020
1050
|
if (device.prefix?.trim()) {
|
|
1021
1051
|
return;
|
|
1022
1052
|
}
|
|
1053
|
+
const prefixFromDefaults = extractDevicePrefixFromNameExplained(defaults.deviceNameExplained);
|
|
1054
|
+
if (prefixFromDefaults) {
|
|
1055
|
+
device.prefix = prefixFromDefaults;
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1023
1058
|
const deviceType = device.deviceType?.trim() ?? '';
|
|
1024
1059
|
if (CISCO_DIGIT_DEVICE_TYPE_PATTERN.test(deviceType)) {
|
|
1025
1060
|
device.prefix = DEFAULT_SEP_DEVICE_PREFIX;
|
|
@@ -1031,6 +1066,7 @@ function applyDefaultDevicePrefixIfMissing(device) {
|
|
|
1031
1066
|
* to validate the name field value (without matPrefix).
|
|
1032
1067
|
*
|
|
1033
1068
|
* - `([sS][eE][pP]|BAT)[0-9a-fA-F]{12}` → `[0-9a-fA-F]{12}`
|
|
1069
|
+
* - `TCT[0-9A-Z._-]{1,12}` → `[0-9A-Z._-]{1,12}`
|
|
1034
1070
|
* - `[a-zA-Z0-9]{1,15}` → `[a-zA-Z0-9]{1,15}` (unchanged)
|
|
1035
1071
|
*/
|
|
1036
1072
|
function parseDeviceNameRegexBody(deviceNameRegex) {
|
|
@@ -1040,12 +1076,14 @@ function parseDeviceNameRegexBody(deviceNameRegex) {
|
|
|
1040
1076
|
}
|
|
1041
1077
|
return stripLeadingPrefixGroup(fullRegex);
|
|
1042
1078
|
}
|
|
1079
|
+
/** Character class with an optional trailing quantifier, e.g. `[0-9a-fA-F]{12}`. */
|
|
1080
|
+
const CHAR_CLASS_WITH_QUANTIFIER = String.raw `\[[^\]]+\](?:\{[^}]+\})?`;
|
|
1043
1081
|
function stripLeadingPrefixGroup(regex) {
|
|
1044
|
-
const parenMatch = regex.match(
|
|
1082
|
+
const parenMatch = regex.match(new RegExp(`^(\\([^)]+\\))(${CHAR_CLASS_WITH_QUANTIFIER})$`));
|
|
1045
1083
|
if (parenMatch?.[2]?.trim()) {
|
|
1046
1084
|
return parenMatch[2];
|
|
1047
1085
|
}
|
|
1048
|
-
const literalMatch = regex.match(
|
|
1086
|
+
const literalMatch = regex.match(new RegExp(`^([A-Za-z]+)(${CHAR_CLASS_WITH_QUANTIFIER})$`));
|
|
1049
1087
|
if (literalMatch?.[2]?.trim()) {
|
|
1050
1088
|
return literalMatch[2];
|
|
1051
1089
|
}
|
|
@@ -1204,7 +1242,7 @@ class UserCreationWizardService {
|
|
|
1204
1242
|
// .filter(line => line.number.trim().length > 0);
|
|
1205
1243
|
this.devices.forEach(device => {
|
|
1206
1244
|
this.initDeviceWithSiteInfo(device);
|
|
1207
|
-
applyDefaultDevicePrefixIfMissing(device);
|
|
1245
|
+
// applyDefaultDevicePrefixIfMissing(device);
|
|
1208
1246
|
});
|
|
1209
1247
|
this.deviceProfiles.forEach(device => this.initDeviceWithSiteInfo(device));
|
|
1210
1248
|
this.lines.forEach(line => this.initLineWithSiteInfo(line));
|
|
@@ -1275,12 +1313,12 @@ class UserCreationWizardService {
|
|
|
1275
1313
|
if (this.templateLinesSnapshot) {
|
|
1276
1314
|
this.lines = JSON.parse(JSON.stringify(this.templateLinesSnapshot));
|
|
1277
1315
|
}
|
|
1278
|
-
this.devices.forEach(device => {
|
|
1279
|
-
|
|
1280
|
-
});
|
|
1281
|
-
this.deviceProfiles.forEach(profile => {
|
|
1282
|
-
|
|
1283
|
-
});
|
|
1316
|
+
// this.devices.forEach(device => {
|
|
1317
|
+
// device.name = '';
|
|
1318
|
+
// });
|
|
1319
|
+
// this.deviceProfiles.forEach(profile => {
|
|
1320
|
+
// profile.name = '';
|
|
1321
|
+
// });
|
|
1284
1322
|
if (this.endUser) {
|
|
1285
1323
|
this.endUser.userid = '';
|
|
1286
1324
|
this.endUser.firstName = '';
|
|
@@ -1345,6 +1383,30 @@ class UserCreationWizardService {
|
|
|
1345
1383
|
this.rebuildOverviewDevices();
|
|
1346
1384
|
this.rebuildOverviewDeviceProfiles();
|
|
1347
1385
|
}
|
|
1386
|
+
/** Replaces [DN]/[FN]/[LN] placeholders in device names after a directory number is chosen. */
|
|
1387
|
+
applyDirectoryNumberToDeviceNames(directoryNumber) {
|
|
1388
|
+
const dn = directoryNumber?.trim();
|
|
1389
|
+
if (!dn) {
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
const user = {
|
|
1393
|
+
firstName: this.userDetailsForm.firstName,
|
|
1394
|
+
lastName: this.userDetailsForm.lastName,
|
|
1395
|
+
userid: this.userDetailsForm.userId,
|
|
1396
|
+
};
|
|
1397
|
+
const resolveDeviceName = (device) => {
|
|
1398
|
+
const template = (device.newName || '').trim();
|
|
1399
|
+
if (!deviceNameHasDynamicTokens(template)) {
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
const resolvedFull = this.mutliStringReplace({}, this.replaceDynamicValueFormat(template), dn, user);
|
|
1403
|
+
device.name = stripDeviceNamePrefix(resolvedFull, device.prefix);
|
|
1404
|
+
};
|
|
1405
|
+
this.devices.forEach(resolveDeviceName);
|
|
1406
|
+
this.deviceProfiles.forEach(resolveDeviceName);
|
|
1407
|
+
this.rebuildOverviewDevices();
|
|
1408
|
+
this.rebuildOverviewDeviceProfiles();
|
|
1409
|
+
}
|
|
1348
1410
|
setLineSelection(index, lineNumber) {
|
|
1349
1411
|
if (!this.lineSelections[index]) {
|
|
1350
1412
|
return;
|
|
@@ -1432,6 +1494,7 @@ class UserCreationWizardService {
|
|
|
1432
1494
|
device.deviceDefaults = defaults;
|
|
1433
1495
|
device.nameValidationRegex = nameValidationRegex;
|
|
1434
1496
|
device.nameValidationCaption = defaults.deviceNameExplained;
|
|
1497
|
+
applyDefaultDevicePrefixIfMissing(device, defaults);
|
|
1435
1498
|
});
|
|
1436
1499
|
}
|
|
1437
1500
|
getDeviceNamePrefix(deviceIndex, isProfile = false) {
|
|
@@ -1680,7 +1743,9 @@ class UserCreationWizardService {
|
|
|
1680
1743
|
}
|
|
1681
1744
|
initDeviceWithSiteInfo(device) {
|
|
1682
1745
|
device.newName = device.name;
|
|
1683
|
-
device.name
|
|
1746
|
+
if (!deviceNameHasDynamicTokens(device.name)) {
|
|
1747
|
+
device.name = '';
|
|
1748
|
+
}
|
|
1684
1749
|
if (!device['enabledExtensionMobility']) {
|
|
1685
1750
|
device.enabledExtensionMobility = this.siteDefaults?.enableEm ?? false;
|
|
1686
1751
|
}
|
|
@@ -1731,7 +1796,13 @@ class UserCreationWizardService {
|
|
|
1731
1796
|
mutliStringReplace(object, input, directoryNumber, user) {
|
|
1732
1797
|
var val = input;
|
|
1733
1798
|
if (val.includes('[DN]') && directoryNumber && !directoryNumber.includes('Line')) {
|
|
1734
|
-
val = val.replace(
|
|
1799
|
+
val = val.replace(/\[DN\]/gi, directoryNumber);
|
|
1800
|
+
}
|
|
1801
|
+
if (user?.firstName) {
|
|
1802
|
+
val = val.replace(/\[FN\]/gi, user.firstName);
|
|
1803
|
+
}
|
|
1804
|
+
if (user?.lastName) {
|
|
1805
|
+
val = val.replace(/\[LN\]/gi, user.lastName);
|
|
1735
1806
|
}
|
|
1736
1807
|
var indexOfDN = val.indexOf('[DN(');
|
|
1737
1808
|
if (indexOfDN !== -1 && directoryNumber) {
|
|
@@ -1814,7 +1885,9 @@ class UserCreationWizardService {
|
|
|
1814
1885
|
});
|
|
1815
1886
|
}
|
|
1816
1887
|
resolveDeviceNameForSave(_index, device) {
|
|
1817
|
-
const
|
|
1888
|
+
const template = (device.newName || '').trim();
|
|
1889
|
+
const resolvedName = (device.name || '').trim();
|
|
1890
|
+
const rawName = resolvedName || (deviceNameHasDynamicTokens(template) ? '' : template);
|
|
1818
1891
|
if (!rawName) {
|
|
1819
1892
|
return '';
|
|
1820
1893
|
}
|
|
@@ -1919,9 +1992,6 @@ class UserDetailsStepComponent {
|
|
|
1919
1992
|
this.setupFormSync();
|
|
1920
1993
|
this.setupValidityEmitter();
|
|
1921
1994
|
this.fetchInitialAvailableNumbers();
|
|
1922
|
-
if (!isRestoringPreviousEntry) {
|
|
1923
|
-
this.userCreationWizardService.applyUserDetailsFormValue(this.userDetailsForm.getRawValue());
|
|
1924
|
-
}
|
|
1925
1995
|
this.applyDeviceNameValidators();
|
|
1926
1996
|
this.userCreationWizardService.deviceDefaultsLoaded$
|
|
1927
1997
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -1969,6 +2039,12 @@ class UserDetailsStepComponent {
|
|
|
1969
2039
|
getDeviceProfileNameValidationCaption(index) {
|
|
1970
2040
|
return this.userCreationWizardService.getDeviceNameValidationCaption(index, true);
|
|
1971
2041
|
}
|
|
2042
|
+
isDeviceNameReadonly(index, isProfile) {
|
|
2043
|
+
const device = isProfile
|
|
2044
|
+
? this.userCreationWizardService.deviceProfiles[index]
|
|
2045
|
+
: this.userCreationWizardService.devices[index];
|
|
2046
|
+
return isDeviceNameReadonlyFromTemplate(device?.newName);
|
|
2047
|
+
}
|
|
1972
2048
|
getFilteredNumbers(lineIndex) {
|
|
1973
2049
|
return this.filteredAvailableNumbersByLine[lineIndex] ?? [];
|
|
1974
2050
|
}
|
|
@@ -1994,6 +2070,8 @@ class UserDetailsStepComponent {
|
|
|
1994
2070
|
const lineGroup = this.linesFormArray.at(lineIndex);
|
|
1995
2071
|
const displayNumber = this.extractDirectoryNumber(number);
|
|
1996
2072
|
lineGroup.get('number')?.setValue(displayNumber, { emitEvent: true });
|
|
2073
|
+
this.userCreationWizardService.applyDirectoryNumberToDeviceNames(displayNumber);
|
|
2074
|
+
this.syncDeviceNamesFromServiceToForm();
|
|
1997
2075
|
}
|
|
1998
2076
|
searchLdapUsers(pageIndex = 0) {
|
|
1999
2077
|
const queryValue = String(this.ldapSearchForm.get('queryValue')?.value).trim() || undefined;
|
|
@@ -2147,25 +2225,31 @@ class UserDetailsStepComponent {
|
|
|
2147
2225
|
});
|
|
2148
2226
|
service.devices.forEach((device, index) => {
|
|
2149
2227
|
const savedDevice = savedFormValue?.devices?.[index];
|
|
2228
|
+
const nameReadonly = isDeviceNameReadonlyFromTemplate(device.newName);
|
|
2150
2229
|
devicesArray.push(this.fb.group({
|
|
2151
2230
|
deviceType: [{ value: device.deviceType || '', disabled: true }],
|
|
2152
2231
|
protocol: [{ value: device.protocol || '', disabled: true }],
|
|
2153
2232
|
buttonTemplate: [{ value: device.buttonTemplate || '', disabled: true }],
|
|
2154
|
-
name: [
|
|
2155
|
-
|
|
2156
|
-
|
|
2233
|
+
name: [{
|
|
2234
|
+
value: savedDevice?.name ?? device.name ?? '',
|
|
2235
|
+
disabled: nameReadonly,
|
|
2236
|
+
},
|
|
2237
|
+
nameReadonly ? [] : this.buildDeviceNameValidators(index, false),
|
|
2157
2238
|
],
|
|
2158
2239
|
}));
|
|
2159
2240
|
});
|
|
2160
2241
|
service.deviceProfiles.forEach((profile, index) => {
|
|
2161
2242
|
const savedProfile = savedFormValue?.deviceProfiles?.[index];
|
|
2243
|
+
const nameReadonly = isDeviceNameReadonlyFromTemplate(profile.newName);
|
|
2162
2244
|
profilesArray.push(this.fb.group({
|
|
2163
2245
|
deviceType: [{ value: profile.deviceType || '', disabled: true }],
|
|
2164
2246
|
protocol: [{ value: profile.protocol || '', disabled: true }],
|
|
2165
2247
|
buttonTemplate: [{ value: profile.buttonTemplate || '', disabled: true }],
|
|
2166
|
-
name: [
|
|
2167
|
-
|
|
2168
|
-
|
|
2248
|
+
name: [{
|
|
2249
|
+
value: savedProfile?.name ?? profile.name ?? '',
|
|
2250
|
+
disabled: nameReadonly,
|
|
2251
|
+
},
|
|
2252
|
+
nameReadonly ? [] : this.buildDeviceNameValidators(index, true),
|
|
2169
2253
|
],
|
|
2170
2254
|
}));
|
|
2171
2255
|
});
|
|
@@ -2180,11 +2264,17 @@ class UserDetailsStepComponent {
|
|
|
2180
2264
|
}
|
|
2181
2265
|
applyDeviceNameValidators() {
|
|
2182
2266
|
this.devicesFormArray.controls.forEach((_, index) => {
|
|
2267
|
+
if (this.isDeviceNameReadonly(index, false)) {
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2183
2270
|
const nameControl = this.getDeviceGroup(index).get('name');
|
|
2184
2271
|
nameControl?.setValidators(this.buildDeviceNameValidators(index, false));
|
|
2185
2272
|
nameControl?.updateValueAndValidity({ emitEvent: false });
|
|
2186
2273
|
});
|
|
2187
2274
|
this.deviceProfilesFormArray.controls.forEach((_, index) => {
|
|
2275
|
+
if (this.isDeviceNameReadonly(index, true)) {
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2188
2278
|
const nameControl = this.getDeviceProfileGroup(index).get('name');
|
|
2189
2279
|
nameControl?.setValidators(this.buildDeviceNameValidators(index, true));
|
|
2190
2280
|
nameControl?.updateValueAndValidity({ emitEvent: false });
|
|
@@ -2312,6 +2402,41 @@ class UserDetailsStepComponent {
|
|
|
2312
2402
|
const spaceIndex = trimmed.indexOf(' ');
|
|
2313
2403
|
return spaceIndex > -1 ? trimmed.substring(0, spaceIndex) : trimmed;
|
|
2314
2404
|
}
|
|
2405
|
+
syncDeviceNamesFromServiceToForm() {
|
|
2406
|
+
this.devicesFormArray.controls.forEach((_, index) => {
|
|
2407
|
+
this.updateDeviceNameControlFromService(index, false);
|
|
2408
|
+
});
|
|
2409
|
+
this.deviceProfilesFormArray.controls.forEach((_, index) => {
|
|
2410
|
+
this.updateDeviceNameControlFromService(index, true);
|
|
2411
|
+
});
|
|
2412
|
+
this.userCreationWizardService.applyUserDetailsFormValue(this.userDetailsForm.getRawValue());
|
|
2413
|
+
this.emitValidity();
|
|
2414
|
+
}
|
|
2415
|
+
updateDeviceNameControlFromService(index, isProfile) {
|
|
2416
|
+
const device = isProfile
|
|
2417
|
+
? this.userCreationWizardService.deviceProfiles[index]
|
|
2418
|
+
: this.userCreationWizardService.devices[index];
|
|
2419
|
+
const group = isProfile ? this.getDeviceProfileGroup(index) : this.getDeviceGroup(index);
|
|
2420
|
+
const nameControl = group.get('name');
|
|
2421
|
+
if (!nameControl || !device) {
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
const readonly = this.isDeviceNameReadonly(index, isProfile);
|
|
2425
|
+
nameControl.setValue(device.name ?? '', { emitEvent: false });
|
|
2426
|
+
if (readonly) {
|
|
2427
|
+
if (!nameControl.disabled) {
|
|
2428
|
+
nameControl.disable({ emitEvent: false });
|
|
2429
|
+
}
|
|
2430
|
+
nameControl.clearValidators();
|
|
2431
|
+
nameControl.updateValueAndValidity({ emitEvent: false });
|
|
2432
|
+
return;
|
|
2433
|
+
}
|
|
2434
|
+
if (nameControl.disabled) {
|
|
2435
|
+
nameControl.enable({ emitEvent: false });
|
|
2436
|
+
}
|
|
2437
|
+
nameControl.setValidators(this.buildDeviceNameValidators(index, isProfile));
|
|
2438
|
+
nameControl.updateValueAndValidity({ emitEvent: false });
|
|
2439
|
+
}
|
|
2315
2440
|
createUserIdAsyncValidator() {
|
|
2316
2441
|
return (control) => {
|
|
2317
2442
|
if (this.userCreationWizardService.isLdapIntegrated) {
|
|
@@ -2340,10 +2465,10 @@ class UserDetailsStepComponent {
|
|
|
2340
2465
|
}
|
|
2341
2466
|
}
|
|
2342
2467
|
UserDetailsStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UserDetailsStepComponent, deps: [{ token: i1$2.FormBuilder }, { token: UserCreationApiService }, { token: UserCreationWizardService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2343
|
-
UserDetailsStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UserDetailsStepComponent, selector: "tk-user-details-step", outputs: { validityChange: "validityChange" }, ngImport: i0, template: "<app-loader *ngIf=\"loadingAvailableNumbers\"></app-loader>\r\n<section class=\"details-step-content\">\r\n <form [formGroup]=\"userDetailsForm\">\r\n <div class=\"details-step-sections\">\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">User details</h3>\r\n <div class=\"details-step-section__content\">\r\n <div class=\"details-step-section__part\">\r\n <div class=\"details-inline-fields\">\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User ID</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"User ID\" formControlName=\"userId\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('required') && userDetailsForm.get('userId')?.touched\">\r\n User ID is required\r\n </mat-error>\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('userIdExists') && userDetailsForm.get('userId')?.touched\">\r\n User ID already exists\r\n </mat-error>\r\n <mat-hint *ngIf=\"userIdCheckPending\">Checking user ID...</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">First Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"First Name\" formControlName=\"firstName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('firstName')?.hasError('required') && userDetailsForm.get('firstName')?.touched\">\r\n First name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Last Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Last Name\" formControlName=\"lastName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('lastName')?.hasError('required') && userDetailsForm.get('lastName')?.touched\">\r\n Last name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Email</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Email\" formControlName=\"email\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('email')?.invalid && userDetailsForm.get('email')?.touched\">\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('required')\">Email is required</span>\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('email')\">Please enter a valid email</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input\r\n matInput\r\n placeholder=\"User Template\"\r\n [value]=\"userCreationWizardService.selectedTemplateName || ''\"\r\n [disabled]=\"true\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"details-step-section__part\">\r\n <mat-accordion class=\"details-user-accordion\">\r\n <mat-expansion-panel togglePosition=\"before\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>Choose an existing or a LDAP user</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"details-user-accordion__content\">\r\n <div class=\"details-ldap-search\" [formGroup]=\"ldapSearchForm\">\r\n <mat-form-field\r\n class=\"details-ldap-search__input\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search\"\r\n formControlName=\"queryValue\"\r\n (keyup.enter)=\"searchLdapUsers()\"\r\n />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-ldap-search__select\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <mat-select formControlName=\"queryType\">\r\n <mat-option *ngFor=\"let option of ldapQueryTypeOptions\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-chip-list *ngIf=\"selectedLdapUser\" class=\"details-ldap-search__chip\">\r\n <mat-chip removable (removed)=\"onRemoveLdapTag()\">\r\n {{ selectedLdapUser.userid }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n\r\n <button\r\n mat-button\r\n class=\"details-ldap-search__btn\"\r\n type=\"button\"\r\n [disabled]=\"ldapLoading\"\r\n (click)=\"searchLdapUsers()\"\r\n >\r\n Search\r\n </button>\r\n </div>\r\n\r\n <app-loader *ngIf=\"ldapLoading\"></app-loader>\r\n\r\n <p\r\n *ngIf=\"!ldapLoading && ldapSearchAttempted && !hasLdapUsers\"\r\n class=\"details-ldap-table__empty\"\r\n >\r\n No users found\r\n </p>\r\n\r\n <table\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n mat-table\r\n [dataSource]=\"userCreationWizardService.ldapUsers\"\r\n class=\"details-ldap-table\"\r\n >\r\n <ng-container matColumnDef=\"userId\">\r\n <th mat-header-cell *matHeaderCellDef>User Id</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.userid }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"firstName\">\r\n <th mat-header-cell *matHeaderCellDef>First Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.firstName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"lastName\">\r\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.lastName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"email\">\r\n <th mat-header-cell *matHeaderCellDef>Email</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.email }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"add\">\r\n <th mat-header-cell *matHeaderCellDef>Add</th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <button\r\n *ngIf=\"!isLdapUserRowSelected(row); else deleteLdapUserBtn\"\r\n mat-button\r\n class=\"details-ldap-table__add-btn\"\r\n type=\"button\"\r\n (click)=\"onAddLdapUser(row)\"\r\n >\r\n Add User\r\n </button>\r\n <ng-template #deleteLdapUserBtn>\r\n <button\r\n mat-button\r\n class=\"details-ldap-table__add-btn details-ldap-table__add-btn--delete\"\r\n type=\"button\"\r\n (click)=\"onDeleteLdapUser(row)\"\r\n >\r\n Delete user\r\n </button>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"userCreationWizardService.ldapTableColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: userCreationWizardService.ldapTableColumns\"></tr>\r\n </table>\r\n\r\n <mat-paginator\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n class=\"details-ldap-paginator\"\r\n [length]=\"ldapTotalCount\"\r\n [pageSize]=\"ldapPageSize\"\r\n [pageIndex]=\"ldapPageIndex\"\r\n [pageSizeOptions]=\"[ldapPageSize]\"\r\n [hidePageSize]=\"true\"\r\n [disabled]=\"ldapLoading\"\r\n (page)=\"onLdapPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </mat-expansion-panel>\r\n </mat-accordion>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Lines</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"lines\">\r\n <div class=\"line-route-list\">\r\n <div\r\n class=\"line-route-row\"\r\n *ngFor=\"let lineGroup of linesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"line-info\">\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input matInput placeholder=\"Line number\" formControlName=\"lineNumber\" />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search for a number\"\r\n formControlName=\"number\"\r\n [matAutocomplete]=\"numberAuto\"\r\n (input)=\"filterAvailableNumbers(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #numberAuto=\"matAutocomplete\"\r\n [panelWidth]=\"'auto'\"\r\n (optionSelected)=\"onNumberSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option *ngFor=\"let option of getFilteredNumbers(idx)\" [value]=\"option\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('number')?.invalid && getLineGroup(idx).get('number')?.touched\">\r\n Number is required\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Select route partition\"\r\n formControlName=\"routePartition\"\r\n [matAutocomplete]=\"routePartitionAuto\"\r\n (input)=\"filterRoutePartitions(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #routePartitionAuto=\"matAutocomplete\"\r\n (optionSelected)=\"onRoutePartitionSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option\r\n *ngFor=\"let routePartition of getFilteredRoutePartitions(idx)\"\r\n [value]=\"routePartition\"\r\n >\r\n {{ routePartition }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('routePartition')?.invalid && getLineGroup(idx).get('routePartition')?.touched\">\r\n Route partition is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Devices</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"devices\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let deviceGroup of devicesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceNamePrefix(idx) as devicePrefix\">{{ devicePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" />\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('deviceName') && getDeviceGroup(idx).get('name')?.touched\">\r\n {{ getDeviceGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('required') && getDeviceGroup(idx).get('name')?.touched\">\r\n Name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\" *ngIf=\"deviceProfilesFormArray.length\">\r\n <h3 class=\"details-step-section__title\">Device profiles</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"deviceProfiles\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let profileGroup of deviceProfilesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceProfileNamePrefix(idx) as profilePrefix\">{{ profilePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" />\r\n <mat-error *ngIf=\"getDeviceProfileGroup(idx).get('name')?.hasError('deviceName') && getDeviceProfileGroup(idx).get('name')?.touched\">\r\n {{ getDeviceProfileGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceProfileNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </form>\r\n</section>\r\n", styles: [".details-step-content{display:flex;flex-direction:column;gap:0}.details-step-dropdowns{display:flex;flex-direction:column;gap:1rem}.details-step-field{display:flex;flex-direction:column;gap:8px}.details-step-label{font-size:16px;font-weight:400;line-height:100%;letter-spacing:0;color:#333}.details-step-select{width:333px}.details-step-divider{border-top:1px solid #d9d9d9;margin-top:24px}.details-step-sections{display:flex;flex-direction:column}.details-step-section{display:flex;flex-direction:column;gap:0;padding:24px 0}.details-step-sections>.details-step-section:first-child{padding-top:0}.details-step-section+.details-step-section{border-top:1px solid #d9d9d9}.details-step-section__title{margin:0;font-family:Inter,sans-serif;font-size:16px;font-weight:600;line-height:100%;letter-spacing:0;color:#333}.details-step-section__content{margin-top:24px}.details-step-section__part+.details-step-section__part{margin-top:24px}.details-user-accordion{width:100%}.details-user-accordion__content{padding:12px 0 0}.details-ldap-search{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px}.details-ldap-search__input{min-width:180px;width:180px}.details-ldap-search__select{flex:0 1 180px;min-width:160px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-wrapper,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin:0}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-flex,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:0 12px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-gap,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-infix,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-infix{width:100%;border-top:0;padding:0;display:flex;align-items:center;min-height:unset}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-input-element,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-input-element{margin:0;line-height:20px}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-trigger{display:flex;align-items:center;width:100%;height:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-value{display:flex;align-items:center;max-width:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-arrow-wrapper{display:flex;align-items:center}.details-ldap-search__chip{flex:0 0 auto}.details-ldap-search__btn{flex:0 0 auto;min-width:0;padding:0 12px;font-family:Inter,sans-serif;font-size:14px;font-weight:500;color:#0d56aa}.details-ldap-paginator{margin-top:8px}.details-ldap-table__add-btn--delete{color:#c62828}.details-ldap-table{width:100%}.details-ldap-table__empty{margin:16px 0 8px;font-family:Inter,sans-serif;font-size:14px;line-height:20px;color:#737480;text-align:center}.details-ldap-table__row--disabled{opacity:.35}.details-ldap-table__add-btn{min-width:0;padding:0;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#0d56aa}:host ::ng-deep .details-ldap-table .mat-header-cell{font-family:Inter,sans-serif;font-size:12px;font-weight:500;line-height:16px;letter-spacing:0;color:#737480;height:30px;padding:7px 8px}:host ::ng-deep .details-ldap-table .mat-cell{font-family:Inter,sans-serif;font-size:14px;font-weight:400;line-height:20px;letter-spacing:0;color:#333;height:40px;padding:8px}.details-inline-fields{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px}.details-inline-fields--four{grid-template-columns:repeat(4,minmax(0,1fr))}.devices-rows{display:flex;flex-direction:column;gap:24px}.details-inline-field{display:flex;flex-direction:column;gap:4px}.details-inline-field__label{color:#c0c2ce;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0}.details-step-input{width:100%}.line-route-list{display:flex;flex-direction:column;gap:16px}.line-route-row{display:flex;gap:16px}.line-info{display:flex;align-items:flex-start;gap:16px}.line-route-field{flex:1 1 180px;min-width:160px}.line-route-field{display:flex;flex-direction:column;gap:0}.line-route-field:nth-of-type(1) .line-route-select{width:230px}.line-route-field .line-route-select{width:185px}:host ::ng-deep .details-step-select .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-input .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-select .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:6px;padding:0 12px}:host ::ng-deep .details-step-input .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:10px 8px}:host ::ng-deep .details-step-select .mat-form-field-outline,:host ::ng-deep .details-step-select .mat-form-field-outline-start,:host ::ng-deep .details-step-select .mat-form-field-outline-end,:host ::ng-deep .details-step-select .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-input .mat-form-field-outline,:host ::ng-deep .details-step-input .mat-form-field-outline-start,:host ::ng-deep .details-step-input .mat-form-field-outline-end,:host ::ng-deep .details-step-input .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-select .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-input .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}:host ::ng-deep .details-step-input .mat-input-element{height:100%;margin:0}:host ::ng-deep .details-step-input.mat-form-field-disabled .mat-form-field-flex{background-color:#f5f6fa;border-color:#b8beca;opacity:.55;cursor:not-allowed}:host ::ng-deep .details-step-input .mat-input-element:disabled{color:#7f8694;-webkit-text-fill-color:#7f8694;cursor:not-allowed}:host ::ng-deep .line-info .details-step-input .mat-form-field-flex{height:36px;padding:0 8px}:host ::ng-deep .line-info .details-step-input .mat-form-field-infix{padding:0}:host ::ng-deep .line-info .details-step-input .mat-input-element{font-size:14px;line-height:20px}:host ::ng-deep .mat-form-field-subscript-wrapper{position:relative}:host ::ng-deep .line-info .details-step-input .mat-form-field-subscript-wrapper{margin-top:4px;position:relative}:host ::ng-deep .details-user-accordion .mat-expansion-panel{border:0;border-radius:0!important;background:transparent;box-shadow:none!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header{padding:0 0 0 8px;min-height:32px;height:32px}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header-title{margin:0;display:flex;align-items:center;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#333}:host ::ng-deep .details-user-accordion .mat-expansion-panel-body{padding:0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-content{display:flex;align-items:center}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator{display:block!important;opacity:1!important;color:#333!important;align-self:center;margin:0 8px 0 0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator:after{color:#333!important;border-color:#333!important;position:relative;top:-4px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex{display:flex;gap:3px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex .mat-form-field-prefix{top:1px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i3.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: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8.MatPrefix, selector: "[matPrefix]" }, { 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: "component", type: i7$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i11.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i12.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i13.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i14.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i14.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i14.MatChipRemove, selector: "[matChipRemove]" }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i15.MatAccordion, selector: "mat-accordion", inputs: ["multi", "hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i15.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i15.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "directive", type: i15.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: AppLoaderComponent, selector: "app-loader" }] });
|
|
2468
|
+
UserDetailsStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UserDetailsStepComponent, selector: "tk-user-details-step", outputs: { validityChange: "validityChange" }, ngImport: i0, template: "<app-loader *ngIf=\"loadingAvailableNumbers\"></app-loader>\r\n<section class=\"details-step-content\">\r\n <form [formGroup]=\"userDetailsForm\">\r\n <div class=\"details-step-sections\">\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">User details</h3>\r\n <div class=\"details-step-section__content\">\r\n <div class=\"details-step-section__part\">\r\n <div class=\"details-inline-fields\">\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User ID</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"User ID\" formControlName=\"userId\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('required') && userDetailsForm.get('userId')?.touched\">\r\n User ID is required\r\n </mat-error>\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('userIdExists') && userDetailsForm.get('userId')?.touched\">\r\n User ID already exists\r\n </mat-error>\r\n <mat-hint *ngIf=\"userIdCheckPending\">Checking user ID...</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">First Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"First Name\" formControlName=\"firstName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('firstName')?.hasError('required') && userDetailsForm.get('firstName')?.touched\">\r\n First name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Last Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Last Name\" formControlName=\"lastName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('lastName')?.hasError('required') && userDetailsForm.get('lastName')?.touched\">\r\n Last name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Email</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Email\" formControlName=\"email\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('email')?.invalid && userDetailsForm.get('email')?.touched\">\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('required')\">Email is required</span>\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('email')\">Please enter a valid email</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input\r\n matInput\r\n placeholder=\"User Template\"\r\n [value]=\"userCreationWizardService.selectedTemplateName || ''\"\r\n [disabled]=\"true\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"details-step-section__part\">\r\n <mat-accordion class=\"details-user-accordion\">\r\n <mat-expansion-panel togglePosition=\"before\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>Choose an existing or a LDAP user</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"details-user-accordion__content\">\r\n <div class=\"details-ldap-search\" [formGroup]=\"ldapSearchForm\">\r\n <mat-form-field\r\n class=\"details-ldap-search__input\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search\"\r\n formControlName=\"queryValue\"\r\n (keyup.enter)=\"searchLdapUsers()\"\r\n />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-ldap-search__select\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <mat-select formControlName=\"queryType\">\r\n <mat-option *ngFor=\"let option of ldapQueryTypeOptions\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-chip-list *ngIf=\"selectedLdapUser\" class=\"details-ldap-search__chip\">\r\n <mat-chip removable (removed)=\"onRemoveLdapTag()\">\r\n {{ selectedLdapUser.userid }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n\r\n <button\r\n mat-button\r\n class=\"details-ldap-search__btn\"\r\n type=\"button\"\r\n [disabled]=\"ldapLoading\"\r\n (click)=\"searchLdapUsers()\"\r\n >\r\n Search\r\n </button>\r\n </div>\r\n\r\n <app-loader *ngIf=\"ldapLoading\"></app-loader>\r\n\r\n <p\r\n *ngIf=\"!ldapLoading && ldapSearchAttempted && !hasLdapUsers\"\r\n class=\"details-ldap-table__empty\"\r\n >\r\n No users found\r\n </p>\r\n\r\n <table\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n mat-table\r\n [dataSource]=\"userCreationWizardService.ldapUsers\"\r\n class=\"details-ldap-table\"\r\n >\r\n <ng-container matColumnDef=\"userId\">\r\n <th mat-header-cell *matHeaderCellDef>User Id</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.userid }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"firstName\">\r\n <th mat-header-cell *matHeaderCellDef>First Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.firstName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"lastName\">\r\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.lastName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"email\">\r\n <th mat-header-cell *matHeaderCellDef>Email</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.email }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"add\">\r\n <th mat-header-cell *matHeaderCellDef>Add</th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <button\r\n *ngIf=\"!isLdapUserRowSelected(row); else deleteLdapUserBtn\"\r\n mat-button\r\n class=\"details-ldap-table__add-btn\"\r\n type=\"button\"\r\n (click)=\"onAddLdapUser(row)\"\r\n >\r\n Add User\r\n </button>\r\n <ng-template #deleteLdapUserBtn>\r\n <button\r\n mat-button\r\n class=\"details-ldap-table__add-btn details-ldap-table__add-btn--delete\"\r\n type=\"button\"\r\n (click)=\"onDeleteLdapUser(row)\"\r\n >\r\n Delete user\r\n </button>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"userCreationWizardService.ldapTableColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: userCreationWizardService.ldapTableColumns\"></tr>\r\n </table>\r\n\r\n <mat-paginator\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n class=\"details-ldap-paginator\"\r\n [length]=\"ldapTotalCount\"\r\n [pageSize]=\"ldapPageSize\"\r\n [pageIndex]=\"ldapPageIndex\"\r\n [pageSizeOptions]=\"[ldapPageSize]\"\r\n [hidePageSize]=\"true\"\r\n [disabled]=\"ldapLoading\"\r\n (page)=\"onLdapPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </mat-expansion-panel>\r\n </mat-accordion>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Lines</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"lines\">\r\n <div class=\"line-route-list\">\r\n <div\r\n class=\"line-route-row\"\r\n *ngFor=\"let lineGroup of linesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"line-info\">\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input matInput placeholder=\"Line number\" formControlName=\"lineNumber\" />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search for a number\"\r\n formControlName=\"number\"\r\n [matAutocomplete]=\"numberAuto\"\r\n (input)=\"filterAvailableNumbers(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #numberAuto=\"matAutocomplete\"\r\n [panelWidth]=\"'auto'\"\r\n (optionSelected)=\"onNumberSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option *ngFor=\"let option of getFilteredNumbers(idx)\" [value]=\"option\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('number')?.invalid && getLineGroup(idx).get('number')?.touched\">\r\n Number is required\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Select route partition\"\r\n formControlName=\"routePartition\"\r\n [matAutocomplete]=\"routePartitionAuto\"\r\n (input)=\"filterRoutePartitions(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #routePartitionAuto=\"matAutocomplete\"\r\n (optionSelected)=\"onRoutePartitionSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option\r\n *ngFor=\"let routePartition of getFilteredRoutePartitions(idx)\"\r\n [value]=\"routePartition\"\r\n >\r\n {{ routePartition }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('routePartition')?.invalid && getLineGroup(idx).get('routePartition')?.touched\">\r\n Route partition is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Devices</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"devices\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let deviceGroup of devicesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceNamePrefix(idx) as devicePrefix\">{{ devicePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" [readonly]=\"isDeviceNameReadonly(idx, false)\" />\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('deviceName') && getDeviceGroup(idx).get('name')?.touched\">\r\n {{ getDeviceGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('required') && getDeviceGroup(idx).get('name')?.touched\">\r\n Name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\" *ngIf=\"deviceProfilesFormArray.length\">\r\n <h3 class=\"details-step-section__title\">Device profiles</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"deviceProfiles\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let profileGroup of deviceProfilesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceProfileNamePrefix(idx) as profilePrefix\">{{ profilePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" [readonly]=\"isDeviceNameReadonly(idx, true)\" />\r\n <mat-error *ngIf=\"getDeviceProfileGroup(idx).get('name')?.hasError('deviceName') && getDeviceProfileGroup(idx).get('name')?.touched\">\r\n {{ getDeviceProfileGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceProfileNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </form>\r\n</section>\r\n", styles: [".details-step-content{display:flex;flex-direction:column;gap:0}.details-step-dropdowns{display:flex;flex-direction:column;gap:1rem}.details-step-field{display:flex;flex-direction:column;gap:8px}.details-step-label{font-size:16px;font-weight:400;line-height:100%;letter-spacing:0;color:#333}.details-step-select{width:333px}.details-step-divider{border-top:1px solid #d9d9d9;margin-top:24px}.details-step-sections{display:flex;flex-direction:column}.details-step-section{display:flex;flex-direction:column;gap:0;padding:24px 0}.details-step-sections>.details-step-section:first-child{padding-top:0}.details-step-section+.details-step-section{border-top:1px solid #d9d9d9}.details-step-section__title{margin:0;font-family:Inter,sans-serif;font-size:16px;font-weight:600;line-height:100%;letter-spacing:0;color:#333}.details-step-section__content{margin-top:24px}.details-step-section__part+.details-step-section__part{margin-top:24px}.details-user-accordion{width:100%}.details-user-accordion__content{padding:12px 0 0}.details-ldap-search{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px}.details-ldap-search__input{min-width:180px;width:180px}.details-ldap-search__select{flex:0 1 180px;min-width:160px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-wrapper,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin:0}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-flex,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:0 12px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-gap,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-infix,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-infix{width:100%;border-top:0;padding:0;display:flex;align-items:center;min-height:unset}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-input-element,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-input-element{margin:0;line-height:20px}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-trigger{display:flex;align-items:center;width:100%;height:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-value{display:flex;align-items:center;max-width:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-arrow-wrapper{display:flex;align-items:center}.details-ldap-search__chip{flex:0 0 auto}.details-ldap-search__btn{flex:0 0 auto;min-width:0;padding:0 12px;font-family:Inter,sans-serif;font-size:14px;font-weight:500;color:#0d56aa}.details-ldap-paginator{margin-top:8px}.details-ldap-table__add-btn--delete{color:#c62828}.details-ldap-table{width:100%}.details-ldap-table__empty{margin:16px 0 8px;font-family:Inter,sans-serif;font-size:14px;line-height:20px;color:#737480;text-align:center}.details-ldap-table__row--disabled{opacity:.35}.details-ldap-table__add-btn{min-width:0;padding:0;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#0d56aa}:host ::ng-deep .details-ldap-table .mat-header-cell{font-family:Inter,sans-serif;font-size:12px;font-weight:500;line-height:16px;letter-spacing:0;color:#737480;height:30px;padding:7px 8px}:host ::ng-deep .details-ldap-table .mat-cell{font-family:Inter,sans-serif;font-size:14px;font-weight:400;line-height:20px;letter-spacing:0;color:#333;height:40px;padding:8px}.details-inline-fields{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px}.details-inline-fields--four{grid-template-columns:repeat(4,minmax(0,1fr))}.devices-rows{display:flex;flex-direction:column;gap:24px}.details-inline-field{display:flex;flex-direction:column;gap:4px}.details-inline-field__label{color:#c0c2ce;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0}.details-step-input{width:100%}.line-route-list{display:flex;flex-direction:column;gap:16px}.line-route-row{display:flex;gap:16px}.line-info{display:flex;align-items:flex-start;gap:16px}.line-route-field{flex:1 1 180px;min-width:160px}.line-route-field{display:flex;flex-direction:column;gap:0}.line-route-field:nth-of-type(1) .line-route-select{width:230px}.line-route-field .line-route-select{width:185px}:host ::ng-deep .details-step-select .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-input .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-select .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:6px;padding:0 12px}:host ::ng-deep .details-step-input .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:10px 8px}:host ::ng-deep .details-step-select .mat-form-field-outline,:host ::ng-deep .details-step-select .mat-form-field-outline-start,:host ::ng-deep .details-step-select .mat-form-field-outline-end,:host ::ng-deep .details-step-select .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-input .mat-form-field-outline,:host ::ng-deep .details-step-input .mat-form-field-outline-start,:host ::ng-deep .details-step-input .mat-form-field-outline-end,:host ::ng-deep .details-step-input .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-select .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-input .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}:host ::ng-deep .details-step-input .mat-input-element{height:100%;margin:0}:host ::ng-deep .details-step-input.mat-form-field-disabled .mat-form-field-flex{background-color:#f5f6fa;border-color:#b8beca;opacity:.55;cursor:not-allowed}:host ::ng-deep .details-step-input .mat-input-element:disabled{color:#7f8694;-webkit-text-fill-color:#7f8694;cursor:not-allowed}:host ::ng-deep .line-info .details-step-input .mat-form-field-flex{height:36px;padding:0 8px}:host ::ng-deep .line-info .details-step-input .mat-form-field-infix{padding:0}:host ::ng-deep .line-info .details-step-input .mat-input-element{font-size:14px;line-height:20px}:host ::ng-deep .mat-form-field-subscript-wrapper{position:relative}:host ::ng-deep .line-info .details-step-input .mat-form-field-subscript-wrapper{margin-top:4px;position:relative}:host ::ng-deep .details-user-accordion .mat-expansion-panel{border:0;border-radius:0!important;background:transparent;box-shadow:none!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header{padding:0 0 0 8px;min-height:32px;height:32px}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header-title{margin:0;display:flex;align-items:center;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#333}:host ::ng-deep .details-user-accordion .mat-expansion-panel-body{padding:0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-content{display:flex;align-items:center}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator{display:block!important;opacity:1!important;color:#333!important;align-self:center;margin:0 8px 0 0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator:after{color:#333!important;border-color:#333!important;position:relative;top:-4px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex{display:flex;gap:3px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex .mat-form-field-prefix{top:1px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i3.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: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8.MatPrefix, selector: "[matPrefix]" }, { 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: "component", type: i7$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i11.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i12.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i13.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i14.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i14.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i14.MatChipRemove, selector: "[matChipRemove]" }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i15.MatAccordion, selector: "mat-accordion", inputs: ["multi", "hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i15.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i15.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "directive", type: i15.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: AppLoaderComponent, selector: "app-loader" }] });
|
|
2344
2469
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UserDetailsStepComponent, decorators: [{
|
|
2345
2470
|
type: Component,
|
|
2346
|
-
args: [{ selector: 'tk-user-details-step', template: "<app-loader *ngIf=\"loadingAvailableNumbers\"></app-loader>\r\n<section class=\"details-step-content\">\r\n <form [formGroup]=\"userDetailsForm\">\r\n <div class=\"details-step-sections\">\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">User details</h3>\r\n <div class=\"details-step-section__content\">\r\n <div class=\"details-step-section__part\">\r\n <div class=\"details-inline-fields\">\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User ID</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"User ID\" formControlName=\"userId\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('required') && userDetailsForm.get('userId')?.touched\">\r\n User ID is required\r\n </mat-error>\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('userIdExists') && userDetailsForm.get('userId')?.touched\">\r\n User ID already exists\r\n </mat-error>\r\n <mat-hint *ngIf=\"userIdCheckPending\">Checking user ID...</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">First Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"First Name\" formControlName=\"firstName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('firstName')?.hasError('required') && userDetailsForm.get('firstName')?.touched\">\r\n First name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Last Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Last Name\" formControlName=\"lastName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('lastName')?.hasError('required') && userDetailsForm.get('lastName')?.touched\">\r\n Last name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Email</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Email\" formControlName=\"email\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('email')?.invalid && userDetailsForm.get('email')?.touched\">\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('required')\">Email is required</span>\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('email')\">Please enter a valid email</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input\r\n matInput\r\n placeholder=\"User Template\"\r\n [value]=\"userCreationWizardService.selectedTemplateName || ''\"\r\n [disabled]=\"true\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"details-step-section__part\">\r\n <mat-accordion class=\"details-user-accordion\">\r\n <mat-expansion-panel togglePosition=\"before\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>Choose an existing or a LDAP user</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"details-user-accordion__content\">\r\n <div class=\"details-ldap-search\" [formGroup]=\"ldapSearchForm\">\r\n <mat-form-field\r\n class=\"details-ldap-search__input\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search\"\r\n formControlName=\"queryValue\"\r\n (keyup.enter)=\"searchLdapUsers()\"\r\n />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-ldap-search__select\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <mat-select formControlName=\"queryType\">\r\n <mat-option *ngFor=\"let option of ldapQueryTypeOptions\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-chip-list *ngIf=\"selectedLdapUser\" class=\"details-ldap-search__chip\">\r\n <mat-chip removable (removed)=\"onRemoveLdapTag()\">\r\n {{ selectedLdapUser.userid }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n\r\n <button\r\n mat-button\r\n class=\"details-ldap-search__btn\"\r\n type=\"button\"\r\n [disabled]=\"ldapLoading\"\r\n (click)=\"searchLdapUsers()\"\r\n >\r\n Search\r\n </button>\r\n </div>\r\n\r\n <app-loader *ngIf=\"ldapLoading\"></app-loader>\r\n\r\n <p\r\n *ngIf=\"!ldapLoading && ldapSearchAttempted && !hasLdapUsers\"\r\n class=\"details-ldap-table__empty\"\r\n >\r\n No users found\r\n </p>\r\n\r\n <table\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n mat-table\r\n [dataSource]=\"userCreationWizardService.ldapUsers\"\r\n class=\"details-ldap-table\"\r\n >\r\n <ng-container matColumnDef=\"userId\">\r\n <th mat-header-cell *matHeaderCellDef>User Id</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.userid }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"firstName\">\r\n <th mat-header-cell *matHeaderCellDef>First Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.firstName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"lastName\">\r\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.lastName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"email\">\r\n <th mat-header-cell *matHeaderCellDef>Email</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.email }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"add\">\r\n <th mat-header-cell *matHeaderCellDef>Add</th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <button\r\n *ngIf=\"!isLdapUserRowSelected(row); else deleteLdapUserBtn\"\r\n mat-button\r\n class=\"details-ldap-table__add-btn\"\r\n type=\"button\"\r\n (click)=\"onAddLdapUser(row)\"\r\n >\r\n Add User\r\n </button>\r\n <ng-template #deleteLdapUserBtn>\r\n <button\r\n mat-button\r\n class=\"details-ldap-table__add-btn details-ldap-table__add-btn--delete\"\r\n type=\"button\"\r\n (click)=\"onDeleteLdapUser(row)\"\r\n >\r\n Delete user\r\n </button>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"userCreationWizardService.ldapTableColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: userCreationWizardService.ldapTableColumns\"></tr>\r\n </table>\r\n\r\n <mat-paginator\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n class=\"details-ldap-paginator\"\r\n [length]=\"ldapTotalCount\"\r\n [pageSize]=\"ldapPageSize\"\r\n [pageIndex]=\"ldapPageIndex\"\r\n [pageSizeOptions]=\"[ldapPageSize]\"\r\n [hidePageSize]=\"true\"\r\n [disabled]=\"ldapLoading\"\r\n (page)=\"onLdapPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </mat-expansion-panel>\r\n </mat-accordion>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Lines</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"lines\">\r\n <div class=\"line-route-list\">\r\n <div\r\n class=\"line-route-row\"\r\n *ngFor=\"let lineGroup of linesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"line-info\">\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input matInput placeholder=\"Line number\" formControlName=\"lineNumber\" />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search for a number\"\r\n formControlName=\"number\"\r\n [matAutocomplete]=\"numberAuto\"\r\n (input)=\"filterAvailableNumbers(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #numberAuto=\"matAutocomplete\"\r\n [panelWidth]=\"'auto'\"\r\n (optionSelected)=\"onNumberSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option *ngFor=\"let option of getFilteredNumbers(idx)\" [value]=\"option\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('number')?.invalid && getLineGroup(idx).get('number')?.touched\">\r\n Number is required\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Select route partition\"\r\n formControlName=\"routePartition\"\r\n [matAutocomplete]=\"routePartitionAuto\"\r\n (input)=\"filterRoutePartitions(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #routePartitionAuto=\"matAutocomplete\"\r\n (optionSelected)=\"onRoutePartitionSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option\r\n *ngFor=\"let routePartition of getFilteredRoutePartitions(idx)\"\r\n [value]=\"routePartition\"\r\n >\r\n {{ routePartition }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('routePartition')?.invalid && getLineGroup(idx).get('routePartition')?.touched\">\r\n Route partition is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Devices</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"devices\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let deviceGroup of devicesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceNamePrefix(idx) as devicePrefix\">{{ devicePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" />\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('deviceName') && getDeviceGroup(idx).get('name')?.touched\">\r\n {{ getDeviceGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('required') && getDeviceGroup(idx).get('name')?.touched\">\r\n Name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\" *ngIf=\"deviceProfilesFormArray.length\">\r\n <h3 class=\"details-step-section__title\">Device profiles</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"deviceProfiles\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let profileGroup of deviceProfilesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceProfileNamePrefix(idx) as profilePrefix\">{{ profilePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" />\r\n <mat-error *ngIf=\"getDeviceProfileGroup(idx).get('name')?.hasError('deviceName') && getDeviceProfileGroup(idx).get('name')?.touched\">\r\n {{ getDeviceProfileGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceProfileNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </form>\r\n</section>\r\n", styles: [".details-step-content{display:flex;flex-direction:column;gap:0}.details-step-dropdowns{display:flex;flex-direction:column;gap:1rem}.details-step-field{display:flex;flex-direction:column;gap:8px}.details-step-label{font-size:16px;font-weight:400;line-height:100%;letter-spacing:0;color:#333}.details-step-select{width:333px}.details-step-divider{border-top:1px solid #d9d9d9;margin-top:24px}.details-step-sections{display:flex;flex-direction:column}.details-step-section{display:flex;flex-direction:column;gap:0;padding:24px 0}.details-step-sections>.details-step-section:first-child{padding-top:0}.details-step-section+.details-step-section{border-top:1px solid #d9d9d9}.details-step-section__title{margin:0;font-family:Inter,sans-serif;font-size:16px;font-weight:600;line-height:100%;letter-spacing:0;color:#333}.details-step-section__content{margin-top:24px}.details-step-section__part+.details-step-section__part{margin-top:24px}.details-user-accordion{width:100%}.details-user-accordion__content{padding:12px 0 0}.details-ldap-search{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px}.details-ldap-search__input{min-width:180px;width:180px}.details-ldap-search__select{flex:0 1 180px;min-width:160px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-wrapper,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin:0}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-flex,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:0 12px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-gap,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-infix,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-infix{width:100%;border-top:0;padding:0;display:flex;align-items:center;min-height:unset}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-input-element,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-input-element{margin:0;line-height:20px}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-trigger{display:flex;align-items:center;width:100%;height:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-value{display:flex;align-items:center;max-width:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-arrow-wrapper{display:flex;align-items:center}.details-ldap-search__chip{flex:0 0 auto}.details-ldap-search__btn{flex:0 0 auto;min-width:0;padding:0 12px;font-family:Inter,sans-serif;font-size:14px;font-weight:500;color:#0d56aa}.details-ldap-paginator{margin-top:8px}.details-ldap-table__add-btn--delete{color:#c62828}.details-ldap-table{width:100%}.details-ldap-table__empty{margin:16px 0 8px;font-family:Inter,sans-serif;font-size:14px;line-height:20px;color:#737480;text-align:center}.details-ldap-table__row--disabled{opacity:.35}.details-ldap-table__add-btn{min-width:0;padding:0;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#0d56aa}:host ::ng-deep .details-ldap-table .mat-header-cell{font-family:Inter,sans-serif;font-size:12px;font-weight:500;line-height:16px;letter-spacing:0;color:#737480;height:30px;padding:7px 8px}:host ::ng-deep .details-ldap-table .mat-cell{font-family:Inter,sans-serif;font-size:14px;font-weight:400;line-height:20px;letter-spacing:0;color:#333;height:40px;padding:8px}.details-inline-fields{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px}.details-inline-fields--four{grid-template-columns:repeat(4,minmax(0,1fr))}.devices-rows{display:flex;flex-direction:column;gap:24px}.details-inline-field{display:flex;flex-direction:column;gap:4px}.details-inline-field__label{color:#c0c2ce;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0}.details-step-input{width:100%}.line-route-list{display:flex;flex-direction:column;gap:16px}.line-route-row{display:flex;gap:16px}.line-info{display:flex;align-items:flex-start;gap:16px}.line-route-field{flex:1 1 180px;min-width:160px}.line-route-field{display:flex;flex-direction:column;gap:0}.line-route-field:nth-of-type(1) .line-route-select{width:230px}.line-route-field .line-route-select{width:185px}:host ::ng-deep .details-step-select .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-input .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-select .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:6px;padding:0 12px}:host ::ng-deep .details-step-input .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:10px 8px}:host ::ng-deep .details-step-select .mat-form-field-outline,:host ::ng-deep .details-step-select .mat-form-field-outline-start,:host ::ng-deep .details-step-select .mat-form-field-outline-end,:host ::ng-deep .details-step-select .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-input .mat-form-field-outline,:host ::ng-deep .details-step-input .mat-form-field-outline-start,:host ::ng-deep .details-step-input .mat-form-field-outline-end,:host ::ng-deep .details-step-input .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-select .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-input .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}:host ::ng-deep .details-step-input .mat-input-element{height:100%;margin:0}:host ::ng-deep .details-step-input.mat-form-field-disabled .mat-form-field-flex{background-color:#f5f6fa;border-color:#b8beca;opacity:.55;cursor:not-allowed}:host ::ng-deep .details-step-input .mat-input-element:disabled{color:#7f8694;-webkit-text-fill-color:#7f8694;cursor:not-allowed}:host ::ng-deep .line-info .details-step-input .mat-form-field-flex{height:36px;padding:0 8px}:host ::ng-deep .line-info .details-step-input .mat-form-field-infix{padding:0}:host ::ng-deep .line-info .details-step-input .mat-input-element{font-size:14px;line-height:20px}:host ::ng-deep .mat-form-field-subscript-wrapper{position:relative}:host ::ng-deep .line-info .details-step-input .mat-form-field-subscript-wrapper{margin-top:4px;position:relative}:host ::ng-deep .details-user-accordion .mat-expansion-panel{border:0;border-radius:0!important;background:transparent;box-shadow:none!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header{padding:0 0 0 8px;min-height:32px;height:32px}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header-title{margin:0;display:flex;align-items:center;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#333}:host ::ng-deep .details-user-accordion .mat-expansion-panel-body{padding:0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-content{display:flex;align-items:center}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator{display:block!important;opacity:1!important;color:#333!important;align-self:center;margin:0 8px 0 0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator:after{color:#333!important;border-color:#333!important;position:relative;top:-4px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex{display:flex;gap:3px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex .mat-form-field-prefix{top:1px}\n"] }]
|
|
2471
|
+
args: [{ selector: 'tk-user-details-step', template: "<app-loader *ngIf=\"loadingAvailableNumbers\"></app-loader>\r\n<section class=\"details-step-content\">\r\n <form [formGroup]=\"userDetailsForm\">\r\n <div class=\"details-step-sections\">\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">User details</h3>\r\n <div class=\"details-step-section__content\">\r\n <div class=\"details-step-section__part\">\r\n <div class=\"details-inline-fields\">\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User ID</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"User ID\" formControlName=\"userId\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('required') && userDetailsForm.get('userId')?.touched\">\r\n User ID is required\r\n </mat-error>\r\n <mat-error *ngIf=\"userDetailsForm.get('userId')?.hasError('userIdExists') && userDetailsForm.get('userId')?.touched\">\r\n User ID already exists\r\n </mat-error>\r\n <mat-hint *ngIf=\"userIdCheckPending\">Checking user ID...</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">First Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"First Name\" formControlName=\"firstName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('firstName')?.hasError('required') && userDetailsForm.get('firstName')?.touched\">\r\n First name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Last Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Last Name\" formControlName=\"lastName\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('lastName')?.hasError('required') && userDetailsForm.get('lastName')?.touched\">\r\n Last name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Email</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput placeholder=\"Email\" formControlName=\"email\" />\r\n <mat-error *ngIf=\"userDetailsForm.get('email')?.invalid && userDetailsForm.get('email')?.touched\">\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('required')\">Email is required</span>\r\n <span *ngIf=\"userDetailsForm.get('email')?.hasError('email')\">Please enter a valid email</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">User Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input\r\n matInput\r\n placeholder=\"User Template\"\r\n [value]=\"userCreationWizardService.selectedTemplateName || ''\"\r\n [disabled]=\"true\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"details-step-section__part\">\r\n <mat-accordion class=\"details-user-accordion\">\r\n <mat-expansion-panel togglePosition=\"before\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>Choose an existing or a LDAP user</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"details-user-accordion__content\">\r\n <div class=\"details-ldap-search\" [formGroup]=\"ldapSearchForm\">\r\n <mat-form-field\r\n class=\"details-ldap-search__input\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search\"\r\n formControlName=\"queryValue\"\r\n (keyup.enter)=\"searchLdapUsers()\"\r\n />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-ldap-search__select\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n >\r\n <mat-select formControlName=\"queryType\">\r\n <mat-option *ngFor=\"let option of ldapQueryTypeOptions\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-chip-list *ngIf=\"selectedLdapUser\" class=\"details-ldap-search__chip\">\r\n <mat-chip removable (removed)=\"onRemoveLdapTag()\">\r\n {{ selectedLdapUser.userid }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n\r\n <button\r\n mat-button\r\n class=\"details-ldap-search__btn\"\r\n type=\"button\"\r\n [disabled]=\"ldapLoading\"\r\n (click)=\"searchLdapUsers()\"\r\n >\r\n Search\r\n </button>\r\n </div>\r\n\r\n <app-loader *ngIf=\"ldapLoading\"></app-loader>\r\n\r\n <p\r\n *ngIf=\"!ldapLoading && ldapSearchAttempted && !hasLdapUsers\"\r\n class=\"details-ldap-table__empty\"\r\n >\r\n No users found\r\n </p>\r\n\r\n <table\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n mat-table\r\n [dataSource]=\"userCreationWizardService.ldapUsers\"\r\n class=\"details-ldap-table\"\r\n >\r\n <ng-container matColumnDef=\"userId\">\r\n <th mat-header-cell *matHeaderCellDef>User Id</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.userid }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"firstName\">\r\n <th mat-header-cell *matHeaderCellDef>First Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.firstName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"lastName\">\r\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.lastName }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"email\">\r\n <th mat-header-cell *matHeaderCellDef>Email</th>\r\n <td mat-cell *matCellDef=\"let row\">{{ row.email }}</td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"add\">\r\n <th mat-header-cell *matHeaderCellDef>Add</th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <button\r\n *ngIf=\"!isLdapUserRowSelected(row); else deleteLdapUserBtn\"\r\n mat-button\r\n class=\"details-ldap-table__add-btn\"\r\n type=\"button\"\r\n (click)=\"onAddLdapUser(row)\"\r\n >\r\n Add User\r\n </button>\r\n <ng-template #deleteLdapUserBtn>\r\n <button\r\n mat-button\r\n class=\"details-ldap-table__add-btn details-ldap-table__add-btn--delete\"\r\n type=\"button\"\r\n (click)=\"onDeleteLdapUser(row)\"\r\n >\r\n Delete user\r\n </button>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"userCreationWizardService.ldapTableColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: userCreationWizardService.ldapTableColumns\"></tr>\r\n </table>\r\n\r\n <mat-paginator\r\n *ngIf=\"!ldapLoading && hasLdapUsers\"\r\n class=\"details-ldap-paginator\"\r\n [length]=\"ldapTotalCount\"\r\n [pageSize]=\"ldapPageSize\"\r\n [pageIndex]=\"ldapPageIndex\"\r\n [pageSizeOptions]=\"[ldapPageSize]\"\r\n [hidePageSize]=\"true\"\r\n [disabled]=\"ldapLoading\"\r\n (page)=\"onLdapPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </mat-expansion-panel>\r\n </mat-accordion>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Lines</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"lines\">\r\n <div class=\"line-route-list\">\r\n <div\r\n class=\"line-route-row\"\r\n *ngFor=\"let lineGroup of linesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"line-info\">\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input matInput placeholder=\"Line number\" formControlName=\"lineNumber\" />\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Search for a number\"\r\n formControlName=\"number\"\r\n [matAutocomplete]=\"numberAuto\"\r\n (input)=\"filterAvailableNumbers(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #numberAuto=\"matAutocomplete\"\r\n [panelWidth]=\"'auto'\"\r\n (optionSelected)=\"onNumberSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option *ngFor=\"let option of getFilteredNumbers(idx)\" [value]=\"option\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('number')?.invalid && getLineGroup(idx).get('number')?.touched\">\r\n Number is required\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n class=\"details-step-input line-route-field\"\r\n appearance=\"outline\"\r\n floatLabel=\"never\"\r\n hideRequiredMarker\r\n >\r\n <input\r\n matInput\r\n placeholder=\"Select route partition\"\r\n formControlName=\"routePartition\"\r\n [matAutocomplete]=\"routePartitionAuto\"\r\n (input)=\"filterRoutePartitions(idx, $event)\"\r\n />\r\n <mat-autocomplete\r\n #routePartitionAuto=\"matAutocomplete\"\r\n (optionSelected)=\"onRoutePartitionSelected(idx, $event.option.value)\"\r\n >\r\n <mat-option\r\n *ngFor=\"let routePartition of getFilteredRoutePartitions(idx)\"\r\n [value]=\"routePartition\"\r\n >\r\n {{ routePartition }}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"getLineGroup(idx).get('routePartition')?.invalid && getLineGroup(idx).get('routePartition')?.touched\">\r\n Route partition is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\">\r\n <h3 class=\"details-step-section__title\">Devices</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"devices\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let deviceGroup of devicesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceNamePrefix(idx) as devicePrefix\">{{ devicePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" [readonly]=\"isDeviceNameReadonly(idx, false)\" />\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('deviceName') && getDeviceGroup(idx).get('name')?.touched\">\r\n {{ getDeviceGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n <mat-error *ngIf=\"getDeviceGroup(idx).get('name')?.hasError('required') && getDeviceGroup(idx).get('name')?.touched\">\r\n Name is required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <section class=\"details-step-section\" *ngIf=\"deviceProfilesFormArray.length\">\r\n <h3 class=\"details-step-section__title\">Device profiles</h3>\r\n <div class=\"details-step-section__content\" formArrayName=\"deviceProfiles\">\r\n <div class=\"devices-rows\">\r\n <div\r\n class=\"details-inline-fields details-inline-fields--four\"\r\n *ngFor=\"let profileGroup of deviceProfilesFormArray.controls; let idx = index\"\r\n [formGroupName]=\"idx\"\r\n >\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Device type</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"deviceType\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Protocol</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"protocol\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Button Template</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <input matInput formControlName=\"buttonTemplate\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"details-inline-field\">\r\n <label class=\"details-inline-field__label\">Name</label>\r\n <mat-form-field class=\"details-step-input\" appearance=\"outline\">\r\n <span matPrefix *ngIf=\"getDeviceProfileNamePrefix(idx) as profilePrefix\">{{ profilePrefix }}</span>\r\n <input matInput placeholder=\"Name\" formControlName=\"name\" [readonly]=\"isDeviceNameReadonly(idx, true)\" />\r\n <mat-error *ngIf=\"getDeviceProfileGroup(idx).get('name')?.hasError('deviceName') && getDeviceProfileGroup(idx).get('name')?.touched\">\r\n {{ getDeviceProfileGroup(idx).get('name')?.getError('deviceName')?.caption || getDeviceProfileNameValidationCaption(idx) || 'Please enter a valid device name' }}\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </form>\r\n</section>\r\n", styles: [".details-step-content{display:flex;flex-direction:column;gap:0}.details-step-dropdowns{display:flex;flex-direction:column;gap:1rem}.details-step-field{display:flex;flex-direction:column;gap:8px}.details-step-label{font-size:16px;font-weight:400;line-height:100%;letter-spacing:0;color:#333}.details-step-select{width:333px}.details-step-divider{border-top:1px solid #d9d9d9;margin-top:24px}.details-step-sections{display:flex;flex-direction:column}.details-step-section{display:flex;flex-direction:column;gap:0;padding:24px 0}.details-step-sections>.details-step-section:first-child{padding-top:0}.details-step-section+.details-step-section{border-top:1px solid #d9d9d9}.details-step-section__title{margin:0;font-family:Inter,sans-serif;font-size:16px;font-weight:600;line-height:100%;letter-spacing:0;color:#333}.details-step-section__content{margin-top:24px}.details-step-section__part+.details-step-section__part{margin-top:24px}.details-user-accordion{width:100%}.details-user-accordion__content{padding:12px 0 0}.details-ldap-search{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px}.details-ldap-search__input{min-width:180px;width:180px}.details-ldap-search__select{flex:0 1 180px;min-width:160px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-wrapper,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin:0}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-flex,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:0 12px}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-outline-gap,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-start,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-end,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-form-field-infix,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-form-field-infix{width:100%;border-top:0;padding:0;display:flex;align-items:center;min-height:unset}:host ::ng-deep .details-ldap-search__input.mat-form-field .mat-input-element,:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-input-element{margin:0;line-height:20px}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-trigger{display:flex;align-items:center;width:100%;height:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-value{display:flex;align-items:center;max-width:100%}:host ::ng-deep .details-ldap-search__select.mat-form-field .mat-select-arrow-wrapper{display:flex;align-items:center}.details-ldap-search__chip{flex:0 0 auto}.details-ldap-search__btn{flex:0 0 auto;min-width:0;padding:0 12px;font-family:Inter,sans-serif;font-size:14px;font-weight:500;color:#0d56aa}.details-ldap-paginator{margin-top:8px}.details-ldap-table__add-btn--delete{color:#c62828}.details-ldap-table{width:100%}.details-ldap-table__empty{margin:16px 0 8px;font-family:Inter,sans-serif;font-size:14px;line-height:20px;color:#737480;text-align:center}.details-ldap-table__row--disabled{opacity:.35}.details-ldap-table__add-btn{min-width:0;padding:0;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#0d56aa}:host ::ng-deep .details-ldap-table .mat-header-cell{font-family:Inter,sans-serif;font-size:12px;font-weight:500;line-height:16px;letter-spacing:0;color:#737480;height:30px;padding:7px 8px}:host ::ng-deep .details-ldap-table .mat-cell{font-family:Inter,sans-serif;font-size:14px;font-weight:400;line-height:20px;letter-spacing:0;color:#333;height:40px;padding:8px}.details-inline-fields{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px}.details-inline-fields--four{grid-template-columns:repeat(4,minmax(0,1fr))}.devices-rows{display:flex;flex-direction:column;gap:24px}.details-inline-field{display:flex;flex-direction:column;gap:4px}.details-inline-field__label{color:#c0c2ce;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0}.details-step-input{width:100%}.line-route-list{display:flex;flex-direction:column;gap:16px}.line-route-row{display:flex;gap:16px}.line-info{display:flex;align-items:flex-start;gap:16px}.line-route-field{flex:1 1 180px;min-width:160px}.line-route-field{display:flex;flex-direction:column;gap:0}.line-route-field:nth-of-type(1) .line-route-select{width:230px}.line-route-field .line-route-select{width:185px}:host ::ng-deep .details-step-select .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-input .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .details-step-select .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:6px;padding:0 12px}:host ::ng-deep .details-step-input .mat-form-field-flex{align-items:center;height:36px;border:1px solid #767676;border-radius:4px;padding:10px 8px}:host ::ng-deep .details-step-select .mat-form-field-outline,:host ::ng-deep .details-step-select .mat-form-field-outline-start,:host ::ng-deep .details-step-select .mat-form-field-outline-end,:host ::ng-deep .details-step-select .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-input .mat-form-field-outline,:host ::ng-deep .details-step-input .mat-form-field-outline-start,:host ::ng-deep .details-step-input .mat-form-field-outline-end,:host ::ng-deep .details-step-input .mat-form-field-outline-gap{display:none}:host ::ng-deep .details-step-select .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-input .mat-form-field-infix{width:100%;border-top:0;padding:0}:host ::ng-deep .details-step-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}:host ::ng-deep .details-step-input .mat-input-element{height:100%;margin:0}:host ::ng-deep .details-step-input.mat-form-field-disabled .mat-form-field-flex{background-color:#f5f6fa;border-color:#b8beca;opacity:.55;cursor:not-allowed}:host ::ng-deep .details-step-input .mat-input-element:disabled{color:#7f8694;-webkit-text-fill-color:#7f8694;cursor:not-allowed}:host ::ng-deep .line-info .details-step-input .mat-form-field-flex{height:36px;padding:0 8px}:host ::ng-deep .line-info .details-step-input .mat-form-field-infix{padding:0}:host ::ng-deep .line-info .details-step-input .mat-input-element{font-size:14px;line-height:20px}:host ::ng-deep .mat-form-field-subscript-wrapper{position:relative}:host ::ng-deep .line-info .details-step-input .mat-form-field-subscript-wrapper{margin-top:4px;position:relative}:host ::ng-deep .details-user-accordion .mat-expansion-panel{border:0;border-radius:0!important;background:transparent;box-shadow:none!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header{padding:0 0 0 8px;min-height:32px;height:32px}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header-title{margin:0;display:flex;align-items:center;font-family:Inter,sans-serif;font-size:14px;font-weight:500;line-height:20px;letter-spacing:0;color:#333}:host ::ng-deep .details-user-accordion .mat-expansion-panel-body{padding:0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-content{display:flex;align-items:center}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator{display:block!important;opacity:1!important;color:#333!important;align-self:center;margin:0 8px 0 0!important}:host ::ng-deep .details-user-accordion .mat-expansion-panel-header .mat-expansion-indicator:after{color:#333!important;border-color:#333!important;position:relative;top:-4px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex{display:flex;gap:3px}:host ::ng-deep .devices-rows .details-inline-fields .details-inline-field .mat-form-field .mat-form-field-flex .mat-form-field-prefix{top:1px}\n"] }]
|
|
2347
2472
|
}], ctorParameters: function () { return [{ type: i1$2.FormBuilder }, { type: UserCreationApiService }, { type: UserCreationWizardService }]; }, propDecorators: { validityChange: [{
|
|
2348
2473
|
type: Output
|
|
2349
2474
|
}] } });
|