common-ui/src/lib/help-mode/help-mode.service.ts
2021-08-25 22:17:20 +03:00

101 lines
3.4 KiB
TypeScript

import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs';
import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component';
import { HELP_DOCS } from './tokens';
interface Helper {
readonly element: HTMLElement;
readonly helperElement: HTMLElement;
}
@Injectable()
export class HelpModeService {
private readonly _isHelpModeActive$ = new BehaviorSubject(false);
readonly isHelpModeActive$ = this._isHelpModeActive$.asObservable();
private readonly _helpModeDialogIsOpened$ = new BehaviorSubject(false);
readonly helpModeDialogIsOpened$ = this._helpModeDialogIsOpened$.asObservable();
private readonly _elements: Record<string, Helper> = {};
private readonly _renderer: Renderer2;
constructor(
@Inject(HELP_DOCS) private readonly _docs: Record<string, Record<string, string>>,
private readonly _dialog: MatDialog,
private readonly _rendererFactory: RendererFactory2,
private readonly _translateService: TranslateService
) {
this._renderer = this._rendererFactory.createRenderer(null, null);
}
get isHelpModeActive(): boolean {
return this._isHelpModeActive$.getValue();
}
get helpModeDialogIsOpened(): boolean {
return this._helpModeDialogIsOpened$.getValue();
}
openHelpModeDialog(): MatDialogRef<HelpModeDialogComponent> {
this._helpModeDialogIsOpened$.next(true);
const ref = this._dialog.open(HelpModeDialogComponent, {
width: '600px'
});
ref.afterClosed()
.toPromise()
.then(() => {
this._helpModeDialogIsOpened$.next(false);
});
return ref;
}
openDocsFor(elementName: string): void {
if (this.isHelpModeActive) {
window.open(this._docs[elementName][this._translateService.currentLang]);
}
}
activateHelpMode(): void {
this._isHelpModeActive$.next(true);
this.openHelpModeDialog();
this._enableHelperElements();
}
deactivateHelpMode(): void {
this._isHelpModeActive$.next(false);
this._disableHelperElements();
}
highlightHelperElements(): void {
if (!this.isHelpModeActive) return;
Object.values(this._elements).forEach(({ helperElement }) => {
this._renderer.addClass(helperElement, 'help-highlight');
setTimeout(() => {
this._renderer.removeClass(helperElement, 'help-highlight');
}, 500);
});
}
addElement(elementName: string, element: HTMLElement, helperElement: HTMLElement): void {
this._elements[elementName] = { element, helperElement };
}
private _enableHelperElements() {
Object.values(this._elements).forEach(({ element, helperElement }) => {
this._renderer.setStyle(element, 'position', 'relative');
this._renderer.appendChild(element, helperElement);
});
}
private _disableHelperElements() {
Object.values(this._elements).forEach(({ element, helperElement }) => {
this._renderer.removeStyle(element, 'position');
this._renderer.removeChild(element, helperElement);
});
}
}