diff --git a/src/lib/empty-state/empty-state.component.html b/src/lib/empty-state/empty-state.component.html index 6420443..49e188f 100644 --- a/src/lib/empty-state/empty-state.component.html +++ b/src/lib/empty-state/empty-state.component.html @@ -19,7 +19,7 @@ *ngIf="showButton" [buttonId]="buttonId" [icon]="buttonIcon" - [iqserHelpMode]="helpModeKey" + [attr.help-mode-key]="helpModeKey" [label]="buttonLabel" [type]="iconButtonTypes.primary" > diff --git a/src/lib/filtering/quick-filters/quick-filters.component.html b/src/lib/filtering/quick-filters/quick-filters.component.html index 5e5cf12..0352a69 100644 --- a/src/lib/filtering/quick-filters/quick-filters.component.html +++ b/src/lib/filtering/quick-filters/quick-filters.component.html @@ -5,7 +5,7 @@ [class.active]="filter.checked" [class.disabled]="filter.disabled" class="quick-filter" - [iqserHelpMode]="filter.helpModeKey" + [attr.help-mode-key]="filter.helpModeKey" > {{ filter.label }} diff --git a/src/lib/help-mode/help-button/help-button.component.ts b/src/lib/help-mode/help-button/help-button.component.ts index 8a017b9..e924372 100644 --- a/src/lib/help-mode/help-button/help-button.component.ts +++ b/src/lib/help-mode/help-button/help-button.component.ts @@ -22,7 +22,7 @@ export class HelpButtonComponent implements OnInit, OnDestroy { activateHelpMode(): void { if (this.helpButtonKey) { - const url = this._helpModeService.getDocsLink(this.helpButtonKey); + const url = this._helpModeService.generateDocsLink(this.helpButtonKey); window.open(url, '_blank'); return; } diff --git a/src/lib/help-mode/help-docs.ts b/src/lib/help-mode/help-docs.ts deleted file mode 100644 index e1df4bf..0000000 --- a/src/lib/help-mode/help-docs.ts +++ /dev/null @@ -1 +0,0 @@ -export type HelpDocs = Record>; diff --git a/src/lib/help-mode/help-mode.directive.ts b/src/lib/help-mode/help-mode.directive.ts deleted file mode 100644 index ab9fb08..0000000 --- a/src/lib/help-mode/help-mode.directive.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Directive, ElementRef, Input, OnInit, Optional, Renderer2 } from '@angular/core'; -import { HELP_MODE_CLASS, OverlappingElement, ScrollableParentView } from './utils/constants'; -import { Helper, HelpModeService } from './help-mode.service'; - -@Directive({ - selector: '[iqserHelpMode]', - exportAs: 'iqserHelpMode', -}) -export class HelpModeDirective implements OnInit { - @Input('iqserHelpMode') helpModeKey!: string; - @Input() scrollableParentView!: ScrollableParentView; - @Input() overlappingElements: OverlappingElement[] = []; - @Input() dialogElement = false; - - constructor( - private readonly _elementRef: ElementRef, - private readonly _renderer: Renderer2, - @Optional() private readonly _helpModeService: HelpModeService, - ) {} - - ngOnInit(): void { - if (this.helpModeKey && this._helpModeService) { - this._createHelperElement(); - } - } - - private _createHelperElement() { - const element = this._elementRef.nativeElement as HTMLElement; - const helperKey = `${this.helpModeKey}-${this._generateId()}`; - - const helperElement = this._renderer.createElement('a') as HTMLElement; - this._renderer.setAttribute(helperElement, 'href', this._helpModeService.getDocsLink(this.helpModeKey)); - this._renderer.setAttribute(helperElement, 'target', '_blank'); - this._renderer.addClass(helperElement, HELP_MODE_CLASS); - - const helper: Helper = { - element, - helperElement, - scrollableParentView: this.scrollableParentView, - overlappingElements: this.overlappingElements, - dialogElement: this.dialogElement, - }; - - this._helpModeService.addHelper(helperKey, helper); - } - - private _generateId(): string { - return Math.random().toString(36).substring(2, 9); - } -} diff --git a/src/lib/help-mode/help-mode.module.ts b/src/lib/help-mode/help-mode.module.ts index 1de5c68..f0250c7 100644 --- a/src/lib/help-mode/help-mode.module.ts +++ b/src/lib/help-mode/help-mode.module.ts @@ -3,15 +3,13 @@ import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component'; import { HelpModeComponent } from './help-mode/help-mode.component'; -import { HelpModeDirective } from './help-mode.directive'; import { HelpButtonComponent } from './help-button/help-button.component'; -import { HelpModeService } from './help-mode.service'; -import { HelpDocs } from './help-docs'; -import { HELP_DOCS } from './tokens'; +import { HelpModeKey, HelpModeService } from './help-mode.service'; import { MatDialogModule } from '@angular/material/dialog'; import { CircleButtonComponent } from '../buttons'; +import { HELP_MODE_KEYS } from './tokens'; -const components = [HelpModeComponent, HelpModeDialogComponent, HelpModeDirective, HelpButtonComponent]; +const components = [HelpModeComponent, HelpModeDialogComponent, HelpButtonComponent]; @NgModule({ declarations: [...components], @@ -19,10 +17,10 @@ const components = [HelpModeComponent, HelpModeDialogComponent, HelpModeDirectiv exports: [...components], }) export class IqserHelpModeModule { - static forRoot(helpDocs: HelpDocs): ModuleWithProviders { + static forRoot(helpModeKeys: HelpModeKey[]): ModuleWithProviders { return { ngModule: IqserHelpModeModule, - providers: [{ provide: HELP_DOCS, useValue: helpDocs }, HelpModeService], + providers: [{ provide: HELP_MODE_KEYS, useValue: helpModeKeys }, HelpModeService], }; } } diff --git a/src/lib/help-mode/help-mode.service.ts b/src/lib/help-mode/help-mode.service.ts index 9ae5e6a..287a047 100644 --- a/src/lib/help-mode/help-mode.service.ts +++ b/src/lib/help-mode/help-mode.service.ts @@ -3,8 +3,7 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, firstValueFrom } from 'rxjs'; import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component'; -import { HELP_DOCS, MANUAL_BASE_URL } from './tokens'; -import { HelpDocs } from './help-docs'; +import { HELP_MODE_KEYS, MANUAL_BASE_URL } from './tokens'; import { ANNOTATIONS_LIST_ID, HELP_HIGHLIGHT_CLASS, @@ -28,6 +27,14 @@ export interface Helper { readonly iframeElement?: boolean; } +export interface HelpModeKey { + readonly elementKey: string; + readonly documentKey: string; + readonly scrollableParentView?: ScrollableParentView; + readonly overlappingElements?: OverlappingElement[]; + readonly dialogElement?: boolean; +} + @Injectable() export class HelpModeService { helpButtonKey: string | undefined; @@ -35,12 +42,12 @@ export class HelpModeService { readonly isHelpModeActive$ = this.#isHelpModeActive$.asObservable(); readonly #helpModeDialogIsOpened$ = new BehaviorSubject(false); readonly helpModeDialogIsOpened$ = this.#helpModeDialogIsOpened$.asObservable(); - readonly #helpers: Record = {}; readonly #renderer: Renderer2; + #helpers: Record = {}; #dialogMode = false; constructor( - @Inject(HELP_DOCS) private readonly _docs: HelpDocs, + @Inject(HELP_MODE_KEYS) private readonly _keys: HelpModeKey[], @Inject(MANUAL_BASE_URL) private readonly _manualBaseURL: string, private readonly _dialog: MatDialog, private readonly _rendererFactory: RendererFactory2, @@ -70,10 +77,6 @@ export class HelpModeService { return ref; } - getDocsLink(elementName: string): string { - return this._docs[elementName] ? `${this._manualBaseURL}${this._docs[elementName][this._translateService.currentLang]}` : ''; - } - activateHelpMode(dialogMode: boolean = false): void { if (!this.isHelpModeActive) { document.body.style.setProperty('overflow', 'unset'); @@ -81,6 +84,7 @@ export class HelpModeService { this.openHelpModeDialog(); this.#dialogMode = dialogMode; setTimeout(() => { + this.#createHelpers(); this.#createWebViewerHelpers(); this.#enableHelperElements(); }, 500); @@ -92,9 +96,60 @@ export class HelpModeService { document.body.style.removeProperty('overflow'); this.#isHelpModeActive$.next(false); this.#disableHelperElements(); + this.#helpers = {}; } } + #createHelpers() { + for (const key of Object.values(this._keys)) { + const elements = document.querySelectorAll(`[help-mode-key='${key.elementKey}']`); + elements.forEach(element => { + const helperKey = `${key.elementKey}-${this.#generateId()}`; + + this.#helpers[helperKey] = { + element: element as HTMLElement, + helperElement: this.#getHelperElement(element as HTMLElement, key.documentKey), + scrollableParentView: key.scrollableParentView, + overlappingElements: key.overlappingElements, + dialogElement: key.elementKey.endsWith('_DIALOG'), + }; + }); + } + } + + #createWebViewerHelpers(): void { + const iframe: HTMLIFrameElement = document.getElementById(PDF_TRON_IFRAME_ID) as HTMLIFrameElement; + if (iframe) { + WEB_VIEWER_ELEMENTS.forEach(e => { + const element: HTMLElement = iframe.contentWindow?.document.querySelector(e.querySelector) as HTMLElement; + + this.#helpers[e.documentKey] = { + element, + helperElement: this.#getHelperElement(element, e.documentKey), + dialogElement: false, + iframeElement: true, + }; + }); + } + } + + #getHelperElement(element: HTMLElement, key: string): HTMLElement { + const helperElement = this.#renderer.createElement('a') as HTMLElement; + this.#renderer.setAttribute(helperElement, 'href', this.generateDocsLink(key)); + this.#renderer.setAttribute(helperElement, 'target', '_blank'); + this.#renderer.addClass(helperElement, HELP_MODE_CLASS); + return helperElement; + } + + #generateId(): string { + return Math.random().toString(36).substring(2, 9); + } + + generateDocsLink(key: string) { + const currentLang = this._translateService.currentLang; + return `${this._manualBaseURL}/${currentLang}/index-${currentLang}.html?contextId=${key}`; + } + highlightHelperElements(): void { Object.values(this.#helpers).forEach(helper => { this.#renderer.addClass(helper.helperElement, HELP_HIGHLIGHT_CLASS); @@ -104,33 +159,6 @@ export class HelpModeService { }); } - #createWebViewerHelpers(): void { - const iframe: HTMLIFrameElement = document.getElementById(PDF_TRON_IFRAME_ID) as HTMLIFrameElement; - if (iframe) { - WEB_VIEWER_ELEMENTS.forEach(e => { - const element: HTMLElement = iframe.contentWindow?.document.querySelector(e.querySelector) as HTMLElement; - - const helperElement: HTMLElement = this.#renderer.createElement('a') as HTMLElement; - this.#renderer.setAttribute(helperElement, 'href', this.getDocsLink(e.helpModeKey)); - this.#renderer.setAttribute(helperElement, 'target', '_blank'); - this.#renderer.addClass(helperElement, HELP_MODE_CLASS); - - const helper: Helper = { - element, - helperElement, - dialogElement: false, - iframeElement: true, - }; - - this.addHelper(e.helpModeKey, helper); - }); - } - } - - addHelper(helperKey: string, helper: Helper): void { - this.#helpers[helperKey] = helper; - } - updateHelperElements() { Object.values(this.#helpers).forEach(helper => this.#updateHelperElement(helper)); } diff --git a/src/lib/help-mode/help-mode/help-mode.component.ts b/src/lib/help-mode/help-mode/help-mode.component.ts index b0999f0..df27ffd 100644 --- a/src/lib/help-mode/help-mode/help-mode.component.ts +++ b/src/lib/help-mode/help-mode/help-mode.component.ts @@ -25,7 +25,7 @@ export class HelpModeComponent { const node = (event.target as IqserEventTarget).localName; if (!this.helpModeService.isHelpModeActive && node !== 'input' && node !== 'textarea') { if (this.helpModeService.helpButtonKey) { - const url = this.helpModeService.getDocsLink(this.helpModeService.helpButtonKey); + const url = this.helpModeService.generateDocsLink(this.helpModeService.helpButtonKey); window.open(url, '_blank'); return; } diff --git a/src/lib/help-mode/index.ts b/src/lib/help-mode/index.ts index 486a9ce..ab6c4be 100644 --- a/src/lib/help-mode/index.ts +++ b/src/lib/help-mode/index.ts @@ -1,8 +1,6 @@ export * from './tokens'; -export * from './help-docs'; export * from './help-mode.module'; export * from './help-mode.service'; -export * from './help-mode.directive'; export * from './help-mode/help-mode.component'; export * from './help-button/help-button.component'; export * from './help-mode-dialog/help-mode-dialog.component'; diff --git a/src/lib/help-mode/tokens.ts b/src/lib/help-mode/tokens.ts index 0965c5a..c842b24 100644 --- a/src/lib/help-mode/tokens.ts +++ b/src/lib/help-mode/tokens.ts @@ -1,8 +1,8 @@ import { inject, InjectionToken } from '@angular/core'; import { IqserConfigService } from '../services'; -import { HelpDocs } from './help-docs'; +import { HelpModeKey } from './help-mode.service'; -export const HELP_DOCS = new InjectionToken('Links to user manual or help docs'); +export const HELP_MODE_KEYS = new InjectionToken('Help mode keys'); export const MANUAL_BASE_URL = new InjectionToken('Base manual URL', { factory: () => inject(IqserConfigService).values.MANUAL_BASE_URL, }); diff --git a/src/lib/help-mode/utils/constants.ts b/src/lib/help-mode/utils/constants.ts index 22a8fad..d97a3cf 100644 --- a/src/lib/help-mode/utils/constants.ts +++ b/src/lib/help-mode/utils/constants.ts @@ -10,7 +10,7 @@ export const PDF_TRON_IFRAME_ID = 'webviewer-1'; export const WEB_VIEWER_ELEMENTS = [ { querySelector: '.HeaderItems', - helpModeKey: 'pdf_features', + documentKey: 'pdf_features', }, ]; diff --git a/src/lib/listing/page-header/models/action-config.model.ts b/src/lib/listing/page-header/models/action-config.model.ts index 0e96c6d..dbfb226 100644 --- a/src/lib/listing/page-header/models/action-config.model.ts +++ b/src/lib/listing/page-header/models/action-config.model.ts @@ -5,6 +5,5 @@ import { OverlappingElement } from '../../../help-mode'; export interface ActionConfig extends BaseHeaderConfig { readonly action: ($event: MouseEvent) => void; readonly helpModeKey?: string; - readonly overlappingElements?: OverlappingElement[]; readonly disabled$?: Observable; } diff --git a/src/lib/listing/page-header/page-header.component.html b/src/lib/listing/page-header/page-header.component.html index bd9a456..4952155 100644 --- a/src/lib/listing/page-header/page-header.component.html +++ b/src/lib/listing/page-header/page-header.component.html @@ -15,8 +15,8 @@ @@ -29,7 +29,7 @@
@@ -46,10 +46,9 @@ *ngIf="!config.hide" [buttonId]="config.label.replace('.', '-')" [icon]="config.icon" - [iqserHelpMode]="config.helpModeKey" [label]="config.label | translate" - [overlappingElements]="config.overlappingElements" [type]="config.type" + [attr.help-mode-key]="config.helpModeKey" > @@ -61,9 +60,8 @@ [buttonId]="config.id" [disabled]="config.disabled$ && (config.disabled$ | async)" [icon]="config.icon" - [iqserHelpMode]="config.helpModeKey" - [overlappingElements]="config.overlappingElements" [tooltip]="config.label" + [attr.help-mode-key]="config.helpModeKey" > @@ -76,8 +74,7 @@ *ngIf="showCloseButton" [class.ml-6]="actionConfigs" [icon]="'iqser:close'" - [iqserHelpMode]="'edit_dossier_in_dossier'" - [overlappingElements]="['USER_MENU']" + [attr.help-mode-key]="'edit_dossier_in_dossier'" [tooltip]="'common.close' | translate" > diff --git a/src/lib/listing/scroll-button/scroll-button.component.html b/src/lib/listing/scroll-button/scroll-button.component.html index c35d6e3..6837236 100644 --- a/src/lib/listing/scroll-button/scroll-button.component.html +++ b/src/lib/listing/scroll-button/scroll-button.component.html @@ -1,7 +1,7 @@