Merge remote-tracking branch 'origin/Development' into Development

This commit is contained in:
George Kalampokis 2021-07-23 18:29:40 +03:00
commit f01e89799b
30 changed files with 488 additions and 262 deletions

View File

@ -25,7 +25,7 @@ public class DataManagementPlanListingModel implements DataModel<DMP, DataManage
private String label;
private String grant;
// private String profile;
// private Date creationTime;
private Date creationTime;
private Date modifiedTime;
//private String organisations;
private int version;
@ -70,12 +70,12 @@ public class DataManagementPlanListingModel implements DataModel<DMP, DataManage
this.profile = profile;
}*/
/*public Date getCreationTime() {
public Date getCreationTime() {
return creationTime;
}
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
}*/
}
public Date getModifiedTime() {
return modifiedTime;
@ -187,7 +187,7 @@ public class DataManagementPlanListingModel implements DataModel<DMP, DataManage
this.id = entity.getId().toString();
this.label = entity.getLabel();
this.groupId = entity.getGroupId();
// this.creationTime = entity.getCreated();
this.creationTime = entity.getCreated();
// this.associatedProfiles = entity.getAssociatedDmps().stream().map(item -> new AssociatedProfile().fromData(item)).collect(Collectors.toList());
return this;
}
@ -196,7 +196,7 @@ public class DataManagementPlanListingModel implements DataModel<DMP, DataManage
this.id = entity.getId().toString();
this.label = entity.getLabel();
this.groupId = entity.getGroupId();
// this.creationTime = entity.getCreated();
this.creationTime = entity.getCreated();
return this;
}
@ -205,8 +205,8 @@ public class DataManagementPlanListingModel implements DataModel<DMP, DataManage
this.status = entity.getStatus();
this.version = entity.getVersion();
this.grant = entity.getGrant().getLabel();
/*if (entity.getProfile() != null) this.profile = entity.getProfile().getLabel();
this.creationTime = entity.getCreated();*/
/*if (entity.getProfile() != null) this.profile = entity.getProfile().getLabel(); */
this.creationTime = entity.getCreated();
this.modifiedTime = entity.getModified();
// this.organisations = LabelBuilder.getLabel(entity.getOrganisations().stream().map(item -> new Organisation().fromDataModel(item)).collect(Collectors.toList()));
this.datasets = entity.getDataset().stream().map(x-> new DatasetUrlListing().fromDataModel(x)).collect(Collectors.toList());

View File

@ -30,7 +30,7 @@ export class CanDeactivateGuard extends BaseComponent implements CanDeactivate<C
warning: this.language.instant('GENERAL.CONFIRMATION-DIALOG.LEAVE-WARNING'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.LEAVE'),
icon: 'error_outline'
// icon: 'error_outline'
}
});
return dialogRef.afterClosed().pipe(map(x => x ? true : false));

View File

@ -5,6 +5,7 @@ import { DatasetProfileListingComponent } from './listing/dataset-profile-listin
import { AdminAuthGuard } from '@app/core/admin-auth-guard.service';
import { AppRole } from '@app/core/common/enum/app-role';
import { SpecialAuthGuard } from '@app/core/special-auth-guard.service';
import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard';
const routes: Routes = [
{
@ -16,7 +17,8 @@ const routes: Routes = [
permissions: [AppRole.Admin, AppRole.DatasetTemplateEditor]
}
},
canActivate: [SpecialAuthGuard]
canActivate: [SpecialAuthGuard],
canDeactivate:[CanDeactivateGuard]
},
{
path: ':id',
@ -27,7 +29,8 @@ const routes: Routes = [
permissions: [AppRole.Admin, AppRole.DatasetTemplateEditor]
}
},
canActivate: [SpecialAuthGuard]
canActivate: [SpecialAuthGuard],
canDeactivate:[CanDeactivateGuard]
},
{
path: 'clone/:cloneid',
@ -38,7 +41,8 @@ const routes: Routes = [
permissions: [AppRole.Admin, AppRole.DatasetTemplateEditor]
}
},
canActivate: [SpecialAuthGuard]
canActivate: [SpecialAuthGuard],
canDeactivate:[CanDeactivateGuard]
},
{
path: 'newversion/:newversionid',
@ -49,7 +53,8 @@ const routes: Routes = [
permissions: [AppRole.Admin, AppRole.DatasetTemplateEditor]
}
},
canActivate: [SpecialAuthGuard]
canActivate: [SpecialAuthGuard],
canDeactivate:[CanDeactivateGuard]
},
{
path: 'versions/:groupId',

View File

@ -78,6 +78,13 @@ export const GENERAL_ANIMATIONS = [
trigger('action-btn',[
transition(":enter", [style({opacity:0, transform:'scale(0)'}), animate('400ms ease', style({'opacity':1, transform:'scale(1)'}))]),
transition(":leave", [style({opacity:1,transform:'scale(1)'}), animate('400ms ease', style({'opacity':0, transform:'scale(0)'}))])
])
]),
trigger('fade-in',[
transition(":enter", [style({opacity:0}), animate('1000ms 800ms ease', style({'opacity':1}))]),
]),
trigger('fade-in-fast',[
transition(":enter", [style({opacity:0}), animate('800ms 100ms ease', style({'opacity':1}))]),
]),
]

View File

@ -76,46 +76,40 @@
</mat-form-field>
</div>
</div>
<div style="position: relative;" class="col-12">
<ng-container *ngIf="hasFocus">
<div class="row" *ngIf="showDescription">
<mat-form-field class="col p-0 underline-line-field" 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" *ngIf="showExtendedDescription">
<mat-form-field class="col p-0 underline-line-field" 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" *ngIf="showAdditionalInfo">
<mat-form-field class="col p-0 underline-line-field" 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 pl-0 underline-line-field" 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 pr-0 underline-line-field" 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>
</ng-container>
<div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]>
<div class="row" *ngIf="showDescription">
<mat-form-field class="col p-0 underline-line-field" 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" *ngIf="showExtendedDescription">
<mat-form-field class="col p-0 underline-line-field" 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" *ngIf="showAdditionalInfo">
<mat-form-field class="col p-0 underline-line-field" 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 pl-0 underline-line-field" 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 pr-0 underline-line-field" 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>
@ -123,66 +117,63 @@
<div class="row">
<!-- FIELDS -->
<div class="col">
<div class="col-12" *ngIf="hasFocus" [@fade-in] >
<div>
<ng-container *ngFor="let field of form.get('fields')['controls']; let i=index" >
<div class="row bg-white" style="position: relative;" (click)="setTargetField(field)"
>
<!-- field-container -->
<!-- [ngClass]="{'field-container-active': (field.get('id').value === targetField?.get('id').value) && hasFocus}" -->
<!-- <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]="hasFocus"
[canBeDeleted]="form.get('fields')['controls'].length !=1"
(delete)="deleteField(i)">
</app-dataset-profile-editor-field-component>
</div>
<hr *ngIf="hasFocus">
</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
<ng-container *ngFor="let field of form.get('fields')['controls']; let i=index" >
<div class="row bg-white" style="position: relative;" (click)="setTargetField(field)"
>
<!-- field-container -->
<!-- [ngClass]="{'field-container-active': (field.get('id').value === targetField?.get('id').value) && hasFocus}" -->
<!-- <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]="hasFocus"
[canBeDeleted]="form.get('fields')['controls'].length !=1"
(delete)="deleteField(i)">
</app-dataset-profile-editor-field-component>
</div>
<hr>
</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>
<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>
</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>
<!-- PREVIEW -->
<div class="col-12 previewer">
<div *ngIf="hasFocus" class="d-flex mb-3" style="justify-content: space-between;">
<span style="font-weight: bold; font-style: italic;">{{'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.PREVIEW' | translate}}</span>
<span class="previewer-text">{{'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.PREVIEW' | translate}}</span>
<span [@fadeElement]="updatedClass" *ngIf="firstField?.get('viewStyle').get('renderStyle').value">
<ng-container *ngIf="!previewDirty">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.STATUS.PREVIEW-UPDATED' | translate}}
@ -193,7 +184,7 @@
</span>
</div>
<div [id]="'preview_container'+ form.get('id').value" class="w-100" style="margin-right: -15px; margin-left: -15px;" >
<div *ngIf="previewForm && showPreview && firstField?.get('viewStyle').get('renderStyle').value">
<div *ngIf="previewForm && showPreview && firstField?.get('viewStyle').get('renderStyle').value" [@fade-in-fast]>
<app-form-section-inner [form]="previewForm">
</app-form-section-inner>
</div>

View File

@ -129,6 +129,11 @@ $blue-color-light: #5cf7f2;
padding-bottom: 0px;
}
.previewer-text{
font-weight: bold;
font-style: italic;
}
// ::ng-deep .underline-line-field .mat-form-field-appearance-legacy .mat-form-field-wapper{
// padding-bottom: 1.25em !important;
// }

View File

@ -21,8 +21,9 @@ import { AutoCompleteFieldData, BooleanDecisionFieldData, CheckBoxFieldData, Cur
import { CompositeField } from '@app/core/model/dataset-profile-definition/composite-field';
import {Field as FieldDefinition} from '@app/core/model/dataset-profile-definition/field';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { debounceTime, delay, map, takeUntil, tap } from 'rxjs/operators';
import { GENERAL_ANIMATIONS } from '../../animations/animations';
import { BaseComponent } from '@common/base/base.component';
@Component({
selector: 'app-dataset-profile-editor-composite-field-component',
@ -30,7 +31,7 @@ import { GENERAL_ANIMATIONS } from '../../animations/animations';
styleUrls: ['./dataset-profile-editor-composite-field.component.scss'],
animations:[GENERAL_ANIMATIONS]
})
export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnChanges {
export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent implements OnInit, OnChanges {
@Input() form: FormGroup;
@Input() indexPath: string;
@ -61,7 +62,9 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
private language: TranslateService,
public enumUtils: EnumUtils,
public datasetProfileService: DatasetProfileService
) { }
) {
super();
}
ngOnChanges(){
// this.setTargetField(null);
@ -112,16 +115,52 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
this.showExtendedDescription = !!this.form.get('extendedDescription').value;
this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
this.form.valueChanges.subscribe(changes=>{
this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes=>{
// this.previewForm = null;
this.previewDirty = true;
this.generatePreviewForm();
});
this.previewSubject$.pipe(debounceTime(600)).subscribe(model=>{
const updatedForm = model.buildForm();
this.reloadPreview(updatedForm)
})
this.previewSubject$
.pipe(debounceTime(600))
.pipe(
takeUntil(this._destroyed),
map(model => model.buildForm()),
map(updatedForm =>{
const previewContainer = document.getElementById('preview_container'+ this.form.get('id').value);
// let clientHeight = -1;
if(previewContainer){
// console.log(previewContainer);
const clientHeight = previewContainer.clientHeight;
// console.log(clientHeight);
if(clientHeight){
previewContainer.style.height = clientHeight.toString() + 'px';
// console.log('height:' ,previewContainer.style.height);
}
}
this.showPreview = false;
this.previewDirty = true;
this.previewForm = updatedForm;
return previewContainer;
}),
delay(100),
tap( previewContainer =>{
this.showPreview = true;
this.previewDirty = false;
}),
delay(100)
)
.subscribe(previewContainer=>{
if(previewContainer){
previewContainer.style.height = 'auto';
}
// const updatedForm = model.buildForm();
// this.reloadPreview(updatedForm)
});
this.generatePreviewForm();
@ -325,7 +364,8 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
fieldsForm.controls.forEach((field, idx)=>{
field.get('ordinal').setValue(idx);
field.updateValueAndValidity();
})
});
this.form.markAsDirty();//deactivate guard
}
getFieldTile(formGroup: FormGroup, index: number) {

View File

@ -15,12 +15,10 @@
<li class="list-inline-item" *ngIf="!viewOnly && viewType && canBeDeleted" class="text-muted">
<mat-icon style="cursor: pointer; opacity: 0.7; transform:translateY(2px) translateX(10px) ;" (click)="onDelete()" [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.DELETE-INPUT' | translate">delete</mat-icon>
</li>
</ul>
</div>
</div>
<div class="row">
<!-- <mat-form-field class="col">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.ID' | translate}}" type="text" [formControl]="this.form.get('id')"
@ -173,9 +171,9 @@
</mat-form-field>
<!-- Combo Box -->
<mat-form-field *ngIf="showOrdinal" class="col">
<!-- <mat-form-field *ngIf="showOrdinal" class="col">
<input matInput type="number" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.ORDER' | translate}}" [formControl]="this.form.get('ordinal')" required>
</mat-form-field>
</mat-form-field> -->
<!-- Validation -->
<!-- <mat-form-field class="col" *ngIf="!(defaulValueRequired(form.get('viewStyle').get('renderStyle').value))">
@ -189,7 +187,7 @@
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.RDA-COMMON-STANDARDS' | translate}}</mat-label>
<mat-select [formControl]="this.form.get('rdaCommonStandard')">
<mat-option>--</mat-option>
<mat-option *ngFor="let property of datasetProfileService.getRDACommonStandards()" [value]="property">
<mat-option *ngFor="let property of rdaCommonStandards" [value]="property">
{{property}}
</mat-option>
</mat-select>
@ -246,7 +244,6 @@
<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>
</ng-container>

View File

@ -41,6 +41,9 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
@Output() delete = new EventEmitter<void>();
rdaCommonStandards = this.datasetProfileService.getRDACommonStandards();
constructor(
public enumUtils: EnumUtils,
public datasetProfileService: DatasetProfileService,
@ -791,7 +794,7 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
validationsControl.updateValueAndValidity();
}
this.form.markAsDirty();//deactivate guard
}
get isRequired(){

View File

@ -12,7 +12,7 @@ import { TranslateService } from '@ngx-translate/core';
styleUrls: ['./dataset-profile-editor-rule.component.scss']
})
export class DatasetProfileEditorRuleComponent implements OnInit{
export class DatasetProfileEditorRuleComponent implements OnInit {
@Input() form: FormArray;
@ -29,6 +29,9 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
fieldSetOptions: OptionItem[];
fieldOptions: OptionItem[];
parentIds: string[] = [];
hiddenBy: string[] = [];
constructor(private language: TranslateService){
}
@ -39,6 +42,7 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
deleteRule(index) {
this.form.removeAt(index);
this.form.markAsDirty();//deactivate guard
}
ngOnInit(): void {
@ -70,6 +74,8 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
this.fieldOptions.forEach(e=>this._buildHiddenBy(e));
this.fieldSetOptions.forEach(e=>this._buildHiddenBy(e));
this.parentIds = this.computeParentIds();
this.hiddenBy = this.computeHiddenBy();
}
@ -164,8 +170,15 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
return result;
}
get parentIds(): string[]{
// get parentIds(): string[]{
// }
// get hiddenBy(): string[]{
// }
computeParentIds(): string[]{
if(!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);
@ -175,7 +188,8 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
}
return [];
}
get hiddenBy(): string[]{
computeHiddenBy(): string[]{
if(!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);

View File

@ -1,5 +1,5 @@
<div id="topofcontainer"></div>
<div class="row" [id]="idprefix+form.get('id').value">
<div class="row" [id]="idprefix+form.get('id').value" *ngIf="form" [@fade-in-fast]>
<div class="col-12" >
@ -69,7 +69,7 @@
<mat-card-content>
<mat-card-header *ngIf="(fieldset.get('id').value === selectedFieldSetId) && !viewOnly">
<mat-icon class="handle" style="display:inline-block; margin: 0px auto; cursor: grab;transform: rotate(90deg); opacity: 0.3;" cdkDragHandle>drag_indicator</mat-icon>
<mat-icon class="handle" style="display:inline-block; margin: 0px auto; cursor: grab;transform: rotate(90deg); opacity: 0.3;">drag_indicator</mat-icon>
</mat-card-header>
<app-dataset-profile-editor-composite-field-component [form]="fieldset"
[viewOnly]="viewOnly"
@ -81,7 +81,6 @@
</div>
<div class="col-2 col-xl-auto ml-4" *ngIf="selectedFieldSetId === fieldset.get('id').value &&(!viewOnly)">
<div class="row bg-white actions-list stick-list">
<nav *ngIf="!viewOnly">
<label class="action-list-label">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' | translate}}</label>

View File

@ -2,16 +2,20 @@
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { Guid } from '@common/types/guid';
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
import { DragulaService } from 'ng2-dragula';
import { Subscription } from 'rxjs';
import { pipe, Subject, Subscription } from 'rxjs';
import { debounceTime, delay, tap } from 'rxjs/operators';
import { FieldEditorModel } from '../../../admin/field-editor-model';
import { FieldSetEditorModel } from '../../../admin/field-set-editor-model';
import { ToCEntry, ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';
import { GENERAL_ANIMATIONS } from '../../animations/animations';
@Component({
selector: 'app-dataset-profile-editor-section-fieldset-component',
templateUrl: './dataset-profile-editor-section-fieldset.component.html',
styleUrls: ['./dataset-profile-editor-section-fieldset.component.scss']
styleUrls: ['./dataset-profile-editor-section-fieldset.component.scss'],
animations:[GENERAL_ANIMATIONS]
})
export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnChanges, OnDestroy {
@ -36,6 +40,10 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
readonly dragula_prefix = "dragulaid";
private subs = new Subscription();
private FIELDSETS = 'FIELDSETS';
private initializer = new Subject<void>();
private scroller = new Subject<string>();
// private $selectedFieldsetId = new Subject<string>();
constructor(
private dragulaService: DragulaService,
private myElement: ElementRef
@ -66,6 +74,33 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.dataNeedsRefresh.emit();
return ;
}));
const initializerSub = this.initializer
.pipe(
debounceTime(100)
)
.subscribe(() =>{
this.initialize();
});
this.subs.add(initializerSub);
this.subs.add(
this.scroller
.pipe(debounceTime(700))
.subscribe(id => {
if(isNullOrUndefined(id)){
this._scrollOnTop();
return ;
}
this._scrollToElement(id);
})
);
// this.subs.add(
// this.$selectedFieldsetId
// .pipe(
// debounceTime(100)
// )
// .subscribe(id => this.selectedEntryId.emit(id))
// );
}
ngOnDestroy(){
@ -74,15 +109,7 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.subs.unsubscribe();
}
ngOnChanges(changes: SimpleChanges): void {
// console.log('---------element updated-------');
// console.log('numbering before:', this.numbering);
this.initialize();
// console.log('----post update----');
// console.log('numbering now', this.numbering, ' changes detected:', changes);
this.initializer.next();
}
@ -99,14 +126,18 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
if(id === this._selectedFieldSetId) return;
this._selectedFieldSetId = id;
this.selectedEntryId.emit(this._selectedFieldSetId);
this.selectedEntryId.emit(id);
}
private _findParentSection():FormGroup{
const parent = this.form.parent;
return parent;
}
// private _findParentSection():FormGroup{
// const parent = this.form.parent;
// return parent;
// }
private initialize(){
@ -115,8 +146,8 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.numbering = this.tocentry.numbering;
this._selectedFieldSetId = null;
// this._scrollToElement(this.tocentry.id);
this._scrollOnTop();
// this.scroller.next(null);
this._scrollOnTop(true);
}else if(this.tocentry.type === ToCEntryType.FieldSet){
this.form = this.tocentry.form.parent.parent;
const numberingArray = this.tocentry.numbering.split('.');
@ -126,45 +157,34 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
}else{
// console.warn('!not found numbering');
}
this.selectedFieldSetId = this.tocentry.id;
this._selectedFieldSetId = this.tocentry.id;
this._scrollToElement(this.selectedFieldSetId);
// this._scrollToElement(this.selectedFieldSetId);
this.scroller.next(this.tocentry.id);
}else{//scroll on top
this._scrollOnTop();
// this._scrollOnTop();
this.scroller.next(null);
}
}
private _scrollToElement(id: string){
let el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
// let el = this.myElement.nativeElement.getElementbyId (this.selectedFieldSetId);
if(el){
/*
Give time to template to build itself (extending and collapsing).
In case we are dragging from one container to another, then the ui takes around 600ms to build
individual previews (dataset-profile-editor-field.component.ts);
*/
setTimeout(() => {
const el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
if(el){
el.scrollIntoView({behavior: "smooth", block:'start'});
}
}, 700);
el.scrollIntoView({behavior: "smooth", block:'start'});
}
}
private _scrollOnTop(){
setTimeout(() => {
const el = this.myElement.nativeElement.querySelector('#topofcontainer');
if(el){
el.scrollIntoView({behavior:'smooth', block:'end'})
private _scrollOnTop(instant?: boolean){
const el = this.myElement.nativeElement.querySelector('#topofcontainer');
if(el){
if(instant){
el.scrollIntoView({ block:'end'});
}else{
el.scrollIntoView({behavior:'smooth', block:'end'});
}
},200);
}
}
ngOnInit() {
}
onRemoveFieldSet(fieldsetId: string){
@ -175,7 +195,18 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.cloneFieldSet.emit(fieldset);
}
onAddFieldSet(){
this.addNewFieldSet.emit(this.form);
// this.addNewFieldSet.emit(this.form);
try{
const length = (this.form.get('fieldSets') as FormArray).length;
if(length === 0){
this.addFieldSetAfter(-9999, 0);
return;
}
else{
const lastElement = (this.form.get('fieldSets') as FormArray).at(length -1);
this.addFieldSetAfter(lastElement.get('ordinal').value, length-1);
}
} catch {}
}
addFieldSetAfter(afterOrdinal: number, afterIndex: number):void{
@ -205,6 +236,8 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
const index = afterOrdinal < 0 ? 0: afterIndex +1;
parentArray.insert(index, fieldsetForm);
this.dataNeedsRefresh.emit();
// this.selectedFieldSetId = fieldSetId;
setTimeout(() => {
this.selectedFieldSetId = fieldSetId;
}, 200);

View File

@ -135,7 +135,7 @@
<!-- <ng-template matStepLabel>{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
</ng-template> -->
<div class="row">
<div class="col-3" style="display: flex; height: 40vh;">
<div class="col-3 side-actions">
<ng-container *ngTemplateOutlet="actions">
</ng-container>
@ -181,58 +181,61 @@
</mat-error>
</mat-form-field>
</div>
</div>
<!-- <div class="col-12">
<div class="heading">1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="full-width basic-info-input">
<table class="col-12 user-table">
<tr class="row user-table-header">
<th>{{'USERS.LISTING.NAME' | translate}}</th>
<th>{{'USERS.LISTING.EMAIL' | translate}}</th>
<th></th>
</tr>
<tbody class="user-table-body">
<tr *ngFor="let user of userChipList" class="user-table-row">
<td>{{user.name}}</td>
<td >{{user.email}}</td>
<td>
<button mat-button class="delete-btn" (click)="verifyAndRemoveUser(user)" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate"><mat-icon>person_remove</mat-icon></button>
</td>
</tr>
<tr *ngIf="!userChipList || !userChipList.length">
<td style="text-align: end; line-height: 3em;" colspan="2" >
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td>
</tr>
</tbody>
</table>
<div class="col-12">
<div class="heading">1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="full-width basic-info-input">
<table class="col-12 user-table">
<thead class="user-table-header">
<tr>
<th>{{'USERS.LISTING.NAME' | translate}}</th>
<th>{{'USERS.LISTING.EMAIL' | translate}}</th>
<th></th>
</tr>
</thead>
<tbody class="user-table-body">
<tr *ngFor="let user of userChipList" class="user-table-row">
<td>{{user.name}}</td>
<td >{{user.email}}</td>
<td>
<button mat-button class="delete-btn" (click)="verifyAndRemoveUser(user)" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate"><mat-icon>person_remove</mat-icon></button>
</td>
</tr>
<tr *ngIf="!userChipList || !userChipList.length">
<td style="text-align: end; line-height: 3em;" colspan="2" >
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-12">
<div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;">
<div style="min-width: 20em;max-width: 25em;" [@add-new-user-field]="inputUserState">
<mat-form-field appearance="legacy">
<input matInput #email placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</mat-form-field>
<div class="col-12">
<div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;">
<div style="min-width: 20em;max-width: 25em;" [@add-new-user-field]="inputUserState">
<mat-form-field appearance="legacy">
<input matInput #email placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</mat-form-field>
</div>
</div>
<div class="col-auto">
<button mat-mini-fab color="primary" (click)="addUser(email)" (focus)="onUserButtonFocus()" (blur)="onUserButtonBlur()" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate" [disabled]="userFormDisabled">
<ng-container *ngIf="inputUserState === 'untriggered' else triggericon">
<mat-icon>add</mat-icon>
</ng-container>
<ng-template #triggericon>
<mat-icon>person_add</mat-icon>
</ng-template>
</button>
</div>
</div>
<div class="col-auto">
<button mat-mini-fab color="primary" (click)="addUser(email)" (focus)="onUserButtonFocus()" (blur)="onUserButtonBlur()" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate" [disabled]="userFormDisabled">
<ng-container *ngIf="inputUserState === 'untriggered' else triggericon">
<mat-icon>add</mat-icon>
</ng-container>
<ng-template #triggericon>
<mat-icon>person_add</mat-icon>
</ng-template>
</button>
</div>
</div>
</div> -->
</div>
<!-- <div class="col-12">
<button mat-button class="full-width" (click)="addPage()"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.ACTIONS.NEXT' | translate}}</button>
@ -247,7 +250,7 @@
<div class="col-3">
<div class="row sticky-top" style="top : 7em;">
<div class="row sticky-top table-container" style="top : 7em;">
<dataset-profile-table-of-contents class="toc-pane-container col"
style="margin-bottom: 2em;"
[links]="toCEntries"
@ -276,7 +279,7 @@
<div class="row" *ngIf="selectedTocEntry">
<!-- PAGE INFO -->
<div class="col-12 content-displayer" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page">
<div class="col-12 content-displayer" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page" [@fade-in-fast]>
<form [formGroup]="selectedTocEntry.form" class="page-infos">
<div class="row">
<!-- PAGE NAME -->
@ -318,7 +321,7 @@
(addNewFieldSet)="addNewEntry({childType: tocEntryEnumValues.FieldSet,parent: {form: $event}})"
(removeFieldSet)="onRemoveEntry(_findTocEntryById($event, toCEntries))"
(cloneFieldSet)="cloneFieldSet($event)"
(selectedEntryId)="displayItem(_findTocEntryById($event, getTocEntries()))"
(selectedEntryId)="displayItem(_findTocEntryById($event, toCEntries))"
(dataNeedsRefresh)="onDataNeedsRefresh()"
>
@ -388,11 +391,10 @@
</mat-horizontal-stepper>
<!--
<ng-container *ngIf="false">
<div class="d-flex">
<!-- SAVE BUTTON -->
<div class="col-6 d-flex" *ngIf="!viewOnly">
<div class="row mt-4">
<ng-container *ngIf="false">
@ -411,7 +413,6 @@
translate}}</button>
</div>
</div>
<!-- SAVE BUTTON WHEN FINALIZED-->
<div class="col-6 d-flex" *ngIf="showUpdateButton()">
<div class="row mt-4">
<ng-container *ngIf="false">
@ -424,7 +425,6 @@
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()">
@ -434,7 +434,7 @@
</div>
</div>
</ng-container>
</ng-container> -->
<div class="scroll-on-top">
<button mat-fab (click)="scrollOnTop()" *ngIf="showScrollOnTopButton" [@scroll-on-top-btn] [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.BACK-TO-TOP'| translate">

View File

@ -277,16 +277,18 @@ $blue-color-light: #5cf7f2;
.user-table {
// border: thin solid rgb(179, 173, 173);
border: 1px solid rgba(0, 0, 0, 0.12);
// border: 1px solid rgba(0, 0, 0, 0.12);
background-color: white;
border-radius: 4px;
padding-bottom: 1em;
box-shadow: -1px 1px 11px -3px #00000017;
}
.user-table-header {
text-align: center;
display: revert;
background-color: rgb(243 245 248);
// background-color: #129d9811;
}
.user-table-header th {
@ -344,7 +346,7 @@ $blue-color-light: #5cf7f2;
background: #f4f4f4;
position: sticky;
top: 0.01em;
z-index: 99;
z-index: 9999;
}
#title-column{
@ -352,3 +354,9 @@ $blue-color-light: #5cf7f2;
align-items: baseline;
padding-right: 15px;
}
.side-actions{
display: flex;
height: 40vh;
position: sticky;
top: 2em;
}

View File

@ -44,6 +44,7 @@ import { GENERAL_ANIMATIONS, STEPPER_ANIMATIONS } from './animations/animations'
import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type';
import { UserService } from '@app/core/services/user/user.service';
import { MatInput } from '@angular/material';
import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component';
const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json');
@ -55,7 +56,10 @@ const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.
animations:[...STEPPER_ANIMATIONS, ...GENERAL_ANIMATIONS],
providers:[VisibilityRulesService]
})
export class DatasetProfileEditorComponent extends BaseComponent implements OnInit {
export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent implements OnInit {
canDeactivate(): boolean {
return !this.form.dirty;
}
isNew = true;
isNewVersion = false;
@ -425,6 +429,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
this.datasetProfileService.updateForm(this.datasetProfileId, data)
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
this.form.markAsPristine();//deactivate guard
this.router.navigate(['/dataset-profiles']);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
},error=> this.onCallbackError(error));
@ -434,6 +439,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
this.datasetProfileService.newVersion(this.newVersionId, data)
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
this.form.markAsPristine();//deactivate guard
this.router.navigate(['/dataset-profiles']);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
},
@ -447,6 +453,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
this.datasetProfileService.createForm(data)
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
this.form.markAsPristine();//deactivate guard
this.router.navigate(['/dataset-profiles']);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
}, error=> this.onCallbackError(error));
@ -1183,7 +1190,8 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
//in case selectedtocentrhy is child of the removed element
this.refreshToCEntries();
// this.refreshToCEntries();
this.onDataNeedsRefresh();
this.form.updateValueAndValidity();
}
@ -1572,6 +1580,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
this.displayItem(this._findTocEntryById(params.draggedItemId, tocentries));
}
}
this.form.markAsDirty();
}
cloneFieldSet(fieldset: FormGroup){
@ -1944,6 +1953,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
email.value = '';
this.userFormDisabled = false;
this.form.markAsDirty();
// email.focus();
// this.inputUserState = 'triggered';
@ -1951,7 +1961,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
},
error=>{
// console.log(error.message);
this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.ERRORS.USER-NOT-FOUND'), SnackBarNotificationLevel.Error);
this.userFormDisabled = false;
// this.inputUserState = 'triggered';//when it loses focus(when disabled) it becomes untriggered
// email.focus();
@ -2029,6 +2039,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
removeUser(user: any) {
this.userChipList.splice(this.userChipList.indexOf(user), 1);
this.form.patchValue({'users': this.userChipList});
this.form.markAsDirty();//deactivate guard
}

View File

@ -1,5 +1,5 @@
<div>
<h3 id="guide-steps">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TEMPLATE-OUTLINE' | translate}}</h3>
<div class="table-container">
<h3 id="guide-steps" [class.opacity-0]="isDragging">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TEMPLATE-OUTLINE' | translate}}</h3>
<div class="scroll-container" id="tocentrytable">
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"
@ -18,6 +18,15 @@
[colorizeInvalid]="colorizeInvalid"
>
</app-dataset-profile-table-of-contents-internal-section>
<div class="top-scroller table-scroller" [hidden]="!isDragging">
<div class="col-auto">
<mat-icon>keyboard_arrow_up</mat-icon>
</div>
</div>
<div class="bottom-scroller table-scroller" [hidden]="!isDragging">
<div class="col-auto">
<mat-icon>keyboard_arrow_down</mat-icon>
</div>
</div>
</div>
</div>

View File

@ -1,10 +1,12 @@
$scroller-height: 3em;
.scroll-container {
// overflow-y: auto;
max-height: 60vh;
overflow-y: scroll;
padding-left: .2em;
padding-right: 1em;
// padding-top: $scroller-height;
// padding-bottom: $scroller-height;
}
// #style-6::-webkit-scrollbar-track
@ -59,4 +61,32 @@
opacity: 0.6;
font-size: 1.6em;
margin-top: 0px;
}
.table-container{
position: relative;
}
.table-scroller{
// background-color: #5cf7f221;
position: absolute;
width: 95%;
height: $scroller-height;
display: flex;
align-items: center;
justify-content: center;
// z-index: -9999;
}
.top-scroller{
top: 1px;
background: rgb(255,255,255);
background: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(92,247,242,0.4542191876750701) 100%);
}
.bottom-scroller{
bottom: 1px;
background: rgb(255,255,255);
background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(92,247,242,0.4542191876750701) 100%);
}
.opacity-0{
opacity: 0 !important;
}

View File

@ -1,8 +1,8 @@
import { DOCUMENT } from '@angular/common';
import { Component, EventEmitter, Inject, OnInit, Output, Input } from '@angular/core';
import { Component, EventEmitter, Inject, OnInit, Output, Input, AfterViewInit } from '@angular/core';
import { BaseComponent } from '@common/base/base.component';
import { interval, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { distinctUntilChanged, filter, takeUntil } from 'rxjs/operators';
import { type } from 'os';
import { SimpleChanges } from '@angular/core';
import { NewEntryType, TableUpdateInfo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
@ -18,7 +18,7 @@ import { ContentObserver } from '@angular/cdk/observers';
styleUrls: ['./table-of-contents.scss'],
templateUrl: './table-of-contents.html'
})
export class DatasetProfileTableOfContents extends BaseComponent implements OnInit {
export class DatasetProfileTableOfContents extends BaseComponent implements OnInit, AfterViewInit {
@Input() links: ToCEntry[];
@Input() itemSelected: ToCEntry;
@ -42,6 +42,11 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
private VALID_DROP_TIME = 500;//ms
overcontainer: string = null;
$clock = interval(10);
scrollTableTop = false;
scrollTableBottom = false;
pxToScroll = 15;
constructor(
@Inject(DOCUMENT) private _document: Document,
private dragulaService: DragulaService,
@ -449,6 +454,54 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
}
ngAfterViewInit(): void {
const top = document.querySelector('.top-scroller');
const bottom = document.querySelector('.bottom-scroller');
const tableDiv = document.querySelector('#tocentrytable');
try {
top.addEventListener('mouseover', (e) => {this.scrollTableTop = true; },{
passive: true
});
bottom.addEventListener('mouseover', (e) => {this.scrollTableBottom = true; },{
passive: true
});
top.addEventListener('mouseout', (e) => {this.scrollTableTop = false},{
passive: true
});
bottom.addEventListener('mouseout', (e) => {this.scrollTableBottom = false;},{
passive: true
});
this.$clock
.pipe(
takeUntil(this._destroyed),
filter(() => this.scrollTableTop)
)
.subscribe(()=>{
try{
tableDiv.scrollBy(0, -this.pxToScroll);
} catch {}
});
this.$clock
.pipe(
takeUntil(this._destroyed),
filter(() => this.scrollTableBottom)
)
.subscribe(()=>{
try{
tableDiv.scrollBy(0, this.pxToScroll);
} catch {}
});
} catch {
console.log('could not find scrolling elements');
}
}
private _scrollIntoDragginItem(id: string){
@ -512,10 +565,6 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
ngOnInit(): void {
}
ngOnChanges(changes: SimpleChanges) {
}

View File

@ -1,7 +1,7 @@
<form class="row user-role-editor" [formGroup]="formGroup" (ngSubmit)="formSubmit()">
<div *ngIf="!this.nowEditing"class="roles col">
<ng-container *ngFor="let role of this.formGroup.get('appRoles').value">
<div *ngIf="role!=3">
<div>
<span class="user-role" [ngClass]="{'user': role == 0, 'manager': role == 1, 'admin': role == 2, 'dataset-template-editor': role == 3}">
{{getPrincipalAppRoleWithLanguage(role)}}
</span>
@ -11,7 +11,7 @@
<mat-form-field *ngIf="this.nowEditing" class="select-role roles-width-180 col-auto">
<mat-select formControlName="appRoles" multiple required>
<ng-container *ngFor="let role of getPrincipalAppRoleValues()">
<mat-option [value]="role" *ngIf="role!=3">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
<mat-option [value]="role">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
</ng-container>
</mat-select>
<mat-error *ngIf="getFormControl('appRoles').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>

View File

@ -27,7 +27,7 @@ export class StartNewDatasetDialogComponent extends BaseComponent {
initialItems: (extraData) => this.searchDmp(''),
displayFn: (item) => this.getDatasetDisplay(item),
titleFn: (item) => item['label'],
subtitleFn: (item) => this.language.instant('DATASET-WIZARD.FIRST-STEP.SUB-TITLE') + new Date(item['creationTime']).toISOString()
subtitleFn: (item) => {try{return this.language.instant('DATASET-WIZARD.FIRST-STEP.SUB-TITLE') + new Date(item['creationTime']).toISOString();}catch{return '-';}}
};
constructor(

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"Ο χρήστης δεν βρέθηκε."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Descrição do modelo de dados",
"UNTITLED": "Sem título",
"QUESTION": "Questão",
"TEMPLATE-OUTLINE": "Esquema do modelo"
"TEMPLATE-OUTLINE": "Esquema do modelo",
"ERRORS":{
"USER-NOT-FOUND":"Usuário não encontrado."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Nome do capítulo",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -296,7 +296,10 @@
"DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description",
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline"
"TEMPLATE-OUTLINE": "Template outline",
"ERRORS":{
"USER-NOT-FOUND":"User not found."
}
},
"PAGE-INFO": {
"PAGE-NAME": "Chapter Name",

View File

@ -1,14 +1,14 @@
<div class="confirmation-dialog">
<div *ngIf="data.icon" class="row d-flex flex-row">
<div class="col-auto close-btn justify-content-start">
<div class="row d-flex flex-row" *ngIf="data.icon || data.warning">
<div class="col-auto close-btn justify-content-start" *ngIf="data.icon">
<mat-icon color="warn">{{ data.icon }}</mat-icon>
</div>
<div *ngIf="data.warning" class="col justify-content-center warn-text">{{ data.warning }}</div>
<div *ngIf="data.warning" class="col justify-content-center warn-text"> <h5><strong>{{ data.warning }}</strong></h5></div>
<div class="col-auto close-btn justify-content-end" (click)="close()">
<mat-icon>close</mat-icon>
</div>
</div>
<div class="row justify-content-end mb-1" *ngIf="!data.icon">
<div class="row justify-content-end mb-1" *ngIf="!data.icon && !data.warning">
<div class="col-auto close-btn" (click)="close()">
<mat-icon>close</mat-icon>
</div>

View File

@ -14,7 +14,8 @@
}
.warn-text {
color: #f44336;
// color: #f44336;
}
.cancel {