User Dataset Editor. Pages/ Sections/Fieldsets that have all inputs hidden, are hidden as well (Both on template and table of contents).

This commit is contained in:
Kristian Ntavidi 2021-04-12 19:08:09 +03:00
parent 4a1f260849
commit 198eb838c5
10 changed files with 110 additions and 43 deletions

View File

@ -165,7 +165,6 @@
</div> </div>
<div class="col-12"> <div class="col-12">
<!-- <div class="heading">1.3 {{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}</div> -->
<div class="heading">1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div> <div class="heading">1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="full-width basic-info-input"> <div class="full-width basic-info-input">
<table class="col-12 user-table"> <table class="col-12 user-table">
@ -179,13 +178,11 @@
<td>{{user.name}}</td> <td>{{user.name}}</td>
<td >{{user.email}}</td> <td >{{user.email}}</td>
<td> <td>
<!-- <button mat-raised-button class="delete-btn" (click)="removeUser(user)">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate}}</button> -->
<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> <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> </td>
</tr> </tr>
<tr *ngIf="!userChipList || !userChipList.length"> <tr *ngIf="!userChipList || !userChipList.length">
<td style="text-align: end; line-height: 3em;" colspan="2" > <td style="text-align: end; line-height: 3em;" colspan="2" >
<!-- ...No users yet -->
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}} {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td> </td>
</tr> </tr>
@ -197,18 +194,11 @@
<div class="col-12"> <div class="col-12">
<div class="row justify-content-end"> <div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;"> <div class="col d-flex justify-content-end" style="overflow: hidden;">
<!-- <div class="row"> <div style="min-width: 20em;max-width: 25em;" [@add-new-user-field]="inputUserState">
<input matInput #email class = "col-8 email-input" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}"> <mat-form-field appearance="legacy">
<button mat-raised-button color="primary" (click)="checkAndAdd(email.value)">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate}}</button> <input matInput #email placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</div> --> </mat-form-field>
<!-- <div class="row"> --> </div>
<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>
<!-- <button mat-raised-button color="primary" (click)="checkAndAdd(email.value)">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate}}</button> -->
<!-- </div> -->
</div> </div>
<div class="col-auto"> <div class="col-auto">

View File

@ -249,7 +249,6 @@ export class DatasetInfoComponent extends BaseComponent implements OnInit {
}); });
} }
onOptionSelected(){ onOptionSelected(){
console.log('this option selected emited');
try{ try{
const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
profiles.sort((a,b)=> a.label.localeCompare(b.label)); profiles.sort((a,b)=> a.label.localeCompare(b.label));

View File

@ -78,7 +78,7 @@
<div *ngFor="let fieldsetEntry of tocentry.subEntries; let i = index;" class="col-12" [id]="TOCENTRY_ID_PREFIX+fieldsetEntry.id" (click)="onAskedToScroll(fieldsetEntry.id)"> <div *ngFor="let fieldsetEntry of tocentry.subEntries; let i = index;" class="col-12" [id]="TOCENTRY_ID_PREFIX+fieldsetEntry.id" (click)="onAskedToScroll(fieldsetEntry.id)">
<!-- <div *ngIf="isElementVisible(compositeField)" class="row"> --> <!-- <div *ngIf="isElementVisible(compositeField)" class="row"> -->
<!-- *ngIf="this.visibilityRulesService.checkElementVisibility(compositeFieldFormGroup.get('id').value)" --> <!-- *ngIf="this.visibilityRulesService.checkElementVisibility(compositeFieldFormGroup.get('id').value)" -->
<div class="row" *ngIf="this.visibilityRulesService.checkElementVisibility(fieldsetEntry.form.get('id').value) && this.visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(fieldsetEntry.form)"> <div class="row" *ngIf="(this.visibilityRulesService.checkElementVisibility(fieldsetEntry.form.get('id').value) && this.visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(fieldsetEntry.form)) && !hiddenEntriesIds.includes(fieldsetEntry.id)">
<div class="col-12"> <div class="col-12">
<div class="row"> <div class="row">
@ -121,12 +121,15 @@
<!-- SECTION CASE --> <!-- SECTION CASE -->
<div *ngIf="form.get('sections')" class="col-12"><!-- MAYBEE NOT NEEDED--> <div *ngIf="form.get('sections')" class="col-12"><!-- MAYBEE NOT NEEDED-->
<div *ngFor="let sectionEntry of tocentry.subEntries; let j = index;" class="row"> <ng-container *ngFor="let sectionEntry of tocentry.subEntries; let j = index;">
<app-form-section [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" class="col-12" [tocentry]="sectionEntry" [form]="sectionEntry.form" [path]="path+'.'+(j+1)" [pathName]="pathName+'.sections.'+j" [linkToScroll]="subsectionLinkToScroll" <div class="row" *ngIf="!hiddenEntriesIds.includes(sectionEntry.id)">
[datasetProfileId]="datasetProfileId" <app-form-section [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" class="col-12" [tocentry]="sectionEntry" [form]="sectionEntry.form" [path]="path+'.'+(j+1)" [pathName]="pathName+'.sections.'+j" [linkToScroll]="subsectionLinkToScroll"
(askedToScroll)="onAskedToScroll($event)" [datasetProfileId]="datasetProfileId"
></app-form-section> (askedToScroll)="onAskedToScroll($event)"
</div> [hiddenEntriesIds]="hiddenEntriesIds"
></app-form-section>
</div>
</ng-container>
</div> </div>
</ng-container> </ng-container>

View File

@ -22,6 +22,7 @@ export class FormSectionComponent implements OnInit, OnChanges {
@Input() pathName: string; @Input() pathName: string;
@Input() path: string; @Input() path: string;
@Input() linkToScroll: LinkToScroll; @Input() linkToScroll: LinkToScroll;
@Input() hiddenEntriesIds: string[] = [];
//trackByFn = (index, item) => item ? item['id'] : null; //trackByFn = (index, item) => item ? item['id'] : null;
panelExpanded = true; panelExpanded = true;
// sub = true; // sub = true;

View File

@ -21,8 +21,8 @@
<!--FIRST LEVEL ALWAYS PAGE--> <!--FIRST LEVEL ALWAYS PAGE-->
<mat-accordion [multi]="true"> <mat-accordion [multi]="true">
<div *ngFor="let pageEntry of tocentries; let z = index;"> <ng-container *ngFor="let pageEntry of tocentries; let z = index;">
<mat-expansion-panel [expanded]="true" #expansionPanel> <mat-expansion-panel [expanded]="true" #expansionPanel *ngIf="!hiddenEntriesIds.includes(pageEntry.id)">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> <mat-panel-title>
@ -34,17 +34,18 @@
<!-- <!--
<h4 class="toc-page-header"> <h4 class="toc-page-header">
</h4> --> </h4> -->
<div *ngFor="let sectionEntry of pageEntry.subEntries; let i = index;"> <ng-container *ngFor="let sectionEntry of pageEntry.subEntries; let i = index;">
<div class="row"> <div class="row" *ngIf="!hiddenEntriesIds.includes(sectionEntry.id)">
<app-form-section [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" class="col-12" [tocentry]="sectionEntry" [path]="z+1" <app-form-section [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" class="col-12" [tocentry]="sectionEntry" [path]="z+1"
[pathName]="'pages.'+z+'.sections.'+i" [datasetProfileId]="datasetProfileId" [pathName]="'pages.'+z+'.sections.'+i" [datasetProfileId]="datasetProfileId"
[linkToScroll]="linkToScroll" [linkToScroll]="linkToScroll"
(askedToScroll)="onAskedToScroll(expansionPanel, $event)" (askedToScroll)="onAskedToScroll(expansionPanel, $event)"
[hiddenEntriesIds]="hiddenEntriesIds"
></app-form-section> ></app-form-section>
</div> </div>
</div> </ng-container>
</mat-expansion-panel> </mat-expansion-panel>
</div> </ng-container>
</mat-accordion> </mat-accordion>
</ng-template> </ng-template>

View File

@ -7,7 +7,7 @@ import { DatasetProfileTableOfContentsInternalSection } from '@app/ui/admin/data
import { LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents'; import { LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service'; import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators'; import { debounceTime, takeUntil } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-dataset-description', selector: 'app-dataset-description',
@ -29,8 +29,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
@Input() TOCENTRY_ID_PREFIX=""; @Input() TOCENTRY_ID_PREFIX="";
public hiddenEntriesIds:string[] = [];
private _form: FormGroup;
constructor( constructor(
private visibilityRulesService: VisibilityRulesService, private visibilityRulesService: VisibilityRulesService,
@ -50,6 +49,16 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
// } // }
this.tocentries = this.getTocEntries(); this.tocentries = this.getTocEntries();
this.hiddenEntriesIds = this._findHiddenEntries(this.tocentries);
this.visibilityRulesService.visibilityChange
.pipe(
takeUntil(this._destroyed),
debounceTime(100)
)
.subscribe(_=>{
this.hiddenEntriesIds = this._findHiddenEntries(this.tocentries);
})
} }
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
@ -153,7 +162,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
getTocEntries(): ToCEntry[] { getTocEntries(): ToCEntry[] {
if (this.form == null) { return []; } if (!this.form) { return []; }
const result: ToCEntry[] = []; const result: ToCEntry[] = [];
//build parent pages //build parent pages
@ -189,6 +198,38 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
return result; return result;
} }
private _findHiddenEntries(tocentries:ToCEntry[]):string[]{
if(!tocentries) return [];
const invisibleEntries:string[] = []
tocentries.forEach(entry=>{
if(entry.type === ToCEntryType.FieldSet){
const isVisible = this.visibilityRulesService.checkElementVisibility(entry.id);
if(!isVisible){
invisibleEntries.push(entry.id);
}else{
//check field inputs
const fields = entry.form.get('fields') as FormArray;
const oneFieldAtLeastIsVisible = fields.controls.some(field=> this.visibilityRulesService.checkElementVisibility(field.get('id').value));
if(!oneFieldAtLeastIsVisible){
invisibleEntries.push(entry.id);
}
}
}else{
const hiddenEntries = this._findHiddenEntries(entry.subEntries);
if(entry.subEntries&& (entry.subEntries.every(e=> hiddenEntries.includes(e.id)))){
//all children all hidden then hide parent node;
invisibleEntries.push(entry.id);
}else{
invisibleEntries.push(...hiddenEntries);
}
}
})
return invisibleEntries;
}
} }
export interface ToCEntry { export interface ToCEntry {

View File

@ -1,6 +1,6 @@
<div *ngFor="let entry of tocentries; index as idx"> <div *ngFor="let entry of tocentries; index as idx">
<!-- check if is visible --> <!-- check if is visible -->
<ng-container *ngIf="visibilityRulesService.checkElementVisibility(entry.id)"> <ng-container *ngIf="!hiddenEntries.includes(entry.id)">
<!-- Is fieldset and has no visible inputs --> <!-- Is fieldset and has no visible inputs -->
<ng-container *ngIf="!(entry.type === tocEntryTypeEnum.FieldSet && !visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(entry.form))"> <ng-container *ngIf="!(entry.type === tocEntryTypeEnum.FieldSet && !visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(entry.form))">
@ -33,7 +33,8 @@
(entrySelected)="onEntrySelected($event)" (entrySelected)="onEntrySelected($event)"
[selected]="selected" [selected]="selected"
[TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX"
[showErrors]="showErrors"> [showErrors]="showErrors"
[hiddenEntries]="hiddenEntries">
</table-of-contents-internal> </table-of-contents-internal>
</div> </div>

View File

@ -25,6 +25,7 @@ export class TableOfContentsInternal implements OnInit {
tocEntryTypeEnum = ToCEntryType; tocEntryTypeEnum = ToCEntryType;
@Input() TOCENTRY_ID_PREFIX=""; @Input() TOCENTRY_ID_PREFIX="";
@Input() showErrors: boolean = false; @Input() showErrors: boolean = false;
@Input() hiddenEntries: string[] =[];
constructor(public visibilityRulesService: VisibilityRulesService){ constructor(public visibilityRulesService: VisibilityRulesService){

View File

@ -31,6 +31,7 @@
[showErrors]="showErrors" [showErrors]="showErrors"
(entrySelected)="onToCentrySelected($event)" (entrySelected)="onToCentrySelected($event)"
[selected]="tocentrySelected" [selected]="tocentrySelected"
[hiddenEntries]="hiddenEntries"
> >

View File

@ -54,8 +54,8 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
private _tocentrySelected:ToCEntry = null; private _tocentrySelected:ToCEntry = null;
private _intersectionObserver: IntersectionObserver; private _intersectionObserver: IntersectionObserver;
private _actOnObservation: boolean = true; private _actOnObservation: boolean = true;
public hiddenEntries:string[] = [];
get tocentrySelected(){ get tocentrySelected(){
return this.hasFocus?this._tocentrySelected: null; return this.hasFocus?this._tocentrySelected: null;
} }
set tocentrySelected(value){ set tocentrySelected(value){
@ -80,9 +80,9 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.pipe(debounceTime(200)) .pipe(debounceTime(200))
.subscribe(_=>{ .subscribe(_=>{
// console.log('visibility was changed');
if(this.hasFocus){ if(this.hasFocus){
this._resetObserver(); this._resetObserver();
this.hiddenEntries = this._findHiddenEntries(this.tocentries);
} }
}) })
@ -90,6 +90,8 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
this.tocentries = this.getTocEntries(this.formGroup.get('datasetProfileDefinition')); this.tocentries = this.getTocEntries(this.formGroup.get('datasetProfileDefinition'));
const fg = this.formGroup.get('datasetProfileDefinition'); const fg = this.formGroup.get('datasetProfileDefinition');
this.visibilityRulesService.buildVisibilityRules(this.visibilityRules, fg); this.visibilityRulesService.buildVisibilityRules(this.visibilityRules, fg);
this.hiddenEntries = this._findHiddenEntries(this.tocentries);
}else{ }else{
//emit value every 500ms //emit value every 500ms
@ -154,6 +156,39 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
} }
private _findHiddenEntries(tocentries:ToCEntry[]):string[]{
if(!tocentries) return [];
const invisibleEntries:string[] = []
tocentries.forEach(entry=>{
if(entry.type === ToCEntryType.FieldSet){
const isVisible = this.visibilityRulesService.checkElementVisibility(entry.id);
if(!isVisible){
invisibleEntries.push(entry.id);
}else{
//check field inputs
const fields = entry.form.get('fields') as FormArray;
const oneFieldAtLeastIsVisible = fields.controls.some(field=> this.visibilityRulesService.checkElementVisibility(field.get('id').value));
if(!oneFieldAtLeastIsVisible){
invisibleEntries.push(entry.id);
}
}
}else{
const hiddenEntries = this._findHiddenEntries(entry.subEntries);
if(entry.subEntries&& (entry.subEntries.every(e=> hiddenEntries.includes(e.id)))){
//all children all hidden then hide parent node;
invisibleEntries.push(entry.id);
}else{
invisibleEntries.push(...hiddenEntries);
}
}
})
return invisibleEntries;
}
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if(this.selectedFieldsetId){ if(this.selectedFieldsetId){
@ -184,7 +219,6 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
if(this._intersectionObserver){//clean up if(this._intersectionObserver){//clean up
this._intersectionObserver.disconnect(); this._intersectionObserver.disconnect();
this._intersectionObserver = null; this._intersectionObserver = null;
// console.log('Clean Up observer');
} }
const options = { const options = {
@ -197,8 +231,6 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
if(!this._actOnObservation){ if(!this._actOnObservation){
return; return;
} }
// console.log('observer called for element', entries );
// console.log('from observer', observer);
entries.forEach(ie=>{ entries.forEach(ie=>{
if(ie.isIntersecting){ if(ie.isIntersecting){
@ -206,7 +238,6 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
const target_id = ie.target.id.replace(this.TOCENTRY_ID_PREFIX,''); const target_id = ie.target.id.replace(this.TOCENTRY_ID_PREFIX,'');
if(this.visibilityRulesService.checkElementVisibility(target_id)){ if(this.visibilityRulesService.checkElementVisibility(target_id)){
this.tocentrySelected = this._findTocEntryById(target_id,this.tocentries); this.tocentrySelected = this._findTocEntryById(target_id,this.tocentries);
// console.log('target id', target_id);
} }
}catch{ }catch{
@ -215,7 +246,6 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
}) })
}, options); }, options);
// console.log('Initializing Intersection Observer');
const fieldsetsEtries = this._getAllFieldSets(this.tocentries); const fieldsetsEtries = this._getAllFieldSets(this.tocentries);
fieldsetsEtries.forEach(e=>{ fieldsetsEtries.forEach(e=>{
@ -385,7 +415,6 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
onToCentrySelected(entry: ToCEntry){ onToCentrySelected(entry: ToCEntry){
this.tocentrySelected = entry; this.tocentrySelected = entry;
// console.log('entry selected', entry);
} }