UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

294 lines 69 kB
import { Component, Optional, ViewChild } from '@angular/core'; import { TenantService } from '@c8y/client'; import { FormControl, FormGroup, NgForm } from '@angular/forms'; import { TenantUiService, AlertService, gettext, GainsightService } from '@c8y/ngx-components'; import { ActivatedRoute } from '@angular/router'; import { assign, cloneDeep, find } from 'lodash-es'; import { Location } from '@angular/common'; import { Ng1TenantPoliciesService } from '@c8y/ngx-components/upgrade/upgraded-services'; import { tenantFormInputsDefinitions } from './tenant-form-inputs-definitions'; import { TranslateService } from '@ngx-translate/core'; import { PRODUCT_EXPERIENCE_TENANT_MANAGEMENT } from '../tenants.model'; import { take } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components/upgrade/upgraded-services"; import * as i2 from "@c8y/client"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/common"; import * as i5 from "@angular/router"; import * as i6 from "@ngx-translate/core"; import * as i7 from "@angular/forms"; import * as i8 from "../support-user-access/support-user-access.component"; const { ACTIONS, COMPONENTS, EVENTS, RESULTS } = PRODUCT_EXPERIENCE_TENANT_MANAGEMENT; export class TenantFormComponent { constructor(tenantPoliciesServiceProvider, tenantService, tenantUiService, location, alertService, activatedRoute, translateService, gainsightService) { this.tenantPoliciesServiceProvider = tenantPoliciesServiceProvider; this.tenantService = tenantService; this.tenantUiService = tenantUiService; this.location = location; this.alertService = alertService; this.activatedRoute = activatedRoute; this.translateService = translateService; this.gainsightService = gainsightService; this.MANAGEMENT_TENANT_NAME = this.tenantUiService.MANAGEMENT; this.tenant = null; this.tenantPolicyNone = { name: this.translateService.instant(gettext('None')) }; this.saveInProgress = false; this.showPasswordComponent = false; this.tenantForm = new FormGroup({}); this.fieldDefinitions = { ...tenantFormInputsDefinitions }; this.initialized = false; } async ngOnInit() { await this.getHost(); this.getTenantId(); await this.getTenant(); await this.checkIfIsEnterpriseEdition(); this.initialized = true; if (!this.isNew) { this.sendGainsightEvent(ACTIONS.TENANT_PROPERTIES_OPENED); } this.tenantForm.valueChanges.pipe(take(1)).subscribe(() => { this.sendGainsightEvent(this.isNew ? ACTIONS.TENANT_CREATION_STARTED_FILLING : ACTIONS.TENANT_PROPERTIES_STARTED_CHANGING); }); } async onTenantPolicyChange() { const passwordSettings = await this.tenantUiService.getPasswordStrengthSettings(); this.tenantPolicy = find(this.tenantPolicies, { id: this.tenantForm.controls.tenantPolicy.value.id }); const enforcedOnSystemLevel = passwordSettings.enforceStrength; const enforcedOnTenantLevel = passwordSettings.strengthValidity; const enforcedOnTenantPolicyLevel = this.tenantPoliciesServiceProvider ? await this.tenantPoliciesServiceProvider.doesEnforceStrongPassword(this.tenantPolicy) : undefined; if (this.isNew) { this.passwordStrengthEnforced = enforcedOnSystemLevel || enforcedOnTenantPolicyLevel; } else { this.passwordStrengthEnforced = enforcedOnSystemLevel || enforcedOnTenantLevel; } } setForm() { this.tenantForm.patchValue({ tenantId: this.tenant.id, domain: this.tenant.domain, companyName: this.tenant.company, contactName: this.tenant.contactName, contactPhone: this.tenant.contactPhone, administratorEmail: this.tenant.adminEmail, administratorUsername: this.tenant.adminName, sendPasswordResetEmail: this.tenant.sendPasswordResetEmail, allowCreateTenants: this.tenant.allowCreateTenants, externalReference: this.tenant.customProperties.externalReference, gainsightEnabled: this.tenant.customProperties.gainsightEnabled }); } getTenantId() { this.tenantId = this.activatedRoute.snapshot.parent.data.contextData.id; this.isNew = !this.tenantId; } async onSubmit() { let tenantToBeSaved; if (!this.isNew) { const formRawValue = this.tenantForm.getRawValue(); const customProperties = { ...this.tenant.customProperties, externalReference: formRawValue.externalReference, gainsightEnabled: formRawValue.gainsightEnabled }; tenantToBeSaved = { id: this.tenant.id, company: formRawValue.companyName, contactName: formRawValue.contactName, contactPhone: formRawValue.contactPhone, domain: formRawValue.domain, status: this.tenant.status, allowCreateTenants: this.tenantForm.value.allowCreateTenants, customProperties: customProperties }; } else { tenantToBeSaved = { adminEmail: this.tenantForm.value.administratorEmail, adminName: this.tenantForm.value.administratorUsername, company: this.tenantForm.value.companyName, contactName: this.tenantForm.value.contactName, contactPhone: this.tenantForm.value.contactPhone, domain: this.tenantForm.value.domain, adminPass: this.tenantForm.value.password, sendPasswordResetEmail: this.tenantForm.value.sendPasswordResetEmail, tenantPolicyId: this.tenantForm.value.tenantPolicy?.id }; } if (this.isNew && this.host) { tenantToBeSaved.domain = tenantToBeSaved.domain + this.host; } const t = cloneDeep(tenantToBeSaved); if (t.storageLimitPerDevice === undefined) { t.storageLimitPerDevice = 0; } this.setSaveInProgress(true); try { let savedTenant; if (this.isNew) { savedTenant = (await this.tenantService.create(t)).data; if (this.tenantForm.value.allowCreateTenants) { assign(savedTenant, { allowCreateTenants: this.tenantForm.value.allowCreateTenants }); await this.tenantService.update(savedTenant); } } else { savedTenant = (await this.tenantService.update(t)).data; } this.sendGainsightEvent(this.isNew ? ACTIONS.TENANT_CREATION_SAVED : ACTIONS.TENANT_PROPERTIES_SAVED, { result: RESULTS.SUCCESS }); this.onSave(savedTenant, this.tenantForm); } catch (error) { this.alertService.addServerFailure(error); this.sendGainsightEvent(this.isNew ? ACTIONS.TENANT_CREATION_SAVED : ACTIONS.TENANT_PROPERTIES_SAVED, { result: RESULTS.FAILURE, error }); } finally { this.setSaveInProgress(false); } } onSave(tenant, form) { if (this.isNew) { setTimeout(() => { this.location.go(`/tenants/${tenant.id}`); location.reload(); }, 2000); this.alertService.success(gettext('Tenant saved.')); } assign(this.tenant, tenant); this.alertService.success(gettext('Tenant saved.')); form.markAsPristine(); } setSaveInProgress(value) { this.saveInProgress = value; } cancel() { this.location.go('tenants'); } shouldDisableSave() { const disabled = !this.tenantForm.valid || !this.tenantForm.dirty || this.saveInProgress; if (this.showPasswordComponent) { if (this.passwordForm) { return disabled || !this.passwordForm.valid; } else { return true; } } else { return disabled; } } onNewPasswordChanged(newPassword) { this.tenantForm.addControl('password', new FormControl(newPassword.password)); } onCheckboxChange(inputField) { if (inputField === 'sendPasswordResetEmail') { this.showPasswordComponent = !this.tenantForm.value.sendPasswordResetEmail; this.removePasswordControl(this.showPasswordComponent); } } setDisabledState() { if (!this.isNew) { this.tenantForm.controls.tenantId.disable(); this.tenantForm.controls.domain.disable(); this.tenantForm.controls.administratorEmail.disable(); this.tenantForm.controls.administratorUsername.disable(); } } async shouldShowSubtenantCheckbox() { const currentTenantIsManagement = await this.tenantUiService.isManagementTenant(); const editedTenantIsChildOfManagement = this.tenant && this.tenant.parent === this.MANAGEMENT_TENANT_NAME; return currentTenantIsManagement && (editedTenantIsChildOfManagement || this.isNew); } removePasswordControl(passwordComponentShown) { if (!passwordComponentShown) { this.tenantForm.removeControl('password'); } } async getTenant() { if (this.tenantId && this.tenantId !== 'new') { const detailedTenant = (await this.tenantService.detail(this.tenantId)).data; this.title = detailedTenant.company; this.onTenant(detailedTenant); await this.generateForm(); this.setForm(); this.setDisabledState(); } else { this.title = this.translateService.instant(gettext('New tenant')); await this.generateForm(); await this.loadTenantPolicies(); } } async loadTenantPolicies() { if (this.tenantPoliciesServiceProvider) { this.onTenantPolicies(await this.tenantPoliciesServiceProvider.list()); } } async getHost() { const currentTenant = await this.tenantService.current(); this.host = `.${currentTenant.data.domainName.split('.').slice(1).join('.')}`; } async checkIfIsEnterpriseEdition() { this.isEnterpriseEditionTenant = await this.tenantUiService.isEnterpriseTenant(); } onTenantPolicies(tenantPolicies) { this.tenantPolicies = [this.tenantPolicyNone, ...tenantPolicies]; } onTenant(tenant = {}) { this.tenant = tenant; } async generateForm() { const shouldShowSubtenantCheckbox = await this.shouldShowSubtenantCheckbox(); const gainsightAvailable = !!(await this.gainsightService.getGainsightKey()); if (!shouldShowSubtenantCheckbox) { delete this.fieldDefinitions.allowCreateTenants; } if (!this.isNew) { delete this.fieldDefinitions.sendPasswordResetEmail; } if (this.isNew || (this.host && this.isEnterpriseEditionTenant)) { delete this.fieldDefinitions.tenantID; } if (!this.isNew && !this.host) { delete this.fieldDefinitions.domain; } if (this.isNew || !gainsightAvailable) { delete this.fieldDefinitions.gainsightEnabled; } if (this.isNew) { delete this.fieldDefinitions.externalReference; } for (const field of Object.values(this.fieldDefinitions)) { this.tenantForm.addControl(field.id, new FormControl(field.defaultValue, field.validators)); } this.fieldKeys = Object.keys(this.fieldDefinitions); } sendGainsightEvent(action, props = {}) { this.gainsightService.triggerEvent(EVENTS.TENANT_MANAGEMENT, { component: COMPONENTS.TENANT_FORM, action, ...props }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantFormComponent, deps: [{ token: i1.Ng1TenantPoliciesService, optional: true }, { token: i2.TenantService }, { token: i3.TenantUiService }, { token: i4.Location }, { token: i3.AlertService }, { token: i5.ActivatedRoute }, { token: i6.TranslateService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TenantFormComponent, selector: "c8y-tenant-form", viewQueries: [{ propertyName: "passwordForm", first: true, predicate: ["passwordForm"], descendants: true }], ngImport: i0, template: "<c8y-title *ngIf=\"title\">\n {{ title }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<form\n [formGroup]=\"tenantForm\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div class=\"card content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"inner-scroll bg-level-0\">\n <div class=\"card-header separator large-padding sticky-top\">\n <div\n class=\"card-title\"\n translate\n >\n Identification\n </div>\n </div>\n\n <div>\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let key of fieldKeys\">\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'text'\">\n <ng-container\n *ngTemplateOutlet=\"textField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'checkbox'\">\n <ng-container\n *ngTemplateOutlet=\"checkboxField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <div\n class=\"inner-scroll bg-level-1\"\n *ngIf=\"!isNew && tenant\"\n >\n <c8y-support-user-access [tenant]=\"tenant\"></c8y-support-user-access>\n </div>\n\n <!-- FOOTER CARD -->\n <div\n class=\"card-footer separator large-padding grid__col--fullspan\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n data-cy=\"c8y-tenant-form--cancelButton\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n [disabled]=\"shouldDisableSave()\"\n data-cy=\"c8y-tenant-form--saveButton\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n\n <!-- NG TEMPLATES -->\n <ng-template\n #textField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"text\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span\n class=\"input-group-addon\"\n *ngIf=\"fieldDefinition.id === 'domain' && host && isNew\"\n >\n {{ host }}\n </span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <input\n class=\"form-control\"\n type=\"number\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #checkboxField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n [title]=\"fieldDefinition.label | translate\"\n [for]=\"fieldDefinition.id\"\n >\n <input\n type=\"checkbox\"\n [id]=\"fieldDefinition.id\"\n [formControlName]=\"fieldDefinition.id\"\n (change)=\"onCheckboxChange(fieldDefinition.id)\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span></span>\n <span>{{ fieldDefinition.label | translate }}</span>\n </label>\n </c8y-form-group>\n <form\n #passwordForm=\"ngForm\"\n *ngIf=\"showPasswordComponent && fieldDefinition.id === 'sendPasswordResetEmail'\"\n >\n <c8y-new-password\n [showChangePasswordButton]=\"false\"\n [requireStrongPassword]=\"passwordStrengthEnforced\"\n (password)=\"onNewPasswordChanged($event)\"\n ></c8y-new-password>\n </form>\n </ng-template>\n\n <ng-template\n #selectField\n let-fieldDefinition\n >\n <c8y-form-group *ngIf=\"tenantPolicies && tenantPolicies.length > 0\">\n <label>{{ fieldDefinition.label | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n title=\"{{ fieldDefinition.label | translate }}\"\n name=\"tenantPolicy\"\n (change)=\"onTenantPolicyChange()\"\n formControlName=\"tenantPolicy\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n >\n <option\n *ngFor=\"let tenantPolicy of tenantPolicies\"\n [ngValue]=\"tenantPolicy\"\n >\n {{ tenantPolicy.name }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n", dependencies: [{ kind: "component", type: i3.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i3.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3.NewPasswordComponent, selector: "c8y-new-password", inputs: ["showChangePasswordButton", "requireStrongPassword"], outputs: ["password"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.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: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i8.SupportUserAccessComponent, selector: "c8y-support-user-access", inputs: ["tenant"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantFormComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-tenant-form', template: "<c8y-title *ngIf=\"title\">\n {{ title }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<form\n [formGroup]=\"tenantForm\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div class=\"card content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"inner-scroll bg-level-0\">\n <div class=\"card-header separator large-padding sticky-top\">\n <div\n class=\"card-title\"\n translate\n >\n Identification\n </div>\n </div>\n\n <div>\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let key of fieldKeys\">\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'text'\">\n <ng-container\n *ngTemplateOutlet=\"textField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'checkbox'\">\n <ng-container\n *ngTemplateOutlet=\"checkboxField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <div\n class=\"inner-scroll bg-level-1\"\n *ngIf=\"!isNew && tenant\"\n >\n <c8y-support-user-access [tenant]=\"tenant\"></c8y-support-user-access>\n </div>\n\n <!-- FOOTER CARD -->\n <div\n class=\"card-footer separator large-padding grid__col--fullspan\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n data-cy=\"c8y-tenant-form--cancelButton\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n [disabled]=\"shouldDisableSave()\"\n data-cy=\"c8y-tenant-form--saveButton\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n\n <!-- NG TEMPLATES -->\n <ng-template\n #textField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"text\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span\n class=\"input-group-addon\"\n *ngIf=\"fieldDefinition.id === 'domain' && host && isNew\"\n >\n {{ host }}\n </span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <input\n class=\"form-control\"\n type=\"number\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #checkboxField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n [title]=\"fieldDefinition.label | translate\"\n [for]=\"fieldDefinition.id\"\n >\n <input\n type=\"checkbox\"\n [id]=\"fieldDefinition.id\"\n [formControlName]=\"fieldDefinition.id\"\n (change)=\"onCheckboxChange(fieldDefinition.id)\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span></span>\n <span>{{ fieldDefinition.label | translate }}</span>\n </label>\n </c8y-form-group>\n <form\n #passwordForm=\"ngForm\"\n *ngIf=\"showPasswordComponent && fieldDefinition.id === 'sendPasswordResetEmail'\"\n >\n <c8y-new-password\n [showChangePasswordButton]=\"false\"\n [requireStrongPassword]=\"passwordStrengthEnforced\"\n (password)=\"onNewPasswordChanged($event)\"\n ></c8y-new-password>\n </form>\n </ng-template>\n\n <ng-template\n #selectField\n let-fieldDefinition\n >\n <c8y-form-group *ngIf=\"tenantPolicies && tenantPolicies.length > 0\">\n <label>{{ fieldDefinition.label | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n title=\"{{ fieldDefinition.label | translate }}\"\n name=\"tenantPolicy\"\n (change)=\"onTenantPolicyChange()\"\n formControlName=\"tenantPolicy\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n >\n <option\n *ngFor=\"let tenantPolicy of tenantPolicies\"\n [ngValue]=\"tenantPolicy\"\n >\n {{ tenantPolicy.name }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n" }] }], ctorParameters: () => [{ type: i1.Ng1TenantPoliciesService, decorators: [{ type: Optional }] }, { type: i2.TenantService }, { type: i3.TenantUiService }, { type: i4.Location }, { type: i3.AlertService }, { type: i5.ActivatedRoute }, { type: i6.TranslateService }, { type: i3.GainsightService }], propDecorators: { passwordForm: [{ type: ViewChild, args: ['passwordForm'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWZvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVuYW50cy90ZW5hbnQtZm9ybS90ZW5hbnQtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi90ZW5hbnRzL3RlbmFudC1mb3JtL3RlbmFudC1mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQVcsYUFBYSxFQUFpQixNQUFNLGFBQWEsQ0FBQztBQUNwRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFlBQVksRUFDWixPQUFPLEVBRVAsZ0JBQWdCLEVBQ2pCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDekYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUVMLG9DQUFvQyxFQUVyQyxNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7OztBQUV0QyxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcs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dGlvbmFsLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElUZW5hbnQsIFRlbmFudFNlcnZpY2UsIElUZW5hbnRQb2xpY3kgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBOZ0Zvcm0gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBUZW5hbnRVaVNlcnZpY2UsXG4gIEFsZXJ0U2VydmljZSxcbiAgZ2V0dGV4dCxcbiAgTmV3UGFzc3dvcmQsXG4gIEdhaW5zaWdodFNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBhc3NpZ24sIGNsb25lRGVlcCwgZmluZCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZzFUZW5hbnRQb2xpY2llc1NlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL3VwZ3JhZGUvdXBncmFkZWQtc2VydmljZXMnO1xuaW1wb3J0IHsgdGVuYW50Rm9ybUlucHV0c0RlZmluaXRpb25zIH0gZnJvbSAnLi90ZW5hbnQtZm9ybS1pbnB1dHMtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtcbiAgVGVuYW50TWFuYWdlbWVudEFjdGlvblR5cGUsXG4gIFBST0RVQ1RfRVhQRVJJRU5DRV9URU5BTlRfTUFOQUdFTUVOVCxcbiAgVGVuYW50TWFuYWdlbWVudFJlc3VsdFR5cGVcbn0gZnJvbSAnLi4vdGVuYW50cy5tb2RlbCc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCB7IEFDVElPTlMsIENPTVBPTkVOVFMsIEVWRU5UUywgUkVTVUxUUyB9ID0gUFJPRFVDVF9FWFBFUklFTkNFX1RFTkFOVF9NQU5BR0VNRU5UO1xuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3RlbmFudC1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgc2VsZWN0b3I6ICdjOHktdGVuYW50LWZvcm0nXG59KVxuZXhwb3J0IGNsYXNzIFRlbmFudEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBAVmlld0NoaWxkKCdwYXNzd29yZEZvcm0nKSBwYXNzd29yZEZvcm06IE5nRm9ybTtcbiAgTUFOQUdFTUVOVF9URU5BTlRfTkFNRSA9IHRoaXMudGVuYW50VWlTZXJ2aWNlLk1BTkFHRU1FTlQ7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGhvc3Q6IHN0cmluZztcbiAgaXNUb3BUZW5hbnQ6IGJvb2xlYW47XG4gIGlzTmV3OiBib29sZWFuO1xuICBpc0VudGVycHJpc2VFZGl0aW9uVGVuYW50OiBib29sZWFuO1xuICB0ZW5hbnQ6IElUZW5hbnQgfCBudWxsID0gbnVsbDtcbiAgdGVuYW50UG9saWNpZXM6IEFycmF5PElUZW5hbnRQb2xpY3k+O1xuICB0ZW5hbnRQb2xpY3lOb25lID0geyBuYW1lOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChnZXR0ZXh0KCdOb25lJykpIH07XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZDogYm9vbGVhbjtcbiAgc2F2ZUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgc2hvd1Bhc3N3b3JkQ29tcG9uZW50ID0gZmFsc2U7XG4gIHRlbmFudFBvbGljeTogSVRlbmFudFBvbGljeTtcbiAgZmllbGRLZXlzOiBzdHJpbmdbXTtcbiAgdGVuYW50Rm9ybTogRm9ybUdyb3VwID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gIGZpZWxkRGVmaW5pdGlvbnMgPSB7IC4uLnRlbmFudEZvcm1JbnB1dHNEZWZpbml0aW9ucyB9O1xuICBpbml0aWFsaXplZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIHB1YmxpYyB0ZW5hbnRQb2xpY2llc1NlcnZpY2VQcm92aWRlcjogTmcxVGVuYW50UG9saWNpZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgdGVuYW50U2VydmljZTogVGVuYW50U2VydmljZSxcbiAgICBwcml2YXRlIHRlbmFudFVpU2VydmljZTogVGVuYW50VWlTZXJ2aWNlLFxuICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ2FpbnNpZ2h0U2VydmljZTogR2FpbnNpZ2h0U2VydmljZVxuICApIHt9XG5cbiAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5nZXRIb3N0KCk7XG4gICAgdGhpcy5nZXRUZW5hbnRJZCgpO1xuICAgIGF3YWl0IHRoaXMuZ2V0VGVuYW50KCk7XG4gICAgYXdhaXQgdGhpcy5jaGVja0lmSXNFbnRlcnByaXNlRWRpdGlvbigpO1xuXG4gICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICBpZiAoIXRoaXMuaXNOZXcpIHtcbiAgICAgIHRoaXMuc2VuZEdhaW5zaWdodEV2ZW50KEFDVElPTlMuVEVOQU5UX1BST1BFUlRJRVNfT1BFTkVEKTtcbiAgICB9XG5cbiAgICB0aGlzLnRlbmFudEZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuc2VuZEdhaW5zaWdodEV2ZW50KFxuICAgICAgICB0aGlzLmlzTmV3XG4gICAgICAgICAgPyBBQ1RJT05TLlRFTkFOVF9DUkVBVElPTl9TVEFSVEVEX0ZJTExJTkdcbiAgICAgICAgICA6IEFDVElPTlMuVEVOQU5UX1BST1BFUlRJRVNfU1RBUlRFRF9DSEFOR0lOR1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIG9uVGVuYW50UG9saWN5Q2hhbmdlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBhc3N3b3JkU2V0dGluZ3MgPSBhd2FpdCB0aGlzLnRlbmFudFVpU2VydmljZS5nZXRQYXNzd29yZFN0cmVuZ3RoU2V0dGluZ3MoKTtcbiAgICB0aGlzLnRlbmFudFBvbGljeSA9IGZpbmQodGhpcy50ZW5hbnRQb2xpY2llcywge1xuICAgICAgaWQ6IHRoaXMudGVuYW50Rm9ybS5jb250cm9scy50ZW5hbnRQb2xpY3kudmFsdWUuaWRcbiAgICB9KTtcbiAgICBjb25zdCBlbmZvcmNlZE9uU3lzdGVtTGV2ZWwgPSBwYXNzd29yZFNldHRpbmdzLmVuZm9yY2VTdHJlbmd0aDtcbiAgICBjb25zdCBlbmZvcmNlZE9uVGVuYW50TGV2ZWwgPSBwYXNzd29yZFNldHRpbmdzLnN0cmVuZ3RoVmFsaWRpdHk7XG4gICAgY29uc3QgZW5mb3JjZWRPblRlbmFudFBvbGljeUxldmVsID0gdGhpcy50ZW5hbnRQb2xpY2llc1NlcnZpY2VQcm92aWRlclxuICAgICAgPyBhd2FpdCB0aGlzLnRlbmFudFBvbGljaWVzU2VydmljZVByb3ZpZGVyLmRvZXNFbmZvcmNlU3Ryb25nUGFzc3dvcmQodGhpcy50ZW5hbnRQb2xpY3kpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGlmICh0aGlzLmlzTmV3KSB7XG4gICAgICB0aGlzLnBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZCA9IGVuZm9yY2VkT25TeXN0ZW1MZXZlbCB8fCBlbmZvcmNlZE9uVGVuYW50UG9saWN5TGV2ZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFzc3dvcmRTdHJlbmd0aEVuZm9yY2VkID0gZW5mb3JjZWRPblN5c3RlbUxldmVsIHx8IGVuZm9yY2VkT25UZW5hbnRMZXZlbDtcbiAgICB9XG4gIH1cblxuICBzZXRGb3JtKCk6IHZvaWQge1xuICAgIHRoaXMudGVuYW50Rm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgIHRlbmFudElkOiB0aGlzLnRlbmFudC5pZCxcbiAgICAgIGRvbWFpbjogdGhpcy50ZW5hbnQuZG9tYWluLFxuICAgICAgY29tcGFueU5hbWU6IHRoaXMudGVuYW50LmNvbXBhbnksXG4gICAgICBjb250YWN0TmFtZTogdGhpcy50ZW5hbnQuY29udGFjdE5hbWUsXG4gICAgICBjb250YWN0UGhvbmU6IHRoaXMudGVuYW50LmNvbnRhY3RQaG9uZSxcbiAgICAgIGFkbWluaXN0cmF0b3JFbWFpbDogdGhpcy50ZW5hbnQuYWRtaW5FbWFpbCxcbiAgICAgIGFkbWluaXN0cmF0b3JVc2VybmFtZTogdGhpcy50ZW5hbnQuYWRtaW5OYW1lLFxuICAgICAgc2VuZFBhc3N3b3JkUmVzZXRFbWFpbDogdGhpcy50ZW5hbnQuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCxcbiAgICAgIGFsb