argos/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor...

341 lines
20 KiB
HTML

<div class="container-fluid description-template-editor" id="main-content">
<div id="header-outer-wrapper" *ngIf="formGroup">
<div class="row">
<div class="col-12 d-flex" id="title-column">
<div style="padding-left: 2em;">
<h3 *ngIf="isNew == true && isClone == false && isNewVersion == false">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE' | translate}}</h3>
<h3 *ngIf="isNew == false && isClone == true && isNewVersion == false">
<span *ngIf="isClone">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE-CLONE' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
<h3 *ngIf="isNew == false && isClone == false && isNewVersion == true">
<span *ngIf="isNewVersion">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE-VERSION' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
<h3 *ngIf="!isNew">{{formGroup.get('label').value}}</h3>
</div>
<ng-container *ngTemplateOutlet="actions"></ng-container>
</div>
</div>
<div class="row stepper-navigation-outer-wrapper">
<!-- Steps Navigation -->
<div id="stepper-navigation-wrapper">
<div class="col-12 d-flex" *ngIf="steps" id="stepper-navigation">
<div class="col-7 bg-white" style="overflow: hidden; padding: 0px" id="progress-container">
<div id="progress" [ngStyle]="progressStyle"></div>
<div class="row h-100 progress-min-height">
<div class="col text-center align-self-center" *ngFor="let step of steps; index as idx">
<span (click)="stepper.selectedIndex=idx" class="stepper-title-label" [ngClass]="{'stepper-title-label-locked': !isStepUnlocked(idx),'stepper-title-label-completed':idx < stepper.selectedIndex} ">
<ng-container *ngIf="(step.completed &&(idx!=steps.length-1)) else numberLabel">
<mat-icon style="font-size:0.7em; height: 0px;">done</mat-icon>
</ng-container>
<ng-template #numberLabel>
{{idx+1}}
</ng-template>
{{step.label}}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<mat-horizontal-stepper [linear]="true" #stepper class="stepper" (selectionChange)="onMatStepperSelectionChange($event)" style="padding-left: 8px; padding-right: 15px;">
<!-- IMPORTANT TO BE !INVALID (WHEN THE TEMPLATE IS FINALIZED THE CONTORLS ARE DISABLED) -->
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate" [completed]="(!formGroup.get('label').invalid && !formGroup.get('description').invalid && !formGroup.get('language').invalid)">
<!-- <ng-template matStepLabel>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
</ng-template> -->
<div class="col-9">
<div class="col">
<div class="col-12">
<div class="heading">1.1 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<input matInput [formControl]="formGroup.get('label')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.DATASET-TITLE' | translate}}">
<mat-error *ngIf="formGroup.get('label').hasError('backendError')">{{formGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<div class="heading">1.2 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION'| translate}} *</div>
<!-- <div class="hint">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div> -->
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-HINT'| translate}}</div>
<div class="full-width basic-info-input">
<rich-text-editor-component [form]="formGroup.get('description')" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER'" [wrapperClasses]="(formGroup.get('description').touched && formGroup.get('description').hasError('required')) ? 'required' : ''" [editable]="formGroup.controls['description'].status !== 'DISABLED'">
</rich-text-editor-component>
<div [class]="(formGroup.get('description').touched && formGroup.get('description').hasError('required')) ? 'visible' : 'invisible'" class="mat-form-field formGroup-field-subscript-wrapper">
<mat-error>{{'GENERAL.VALIDATION.REQUIRED'| translate}}</mat-error>
<mat-error *ngIf="formGroup.get('description').hasError('backendError')">{{formGroup.get('description').getError('backendError').message}}</mat-error>
</div>
</div>
</div>
<div class="col-12">
<div class="heading">1.3 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-TYPE'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-TYPE-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}</mat-label>
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('type')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}" [configuration]="descriptionTemplateTypeService.singleAutocompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('type').hasError('backendError')">{{formGroup.get('type').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<!-- <div class="heading">1.4 {{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}</div> -->
<div class="heading">1.4 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<!-- <input matInput formControlName="description" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required> -->
<mat-select [formControl]="formGroup.get('language')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-SELECT-LANGUAGE'| translate}}">
<mat-option *ngFor="let lang of availableLanguages" [value]="lang.code">
{{ lang.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('language').hasError('backendError')">{{formGroup.get('language').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('language').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<div class="heading">1.5 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}</div>
<div class="full-width basic-info-input">
<table class="col-12 user-table">
<thead class="user-table-header">
<tr>
<th>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.USERS.NAME' | translate}}</th>
<th>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.USERS.ROLE' | translate}}</th>
<th></th>
</tr>
</thead>
<tbody class="user-table-body">
<tr *ngFor="let user of formGroup?.get('users')?.controls; let i=index;" class="user-table-row">
<td>{{usersMap.get(user?.get('userId')?.value)?.name}}</td>
<td>{{enumUtils.toUserDescriptionTemplateRoleString(user?.get('role')?.value)}}</td>
<td>
<button [disabled]="formGroup.disabled" mat-button class="delete-btn" (click)="verifyAndRemoveUser(i)" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate"><mat-icon>person_remove</mat-icon></button>
</td>
</tr>
<tr *ngIf="formGroup.get('users')?.controls?.length === 0">
<td style="text-align: end; line-height: 3em;" colspan="2">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-12">
<div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;">
<div style="min-width: 20em;max-width: 25em;">
<!-- <mat-form-field>
<input matInput #email placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</mat-form-field> -->
<mat-form-field class="full-width basic-info-input">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS' | translate}}</mat-label>
<app-single-auto-complete [disabled]="formGroup.disabled" [required]="false" [formControl]="userFormControl" (optionSelected)="addUser($event)" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS' | translate}}" [configuration]="userService.singleAutocompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
<!-- <div class="col-auto">
<button mat-mini-fab color="primary" (click)="addUser(email)" (focus)="onUserButtonFocus()" (blur)="onUserButtonBlur()" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate" [disabled]="userFormDisabled">
<ng-container *ngIf="inputUserState === 'untriggered' else triggericon">
<mat-icon>add</mat-icon>
</ng-container>
<ng-template #triggericon>
<mat-icon>person_add</mat-icon>
</ng-template>
</button>
</div> -->
</div>
</div>
</div>
<!-- <div class="col-12">
<button mat-button class="full-width" (click)="addPage()"
[disabled]="viewOnly">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.NEXT' | translate}}</button>
</div> -->
</div>
</mat-step>
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TITLE' | translate" [completed]="formGroup.valid">
<div class="row">
<!-- TABLE -->
<div class="col-3">
<div class="row sticky-top table-container" style="top : 7em;">
<description-template-table-of-contents class="toc-pane-container col" style="margin-bottom: 2em;"
[links]="toCEntries"
(itemClick)="displayItem($event)"
(createEntry)="addNewEntry($event)"
(removeEntry)="onRemoveEntry($event)"
[itemSelected]="selectedTocEntry"
[viewOnly]="formGroup.disabled"
(dataNeedsRefresh)="onDataNeedsRefresh($event)"
[colorizeInvalid]="colorizeInvalid">
</description-template-table-of-contents>
</div>
</div>
<!-- DISPLAYER -->
<div class="col ml-3">
<div class="row">
<div class="col">
<div class="col-12" *ngIf="selectedTocEntry">
<div class="col-12 content-displayer page-infos" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page" [@fade-in-fast]>
<formGroup [formGroup]="selectedTocEntry.form">
<div class="row">
<div class="col-12">
<div class="heading">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME' | translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME-HINT' | translate}}</div>
<mat-form-field>
<input type="text" matInput formControlName="title" [placeholder]="('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) +' '+ ('DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE' |translate)">
<mat-error *ngIf="selectedTocEntry.form.get('title').hasError('backendError')">{{selectedTocEntry.form.get('title').getError('backendError').message}}</mat-error>
<mat-error *ngIf="selectedTocEntry.form.get('title').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12" *ngIf="!viewOnly && (!selectedTocEntry?.subEntries?.length)">
<button class="create-section-btn" (click)="addNewEntry({parent:selectedTocEntry, childType: tocEntryEnumValues.Section})">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.CREATE-SECTION' | translate}}</button>
</div>
</div>
</formGroup>
</div>
<div class="col-12" *ngIf="(selectedTocEntry.type === tocEntryEnumValues.Section) || (selectedTocEntry.type === tocEntryEnumValues.FieldSet)">
<app-description-template-editor-section-fieldset-component
[tocentry]="selectedTocEntry"
[viewOnly]="viewOnly"
[datasetProfileId]="datasetProfileId"
[validationErrorModel]="editorModel.validationErrorModel"
[validationRootPath]="selectedTocEntry.validationRootPath"
(addNewFieldSet)="addNewEntry({childType: tocEntryEnumValues.FieldSet,parent: {formGroup: $event}})" (removeFieldSet)="onRemoveEntry(_findTocEntryById($event, toCEntries))" (cloneFieldSet)="cloneFieldSet($event)" (selectedEntryId)="displayItem(_findTocEntryById($event, toCEntries))" (dataNeedsRefresh)="onDataNeedsRefresh()"
>
</app-description-template-editor-section-fieldset-component>
</div>
</div>
<div class="content-displayer row justify-content-center" *ngIf="!numOfPages" style="min-height: 30em;">
<div class="col-auto align-self-center">
<div class="row w-100 justify-content-center">
<div class="col-auto">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.NOTHING-HERE-HINT'| translate}}
<p *ngIf="formGroup.get('definition').get('pages').dirty && formGroup.get('definition').get('pages').hasError('required')">{{'DMP-BLUEPRINT-EDITOR.FIELDS-REQUIRED' | translate}}</p>
<p *ngIf="formGroup.get('definition').get('pages').hasError('backendError')">{{formGroup.get('definition').get('pages').getError('backendError').message}}</p>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto d-flex aling-contents-center">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-START'| translate}}
<mat-icon color="accent" style="font-size: 1.5em; text-align: center; width: 1.5em;">add</mat-icon>
<strong style="cursor: pointer;" (click)="addNewEntry({childType: tocEntryEnumValues.Page,parent: null})">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-END'| translate}}
</strong>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</mat-step>
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.PREVIEW-AND-FINALIZE' | translate">
<ng-container *ngIf="formGroup">
<div class="col-9">
<div class="col">
<div class="col-12">
<app-final-preview-component [formGroup]="formGroup" [visibilityRules]="visibilityRules">
</app-final-preview-component>
</div>
</div>
</div>
</ng-container>
</mat-step>
</mat-horizontal-stepper>
<a class="scroll-on-top d-flex flex-column align-items-center" (click)="scrollOnTop()" [@scroll-on-top-btn] [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.BACK-TO-TOP'| translate">
<mat-icon>
arrow_upward
</mat-icon>
<div>SCROLL</div>
</a>
<ng-container *ngIf="steps && stepper">
<div class="floating-btn">
<button *ngIf="stepper?.selectedIndex > 0" [@previous_btn] mat-button class="navigate-btn" (click)="stepper?.previous()">
<mat-icon class="back-icon pointer">chevron_left</mat-icon>
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.PREVIOUS' | translate}}
</button>
<button *ngIf="stepper?.selectedIndex < (steps.length-1)" mat-button class="navigate-btn ml-3" [@next_btn] (click)="validateStep(stepper?.selectedIndex);stepper?.next();" [ngClass]="{'navigate-btn-disabled': !isStepCompleted(stepper?.selectedIndex)}">
<span>{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.NEXT' | translate}}</span>
<mat-icon class="back-icon pointer">chevron_right</mat-icon>
</button>
</div>
</ng-container>
</div>
<ng-template #actions>
<div>
<button mat-raised-button class="template_action_btn mr-3" (click)="cancel()">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.CLOSE' | translate}}</button>
<!-- <button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" [disabled]="!formGroup.valid" mat-raised-button class="template_action_btn save-btn" type="button"> -->
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" mat-raised-button class="template_action_btn save-btn" type="button">
<span class="d-flex flex-row row">
<span (click)="save(); formSubmit()" class="col">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE' | translate}}</span>
<mat-divider [vertical]="true"></mat-divider>
<span class="align-items-center justify-content-center mw-100 col-4 d-flex" (click)="$event.stopPropagation();" [matMenuTriggerFor]="menuSave">
<mat-icon>expand_more</mat-icon>
</span>
</span>
</button>
<mat-menu #menuSave="matMenu">
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit()" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
</mat-menu>
<!-- <button *ngIf="formGroup.disabled || formGroup.get('status').value==1" [@finalize_btn] mat-raised-button class="template_action_btn save-btn" [disabled]="!formGroup.valid" (click)="updateAndFinalize()">
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE' |translate}}
<mat-icon (click)="$event.stopPropagation();" style="width: 14px;" [matMenuTriggerFor]="menuUpdate">expand_more</mat-icon>
</button> -->
<!-- <button *ngIf="formGroup.disabled || formGroup.get('status').value==1" [@finalize_btn] mat-raised-button class="template_action_btn save-btn" (click)="formSubmit()">
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE' | translate}}
<mat-icon (click)="$event.stopPropagation();" style="width: 14px;" [matMenuTriggerFor]="menuUpdate">expand_more</mat-icon>
</button> -->
<!-- <mat-menu #menuUpdate="matMenu">
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize()" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE-AND-CONTINUE' | translate }}</button>
</mat-menu> -->
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!= finalized && steps?.length-1 === stepper?.selectedIndex" [@finalize_btn] mat-button class="finalize-btn ml-3" [disabled]="!formGroup.valid" [class.invisible]="steps?.length-1 !== stepper?.selectedIndex" (click)="finalize()">
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FINALIZE' | translate}}
</button>
</div>
</ng-template>