File
Implements
Metadata
selector |
cd-configuration-form |
styleUrls |
./configuration-form.component.scss |
templateUrl |
./configuration-form.component.html |
Methods
createRequest
|
createRequest()
|
|
|
getStep
|
getStep(type: string, value: number)
|
|
Returns : number | undefined
|
getValidators
|
getValidators(configOption: any)
|
|
Parameters :
Name |
Type |
Optional |
configOption |
any
|
No
|
Returns : ValidatorFn[]
|
availSections
|
Type : []
|
Default value : ['global', 'mon', 'mgr', 'osd', 'mds', 'client']
|
|
humanReadableType
|
Type : string
|
|
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, ValidatorFn } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { I18n } from '@ngx-translate/i18n-polyfill';
import * as _ from 'lodash';
import { ConfigurationService } from '../../../../shared/api/configuration.service';
import { NotificationType } from '../../../../shared/enum/notification-type.enum';
import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
import { NotificationService } from '../../../../shared/services/notification.service';
import { ConfigFormCreateRequestModel } from './configuration-form-create-request.model';
import { ConfigFormModel } from './configuration-form.model';
import { ConfigOptionTypes } from './configuration-form.types';
@Component({
selector: 'cd-configuration-form',
templateUrl: './configuration-form.component.html',
styleUrls: ['./configuration-form.component.scss']
})
export class ConfigurationFormComponent implements OnInit {
configForm: CdFormGroup;
response: ConfigFormModel;
type: string;
inputType: string;
humanReadableType: string;
minValue: number;
maxValue: number;
patternHelpText: string;
availSections = ['global', 'mon', 'mgr', 'osd', 'mds', 'client'];
constructor(
private route: ActivatedRoute,
private router: Router,
private configService: ConfigurationService,
private notificationService: NotificationService,
private i18n: I18n
) {
this.createForm();
}
createForm() {
const formControls = {
name: new FormControl({ value: null }),
desc: new FormControl({ value: null }),
long_desc: new FormControl({ value: null }),
values: new FormGroup({}),
default: new FormControl({ value: null }),
daemon_default: new FormControl({ value: null }),
services: new FormControl([])
};
this.availSections.forEach((section) => {
formControls.values.addControl(section, new FormControl(null));
});
this.configForm = new CdFormGroup(formControls);
}
ngOnInit() {
this.route.params.subscribe((params: { name: string }) => {
const configName = params.name;
this.configService.get(configName).subscribe((resp: ConfigFormModel) => {
this.setResponse(resp);
});
});
}
getValidators(configOption: any): ValidatorFn[] {
const typeValidators = ConfigOptionTypes.getTypeValidators(configOption);
if (typeValidators) {
this.patternHelpText = typeValidators.patternHelpText;
if ('max' in typeValidators && typeValidators.max !== '') {
this.maxValue = typeValidators.max;
}
if ('min' in typeValidators && typeValidators.min !== '') {
this.minValue = typeValidators.min;
}
return typeValidators.validators;
}
}
getStep(type: string, value: number): number | undefined {
const numberTypes = ['uint', 'int', 'size', 'secs'];
if (numberTypes.includes(type)) {
return 1;
}
if (type === 'float') {
if (value !== null) {
const stringVal = value.toString();
if (stringVal.indexOf('.') !== -1) {
// Value type float and contains decimal characters
const decimal = value.toString().split('.');
return Math.pow(10, -decimal[1].length);
}
}
return 0.1;
}
return undefined;
}
setResponse(response: ConfigFormModel) {
this.response = response;
const validators = this.getValidators(response);
this.configForm.get('name').setValue(response.name);
this.configForm.get('desc').setValue(response.desc);
this.configForm.get('long_desc').setValue(response.long_desc);
this.configForm.get('default').setValue(response.default);
this.configForm.get('daemon_default').setValue(response.daemon_default);
this.configForm.get('services').setValue(response.services);
if (this.response.value) {
this.response.value.forEach((value) => {
// Check value type. If it's a boolean value we need to convert it because otherwise we
// would use the string representation. That would cause issues for e.g. checkboxes.
let sectionValue = null;
if (value.value === 'true') {
sectionValue = true;
} else if (value.value === 'false') {
sectionValue = false;
} else {
sectionValue = value.value;
}
this.configForm
.get('values')
.get(value.section)
.setValue(sectionValue);
});
}
this.availSections.forEach((section) => {
this.configForm
.get('values')
.get(section)
.setValidators(validators);
});
const currentType = ConfigOptionTypes.getType(response.type);
this.type = currentType.name;
this.inputType = currentType.inputType;
this.humanReadableType = currentType.humanReadable;
}
createRequest(): ConfigFormCreateRequestModel | null {
const values = [];
this.availSections.forEach((section) => {
const sectionValue = this.configForm.getValue(section);
if (sectionValue) {
values.push({ section: section, value: sectionValue });
}
});
if (!_.isEqual(this.response.value, values)) {
const request = new ConfigFormCreateRequestModel();
request.name = this.configForm.getValue('name');
request.value = values;
return request;
}
return null;
}
submit() {
const request = this.createRequest();
if (request) {
this.configService.create(request).subscribe(
() => {
this.notificationService.show(
NotificationType.success,
this.i18n('Updated config option {{name}}', { name: request.name })
);
this.router.navigate(['/configuration']);
},
() => {
this.configForm.setErrors({ cdSubmitButton: true });
}
);
}
this.router.navigate(['/configuration']);
}
}
<div class="col-sm-12 col-lg-6">
<form name="configForm"
class="form-horizontal"
#formDir="ngForm"
[formGroup]="configForm"
novalidate>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<ng-container i18n>Edit</ng-container> {{ configForm.getValue('name') }}
</h3>
</div>
<div class="panel-body">
<!-- Name -->
<div class="form-group">
<label i18n
class="control-label col-sm-3">Name</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
id="name"
formControlName="name"
readonly>
</div>
</div>
<!-- Description -->
<div class="form-group"
*ngIf="configForm.getValue('desc')">
<label i18n
class="control-label col-sm-3">Description</label>
<div class="col-sm-9">
<textarea class="form-control resize-vertical"
id="desc"
formControlName="desc"
readonly>
</textarea>
</div>
</div>
<!-- Long description -->
<div class="form-group"
*ngIf="configForm.getValue('long_desc')">
<label i18n
class="control-label col-sm-3">Long description</label>
<div class="col-sm-9">
<textarea class="form-control resize-vertical"
id="long_desc"
formControlName="long_desc"
readonly>
</textarea>
</div>
</div>
<!-- Default -->
<div class="form-group"
*ngIf="configForm.getValue('default') !== ''">
<label i18n
class="control-label col-sm-3">Default</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
id="default"
formControlName="default"
readonly>
</div>
</div>
<!-- Daemon default -->
<div class="form-group"
*ngIf="configForm.getValue('daemon_default') !== ''">
<label i18n
class="control-label col-sm-3">Daemon default</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
id="daemon_default"
formControlName="daemon_default"
readonly>
</div>
</div>
<!-- Services -->
<div class="form-group"
*ngIf="configForm.getValue('services').length > 0">
<label i18n
class="control-label col-sm-3">Services</label>
<div class="col-sm-9">
<span *ngFor="let service of configForm.getValue('services')"
class="form-component-badge">
<span class="badge badge-pill badge-primary">{{ service }}</span>
</span>
</div>
</div>
<!-- Values -->
<div class="col-sm-12"
formGroupName="values">
<h2 i18n
class="page-header">Values</h2>
<div class="row"
*ngFor="let section of availSections">
<div class="form-group"
*ngIf="type === 'bool'">
<div class="col-sm-offset-3 col-sm-9">
<div class="checkbox checkbox-primary">
<input [id]="section"
type="checkbox"
[formControlName]="section">
<label [for]="section">{{ section }}
</label>
</div>
</div>
</div>
<div class="form-group"
[ngClass]="{'has-error': configForm.showError(section, formDir)}"
*ngIf="type !== 'bool'">
<label class="control-label col-sm-3"
[for]="section">{{ section }}
</label>
<div class="col-sm-9">
<input class="form-control"
[type]="inputType"
[id]="section"
[placeholder]="humanReadableType"
[formControlName]="section"
[step]="getStep(type, this.configForm.getValue(section))">
<span class="help-block"
*ngIf="configForm.showError(section, formDir, 'pattern')">
{{ patternHelpText }}
</span>
<span class="help-block"
*ngIf="configForm.showError(section, formDir, 'invalidUuid')">
{{ patternHelpText }}
</span>
<span class="help-block"
*ngIf="configForm.showError(section, formDir, 'max')"
i18n>The entered value is too high! It must not be greater than {{ maxValue }}.</span>
<span class="help-block"
*ngIf="configForm.showError(section, formDir, 'min')"
i18n>The entered value is too low! It must not be lower than {{ minValue }}.</span>
</div>
</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="panel-footer">
<div class="button-group text-right">
<cd-submit-button [form]="formDir"
type="button"
(submitAction)="submit()">
<span i18n>Save</span>
</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
</div>
</form>
</div>
.form-component-badge {
height: 34px;
display: block;
span {
margin-top: 7px;
}
}
.resize-vertical {
resize: vertical;
}
Legend
Html element with directive