bdc-walkthrough
Version:
An Angular Material library for displaying walk-through pop-ups and dialogs using a declarative way
670 lines (666 loc) • 51.6 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, TemplateRef, ViewChild, Output, Input, ViewEncapsulation, Component, ContentChild, HostBinding, HostListener, Inject, Optional, Directive } from '@angular/core';
import { BehaviorSubject, Subject, Subscription, of, merge } from 'rxjs';
import * as _ from 'lodash';
import * as i1 from '@angular/material/dialog';
import { MatMenu, MAT_MENU_SCROLL_STRATEGY } from '@angular/material/menu';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { MatButton } from '@angular/material/button';
import * as i2 from '@angular/cdk/overlay';
import { OverlayConfig } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import { takeUntil, filter, take } from 'rxjs/operators';
import * as i3 from '@angular/cdk/bidi';
class BdcWalkService {
get disabled() {
return this._disabled;
}
constructor() {
this._notify = new BehaviorSubject(null);
this._notifyDisplaying = new Subject();
this._displaying = {};
this._version = 1;
this._key = 'bdcWalkthrough';
this._disabled = false;
this.changes = this._notify.asObservable();
this.changesDisplaying = this._notifyDisplaying.asObservable();
this._values = JSON.parse(localStorage.getItem(this._key)) || {};
// reset all values if version is different
if (this._values.version !== this._version) {
this.reset();
}
}
migrate(migrations) {
const version = this._values.migrationVersion || 0;
migrations.filter(migration => migration.version > version).forEach(migration => {
console.log(`Running bdc-migration version ${migration.version}`);
migration.operations.forEach(operation => {
if (this.evalMustCompleted(operation.condition)) {
Object.entries(operation.then).forEach(([id, data]) => {
if (data) {
this._values[id] = data;
}
else {
delete this._values[id];
}
});
}
});
this._values.migrationVersion = migration.version;
});
this.save();
}
getIsDisplaying(id) {
return this._displaying[id] || false;
}
setIsDisplaying(id, visible) {
if (this._displaying[id] !== visible) {
if (visible) {
this._displaying[id] = visible;
}
else {
delete this._displaying[id];
}
this._notify.next();
this._notifyDisplaying.next({ id, visible, action: BdcDisplayEventAction.VisibilityChanged });
}
}
logUserAction(id, action) {
this._notifyDisplaying.next({ id, visible: false, action });
}
getTaskCompleted(id) {
return this._values[id] || false;
}
setTaskCompleted(id, value = true) {
if (this._values[id] !== value && value) {
this._values[id] = value;
this.save();
}
else if (this._values.hasOwnProperty(id) && !value) {
delete this._values[id];
this.save();
}
}
setTasks(tasks) {
let changed = false;
Object.entries(tasks).forEach(([id, data]) => {
if (this._values[id] !== data && data) {
this._values[id] = data;
changed = true;
}
else if (this._values.hasOwnProperty(id) && !data) {
delete this._values[id];
changed = true;
}
});
if (changed) {
this.save();
}
}
getTasks() {
return { ...this._values };
}
reset(prefix) {
if (prefix) {
// remove only keys prefixed with param
Object.keys(this._values).filter(key => key.startsWith(prefix)).forEach(keyToRemove => delete this._values[keyToRemove]);
}
else {
// remove all keys
this._values = { version: this._version };
}
this.save();
}
disableAll(disabled = true) {
this._disabled = disabled;
this._notify.next();
}
_isCompleteMatch(name, value) {
const src = this.getTaskCompleted(name);
return this._isEqual(src, value) || (typeof (value) === 'object' && _.isMatch(src, value));
}
_isEqual(src, value) {
if (src === value) {
return true;
}
else if (src !== false && value === true) {
// we can compare value of true with any source
return true;
}
else if (typeof (value) === 'string') {
// support not (!) less than (<) or greater than (>) comparisons
const op = value[0];
const compValue = value.substr(1);
if ((op === '!' && compValue != src) || (op === '<' && src < compValue) || (op === '>' && src > compValue)) {
return true;
}
}
}
evalMustCompleted(mustCompleted) {
return Object.entries(mustCompleted).find(([name, value]) => !this._isCompleteMatch(name, value)) === undefined;
}
evalMustNotDisplaying(mustNotDisplaying) {
// allow using prefix in task names
const displaying = Object.keys(this._displaying);
return mustNotDisplaying.find(prefix => displaying.find(key => key.startsWith(prefix))) === undefined;
}
save() {
localStorage.setItem(this._key, JSON.stringify(this._values));
this._notify.next();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [] });
var BdcDisplayEventAction;
(function (BdcDisplayEventAction) {
BdcDisplayEventAction[BdcDisplayEventAction["VisibilityChanged"] = 0] = "VisibilityChanged";
BdcDisplayEventAction[BdcDisplayEventAction["UserClosed"] = 1] = "UserClosed";
BdcDisplayEventAction[BdcDisplayEventAction["ButtonClicked"] = 2] = "ButtonClicked";
})(BdcDisplayEventAction || (BdcDisplayEventAction = {}));
class BdcWalkDialogComponent {
constructor(dialog, tutorialService) {
this.dialog = dialog;
this.tutorialService = tutorialService;
this.mustCompleted = {};
this.mustNotDisplaying = [];
this.width = '500px';
this.opened = new EventEmitter();
this.closed = new EventEmitter();
}
ngAfterContentInit() {
this.componentSubscription = this.tutorialService.changes.subscribe(() => this._sync());
}
ngOnChanges() {
this._sync();
}
ngOnDestroy() {
if (this.componentSubscription) {
this.componentSubscription.unsubscribe();
}
this._close();
}
getValue(taskName) {
return this.tutorialService.getTaskCompleted(taskName);
}
close(setTasks = {}) {
this.tutorialService.logUserAction(this.name, BdcDisplayEventAction.UserClosed);
this.tutorialService.setTaskCompleted(this.name);
this.tutorialService.setTasks(setTasks);
}
_open() {
this.dialogRef = this.dialog.open(this.templateRef, { width: this.width, disableClose: true, restoreFocus: false, panelClass: 'bdc-walk-dialog' });
this.opened.emit();
}
_close() {
if (this.dialogRef) {
this.dialogRef.close();
this.dialogRef = null;
this.closed.emit();
}
}
_sync() {
if (this.name) {
if (!this.tutorialService.getTaskCompleted(this.name) &&
!this.tutorialService.disabled &&
this.tutorialService.evalMustCompleted(this.mustCompleted) &&
this.tutorialService.evalMustNotDisplaying(this.mustNotDisplaying)) {
if (!this.dialogRef) {
this._open();
this.tutorialService.setIsDisplaying(this.name, true);
}
}
else if (this.dialogRef) {
this._close();
this.tutorialService.setIsDisplaying(this.name, false);
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkDialogComponent, deps: [{ token: i1.MatDialog }, { token: BdcWalkService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: BdcWalkDialogComponent, isStandalone: true, selector: "bdc-walk-dialog", inputs: { name: "name", mustCompleted: "mustCompleted", mustNotDisplaying: "mustNotDisplaying", width: "width" }, outputs: { opened: "opened", closed: "closed" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template>\n <div class=\"container\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n", styles: [""], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'bdc-walk-dialog', encapsulation: ViewEncapsulation.None, template: "<ng-template>\n <div class=\"container\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: BdcWalkService }], propDecorators: { name: [{
type: Input
}], mustCompleted: [{
type: Input
}], mustNotDisplaying: [{
type: Input
}], width: [{
type: Input
}], opened: [{
type: Output
}], closed: [{
type: Output
}], templateRef: [{
type: ViewChild,
args: [TemplateRef, { static: true }]
}] } });
class BdcWalkPopupComponent {
constructor(tutorialService) {
this.tutorialService = tutorialService;
this.xPosition = 'before';
this.yPosition = 'below';
this.arrow = true;
this.horizontal = false;
this.closeOnClick = false;
this.offsetX = 0;
this.offsetY = 0;
this.class = '';
this.showCloseButton = true;
this.showButton = false;
this.buttonText = 'Got it';
this.mustCompleted = {};
this.mustNotDisplaying = [];
this.onCloseCompleteTask = {};
this.onButtonCompleteTask = {};
this.opened = new EventEmitter();
this.closed = new EventEmitter();
this.className = undefined;
}
ngOnInit() {
}
ngOnChanges() {
if (this.trigger) {
this.trigger.reposition();
}
}
_getClass() {
return `bdc-walk-popup ${this.class} ` + (this.arrow ? ' arrow' : '') + (this.horizontal ? ' horizontal' : '');
}
getValue(taskName) {
return this.tutorialService.getTaskCompleted(taskName);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkPopupComponent, deps: [{ token: BdcWalkService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: BdcWalkPopupComponent, isStandalone: true, selector: "bdc-walk-popup", inputs: { name: "name", header: "header", xPosition: "xPosition", yPosition: "yPosition", arrow: "arrow", horizontal: "horizontal", closeOnClick: "closeOnClick", alignCenter: "alignCenter", offsetX: "offsetX", offsetY: "offsetY", class: "class", showCloseButton: "showCloseButton", showButton: "showButton", buttonText: "buttonText", sideNoteText: "sideNoteText", mustCompleted: "mustCompleted", mustNotDisplaying: "mustNotDisplaying", onCloseCompleteTask: "onCloseCompleteTask", onButtonCompleteTask: "onButtonCompleteTask" }, outputs: { opened: "opened", closed: "closed" }, host: { properties: { "attr.class": "this.className" } }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "menu", first: true, predicate: MatMenu, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<mat-menu [overlapTrigger]=\"false\" [xPosition]=\"xPosition\" [yPosition]=\"yPosition\" [hasBackdrop]=\"false\" [class]=\"_getClass()\">\n <div class=\"container\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\" tabindex=\"-1\">\n <div class=\"title\">\n <div class=\"header\">{{ header }}</div>\n\n <a *ngIf=\"showCloseButton\" (click)=\"$event.preventDefault(); trigger.close(false)\" class=\"close\" href=\"\"></a>\n </div>\n\n <ng-content></ng-content>\n\n <ng-container *ngIf=\"templateRef && trigger\">\n <ng-container *ngTemplateOutlet=\"templateRef; context: {$implicit: data}\"></ng-container>\n </ng-container>\n\n <div *ngIf=\"showButton\" class=\"buttons\">\n <div class=\"sideNote\">{{ sideNoteText }}</div>\n <button (click)=\"trigger.close(true)\" type=\"button\" mat-stroked-button>{{ buttonText }}</button>\n </div>\n </div>\n</mat-menu>\n", styles: ["div.mat-mdc-menu-panel.bdc-walk-popup,div.mat-menu-panel.bdc-walk-popup{min-height:auto;border:1px solid #E3E4E6;box-shadow:0 2px 2px #0003;overflow:visible;min-width:300px;border-radius:10px}div.mat-mdc-menu-panel.bdc-walk-popup .container,div.mat-menu-panel.bdc-walk-popup .container{padding:10px 18px 16px;outline:none;font-size:14px;line-height:1.35;background:#fff}div.mat-mdc-menu-panel.bdc-walk-popup .title,div.mat-menu-panel.bdc-walk-popup .title{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:10px}div.mat-mdc-menu-panel.bdc-walk-popup .title .header,div.mat-menu-panel.bdc-walk-popup .title .header{font-size:18px;font-weight:700;color:#0293db}div.mat-mdc-menu-panel.bdc-walk-popup .title a.close,div.mat-menu-panel.bdc-walk-popup .title a.close{margin-right:-4px;width:16px;height:16px;display:block;background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDBWMHoiLz48cGF0aCBmaWxsPSIjRDVEQUUwIiBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyIDE5IDYuNDF6Ii8+PC9zdmc+);background-size:16px}div.mat-mdc-menu-panel.bdc-walk-popup .buttons,div.mat-menu-panel.bdc-walk-popup .buttons{margin-top:12px;margin-bottom:-5px;display:flex;justify-content:space-between;align-items:center}div.mat-mdc-menu-panel.bdc-walk-popup .buttons .sideNote,div.mat-menu-panel.bdc-walk-popup .buttons .sideNote{color:#b1bcc7;font-size:12px}div.mat-mdc-menu-panel.bdc-walk-popup .buttons button,div.mat-menu-panel.bdc-walk-popup .buttons button{color:#0293db;line-height:30px!important}div.mat-mdc-menu-panel.bdc-walk-popup.mat-menu-above,div.mat-menu-panel.bdc-walk-popup.mat-menu-above{box-shadow:0 0 2px #0003}div.mat-mdc-menu-panel.bdc-walk-popup .mat-mdc-menu-content,div.mat-mdc-menu-panel.bdc-walk-popup .mat-menu-content,div.mat-menu-panel.bdc-walk-popup .mat-mdc-menu-content,div.mat-menu-panel.bdc-walk-popup .mat-menu-content{border-radius:10px;height:100%;padding:0;overflow-y:auto}div.mat-mdc-menu-panel.bdc-walk-popup.arrow,div.mat-menu-panel.bdc-walk-popup.arrow{position:relative}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow:before,div.mat-menu-panel.bdc-walk-popup.arrow:after,div.mat-menu-panel.bdc-walk-popup.arrow:before{bottom:100%;border:solid transparent;content:\" \";height:0;width:0;position:absolute;pointer-events:none}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:after,div.mat-menu-panel.bdc-walk-popup.arrow:after{border-color:#fff0;border-width:8px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:before,div.mat-menu-panel.bdc-walk-popup.arrow:before{border-color:#e3e4e600;border-width:9px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{right:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{right:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{margin-right:-1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before{left:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before{left:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after{margin-left:1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal),div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal){margin-top:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):after{border-top-color:transparent;border-bottom-color:#fff}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):before{border-top-color:transparent;border-bottom-color:#e3e4e6}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal),div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal){margin-bottom:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before{top:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after{border-top-color:#fff;border-bottom-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before{border-top-color:#e3e4e6;border-bottom-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal{margin-right:15px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before{left:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after{border-left-color:#fff;border-right-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before{border-left-color:#e3e4e6;border-right-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal{margin-left:15px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before{right:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after{border-left-color:transparent;border-right-color:#fff}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before{border-left-color:transparent;border-right-color:#e3e4e6}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:before{top:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after{margin-top:1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:before{bottom:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after{margin-bottom:1px}\n"], dependencies: [{ kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkPopupComponent, decorators: [{
type: Component,
args: [{ selector: 'bdc-walk-popup', encapsulation: ViewEncapsulation.None, imports: [MatMenu, NgIf, NgTemplateOutlet, MatButton], template: "<mat-menu [overlapTrigger]=\"false\" [xPosition]=\"xPosition\" [yPosition]=\"yPosition\" [hasBackdrop]=\"false\" [class]=\"_getClass()\">\n <div class=\"container\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\" tabindex=\"-1\">\n <div class=\"title\">\n <div class=\"header\">{{ header }}</div>\n\n <a *ngIf=\"showCloseButton\" (click)=\"$event.preventDefault(); trigger.close(false)\" class=\"close\" href=\"\"></a>\n </div>\n\n <ng-content></ng-content>\n\n <ng-container *ngIf=\"templateRef && trigger\">\n <ng-container *ngTemplateOutlet=\"templateRef; context: {$implicit: data}\"></ng-container>\n </ng-container>\n\n <div *ngIf=\"showButton\" class=\"buttons\">\n <div class=\"sideNote\">{{ sideNoteText }}</div>\n <button (click)=\"trigger.close(true)\" type=\"button\" mat-stroked-button>{{ buttonText }}</button>\n </div>\n </div>\n</mat-menu>\n", styles: ["div.mat-mdc-menu-panel.bdc-walk-popup,div.mat-menu-panel.bdc-walk-popup{min-height:auto;border:1px solid #E3E4E6;box-shadow:0 2px 2px #0003;overflow:visible;min-width:300px;border-radius:10px}div.mat-mdc-menu-panel.bdc-walk-popup .container,div.mat-menu-panel.bdc-walk-popup .container{padding:10px 18px 16px;outline:none;font-size:14px;line-height:1.35;background:#fff}div.mat-mdc-menu-panel.bdc-walk-popup .title,div.mat-menu-panel.bdc-walk-popup .title{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:10px}div.mat-mdc-menu-panel.bdc-walk-popup .title .header,div.mat-menu-panel.bdc-walk-popup .title .header{font-size:18px;font-weight:700;color:#0293db}div.mat-mdc-menu-panel.bdc-walk-popup .title a.close,div.mat-menu-panel.bdc-walk-popup .title a.close{margin-right:-4px;width:16px;height:16px;display:block;background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDBWMHoiLz48cGF0aCBmaWxsPSIjRDVEQUUwIiBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyIDE5IDYuNDF6Ii8+PC9zdmc+);background-size:16px}div.mat-mdc-menu-panel.bdc-walk-popup .buttons,div.mat-menu-panel.bdc-walk-popup .buttons{margin-top:12px;margin-bottom:-5px;display:flex;justify-content:space-between;align-items:center}div.mat-mdc-menu-panel.bdc-walk-popup .buttons .sideNote,div.mat-menu-panel.bdc-walk-popup .buttons .sideNote{color:#b1bcc7;font-size:12px}div.mat-mdc-menu-panel.bdc-walk-popup .buttons button,div.mat-menu-panel.bdc-walk-popup .buttons button{color:#0293db;line-height:30px!important}div.mat-mdc-menu-panel.bdc-walk-popup.mat-menu-above,div.mat-menu-panel.bdc-walk-popup.mat-menu-above{box-shadow:0 0 2px #0003}div.mat-mdc-menu-panel.bdc-walk-popup .mat-mdc-menu-content,div.mat-mdc-menu-panel.bdc-walk-popup .mat-menu-content,div.mat-menu-panel.bdc-walk-popup .mat-mdc-menu-content,div.mat-menu-panel.bdc-walk-popup .mat-menu-content{border-radius:10px;height:100%;padding:0;overflow-y:auto}div.mat-mdc-menu-panel.bdc-walk-popup.arrow,div.mat-menu-panel.bdc-walk-popup.arrow{position:relative}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow:before,div.mat-menu-panel.bdc-walk-popup.arrow:after,div.mat-menu-panel.bdc-walk-popup.arrow:before{bottom:100%;border:solid transparent;content:\" \";height:0;width:0;position:absolute;pointer-events:none}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:after,div.mat-menu-panel.bdc-walk-popup.arrow:after{border-color:#fff0;border-width:8px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow:before,div.mat-menu-panel.bdc-walk-popup.arrow:before{border-color:#e3e4e600;border-width:9px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{right:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{right:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before:not(.horizontal):before{margin-right:-1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before{left:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):before{left:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after:not(.horizontal):after{margin-left:1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal),div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal){margin-top:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):after{border-top-color:transparent;border-bottom-color:#fff}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below:not(.horizontal):before{border-top-color:transparent;border-bottom-color:#e3e4e6}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal),div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal){margin-bottom:10px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before{top:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):after{border-top-color:#fff;border-bottom-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above:not(.horizontal):before{border-top-color:#e3e4e6;border-bottom-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal{margin-right:15px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before{left:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:after{border-left-color:#fff;border-right-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-before.horizontal:before{border-left-color:#e3e4e6;border-right-color:transparent}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal{margin-left:15px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before{right:100%}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:after{border-left-color:transparent;border-right-color:#fff}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-after.horizontal:before{border-left-color:transparent;border-right-color:#e3e4e6}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:before{top:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-below.horizontal:after{margin-top:1px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:before,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:before{bottom:20px}div.mat-mdc-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after,div.mat-menu-panel.bdc-walk-popup.arrow.mat-menu-above.horizontal:after{margin-bottom:1px}\n"] }]
}], ctorParameters: () => [{ type: BdcWalkService }], propDecorators: { name: [{
type: Input
}], header: [{
type: Input
}], xPosition: [{
type: Input
}], yPosition: [{
type: Input
}], arrow: [{
type: Input
}], horizontal: [{
type: Input
}], closeOnClick: [{
type: Input
}], alignCenter: [{
type: Input
}], offsetX: [{
type: Input
}], offsetY: [{
type: Input
}], class: [{
type: Input
}], showCloseButton: [{
type: Input
}], showButton: [{
type: Input
}], buttonText: [{
type: Input
}], sideNoteText: [{
type: Input
}], mustCompleted: [{
type: Input
}], mustNotDisplaying: [{
type: Input
}], onCloseCompleteTask: [{
type: Input
}], onButtonCompleteTask: [{
type: Input
}], opened: [{
type: Output
}], closed: [{
type: Output
}], className: [{
type: HostBinding,
args: ['attr.class']
}], menu: [{
type: ViewChild,
args: [MatMenu, { static: true }]
}], templateRef: [{
type: ContentChild,
args: [TemplateRef]
}] } });
class BdcWalkTriggerDirective {
/** References the popup instance that the trigger is associated with. */
get popup() {
return this._popup;
}
set popup(popup) {
if (popup === this._popup) {
return;
}
this._popup = popup;
this._menu = popup.menu;
this._menuCloseSubscription.unsubscribe();
if (popup) {
this._menuCloseSubscription = popup.menu.closed.subscribe(() => {
this._destroyMenu();
});
}
}
constructor(tutorialService, _overlay, _element, _viewContainerRef, scrollStrategy, _dir, _ngZone) {
this.tutorialService = tutorialService;
this._overlay = _overlay;
this._element = _element;
this._viewContainerRef = _viewContainerRef;
this._dir = _dir;
this._ngZone = _ngZone;
this._overlayRef = null;
this._menuOpen = false;
this._closingActionsSubscription = Subscription.EMPTY;
this._hoverSubscription = Subscription.EMPTY;
this._menuCloseSubscription = Subscription.EMPTY;
this._initialized = false;
this._contentInited = false;
this._isTriggerVisible = true;
this.enabled = true;
this.mustCompleted = {};
this._scrollStrategy = scrollStrategy;
}
ngAfterContentInit() {
this._contentInited = true;
this._componentSubscription = this.tutorialService.changes.subscribe(() => this._sync());
}
ngAfterContentChecked() {
// detect changes if trigger visibility changed
const isTriggerVisible = !!this._element.nativeElement.offsetParent;
if (isTriggerVisible !== this._isTriggerVisible && this._contentInited) {
this._isTriggerVisible = isTriggerVisible;
this._sync();
}
}
ngOnChanges() {
if (this._contentInited) {
this._sync();
}
}
ngOnDestroy() {
if (this._componentSubscription) {
this._componentSubscription.unsubscribe();
}
// must disable auto-init and release popup so others may use it
clearTimeout(this._timer);
if (this._initialized) {
this.popup.trigger = null;
this.popup.data = null;
this.tutorialService.setIsDisplaying(this.popup.name, false);
}
if (this._overlayRef) {
this._overlayRef.dispose();
this._overlayRef = null;
}
this._menuCloseSubscription.unsubscribe();
this._closingActionsSubscription.unsubscribe();
this._hoverSubscription.unsubscribe();
}
/** Whether the menu is open. */
get menuOpen() {
return this._menuOpen;
}
/** The text direction of the containing app. */
get dir() {
return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
}
/** Opens the menu. */
openMenu() {
const menu = this._menu;
if (this._menuOpen || !menu) {
return;
}
const overlayRef = this._createOverlay(menu);
const overlayConfig = overlayRef.getConfig();
const positionStrategy = overlayConfig.positionStrategy;
this._setPosition(menu, positionStrategy);
overlayConfig.hasBackdrop = menu.hasBackdrop;
overlayRef.attach(this._getPortal(menu));
if (menu.lazyContent) {
menu.lazyContent.attach();
}
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
this._initMenu(menu);
if (menu instanceof MatMenu) {
menu._setIsOpen(true);
menu._directDescendantItems.changes.pipe(takeUntil(menu.close)).subscribe(() => {
// Re-adjust the position without locking when the amount of items
// changes so that the overlay is allowed to pick a new optimal position.
positionStrategy.withLockedPosition(false).reapplyLastPosition();
positionStrategy.withLockedPosition(true);
});
}
}
/** Closes the menu. */
closeMenu() {
this._menu?.close.emit();
}
/**
* Updates the position of the menu to ensure that it fits all options within the viewport.
*/
updatePosition() {
this._overlayRef?.updatePosition();
}
/** Closes the menu and does the necessary cleanup. */
_destroyMenu() {
if (!this._overlayRef || !this.menuOpen) {
return;
}
const menu = this._menu;
this._closingActionsSubscription.unsubscribe();
this._overlayRef.detach();
if (menu instanceof MatMenu) {
menu._setIsOpen(false);
if (menu.lazyContent) {
// Wait for the exit animation to finish before detaching the content.
menu._animationDone
.pipe(filter(event => {
return event === 'void';
}), take(1),
// Interrupt if the content got re-attached.
takeUntil(menu.lazyContent._attached))
.subscribe({
next: () => menu.lazyContent.detach(),
// No matter whether the content got re-attached, reset the menu.
complete: () => this._setIsMenuOpen(false),
});
}
else {
this._setIsMenuOpen(false);
}
}
else {
this._setIsMenuOpen(false);
menu?.lazyContent?.detach();
}
}
/**
* This method sets the menu state to open and focuses the first item if
* the menu was opened via the keyboard.
*/
_initMenu(menu) {
menu.direction = this.dir;
this._setIsMenuOpen(true);
}
// set state rather than toggle to support triggers sharing a menu
_setIsMenuOpen(isOpen) {
this._menuOpen = isOpen;
}
/**
* This method creates the overlay from the provided menu's template and saves its
* OverlayRef so that it can be attached to the DOM when openMenu is called.
*/
_createOverlay(menu) {
if (!this._overlayRef) {
const config = this._getOverlayConfig(menu);
this._subscribeToPositions(menu, config.positionStrategy);
this._overlayRef = this._overlay.create(config);
}
return this._overlayRef;
}
/**
* This method builds the configuration object needed to create the overlay, the OverlayState.
* @returns OverlayConfig
*/
_getOverlayConfig(menu) {
// override overlay to avoid resizing of popups
const positionStrategy = this._overlay.position()
.flexibleConnectedTo(this._element)
.withPush(true)
.withFlexibleDimensions(false)
.withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel');
// patch positionStrategy to disable push for Y axis
const curGetExactOverlayY = positionStrategy['_getExactOverlayY'];
positionStrategy['_getExactOverlayY'] = (...args) => {
const curIsPushed = positionStrategy['_isPushed'];
positionStrategy['_isPushed'] = false;
const value = curGetExactOverlayY.call(positionStrategy, ...args);
positionStrategy['_isPushed'] = curIsPushed;
return value;
};
return new OverlayConfig({
positionStrategy,
scrollStrategy: this._scrollStrategy(),
direction: this._dir
});
}
/**
* Listens to changes in the position of the overlay and sets the correct classes
* on the menu based on the new position. This ensures the animation origin is always
* correct, even if a fallback position is used for the overlay.
*/
_subscribeToPositions(menu, position) {
if (menu.setPositionClasses) {
position.positionChanges.subscribe(change => {
const posX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
const posY = change.connectionPair.overlayY === 'top' ? 'below' : 'above';
if (!this._lastPosition || this._lastPosition.originX !== change.connectionPair.originX ||
this._lastPosition.originY !== change.connectionPair.originY) {
// selected position changed, we must run detect changes to update arrow css
this._lastPosition = change.connectionPair;
// this._ngZone.run(() => setTimeout(() => {}));
this._ngZone.run(() => menu.setPositionClasses(posX, posY));
}
});
}
}
/**
* Sets the appropriate positions on a position strategy
* so the overlay connects with the trigger correctly.
*/
_setPosition(menu, positionStrategy) {
// override position strategy to support open to the sides
let [originX, originFallbackX] = menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'];
const [overlayY, overlayFallbackY] = menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'];
let [originY, originFallbackY] = [overlayY, overlayFallbackY];
let [overlayX, overlayFallbackX] = [originX, originFallbackX];
// align popup's arrow to center of attached element if element size < 70
const offsetX = this.popup.offsetX || ((this.popup.alignCenter || (this._element.nativeElement.offsetWidth < 130 &&
this.popup.alignCenter === undefined)) && !this.popup.horizontal ? (this._element.nativeElement.offsetWidth / -2 + 29) *
(menu.xPosition === 'before' ? 1 : -1) : 0);
const offsetY = this.popup.offsetY || ((this.popup.alignCenter || (this._element.nativeElement.offsetHeight < 80 &&
this.popup.alignCenter === undefined)) && this.popup.horizontal ? (this._element.nativeElement.offsetHeight / 2 - 29) *
(menu.yPosition === 'below' ? 1 : -1) : 0);
if (this.popup.horizontal) {
// When the menu is a sub-menu, it should always align itself
// to the edges of the trigger, instead of overlapping it.
overlayFallbackX = originX = menu.xPosition === 'before' ? 'start' : 'end';
originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
}
else if (!menu.overlapTrigger) {
originY = overlayY === 'top' ? 'bottom' : 'top';
originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
}
const original = { originX, originY, overlayX, overlayY, offsetX, offsetY };
const flipX = { originX: originFallbackX, originY, overlayX: overlayFallbackX, overlayY, offsetX: -offsetX, offsetY };
const flipY = { originX, originY: originFallbackY, overlayX, overlayY: overlayFallbackY, offsetX, offsetY: -offsetY };
const flipXY = { originX: originFallbackX, originY: originFallbackY, overlayX: overlayFallbackX, overlayY: overlayFallbackY,
offsetX: -offsetX, offsetY: -offsetY };
positionStrategy.withPositions(this.popup.horizontal ? [original, flipX] : [original, flipY, flipXY]);
}
/** Returns a stream that emits whenever an action that should close the menu occurs. */
_menuClosingActions() {
const backdrop = this._overlayRef.backdropClick();
const detachments = this._overlayRef.detachments();
const parentClose = of();
const hover = of();
return merge(backdrop, parentClose, hover, detachments);
}
/** Gets the portal that should be attached to the overlay. */
_getPortal(menu) {
// Note that we can avoid this check by keeping the portal on the menu panel.
// While it would be cleaner, we'd have to introduce another required method on
// `MatMenuPanel`, making it harder to consume.
if (!this._portal || this._portal.templateRef !== menu.templateRef) {
this._portal = new TemplatePortal(menu.templateRef, this._viewContainerRef);
}
return this._portal;
}
/// custom code
_click() {
// element click
if (this._initialized && this.popup.closeOnClick) {
this.close(false);
}
}
_sync() {
const isTriggerVisible = !!this._element.nativeElement.offsetParent;
if (this._menu && this.popup.name) {
if (this.enabled && isTriggerVisible && !this.tutorialService.getTaskCompleted(this.popup.name) &&
!this.tutorialService.disabled &&
this.tutorialService.evalMustCompleted(this.mustCompleted) &&
this.tutorialService.evalMustCompleted(this.popup.mustCompleted) &&
this.tutorialService.evalMustNotDisplaying(this.popup.mustNotDisplaying)) {
// should be visible, but let's check if popup not already in use by other trigger (in table or ngFor)
if (!this.popup.trigger) {
this._initialized = true;
this.popup.trigger = this;
this.popup.data = this.data;
clearTimeout(this._timer);
this._timer = setTimeout(() => this.openMenu(), 500);
this.tutorialService.setIsDisplaying(this.popup.name, true);
this.popup.opened.emit();
}
}
else if (this._initialized) {
// only close if this is our popup (initialized)
this._initialized = false;
this.popup.trigger = null;
this.popup.data = null;
clearTimeout(this._timer);
this.closeMenu();
this.tutorialService.setIsDisplaying(this.popup.name, false);
this.popup.closed.emit();
}
}
}
reposition() {
if (this._initialized && this._componentSubscription) {
this.closeMenu();
this.openMenu();
}
}
close(buttonClicked) {
this.tutorialService.logUserAction(this.popup.name, buttonClicked ? BdcDisplayEventAction.ButtonClicked :
BdcDisplayEventAction.UserClosed);
this.tutorialService.setTaskCompleted(this.popup.name);
this.tutorialService.setTasks(this.popup.onCloseCompleteTask);
if (buttonClicked) {
this.tutorialService.setTasks(this.popup.onButtonCompleteTask);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BdcWalkTriggerDirective, deps: [{ token: BdcWalkService }, { token: i2.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: MAT_MENU_SCROLL_STRATEGY }, { token: i3.Directionality, optional: true }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirect