@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.
@@ -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
- function applyDefaultDevicePrefixIfMissing(device) {
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(/^(\(.+?\))(.+)$/s);
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(/^([A-Za-z]+)(\[.+\])$/s);
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
- device.name = '';
1280
- });
1281
- this.deviceProfiles.forEach(profile => {
1282
- profile.name = '';
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('[DN]', directoryNumber);
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 rawName = (device.name || device.newName || '').trim();
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
- savedDevice?.name ?? device.name ?? '',
2156
- this.buildDeviceNameValidators(index, false),
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
- savedProfile?.name ?? profile.name ?? '',
2168
- this.buildDeviceNameValidators(index, true),
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
  }] } });