refactor tenant, notification-template ui editors
This commit is contained in:
parent
46862e06cc
commit
5da3c4f9b9
|
@ -0,0 +1,92 @@
|
|||
<div class="col-6" >
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="form.get('mandatory')">
|
||||
<mat-chip-row *ngFor="let field of mandatoryFields"
|
||||
(removed)="removeChipListValues(field)"
|
||||
[editable]="true"
|
||||
(edited)="editChipListValues($event, field)">
|
||||
{{field}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addChipListValues($event)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="form.get('mandatory').hasError('backendError')">{{form.get('mandatory').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.OPTIONAL-TITLE' | translate}}</h4>
|
||||
<div class="col-12">
|
||||
<div class="row" *ngFor="let options of form.get('optional')['controls']; let i = index">
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [formControl]="options.get('key')">
|
||||
<mat-error *ngIf="options.get('key').hasError('backendError')">{{options.get('key').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="options.get('key').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.DATA-TYPE' | translate}}</mat-label>
|
||||
<mat-select name="channel" [formControl]="options.get('type')">
|
||||
<mat-option *ngFor="let type of notificationDataTypeEnum" [value]="type">
|
||||
{{enumUtils.toNotificationTemplateDataTypeString(type)}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="options.get('type').hasError('backendError')">{{options.get('type').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="options.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [formControl]="options.get('value')">
|
||||
<mat-error *ngIf="options.get('value').hasError('backendError')">{{options.get('value').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="options.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="removeSubjectOptionalItem(i)" [disabled]="form.disabled">
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="addOptionalItem()" [disabled]="form.disabled">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.FORMATTING' | translate}}</h4>
|
||||
<div class="row" *ngFor="let item of form.get('mandatory').value; let i = index">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value] ="formatting[item]" (change)="formattingValueChange($event, item)">
|
||||
<mat-error *ngIf="form.get('formatting').hasError('backendError')">{{form.get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row" *ngFor="let item of form.get('optional')['controls']; let i = index">
|
||||
<div *ngIf="item.valid">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item.value.key" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value]="formatting[item]" (change)="formattingValueChange($event, item)">
|
||||
<mat-error *ngIf="form.get('formatting').hasError('backendError')">{{form.get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,127 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { UntypedFormArray } from '@angular/forms';
|
||||
import { NotificationDataType } from '@app/core/common/enum/notification-data-type';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { NotificationFieldInfoEditorModel, NotificationFieldOptionsEditorModel } from '../notification-template-editor.model';
|
||||
import { MatChipEditedEvent, MatChipInputEvent } from '@angular/material/chips';
|
||||
import { COMMA, ENTER } from '@angular/cdk/keycodes';
|
||||
|
||||
@Component({
|
||||
selector: 'app-notification-template-field-options-component',
|
||||
templateUrl: 'notification-template-field-options.component.html',
|
||||
styleUrls: ['./notification-template-field-options.component.scss']
|
||||
})
|
||||
export class NotificationTemplateFieldOptionsComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Input() form;
|
||||
@Input() validationErrorModel: ValidationErrorModel = null;
|
||||
@Input() validationRootPath: string = null;
|
||||
@Input() mandatoryFields: string[] = [];
|
||||
@Input() formatting: { [key: string]: string } = {};
|
||||
|
||||
public notificationDataTypeEnum = this.enumUtils.getEnumValues(NotificationDataType);
|
||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
|
||||
constructor(
|
||||
public enumUtils: EnumUtils,
|
||||
) { super(); }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
addChipListValues(event: MatChipInputEvent){
|
||||
this.mandatoryFields = this.add(event, this.mandatoryFields);
|
||||
}
|
||||
|
||||
editChipListValues(event: MatChipEditedEvent, field: string){
|
||||
this.mandatoryFields = this.edit(field, this.mandatoryFields, event);
|
||||
this.editFormmattingKey(field, event.value.trim());
|
||||
}
|
||||
|
||||
removeChipListValues(field: string){
|
||||
this.mandatoryFields = this.remove(field, this.mandatoryFields);
|
||||
this.deleteFormattingItem(field);
|
||||
}
|
||||
|
||||
add(event: MatChipInputEvent, values: string[]) {
|
||||
const value = (event.value || '').trim();
|
||||
|
||||
if (value) values.push(value)
|
||||
event.chipInput!.clear();
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
remove(field: string, values: string[]) {
|
||||
const index = values.indexOf(field);
|
||||
|
||||
if (index >= 0) values.splice(index, 1);
|
||||
return values;
|
||||
}
|
||||
|
||||
edit(field: string, values: string[], event: MatChipEditedEvent) {
|
||||
const value = event.value.trim();
|
||||
|
||||
if (!value) {
|
||||
values = this.remove(field, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
const index = values.indexOf(field);
|
||||
if (index >= 0) values[index] = value
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
//options fields
|
||||
|
||||
addOptionalItem() {
|
||||
const formArray = (this.form.get('optional') as UntypedFormArray);
|
||||
const optional: NotificationFieldInfoEditorModel = new NotificationFieldInfoEditorModel(this.validationErrorModel);
|
||||
|
||||
formArray.push(optional.buildForm({ rootPath: this.validationRootPath + 'optional[' + formArray.length + '].' }));
|
||||
}
|
||||
|
||||
removeSubjectOptionalItem(optionalIndex: number): void {
|
||||
const key = (this.form.get('optional') as UntypedFormArray).at(optionalIndex).get("key").value;
|
||||
this.deleteFormattingItem(key);
|
||||
|
||||
(this.form.get('optional') as UntypedFormArray).removeAt(optionalIndex);
|
||||
|
||||
//Reapply validators
|
||||
NotificationFieldOptionsEditorModel.reapplyValidators(
|
||||
{
|
||||
formGroup: this.form,
|
||||
validationErrorModel: this.validationErrorModel,
|
||||
rootPath: this.validationRootPath
|
||||
}
|
||||
);
|
||||
this.form.get('optional').markAsDirty();
|
||||
}
|
||||
|
||||
// subject formatting
|
||||
insertFormattingItem(key: string, value: string){
|
||||
this.formatting[key] = value;
|
||||
this.form.get('formatting').setValue(this.formatting);
|
||||
}
|
||||
|
||||
formattingValueChange(event: Event, key: string){
|
||||
this.formatting[key] = (event.target as HTMLInputElement).value;
|
||||
this.form.get('formatting').setValue(this.formatting);
|
||||
}
|
||||
|
||||
editFormmattingKey(oldKey: string, newKey: string){
|
||||
this.insertFormattingItem(newKey, this.formatting[oldKey]);
|
||||
this.deleteFormattingItem(oldKey);
|
||||
}
|
||||
|
||||
deleteFormattingItem(key:string){
|
||||
if (key in this.formatting) {
|
||||
delete this.formatting[key];
|
||||
this.form.get('formatting').setValue(this.formatting);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -102,99 +102,14 @@
|
|||
<mat-checkbox [checked]="subjectFieldOptionsEnabled" (change)="subjectFieldOptionsSelectionChanged($event)"></mat-checkbox>
|
||||
</h4>
|
||||
<div *ngIf="subjectFieldOptionsEnabled == true">
|
||||
<div class="col-6" >
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="formGroup.get('value').get('subjectFieldOptions').get('mandatory')">
|
||||
<mat-chip-row *ngFor="let field of subjectMandatoryFields"
|
||||
(removed)="removeChipListValues('subject', field)"
|
||||
[editable]="true"
|
||||
(edited)="editChipListValues('subject', $event, field)">
|
||||
{{field}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addChipListValues('subject', $event)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="formGroup.get('value').get('subjectFieldOptions').get('mandatory').hasError('backendError')">{{formGroup.get('value').get('subjectFieldOptions').get('mandatory').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.OPTIONAL-TITLE' | translate}}</h4>
|
||||
<div class="col-12">
|
||||
<div class="row" *ngFor="let subjectOptions of formGroup.get('value').get('subjectFieldOptions').get('optional')['controls']; let i = index">
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [formControl]="subjectOptions.get('key')">
|
||||
<mat-error *ngIf="subjectOptions.get('key').hasError('backendError')">{{subjectOptions.get('key').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="subjectOptions.get('key').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.DATA-TYPE' | translate}}</mat-label>
|
||||
<mat-select name="channel" [formControl]="subjectOptions.get('type')">
|
||||
<mat-option *ngFor="let type of notificationDataTypeEnum" [value]="type">
|
||||
{{enumUtils.toNotificationTemplateDataTypeString(type)}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="subjectOptions.get('type').hasError('backendError')">{{subjectOptions.get('type').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="subjectOptions.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [formControl]="subjectOptions.get('value')">
|
||||
<mat-error *ngIf="subjectOptions.get('value').hasError('backendError')">{{subjectOptions.get('value').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="subjectOptions.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="removeSubjectOptionalItem(i)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="addSubjectOptionalItem()" [disabled]="formGroup.disabled">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.FORMATTING' | translate}}</h4>
|
||||
<div class="row" *ngFor="let item of formGroup.get('value').get('subjectFieldOptions').get('mandatory').value; let i = index">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value] ="subjectFormatting[item]" (change)="subjectFormattingValueChange($event, item)">
|
||||
<mat-error *ngIf="formGroup.get('value').get('subjectFieldOptions').get('formatting').hasError('backendError')">{{formGroup.get('value').get('subjectFieldOptions').get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row" *ngFor="let item of formGroup.get('value').get('subjectFieldOptions').get('optional')['controls']; let i = index">
|
||||
<div *ngIf="item.valid">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item.value.key" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value]="subjectFormatting[item]" (change)="subjectFormattingValueChange($event, item)">
|
||||
<mat-error *ngIf="formGroup.get('value').get('subjectFieldOptions').get('formatting').hasError('backendError')">{{formGroup.get('value').get('subjectFieldOptions').get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-notification-template-field-options-component
|
||||
[form]="formGroup.get('value').get('subjectFieldOptions')"
|
||||
[validationErrorModel]="editorModel.validationErrorModel"
|
||||
[validationRootPath]="'value.subjectFieldOptions.'"
|
||||
[mandatoryFields]="subjectMandatoryFields"
|
||||
[formatting]="subjectFormatting">
|
||||
</app-notification-template-field-options-component>
|
||||
</div>
|
||||
|
||||
<!-- Body -->
|
||||
<div>
|
||||
|
@ -236,98 +151,13 @@
|
|||
<mat-checkbox [checked]="bodyFieldOptionsEnabled" (change)="bodyFieldOptionsSelectionChanged($event)"></mat-checkbox>
|
||||
</h4>
|
||||
<div *ngIf="bodyFieldOptionsEnabled == true">
|
||||
<div class="col-6" >
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="formGroup.get('value').get('bodyFieldOptions').get('mandatory')">
|
||||
<mat-chip-row *ngFor="let field of bodyMandatoryFields"
|
||||
(removed)="removeChipListValues('body', field)"
|
||||
[editable]="true"
|
||||
(edited)="editChipListValues('body', $event, field)">
|
||||
{{field}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addChipListValues('body',$event)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="formGroup.get('value').get('bodyFieldOptions').get('mandatory').hasError('backendError')">{{formGroup.get('value').get('bodyFieldOptions').get('mandatory').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.OPTIONAL-TITLE' | translate}}</h4>
|
||||
<div class="col-12">
|
||||
<div class="row" *ngFor="let bodyOptions of formGroup.get('value').get('bodyFieldOptions').get('optional')['controls']; let i = index">
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [formControl]="bodyOptions.get('key')">
|
||||
<mat-error *ngIf="bodyOptions.get('key').hasError('backendError')">{{bodyOptions.get('key').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="bodyOptions.get('key').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col-auto">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.DATA-TYPE' | translate}}</mat-label>
|
||||
<mat-select name="channel" [formControl]="bodyOptions.get('type')">
|
||||
<mat-option *ngFor="let type of notificationDataTypeEnum" [value]="type">
|
||||
{{enumUtils.toNotificationTemplateDataTypeString(type)}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="bodyOptions.get('type').hasError('backendError')">{{bodyOptions.get('type').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="bodyOptions.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<mat-form-field class="col">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [formControl]="bodyOptions.get('value')">
|
||||
<mat-error *ngIf="bodyOptions.get('value').hasError('backendError')">{{bodyOptions.get('value').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="bodyOptions.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="removeBodyOptionalItem(i)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="addBodyOptionalItem()" [disabled]="formGroup.disabled">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.FORMATTING' | translate}}</h4>
|
||||
<div class="row" *ngFor="let item of formGroup.get('value').get('bodyFieldOptions').get('mandatory').value; let i = index">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value] ="bodyFormatting[item]" (change)="bodyFormattingValueChange($event, item)">
|
||||
<mat-error *ngIf="formGroup.get('value').get('bodyFieldOptions').get('formatting').hasError('backendError')">{{formGroup.get('value').get('bodyFieldOptions').get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row" *ngFor="let item of formGroup.get('value').get('bodyFieldOptions').get('optional')['controls']; let i = index">
|
||||
<div *ngIf="item.valid">
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}}</mat-label>
|
||||
<input matInput [value]="item.value.key" [disabled] = "true">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}}</mat-label>
|
||||
<input matInput [value]="bodyFormatting[item]" (change)="bodyFormattingValueChange($event, item)">
|
||||
<mat-error *ngIf="formGroup.get('value').get('bodyFieldOptions').get('formatting').hasError('backendError')">{{formGroup.get('value').get('bodyFieldOptions').get('formatting').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-notification-template-field-options-component
|
||||
[form]="formGroup.get('value').get('bodyFieldOptions')"
|
||||
[validationErrorModel]="editorModel.validationErrorModel"
|
||||
[validationRootPath]="'value.bodyFieldOptions.'"
|
||||
[bodyMandatoryFields]="subjectMandatoryFields"
|
||||
[formatting]="bodyFormatting">
|
||||
</app-notification-template-field-options-component>
|
||||
</div>
|
||||
<!--Extra Options -->
|
||||
<div class="row">
|
||||
|
|
|
@ -252,10 +252,6 @@ export class NotificationTemplateEditorComponent extends BaseEditor<Notification
|
|||
this.bccValues = this.add(event, this.bccValues);
|
||||
}else if(type == "extraDataKeys"){
|
||||
this.extraDataKeys = this.add(event, this.extraDataKeys);
|
||||
}else if(type == "subject"){
|
||||
this.subjectMandatoryFields = this.add(event, this.subjectMandatoryFields);
|
||||
}else if(type == "body"){
|
||||
this.bodyMandatoryFields = this.add(event, this.bodyMandatoryFields);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,12 +262,6 @@ export class NotificationTemplateEditorComponent extends BaseEditor<Notification
|
|||
this.bccValues = this.edit(field, this.bccValues, event);
|
||||
}else if(type == "extraDataKeys"){
|
||||
this.extraDataKeys = this.edit(field, this.extraDataKeys, event);
|
||||
}else if(type == "subject"){
|
||||
this.subjectMandatoryFields = this.edit(field, this.subjectMandatoryFields, event);
|
||||
this.editSubjectFormmattingKey(field, event.value.trim());
|
||||
}else if(type == "body"){
|
||||
this.bodyMandatoryFields = this.edit(field, this.bodyMandatoryFields, event);
|
||||
this.editBodyFormmattingKey(field, event.value.trim());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,12 +272,6 @@ export class NotificationTemplateEditorComponent extends BaseEditor<Notification
|
|||
this.bccValues = this.remove(field, this.bccValues);
|
||||
}else if(type == "extraDataKeys"){
|
||||
this.extraDataKeys = this.remove(field, this.extraDataKeys);
|
||||
}else if(type == "subject"){
|
||||
this.subjectMandatoryFields = this.remove(field, this.subjectMandatoryFields);
|
||||
this.deleteSubjectFormattingItem(field);
|
||||
}else if(type == "body"){
|
||||
this.bodyMandatoryFields = this.remove(field, this.bodyMandatoryFields);
|
||||
this.deleteBodyFormattingItem(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,92 +305,4 @@ export class NotificationTemplateEditorComponent extends BaseEditor<Notification
|
|||
return values;
|
||||
}
|
||||
|
||||
//options fields
|
||||
|
||||
addSubjectOptionalItem() {
|
||||
(this.formGroup.get('value').get('subjectFieldOptions').get('optional') as FormArray).push(this.editorModel.createSubjectOptionalField((this.formGroup.get('value').get('subjectFieldOptions').get('optional') as FormArray).length));
|
||||
}
|
||||
|
||||
addBodyOptionalItem() {
|
||||
(this.formGroup.get('value').get('bodyFieldOptions').get('optional') as FormArray).push(this.editorModel.createBodyOptionalField((this.formGroup.get('value').get('bodyFieldOptions').get('optional') as FormArray).length));
|
||||
}
|
||||
|
||||
removeSubjectOptionalItem(optionalIndex: number): void {
|
||||
const key = (this.formGroup.get('value').get('subjectFieldOptions').get('optional') as FormArray).at(optionalIndex).get("key").value;
|
||||
this.deleteSubjectFormattingItem(key);
|
||||
|
||||
(this.formGroup.get('value').get('subjectFieldOptions').get('optional') as FormArray).removeAt(optionalIndex);
|
||||
|
||||
//Reapply validators
|
||||
NotificationTemplateEditorModel.reApplyValueValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
}
|
||||
);
|
||||
this.formGroup.get('value').get('subjectFieldOptions').get('optional').markAsDirty();
|
||||
}
|
||||
removeBodyOptionalItem(optionalIndex: number): void {
|
||||
const key = (this.formGroup.get('value').get('bodyFieldOptions').get('optional') as FormArray).at(optionalIndex).get("key").value;
|
||||
this.deleteBodyFormattingItem(key);
|
||||
|
||||
(this.formGroup.get('value').get('bodyFieldOptions').get('optional') as FormArray).removeAt(optionalIndex);
|
||||
|
||||
//Reapply validators
|
||||
NotificationTemplateEditorModel.reApplyValueValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
}
|
||||
);
|
||||
this.formGroup.get('value').get('bodyFieldOptions').get('optional').markAsDirty();
|
||||
}
|
||||
|
||||
// subject formatting
|
||||
insertSubjectFormattingItem(key: string, value: string){
|
||||
this.subjectFormatting[key] = value;
|
||||
this.formGroup.get('value').get('subjectFieldOptions').get('formatting').setValue(this.subjectFormatting);
|
||||
}
|
||||
|
||||
subjectFormattingValueChange(event: Event, key: string){
|
||||
this.bodyFormatting[key] = (event.target as HTMLInputElement).value;
|
||||
this.formGroup.get('value').get('subjectFieldOptions').get('formatting').setValue(this.bodyFormatting);
|
||||
}
|
||||
|
||||
editSubjectFormmattingKey(oldKey: string, newKey: string){
|
||||
this.insertSubjectFormattingItem(newKey, this.subjectFormatting[oldKey]);
|
||||
this.deleteSubjectFormattingItem(oldKey);
|
||||
}
|
||||
|
||||
deleteSubjectFormattingItem(key:string){
|
||||
if (key in this.subjectFormatting) {
|
||||
delete this.subjectFormatting[key];
|
||||
this.formGroup.get('value').get('subjectFieldOptions').get('formatting').setValue(this.subjectFormatting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// body formatting
|
||||
insertBodyFormattingItem(key: string, value: string){
|
||||
this.bodyFormatting[key] = value;
|
||||
this.formGroup.get('value').get('bodyFieldOptions').get('formatting').setValue(this.bodyFormatting);
|
||||
}
|
||||
|
||||
bodyFormattingValueChange(event: Event, key: string){
|
||||
this.bodyFormatting[key] = (event.target as HTMLInputElement).value;
|
||||
this.formGroup.get('value').get('bodyFieldOptions').get('formatting').setValue(this.bodyFormatting);
|
||||
}
|
||||
|
||||
editBodyFormmattingKey(oldKey: string, newKey: string){
|
||||
this.insertBodyFormattingItem(newKey, this.bodyFormatting[oldKey]);
|
||||
this.deleteBodyFormattingItem(oldKey);
|
||||
}
|
||||
|
||||
deleteBodyFormattingItem(key:string){
|
||||
if (key in this.bodyFormatting) {
|
||||
delete this.bodyFormatting[key];
|
||||
this.formGroup.get('value').get('bodyFieldOptions').get('formatting').setValue(this.bodyFormatting);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,16 +68,6 @@ export class NotificationTemplateEditorModel extends BaseEditorModel implements
|
|||
return baseContext;
|
||||
}
|
||||
|
||||
createSubjectOptionalField(index: number): UntypedFormGroup {
|
||||
const source: NotificationFieldInfoEditorModel = new NotificationFieldInfoEditorModel(this.validationErrorModel);
|
||||
return source.buildForm({ rootPath: 'value.subjectFieldOptions.optional[' + index + '].' });
|
||||
}
|
||||
|
||||
createBodyOptionalField(index: number): UntypedFormGroup {
|
||||
const source: NotificationFieldInfoEditorModel = new NotificationFieldInfoEditorModel(this.validationErrorModel);
|
||||
return source.buildForm({ rootPath: 'value.bodyFieldOptions.optional[' + index + '].' });
|
||||
}
|
||||
|
||||
static reApplyValueValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
|
|
|
@ -16,6 +16,7 @@ import { NotificationTemplateEditorComponent } from './editor/notification-templ
|
|||
import { NotificationTemplateListingFiltersComponent } from './listing/filters/notification-template-listing-filters.component';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { EditorModule } from '@tinymce/tinymce-angular';
|
||||
import { NotificationTemplateFieldOptionsComponent } from './editor/field-options/notification-template-field-options.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -37,7 +38,8 @@ import { EditorModule } from '@tinymce/tinymce-angular';
|
|||
declarations: [
|
||||
NotificationTemplateEditorComponent,
|
||||
NotificationTemplateListingComponent,
|
||||
NotificationTemplateListingFiltersComponent
|
||||
NotificationTemplateListingFiltersComponent,
|
||||
NotificationTemplateFieldOptionsComponent
|
||||
]
|
||||
})
|
||||
export class NotificationTemplateModule { }
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<h3>
|
||||
{{label}}
|
||||
<button mat-button class="action-btn" type="button" (click)="addSource()" [disabled]="form.disabled">{{'TENANT-EDITOR.ACTIONS.ADD-SOURCE' | translate}}</button>
|
||||
</h3>
|
||||
<div *ngFor="let source of form.get('sources').controls; let sourceIndex=index;" class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="row mb-3 d-flex align-items-center">
|
||||
<div class="col-auto d-flex">
|
||||
<mat-card-title>{{'TENANT-EDITOR.FIELDS.SOURCE' | translate}} {{sourceIndex + 1}}</mat-card-title>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'TENANT-EDITOR.ACTIONS.REMOVE-SOURCE' | translate}}" (click)="removeSource(sourceIndex)" [disabled]="form.disabled">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="url" [formControl]="source.get('url')" required>
|
||||
<mat-error *ngIf="source.get('url').hasError('backendError')">{{source.get('url').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('url').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.ISSUER-URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="issuerUrl" [formControl]="source.get('issuerUrl')" required>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('backendError')">{{source.get('issuerUrl').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-ID' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientId" [formControl]="source.get('clientId')" required>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('backendError')">{{source.get('clientId').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-SECRET' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientSecret" [formControl]="source.get('clientSecret')" required>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('backendError')">{{source.get('clientSecret').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.SCOPE' | translate}}</mat-label>
|
||||
<input matInput type="text" name="scope" [formControl]="source.get('scope')" required>
|
||||
<mat-error *ngIf="source.get('scope').hasError('backendError')">{{source.get('scope').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('scope').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CODES' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="source.get('codes')">
|
||||
<mat-chip-row *ngFor="let code of codes.get(sourceIndex)"
|
||||
(removed)="removeCode(code, sourceIndex)"
|
||||
[editable]="true"
|
||||
(edited)="editCode(code, $event, sourceIndex)">
|
||||
{{code}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'TENANT-EDITOR.FIELDS.CODES-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addCode($event, sourceIndex)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="source.get('codes').hasError('backendError')">{{source.get('codes').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('codes').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
.action-btn {
|
||||
border-radius: 30px;
|
||||
background-color: var(--secondary-color);
|
||||
border: 1px solid transparent;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
box-shadow: 0px 3px 6px #1E202029;
|
||||
|
||||
transition-property: background-color, color;
|
||||
transition-duration: 200ms;
|
||||
transition-delay: 50ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
&:disabled{
|
||||
background-color: #CBCBCB;
|
||||
color: #FFF;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { UntypedFormArray } from '@angular/forms';
|
||||
import { MatChipEditedEvent, MatChipInputEvent } from '@angular/material/chips';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { TenantDepositConfigEditorModel, TenantEditorModel, TenantSourceEditorModel } from '../tenant-editor.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tenant-source-component',
|
||||
templateUrl: 'tenant-source.component.html',
|
||||
styleUrls: ['./tenant-source.component.scss']
|
||||
})
|
||||
export class TenantSourceComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Input() form;
|
||||
@Input() validationErrorModel: ValidationErrorModel = null;
|
||||
@Input() validationRootPath: string = null;
|
||||
@Input() codes: Map<number, string[]>;
|
||||
@Input() label: string = null;
|
||||
|
||||
constructor(
|
||||
public enumUtils: EnumUtils,
|
||||
) { super(); }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
//
|
||||
// source
|
||||
//
|
||||
addSource(): void {
|
||||
const formArray = this.form.get('sources') as UntypedFormArray;
|
||||
this.codes.set(formArray.length, []);
|
||||
const source: TenantSourceEditorModel = new TenantSourceEditorModel(this.validationErrorModel);
|
||||
formArray.push(source.buildForm({ rootPath: this.validationRootPath + 'sources[' + formArray.length + '].' }));
|
||||
}
|
||||
|
||||
removeSource(sourceIndex: number): void {
|
||||
this.codes.delete((this.form.get('sources') as UntypedFormArray).length);
|
||||
(this.form.get('sources') as UntypedFormArray).removeAt(sourceIndex);
|
||||
|
||||
// Reapply validators
|
||||
TenantDepositConfigEditorModel.reapplySourcesFieldsValidators(
|
||||
{
|
||||
formArray: this.form.get('sources') as UntypedFormArray,
|
||||
validationErrorModel: this.validationErrorModel,
|
||||
rootPath: this.validationRootPath
|
||||
}
|
||||
)
|
||||
this.form.get('sources').markAsDirty();
|
||||
}
|
||||
|
||||
// source codes
|
||||
|
||||
addCode(event: MatChipInputEvent, key: number): void {
|
||||
const value = (event.value || '').trim();
|
||||
|
||||
if (value){
|
||||
const values = this.codes.get(key);
|
||||
values.push(value);
|
||||
this.codes.set(key, values);
|
||||
}
|
||||
event.chipInput!.clear();
|
||||
}
|
||||
|
||||
removeCode(code: string, key: number): void {
|
||||
const values = this.codes.get(key);
|
||||
if (values){
|
||||
const index = values.indexOf(code);
|
||||
|
||||
if (index >= 0) {
|
||||
values.splice(index, 1);
|
||||
this.codes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editCode(code: string, event: MatChipEditedEvent, key: number) {
|
||||
const values = this.codes.get(key);
|
||||
if (values){
|
||||
const value = event.value.trim();
|
||||
|
||||
// Remove code if it no longer has a value
|
||||
if (!value) {
|
||||
this.removeCode(code, key);
|
||||
return;
|
||||
}
|
||||
|
||||
const index = values.indexOf(code);
|
||||
if (index >= 0) {
|
||||
values[index] = value;
|
||||
this.codes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -57,174 +57,22 @@
|
|||
</div>
|
||||
<!-- Deposit -->
|
||||
<div class="col-12">
|
||||
<h3>
|
||||
{{'TENANT-EDITOR.FIELDS.DEPOSIT' | translate}}
|
||||
<button mat-button class="action-btn" type="button" (click)="addDepositSource()" [disabled]="formGroup.disabled">{{'TENANT-EDITOR.ACTIONS.ADD-SOURCE' | translate}}</button>
|
||||
</h3>
|
||||
<div *ngFor="let source of formGroup.get('config').get('deposit').get('sources').controls; let sourceIndex=index;" class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="row mb-3 d-flex align-items-center">
|
||||
<div class="col-auto d-flex">
|
||||
<mat-card-title>{{'TENANT-EDITOR.FIELDS.SOURCE' | translate}} {{sourceIndex + 1}}</mat-card-title>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'TENANT-EDITOR.ACTIONS.REMOVE-SOURCE' | translate}}" (click)="removeDepositSource(sourceIndex)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="url" [formControl]="source.get('url')" required>
|
||||
<mat-error *ngIf="source.get('url').hasError('backendError')">{{source.get('url').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('url').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.ISSUER-URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="issuerUrl" [formControl]="source.get('issuerUrl')" required>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('backendError')">{{source.get('issuerUrl').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-ID' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientId" [formControl]="source.get('clientId')" required>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('backendError')">{{source.get('clientId').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-SECRET' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientSecret" [formControl]="source.get('clientSecret')" required>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('backendError')">{{source.get('clientSecret').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.SCOPE' | translate}}</mat-label>
|
||||
<input matInput type="text" name="scope" [formControl]="source.get('scope')" required>
|
||||
<mat-error *ngIf="source.get('scope').hasError('backendError')">{{source.get('scope').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('scope').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CODES' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="source.get('codes')">
|
||||
<mat-chip-row *ngFor="let code of depositCodes.get(sourceIndex)"
|
||||
(removed)="removeDepositCode(code, sourceIndex)"
|
||||
[editable]="true"
|
||||
(edited)="editDepositCode(code, $event, sourceIndex)">
|
||||
{{code}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'TENANT-EDITOR.FIELDS.CODES-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addDepositCode($event, sourceIndex)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="source.get('codes').hasError('backendError')">{{source.get('codes').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('codes').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-tenant-source-component
|
||||
[form]="formGroup.get('config').get('deposit')"
|
||||
[validationErrorModel]="editorModel.validationErrorModel"
|
||||
[validationRootPath]="'config.deposit.'"
|
||||
[codes]="depositCodes"
|
||||
[label]="'TENANT-EDITOR.FIELDS.DEPOSIT' | translate">
|
||||
</app-tenant-source-component>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h3>
|
||||
{{'TENANT-EDITOR.FIELDS.FILE-TRANSFORMERS' | translate}}
|
||||
<button mat-button class="action-btn" type="button" (click)="addFileSource()" [disabled]="formGroup.disabled">{{'TENANT-EDITOR.ACTIONS.ADD-SOURCE' | translate}}</button>
|
||||
</h3>
|
||||
<div *ngFor="let source of formGroup.get('config').get('fileTransformers').get('sources').controls; let sourceIndex=index;" class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="row mb-3 d-flex align-items-center">
|
||||
<div class="col-auto d-flex">
|
||||
<mat-card-title>{{'TENANT-EDITOR.FIELDS.SOURCE' | translate}} {{sourceIndex + 1}}</mat-card-title>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'TENANT-EDITOR.ACTIONS.REMOVE-SOURCE' | translate}}" (click)="removeFileSource(sourceIndex)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="url" [formControl]="source.get('url')" required>
|
||||
<mat-error *ngIf="source.get('url').hasError('backendError')">{{source.get('url').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('url').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.ISSUER-URL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="issuerUrl" [formControl]="source.get('issuerUrl')" required>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('backendError')">{{source.get('issuerUrl').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('issuerUrl').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-ID' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientId" [formControl]="source.get('clientId')" required>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('backendError')">{{source.get('clientId').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CLIENT-SECRET' | translate}}</mat-label>
|
||||
<input matInput type="text" name="clientSecret" [formControl]="source.get('clientSecret')" required>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('backendError')">{{source.get('clientSecret').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('clientSecret').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.SCOPE' | translate}}</mat-label>
|
||||
<input matInput type="text" name="scope" [formControl]="source.get('scope')" required>
|
||||
<mat-error *ngIf="source.get('scope').hasError('backendError')">{{source.get('scope').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('scope').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<mat-form-field class="chip-list">
|
||||
<mat-label>{{'TENANT-EDITOR.FIELDS.CODES' | translate}}</mat-label>
|
||||
<mat-chip-grid #chipGrid [formControl]="source.get('codes')">
|
||||
<mat-chip-row *ngFor="let code of fileTransformersCodes.get(sourceIndex)"
|
||||
(removed)="removeFileCode(code, sourceIndex)"
|
||||
[editable]="true"
|
||||
(edited)="editFileCode(code, $event, sourceIndex)">
|
||||
{{code}}
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
<input placeholder="{{'TENANT-EDITOR.FIELDS.CODES-PLACEHOLDER' | translate}}"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addFileCode($event, sourceIndex)"/>
|
||||
</mat-chip-grid>
|
||||
<mat-error *ngIf="source.get('codes').hasError('backendError')">{{source.get('codes').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="source.get('codes').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-tenant-source-component
|
||||
[form]="formGroup.get('config').get('fileTransformers')"
|
||||
[validationErrorModel]="editorModel.validationErrorModel"
|
||||
[validationRootPath]="'config.fileTransformers.'"
|
||||
[codes]="fileTransformersCodes"
|
||||
[label]="'TENANT-EDITOR.FIELDS.FILE-TRANSFORMERS' | translate">
|
||||
</app-tenant-source-component>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
|
|
@ -27,8 +27,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { TenantEditorResolver } from './tenant-editor.resolver';
|
||||
import { TenantEditorService } from './tenant-editor.service';
|
||||
import { TenantEditorModel, TenantSourceEditorModel } from './tenant-editor.model';
|
||||
import { MatChipEditedEvent, MatChipInputEvent } from '@angular/material/chips';
|
||||
import { TenantEditorModel } from './tenant-editor.model';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -188,137 +187,5 @@ export class TenantEditorComponent extends BaseEditor<TenantEditorModel, Tenant>
|
|||
this.formService.validateAllFormFields(this.formGroup);
|
||||
}
|
||||
|
||||
//
|
||||
// deposit source
|
||||
//
|
||||
addDepositSource(): void {
|
||||
this.depositCodes.set((this.formGroup.get('config').get('deposit').get('sources') as FormArray).length, []);
|
||||
(this.formGroup.get('config').get('deposit').get('sources') as FormArray).push(this.editorModel.createChildDeposit((this.formGroup.get('config').get('deposit').get('sources') as FormArray).length));
|
||||
}
|
||||
|
||||
removeDepositSource(sourceIndex: number): void {
|
||||
this.depositCodes.delete((this.formGroup.get('config').get('deposit').get('sources') as FormArray).length);
|
||||
(this.formGroup.get('config').get('deposit').get('sources') as FormArray).removeAt(sourceIndex);
|
||||
|
||||
//Reapply validators
|
||||
TenantEditorModel.reApplyDepositSourcesValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
}
|
||||
)
|
||||
this.formGroup.get('config').get('deposit').get('sources').markAsDirty();
|
||||
}
|
||||
|
||||
// deposit source codes
|
||||
|
||||
addDepositCode(event: MatChipInputEvent, key: number): void {
|
||||
const value = (event.value || '').trim();
|
||||
|
||||
if (value){
|
||||
const values = this.depositCodes.get(key);
|
||||
values.push(value);
|
||||
this.depositCodes.set(key, values);
|
||||
}
|
||||
event.chipInput!.clear();
|
||||
}
|
||||
|
||||
removeDepositCode(code: string, key: number): void {
|
||||
const values = this.depositCodes.get(key);
|
||||
if (values){
|
||||
const index = values.indexOf(code);
|
||||
|
||||
if (index >= 0) {
|
||||
values.splice(index, 1);
|
||||
this.depositCodes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editDepositCode(code: string, event: MatChipEditedEvent, key: number) {
|
||||
const values = this.depositCodes.get(key);
|
||||
if (values){
|
||||
const value = event.value.trim();
|
||||
|
||||
// Remove code if it no longer has a value
|
||||
if (!value) {
|
||||
this.removeDepositCode(code, key);
|
||||
return;
|
||||
}
|
||||
|
||||
const index = values.indexOf(code);
|
||||
if (index >= 0) {
|
||||
values[index] = value;
|
||||
this.depositCodes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// fileTransformers source
|
||||
//
|
||||
addFileSource(): void {
|
||||
this.fileTransformersCodes.set((this.formGroup.get('config').get('fileTransformers').get('sources') as FormArray).length, []);
|
||||
(this.formGroup.get('config').get('fileTransformers').get('sources') as FormArray).push(this.editorModel.createChildFileTransformer((this.formGroup.get('config').get('fileTransformers').get('sources') as FormArray).length));
|
||||
}
|
||||
|
||||
removeFileSource(sourceIndex: number): void {
|
||||
this.fileTransformersCodes.delete((this.formGroup.get('config').get('fileTransformers').get('sources') as FormArray).length);
|
||||
(this.formGroup.get('config').get('fileTransformers').get('sources') as FormArray).removeAt(sourceIndex);
|
||||
|
||||
//Reapply validators
|
||||
TenantEditorModel.reApplyFileTransformerSourcesValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
}
|
||||
)
|
||||
this.formGroup.get('config').get('fileTransformers').get('sources').markAsDirty();
|
||||
}
|
||||
|
||||
// fileTransformers source codes
|
||||
|
||||
addFileCode(event: MatChipInputEvent, key: number): void {
|
||||
const value = (event.value || '').trim();
|
||||
|
||||
if (value){
|
||||
const values = this.fileTransformersCodes.get(key);
|
||||
values.push(value);
|
||||
this.fileTransformersCodes.set(key, values);
|
||||
}
|
||||
event.chipInput!.clear();
|
||||
}
|
||||
|
||||
removeFileCode(code: string, key: number): void {
|
||||
const values = this.fileTransformersCodes.get(key);
|
||||
if (values){
|
||||
const index = values.indexOf(code);
|
||||
|
||||
if (index >= 0) {
|
||||
values.splice(index, 1);
|
||||
this.fileTransformersCodes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editFileCode(code: string, event: MatChipEditedEvent, key:number) {
|
||||
const values = this.fileTransformersCodes.get(key);
|
||||
if (values){
|
||||
const value = event.value.trim();
|
||||
|
||||
// Remove code if it no longer has a value
|
||||
if (!value) {
|
||||
this.removeFileCode(code, key);
|
||||
return;
|
||||
}
|
||||
|
||||
const index = values.indexOf(code);
|
||||
if (index >= 0) {
|
||||
values[index] = value;
|
||||
this.fileTransformersCodes.set(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -56,11 +56,6 @@ export class TenantEditorModel extends BaseEditorModel implements TenantPersist
|
|||
return baseContext;
|
||||
}
|
||||
|
||||
createChildDeposit(index: number): UntypedFormGroup {
|
||||
const deposit: TenantSourceEditorModel = new TenantSourceEditorModel(this.validationErrorModel);
|
||||
return deposit.buildForm({ rootPath: 'config.deposit.sources[' + index + '].' });
|
||||
}
|
||||
|
||||
static reApplyDepositSourcesValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
|
@ -75,11 +70,6 @@ export class TenantEditorModel extends BaseEditorModel implements TenantPersist
|
|||
});
|
||||
}
|
||||
|
||||
createChildFileTransformer(index: number): UntypedFormGroup {
|
||||
const deposit: TenantSourceEditorModel = new TenantSourceEditorModel(this.validationErrorModel);
|
||||
return deposit.buildForm({ rootPath: 'config.fileTransformers.sources[' + index + '].' });
|
||||
}
|
||||
|
||||
static reApplyFileTransformerSourcesValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
|
@ -186,8 +176,8 @@ export class TenantDepositConfigEditorModel implements TenantDepositConfigPersis
|
|||
this.validationErrorModel
|
||||
).fromModel(item).buildForm({
|
||||
rootPath: `${rootPath}sources[${index}].`
|
||||
}), context.getValidation('sources')
|
||||
)
|
||||
})
|
||||
), context.getValidation('sources')
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -258,8 +248,8 @@ export class TenantFileTransformersConfigEditorModel implements TenantFileTransf
|
|||
this.validationErrorModel
|
||||
).fromModel(item).buildForm({
|
||||
rootPath: `${rootPath}sources[${index}].`
|
||||
}), context.getValidation('sources')
|
||||
)
|
||||
})
|
||||
), context.getValidation('sources')
|
||||
),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import { TenantEditorComponent } from './editor/tenant-editor.component';
|
|||
import { TenantListingComponent } from './listing/tenant-listing.component';
|
||||
import { TenantListingFiltersComponent } from "./listing/filters/tenant-listing-filters.component";
|
||||
import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-editor.module';
|
||||
import { TenantSourceComponent } from './editor/source/tenant-source.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -33,7 +34,8 @@ import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-ed
|
|||
declarations: [
|
||||
TenantEditorComponent,
|
||||
TenantListingComponent,
|
||||
TenantListingFiltersComponent
|
||||
TenantListingFiltersComponent,
|
||||
TenantSourceComponent
|
||||
]
|
||||
})
|
||||
export class TenantModule { }
|
||||
|
|
Loading…
Reference in New Issue