@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
294 lines • 69 kB
JavaScript
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