Add next-previous buttons in dataset editot in order to navigate through chapters

This commit is contained in:
Konstantinos Triantafyllou 2022-10-05 16:22:47 +03:00
parent 4cab6ca160
commit fd2ec314a0
4 changed files with 70 additions and 44 deletions

View File

@ -68,11 +68,16 @@
<div class="stepper-title">{{'DMP-EDITOR.STEPPER.USER-GUIDE' | translate}}</div>
<div class="stepper-options" id="stepper-options">
<div class="col stepper-list">
<div (click)="changeStep(0)" *ngIf="!datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0, 'text-danger':hintErrors}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (2)</div>
<div (click)="changeStep(0)" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
<div class="row toc-pane-container" #boundary (click)="changeStep(1)">
<div (click)="changeStep()" *ngIf="!datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0, 'text-danger':hintErrors}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (2)</div>
<div (click)="changeStep()" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
<div class="row toc-pane-container" #boundary>
<div #spacer></div>
<table-of-contents [visibilityRulesService]="visRulesService" [selectedFieldsetId]="fieldsetIdWithFocus" #table0fContents [showErrors]="showtocentriesErrors" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hasFocus]="step === 1" [formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
<table-of-contents [visibilityRulesService]="visRulesService" [selectedFieldsetId]="fieldsetIdWithFocus" #table0fContents
[showErrors]="showtocentriesErrors" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hasFocus]="step > 0"
[formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links"
[boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)"
(currentLinks)="getLinks($event)" (entrySelected)="changeStep($event)"
[visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
</div>
</div>
</div>
@ -81,6 +86,7 @@
<span class="material-icons">chevron_left</span>
<div>{{'DMP-EDITOR.STEPPER.PREVIOUS' | translate}}</div>
</div>
<div *ngIf="this.step < this.maxStep" mat-raised-button type="button" class="col-auto stepper-btn dataset-next ml-auto" (click)="nextStep()">
<div>{{'DMP-EDITOR.STEPPER.NEXT' | translate}}</div>
<span class="material-icons">chevron_right</span>

View File

@ -1,4 +1,4 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Component, OnInit, ViewChild} from '@angular/core';
import {AbstractControl, FormArray, FormControl, FormGroup} from '@angular/forms';
import {MatDialog} from '@angular/material/dialog';
import {MatSnackBar} from '@angular/material/snack-bar';
@ -14,14 +14,18 @@ import {DmpCriteria} from '@app/core/query/dmp/dmp-criteria';
import {RequestItem} from '@app/core/query/request-item';
import {DatasetWizardService} from '@app/core/services/dataset-wizard/dataset-wizard.service';
import {DmpService} from '@app/core/services/dmp/dmp.service';
import {ExternalSourcesConfigurationService} from '@app/core/services/external-sources/external-sources-configuration.service';
import {
ExternalSourcesConfigurationService
} from '@app/core/services/external-sources/external-sources-configuration.service';
import {ExternalSourcesService} from '@app/core/services/external-sources/external-sources.service';
import {
SnackBarNotificationLevel,
UiNotificationService
} from '@app/core/services/notification/ui-notification-service';
import {SingleAutoCompleteConfiguration} from '@app/library/auto-complete/single/single-auto-complete-configuration';
import {DatasetCopyDialogueComponent} from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
import {
DatasetCopyDialogueComponent
} from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
import {DatasetWizardEditorModel} from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import {IBreadCrumbComponent} from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent';
@ -32,7 +36,9 @@ import {
TableOfContents
} from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents';
import {FormService} from '@common/forms/form-service';
import {FormValidationErrorsDialogComponent} from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
import {
FormValidationErrorsDialogComponent
} from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
import {ValidationErrorModel} from '@common/forms/validation/error-model/validation-error-model';
import {ConfirmationDialogComponent} from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import {TranslateService} from '@ngx-translate/core';
@ -54,6 +60,7 @@ import {VisibilityRulesService} from '@app/ui/misc/dataset-description-form/visi
import {PopupNotificationDialogComponent} from '@app/library/notification/popup/popup-notification.component';
import {CheckDeactivateBaseComponent} from '@app/library/deactivate/deactivate.component';
import {PrefillDatasetComponent} from "@app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component";
import {ToCEntry} from "@app/ui/misc/dataset-description-form/dataset-description.component";
@Component({
selector: 'app-dataset-wizard-component',
@ -94,7 +101,6 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
step: number = 0;
stepOffset: number = 1;
maxStep: number;
saveAnd = SaveType;
datasetSavedLinks: any = null;
@ -260,7 +266,6 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
this.formGroup = this.datasetWizardModel.buildForm();
this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue()));
this.formGroup.get('dmp').disable();
this.maxStep = 1;
this.loadDatasetProfiles();
this.registerFormListeners();
}
@ -437,8 +442,6 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
}]);
}
!this.isNew ? this.maxStep = 1 : this.maxStep = 0;
// this.route.params
// .pipe(takeUntil(this._destroyed))
// .subscribe((params: Params) => {
@ -528,7 +531,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
if (profiledId && profiledId.length > 0) {
this.formGroup.removeControl('datasetProfileDefinition');
this.getDefinition(profiledId);
this.maxStep = 1;
console.log(this.table0fContents.tocentries.length + 1);
}
}
@ -1151,31 +1154,46 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
});
}
public changeStep(index: number, dataset?: FormControl) {
if (this.step != index) { //view is changing
this.resetScroll();
checkSelectedParent(entry: ToCEntry, selected: ToCEntry = null) {
if(!selected) {
selected = this.table0fContents.tocentrySelected;
}
this.step = index;
if(entry.numbering === selected.numbering) {
return true;
} else {
return !!entry.subEntries.find(subEntry => this.checkSelectedParent(subEntry, selected))
}
}
public changeStep(selected: ToCEntry = null) {
if(selected) {
let index = this.table0fContents.tocentries.findIndex(entry => this.checkSelectedParent(entry, selected));
console.log(index);
this.step = index + 1;
} else {
this.table0fContents.onToCentrySelected(null);
this.step = 0;
}
}
get maxStep() {
return this.table0fContents?this.table0fContents.tocentries.length:0;
}
public nextStep() {
if (this.step < this.maxStep) {//view is changing
if (this.step === 0 && this.table0fContents) {
this.table0fContents.seekToFirstElement();
}
this.step++;
this.table0fContents.internalTable.selected = this.table0fContents.tocentries[this.step - 1];
this.resetScroll();
}
// this.step = this.step < this.maxStep ? this.step + 1 : this.step;
}
public previousStep() {
if (this.step > 0) {
this.resetScroll();
this.step--;
this.table0fContents.internalTable.selected = this.step > 0?this.table0fContents.tocentries[this.step - 1]:null;
this.resetScroll();
}
// this.step = this.step !== 0 ? this.step - 1 : this.step;
}
private resetScroll() {

View File

@ -37,7 +37,7 @@ export class TableOfContentsInternal implements OnInit {
}
break;
}
}
}
}
}
}
@ -51,7 +51,7 @@ export class TableOfContentsInternal implements OnInit {
}
break;
}
}
}
}
// if (!this.isActive && this.links && this.links.length > 0) {
// this.links.forEach(link => {
@ -68,12 +68,12 @@ export class TableOfContentsInternal implements OnInit {
navigateToFieldSet(entry:ToCEntry, event){
if(entry.type === ToCEntryType.FieldSet){
const fieldSetId = entry.id;
const element = document.getElementById(this.TOCENTRY_ID_PREFIX+fieldSetId);
if(element){
element.click();//open mat expansion panel
//scroll asyn in 200 ms so the expansion panel is expanded and the element coordinates are updated
setTimeout(() => {
const element = document.getElementById(this.TOCENTRY_ID_PREFIX+fieldSetId);
@ -121,7 +121,7 @@ export class TableOfContentsInternal implements OnInit {
if(tocEntryFound){
return tocEntryFound;
}
}
for(let entry of tocentries){
const result = this._findTocEntryById(id, entry.subEntries);
@ -130,7 +130,7 @@ export class TableOfContentsInternal implements OnInit {
break;
}
}
return tocEntryFound? tocEntryFound: null;
}
public invalidChildsVisible(entry: ToCEntry):boolean {

View File

@ -43,6 +43,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
headerSelectors = '.toc-page-header, .toc-section-header, .toc-compositeField-header';
@Output() stepFound = new EventEmitter<LinkToScroll>();
@Output() currentLinks = new EventEmitter<Link[]>();
@Output() entrySelected = new EventEmitter<ToCEntry>();
subscription: Subscription;
linksSubject: Subject<HTMLElement[]> = new Subject<HTMLElement[]>();
@ -100,7 +101,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
}
}else{
//emit value every 500ms
const source = interval(500);
this.subscription = source.subscribe(val => {
@ -198,20 +199,20 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
private _visibilityRulesSubscription:Subscription;
ngOnChanges(changes: SimpleChanges) {
if(this.selectedFieldsetId){
this.tocentrySelected = this._findTocEntryById(this.selectedFieldsetId,this.tocentries);
this._actOnObservation = false;
setTimeout(() => {
this._actOnObservation = true;
}, 1000);
}
if(changes['hasFocus'] && changes.hasFocus.currentValue){
this._resetObserver();
}
if('visibilityRulesService'){
@ -219,7 +220,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
this._visibilityRulesSubscription.unsubscribe();
this._visibilityRulesSubscription = null;
}
if(!this.visibilityRulesService) return;
this._visibilityRulesSubscription = this.visibilityRulesService.visibilityChange
@ -247,13 +248,13 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
this._intersectionObserver.disconnect();
this._intersectionObserver = null;
}
const options = {
root: null,
rootMargin: '-38% 0px -60% 0px',
threshold: 0
}
this._intersectionObserver = new IntersectionObserver((entries,observer)=>{
if(!this._actOnObservation){
return;
@ -273,7 +274,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
})
}, options);
const fieldsetsEtries = this._getAllFieldSets(this.tocentries);
const fieldsetsEtries = this._getAllFieldSets(this.tocentries);
fieldsetsEtries.forEach(e=>{
if(e.type === ToCEntryType.FieldSet){
@ -338,7 +339,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
const tempResult:ToCEntry[] = [];
if(sections &&sections.length){
sections.controls.forEach(section=>{
tempResult.push(this._buildRecursively(section as FormGroup, ToCEntryType.Section));
@ -374,9 +375,9 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
}
private _sortByOrdinal(tocentries: ToCEntry[]){
if(!tocentries || !tocentries.length) return;
tocentries.sort(this._customCompare);
tocentries.forEach(entry=>{
this._sortByOrdinal(entry.subEntries);
@ -401,7 +402,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
});
}
getTocEntries(form): ToCEntry[] {
if (form == null) { return []; }
const result: ToCEntry[] = [];
@ -442,6 +443,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
onToCentrySelected(entry: ToCEntry){
this.tocentrySelected = entry;
this.entrySelected.emit(entry);
}
@ -460,7 +462,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
if(tocEntryFound){
return tocEntryFound;
}
}
for(let entry of tocentries){
const result = this._findTocEntryById(id, entry.subEntries);
@ -469,7 +471,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges
break;
}
}
return tocEntryFound? tocEntryFound: null;
}
/**