Merged in CST-12179 (pull request #980)

CST-12179

Approved-by: Stefano Maffei
This commit is contained in:
Mattia Vianelli
2023-11-16 15:56:33 +00:00
committed by Stefano Maffei
8 changed files with 574 additions and 493 deletions

View File

@@ -1,284 +1,293 @@
<div class="container"> <div class="container">
<form (ngSubmit)="onSubmit()" [formGroup]="formModel"> <form (ngSubmit)="onSubmit()" [formGroup]="formModel">
<div class="d-flex"> <div class="d-flex">
<h2 class="flex-grow-1">{{ 'ldn-edit-registered-service.title' | translate }}</h2> <h2 class="flex-grow-1">{{ 'ldn-edit-registered-service.title' | translate }}</h2>
</div> </div>
<!-- In the toggle section --> <!-- In the toggle section -->
<div class="toggle-switch-container"> <div class="toggle-switch-container">
<label class="status-label" for="enabled">{{ 'ldn-service-status' | translate }}</label> <label class="status-label" for="enabled">{{ 'ldn-service-status' | translate }}</label>
<div> <div>
<input formControlName="enabled" hidden id="enabled" name="enabled" type="checkbox"> <input formControlName="enabled" hidden id="enabled" name="enabled" type="checkbox">
<div (click)="toggleEnabled()" [class.checked]="formModel.get('enabled').value" class="toggle-switch"> <div (click)="toggleEnabled()" [class.checked]="formModel.get('enabled').value" class="toggle-switch">
<div class="slider"></div> <div class="slider"></div>
</div>
</div>
</div> </div>
</div>
</div>
<div class="mb-2"> <div class="mb-5">
<label for="name">{{ 'ldn-new-service.form.label.name' | translate }}</label> <label for="name">{{ 'ldn-new-service.form.label.name' | translate }}</label>
<input [class.invalid-field]="formModel.get('name').invalid && formModel.get('name').touched" <input [class.invalid-field]="formModel.get('name').invalid && formModel.get('name').touched"
[placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name" [placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name"
name="name" name="name"
type="text"> type="text">
</div> <div *ngIf="formModel.get('name').invalid && formModel.get('name').touched" class="error-text">
{{ 'ldn-new-service.form.error.name' | translate }}
</div>
</div>
<div class="mb-4"> <!-- In the description section -->
&nbsp; <div class="mb-5 mt-5 d-flex flex-column">
</div> <label for="description">{{ 'ldn-new-service.form.label.description' | translate }}</label>
<textarea [placeholder]="'ldn-new-service.form.placeholder.description' | translate"
formControlName="description" id="description" name="description"></textarea>
</div>
<!-- In the description section --> <!-- In the url section -->
<div class="mb-2 d-flex flex-column"> <div class="mb-5 mt-5">
<label for="description">{{ 'ldn-new-service.form.label.description' | translate }}</label> <label for="url">{{ 'ldn-new-service.form.label.url' | translate }}</label>
<textarea [placeholder]="'ldn-new-service.form.placeholder.description' | translate" <input [class.invalid-field]="formModel.get('url').invalid && formModel.get('url').touched"
formControlName="description" id="description" name="description"></textarea> [placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url"
</div> name="url"
type="text">
<div class="mb-4"> <div *ngIf="formModel.get('url').invalid && formModel.get('url').touched" class="error-text">
&nbsp; {{ 'ldn-new-service.form.error.url' | translate }}
</div> </div>
</div>
<!-- In the url section -->
<div class="mb-2">
<label for="url">{{ 'ldn-new-service.form.label.url' | translate }}</label>
<input [class.invalid-field]="formModel.get('url').invalid && formModel.get('url').touched"
[placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url"
name="url"
type="text">
</div>
<div class="mb-4">
&nbsp;
</div>
<!-- In the ldnUrl section -->
<div class="mb-2">
<label for="ldnUrl">{{ 'ldn-new-service.form.label.ldnUrl' | translate }}</label>
<input [class.invalid-field]="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched"
[placeholder]="'ldn-new-service.form.placeholder.ldnUrl' | translate" formControlName="ldnUrl"
id="ldnUrl"
name="ldnUrl"
type="text">
</div>
<div class="mb-4">
&nbsp;
</div>
<div class="row">
<div class="col">
<label>{{ 'ldn-new-service.form.label.inboundPattern' | translate }} </label>
</div>
<div class="col">
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm1 ">
<label class="label-box-2">{{ 'ldn-new-service.form.label.automatic' | translate }}</label>
</div>
<div class="col-sm-1">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceInboundPatterns')['controls']; let i = index"
formGroupName="notifyServiceInboundPatterns" [class.marked-for-deletion]="markedForDeletionInboundPattern.includes(i)">
<ng-container [formGroupName]="i">
<div class="row mb-1"> <!-- In the ldnUrl section -->
<div class="col"> <div class="mb-5 mt-5">
<select #inboundPattern formControlName="pattern" id="additionalInboundPattern{{i}}" <label for="ldnUrl">{{ 'ldn-new-service.form.label.ldnUrl' | translate }}</label>
name="additionalInboundPattern{{i}}" required> <input [class.invalid-field]="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched"
<option value="">{{ 'ldn-new-service.form.label.placeholder.inboundPattern' | translate }}</option> [placeholder]="'ldn-new-service.form.placeholder.ldnUrl' | translate" formControlName="ldnUrl"
<option *ngFor="let pattern of inboundPatterns" id="ldnUrl"
[ngValue]="pattern.name">{{ pattern.name }}</option> name="ldnUrl"
</select> type="text">
</div> <div *ngIf="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched" class="error-text">
{{ 'ldn-new-service.form.error.ldnurl' | translate }}
</div>
</div>
<div class="col"> <!-- In the score section -->
<ng-container *ngIf="inboundPattern.value"> <div class="mb-2">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}"> <label for="score">{{ 'ldn-new-service.form.label.score' | translate }}</label>
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option> <input [class.invalid-field]="formModel.get('score').invalid && formModel.get('score').touched"
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page" [placeholder]="'ldn-new-service.form.placeholder.score' | translate" formControlName="score"
[value]="itemFilter.id">{{ itemFilter.id }}</option> id="score"
</select> name="score"
</ng-container> type="text">
</div> <div *ngIf="formModel.get('score').invalid && formModel.get('score').touched" class="error-text">
{{ 'ldn-new-service.form.error.score' | translate }}
<div [style.visibility]="inboundPattern.value ? 'visible' : 'hidden'" class="col-sm1"> </div>
<input formControlName="automatic" hidden id="automatic{{i}}" name="automatic{{i}}" </div>
type="checkbox">
<div (click)="toggleAutomatic(i)"
[class.checked]="formModel.get('notifyServiceInboundPatterns.' + i + '.automatic').value"
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-2"> <div class="row mb-1 mt-5">
<button (click)="markForInboundPatternDeletion(i)" class="btn btn-outline-dark" <div class="col">
type="button"> <label>{{ 'ldn-new-service.form.label.inboundPattern' | translate }} </label>
<i class="fas fa-trash"></i> </div>
</button> <div class="col">
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm1 ">
<label class="label-box-2">{{ 'ldn-new-service.form.label.automatic' | translate }}</label>
</div>
<div class="col-sm-2">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceInboundPatterns')['controls']; let i = index"
[class.marked-for-deletion]="markedForDeletionInboundPattern.includes(i)"
formGroupName="notifyServiceInboundPatterns">
<ng-container [formGroupName]="i">
<button (click)="unmarkForInboundPatternDeletion(i)" *ngIf="markedForDeletionInboundPattern.includes(i)" class="btn btn-warning ml-2" <div class="row mb-1">
type="button"> <div class="col">
<i class="fas fa-undo"></i> <select #inboundPattern formControlName="pattern" id="additionalInboundPattern{{i}}"
</button> name="additionalInboundPattern{{i}}" required>
</div> <option value="">{{ 'ldn-new-service.form.label.placeholder.inboundPattern' | translate }}</option>
</div> <option *ngFor="let pattern of inboundPatterns"
[value]="pattern">{{ 'ldn-service.form.pattern.' + pattern + '.label' | translate }} </option>
</select>
</div>
<div class="col">
<ng-container *ngIf="inboundPattern.value">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
[value]="itemFilter.id">{{ itemFilter.id }}</option>
</select>
</ng-container> </ng-container>
</div>
<div [style.visibility]="inboundPattern.value ? 'visible' : 'hidden'" class="col-sm1">
<input formControlName="automatic" hidden id="automatic{{i}}" name="automatic{{i}}"
type="checkbox">
<div (click)="toggleAutomatic(i)"
[class.checked]="formModel.get('notifyServiceInboundPatterns.' + i + '.automatic').value"
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-2">
<div class="btn-group">
<button (click)="markForInboundPatternDeletion(i)" class="btn btn-outline-dark trash-button"
type="button">
<i class="fas fa-trash"></i>
</button>
<button (click)="unmarkForInboundPatternDeletion(i)" *ngIf="markedForDeletionInboundPattern.includes(i)"
class="btn btn-warning"
type="button">
<i class="fas fa-undo"></i>
</button>
</div>
</div>
</div> </div>
</ng-container>
</div>
<span (click)="addInboundPattern()" <span (click)="addInboundPattern()"
class="add-pattern-link mb-2">{{ 'ldn-new-service.form.label.addPattern' | translate }}</span> class="add-pattern-link mb-2">{{ 'ldn-new-service.form.label.addPattern' | translate }}</span>
<div class="mb-4">
&nbsp;
</div>
<div class="row"> <div class="row mb-1 mt-5">
<div class="col"> <div class="col">
<label>{{ 'ldn-new-service.form.label.outboundPattern' | translate }}</label> <label>{{ 'ldn-new-service.form.label.outboundPattern' | translate }} </label>
</div> </div>
<div class="col"> <div class="col">
<label class="label-box-3">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label> <label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div> </div>
<div class="col-sm-1 "> <div class="col-sm1 ">
<label class="label-box-2"></label> <label class="label-box-2" style="visibility: hidden;">
</div> {{ 'ldn-new-service.form.label.automatic' | translate }}
<div class="col-sm-1 "> </label>
</div> </div>
</div> <div class="col-sm-2">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceOutboundPatterns')['controls']; let i = index" <div *ngFor="let patternGroup of formModel.get('notifyServiceOutboundPatterns')['controls']; let i = index"
formGroupName="notifyServiceOutboundPatterns" [class.marked-for-deletion]="markedForDeletionOutboundPattern.includes(i)"> [class.marked-for-deletion]="markedForDeletionOutboundPattern.includes(i)"
formGroupName="notifyServiceOutboundPatterns">
<ng-container [formGroupName]="i"> <ng-container [formGroupName]="i">
<!-- Input elements in a separate row --> <!-- Input elements in a separate row -->
<div class="row mb-1"> <div class="row mb-1">
<div class="col"> <div class="col">
<select #outboundPattern formControlName="pattern" id="additionalOutboundPattern{{i}}" <select #outboundPattern formControlName="pattern" id="additionalOutboundPattern{{i}}"
name="additionalOutboundPattern{{i}}" name="additionalOutboundPattern{{i}}"
required> required>
<option value="">{{ 'ldn-new-service.form.label.placeholder.outboundPattern' | translate }}</option> <option value="">{{ 'ldn-new-service.form.label.placeholder.outboundPattern' | translate }}</option>
<option *ngFor="let pattern of outboundPatterns" <option *ngFor="let pattern of outboundPatterns"
[ngValue]="pattern.name">{{ pattern.name }}</option> [value]="pattern">{{ 'ldn-service.form.pattern.' + pattern + '.label' | translate }} </option>
</select> </select>
</div> </div>
<div class="col"> <div class="col">
<ng-container *ngIf="outboundPattern.value"> <ng-container *ngIf="outboundPattern.value">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}"> <select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option> <option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page" <option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
[value]="itemFilter.id">{{ itemFilter.id }}</option> [value]="itemFilter.id">{{ itemFilter.id }}</option>
</select> </select>
</ng-container>
</div>
<div [style.visibility]="'hidden'" class="col-sm1">
<input hidden id="automatic{{i}}" name="automatic{{i}}" type="checkbox">
<div
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-2">
<button (click)="markForOutboundPatternDeletion(i)" class="btn btn-outline-dark trash-button" type="button">
<i class="fas fa-trash"></i>
</button>
<button (click)="unmarkForOutboundPatternDeletion(i)" *ngIf="markedForDeletionOutboundPattern.includes(i)" class="btn btn-warning ml-2"
type="button">
<i class="fas fa-undo"></i>
</button>
</div>
</div>
</ng-container> </ng-container>
</div> </div>
<span <div [style.visibility]="'hidden'" class="col-sm1">
(click)="addOutboundPattern()" <input hidden id="automatic{{i}}" name="automatic{{i}}" type="checkbox">
class="add-pattern-link mb-2">{{ 'ldn-new-service.form.label.addPattern' | translate }} <div
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-2">
<div class="btn-group">
<button (click)="markForOutboundPatternDeletion(i)" class="btn btn-outline-dark trash-button"
type="button">
<i class="fas fa-trash"></i>
</button>
<button (click)="unmarkForOutboundPatternDeletion(i)" *ngIf="markedForDeletionOutboundPattern.includes(i)"
class="btn btn-warning"
type="button">
<i class="fas fa-undo"></i>
</button>
</div>
</div>
</div>
</ng-container>
</div>
<span
(click)="addOutboundPattern()"
class="add-pattern-link mb-2">{{ 'ldn-new-service.form.label.addPattern' | translate }}
</span> </span>
<div aria-label="Basic example" class="submission-form-footer mt-1 mb-1 position-sticky" role="group">
<div class="mb-5"> <button class="btn btn-primary" type="submit">
&nbsp; <span><i class="fas fa-save"></i> {{ 'ldn-new-service.form.label.submit' | translate }}</span>
</div> </button>
<div aria-label="Basic example" class="submission-form-footer mt-1 mb-1 position-sticky" role="group"> <div class="d-flex">
<button class="btn btn-primary" type="submit"> <button (click)="this.openResetFormModal(this.resetFormModal)" class="btn btn-danger" type="button">
<span><i class="fas fa-save"></i> {{ 'ldn-new-service.form.label.submit' | translate }}</span> <span><i class="fas fa-trash"></i> {{ 'submission.general.discard.submit' | translate }}</span>
</button> </button>
<div class="d-flex"> </div>
<button (click)="this.openResetFormModal(this.resetFormModal)" class="btn btn-danger" type="button"> </div>
<span><i class="fas fa-trash"></i> {{ 'submission.general.discard.submit' | translate }}</span> </form>
</button>
</div>
</div>
</form>
</div> </div>
<ng-template #confirmModal> <ng-template #confirmModal>
<div> <div>
<div class="modal-header"> <div class="modal-header">
<div> <div>
<h4>{{'service.overview.edit.modal' | translate }}</h4> <h4>{{'service.overview.edit.modal' | translate }}</h4>
</div> </div>
<button (click)="closeModal()" aria-label="Close" <button (click)="closeModal()" aria-label="Close"
class="close" type="button"> class="close" type="button">
<span aria-hidden="true">×</span> <span aria-hidden="true">×</span>
</button> </button>
</div>
<div class="modal-body">
<div>
{{ 'service.overview.edit.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="btn btn-danger mr-2"
id="delete-confirm">{{ 'service.detail.return' | translate }}
</button>
<button (click)="this.patchService()"
class="btn btn-primary custom-btn">{{ 'service.detail.update' | translate }}
</button>
</div>
</div>
</div> </div>
<div class="modal-body">
<div>
{{ 'service.overview.edit.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="btn btn-danger mr-2"
id="delete-confirm">{{ 'service.detail.return' | translate }}
</button>
<button (click)="this.patchService()"
class="btn btn-primary custom-btn">{{ 'service.detail.update' | translate }}
</button>
</div>
</div>
</div>
</ng-template> </ng-template>
<ng-template #resetFormModal> <ng-template #resetFormModal>
<div> <div>
<div class="modal-header"> <div class="modal-header">
<div> <div>
<h4>{{'service.overview.reset-form.modal' | translate }}</h4> <h4>{{'service.overview.reset-form.modal' | translate }}</h4>
</div> </div>
<button (click)="closeModal()" aria-label="Close" <button (click)="closeModal()" aria-label="Close"
class="close" type="button"> class="close" type="button">
<span aria-hidden="true">×</span> <span aria-hidden="true">×</span>
</button> </button>
</div>
<div class="modal-body">
<div>
{{ 'service.overview.reset-form.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="mr-2 btn btn-danger"
id="reset-delete">{{ 'service.overview.reset-form.reset-confirm' | translate }}
</button>
<button (click)="resetFormAndLeave()"
class="btn btn-primary custom-btn"
id="reset-confirm">{{ 'service.overview.reset-form.reset-return' | translate }}
</button>
</div>
</div>
</div> </div>
<div class="modal-body">
<div>
{{ 'service.overview.reset-form.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="mr-2 btn btn-danger"
id="reset-delete">{{ 'service.overview.reset-form.reset-confirm' | translate }}
</button>
<button (click)="resetFormAndLeave()"
class="btn btn-primary custom-btn"
id="reset-confirm">{{ 'service.overview.reset-form.reset-return' | translate }}
</button>
</div>
</div>
</div>
</ng-template> </ng-template>

View File

@@ -47,6 +47,12 @@ textarea {
color: #000000; color: #000000;
} }
.error-text {
color: red;
font-size: 0.8em;
margin-top: 5px;
}
.toggle-switch { .toggle-switch {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -51,6 +51,7 @@ export class LdnServiceFormEditComponent implements OnInit {
@Input() public description: string; @Input() public description: string;
@Input() public url: string; @Input() public url: string;
@Input() public ldnUrl: string; @Input() public ldnUrl: string;
@Input() public score: number;
@Input() public inboundPattern: string; @Input() public inboundPattern: string;
@Input() public outboundPattern: string; @Input() public outboundPattern: string;
@Input() public constraint: string; @Input() public constraint: string;
@@ -85,6 +86,7 @@ export class LdnServiceFormEditComponent implements OnInit {
description: ['', Validators.required], description: ['', Validators.required],
url: ['', Validators.required], url: ['', Validators.required],
ldnUrl: ['', Validators.required], ldnUrl: ['', Validators.required],
score: ['', [Validators.required, Validators.pattern('^0*(\.[0-9]+)?$|^1(\.0+)?$')]],
inboundPattern: [''], inboundPattern: [''],
outboundPattern: [''], outboundPattern: [''],
constraintPattern: [''], constraintPattern: [''],
@@ -124,6 +126,7 @@ export class LdnServiceFormEditComponent implements OnInit {
name: this.service.name, name: this.service.name,
description: this.service.description, description: this.service.description,
url: this.service.url, url: this.service.url,
score: this.service.score,
ldnUrl: this.service.ldnUrl, ldnUrl: this.service.ldnUrl,
type: this.service.type, type: this.service.type,
enabled: this.service.enabled enabled: this.service.enabled
@@ -163,6 +166,8 @@ export class LdnServiceFormEditComponent implements OnInit {
this.createReplaceOperation(patchOperations, 'description', '/description'); this.createReplaceOperation(patchOperations, 'description', '/description');
this.createReplaceOperation(patchOperations, 'ldnUrl', '/ldnurl'); this.createReplaceOperation(patchOperations, 'ldnUrl', '/ldnurl');
this.createReplaceOperation(patchOperations, 'url', '/url'); this.createReplaceOperation(patchOperations, 'url', '/url');
this.createReplaceOperation(patchOperations, 'score', '/score');
this.handlePatterns(patchOperations, 'notifyServiceInboundPatterns'); this.handlePatterns(patchOperations, 'notifyServiceInboundPatterns');
this.handlePatterns(patchOperations, 'notifyServiceOutboundPatterns'); this.handlePatterns(patchOperations, 'notifyServiceOutboundPatterns');
@@ -250,16 +255,18 @@ export class LdnServiceFormEditComponent implements OnInit {
this.ldnServicesService.patch(this.service, patchOperations).pipe( this.ldnServicesService.patch(this.service, patchOperations).pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData()
).subscribe( ).subscribe((rd: RemoteData<LdnService>) => {
() => { if (rd.hasSucceeded) {
this.closeModal();
this.closeModal(); this.sendBack();
this.sendBack(); this.notificationService.success(this.translateService.get('admin.registries.services-formats.modify.success.head'),
this.notificationService.success(this.translateService.get('admin.registries.services-formats.modify.success.head'), this.translateService.get('admin.registries.services-formats.modify.success.content'));
this.translateService.get('admin.registries.services-formats.modify.success.content')); } else {
} this.notificationService.error(this.translateService.get('admin.registries.services-formats.modify.failure.head'),
); this.translateService.get('admin.registries.services-formats.modify.failure.content'));
this.closeModal();
}
});
} }
resetFormAndLeave() { resetFormAndLeave() {

View File

@@ -1,266 +1,273 @@
<div class="container"> <div class="container">
<form (ngSubmit)="onSubmit()" [formGroup]="formModel"> <form (ngSubmit)="onSubmit()" [formGroup]="formModel">
<div class="d-flex"> <div class="d-flex">
<h2 class="flex-grow-1">{{ 'ldn-create-service.title' | translate }}</h2> <h2 class="flex-grow-1">{{ 'ldn-create-service.title' | translate }}</h2>
</div> </div>
<!-- In the name section --> <!-- In the name section -->
<div class="mb-2"> <div class="mb-5">
<label for="name">{{ 'ldn-new-service.form.label.name' | translate }}</label> <label for="name">{{ 'ldn-new-service.form.label.name' | translate }}</label>
<input [class.invalid-field]="formModel.get('name').invalid && formModel.get('name').touched" <input [class.invalid-field]="formModel.get('name').invalid && formModel.get('name').touched"
[placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name" [placeholder]="'ldn-new-service.form.placeholder.name' | translate" formControlName="name" id="name"
name="name" name="name"
type="text"> type="text">
</div> <div *ngIf="formModel.get('name').invalid && formModel.get('name').touched" class="error-text">
{{ 'ldn-new-service.form.error.name' | translate }}
</div>
</div>
<div class="mb-4">
&nbsp;
</div>
<!-- In the description section --> <!-- In the description section -->
<div class="mb-2 d-flex flex-column"> <div class="mb-5 mt-5 d-flex flex-column">
<label for="description">{{ 'ldn-new-service.form.label.description' | translate }}</label> <label for="description">{{ 'ldn-new-service.form.label.description' | translate }}</label>
<textarea [placeholder]="'ldn-new-service.form.placeholder.description' | translate" <textarea [placeholder]="'ldn-new-service.form.placeholder.description' | translate"
formControlName="description" id="description" name="description"></textarea> formControlName="description" id="description" name="description"></textarea>
</div> </div>
<div class="mb-4">
&nbsp;
</div>
<!-- In the url section --> <!-- In the url section -->
<div class="mb-2"> <div class="mb-5 mt-5">
<label for="url">{{ 'ldn-new-service.form.label.url' | translate }}</label> <label for="url">{{ 'ldn-new-service.form.label.url' | translate }}</label>
<input [class.invalid-field]="formModel.get('url').invalid && formModel.get('url').touched" <input [class.invalid-field]="formModel.get('url').invalid && formModel.get('url').touched"
[placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url" [placeholder]="'ldn-new-service.form.placeholder.url' | translate" formControlName="url" id="url"
name="url" name="url"
type="text"> type="text">
</div> <div *ngIf="formModel.get('url').invalid && formModel.get('url').touched" class="error-text">
{{ 'ldn-new-service.form.error.url' | translate }}
</div>
</div>
<div class="mb-4">
&nbsp;
</div>
<!-- In the ldnUrl section --> <!-- In the ldnUrl section -->
<div class="mb-2"> <div class="mb-5 mt-5">
<label for="ldnUrl">{{ 'ldn-new-service.form.label.ldnUrl' | translate }}</label> <label for="ldnUrl">{{ 'ldn-new-service.form.label.ldnUrl' | translate }}</label>
<input [class.invalid-field]="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched" <input [class.invalid-field]="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched"
[placeholder]="'ldn-new-service.form.placeholder.ldnUrl' | translate" formControlName="ldnUrl" [placeholder]="'ldn-new-service.form.placeholder.ldnUrl' | translate" formControlName="ldnUrl"
id="ldnUrl" id="ldnUrl"
name="ldnUrl" name="ldnUrl"
type="text"> type="text">
</div> <div *ngIf="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched" class="error-text">
{{ 'ldn-new-service.form.error.ldnurl' | translate }}
</div>
</div>
<!-- In the score section -->
<div class="mb-2">
<label for="score">{{ 'ldn-new-service.form.label.score' | translate }}</label>
<input [class.invalid-field]="formModel.get('score').invalid && formModel.get('score').touched"
[placeholder]="'ldn-new-service.form.placeholder.score' | translate" formControlName="score"
id="score"
name="score"
type="text">
<div *ngIf="formModel.get('score').invalid && formModel.get('score').touched" class="error-text">
{{ 'ldn-new-service.form.error.score' | translate }}
</div>
</div>
<div class="mb-4"> <!-- In the Inbound Patterns section -->
&nbsp; <div class="row mb-2 mt-5">
</div> <div class="col">
<label>{{ 'ldn-new-service.form.label.inboundPattern' | translate }} </label>
</div>
<div class="col">
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm1 ">
<label class="label-box-2">{{ 'ldn-new-service.form.label.automatic' | translate }}</label>
</div>
<div class="col-sm-2">
</div>
</div>
<!-- In the Inbound Patterns section --> <div *ngFor="let patternGroup of formModel.get('notifyServiceInboundPatterns')['controls']; let i = index"
<div class="row"> formGroupName="notifyServiceInboundPatterns">
<div class="col">
<label>{{ 'ldn-new-service.form.label.inboundPattern' | translate }} </label> <ng-container [formGroupName]="i">
<div class="row mb-1">
<div class="col">
<select #inboundPattern formControlName="pattern" id="additionalInboundPattern{{i}}"
name="additionalInboundPattern{{i}}" required>
<option value="">{{ 'ldn-new-service.form.label.placeholder.inboundPattern' | translate }}</option>
<option *ngFor="let pattern of inboundPatterns"
[value]="pattern">{{ 'ldn-service.form.pattern.' + pattern + '.label' | translate }} </option>
</select>
<div *ngIf="!patternSelected()" class="error-text">
{{ 'ldn-new-service.form.error.patterns' | translate }}
</div> </div>
<div class="col"> </div>
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm1 ">
<label class="label-box-2">{{ 'ldn-new-service.form.label.automatic' | translate }}</label>
</div>
<div class="col-sm-1">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceInboundPatterns')['controls']; let i = index"
formGroupName="notifyServiceInboundPatterns">
<ng-container [formGroupName]="i">
<div class="row mb-1"> <div class="col">
<div class="col"> <ng-container *ngIf="inboundPattern.value">
<select #inboundPattern formControlName="pattern" id="additionalInboundPattern{{i}}" <select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
name="additionalInboundPattern{{i}}" required> <option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option value="">{{ 'ldn-new-service.form.label.placeholder.inboundPattern' | translate }}</option> <option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
<option *ngFor="let pattern of inboundPatterns" [value]="itemFilter.id">{{ itemFilter.id }}</option>
[ngValue]="pattern.name">{{ pattern.name }}</option> </select>
</select>
</div>
<div class="col">
<ng-container *ngIf="inboundPattern.value">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
[value]="itemFilter.id">{{ itemFilter.id }}</option>
</select>
</ng-container>
</div>
<div [style.visibility]="inboundPattern.value ? 'visible' : 'hidden'" class="col-sm-1">
<input formControlName="automatic" hidden id="automatic{{i}}" name="automatic{{i}}"
type="checkbox">
<div (click)="toggleAutomatic(i)"
[class.checked]="formModel.get('notifyServiceInboundPatterns.' + i + '.automatic').value"
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-1">
<button (click)="removeInboundPattern(i)" class="btn btn-outline-dark trash-button">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</ng-container> </ng-container>
</div> </div>
<span (click)="addInboundPattern()" <div [style.visibility]="inboundPattern.value ? 'visible' : 'hidden'" class="col-sm-1">
class="add-pattern-link mb-2">{{ 'ldn-new-service.form.label.addPattern' | translate }}</span> <input formControlName="automatic" hidden id="automatic{{i}}" name="automatic{{i}}"
type="checkbox">
<div (click)="toggleAutomatic(i)"
<div class="mb-4"> [class.checked]="formModel.get('notifyServiceInboundPatterns.' + i + '.automatic').value"
&nbsp; class="toggle-switch">
</div> <div class="slider"></div>
<!-- In the Outbound Patterns section -->
<div class="row">
<div class="col">
<label>{{ 'ldn-new-service.form.label.outboundPattern' | translate }}</label>
</div> </div>
<div class="col"> </div>
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm-1 ">
</div>
<div class="col-sm-1 ">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceOutboundPatterns')['controls']; let i = index" <div class="col-sm-1">
formGroupName="notifyServiceOutboundPatterns"> <button (click)="removeInboundPattern(i)" class="btn btn-outline-dark trash-button">
<i class="fas fa-trash"></i>
<ng-container [formGroupName]="i">
<!-- Input elements in a separate row -->
<div class="row mb-1">
<div class="col">
<select #outboundPattern formControlName="pattern" id="additionalOutboundPattern{{i}}"
name="additionalOutboundPattern{{i}}"
required>
<option value="">{{ 'ldn-new-service.form.label.placeholder.outboundPattern' | translate }}</option>
<option *ngFor="let pattern of outboundPatterns"
[ngValue]="pattern.name">{{ pattern.name }}</option>
</select>
</div>
<div class="col">
<ng-container *ngIf="outboundPattern.value">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
[value]="itemFilter.id">{{ itemFilter.id }}</option>
</select>
</ng-container>
</div>
<div [style.visibility]="'hidden'" class="col-sm1">
<input hidden id="automatic{{i}}" name="automatic{{i}}" type="checkbox">
<div
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-1">
<button (click)="removeOutboundPattern(i)" class="btn btn-outline-dark trash-button">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</ng-container>
</div>
<span (click)="addOutboundPattern()"
class="add-pattern-link">{{ 'ldn-new-service.form.label.addPattern' | translate }}
</span>
<div class="mb-4">
&nbsp;
</div>
<div aria-label="Basic example" class="submission-form-footer mt-1 mb-1 position-sticky" role="group">
<button class="btn btn-primary" type="submit">
<span><i class="fas fa-save"></i> {{ 'ldn-new-service.form.label.submit' | translate }}</span>
</button> </button>
<div class="d-flex"> </div>
<button (click)="this.openResetFormModal(this.resetFormModal)" class="btn btn-danger" type="button">
<span><i class="fas fa-trash"></i> {{ 'submission.general.discard.submit' | translate }}</span>
</button>
</div>
</div> </div>
</ng-container>
</div>
<span (click)="addInboundPattern()"
class="add-pattern-link mb-4">{{ 'ldn-new-service.form.label.addPattern' | translate }}</span>
</form> <!-- In the Outbound Patterns section -->
<div class="row mb-1 mt-5">
<div class="col">
<label>{{ 'ldn-new-service.form.label.outboundPattern' | translate }} </label>
</div>
<div class="col">
<label class="label-box">{{ 'ldn-new-service.form.label.ItemFilter' | translate }}</label>
</div>
<div class="col-sm1 ">
<label class="label-box-2" style="visibility: hidden;">
{{ 'ldn-new-service.form.label.automatic' | translate }}
</label>
</div>
<div class="col-sm-2">
</div>
</div>
<div *ngFor="let patternGroup of formModel.get('notifyServiceOutboundPatterns')['controls']; let i = index"
formGroupName="notifyServiceOutboundPatterns">
<ng-container [formGroupName]="i">
<!-- Input elements in a separate row -->
<div class="row mb-1">
<div class="col">
<select #outboundPattern formControlName="pattern" id="additionalOutboundPattern{{i}}"
name="additionalOutboundPattern{{i}}"
required>
<option value="">{{ 'ldn-new-service.form.label.placeholder.outboundPattern' | translate }}</option>
<option *ngFor="let pattern of outboundPatterns"
[value]="pattern">{{ 'ldn-service.form.pattern.' + pattern + '.label' | translate }}</option>
</select>
<div *ngIf="!patternSelected()" class="error-text">
{{ 'ldn-new-service.form.error.patterns' | translate }}
</div>
</div>
<div class="col">
<ng-container *ngIf="outboundPattern.value">
<select formControlName="constraint" id="constraint{{i}}" name="constraint{{i}}">
<option value="">{{ 'ldn-new-service.form.label.placeholder.selectedItemFilter' | translate }}</option>
<option *ngFor="let itemFilter of (itemfiltersRD$ | async)?.payload?.page"
[value]="itemFilter.id">{{ itemFilter.id }}</option>
</select>
</ng-container>
</div>
<div [style.visibility]="'hidden'" class="col-sm1">
<input hidden id="automatic{{i}}" name="automatic{{i}}" type="checkbox">
<div
class="toggle-switch">
<div class="slider"></div>
</div>
</div>
<div class="col-sm-1">
<button (click)="removeOutboundPattern(i)" class="btn btn-outline-dark trash-button">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</ng-container>
</div>
<span (click)="addOutboundPattern()"
class="add-pattern-link mb-4">{{ 'ldn-new-service.form.label.addPattern' | translate }}
</span>
<div aria-label="Basic example" class="submission-form-footer mt-1 mb-1 position-sticky" role="group">
<button class="btn btn-primary" type="submit">
<span><i class="fas fa-save"></i> {{ 'ldn-new-service.form.label.submit' | translate }}</span>
</button>
<div class="d-flex">
<button (click)="this.openResetFormModal(this.resetFormModal)" class="btn btn-danger" type="button">
<span><i class="fas fa-trash"></i> {{ 'submission.general.discard.submit' | translate }}</span>
</button>
</div>
</div>
</form>
</div> </div>
<ng-template #confirmModal> <ng-template #confirmModal>
<div> <div>
<div class="modal-header"> <div class="modal-header">
<div> <div>
<h4>{{'service.overview.create.modal' | translate }}</h4> <h4>{{'service.overview.create.modal' | translate }}</h4>
</div> </div>
<button (click)="closeModal()" aria-label="Close" <button (click)="closeModal()" aria-label="Close"
class="close" type="button"> class="close" type="button">
<span aria-hidden="true">×</span> <span aria-hidden="true">×</span>
</button> </button>
</div>
<div class="modal-body">
<div>
{{ 'service.create.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="btn btn-danger"
id="delete-confirm">{{ 'service.refuse.create' | translate }}
</button>
<button (click)="createService()"
class="btn btn-primary mr-2 custom-btn">{{ 'service.confirm.create' | translate }}
</button>
</div>
</div>
</div> </div>
<div class="modal-body">
<div>
{{ 'service.create.body' | translate }}
</div>
<div class="mt-4">
<button (click)="closeModal()" class="btn btn-danger"
id="delete-confirm">{{ 'service.refuse.create' | translate }}
</button>
<button (click)="createService()"
class="btn btn-primary mr-2 custom-btn">{{ 'service.confirm.create' | translate }}
</button>
</div>
</div>
</div>
</ng-template> </ng-template>
<ng-template #resetFormModal> <ng-template #resetFormModal>
<div> <div>
<div class="modal-header"> <div class="modal-header">
<div> <div>
<h4>{{'service.create.reset-form.modal' | translate }}</h4> <h4>{{'service.create.reset-form.modal' | translate }}</h4>
</div> </div>
<button (click)="closeModal()" aria-label="Close" <button (click)="closeModal()" aria-label="Close"
class="close" type="button"> class="close" type="button">
<span aria-hidden="true">×</span> <span aria-hidden="true">×</span>
</button> </button>
</div>
<div class="modal-body">
<div>
{{ 'service.create.reset-form.body' | translate }}
</div>
<div class="mt-4">
<button (click)="resetFormAndLeave()"
class="btn btn-primary mr-2 custom-btn"
id="reset-confirm">{{ 'service.overview.reset-form.reset-return' | translate }}
</button>
<button (click)="closeModal()" class="btn btn-danger"
id="reset-delete">{{ 'service.overview.reset-form.reset-confirm' | translate }}
</button>
</div>
</div>
</div> </div>
<div class="modal-body">
<div>
{{ 'service.create.reset-form.body' | translate }}
</div>
<div class="mt-4">
<button (click)="resetFormAndLeave()"
class="btn btn-primary mr-2 custom-btn"
id="reset-confirm">{{ 'service.overview.reset-form.reset-return' | translate }}
</button>
<button (click)="closeModal()" class="btn btn-danger"
id="reset-delete">{{ 'service.overview.reset-form.reset-confirm' | translate }}
</button>
</div>
</div>
</div>
</ng-template> </ng-template>

View File

@@ -1,8 +1,6 @@
form { form {
max-width: 800px;
font-size: 14px; font-size: 14px;
position: relative; position: relative;
} }
input[type="text"], input[type="text"],
@@ -49,6 +47,12 @@ textarea {
color: #000000; color: #000000;
} }
.error-text {
color: red;
font-size: 0.8em;
margin-top: 5px;
}
.toggle-switch { .toggle-switch {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -58,6 +58,7 @@ export class LdnServiceFormComponent implements OnInit {
@Input() public name: string; @Input() public name: string;
@Input() public description: string; @Input() public description: string;
@Input() public url: string; @Input() public url: string;
@Input() public score: string;
@Input() public ldnUrl: string; @Input() public ldnUrl: string;
@Input() public inboundPattern: string; @Input() public inboundPattern: string;
@Input() public outboundPattern: string; @Input() public outboundPattern: string;
@@ -67,6 +68,9 @@ export class LdnServiceFormComponent implements OnInit {
@Output() submitForm: EventEmitter<any> = new EventEmitter(); @Output() submitForm: EventEmitter<any> = new EventEmitter();
@Output() cancelForm: EventEmitter<any> = new EventEmitter(); @Output() cancelForm: EventEmitter<any> = new EventEmitter();
private modalRef: any; private modalRef: any;
hasInboundPattern: boolean;
hasOutboundPattern: boolean;
isScoreValid: boolean;
constructor( constructor(
private ldnServicesService: LdnServicesService, private ldnServicesService: LdnServicesService,
@@ -85,6 +89,7 @@ export class LdnServiceFormComponent implements OnInit {
name: ['', Validators.required], name: ['', Validators.required],
description: [''], description: [''],
url: ['', Validators.required], url: ['', Validators.required],
score: ['', [Validators.required, Validators.pattern('^0*(\.[0-9]+)?$|^1(\.0+)?$')]],
ldnUrl: ['', Validators.required], ldnUrl: ['', Validators.required],
inboundPattern: [''], inboundPattern: [''],
outboundPattern: [''], outboundPattern: [''],
@@ -119,14 +124,21 @@ export class LdnServiceFormComponent implements OnInit {
createService() { createService() {
this.formModel.get('name').markAsTouched(); this.formModel.get('name').markAsTouched();
this.formModel.get('score').markAsTouched();
this.formModel.get('url').markAsTouched(); this.formModel.get('url').markAsTouched();
this.formModel.get('ldnUrl').markAsTouched(); this.formModel.get('ldnUrl').markAsTouched();
this.formModel.get('notifyServiceInboundPatterns').markAsTouched();
this.formModel.get('notifyServiceOutboundPatterns').markAsTouched();
const name = this.formModel.get('name').value; const name = this.formModel.get('name').value;
const url = this.formModel.get('url').value; const url = this.formModel.get('url').value;
const score = this.formModel.get('score').value;
const ldnUrl = this.formModel.get('ldnUrl').value; const ldnUrl = this.formModel.get('ldnUrl').value;
if (!name || !url || !ldnUrl) { const hasInboundPattern = this.checkPatterns(this.formModel.get('notifyServiceInboundPatterns') as FormArray);
const hasOutboundPattern = this.checkPatterns(this.formModel.get('notifyServiceOutboundPatterns') as FormArray);
if (!name || !url || !ldnUrl || !score || (!hasInboundPattern && !hasOutboundPattern)) {
this.closeModal(); this.closeModal();
return; return;
} }
@@ -144,15 +156,26 @@ export class LdnServiceFormComponent implements OnInit {
if (rd.hasSucceeded) { if (rd.hasSucceeded) {
this.notificationsService.success(this.translateService.get('ldn-service-notification.created.success.title'), this.notificationsService.success(this.translateService.get('ldn-service-notification.created.success.title'),
this.translateService.get('ldn-service-notification.created.success.body')); this.translateService.get('ldn-service-notification.created.success.body'));
this.sendBack(); this.sendBack();
this.closeModal(); this.closeModal();
} else { } else {
this.notificationsService.error(this.translateService.get('notification.created.failure')); this.notificationsService.error(this.translateService.get('ldn-service-notification.created.failure.title'),
this.translateService.get('ldn-service-notification.created.failure.body'));
this.closeModal();
} }
}); });
} }
checkPatterns(formArray: FormArray): boolean {
for (let i = 0; i < formArray.length; i++) {
const pattern = formArray.at(i).get('pattern').value;
if (pattern) {
return true;
}
}
return false;
}
resetFormAndLeave() { resetFormAndLeave() {
this.sendBack(); this.sendBack();
@@ -191,6 +214,22 @@ export class LdnServiceFormComponent implements OnInit {
} }
} }
patternSelected(): boolean {
for (let pattern of this.formModel.get('notifyServiceInboundPatterns').value) {
if (pattern.pattern !== '') {
return true;
}
}
for (let pattern of this.formModel.get('notifyServiceOutboundPatterns').value) {
if (pattern.pattern !== '') {
return true;
}
}
return false;
}
private sendBack() { private sendBack() {
this.router.navigateByUrl('admin/ldn/services'); this.router.navigateByUrl('admin/ldn/services');
} }

View File

@@ -32,6 +32,9 @@ export class LdnService extends CacheableObject {
@autoserialize @autoserialize
url: string; url: string;
@autoserialize
score: number;
@autoserialize @autoserialize
enabled: boolean; enabled: boolean;

View File

@@ -941,6 +941,12 @@
"ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected", "ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected",
"ldn-new-service.form.label.ItemFilter": "Item Filter", "ldn-new-service.form.label.ItemFilter": "Item Filter",
"ldn-new-service.form.label.automatic": "Automatic", "ldn-new-service.form.label.automatic": "Automatic",
"ldn-new-service.form.error.name": "Name is required",
"ldn-new-service.form.error.url": "URL is required",
"ldn-new-service.form.error.ldnurl": "LDN URL is required",
"ldn-new-service.form.error.patterns": "At least a pattern is required",
"ldn-new-service.form.error.score": "Please enter a valid score (between 0 and 1). Use the “.” as decimal separator",
"ldn-new-service.form.label.outboundPattern": "Outbound Patterns", "ldn-new-service.form.label.outboundPattern": "Outbound Patterns",
"ldn-new-service.form.label.placeholder.outboundPattern": "Select an Outbound Pattern", "ldn-new-service.form.label.placeholder.outboundPattern": "Select an Outbound Pattern",
"ldn-new-service.form.label.addPattern": "+ Add more", "ldn-new-service.form.label.addPattern": "+ Add more",