Guided tour added in dataset editor details
This commit is contained in:
parent
9ff36a1b12
commit
24855f776b
|
@ -8,13 +8,16 @@
|
|||
</div> -->
|
||||
<div *ngIf="currentTourStep && !isOrbShowing">
|
||||
<div class="guided-tour-user-input-mask" (click)="backdropClick($event)"></div>
|
||||
<div class="guided-tour-spotlight-overlay" [style.top.px]="overlayTop" [style.left.px]="overlayLeft"
|
||||
[style.height.px]="overlayHeight" [style.width.px]="overlayWidth">
|
||||
<div *ngIf="!isStepUnique" class="guided-tour-spotlight-overlay" [style.top.px]="overlayTop" [style.left.px]="overlayLeft"
|
||||
[style.height.px]="overlayHeight" [style.width.px]="overlayWidth" >
|
||||
</div>
|
||||
<div *ngIf="isStepUnique" class="guided-tour-spotlight-overlay spotlight-overlay-step-unique" [style.top.px]="overlayTop-12" [style.left.px]="overlayLeft-3"
|
||||
[style.height.px]="overlayHeight" [style.width.px]="overlayWidth" >
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="currentTourStep && !isOrbShowing">
|
||||
<div #tourStep *ngIf="currentTourStep" class="tour-step tour-{{ currentTourStep.orientation }}" [ngClass]="{
|
||||
'page-tour-step': !currentTourStep.selector
|
||||
'page-tour-step': !currentTourStep.selector, 'tour-step-unique' : isStepUnique
|
||||
}" [style.top.px]="(currentTourStep.selector && selectedElementRect ? topPosition : null)"
|
||||
[style.left.px]="(currentTourStep.selector && selectedElementRect ? leftPosition : null)"
|
||||
[style.width.px]="(currentTourStep.selector && selectedElementRect ? calculatedTourStepWidth : null)"
|
||||
|
@ -38,7 +41,7 @@
|
|||
(click)="guidedTourService.nextStep()">
|
||||
{{ nextText }}
|
||||
</button>
|
||||
<button *ngIf="!guidedTourService.onResizeMessage" (click)="guidedTourService.skipTour()"
|
||||
<button *ngIf="!guidedTourService.onResizeMessage && !isStepUnique" (click)="guidedTourService.skipTour()"
|
||||
class="skip-button link-button">
|
||||
{{ skipText }}
|
||||
</button>
|
||||
|
|
|
@ -17,6 +17,10 @@ ngx-guided-tour {
|
|||
border-radius: 44px;
|
||||
}
|
||||
|
||||
.spotlight-overlay-step-unique {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.tour-orb {
|
||||
position: fixed;
|
||||
width: 20px;
|
||||
|
@ -53,6 +57,10 @@ ngx-guided-tour {
|
|||
}
|
||||
}
|
||||
|
||||
.tour-step-unique {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.tour-step {
|
||||
position: fixed;
|
||||
&.page-tour-step {
|
||||
|
@ -133,9 +141,9 @@ ngx-guided-tour {
|
|||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.tour-progress-indicator {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
// .tour-progress-indicator {
|
||||
// padding-bottom: 15px;
|
||||
// }
|
||||
|
||||
.tour-title {
|
||||
font-weight: lighter !important;
|
||||
|
@ -149,6 +157,7 @@ ngx-guided-tour {
|
|||
line-height: 26px;
|
||||
white-space:pre-line;
|
||||
height: 182px;
|
||||
width: 983px;
|
||||
}
|
||||
|
||||
h3.tour-title {
|
||||
|
@ -158,11 +167,11 @@ ngx-guided-tour {
|
|||
font-size: 30px;
|
||||
}
|
||||
|
||||
.tour-content {
|
||||
min-height: 80px;
|
||||
padding-bottom: 30px;
|
||||
font-size: 15px;
|
||||
}
|
||||
// .tour-content {
|
||||
// min-height: 80px;
|
||||
// padding-bottom: 30px;
|
||||
// font-size: 15px;
|
||||
// }
|
||||
|
||||
.tour-buttons {
|
||||
overflow: hidden; // clearfix
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, ViewChild, ViewEncapsulation, TemplateRef, Inject } from '@angular/core';
|
||||
import { fromEvent, Subscription } from 'rxjs';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Orientation, TourStep, ProgressIndicatorLocation } from './guided-tour.constants';
|
||||
import { Orientation, TourStep } from './guided-tour.constants';
|
||||
import { GuidedTourService } from './guided-tour.service';
|
||||
import { WindowRefService } from "./windowref.service";
|
||||
|
||||
|
@ -12,22 +12,23 @@ import { WindowRefService } from "./windowref.service";
|
|||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class GuidedTourComponent implements AfterViewInit, OnDestroy {
|
||||
@Input() public topOfPageAdjustment ?= 0;
|
||||
@Input() public tourStepWidth ?= 1043;
|
||||
@Input() public minimalTourStepWidth ?= 900;
|
||||
@Input() public skipText ?= 'Leave Tour';
|
||||
@Input() public nextText ?= 'Got it!';
|
||||
@Input() public doneText ?= 'Done';
|
||||
@Input() public closeText ?= 'Close';
|
||||
@Input() public backText ?= 'Back';
|
||||
@Input() public progressIndicatorLocation?: ProgressIndicatorLocation = ProgressIndicatorLocation.InsideNextButton;
|
||||
@Input() public topOfPageAdjustment?= 0;
|
||||
@Input() public tourStepWidth?= 1043;
|
||||
@Input() public minimalTourStepWidth?= 900;
|
||||
@Input() public skipText?= 'Leave Tour';
|
||||
@Input() public nextText?= 'Got it!';
|
||||
// @Input() public doneText?= 'Done';
|
||||
// @Input() public closeText?= 'Close';
|
||||
// @Input() public backText?= 'Back';
|
||||
// @Input() public progressIndicatorLocation?: ProgressIndicatorLocation = ProgressIndicatorLocation.InsideNextButton;
|
||||
@Input() public progressIndicator?: TemplateRef<any> = undefined;
|
||||
@ViewChild('tourStep', { static: false }) public tourStep: ElementRef;
|
||||
public highlightPadding = 4;
|
||||
public currentTourStep: TourStep = null;
|
||||
public selectedElementRect: DOMRect = null;
|
||||
public isOrbShowing = false;
|
||||
public progressIndicatorLocations = ProgressIndicatorLocation;
|
||||
// public progressIndicatorLocations = ProgressIndicatorLocation;
|
||||
public isStepUnique = false;
|
||||
|
||||
private resizeSubscription: Subscription;
|
||||
private scrollSubscription: Subscription;
|
||||
|
@ -58,11 +59,13 @@ export class GuidedTourComponent implements AfterViewInit, OnDestroy {
|
|||
}
|
||||
|
||||
public get calculatedTourStepWidth() {
|
||||
return this.tourStepWidth - this.widthAdjustmentForScreenBound;
|
||||
return this.tourStepWidth;
|
||||
// return this.tourStepWidth - this.widthAdjustmentForScreenBound;
|
||||
}
|
||||
|
||||
public ngAfterViewInit(): void {
|
||||
this.guidedTourService.guidedTourCurrentStepStream.subscribe((step: TourStep) => {
|
||||
this.isStepUnique = this.guidedTourService.isStepUnique;
|
||||
this.currentTourStep = step;
|
||||
if (step && step.selector) {
|
||||
const selectedElement = this.dom.querySelector(step.selector);
|
||||
|
@ -203,8 +206,8 @@ export class GuidedTourComponent implements AfterViewInit, OnDestroy {
|
|||
private isBottom(): boolean {
|
||||
return this.currentTourStep.orientation
|
||||
&& (this.currentTourStep.orientation === Orientation.Bottom
|
||||
|| this.currentTourStep.orientation === Orientation.BottomLeft
|
||||
|| this.currentTourStep.orientation === Orientation.BottomRight);
|
||||
|| this.currentTourStep.orientation === Orientation.BottomLeft
|
||||
|| this.currentTourStep.orientation === Orientation.BottomRight);
|
||||
}
|
||||
|
||||
public get topPosition(): number {
|
||||
|
|
|
@ -68,8 +68,8 @@ export class Orientation {
|
|||
public static readonly TopRight = 'top-right';
|
||||
}
|
||||
|
||||
export enum ProgressIndicatorLocation {
|
||||
InsideNextButton = 'inside-next-button',
|
||||
TopOfTourBlock = 'top-of-tour-block',
|
||||
None = 'none',
|
||||
}
|
||||
// export enum ProgressIndicatorLocation {
|
||||
// InsideNextButton = 'inside-next-button',
|
||||
// TopOfTourBlock = 'top-of-tour-block',
|
||||
// None = 'none',
|
||||
// }
|
||||
|
|
|
@ -18,6 +18,7 @@ export class GuidedTourService {
|
|||
private _onFirstStep = true;
|
||||
private _onLastStep = true;
|
||||
private _onResizeMessage = false;
|
||||
public isStepUnique = false;
|
||||
|
||||
constructor(
|
||||
public errorHandler: ErrorHandler,
|
||||
|
@ -77,33 +78,33 @@ export class GuidedTourService {
|
|||
}
|
||||
}
|
||||
|
||||
public backStep(): void {
|
||||
if (this._currentTour.steps[this._currentTourStepIndex].closeAction) {
|
||||
this._currentTour.steps[this._currentTourStepIndex].closeAction();
|
||||
}
|
||||
if (this._currentTour.steps[this._currentTourStepIndex - 1]) {
|
||||
this._currentTourStepIndex--;
|
||||
this._setFirstAndLast();
|
||||
if (this._currentTour.steps[this._currentTourStepIndex].action) {
|
||||
this._currentTour.steps[this._currentTourStepIndex].action();
|
||||
setTimeout(() => {
|
||||
if (this._checkSelectorValidity()) {
|
||||
this._guidedTourCurrentStepSubject.next(this.getPreparedTourStep(this._currentTourStepIndex));
|
||||
} else {
|
||||
this.backStep();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (this._checkSelectorValidity()) {
|
||||
this._guidedTourCurrentStepSubject.next(this.getPreparedTourStep(this._currentTourStepIndex));
|
||||
} else {
|
||||
this.backStep();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.resetTour();
|
||||
}
|
||||
}
|
||||
// public backStep(): void {
|
||||
// if (this._currentTour.steps[this._currentTourStepIndex].closeAction) {
|
||||
// this._currentTour.steps[this._currentTourStepIndex].closeAction();
|
||||
// }
|
||||
// if (this._currentTour.steps[this._currentTourStepIndex - 1]) {
|
||||
// this._currentTourStepIndex--;
|
||||
// this._setFirstAndLast();
|
||||
// if (this._currentTour.steps[this._currentTourStepIndex].action) {
|
||||
// this._currentTour.steps[this._currentTourStepIndex].action();
|
||||
// setTimeout(() => {
|
||||
// if (this._checkSelectorValidity()) {
|
||||
// this._guidedTourCurrentStepSubject.next(this.getPreparedTourStep(this._currentTourStepIndex));
|
||||
// } else {
|
||||
// this.backStep();
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// if (this._checkSelectorValidity()) {
|
||||
// this._guidedTourCurrentStepSubject.next(this.getPreparedTourStep(this._currentTourStepIndex));
|
||||
// } else {
|
||||
// this.backStep();
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// this.resetTour();
|
||||
// }
|
||||
// }
|
||||
|
||||
public skipTour(): void {
|
||||
if (this._currentTour.skipCallback) {
|
||||
|
@ -144,6 +145,13 @@ export class GuidedTourService {
|
|||
}
|
||||
}
|
||||
|
||||
public checkIfStepIsUnique(tour: GuidedTour): boolean {
|
||||
if(tour.steps.length === 1) {
|
||||
this.isStepUnique = true;
|
||||
}
|
||||
return this.isStepUnique;
|
||||
}
|
||||
|
||||
public activateOrb(): void {
|
||||
this._guidedTourOrbShowingSubject.next(false);
|
||||
this.dom.body.classList.add('tour-open');
|
||||
|
|
|
@ -34,18 +34,20 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
<!-- End of Sort by -->
|
||||
<!-- Guided Tour -->
|
||||
<div class="center-content" [style.display]=" (!isVisible && isAuthenticated()) ? 'block' : 'none'" (click)="restartTour()">
|
||||
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
|
||||
<div class="d-flex flex-row ml-auto">
|
||||
<!-- Guided Tour -->
|
||||
<div class="center-content" [style.display]=" (!isVisible && isAuthenticated()) ? 'block' : 'none'" (click)="restartTour()">
|
||||
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
|
||||
</div>
|
||||
<!-- End of Guided Tour -->
|
||||
<!-- Search Filter-->
|
||||
<mat-form-field appearance="outline" class="search-form ml-auto col-auto" floatLabel="never">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<input matInput placeholder="{{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- End of Search Filter -->
|
||||
</div>
|
||||
<!-- End of Guided Tour -->
|
||||
<!-- Search Filter-->
|
||||
<mat-form-field appearance="outline" class="search-form ml-auto col-auto" floatLabel="never">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<input matInput placeholder="{{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- End of Search Filter -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12 col-md-9">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="heading">1.1 {{'DATASET-EDITOR.FIELDS.TITLE' | translate}}*</div>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link" target="_blank" [routerLink]="['/overview/' + dmpId]">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link dmp-only-tour-title" target="_blank" (click)="restartTourFromTitle()">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
|
||||
<div class="title-form">
|
||||
<mat-form-field appearance="outline">
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.TITLE' | translate}}" type="text" name="label" formControlName="label" required>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="heading">1.2 {{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}</div>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link" target="_blank" [routerLink]="['/overview/' + dmpId]">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link dmp-only-tour-desc" target="_blank" (click)="restartTourFromDesc()">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
|
||||
<div class="description-form">
|
||||
<mat-form-field appearance="outline">
|
||||
<textarea rows="3" matInput class="description-area" placeholder="{{'DMP-EDITOR.PLACEHOLDER.DESCRIPTION' | translate}}" formControlName="description"></textarea>
|
||||
|
|
|
@ -27,6 +27,8 @@ import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-
|
|||
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
|
||||
import { DatasetWizardEditorModel, ExternalTagEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
||||
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
|
||||
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -57,6 +59,7 @@ export class DatasetEditorDetailsComponent extends BaseComponent implements OnIn
|
|||
// isLinear = false;
|
||||
lock: LockModel;
|
||||
lockStatus: Boolean;
|
||||
dmpText: string;
|
||||
|
||||
@Input() formGroup: FormGroup;
|
||||
@Input() dmpId: string;
|
||||
|
@ -79,7 +82,8 @@ export class DatasetEditorDetailsComponent extends BaseComponent implements OnIn
|
|||
private formService: FormService,
|
||||
private lockService: LockService,
|
||||
private location: Location,
|
||||
private authService: AuthService
|
||||
private authService: AuthService,
|
||||
private guidedTourService: GuidedTourService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
@ -133,6 +137,53 @@ export class DatasetEditorDetailsComponent extends BaseComponent implements OnIn
|
|||
}
|
||||
}
|
||||
|
||||
public dashboardTourDmpTitle: GuidedTour = {
|
||||
tourId: 'only-dmp-tour',
|
||||
useOrb: true,
|
||||
steps: [
|
||||
{
|
||||
title: this.dmpText,
|
||||
selector: '.dmp-only-tour-title',
|
||||
content: 'Step 1',
|
||||
orientation: Orientation.Bottom
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
public dashboardTourDmpDescription: GuidedTour = {
|
||||
tourId: 'only-dmp-tour',
|
||||
useOrb: true,
|
||||
steps: [
|
||||
{
|
||||
title: this.dmpText,
|
||||
selector: '.dmp-only-tour-desc',
|
||||
content: 'Step 1',
|
||||
orientation: Orientation.Bottom
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
setDashboardTourDmpText(): void {
|
||||
this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
||||
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
|
||||
this.language.instant('DMP-LISTING.GET-IDEA');
|
||||
this.dashboardTourDmpTitle.steps[0].title = this.dmpText;
|
||||
this.dashboardTourDmpDescription.steps[0].title = this.dmpText;
|
||||
}
|
||||
|
||||
public restartTourFromTitle(): void {
|
||||
this.setDashboardTourDmpText();
|
||||
this.guidedTourService.checkIfStepIsUnique(this.dashboardTourDmpTitle);
|
||||
this.guidedTourService.startTour(this.dashboardTourDmpTitle);
|
||||
}
|
||||
|
||||
public restartTourFromDesc(): void {
|
||||
this.setDashboardTourDmpText();
|
||||
this.guidedTourService.checkIfStepIsUnique(this.dashboardTourDmpDescription);
|
||||
this.guidedTourService.startTour(this.dashboardTourDmpDescription);
|
||||
}
|
||||
|
||||
registerFormListeners() {
|
||||
this.formGroup.get('dmp').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
|
|
|
@ -29,18 +29,24 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
<!-- End of Sort by -->
|
||||
<!-- Guided Tour -->
|
||||
<div class="center-content" [style.display]="!isVisible && isAuthenticated()? 'block' : 'none'" (click)="restartTour()">
|
||||
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
|
||||
<div class="d-flex flex-row ml-auto">
|
||||
<!-- Guided Tour -->
|
||||
<div class="center-content"
|
||||
[style.display]="!isVisible && isAuthenticated()? 'block' : 'none'" (click)="restartTour()">
|
||||
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
|
||||
</div>
|
||||
<!-- End of Guided Tour -->
|
||||
<!-- Search Filter-->
|
||||
<mat-form-field appearance="outline" class="search-form ml-auto col-auto pr-0"
|
||||
floatLabel="never">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<input matInput placeholder="{{'CRITERIA.DMP.LIKE'| translate}}" name="likeCriteria"
|
||||
[formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">
|
||||
{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- End of Search Filter -->
|
||||
</div>
|
||||
<!-- End of Guided Tour -->
|
||||
<!-- Search Filter-->
|
||||
<mat-form-field appearance="outline" class="search-form ml-auto col-auto pr-0" floatLabel="never">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<input matInput placeholder="{{'CRITERIA.DMP.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- End of Search Filter -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12 col-md-9">
|
||||
|
|
|
@ -197,6 +197,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
|
|||
public isAuthenticated(): boolean {
|
||||
return !(!this.authService.current());
|
||||
}
|
||||
|
||||
ngAfterContentChecked(): void {
|
||||
this.scrollbar = this.hasScrollbar();
|
||||
}
|
||||
|
@ -470,6 +471,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
|
|||
public restartTour(): void {
|
||||
this.setDashboardTourDmpText();
|
||||
this.setDashboardTourDatasetText();
|
||||
this.guidedTourService.checkIfStepIsUnique(this.dashboardTour);
|
||||
this.guidedTourService.startTour(this.dashboardTour);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue