Redesign dataset profile editor changes. Basic UI outline and functionality.

This commit is contained in:
Kristian Ntavidi 2021-02-12 13:23:39 +02:00
parent 8a9277f0e6
commit 35eb42e631
31 changed files with 1927 additions and 352 deletions

View File

@ -45,6 +45,7 @@ import { NgxDropzoneModule } from 'ngx-dropzone';
import { ParseStatus } from './listing/pipe/parse-status.pipe';
import { DatasetProfileTableOfContents } from './table-of-contents/table-of-contents';
import { DatasetProfileTableOfContentsInternalSection } from './table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
@NgModule({
imports: [
@ -98,7 +99,8 @@ import { DatasetProfileTableOfContentsInternalSection } from './table-of-content
],
entryComponents: [
DialogConfirmationUploadDatasetProfiles
]
],
providers:[VisibilityRulesService]
})
export class DatasetProfileModule { }

View File

@ -1,11 +1,17 @@
<div class="row">
<!-- TO LINK -->
<!-- <div class="row">
<h4 *ngIf="isComposite" class="col-auto titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.TITLE' | translate}}</h4>
<h4 *ngIf="!isComposite" class="col-auto titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.SIMPLE-FIELD-TITLE' | translate}}</h4>
<mat-checkbox class="col-auto" [(ngModel)]="isComposite" (ngModelChange)="onIsCompositeChange(isComposite)" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMPOSITE-CHECKBOX' | translate}}</mat-checkbox>
<mat-checkbox class="col-auto" [(ngModel)]="isMultiplicityEnabled" (ngModelChange)="onIsMultiplicityEnabledChange(isMultiplicityEnabled)"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-CHECKBOX' | translate}}</mat-checkbox>
<mat-checkbox class="col" [formControl]="this.form.get('hasCommentField')">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-CHECKBOX' | translate}}</mat-checkbox>
</div>
</div> -->
<!-- TO LINK -->
<!--
<div class="row">
<mat-form-field *ngIf="isComposite" class="col">
<input matInput type="string" placeholder="Id" [formControl]="form.get('id')" required>
@ -36,48 +42,204 @@
<input matInput type="number" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ORDER' | translate}}"
[formControl]="this.form.get('ordinal')" required>
</mat-form-field>
</div> -->
<!-- ID TOP RIGHT CORNER -->
<div class="field-id-container">
{{this.form.get('id').value}}
<button mat-mini-fab class="field-id-container-icon">
<mat-icon>delete</mat-icon>
</button>
</div>
<div class="row">
<mat-form-field class="col">
<textarea matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}"
[formControl]="this.form.get('description')"></textarea>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col">
<textarea matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}"
[formControl]="this.form.get('extendedDescription')"></textarea>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col">
<textarea matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}"
[formControl]="this.form.get('additionalInformation')"></textarea>
</mat-form-field>
</div>
<div class="row">
<app-dataset-profile-editor-field-component class="col-12" *ngIf="!isComposite" [form]="form.get('fields').get(''+0)" [showOrdinal]="false"
[indexPath]="indexPath + 'f' + 0" [viewOnly]="viewOnly"></app-dataset-profile-editor-field-component>
</div>
<div *ngIf="isComposite" class="row">
<h4 class="col-12 titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.SUB-FIELDS-TITLE' | translate}}
</h4>
<div class="col-12">
<mat-expansion-panel *ngFor="let field of form.get('fields')['controls'] let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title class="cardTitle">{{i + 1}}. {{getFieldTile(field, i)}}</mat-panel-title>
<div class="row">
<button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteField(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
<!-- MAIN CONTENT -->
<div class="main-content-page">
<div style="position: relative; padding: 3em 0em;" class="col-9">
<!-- TITLE -->
<div class="row">
<div class="col-auto d-flex">
<div class="align-self-center">
{{numbering}}
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 'f' + i}}" *ngIf="panel.expanded">
<app-dataset-profile-editor-field-component [form]="form.get('fields').get(''+i)" [indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"></app-dataset-profile-editor-field-component>
</div>
</mat-expansion-panel>
<mat-form-field class="col" appearance="none">
<input matInput type="text" placeholder="Title"
[formControl]="this.form.get('title')">
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}"
[formControl]="this.form.get('description')">
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}"
[formControl]="this.form.get('extendedDescription')"/>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}"
[formControl]="this.form.get('additionalInformation')"/>
</mat-form-field>
</div>
<div class="row">
<mat-form-field *ngIf="isMultiplicityEnabled" class="col" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MIN' | translate}}"
type="number" [formControl]="form.get('multiplicity').get('min')" required>
<mat-error *ngIf="form.get('multiplicity').get('min').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field *ngIf="isMultiplicityEnabled" class="col" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MAX' | translate}}"
type="number" [formControl]="this.form.get('multiplicity').get('max')" required>
<mat-error *ngIf="form.get('multiplicity').get('max').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
</div>
</div>
<div class="col-12">
<button mat-button class="full-width" (click)="addNewField()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.ACTIONS.ADD-CHILD-FIELD' | translate}}</button>
<!-- FIELDS DETAILS AND ACTIONS -->
<div class="row">
<!-- FIELDS -->
<div class="col">
<div class="">
<ng-container *ngFor="let field of form.get('fields')['controls']; let i=index">
<div class="row field-container" style="position: relative;" (click)="setTargetField(field)"
[ngClass]="{'field-container-active': field.get('id').value === targetField?.get('id').value}">
<div class="field-id-container">
{{form.get('fields').get(''+i).get('id').value}}
<!-- <button mat-mini-fab class="field-id-container-icon" (click)="DeleteField(i)">
<mat-icon>delete</mat-icon>
</button> -->
</div>
<!-- *ngIf="!isComposite" -->
<app-dataset-profile-editor-field-component class="col-12"
[form]="form.get('fields').get(''+i)" [showOrdinal]="false"
[indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"
[expandView]="targetField?.get('id').value === field.get('id').value">
</app-dataset-profile-editor-field-component>
</div>
</ng-container>
<!--
<div *ngIf="isComposite" class="row">
<h4 class="col-12 titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.SUB-FIELDS-TITLE' | translate}}
</h4>
<div class="col-12">
<mat-expansion-panel *ngFor="let field of form.get('fields')['controls'] let i=index;" #panel class="field-container">
<div class="field-id-container">
random id
</div>
<mat-expansion-panel-header>
<mat-panel-title class="cardTitle">{{i + 1}}. {{getFieldTile(field, i)}}</mat-panel-title>
<div class="row">
<button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteField(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 'f' + i}}" *ngIf="panel.expanded">
<app-dataset-profile-editor-field-component [form]="form.get('fields').get(''+i)" [indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"></app-dataset-profile-editor-field-component>
</div>
</mat-expansion-panel>
</div>
<div class="col-12">
<button mat-button class="full-width" (click)="addNewField()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.ACTIONS.ADD-CHILD-FIELD' | translate}}</button>
</div>
</div> -->
</div>
</div>
<!-- ACTIONS LIST -->
<div class="col-auto">
<div class="row" class="actions-list">
<mat-list role="list">
<!-- INPUT TOOLS -->
<h3 matSubheader>Input tools</h3>
<!-- Add new Input -->
<mat-list-item *ngIf="!viewOnly">
<mat-icon matListIcon>folder</mat-icon>
<span matLine (click)="addNewField()" style="cursor: pointer;" >Add Input</span>
</mat-list-item>
<!-- Visibility -->
<mat-list-item *ngIf="targetField && !viewOnly">
<mat-icon matListIcon [ngClass]="{'text-muted':!targetField.get('viewStyle').get('renderStyle').value}"
>visibility_off</mat-icon>
<button matLine class="mat-button" (click)="addVisibilityRule(targetField)" [disabled]="!targetField.get('viewStyle').get('renderStyle').value">
<span>Add Visibility Rule</span>
</button>
</mat-list-item>
<!-- INPUT SETTINGS -->
<h3 matSubheader>Input settings</h3>
<!-- multiplicity -->
<mat-list-item>
<!-- <mat-icon matListIcon>folder</mat-icon> -->
<mat-checkbox matLine [(ngModel)]="isMultiplicityEnabled" (ngModelChange)="onIsMultiplicityEnabledChange(isMultiplicityEnabled)" [disabled]="viewOnly ||!targetField?.get('viewStyle').get('renderStyle').value">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-CHECKBOX' | translate}}
</mat-checkbox>
</mat-list-item>
<!-- Include Comment -->
<mat-list-item>
<mat-checkbox matLine [formControl]="this.form.get('hasCommentField')" [disabled]="viewOnly ||!targetField?.get('viewStyle').get('renderStyle').value">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-CHECKBOX' | translate}}
</mat-checkbox>
</mat-list-item>
<!-- Required -->
<mat-list-item *ngIf="targetField &&!( targetField?.get('viewStyle').get('renderStyle').value ==viewStyleEnum.CheckBox )">
<!-- <mat-icon matListIcon>folder</mat-icon> -->
<mat-checkbox matLine [checked]="targetField.get('validations').value?.includes(validationTypeEnum.Required)" (change)="toggleRequired(targetField, $event)">Make it required</mat-checkbox>
<!-- <span (click)="toggleRequired(targetField)"></span> -->
</mat-list-item>
<!-- OTHER ACTIONS -->
<h3 matSubheader>Other actions</h3>
<!-- <mat-list-item> -->
<!-- <mat-icon matListIcon>folder</mat-icon> -->
<!-- <mat-checkbox [(ngModel)]="isComposite" (ngModelChange)="onIsCompositeChange(isComposite)" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMPOSITE-CHECKBOX' | translate}}</mat-checkbox>
</mat-list-item> -->
<mat-list-item *ngIf="targetField">
<mat-icon matListIcon>delete</mat-icon>
<span matLine (click)="deleteTargetField()" style="cursor: pointer;">Delete</span>
</mat-list-item>
</mat-list>
</div>
</div>
</div>
</div>
<!--
<span>Preview</span>
<app-form-composite-field [form]="previewForm" *ngIf="previewForm">
</app-form-composite-field> -->
Current FORM: {{this.form.value |json}}
<br>
Target: {{this.targetField?.value |json}}
<!--
<button (click)="generatePreview()">Generate preview</button>
-->

View File

@ -8,4 +8,55 @@
.titleStile{
font-weight: bold;
}
//REFACTOR SECTION
//Palete
$blue-color : #129D99;
$blue-color-light: #5cf7f2;
.actions-list{
border-radius: 7px;
box-shadow: 0 1px 0.8em $blue-color;
padding: 1em 0em;
font-size: small;
}
.field-container{
box-shadow: 0px 1px 2px rgb(173, 173, 173) ;
padding: 3em;
border-radius: .3em;
border-left: 0.3em solid yellow;
padding-bottom: 2em;
margin-bottom: 2em;
}
.field-container-active{
box-shadow: 0px 1px 2px rgb(173, 173, 173) ;
padding: 3em;
border-radius: .3em;
border-left: 0.3em solid $blue-color;
padding-bottom: 2em;
margin-bottom: 2em;
}
.field-id-container{
background-color: $blue-color-light;
position: absolute;
right: 0;
top: 0;
padding: .6em 1.2em;
overflow: visible;
.field-id-container-icon{
position: absolute;
top: -50%;
}
}
.main-content-page{
padding: 1.5em;
}

View File

@ -1,24 +1,37 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { FieldEditorModel } from '../../../admin/field-editor-model';
import { Guid } from '@common/types/guid';
import { RuleEditorModel } from '../../../admin/rule-editor-model';
import { ValidationType } from '@app/core/common/enum/validation-type';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { DatasetDescriptionCompositeFieldEditorModel, DatasetDescriptionFieldEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
@Component({
selector: 'app-dataset-profile-editor-composite-field-component',
templateUrl: './dataset-profile-editor-composite-field.component.html',
styleUrls: ['./dataset-profile-editor-composite-field.component.scss']
})
export class DatasetProfileEditorCompositeFieldComponent implements OnInit {
export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnChanges {
@Input() form: FormGroup;
@Input() indexPath: string;
@Input() viewOnly: boolean;
isComposite = false;
@Input() numbering: string;
previewForm: FormGroup;
// isComposite = false;
isMultiplicityEnabled = false;
viewStyleEnum = DatasetProfileFieldViewStyle;
constructor() { }
ngOnChanges(){
this.setTargetField(null);
}
ngOnInit() {
//this.addNewField();
if (this.form.get('multiplicity')) {
@ -26,11 +39,55 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit {
this.isMultiplicityEnabled = true;
}
}
this.isComposite = (this.form.get('fields') as FormArray).length > 1;
// this.isComposite = (this.form.get('fields') as FormArray).length > 1;
if (this.viewOnly) {
this.form.get('hasCommentField').disable();
}
//SET UP TARGET FIELD
if((this.form.get('fields') as FormArray).length>0){
//get the first field in list
this.targetField = (this.form.get('fields') as FormArray).at(0) as FormGroup;
}
}
generatePreview(){
const editorModel = new DatasetDescriptionCompositeFieldEditorModel();
editorModel.title = this.form.get('title').value;
editorModel.description = this.form.get('description').value;
editorModel.extendedDescription = this.form.get('extendedDescription').value;
editorModel.additionalInformation = this.form.get('additionalInformation').value;
editorModel.hasCommentField = this.form.get('hasCommentField').value;
editorModel.fields = [];
(this.form.get('fields') as FormArray).controls.forEach(field=>{
const fieldEditorModel = new DatasetDescriptionFieldEditorModel();
fieldEditorModel.viewStyle= {
renderStyle: field.get('viewStyle').get('renderStyle').value,
cssClass: null
};
fieldEditorModel.defaultValue = field.get('defaultValue').value;
switch (field.get('viewStyle').get('renderStyle').value) {
case DatasetProfileFieldViewStyle.TextArea:
fieldEditorModel.data = {
label: field.get('data').get('label').value
};
break;
default:
break;
}
editorModel.fields.push(fieldEditorModel);
});
this.previewForm = editorModel.buildForm();
}
onIsCompositeChange(isComposite: boolean) {
@ -67,4 +124,70 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit {
if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
return "Field " + (index + 1);
}
targetField:FormGroup;
validationTypeEnum = ValidationType;
addVisibilityRule(targetField: FormGroup){
const rule: RuleEditorModel = new RuleEditorModel();
(<FormArray>targetField.get('visible').get('rules')).push(rule.buildForm());
}
toggleRequired(targetField: FormGroup, event:MatCheckboxChange){
let validationsControl = targetField.get('validations') as FormControl;
let validations: Array<ValidationType> = validationsControl.value;
if(event.checked){
if(!validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
// validationsControl.updateValueAndValidity();
validations.push(ValidationType.Required);
// validationsControl.setValue(validations);
validationsControl.updateValueAndValidity();
}
}else{
validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
validationsControl.updateValueAndValidity();
}
// if(validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
// validationsControl.updateValueAndValidity();
// }else{
// //SET REQUIRED VALIDATOR
// console.log('setting required validator');
// validations.push(ValidationType.Required);
// validationsControl.setValue(validations);
// validationsControl.updateValueAndValidity();
// }
}
setTargetField(field:FormGroup){
this.targetField = field;
}
deleteTargetField(){
if(!this.targetField) return;
let index = -1;
const fields = this.form.get('fields') as FormArray;
for(let i=0;i< fields.length; i++){
let field = fields.at(i);
if(field.get('id').value === this.targetField.get('id').value){//index found
index = i;
break;
}
}
if(index>=0){//target found in fields
this.DeleteField(index);
this.targetField = null;
}
}
}

View File

@ -1,6 +1,7 @@
<div class="row">
<!-- BooleanDecision -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.BooleanDecision">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder" [required]="required">
<mat-option [value]="null">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' |
translate}}</mat-option>
@ -16,6 +17,7 @@
<!-- CheckBox -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.CheckBox">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder" [required]="required">
<mat-option [value]="'true'">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | translate}}</mat-option>
<mat-option [value]="'false'">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' | translate}}</mat-option>
@ -25,9 +27,11 @@
<!-- ComboBox -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.ComboBox && comboBoxType === comboBoxTypeEnum.Autocomplete">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
</mat-form-field>
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.ComboBox && comboBoxType === comboBoxTypeEnum.WordList">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder" [required]="required">
<mat-option [value]="null">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate }}</mat-option>
<mat-option *ngFor="let opt of formArrayOptions['controls']" [value]="opt.get('value').value">{{opt.get('label').value}}</mat-option>
@ -37,23 +41,28 @@
<!-- InternalDmpEntities -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.InternalDmpEntities && internalDmpEntitiesType === internalDmpEntitiesTypeEnum.Researchers">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
</mat-form-field>
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.InternalDmpEntities && internalDmpEntitiesType === internalDmpEntitiesTypeEnum.Datasets">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
</mat-form-field>
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.InternalDmpEntities && internalDmpEntitiesType === internalDmpEntitiesTypeEnum.Dmps">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
</mat-form-field>
<!-- FreeText -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.FreeText">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- RadioBox -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.RadioBox">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder" [required]="required">
<mat-option [value]="null">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}}</mat-option>
<mat-option *ngFor="let opt of formArrayOptions['controls']" [value]="opt.get('value').value">{{opt.get('label').value}}</mat-option>
@ -63,6 +72,7 @@
<!-- TextArea -->
<mat-form-field class="col-md-12" *ngIf="viewStyle === viewStyleEnum.TextArea">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form" [required]="required">
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
@ -70,6 +80,7 @@
<!-- DatePicker -->
<mat-form-field class="col-12" *ngIf="viewStyle === viewStyleEnum.DatePicker">
<!--(focus)="date.open()" (click)="date.open()"-->
<mat-label>{{placeHolder}}</mat-label>
<input matInput [placeholder]="placeHolder" class="table-input" [matDatepicker]="date" [formControl]="form" [required]="required">
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date></mat-datepicker>

View File

@ -1,10 +1,13 @@
<ng-container *ngIf="expandView">
<div class="row">
<mat-form-field class="col">
<!-- <mat-form-field class="col">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.ID' | translate}}" type="text" [formControl]="this.form.get('id')"
required>
<mat-error *ngIf="this.form.get('id').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="this.form.get('id').hasError('pattern')">{{'GENERAL.VALIDATION.PATTERN-_' | translate}}</mat-error>
</mat-form-field>
</mat-form-field> -->
<mat-form-field class="col">
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.VIEW-STYLE' | translate}}" [formControl]="this.form.get('viewStyle').get('renderStyle')"
@ -44,12 +47,12 @@
</app-component-profile-editor-default-value-component>
<!-- Validation -->
<mat-form-field class="col" *ngIf="!(defaulValueRequired(form.get('viewStyle').get('renderStyle').value))">
<!-- <mat-form-field class="col" *ngIf="!(defaulValueRequired(form.get('viewStyle').get('renderStyle').value))">
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.VALIDATION' | translate}}" [formControl]="this.form.get('validations')"
multiple>
<mat-option [value]="validationTypeEnum.Required">{{enumUtils.toDatasetProfileFieldValidationTypeString(validationTypeEnum.Required)}}</mat-option>
</mat-select>
</mat-form-field>
</mat-form-field> -->
<mat-form-field class="col">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.RDA-COMMON-STANDARDS' | translate}}</mat-label>
@ -62,7 +65,7 @@
</mat-form-field>
</div>
<div class="row" [ngSwitch]="form.get('viewStyle').get('renderStyle').value">
<div class="row" [ngSwitch]="form.get('viewStyle').get('renderStyle').value" *ngIf="expandView">
<app-dataset-profile-editor-combo-box-field-component *ngSwitchCase="viewStyleEnum.ComboBox" class="col-12" [form]="form"></app-dataset-profile-editor-combo-box-field-component>
<app-dataset-profile-internal-dmp-entities-field-component *ngSwitchCase="viewStyleEnum.InternalDmpEntities" class="col-12" [form]="form"></app-dataset-profile-internal-dmp-entities-field-component>
<app-dataset-profile-editor-radio-box-field-component *ngSwitchCase="viewStyleEnum.RadioBox" class="col-12" [form]="form"></app-dataset-profile-editor-radio-box-field-component>
@ -85,13 +88,50 @@
<app-dataset-profile-editor-currency-field-component *ngSwitchCase="viewStyleEnum.Currency" class="col-12" [form]="form"></app-dataset-profile-editor-currency-field-component>
<app-dataset-profile-editor-validator-field-component *ngSwitchCase="viewStyleEnum.Validation" class="col-12" [form]="form"></app-dataset-profile-editor-validator-field-component>
</div>
<div class="row">
<h4 class="col-12" style="font-weight: bold">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}}
</h4>
<app-dataset-profile-editor-rule-component class="col-12" [form]="form.get('visible').get('rules')" [viewStyleForCheck]="form.get('viewStyle').get('renderStyle').value"
[formArrayOptionsForCheck]="this.form.get('data')?.get('options')" [comboBoxTypeForCheck]="this.form.get('data')?.get('type')?.value"
[viewOnly]="viewOnly"></app-dataset-profile-editor-rule-component>
<div class="col-12" *ngIf="!viewOnly">
<button mat-button class="full-width" (click)="addNewRule()" [disabled]="!form.get('viewStyle').get('renderStyle').value">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ACTIONS.ADD-RULE' | translate}}</button>
</div>
<div class="row" *ngIf="this.form.get('viewStyle').get('renderStyle').value">
<ng-container *ngIf="form.get('visible').get('rules')?.value.length">
<h4 class="col-12" style="font-weight: bold">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}}
</h4>
<app-dataset-profile-editor-rule-component class="col-12" [form]="form.get('visible').get('rules')" [viewStyleForCheck]="form.get('viewStyle').get('renderStyle').value"
[formArrayOptionsForCheck]="this.form.get('data')?.get('options')" [comboBoxTypeForCheck]="this.form.get('data')?.get('type')?.value"
[viewOnly]="viewOnly"
[formControlForCheck]="form"></app-dataset-profile-editor-rule-component>
<!-- <div class="col-12" *ngIf="!viewOnly">
<button mat-button class="full-width" (click)="addNewRule()" [disabled]="!form.get('viewStyle').get('renderStyle').value">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ACTIONS.ADD-RULE' | translate}}</button>
</div> -->
</ng-container>
<!-- <div class="row">
<button (click)="generatePreview()">Generate Preview</button>
</div> -->
</div>
</ng-container>
<ng-container>
<div class="row">
<div class="col-12">
<span style="font-weight: bold">Preview</span>
</div>
<!-- <div class="col-12">
<mat-radio-group [(ngModel)]="showPreview">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</mat-radio-group>
</div> -->
<div class="col-12">
<app-form-field [form]="previewForm" *ngIf="previewForm">
</app-form-field>
</div>
<div class="col-12" *ngIf="!previewForm">
<em>
Not initialized yet
</em>
</div>
</div>
</ng-container>

View File

@ -1,3 +1,14 @@
.full-width {
width: 100%;
}
.preview-box{
padding: 1em;
border: 1px solid #e8dcdc;
border-radius: 0.3em;
}
mat-radio-button{
padding-right: 1em;
}

View File

@ -1,5 +1,5 @@

import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
import { ValidationType } from '@app/core/common/enum/validation-type';
@ -27,13 +27,15 @@ import { DatasetIdentifierDataEditorModel } from '../../../admin/field-data/data
import { ExternalDatasetsDataEditorModel } from '../../../admin/field-data/external-datasets-data-editor-models';
import { CurrencyDataEditorModel } from '../../../admin/field-data/currency-data-editor-models';
import { ValidationDataEditorModel } from '../../../admin/field-data/validation-data-editor-models';
import { DatasetDescriptionFieldEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-dataset-profile-editor-field-component',
templateUrl: './dataset-profile-editor-field.component.html',
styleUrls: ['./dataset-profile-editor-field.component.scss']
})
export class DatasetProfileEditorFieldComponent extends BaseComponent implements OnInit {
export class DatasetProfileEditorFieldComponent extends BaseComponent implements OnInit,OnChanges {
@Input() viewOnly: boolean;
@Input() form: FormGroup;
@Input() showOrdinal = true;
@ -42,13 +44,18 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
viewStyleEnum = DatasetProfileFieldViewStyle;
isFieldMultiplicityEnabled = false;
@Input() expandView: boolean = true;
constructor(
public enumUtils: EnumUtils,
public datasetProfileService: DatasetProfileService
) { super(); }
ngOnChanges(changes: SimpleChanges): void {
this.generatePreviewForm();
}
ngOnInit() {
this.showPreview = true;
if (this.form.get('multiplicity')) {
if (this.form.get('multiplicity').value.min > 1 && this.form.get('multiplicity').value.max > 1) {
this.isFieldMultiplicityEnabled = true;
@ -59,6 +66,12 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
this.form.get('viewStyle').get('renderStyle').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => {
// const previewStatus = this.showPreview;
//!! Important to be before the if statement
this.showPreview = false;
if (this.form.get('data')) {
this.form.removeControl('data');
@ -119,6 +132,11 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
break;
}
}
//reset the preview status
// this.showPreview = previewStatus;
this.showPreview = true;
});
}
@ -162,4 +180,84 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
const rule: RuleEditorModel = new RuleEditorModel();
(<FormArray>this.form.get('visible').get('rules')).push(rule.buildForm());
}
private _formChangesSubscription:Subscription;
private _showPreview: boolean = false;;
get showPreview(): boolean{
return this._showPreview;
}
set showPreview(value:boolean){
if(value == false){//hide preview
//close subsciption
if(this._formChangesSubscription){
this._formChangesSubscription.unsubscribe();
this._formChangesSubscription = null;
}
}
if(value == true){
this._formChangesSubscription = this.form.valueChanges.subscribe(()=>{
this.generatePreviewForm();
});
//initialize
if(this.form.get('viewStyle').get('renderStyle').value){
this.generatePreviewForm();
}
}
this._showPreview = value;
}
previewForm: FormGroup;
generatePreviewForm(){
this.previewForm = null;
// this._showPreview = false;
const fieldEditorModel = new DatasetDescriptionFieldEditorModel();
fieldEditorModel.viewStyle= {
renderStyle: this.form.get('viewStyle').get('renderStyle').value,
cssClass: null
};
fieldEditorModel.data = this.form.get('data').value;
fieldEditorModel.value = this.form.get('defaultValue').get('value').value;
fieldEditorModel.validationRequired = (this.form.get('validations').value as Array<ValidationType>).includes(ValidationType.Required);
if(this.form.get('viewStyle').get('renderStyle').value == DatasetProfileFieldViewStyle.CheckBox){
fieldEditorModel.value = this.form.get('defaultValue').get('value').value === 'true';
}
this.previewForm = fieldEditorModel.buildForm();
// this._showPreview = true;
};
// generatePreview(){
// const fieldEditorModel = new DatasetDescriptionFieldEditorModel();
// fieldEditorModel.viewStyle= {
// renderStyle: this.form.get('viewStyle').get('renderStyle').value,
// cssClass: null
// };
// fieldEditorModel.defaultValue = this.form.get('defaultValue').value;
// switch (this.form.get('viewStyle').get('renderStyle').value) {
// case DatasetProfileFieldViewStyle.TextArea:
// fieldEditorModel.data = {
// label: this.form.get('data').get('label').value
// };
// break;
// default:
// break;
// }
// // this.previewForm = fieldEditorModel.buildForm();
// }
}

View File

@ -10,15 +10,79 @@
<span class="col-auto">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.RULE.FIELDS.RULE-THEN'| translate}}</span>
<!-- Field Or Section ID -->
<mat-form-field class="col-auto">
<!-- <mat-form-field class="col-auto">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.RULE.FIELDS.TARGET' | translate}}"
formControlName="target" (change)="targetValidation()" required>
<mat-error>{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
-->
<!-- SELECTION -->
<mat-form-field class="col-auto">
<mat-label>Pick one</mat-label>
<mat-select formControlName="target" required>
<!-- SHOW SECTIONS -->
<mat-optgroup label="Sections">
<mat-option *ngFor="let option of sectionOptions" [value]="option.id" style="line-height: normal;"
[disabled]="parentIds.includes(option.id)">
<span>
{{option.label? option.label:'<'+ ('DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) + '>'}}
</span> <br>
<small>
{{option.id}}
</small>
</mat-option>
</mat-optgroup>
<!-- SHOW FIELDSETS -->
<mat-optgroup label="Fieldsets">
<mat-option *ngFor="let option of fieldSetOptions" [value]="option.id" style="line-height: normal;"
[disabled]="parentIds.includes(option.id)">
<span>
{{option.label? option.label:'<'+ ('DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) + '>'}}
</span> <br>
<small>
{{option.id}}
</small>
</mat-option>
</mat-optgroup>
<!-- SHOW FIELDS -->
<mat-optgroup label="Fields">
<mat-option *ngFor="let option of fieldOptions" [value]="option.id" style="line-height: normal;"
[disabled]="parentIds.includes(option.id)">
<span>
{{option.label? option.label:'<'+ ('DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) + '>'}}
</span> <br>
<small>
{{option.id}}
</small>
</mat-option>
</mat-optgroup>
</mat-select>
<mat-error>{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<div class="col-auto"><button mat-icon-button type="button" (click)="deleteRule(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<!--
{{parentIds |json}}
<br>
{{this.formControlForCheck.value | json}} -->
<!--
<ng-template #optionTemplate>
<span>
{{option.label? option.label: '< Not Set> '}}
</span> <br>
<small>
{{option.id}}
</small>
</ng-template> -->

View File

@ -1,7 +1,8 @@
import { Component, Input } from '@angular/core';
import { FormArray, FormControl } from '@angular/forms';
import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { DatasetProfileFieldViewStyle } from '../../../../../../core/common/enum/dataset-profile-field-view-style';
import { DatasetProfileComboBoxType } from '../../../../../../core/common/enum/dataset-profile-combo-box-type';
import { ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';
@Component({
selector: 'app-dataset-profile-editor-rule-component',
@ -9,21 +10,132 @@ import { DatasetProfileComboBoxType } from '../../../../../../core/common/enum/d
styleUrls: ['./dataset-profile-editor-rule.component.scss']
})
export class DatasetProfileEditorRuleComponent {
export class DatasetProfileEditorRuleComponent implements OnInit{
@Input() form: FormArray;
@Input() viewStyleForCheck: DatasetProfileFieldViewStyle;
@Input() formControlForCheck: FormControl;
@Input() formArrayOptionsForCheck: FormArray;
@Input() comboBoxTypeForCheck: DatasetProfileComboBoxType;
@Input() viewOnly: boolean;
targetValidation() {
//TODO
}
deleteRule(index) {
this.form.removeAt(index);
}
ngOnInit(): void {
this.options = this.getOptions();
this.sectionOptions = [];
this.fieldOptions = [];
this.fieldSetOptions = [];
this.options.forEach(option=>{
switch (option.type) {
case ToCEntryType.Field:
this.fieldOptions.push(option);
break;
case ToCEntryType.FieldSet:
this.fieldSetOptions.push(option);
break;
case ToCEntryType.Section:
this.sectionOptions.push(option);
break;
default:
break;
}
});
}
options: OptionItem[];
sectionOptions: OptionItem[];
fieldSetOptions: OptionItem[];
fieldOptions: OptionItem[];
getOptions():OptionItem[]{
const rootForm = this.form.root;
if(rootForm){
// const parentSections = rootForm.get('sections') as FormArray;
const result:OptionItem[] =[];
const sections = rootForm.get('sections') as FormArray;
if(sections){
sections.controls.forEach(section=>{
const subResult = this.buildOptions(section as FormGroup, ToCEntryType.Section,[]);
result.push(...subResult);
});
}
//return options
return result;
}
//nothing found
return [];
}
private buildOptions(form: FormGroup, type: ToCEntryType, parentIds:string[]):OptionItem[]{
const sections = form.get('sections') as FormArray;
const fieldSets = form.get('fieldSets') as FormArray;
const fields = form.get('fields') as FormArray;
const result:OptionItem[] = [];
parentIds.push(form.get('id').value);
result.push({
id: form.get('id').value,
type: type,
label: type ===ToCEntryType.Field? form.get('data').get('label').value :form.get('title').value,
// parentsIds: [form.get('id').value]
parentsIds: [...parentIds]
});
if(sections){
sections.controls.forEach(section=>{
result.push( ...this.buildOptions(section as FormGroup, ToCEntryType.Section,parentIds) );
});
}
if(fieldSets){
fieldSets.controls.forEach(fieldset=>{
result.push( ...this.buildOptions(fieldset as FormGroup, ToCEntryType.FieldSet, parentIds) );
});
}
if(fields){
fields.controls.forEach(field=>{
result.push( ...this.buildOptions(field as FormGroup, ToCEntryType.Field, parentIds) ); //TODO NA TO DOUME
});
}
return result;
}
get parentIds(): string[]{
if(!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);
if(current){
return current.parentsIds;
}
return [];
}
}
interface OptionItem{
id: string,
label: string,
type: ToCEntryType,
parentsIds: string[]
}

View File

@ -1,31 +1,40 @@
<div [formGroup]="form" class="row dataset-profile-editor">
<h4 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.TITLE' | translate}}</h4>
<!-- <h4 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.TITLE' | translate}}</h4> -->
<!-- <div class="heading col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.TITLE' | translate}}</div> -->
<mat-form-field class="col-md-3">
<!-- <mat-form-field class="col-md-3">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.ID' | translate}}"
formControlName="id" required>
formControlName="id" required>
<mat-error *ngIf="form.get('id').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="form.get('id').hasError('pattern')">{{'GENERAL.VALIDATION.PATTERN-_' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-3">
</mat-form-field> -->
<div class="heading col-12">{{'DATASET-PROFILE-EDITOR.STEPS.SECTION-INFO.SECTION-NAME' | translate}} *</div>
<div class="hint col-12">{{'DATASET-PROFILE-EDITOR.STEPS.SECTION-INFO.SECTION-NAME-HINT' | translate}}</div>
<mat-form-field class="col-12">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.TITLE' | translate}}"
formControlName="title">
</mat-form-field>
<mat-form-field class="col-md-3">
<!-- <mat-form-field class="col-md-3">
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.PAGE' | translate}}" formControlName="page"
required>
<mat-option *ngFor="let pageGroup of form.root.get('pages')['controls'];" [value]="pageGroup.get('id').value">{{pageGroup.get('title').value}}</mat-option>
</mat-select>
<mat-error *ngIf="form.get('page').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-3">
</mat-form-field> -->
<!-- <mat-form-field class="col-md-3">
<input matInput type="number" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.ORDER' | translate}}"
formControlName="ordinal">
</mat-form-field>
<mat-form-field class="col-md-12">
</mat-form-field> -->
<div class="heading col-12">{{'DATASET-PROFILE-EDITOR.STEPS.SECTION-INFO.SECTION-DESCRIPTION' | translate}} *</div>
<div class="hint col-12">{{'DATASET-PROFILE-EDITOR.STEPS.SECTION-INFO.SECTION-DESCRIPTION-HINT' | translate}}</div>
<mat-form-field class="col-12">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.DESCRIPTION' | translate}}"
formControlName="description">
</mat-form-field>
<!-- <div class="col-md-6">
<label>Default Visibility</label>
<mat-radio-group formControlName="defaultVisibility" class="full-width">
@ -50,15 +59,21 @@
<div class="col-12"><button mat-button class="full-width" (click)="addField()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.ACTIONS.ADD-FIELD'
| translate}}</button></div> -->
<h4 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.SUB-SECTIONS-TITLE' |
<!-- SUBSECTIONS -->
<!-- <h4 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.SUB-SECTIONS-TITLE' |
translate}}</h4>
<div *ngIf="form.get('sections')['controls'].length > 0" class="col-12">
<mat-expansion-panel *ngFor="let sectionFormGroup of form.get('sections')['controls']; let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title>{{i + 1}}. {{form.get('sections').get(''+i).get('title').value}}</mat-panel-title>
<div class="row deleteBtn">
<div class="row deleteBtn"> -->
<!-- <span class="col">{{i + 1}}. {{form.get('sections').get(''+i).get('title').value}}</span> -->
<button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteSectionInSection(i);" [disabled]="viewOnly">
<!-- <button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteSectionInSection(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
@ -70,6 +85,6 @@
</mat-expansion-panel>
</div>
<div class="col-12"><button mat-button class="full-width" (click)="addSectioninSection()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.ACTIONS.ADD-SUB-SECTION'
| translate}}</button></div>
| translate}}</button></div> -->
</div>

View File

@ -6,3 +6,24 @@
.deleteBtn{
margin-right:2em;
}
.heading {
text-align: left;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-top: 1.625rem;
margin-bottom: 0.625rem;
}
.hint {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-bottom: 0.125rem;
}

View File

@ -1,4 +1,4 @@
<div class="main-content">
<div class="main-content" style="max-width:1500px">
<div class="container-fluid dataset-profile-editor" *ngIf="form" [formGroup]='form'>
<h3 *ngIf="isNew && !isClone && !isNewVersion">{{'DATASET-PROFILE-EDITOR.TITLE.NEW-PROFILE' | translate}}</h3>
<h3 *ngIf="isNew && isClone">
@ -16,45 +16,99 @@
<button mat-raised-button color="primary" (click)="downloadXML();" type="button">{{
'DATASET-WIZARD.ACTIONS.DOWNLOAD-XML' | translate }}</button>
</div>
<mat-horizontal-stepper [linear]="true" #stepper>
<!-- Total steps: {{stepper.steps.length}} -->
<!-- Steps Navigation -->
<div class="row" style="padding: 2em;">
<div class="col-7 bg-white" style="overflow: hidden; padding: 0px" id="progress-container">
<div id="progress" [ngStyle]="{'transform': 'translateX('+barPercentageA+'%) skewX(-25deg)'}"></div>
<div class="row p-1">
<div class="col text-center" >
<span (click)="stepper.selectedIndex=0" style="cursor: pointer">
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
</span>
</div>
<div class="col text-center">
<span (click)="stepper.selectedIndex=1" style="cursor: pointer">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.TITLE' | translate}}
</span>
</div>
<div class="col text-center text-muted">
<span style="cursor: pointer">
Preview and Finalize
</span>
</div>
</div>
</div>
<div class="col d-flex justify-content-end">
<button mat-button class="navigate-btn" (click)="stepper.previous()">
Previous
</button>
<button mat-button class="navigate-btn ml-2" (click)="stepper.next()">
Next
</button>
</div>
</div>
<mat-horizontal-stepper [linear]="true" #stepper class="stepper" (selectionChange)="onStepperSelectionChange($event)">
<mat-step>
<ng-template matStepLabel>{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
</ng-template>
<div class="row">
<mat-form-field class="full-width">
<input matInput formControlName="label"
placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-TITLE' | translate}}" required>
<mat-error *ngIf="form.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' |
translate}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<input matInput formControlName="description"
placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required>
<mat-error *ngIf="form.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED'
| translate}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<!-- <input matInput formControlName="description" placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required> -->
<mat-select formControlName="language">
<mat-option *ngFor="let lang of getLanguageInfos()" [value]="lang.code">
{{ lang.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="form.get('language').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' |
translate}}
</mat-error>
</mat-form-field>
<div class="col-12">
<div class="heading">1.1 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME'| translate}} *</div>
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME-HINT'| translate}}</div>
<mat-form-field class="full-width">
<input matInput formControlName="label"
placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-TITLE' | translate}}" required>
<mat-error *ngIf="form.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' |
translate}}
</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<div class="heading">1.2 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION'| translate}} *</div>
<!-- <div class="hint">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div> -->
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-HINT'| translate}}</div>
<mat-form-field class="full-width">
<textarea matInput formControlName="description" cdkTextareaAutosize cdkAutosizeMinRows="3" cdkAutosizeMaxRows="5"
placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required>
</textarea>
<mat-error *ngIf="form.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED'
| translate}}
</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<!-- <div class="heading">1.3 {{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}</div> -->
<div class="heading">1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}}</div>
<mat-form-field class="full-width">
<!-- <input matInput formControlName="description" placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required> -->
<mat-select formControlName="language">
<mat-option *ngFor="let lang of getLanguageInfos()" [value]="lang.code">
{{ lang.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="form.get('language').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' |
translate}}
</mat-error>
</mat-form-field>
</div>
<!-- <div class="col-12">
<button mat-button class="full-width" (click)="addPage()"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.ACTIONS.NEXT' | translate}}</button>
</div>
</div> -->
</div>
</mat-step>
<mat-step>
<!-- <mat-step>
<ng-template matStepLabel>{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.TITLE' | translate}}</ng-template>
<div class="row">
<app-dataset-profile-editor-page-component class="col-12" [form]="form.get('pages')"
@ -64,31 +118,75 @@
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.ACTIONS.ADD-PAGE' | translate}}</button>
</div>
</div>
</mat-step>
</mat-step> -->
<mat-step>
<ng-template matStepLabel>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.TITLE' | translate}}</ng-template>
<div class="row">
<div class="col-6">
<dataset-profile-table-of-contents class="toc-pane-container" [links]="getTocEntries()"
(stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)"
(itemClick)="displayItem($event)"></dataset-profile-table-of-contents>
</div>
<div class="col-6">
<div class="row" *ngIf="selectedTocEntry">
<div class="col-12" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page">
<!-- TABLE -->
<div class="col-3">
<dataset-profile-table-of-contents class="toc-pane-container"
[links]="getTocEntries()"
(stepFound)="onStepFound($event)"
(currentLinks)="getLinks($event)"
(itemClick)="displayItem($event)"
(newEntry)="addNewEntry($event)"
(createEntry) = "addNewEntry($event)"
(removeEntry)="onRemoveEntry($event)"
[itemSelected]="selectedTocEntry">
</dataset-profile-table-of-contents>
</div>
<!-- DISPLAYER -->
<div class="col">
<div class="row content-displayer" *ngIf="selectedTocEntry">
<!-- PAGE INFO -->
<div class="col-12" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page">
<form [formGroup]="selectedTocEntry.form">
<div class="row">
<!-- PAGE NAME -->
<div class="col">
<div class="heading">{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME' | translate}} *</div>
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME-HINT' | translate}}</div>
<mat-form-field>
<input type="text" matInput formControlName="title">
</mat-form-field>
</div>
<!-- PAGE ID -->
<!-- <div class="col">
<div class="heading">Page id *</div>
<mat-form-field>
<input type="text" matInput formControlName="id">
</mat-form-field>
</div> -->
</div>
<!-- <div class="row">
<div class="col">
<div class="heading">Ordinal *</div>
<mat-form-field>
<input type="text" matInput formControlName="ordinal">
</mat-form-field>
</div>
</div> -->
</form>
</div>
<app-dataset-profile-editor-section-component class="col-12"
<!-- SECTION INFO -->
<app-dataset-profile-editor-section-component class="col-12"
*ngIf="selectedTocEntry.type === tocEntryEnumValues.Section"
[form]="selectedTocEntry.form" [indexPath]="'tbd'" [viewOnly]="viewOnly">
[form]="selectedTocEntry.form" [indexPath]="'tbd'" [viewOnly]="viewOnly"
>
</app-dataset-profile-editor-section-component>
<!-- FIELDSET INFO -->
<div class="col-12" *ngIf="selectedTocEntry.type === tocEntryEnumValues.FieldSet">
<h4 style="font-weight: bold" class="col-12">
<!-- <h4 style="font-weight: bold" class="col-12">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.FIELDS.FIELDS-TITLE' |
translate}}</h4>
<div class="col-12">
translate}}</h4> -->
<!-- <div class="col-12"> -->
<!-- <mat-card-title class="col">{{i + 1}}. {{getFieldTile(fieldControl, i)}}
</mat-card-title> -->
@ -96,32 +194,33 @@
(click)="deleteFieldSet(selectedTocEntry.form, i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button> -->
<app-dataset-profile-editor-composite-field-component class="col-12"
<app-dataset-profile-editor-composite-field-component class="p-0"
[form]="selectedTocEntry.form" [indexPath]="'indexPath' + 'cf' + 'i'"
[viewOnly]="viewOnly">
[viewOnly]="viewOnly"
[numbering]="selectedTocEntry.numbering">
</app-dataset-profile-editor-composite-field-component>
</div>
<!-- </div> -->
<!-- <div class="col-12"><button mat-button class="full-width" (click)="addField()"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.SECTION.ACTIONS.ADD-FIELD'
| translate}}</button></div> -->
</div>
</div>
<!-- <app-dataset-profile-editor-section-component *ngIf="this.selectedTocEntry.type === tocEntryEnumValues.Section" class="col-12"
[form]="profileEditorConfig.form"
[indexPath]="'s' + profileEditorConfig.index"
[dataModel]="profileEditorConfig.sectionEditorModel"
[viewOnly]="viewOnly">
</app-dataset-profile-editor-section-component> -->
<div class="content-displayer row justify-content-center" *ngIf="!numOfPages">
<div class="col-auto align-self-center text-center">
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.NOTHING-HERE-HINT'| translate}}
<br>
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-START'| translate}}
<!-- <app-dataset-profile-editor-composite-field-component class="col-12"
*ngIf="profileEditorCompositeConfig"
[form]="profileEditorCompositeConfig.form"
[indexPath]="profileEditorCompositeConfig.index"
[viewOnly]="viewOnly">
</app-dataset-profile-editor-composite-field-component> -->
<strong style="cursor: pointer;" (click)="addNewEntry({childType: tocEntryEnumValues.Page,parent: null})">
<em>
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-END'| translate}}
</em>
<mat-icon color="accent">add</mat-icon>
</strong>
</div>
</div>
@ -145,48 +244,62 @@
</mat-expansion-panel>
</mat-accordion> -->
</div>
<div class="col-12">
<!-- <div class="col-12">
<button mat-button (click)="addSection()" class="full-width"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button>
</div>
</div> -->
</div>
</mat-step>
</mat-horizontal-stepper>
<div class="d-flex">
<!-- SAVE BUTTON -->
<div class="col-6 d-flex" *ngIf="!viewOnly">
<div class="row mt-4">
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='checkFormValidation()'
[disabled]="form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.VALIDATE' | translate}}</button>
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='onSubmit()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.SAVE' |
translate}}</button>
<button mat-raised-button class="col-auto" color="primary" type="button col-auto"
(click)='finalize()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.FINALIZE' |
translate}}</button>
<ng-container *ngIf="false">
<div class="d-flex">
<!-- SAVE BUTTON -->
<div class="col-6 d-flex" *ngIf="!viewOnly">
<div class="row mt-4">
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='checkFormValidation()'
[disabled]="form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.VALIDATE' | translate}}</button>
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='onSubmit()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.SAVE' |
translate}}</button>
<button mat-raised-button class="col-auto" color="primary" type="button col-auto"
(click)='finalize()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.FINALIZE' |
translate}}</button>
</div>
</div>
<!-- SAVE BUTTON WHEN FINALIZED-->
<div class="col-6 d-flex" *ngIf="showUpdateButton()">
<div class="row mt-4">
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='checkFormValidation()'
[disabled]="form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.VALIDATE' | translate}}</button>
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='updateFinalized()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.UPDATE' |
translate}}</button>
</div>
</div>
<!-- DELETE BUTTON -->
<div class="col-6 d-flex justify-content-end" *ngIf="!isNew">
<div class="row mt-4">
<button mat-raised-button color="primary" (click)="delete()">
<mat-icon>delete</mat-icon>{{'DATASET-PROFILE-EDITOR.ACTIONS.DELETE' | translate}}
</button>
</div>
</div>
</div>
<!-- SAVE BUTTON WHEN FINALIZED-->
<div class="col-6 d-flex" *ngIf="showUpdateButton()">
<div class="row mt-4">
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='checkFormValidation()'
[disabled]="form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.VALIDATE' | translate}}</button>
<button mat-raised-button class="col-auto mr-2" color="primary" type="button col-auto"
(click)='updateFinalized()' [disabled]="!form.valid">{{'DATASET-PROFILE-EDITOR.ACTIONS.UPDATE' |
translate}}</button>
</div>
</div>
<!-- DELETE BUTTON -->
<div class="col-6 d-flex justify-content-end" *ngIf="!isNew">
<div class="row mt-4">
<button mat-raised-button color="primary" (click)="delete()">
<mat-icon>delete</mat-icon>{{'DATASET-PROFILE-EDITOR.ACTIONS.DELETE' | translate}}
</button>
</div>
</div>
</div>
</ng-container>
<!-- <div class="row">
<button (click)="printForm()">
console form
</button>
</div> -->
</div>
</div>

View File

@ -9,3 +9,86 @@
.deleteBtn{
margin-right:2em;
}
// REFACTORED CSS
.stepper{
background-color: transparent;
}
.content-displayer{
background-color: #fff;
border-radius: 7px;
box-shadow: 0px 1px 2px #bfbfbf;
padding: 0em;
// padding-top: 0em;
overflow: visible;
min-height: 30em;
}
.heading {
text-align: left;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-top: 1.625rem;
margin-bottom: 0.625rem;
}
.hint {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-bottom: 0.125rem;
}
//TO CHECK
:host ::ng-deep .mat-horizontal-content-container {
overflow: visible;
}
:host ::ng-deep .mat-form-field-outline{
background-color: #ffffff4f;
}
:host ::ng-deep .mat-horizontal-stepper-header-container {
display: none !important;
}
#progress{
position: absolute;
height: 100%;
width: 110%;
transform: translateX(-110%);
transition-property: transform;
transition-duration: 600ms;
transition-timing-function: ease-out;
transition-delay: 50ms;
box-shadow: 0px 1px 2px #bfbfbf;
background-color: #f7dd72;
}
#progress-container{
box-shadow: 0px 1px 2px #bfbfbf;
border-radius: .3em;
}
// .import-btn {
// background: #ffffff 0% 0% no-repeat padding-box;
// border-radius: 30px;
// // color: #129d99;
// // border: 1px solid #129d99;
// padding-left: 2em;
// padding-right: 2em;
// color: #000;
// border: 1px solid #000;
// }
.navigate-btn {
border-radius: 30px;
background-color: #f7dd72;
padding-left: 2em;
padding-right: 2em;
}

View File

@ -1,7 +1,7 @@
import { of as observableOf, Observable } from 'rxjs';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit, ViewChild } from '@angular/core';
import { AfterViewInit, Component, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { Form, FormArray, FormControl, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatHorizontalStepper } from '@angular/material/stepper';
@ -29,8 +29,13 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { Link, LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
import { ToCEntry, ToCEntryType } from '../table-of-contents/table-of-contents-entry';
import { Foo, ToCEntry, ToCEntryType } from '../table-of-contents/table-of-contents-entry';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FieldSetEditorModel } from '../admin/field-set-editor-model';
import { Guid } from '@common/types/guid';
import { FieldEditorModel } from '../admin/field-editor-model';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
import { StepperSelectionEvent } from '@angular/cdk/stepper';
const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json');
@ -39,7 +44,7 @@ const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.
templateUrl: './dataset-profile-editor.component.html',
styleUrls: ['./dataset-profile-editor.component.scss']
})
export class DatasetProfileEditorComponent extends BaseComponent implements OnInit {
export class DatasetProfileEditorComponent extends BaseComponent implements OnInit, AfterViewInit {
isNew = true;
isNewVersion = false;
@ -59,22 +64,6 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
errorMessages: string[] = [];
tocEntryEnumValues = ToCEntryType;
profileEditorConfig: {
form: FormGroup,
index: string,
id: string,
sectionEditorModel?: SectionEditorModel
};
profileEditorCompositeConfig: {
form: FormGroup,
index: string,
id: string
};
isSectionControl: boolean = false;
// sectionIdPreviewed:string = null;
// currentSubForm:FormGroup = null;
// currentSectionIndex: number = null;
@ -92,12 +81,19 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
private httpClient: HttpClient,
private matomoService: MatomoService,
private enumUtils: EnumUtils,
private datasetWizardService: DatasetWizardService
private datasetWizardService: DatasetWizardService,
private visibilityRulesService: VisibilityRulesService
) {
super();
// this.profileID = route.snapshot.params['id'];
// this.cloneId = route.snapshot.params['cloneid'];
}
ngAfterViewInit(): void {
// setTimeout(() => {
// this.barPercentage = (1 / (this.stepper.steps.length+1)) * 110 - 110;
// }, 0);
}
ngOnInit() {
this.matomoService.trackPageView('Admin: Dataset Profile Edit');
@ -183,13 +179,15 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
this.form.disable();
this.viewOnly = true;
}
this.addSection();
this.addPage();
// this.addSection();
// this.addPage();
this.visibilityRulesService.buildVisibilityRules([],this.form);
}
});
}
prepareForm() {
this.visibilityRulesService.buildVisibilityRules([],this.form);
this.form.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(change => {
@ -519,17 +517,21 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
getTocEntries(): ToCEntry[] {
if (this.form == null) { return []; }
const result: ToCEntry[] = [];
//build parent pages
(this.form.get('pages') as FormArray).controls.forEach((pageElement, i) => {
result.push({
id: pageElement.get('id').value,
label: pageElement.get('title').value,
type: ToCEntryType.Page,
form: pageElement
form: pageElement,
numbering: (i + 1).toString(),
subEntriesType: ToCEntryType.Section
} as ToCEntry)
});
// build first level sections
(this.form.get('sections') as FormArray).controls.forEach((sectionElement, i) => {
const currentSectionPageId = sectionElement.get('page').value;
const pageToAdd = result.filter(x => x.id == currentSectionPageId)[0];
@ -540,12 +542,13 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
label: sectionElement.get('title').value,
type: ToCEntryType.Section,
form: sectionElement,
numbering: pageToAdd.numbering + '.' + i
numbering: pageToAdd.numbering + '.' + (pageToAdd.subEntries.length +1)
} as ToCEntry;
const sectionItems = this.populateSections(sectionElement.get('sections') as FormArray, item.numbering);
const fieldSetItems = this.populateFieldSets(sectionElement.get('fieldSets') as FormArray, item.numbering);
if (sectionItems != null) {
item.subEntries = sectionItems;
item.subEntriesType = ToCEntryType.Section;
}
if (fieldSetItems != null) {
if (item.subEntries == null) {
@ -553,11 +556,12 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
} else {
item.subEntries.push(...fieldSetItems);
}
item.subEntriesType = ToCEntryType.FieldSet;
}
pageToAdd.subEntries.push(item);
});
return result;
}
@ -572,12 +576,13 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
label: sectionElement.get('title').value,
type: ToCEntryType.Section,
form: sectionElement,
numbering: existingNumbering + '.' + i
numbering: existingNumbering + '.' + (i + 1)
} as ToCEntry;
const sectionItems = this.populateSections(sectionElement.get('sections') as FormArray, item.numbering);
const fieldSetItems = this.populateFieldSets(sectionElement.get('fieldSets') as FormArray, item.numbering);
if (sectionItems != null) {
item.subEntries = sectionItems;
item.subEntriesType = ToCEntryType.Section;
}
if (fieldSetItems != null) {
if (item.subEntries == null) {
@ -585,6 +590,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
} else {
item.subEntries.push(...fieldSetItems);
}
item.subEntriesType = ToCEntryType.FieldSet;
}
result.push(item);
});
@ -602,9 +608,9 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
id: fieldSetElement.get('id').value,
label: fieldSetElement.get('title').value,
type: ToCEntryType.FieldSet,
subEntries: this.populateSections((fieldSetElement.get('fieldSets') as FormArray), existingNumbering + '.' + i),
//subEntries: this.populateSections((fieldSetElement.get('fieldSets') as FormArray), existingNumbering + '.' + i),
form: fieldSetElement,
numbering: existingNumbering + '.' + i
numbering: existingNumbering + '.' + (i + 1)
} as ToCEntry)
});
@ -612,89 +618,293 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
return result;
}
addNewEntry(tce: Foo) {
const parent = tce.parent;
//define entry type
switch (tce.childType) {
case ToCEntryType.Page: //CALLED FROM PAGE
//create section
// this.addPage();
// this.displayItem(child);
//ceate page editor model and give ordinal
const page: PageEditorModel = new PageEditorModel(this.dataModel.pages.length);
this.dataModel.pages.push(page);
(<FormArray>this.form.get('pages')).push(page.buildForm());
//make new entry selected
const pagesArray = (this.form.get('pages') as FormArray);
const addedEntry = pagesArray.at(pagesArray.length-1) as FormGroup;
this.selectedTocEntry = {
form: addedEntry,
label: addedEntry.get('title').value,
type: ToCEntryType.Page,
id: addedEntry.get('id').value,
numbering:pagesArray.value.length,
subEntries:null,
subEntriesType: ToCEntryType.Section
}
break;
case ToCEntryType.Section: //adding a section
const section: SectionEditorModel = new SectionEditorModel();
//give id
section.id = Guid.create().toString();
let sectionsArray:FormArray;
if (parent.type === ToCEntryType.Page) {
//FIRST LEVEL SECTION
//give ordinal and link to parent
section.page = parent.id;
section.ordinal = (this.form.get('sections') as FormArray).length;
(<FormArray>this.form.get('sections')).push(section.buildForm());
sectionsArray = this.form.get('sections') as FormArray;
} else if( parent.type == ToCEntryType.Section) { //subsection
//adding page parent MAYBE NOT NEEDED
section.page = parent.form.get('page').value;
//MAYBE NOT NEEDED
section.ordinal = (parent.form.get('sections') as FormArray).length;
(<FormArray>parent.form.get('sections')).push(section.buildForm());
// (child.form.parent as FormArray).push(section.buildForm());
sectionsArray = parent.form.get('sections') as FormArray;
}else{
console.error('BUg found');
}
const sectionAdded = sectionsArray.at(sectionsArray.length -1) as FormGroup;
this.selectedTocEntry = {
id: sectionAdded.get('id').value,
label: sectionAdded.get('title').value,
form: sectionAdded,
numbering:'',
subEntries: null,
subEntriesType: undefined, //ADDNEW VALUE TO TOCENTRY TYPE FOR UNDFINED
type: ToCEntryType.Section
}
break;
case ToCEntryType.FieldSet:
const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
//create one field form fieldset
const field: FieldEditorModel = new FieldEditorModel(); //to ask
field.id = Guid.create().toString();
field.ordinal = fieldSet.fields.length;
fieldSet.fields.push(field);
//give fieldset id and ordinal
fieldSet.id = Guid.create().toString();
fieldSet.ordinal = (parent.form.get('fieldSets') as FormArray).length;
(<FormArray>parent.form.get('fieldSets')).push(fieldSet.buildForm());
const parentArray = parent.form.get('fieldSets') as FormArray;
const addedFieldSet = parentArray.at(parentArray.length - 1);
this.selectedTocEntry = {
id: addedFieldSet.get('id').value,
label: addedFieldSet.get('title').value,
form: addedFieldSet,
numbering: '',
subEntries: null, //TODO IT SHOULD HAVE CHILDS
subEntriesType: ToCEntryType.Field,
type: ToCEntryType.FieldSet
}
break;
default:
break;
}
}
onRemoveEntry(tce: ToCEntry) {
//define entry type
switch (tce.type) {
case ToCEntryType.Page:
const pages = this.form.get('pages') as FormArray;
let pageIndex = -1;
//get the index
for (let i = 0; i < pages.length; i++) {
let page = pages.at(i) as FormGroup;
if (page.controls.id.value === tce.id) {
pageIndex = i;
break;
}
}
if (pageIndex >= 0) {
//remove page
pages.removeAt(pageIndex);
//clean up sections of removed page
const sections = (this.form.get('sections') as FormArray).controls;
const updatedSections = new FormArray([]);
for (let i = 0; i < sections.length; i++) {
let section = sections[i];
if (section.get('page').value != tce.id) {
updatedSections.push(section);
}
}
//replace sections value
this.form.controls.sections = updatedSections;
//update page orders
for(let i=0; i<pages.length; i++){
pages.at(i).get('ordinal').patchValue(i);
}
//update validity
this.form.controls.sections.updateValueAndValidity();
}
break;
case ToCEntryType.Section:
//FIRST LEVEL SECTION CASE
let index = -1;
const sections = (this.form.get('sections') as FormArray);
for (let i = 0; i < sections.length; i++) {
let section = sections.at(i);
let sectionId = section.get('id').value;
if (sectionId == tce.id) {
index = i;
break;
}
}
if (index >= 0) { //section found
const sections = (this.form.get('sections') as FormArray);
//remove section
sections.removeAt(index);
//update ordinal
for(let i=0; i< sections.length; i++){
sections.at(i).get('ordinal').patchValue(i);
}
} else {//NOT FOUND IN FIRST LEVEL CASE
//LOOK FOR SUBSECTION CASE
let parentFormArray = tce.form.parent as FormArray;
for (let i = 0; i < parentFormArray.length; i++) {
let section = parentFormArray.at(i);
if (section.get('id').value == tce.id) {
index = i;
break;
}
}
if (index >= 0) {
parentFormArray.removeAt(index);
//update odrinal
for(let i=0; i<parentFormArray.length; i++){
parentFormArray.at(i).get('ordinal').patchValue(i);
}
}
}
break;
case ToCEntryType.FieldSet:
const parentFormArray = tce.form.parent as FormArray;
let idx = -1;
for(let i =0; i< parentFormArray.length; i++){
let inspectingField = parentFormArray.at(i);
if(inspectingField.get('id').value === tce.id){
//fieldset found
idx = i;
break;
}
}
if(idx>=0){//fieldset found
parentFormArray.removeAt(idx);
//patching order
for(let i=0; i<parentFormArray.length;i++){
parentFormArray.at(i).get('ordinal').patchValue(i);
}
}
break;
default:
break;
}
//in case selectedtocentrhy is child of the removed element
if(this.selectedTocEntry ){
//
if(this.tocEntryIsChildOf(this.selectedTocEntry,tce)){
this.selectedTocEntry = null;
}
}
}
tocEntryIsChildOf(testingChild: ToCEntry,parent: ToCEntry): boolean{
if(!testingChild || !parent) return false;
if(testingChild.id == parent.id){return true;}
if(parent.subEntries){
let childFound:boolean = false;
parent.subEntries.forEach(subEntry=>{
if(this.tocEntryIsChildOf(testingChild, subEntry)){
childFound = true;
return true;
}
})
return childFound;
}
return false;
}
selectedTocEntry: ToCEntry
displayItem(entry: ToCEntry): void {
this.selectedTocEntry = entry;
}
// console.log(this.form);
// console.log(this.dataModel);
// this.profileEditorConfig = null;
// let entry = entries[0];
// console.log(entries);
// if (entry.subEntries && (entry.subEntries.length > 0)) {// its a page
// // this.sectionIdPreviewed = entry.id;
// const valuesArray = this.form.get('sections').value;
// let currentVal = entry.id;
// let indexArray: string[] = valuesArray.map(element => element.page);
// let index = indexArray.indexOf(currentVal);
// let subForm = (this.form.get('sections') as FormArray).controls[index] as FormGroup;
// let currentEditor = this.dataModel.sections.filter(section => section.page == entry.id)[0];
// this.profileEditorConfig = {
// id: entry.id,
// form: subForm,
// index: index.toString(),
// sectionEditorModel: currentEditor
// };
// this.isSectionControl = false;
// // this.currentSubForm = subForm;
// // this.currentSectionIndex = index;
// // this.currentSectionEditorModel = currentEditor;
// // this.isCompoSiteFieldEditor = true;
// } else if (entries.length == 2) {//its section
// this.isSectionControl = true;
// const valuesArray = this.form.get('sections').value;
// let currentVal = entries[1].id // Parent node entry.id;
// let indexArray: string[] = valuesArray.map(element => element.page);
// let index = indexArray.indexOf(currentVal);
// //Section Form
// const sectionForm = (this.form.get('sections') as FormArray).controls[index] as FormGroup;
// const sectionFormControls = sectionForm.get('fieldSets')['controls'];
// const fieldSetsIds = sectionForm.get('fieldSets').value;//.map(fieldset => fieldset.id);
// // const fieldsetIndex = fieldSetsIds.indexOf(entries[0].id);
// console.log(fieldSetsIds);
// const sectionFormControl = sectionFormControls[0];
// this.profileEditorCompositeConfig = {
// id: entries[0].id,
// form: sectionFormControl,
// index: 's' + index + 'cf' + 0
// }
// }
get numOfPages(){
return (<FormArray>this.form.get('pages')).length;
}
// getSectionIndex(): number{
@ -734,4 +944,27 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
}
printForm(){
console.log(this.form.value);
}
barPercentage = -100;
onStepperSelectionChange(selectionChange: StepperSelectionEvent){
this.barPercentage = ((selectionChange.selectedIndex+1) / (this.stepper.steps.length+1)) * 110- 110;
}
get barPercentageA(){
if(!this.stepper){
return -110;
}
const selectedIndex = this.stepper.selectedIndex + 1;
return (selectedIndex / (this.stepper.steps.length+1)) * 110- 110;
}
}

View File

@ -3,6 +3,7 @@ import { AbstractControl } from "@angular/forms";
export interface ToCEntry {
id: string;
label: string;
subEntriesType: ToCEntryType;
subEntries: ToCEntry[];
type: ToCEntryType;
form: AbstractControl;
@ -13,5 +14,11 @@ export interface ToCEntry {
export enum ToCEntryType {
Page = 0,
Section = 1,
FieldSet = 2
FieldSet = 2,
Field = 3
}
export interface Foo {
childType: ToCEntryType,
parent: ToCEntry
}

View File

@ -1,5 +1,81 @@
<div *ngFor="let link of links; let i = index" class="docs-link mt-0">
<span class="link-name" (click)="itemClicked(link)"><span>{{link.numbering}}</span> <span>{{link.label}}</span></span>
<app-dataset-profile-table-of-contents-internal-section *ngIf="link.subEntries" [links]="link.subEntries"
(itemClick)="itemClicked($event)"></app-dataset-profile-table-of-contents-internal-section>
<div *ngFor="let link of links; let i = index; last as isLast " class="docs-link mt-0" style="border-left: 1px solid black; padding-left: 1em;">
<div class="link-name">
<div class="table-item">
<span style="display: inline-block; cursor: pointer;" [ngClass]="{'active': itemSelected?.id == link.id}" (click)="itemClicked(link)" >
{{link.numbering}} {{link.label? link.label : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}}
</span>
<div class="table-item-actions">
<button class="mat-button" (click)="deleteEntry(link)"><mat-icon>delete</mat-icon></button>
</div>
</div>
<!-- For dev purposes -->
<!-- <ng-container [ngSwitch]="link.type">
<div *ngSwitchCase="tocEntryType.FieldSet">
<span style="background-color: yellow;"> Fieldset</span>
</div>
<div *ngSwitchCase="tocEntryType.Page">
<span style="background-color: lightblue;"> Page</span>
</div>
<div *ngSwitchCase="tocEntryType.Section">
<span style="background-color: lightgreen;"> Section</span>
</div>
</ng-container> -->
</div>
<div class="ml-2">
<app-dataset-profile-table-of-contents-internal-section
[links]="link.subEntries"
(itemClick)="itemClicked($event)"
(removeEntry)="deleteEntry($event)"
[parentLink]="link"
[itemSelected] = "itemSelected"
(createFooEntry)="createNewEntry($event)">
</app-dataset-profile-table-of-contents-internal-section>
</div>
</div>
<!-- BUILD SUBENTRIES IF THEY DONT EXIST -- CURRENT ITEM DOES HAVE CHILDREN -->
<div *ngIf="!links && parentLink.type!= tocEntryType.FieldSet" class="docs-link mt-0" style="border: 1px solid ;">
NoEntries
<div class="ml-2">
<!-- Give option to generate section -->
<button class="mat-button" style="padding-left: 0px; display: block;" (click)="createNewEntry({childType:tocEntryType.Section,parent:parentLink})">
<mat-icon>add</mat-icon>Section
</button>
<!-- Give option to generate fieldset (only if parent is section)-->
<button *ngIf="parentLink.type == tocEntryType.Section" class="mat-button" style="padding-left: 0px;" (click)="createNewEntry({childType:tocEntryType.FieldSet,parent:parentLink})">
<mat-icon>add</mat-icon> Fieldset
</button>
</div>
</div>
<!-- BUILD TYPE OF SAME LEVEL AS LINK OF LINKS -->
<div *ngIf="links">
<button class="mat-button" style="padding-left: 0px;" (click)="createNewEntry({childType:parentLink.subEntriesType,parent:parentLink})">
<mat-icon>add</mat-icon>
<!-- Create => {{parentLink?.subEntriesType}} -->
<ng-container [ngSwitch]="parentLink?.subEntriesType">
<ng-container *ngSwitchCase="tocEntryType.Section">
Section
</ng-container>
<ng-container *ngSwitchCase="tocEntryType.Page">
Page
</ng-container>
<ng-container *ngSwitchCase="tocEntryType.FieldSet">
Fieldset
</ng-container>
</ng-container>
</button>
</div>

View File

@ -1,7 +1,7 @@
.docs-toc-container {
width: 100%;
padding: 5px 0 10px 0px;
cursor: pointer;
// cursor: pointer;
// border-left: solid 4px #0c7489;
.scroll-container {
@ -19,7 +19,8 @@
&.docs-active {
.link-name {
background-color: #ececec;
border-radius: 6px;
border-radius: 6px;
cursor: pointer;;
// color: #0c7489;
}
// color: mat-color($primary, if($is-dark-theme, 200, default));
@ -34,26 +35,26 @@
font-weight: bold;
}
span {
line-height: 16px;
margin: 6px 0 0;
position: relative;
text-decoration: none;
display: block;
overflow: hidden;
color: #21212194;
font-weight: 400;
max-width: 290px;
min-width: 290px;
padding: 0rem .4rem;
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
width: 100%;
}
}
// span {
// line-height: 16px;
// margin: 6px 0 0;
// position: relative;
// text-decoration: none;
// display: block;
// overflow: hidden;
// color: #21212194;
// font-weight: 400;
// max-width: 290px;
// min-width: 290px;
// padding: 0rem .4rem;
// span {
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
// display: inline-block;
// width: 100%;
// }
// }
.selected {
color: #212121 !important;
@ -68,3 +69,21 @@ span {
.docs-level-h5 {
margin-left: 24px;
}
.active{
font-weight: bold;
}
.table-item-actions{
// display: none;
display: inline-block;
visibility: hidden;
}
.table-item:hover {
.table-item-actions{
// display: inline-block;
visibility: visible;
}
}

View File

@ -1,8 +1,7 @@
import { DOCUMENT } from '@angular/common';
import { Component, EventEmitter, Inject, Input, OnInit, Output, SimpleChanges } from '@angular/core';
import { BaseComponent } from '@common/base/base.component';
import { ToCEntry } from '../table-of-contents-entry';
import { Foo, ToCEntry, ToCEntryType } from '../table-of-contents-entry';
@Component({
selector: 'app-dataset-profile-table-of-contents-internal-section',
@ -13,12 +12,20 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
@Input() links: ToCEntry[];
@Output() itemClick = new EventEmitter<ToCEntry>();
@Output() newEntry = new EventEmitter<ToCEntry>();
@Output() removeEntry = new EventEmitter<ToCEntry>();
@Output() createFooEntry = new EventEmitter<Foo>();
@Input() parentLink: ToCEntry;
@Input() itemSelected: ToCEntry;
constructor(
@Inject(DOCUMENT) private _document: Document) {
super();
}
tocEntryType = ToCEntryType;
ngOnInit(): void {
@ -33,8 +40,11 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
this.itemClick.emit(item);
}
// propagateClickToParent(childIds: ToCEntry[], currentItem: ToCEntry) {
// childIds.push(currentItem);
// this.itemClick.emit(childIds);
// }
deleteEntry(currentLink: ToCEntry){
this.removeEntry.emit(currentLink);
}
createNewEntry(foo: Foo){
this.createFooEntry.emit(foo);
}
}

View File

@ -1,4 +1,4 @@
<div *ngIf="links?.length > 0" class="docs-toc-container">
<div class="docs-toc-container">
<!-- <div class="docs-toc-heading">Contents</div> -->
<!-- <nav> -->
<!-- <a [href]="_rootUrl + '#' + link.id" -->
@ -6,11 +6,16 @@
<!-- <span *ngFor="let link of links; let i = index" (click)="toggle(link); goToStep(link)" class="docs-level-{{link.type}} docs-link mt-0" [class.docs-active]="link.active">
<span *ngIf="link.show" class="link-name"><span [class.selected]="link.selected && isActive">{{link.name}}</span></span>
</span> -->
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"></app-dataset-profile-table-of-contents-internal-section>
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"
(newEntry)="addNewEntry($event)" (removeEntry)="deleteEntry($event)"
(createFooEntry)="createNewEntry($event)"
[parentLink]="{ subEntriesType: tocEntryType.Page }"
[itemSelected]="itemSelected"></app-dataset-profile-table-of-contents-internal-section>
<!-- <span *ngFor="let link of links; let i = index" (click)="toggle(link); goToStep(link);" class="docs-link mt-0">
<span class="link-name" (click)="itemClicked(link)"><span>{{link.label}}</span></span>
<dataset-profile-table-of-contents *ngIf="link.subEntries" [links]="link.subEntries" (itemClick)="propagateClickToParent($event, link)"></dataset-profile-table-of-contents>
</span> -->
<!-- </nav> -->
</div>
</div>
</div>

View File

@ -1,7 +1,7 @@
.docs-toc-container {
width: 100%;
padding: 5px 0 10px 0px;
cursor: pointer;
// cursor: pointer;
// border-left: solid 4px #0c7489;
.scroll-container {

View File

@ -5,7 +5,7 @@ import { interval, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { type } from 'os';
import { SimpleChanges } from '@angular/core';
import { ToCEntry } from './table-of-contents-entry';
import { Foo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
export interface Link {
/* id of the section*/
@ -38,14 +38,24 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
@Output() currentLinks = new EventEmitter<Link[]>();
@Output() itemClick = new EventEmitter<ToCEntry>();
@Output() newEntry = new EventEmitter<ToCEntry>();
@Output() removeEntry = new EventEmitter<ToCEntry>();
@Output() createEntry = new EventEmitter<Foo>();
@Input() itemSelected: ToCEntry;
subscription: Subscription;
linksSubject: Subject<HTMLElement[]> = new Subject<HTMLElement[]>();
@Input() isActive: boolean;
show: boolean = false;
tocEntryType = ToCEntryType;
constructor(
@Inject(DOCUMENT) private _document: Document) {
super();
@ -175,6 +185,19 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
// }
addNewEntry(tce: ToCEntry){
this.newEntry.emit(tce);
}
deleteEntry(currentLink: ToCEntry){
this.removeEntry.emit(currentLink);
}
createNewEntry(foo: Foo){
this.createEntry.emit(foo);
}
}
export interface LinkToScroll {

View File

@ -32,7 +32,9 @@ import { FormProgressIndicationModule } from './components/form-progress-indicat
],
exports: [
DatasetDescriptionFormComponent,
DatasetDescriptionComponent
DatasetDescriptionComponent,
FormCompositeFieldComponent,
FormFieldComponent
],
providers: [
VisibilityRulesService,

View File

@ -280,6 +280,33 @@
"ROLES": "Roles"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Page Description",
"PAGE-PREFIX": "Page",
@ -429,9 +456,9 @@
}
},
"DMP-LISTING": {
"TITLE": "Datenmanagementpläne",
"DMP": "DMP",
"GRANT": "Grant",
"TITLE": "Data Management Plans",
"TITLE": "Datenmanagementpläne",
"OWNER": "Besitzer",
"MEMBER": "Mitglied",
"CREATOR": "Ersteller",
@ -1152,7 +1179,8 @@
"RESEARCHERS": "Researchers",
"ORGANIZATIONS": "Organizations",
"DATASET-IDENTIFIER": "Dataset Identifier",
"CURRENCY": "Currency"
"CURRENCY": "Currency",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Word List",
@ -1169,6 +1197,9 @@
"DATASETS": "Datensatzbeschreibungen",
"EXTERNAL-SOURCE-HINT": "Liste jener Werte, die von externer(n) Quelle(n) stammen"
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Created",
"LABEL": "Label",
@ -1590,4 +1621,4 @@
"FINALIZED": "Finalized",
"DELETED": "Deleted"
}
}
}

View File

@ -280,6 +280,33 @@
"ROLES": "Roles"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Page Description",
"PAGE-PREFIX": "Page",

View File

@ -280,6 +280,33 @@
"ROLES": "Funciones"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Descripición de la página",
"PAGE-PREFIX": "Página",
@ -1152,7 +1179,8 @@
"RESEARCHERS": "Investigadores",
"ORGANIZATIONS": "Organizaciones",
"DATASET-IDENTIFIER": "Identificador del dataset",
"CURRENCY": "Moneda"
"CURRENCY": "Moneda",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Lista de palabras",
@ -1169,6 +1197,9 @@
"DATASETS": "Descripciones del dataset",
"EXTERNAL-SOURCE-HINT": "Lista de valores para seleccionar la(s) fuente(s) externa(s)"
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Creado",
"LABEL": "Etiqueta",
@ -1590,4 +1621,4 @@
"FINALIZED": "Finalizado",
"DELETED": "Deleted"
}
}
}

View File

@ -280,6 +280,33 @@
"ROLES": "Ρόλοι"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Περιγραφή Σελίδας",
"PAGE-PREFIX": "Σελίδα",
@ -1152,7 +1179,8 @@
"RESEARCHERS": "Ερευνητές",
"ORGANIZATIONS": "Οργανισμοί",
"DATASET-IDENTIFIER": "Αναγνωριστικό Συνόλου Δεδομένων",
"CURRENCY": "Επικαιρότητα"
"CURRENCY": "Επικαιρότητα",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Λίστα Λέξεων",
@ -1169,6 +1197,9 @@
"DATASETS": "Περιγραφές Συνόλων Δεδομένων",
"EXTERNAL-SOURCE-HINT": "Κατάλογος τιμών που παρέχονται από εξωτερικές πηγές"
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Δημιουργημένο",
"LABEL": "Ετικέτα",
@ -1590,4 +1621,4 @@
"FINALIZED": "Οριστικοποιημένα",
"DELETED": "Deleted"
}
}
}

View File

@ -280,6 +280,33 @@
"ROLES": "Funções"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Descrição da Página",
"PAGE-PREFIX": "Página",
@ -1591,6 +1618,7 @@
"DATASET-PROFILE-STATUS": {
"NONE": "Nenhum",
"DRAFT": "Rascunho",
"FINALIZED": "Concluído"
"FINALIZED": "Concluído",
"DELETED": "Deleted"
}
}

View File

@ -280,6 +280,33 @@
"ROLES": "Role"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Opis stránky",
"PAGE-PREFIX": "Stránka",
@ -1152,7 +1179,8 @@
"RESEARCHERS": "Výskumníci (Researchers)",
"ORGANIZATIONS": "Organizácie (Organizations)",
"DATASET-IDENTIFIER": "Identifikátor súborov dát (Dataset Identifier)",
"CURRENCY": "Mena (Currency)"
"CURRENCY": "Mena (Currency)",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Zoznam slov",
@ -1169,6 +1197,9 @@
"DATASETS": "Súbory dát",
"EXTERNAL-SOURCE-HINT": "Zoznam hodnôt dodaných z externých zdrojov."
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Vytvorené",
"LABEL": "Označenie",
@ -1590,4 +1621,4 @@
"FINALIZED": "Dokončené",
"DELETED": "Deleted"
}
}
}

View File

@ -17,6 +17,7 @@
"SUCCESSFUL-LOGIN": "Uspešno ste se prijavili",
"SUCCESSFUL-LOGOUT": "Uspešno ste se odjavili",
"SUCCESSFUL-EMAIL-SEND": "Email uspešno poslat",
"SUCCESSFUL-COPY-TO-CLIPBOARD": "Copied to Clipboard",
"UNSUCCESSFUL-LOGOUT": "Neuspešno odjavljivanje",
"UNSUCCESSFUL-LOGIN": "Neuspešno prijavljivanje",
"SUCCESSFUL-DATASET-PROFILE-DELETE": "Uspešno brisanje",
@ -84,7 +85,8 @@
"PRODUCED": "izrađen",
"RDA-SPECIFICATIONS": "prema RDA specifikacijama",
"MACHINE-ACTIONABLE": "za mašinski čitljive Planove",
"UPLOAD-FILE": "Uvezite datoteku"
"UPLOAD-FILE": "Uvezite datoteku",
"REPLACE-FILE": "Replace File"
},
"INVITATION-DIALOG": {
"HINT": "Za razdvajanje autora koristite tastere zapeta \",\" ili \"Enter\"",
@ -277,7 +279,34 @@
"DATASET-DESCRIPTION": "Opis",
"ROLES": "Uloge"
},
"STEPS": {
"STEPS":
{"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Opis stranice",
"PAGE-PREFIX": "Stranica",
@ -471,6 +500,7 @@
"START-NEW-VERSION": "Započnite novu verziju",
"VIEW-VERSION": "Sve verzije Plana",
"CLONE": "Napravite kopiju",
"COPY": "Copy",
"DELETE": "Obrišite",
"DEPOSIT": "Deponujte",
"EXPORT": "Izvezite",
@ -657,7 +687,8 @@
"NEW": "Novi skup podataka",
"CREATE-NEW": "Kreirajte novi skup podataka",
"EXPORT": "Izvezite",
"INVITE-COLLABORATORS": "Pozovite saradnike"
"INVITE-COLLABORATORS": "Pozovite saradnike",
"INVITE-SHORT": "Invite"
},
"STATES": {
"EDITED": "Izmenjeno",
@ -990,7 +1021,8 @@
},
"USERS": {
"LABEL": "Pretražite",
"ROLE": "Uloga"
"ROLE": "Uloga",
"SHOW": "Show"
},
"SELECT": "Odaberite opciju",
"LIKE": "Pretražite"
@ -999,7 +1031,8 @@
"TITLE": {
"NEW": "Novi plan upravljanja podacima",
"EDIT": "Uredite",
"INTRO": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) se sastoji od Vaših planova za upravljanje podacima i sadrži informacije kako su nastali, kako su analizirani i na koji način su sačuvani podaci. Argos je otvoren kolaboracioni alat sa mogućnošću nadogradnje koji podržava otvorene i FAIR principe za upravljanje podacima."
"INTRO": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) se sastoji od Vaših planova za upravljanje podacima i sadrži informacije kako su nastali, kako su analizirani i na koji način su sačuvani podaci. Argos je otvoren kolaboracioni alat sa mogućnošću nadogradnje koji podržava otvorene i FAIR principe za upravljanje podacima.",
"INTRO-TIP": "Tip: Add new datasets to describe different types of data or disciplinary data to avoid mixing information."
},
"FIELDS": {
"NAME": "Naziv skupa podataka",
@ -1032,6 +1065,7 @@
"EXTERNAL-LINK": "Dodajte spoljni URL link"
},
"HINT": {
"DESCRIPTION": "Briefly describe the context and purpose of the Dataset",
"TITLE": "Kratko uputstvo o",
"TITLE-REST": "radi se o njegovoj nameni i ciljevima."
},
@ -1069,7 +1103,12 @@
"LABEL": "Oznaka",
"ROLES": "Uloge",
"NAME": "Ime",
"PERMISSIONS": "Dozvole"
"PERMISSIONS": "Dozvole",
"EXPORT": "Export users"
},
"ACTIONS": {
"EDIT": "Edit",
"SAVE": "Save"
}
},
"TYPES": {
@ -1140,7 +1179,8 @@
"RESEARCHERS": "Istraživači",
"ORGANIZATIONS": "Institucije",
"DATASET-IDENTIFIER": "Identifikatori skupa podataka",
"CURRENCY": "Valuta"
"CURRENCY": "Valuta",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Lista reči",
@ -1156,7 +1196,10 @@
"DMPS": "Planovi upravljanja podacima",
"DATASETS": "Skupovi podataka",
"EXTERNAL-SOURCE-HINT": "Lista vrednosti obezbeđenih od spoljnih izvora"
},
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Kreirano",
"LABEL": "Oznaka",
@ -1277,7 +1320,8 @@
"GUIDE": {
"TITLE": "Korisničko uputstvo",
"TITLE-DASHED": "-Korisničko uputstvo-",
"CLOSE": "Zatvorite"
"CLOSE": "Zatvorite",
"SAVE": "Save"
},
"PRIVACY-POLICY": {
"TITLE": "-Politika privatnosti-",
@ -1348,6 +1392,14 @@
"ADD-DATASET-DESCRIPTION": "Dodajte skup podataka",
"ADD-DATASET": "Dodajte skup podataka",
"ADD-DMP-DESCRIPTION": "Dodajte opis Plana"
},
"TOUR-GUIDE": {
"DMP": "This is your dashboard. You can view and edit all DMPs that you have either contributed to or created yourself.",
"START-NEW": "Create your DMP with Start new DMP.",
"IMPORT-DMP": "You can import a DMP",
"START-WIZARD": "or create new in Argos.",
"DATASET": "This is your dashboard. You can view and edit all Datasets that you have either contributed to or created yourself.",
"NEW-DATASET": "With Add Dataset you can describe new datasets anytime in the research process."
}
},
"USER-DIALOG": {
@ -1361,7 +1413,15 @@
"TITLE": "Podešavanja",
"TIMEZONE": "Vremenska zona",
"CULTURE": "Kultura",
"LANGUAGE": "Jezik"
"LANGUAGE": "Jezik",
"CONNECTED-WITH": "Connected with",
"NAME": "Name",
"ORGANIZATION": "Organization",
"ROLE": "Role",
"SELECT-ROLE": "Select Role",
"ACCOUNTS": "Accounts",
"EMAILS": "Emails",
"YOUR-EMAIL": "Your Email"
},
"ASSOCIATED-DMPS": "Povezani Planovi",
"DMPS": {
@ -1372,8 +1432,32 @@
"ZENODO": {
"LOGIN": "Prijavite se na Zenodo",
"LOGOUT": "Uklonite Zenodo",
"AUTHORIZE": "Authorize Zenodo",
"TITLE": "Zenodo nalog",
"DESCRIPTION": "Povezani Zenodo nalog:"
},
"ROLE-ORGANIZATION": {
"FACULTY": "Faculty",
"LIBRARIAN": "Librarian",
"RESEARCHER": "Researcher",
"STUDENT": "Student (BA/BSc, MSc)",
"EARLY-CAREER-RESEARCHER": "Early Career Researcher (PhD candidate, post-graduate)",
"RESEARCH-ADMINISTRATOR": "Research Administrator",
"REPOSITORY-MANAGER": "Repository Manager",
"RESEARCH-INFRASTRUCTURE": "Research Infrastructure",
"SERVICE-PROVIDER": "Service Provider",
"PUBLISHER": "Publisher",
"RESEARCH-FUNDER": "Research Funder",
"POLICY-MAKER": "Policymaker",
"SME-INDUSTRY": "SME/ Industry",
"OTHER": "Other"
},
"ACTIONS": {
"SAVE": "Save",
"LINK-NEW": "Link new",
"LINK-NEW-ACCOUNT": "Link new account",
"ADD": "Add",
"CANCEL": "Cancel"
}
},
"DATASET-REFERENCED-MODELS": {

View File

@ -280,6 +280,33 @@
"ROLES": "Görev"
},
"STEPS": {
"GENERAL-INFO":{
"TITLE": "General Info",
"DATASET-TEMPLATE-NAME": "Dataset template name",
"DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.",
"DATASET-TEMPLATE-DESCRIPTION": "Description",
"DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.",
"DATASET-TEMPLATE-LANGUAGE": "Dataset template language",
"UNTITLED": "Untitled"
},
"PAGE-INFO":{
"PAGE-NAME": "Page Name",
"PAGE-NAME-HINT": "Set a name for the dataset page.",
"PAGE-DESCRIPTION": "Description",
"PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the page is about.",
"ACTIONS":{
"CREATE-FIRST-PAGE": "Create the first page",
"NOTHING-HERE-HINT": "Nothing here yet.",
"START-CREATING-PAGE-START": "Start by ",
"START-CREATING-PAGE-END": "creating the first page."
}
},
"SECTION-INFO":{
"SECTION-NAME": "Section Name",
"SECTION-NAME-HINT": "Set a name for the section.",
"SECTION-DESCRIPTION": "Description",
"SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about."
},
"PAGES": {
"TITLE": "Sayfa Tanımı",
"PAGE-PREFIX": "Sayfa",
@ -1152,7 +1179,8 @@
"RESEARCHERS": "Araştırmacılar",
"ORGANIZATIONS": "Kurumlar",
"DATASET-IDENTIFIER": "Veri Seti Tanımlayıcısı",
"CURRENCY": "Değer"
"CURRENCY": "Değer",
"VALIDATION": "Validator"
},
"DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Kelime Listesi",
@ -1169,6 +1197,9 @@
"DATASETS": "Veri Seti Tanımları",
"EXTERNAL-SOURCE-HINT": "Dış kaynak(lar) tarafından sağlanan değerlerin listesi"
},
"DATASET-PROFILE-VALIDATOR": {
"ACTION": "Validate"
},
"RECENT-ACTIVITY-ORDER": {
"CREATED": "Oluşturulmuş",
"LABEL": "Etiket",
@ -1590,4 +1621,4 @@
"FINALIZED": "Tamamlandı",
"DELETED": "Deleted"
}
}
}