RED-9437: fix help mode button placement in dialogs.

This commit is contained in:
Nicoleta Panaghiu 2024-07-09 14:48:40 +03:00
parent 9b1179d99a
commit 88743acacc
5 changed files with 65 additions and 56 deletions

View File

@ -2,12 +2,14 @@
[id]="buttonId"
class="help-mode-slide-toggle"
[class.dialog-toggle]="dialogButton"
[class.active]="helpModeService.isHelpModeActive"
[class.active]="helpModeService.isHelpModeActive()"
[matTooltip]="buttonTooltip"
#helpModeButton
>
<input type="checkbox" class="toggle-input" [checked]="helpModeService.isHelpModeActive" (change)="toggleHelpMode()" />
<div class="toggle-track"></div>
<div class="toggle-thumb">
<mat-icon svgIcon="iqser:help-outline" [class.active-thumb]="helpModeService.isHelpModeActive"></mat-icon>
<input type="checkbox" class="toggle-input" [checked]="helpModeService.isHelpModeActive()" (change)="toggleHelpMode()" />
<div class="toggle-track">
<div class="toggle-thumb">
<mat-icon svgIcon="iqser:help-outline" [class.active-thumb]="helpModeService.isHelpModeActive()"></mat-icon>
</div>
</div>
</label>

View File

@ -22,27 +22,24 @@
}
.toggle-track {
position: absolute;
top: 50%;
left: 0;
position: relative;
display: flex;
align-items: center;
justify-content: start;
width: 100%;
height: 25px;
background-color: var(--iqser-grey-4);
border-radius: 20px;
transform: translateY(-50%);
}
.toggle-thumb {
position: absolute;
top: 50%;
left: 4px;
margin-left: 6%;
width: 20px;
height: 20px;
background-color: #fff;
border-radius: 50%;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
transform: translateY(-50%);
transition: left 0.3s ease;
transition: margin-left 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
@ -60,7 +57,9 @@
background: var(--iqser-helpmode-primary);
}
.toggle-input:checked + .toggle-track + .toggle-thumb {
left: calc(100% - 22px);
.toggle-input:checked + .toggle-track {
.toggle-thumb {
margin-left: 43.5%;
}
}
}

View File

@ -1,5 +1,5 @@
/* eslint-disable @angular-eslint/prefer-on-push-component-change-detection */
import { AfterViewInit, Component, ElementRef, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
import { Component, effect, ElementRef, Input, OnDestroy, OnInit, viewChild } from '@angular/core';
import { MatIcon } from '@angular/material/icon';
import { HelpModeService } from '../help-mode.service';
import { MatTooltip } from '@angular/material/tooltip';
@ -13,15 +13,30 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
standalone: true,
imports: [MatIcon, MatTooltip],
})
export class HelpButtonComponent implements OnInit, AfterViewInit, OnDestroy {
export class HelpButtonComponent implements OnInit, OnDestroy {
#helpModeHasBeenActivated = false;
readonly helpModeButton = viewChild.required<ElementRef>('helpModeButton');
@Input() dialogButton = true;
helpModeButton: HTMLElement;
constructor(
private readonly _elementRef: ElementRef,
private readonly _translateService: TranslateService,
readonly helpModeService: HelpModeService,
) {}
) {
effect(() => {
if (this.helpModeService.isHelpModeActive()) {
this.#helpModeHasBeenActivated = true;
this.#applyActiveButtonStyles();
} else if (this.#helpModeHasBeenActivated) {
this.#applyInactiveButtonStyles();
}
});
}
get buttonTooltip() {
const translation = this.helpModeService.isHelpModeActive() ? _('help-button.disable') : _('help-button.enable');
return this._translateService.instant(translation);
}
get buttonId() {
return `help-mode-button${this.dialogButton ? '-dialog' : ''}`;
@ -34,47 +49,42 @@ export class HelpButtonComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
ngAfterViewInit() {
const currentComponent = this._elementRef.nativeElement;
this.helpModeButton = currentComponent.querySelector('.help-mode-slide-toggle');
if (this.helpModeButton) {
setTimeout(() => {
const currentComponentRect = currentComponent.getBoundingClientRect();
this.helpModeButton.style.setProperty('position', 'absolute');
this.helpModeButton.style.setProperty('top', `${currentComponentRect.top}px`);
this.helpModeButton.style.setProperty('left', `${currentComponentRect.left}px`);
document.body.appendChild(this.helpModeButton);
}, 500);
}
}
ngOnDestroy() {
document.body.removeChild(this.helpModeButton);
if (this.dialogButton) {
const defaultButton = document.getElementById('help-mode-button') as HTMLElement;
defaultButton.style.removeProperty('z-index');
if (!this.helpModeService.isHelpModeActive()) {
document.querySelectorAll('iqser-help-button')[this.dialogButton ? 1 : 0]?.removeChild(this.helpModeButton().nativeElement);
}
}
}
toggleHelpMode(): void {
if (this.helpModeService.isHelpModeActive) {
if (this.helpModeService.isHelpModeActive()) {
this.helpModeService.deactivateHelpMode();
return;
}
this.helpModeService.activateHelpMode(this.dialogButton);
}
@HostListener('window:resize', ['$event'])
onResize() {
#applyActiveButtonStyles() {
const currentComponent = this._elementRef.nativeElement;
const currentComponentRect = currentComponent.getBoundingClientRect();
this.helpModeButton?.style.setProperty('top', `${currentComponentRect.top}px`);
this.helpModeButton?.style.setProperty('left', `${currentComponentRect.left}px`);
setTimeout(() => {
this.helpModeButton().nativeElement.style.setProperty('position', 'absolute');
this.helpModeButton().nativeElement.style.setProperty('top', `${currentComponentRect.top}px`);
this.helpModeButton().nativeElement.style.setProperty('left', `${currentComponentRect.left}px`);
document.body.appendChild(this.helpModeButton().nativeElement);
}, 500);
}
get buttonTooltip() {
const translation = this.helpModeService.isHelpModeActive ? _('help-button.disable') : _('help-button.enable');
return this._translateService.instant(translation);
#applyInactiveButtonStyles() {
setTimeout(() => {
this.helpModeButton().nativeElement.style.setProperty('position', 'relative');
this.helpModeButton().nativeElement.style.setProperty('top', 'unset');
this.helpModeButton().nativeElement.style.setProperty('left', 'unset');
document.body.removeChild(this.helpModeButton().nativeElement);
document.querySelectorAll('iqser-help-button')[this.dialogButton ? 1 : 0]?.appendChild(this.helpModeButton().nativeElement);
}, 500);
}
}

View File

@ -2,8 +2,8 @@ import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { getConfig } from '../services/iqser-config.service';
import { IqserUserPreferenceService } from '../services/iqser-user-preference.service';
import { getConfig } from '../services';
import { IqserUserPreferenceService } from '../services';
import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component';
import { HELP_MODE_KEYS, MANUAL_BASE_URL } from './tokens';
import { HelpModeKey } from './types';
@ -20,6 +20,7 @@ import {
ScrollableParentViews,
WEB_VIEWER_ELEMENTS,
} from './utils/constants';
import { toSignal } from '@angular/core/rxjs-interop';
export interface Helper {
readonly element: HTMLElement;
@ -39,6 +40,7 @@ export class HelpModeService {
#helpers: Record<string, Helper> = {};
#dialogMode = false;
readonly isHelpModeActive$ = this.#isHelpModeActive$.asObservable();
readonly isHelpModeActive = toSignal(this.isHelpModeActive$, { initialValue: false });
readonly helpModeDialogIsOpened$ = this.#helpModeDialogIsOpened$.asObservable();
constructor(
@ -52,10 +54,6 @@ export class HelpModeService {
this.#renderer = this._rendererFactory.createRenderer(null, null);
}
get isHelpModeActive(): boolean {
return this.#isHelpModeActive$.getValue();
}
get helpModeDialogIsOpened(): boolean {
return this.#helpModeDialogIsOpened$.getValue();
}
@ -78,7 +76,7 @@ export class HelpModeService {
}
activateHelpMode(dialogMode: boolean = false): void {
if (!this.isHelpModeActive) {
if (!this.isHelpModeActive()) {
document.body.style.setProperty('overflow', 'unset');
this.#isHelpModeActive$.next(true);
this.openHelpModeDialog();
@ -92,7 +90,7 @@ export class HelpModeService {
}
deactivateHelpMode(): void {
if (this.isHelpModeActive) {
if (this.isHelpModeActive()) {
document.body.style.removeProperty('overflow');
this.#isHelpModeActive$.next(false);
this.#disableHelperElements();

View File

@ -24,7 +24,7 @@ export class HelpModeComponent {
@HostListener('document:keydown.escape', ['$event'])
onEscKeydownHandler(event: KeyboardEvent): void {
if (!this.helpModeService.helpModeDialogIsOpened && this.helpModeService.isHelpModeActive) {
if (!this.helpModeService.helpModeDialogIsOpened && this.helpModeService.isHelpModeActive()) {
event?.stopPropagation();
this.helpModeService.deactivateHelpMode();
}
@ -33,7 +33,7 @@ export class HelpModeComponent {
@HostListener('document:keydown.h', ['$event'])
onHKeydownHandler(event: KeyboardEvent): void {
const node = (event.target as IqserEventTarget).localName;
if (!this.helpModeService.isHelpModeActive && node !== 'input' && node !== 'textarea') {
if (!this.helpModeService.isHelpModeActive() && node !== 'input' && node !== 'textarea') {
const dialogMode = !!this._dialog.openDialogs.length;
this.helpModeService.activateHelpMode(dialogMode);
}
@ -41,14 +41,14 @@ export class HelpModeComponent {
@HostListener('click')
onClick(): void {
if (this.helpModeService.isHelpModeActive) {
if (this.helpModeService.isHelpModeActive()) {
this.helpModeService.highlightHelperElements();
}
}
@HostListener('window:resize')
onResize() {
if (this.helpModeService.isHelpModeActive) {
if (this.helpModeService.isHelpModeActive()) {
this.helpModeService.updateHelperElements();
}
}