UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

533 lines (527 loc) 46.9 kB
import * as i1 from '@c8y/ngx-components'; import { C8yTranslateDirective, FormGroupComponent, RequiredInputPlaceholderDirective, C8yTranslatePipe, CommonModule, FormsModule as FormsModule$1 } from '@c8y/ngx-components'; import * as i0 from '@angular/core'; import { Injectable, EventEmitter, Output, Input, Component, NgModule } from '@angular/core'; import * as i2 from '@angular/forms'; import { FormControl, Validators, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { gettext } from '@c8y/ngx-components/gettext'; import { NgFor, NgSwitch, NgSwitchCase, NgTemplateOutlet, NgIf } from '@angular/common'; class PlatformConfigurationFormProviderService { constructor(c8yDatePipe) { this.c8yDatePipe = c8yDatePipe; this.lineBreakHint = gettext('Use [Enter] or <br> tag to add a new line'); this.exampleTomorrowDate = (() => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); return this.c8yDatePipe.transform(tomorrow, 'yyyy-MM-ddTHH:mm:ssZ'); })(); this.platformConfigurationFormDefinitions = { 'system.password.enforce.strength': { formId: 'system.password.enforce.strength', title: gettext('Enforce "green" passwords for all users'), type: 'boolean', control: new FormControl('') }, 'system.password.limit.validity': { formId: 'system.password.limit.validity', title: gettext('Password validity limit (days)'), description: gettext('The number of days a password may be valid before it must be reset; minimum value is 0, maximum value is 999999. Leave empty to use the value from the tenant options.'), type: 'number', control: new FormControl('', [Validators.min(0), Validators.max(999999)]) }, 'system.password.history.size': { formId: 'system.password.history.size', title: gettext('Password history size'), description: gettext('The number of times before the current password can be reused. Minimum value is 0, preset value is 10.'), type: 'number', placeholder: `${gettext('e.g. {{ example }}')}`, placeholderParams: { example: '10' }, control: new FormControl('', [Validators.min(0)]) }, 'system.password.green.min-length': { formId: 'system.password.green.min-length', title: gettext('Minimal length of "green" password'), description: gettext('The minimum number of characters which are required for a safe password. Minimum (and preset) value is 8, maximum value is 32. Leave empty to skip this constraint.'), type: 'number', control: new FormControl('', [Validators.min(8), Validators.max(32)]) }, 'ui.email.protocolAndEncryption': { formId: 'ui.email.protocolAndEncryption', title: gettext('Protocol and encryption'), type: 'select', options: [ { value: 'SMTP_PLAIN', name: gettext('SMTP (no encryption)') }, { value: 'SMTP_ENCRYPTED', name: gettext('SMTP (STARTTLS)') }, { value: 'SMTPS_ENCRYPTED', name: gettext('SMTPS (SSL/TLS)') } ], skipOnSave: true, control: new FormControl('') }, 'email.protocol': { formId: 'email.protocol', title: gettext('Protocol'), type: 'select', options: [ { value: 'smtp', name: 'SMTP' }, { value: 'smtps', name: 'SMTPS' } ], control: new FormControl('') }, 'email.connection.encrypted': { formId: 'email.connection.encrypted', title: gettext('Connection encrypted'), type: 'boolean', control: new FormControl('') }, 'email.host': { formId: 'email.host', title: gettext('Host'), type: 'string', placeholder: `${gettext('e.g. {{ example }}')}`, placeholderParams: { example: 'localhost' }, control: new FormControl('') }, 'email.port': { formId: 'email.port', title: gettext('Port'), type: 'number', placeholder: `${gettext('e.g. {{ example }}')}`, placeholderParams: { example: '25' }, control: new FormControl('', [Validators.min(1), Validators.max(65535)]) }, 'email.username': { formId: 'email.username', title: gettext('Username'), type: 'string', control: new FormControl('') }, 'credentials.email.password': { formId: 'credentials.email.password', title: gettext('Password'), type: 'password', control: new FormControl('') }, 'email.from': { formId: 'email.from', title: gettext('Sender address'), type: 'string', control: new FormControl('', [Validators.email]) }, 'passwordReset.sendNotificationToUnknownEmails': { formId: 'passwordReset.sendNotificationToUnknownEmails', title: gettext('Send notifications to unknown email addresses'), type: 'boolean', control: new FormControl('') }, 'passwordReset.email.subject': { formId: 'passwordReset.email.subject', title: gettext('Email subject'), description: gettext('Subject used for all password reset related emails'), type: 'string', control: new FormControl('') }, 'passwordReset.token.email.template': { formId: 'passwordReset.token.email.template', title: gettext('Password reset email template (when address is known)'), description: `${gettext('Placeholders: {tenant-domain}, {host}, {token}, {username}, {email}. Whole link to reset password can be, for example: {tenant-domain}/apps/devicemanagement/index.html?token={token}&email={email}')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'passwordReset.user.not.found.email.template': { formId: 'passwordReset.user.not.found.email.template', title: gettext('Password reset email template (when address is not known)'), type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'passwordReset.success.email.template': { formId: 'passwordReset.success.email.template', title: gettext('Password change confirmation email template'), description: `${gettext('Placeholders: {host}, {tenant-domain}, {username}')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'passwordReset.invite.template': { formId: 'passwordReset.invite.template', title: gettext('Invitation email template'), description: `${gettext('Placeholders: {tenant-domain}, {host}, {token}, {username}, {email}. Whole link to setup password can be, for example: {tenant-domain}/apps/devicemanagement/index.html?token={token}')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'export.data.mail.subject': { formId: 'export.data.mail.subject', title: gettext('Email subject'), description: gettext('Placeholders: {tenant-domain}, {host}, {binaryId}. Whole link to result file is: {tenant-domain}/inventory/binaries/{binaryId}'), type: 'string', control: new FormControl('') }, 'export.data.mail.text': { formId: 'export.data.mail.text', title: gettext('Email template'), description: `${gettext('Placeholders: {tenant-domain}, {host}, {binaryId}. Whole link to result file is: {tenant-domain}/inventory/binaries/{binaryId}')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'export.data.mail.text.userunauthorized': { formId: 'export.data.mail.text.userunauthorized', title: gettext('User unauthorized error message'), description: gettext('Placeholders: {user}, {exportApi}'), type: 'string', control: new FormControl('') }, 'two-factor-authentication.token.sms.template': { formId: 'two-factor-authentication.token.sms.template', title: gettext('Verification token SMS template'), description: gettext('Placeholder: {token} - created token'), type: 'string', placeholder: gettext('e.g.: Verification code: {token}'), control: new FormControl('') }, 'system.support.url': { formId: 'system.support.url', title: gettext('URL'), type: 'string', description: gettext('Possible values: URL string, "false`KEEP_ORIGINAL`" (hides the link) or leave empty (uses the default). Applications can override this setting by defining "supportUrl`KEEP_ORIGINAL`" application option.'), control: new FormControl('') }, 'storageLimit.warning.email.subject': { formId: 'storageLimit.warning.email.subject', title: gettext('Warning email subject'), description: gettext('Email which will be sent one day before data is deleted'), type: 'string', control: new FormControl('') }, 'storageLimit.warning.email.template': { formId: 'storageLimit.warning.email.template', title: gettext('Warning email template'), description: `${gettext('Email which will be sent one day before data is deleted. Placeholders: {tenant-domain}, {tenant}, {size} - storage usage in %')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'storageLimit.process.email.subject': { formId: 'storageLimit.process.email.subject', title: gettext('Limit exceeded email subject'), description: gettext('Email which will be sent after over-limit data has been deleted'), type: 'string', control: new FormControl('') }, 'storageLimit.process.email.template': { formId: 'storageLimit.process.email.template', title: gettext('Limit exceeded email template'), description: `${gettext('Email which will be sent after over-limit data has been deleted. Placeholders: {tenant-domain}, {tenant}, {size} - storage usage in %')}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'tenantSuspend.mail.sendtosuspended': { formId: 'tenantSuspend.mail.sendtosuspended', title: gettext("Send email to suspended tenant's administrator"), type: 'boolean', control: new FormControl('') }, 'tenantSuspend.mail.additional.address': { formId: 'tenantSuspend.mail.additional.address', title: gettext('Tenant suspended email additional receiver'), type: 'string', control: new FormControl('', [Validators.email]) }, 'tenantSuspend.mail.subject': { formId: 'tenantSuspend.mail.subject', title: gettext('Tenant suspended email subject'), description: gettext("Placeholder: {tenant} - suspended tenant's ID; {tenant-domain} - tenant's domain"), type: 'string', control: new FormControl('') }, 'tenantSuspend.mail.text': { formId: 'tenantSuspend.mail.text', title: gettext('Tenant suspended email template'), description: `${gettext("Placeholder: {tenant} - suspended tenant's ID; {tenant-domain} - tenant's domain")}`, type: 'textarea', control: new FormControl(''), lineBreakHint: true }, 'system.support-user.enabled': { formId: 'system.support-user.enabled', title: gettext('Activate support user'), description: gettext('Possible values: "true`KEEP_ORIGINAL`", "false`KEEP_ORIGINAL`", or a specific date until the user should remain active, for example, "{{ exampleDate }}". Leaving it blank, will set the value to "true`KEEP_ORIGINAL`".'), descriptionTranslateParams: { exampleDate: this.exampleTomorrowDate }, type: 'string', control: new FormControl(''), placeholder: this.exampleTomorrowDate }, 'system.support-user.validity-limit': { formId: 'system.support-user.validity-limit', title: gettext('Validity limit'), description: gettext('Each support user request from subtenant user will prolong support user access by the given number of hours (default: 24 hours). Leaving it blank, will set the value to "24".'), type: 'number', placeholder: `${gettext('e.g. {{ example }}')}`, placeholderParams: { example: '24' }, control: new FormControl('', [Validators.min(0)]) } }; this.optionsGroups = [ { title: gettext('Passwords'), id: 'passwordsOptions', items: [ this.platformConfigurationFormDefinitions['system.password.enforce.strength'], this.platformConfigurationFormDefinitions['system.password.limit.validity'], this.platformConfigurationFormDefinitions['system.password.history.size'], this.platformConfigurationFormDefinitions['system.password.green.min-length'] ] }, { title: gettext('Two-factor authentication'), id: 'twoFactorAuthenticationOptions', items: [ this.platformConfigurationFormDefinitions['two-factor-authentication.token.sms.template'] ] }, { title: gettext('Support link'), id: 'supportLinkOptions', items: [this.platformConfigurationFormDefinitions['system.support.url']] }, { title: gettext('Password reset'), id: 'passwordResetOptions', items: [ this.platformConfigurationFormDefinitions['passwordReset.sendNotificationToUnknownEmails'], this.platformConfigurationFormDefinitions['passwordReset.token.email.template'], this.platformConfigurationFormDefinitions['passwordReset.user.not.found.email.template'], this.platformConfigurationFormDefinitions['passwordReset.email.subject'], this.platformConfigurationFormDefinitions['passwordReset.success.email.template'], this.platformConfigurationFormDefinitions['passwordReset.invite.template'] ] }, { title: gettext('Support user'), id: 'supportUserOptions', items: [ this.platformConfigurationFormDefinitions['system.support-user.enabled'], this.platformConfigurationFormDefinitions['system.support-user.validity-limit'] ] }, { title: gettext('Email server'), id: 'emailServerOptions', items: [ this.platformConfigurationFormDefinitions['ui.email.protocolAndEncryption'], this.platformConfigurationFormDefinitions['email.host'], this.platformConfigurationFormDefinitions['email.port'], this.platformConfigurationFormDefinitions['email.username'], this.platformConfigurationFormDefinitions['credentials.email.password'], this.platformConfigurationFormDefinitions['email.from'] ] }, { title: gettext('Data export'), id: 'dataExportOptions', items: [ this.platformConfigurationFormDefinitions['export.data.mail.subject'], this.platformConfigurationFormDefinitions['export.data.mail.text'], this.platformConfigurationFormDefinitions['export.data.mail.text.userunauthorized'] ] }, { title: gettext('Storage limit'), id: 'storageLimitOptions', items: [ this.platformConfigurationFormDefinitions['storageLimit.warning.email.subject'], this.platformConfigurationFormDefinitions['storageLimit.warning.email.template'], this.platformConfigurationFormDefinitions['storageLimit.process.email.subject'], this.platformConfigurationFormDefinitions['storageLimit.process.email.template'] ] }, { title: gettext('Suspending tenants'), id: 'suspendingTenantsOptions', items: [ this.platformConfigurationFormDefinitions['tenantSuspend.mail.sendtosuspended'], this.platformConfigurationFormDefinitions['tenantSuspend.mail.additional.address'], this.platformConfigurationFormDefinitions['tenantSuspend.mail.subject'], this.platformConfigurationFormDefinitions['tenantSuspend.mail.text'] ] } ]; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationFormProviderService, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationFormProviderService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationFormProviderService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.DatePipe }] }); class PlatformConfigurationFormComponent { set _optionsGroups(groupIds) { if (groupIds === undefined) { return; } this.optionsGroups = groupIds.map(groupId => this.formProviderService.optionsGroups.find(option => option.id === groupId)); } set readOnly(disabled) { disabled ? this.form.disable() : this.form.enable(); } set formValue(value) { if (value) { const convertedValue = this.afterLoad(value); this.form.patchValue(convertedValue, { emitEvent: false }); this.form.markAsUntouched(); this.form.markAsPristine(); } } constructor(formProviderService) { this.formProviderService = formProviderService; this.optionsGroups = []; this.onSave = new EventEmitter(); this.form = new FormGroup({}); this.lineBreakHint = this.formProviderService.lineBreakHint; Object.keys(formProviderService.platformConfigurationFormDefinitions).forEach(fieldId => { this.form.addControl(fieldId, formProviderService.platformConfigurationFormDefinitions[fieldId].control); }); } /** * Parses provided object's property values * @param options */ parseConfiguration(options) { const definitions = this.formProviderService.platformConfigurationFormDefinitions; Object.entries(options).forEach(([key, rawValue]) => { if (definitions[key] && (definitions[key].type === 'number' || definitions[key].type === 'boolean')) { try { options[key] = JSON.parse(rawValue); } catch { options[key] = rawValue; } } }); } /** * Parses incoming raw object before it is applied to FormGroup. */ afterLoad(options) { this.parseConfiguration(options); delete options['ui.email.protocolAndEncryption']; const emailProtocol = options['email.protocol']; const connectionEncrypted = options['email.connection.encrypted'] || false; if (emailProtocol === 'smtp') { if (connectionEncrypted) { options['ui.email.protocolAndEncryption'] = 'SMTP_ENCRYPTED'; } else { options['ui.email.protocolAndEncryption'] = 'SMTP_PLAIN'; } } else if (emailProtocol === 'smtps') { options['ui.email.protocolAndEncryption'] = 'SMTPS_ENCRYPTED'; } else { options['ui.email.protocolAndEncryption'] = undefined; } return options; } /** * Translates ui.email.protocolAndEncryption field into * separate email.protocol and email.connection.encrypted */ beforeSave(value) { const protocolAndEncryption = value['ui.email.protocolAndEncryption']; if (protocolAndEncryption) { //email.protocol const protocol = protocolAndEncryption.match(/^(.+?)_(.+?)$/)[1]; value['email.protocol'] = protocol ? protocol.toLowerCase() : protocol; // email.connection.encrypted const encryption = protocolAndEncryption.match(/^(.+?)_(.+?)$/)[2]; value['email.connection.encrypted'] = encryption === 'ENCRYPTED'; delete value['ui.email.protocolAndEncryption']; } return value; } getDirtyValues() { const dirtyValues = {}; Object.keys(this.form.controls).forEach(key => { const currentControl = this.form.controls[key]; if (currentControl.dirty) { dirtyValues[key] = currentControl.value; } }); return dirtyValues; } emitForm() { if (this.form.valid) { const changedValues = this.getDirtyValues(); const convertedValue = this.beforeSave(changedValues); this.onSave.emit(convertedValue); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationFormComponent, deps: [{ token: PlatformConfigurationFormProviderService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: PlatformConfigurationFormComponent, isStandalone: true, selector: "c8y-platform-configuration-form", inputs: { _optionsGroups: ["optionsGroups", "_optionsGroups"], readOnly: "readOnly", formValue: "formValue" }, outputs: { onSave: "onSave" }, ngImport: i0, template: "<form [formGroup]=\"form\">\n <div class=\"row\">\n <div class=\"col-lg-12 col-lg-max\">\n <div class=\"card card--fullpage\">\n <div class=\"card-header separator\">\n <div class=\"card-title\">\n {{ 'Configuration' | translate }}\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-block\">\n <div>\n <fieldset\n class=\"row schema-form-fieldset separator-bottom p-t-24\"\n *ngFor=\"let category of optionsGroups\"\n >\n <div class=\"col-sm-3 col-md-2 p-l-24 p-l-xs-8 p-b-8\">\n <div\n class=\"h4 text-normal text-right text-left-xs\"\n data-cy=\"fieldset--section-title\"\n >\n {{ category.title | translate }}\n </div>\n </div>\n <div class=\"col-sm-9 col-md-8\">\n <div\n class=\"form-group\"\n *ngFor=\"let field of category.items\"\n >\n <ng-container [ngSwitch]=\"field.type\">\n <ng-container *ngSwitchCase=\"'string'\">\n <ng-container\n *ngTemplateOutlet=\"stringTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'password'\">\n <ng-container\n *ngTemplateOutlet=\"passwordTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'textarea'\">\n <ng-container\n *ngTemplateOutlet=\"textareaTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <ng-container\n *ngTemplateOutlet=\"booleanTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </fieldset>\n </div>\n </div>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-primary\"\n [title]=\"'Save configuration' | translate\"\n type=\"submit\"\n (click)=\"emitForm()\"\n [disabled]=\"!form.dirty || form.invalid || form.disabled\"\n >\n <span translate>Save</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <ng-template\n #stringTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"text\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #passwordTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"password\"\n autocomplete=\"new-password\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"number\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #textareaTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <textarea\n class=\"form-control\"\n [title]=\"field.title | translate\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n [rows]=\"10\"\n ></textarea>\n <div\n class=\"help-block\"\n *ngIf=\"field.description || field.lineBreakHint\"\n >\n <span *ngIf=\"field.description\">\n {{ field.description | translate : field.descriptionTranslateParams }}\n </span>\n <span *ngIf=\"field.description && field.lineBreakHint\"><br /></span>\n <span *ngIf=\"field.lineBreakHint\">{{ lineBreakHint | translate }}</span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #booleanTemplate\n let-field\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n title=\"{{ field.title | translate }}\"\n >\n <input\n [title]=\"field.title | translate\"\n type=\"checkbox\"\n [formControlName]=\"field.formId\"\n />\n <span></span>\n <span>{{ field.title | translate }}</span>\n </label>\n\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #selectTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n <span>{{ field.title | translate }}</span>\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n >\n <option></option>\n <option\n *ngFor=\"let option of field.options\"\n [value]=\"option.value\"\n >\n {{ option.name | translate }}\n </option>\n </select>\n <span></span>\n </div>\n\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationFormComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-platform-configuration-form', imports: [ FormsModule, ReactiveFormsModule, NgFor, NgSwitch, NgSwitchCase, NgTemplateOutlet, C8yTranslateDirective, FormGroupComponent, RequiredInputPlaceholderDirective, NgIf, C8yTranslatePipe ], template: "<form [formGroup]=\"form\">\n <div class=\"row\">\n <div class=\"col-lg-12 col-lg-max\">\n <div class=\"card card--fullpage\">\n <div class=\"card-header separator\">\n <div class=\"card-title\">\n {{ 'Configuration' | translate }}\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-block\">\n <div>\n <fieldset\n class=\"row schema-form-fieldset separator-bottom p-t-24\"\n *ngFor=\"let category of optionsGroups\"\n >\n <div class=\"col-sm-3 col-md-2 p-l-24 p-l-xs-8 p-b-8\">\n <div\n class=\"h4 text-normal text-right text-left-xs\"\n data-cy=\"fieldset--section-title\"\n >\n {{ category.title | translate }}\n </div>\n </div>\n <div class=\"col-sm-9 col-md-8\">\n <div\n class=\"form-group\"\n *ngFor=\"let field of category.items\"\n >\n <ng-container [ngSwitch]=\"field.type\">\n <ng-container *ngSwitchCase=\"'string'\">\n <ng-container\n *ngTemplateOutlet=\"stringTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'password'\">\n <ng-container\n *ngTemplateOutlet=\"passwordTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'textarea'\">\n <ng-container\n *ngTemplateOutlet=\"textareaTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <ng-container\n *ngTemplateOutlet=\"booleanTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectTemplate; context: { $implicit: field }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </fieldset>\n </div>\n </div>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-primary\"\n [title]=\"'Save configuration' | translate\"\n type=\"submit\"\n (click)=\"emitForm()\"\n [disabled]=\"!form.dirty || form.invalid || form.disabled\"\n >\n <span translate>Save</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <ng-template\n #stringTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"text\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #passwordTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"password\"\n autocomplete=\"new-password\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <input\n class=\"text-truncate form-control\"\n [title]=\"field.title | translate\"\n type=\"number\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n />\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #textareaTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n {{ field.title | translate }}\n </label>\n <textarea\n class=\"form-control\"\n [title]=\"field.title | translate\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n [placeholder]=\"field.placeholder || '' | translate : field.placeholderParams\"\n [rows]=\"10\"\n ></textarea>\n <div\n class=\"help-block\"\n *ngIf=\"field.description || field.lineBreakHint\"\n >\n <span *ngIf=\"field.description\">\n {{ field.description | translate : field.descriptionTranslateParams }}\n </span>\n <span *ngIf=\"field.description && field.lineBreakHint\"><br /></span>\n <span *ngIf=\"field.lineBreakHint\">{{ lineBreakHint | translate }}</span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #booleanTemplate\n let-field\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n title=\"{{ field.title | translate }}\"\n >\n <input\n [title]=\"field.title | translate\"\n type=\"checkbox\"\n [formControlName]=\"field.formId\"\n />\n <span></span>\n <span>{{ field.title | translate }}</span>\n </label>\n\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #selectTemplate\n let-field\n >\n <c8y-form-group>\n <label\n title=\"{{ field.title | translate }}\"\n [for]=\"field.formId\"\n >\n <span>{{ field.title | translate }}</span>\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [id]=\"field.formId\"\n [formControlName]=\"field.formId\"\n >\n <option></option>\n <option\n *ngFor=\"let option of field.options\"\n [value]=\"option.value\"\n >\n {{ option.name | translate }}\n </option>\n </select>\n <span></span>\n </div>\n\n <div\n class=\"help-block\"\n *ngIf=\"field.description\"\n >\n {{ field.description | translate : field.descriptionTranslateParams }}\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n" }] }], ctorParameters: () => [{ type: PlatformConfigurationFormProviderService }], propDecorators: { _optionsGroups: [{ type: Input, args: ['optionsGroups'] }], readOnly: [{ type: Input }], formValue: [{ type: Input }], onSave: [{ type: Output }] } }); class PlatformConfigurationModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationModule, imports: [CommonModule, FormsModule$1, ReactiveFormsModule, PlatformConfigurationFormComponent], exports: [PlatformConfigurationFormComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationModule, imports: [CommonModule, FormsModule$1, ReactiveFormsModule, PlatformConfigurationFormComponent] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PlatformConfigurationModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, FormsModule$1, ReactiveFormsModule, PlatformConfigurationFormComponent], exports: [PlatformConfigurationFormComponent] }] }] }); /** * Generated bundle index. Do not edit. */ export { PlatformConfigurationFormComponent, PlatformConfigurationModule }; //# sourceMappingURL=c8y-ngx-components-platform-configuration.mjs.map