move help mode to common lib
This commit is contained in:
parent
f947e9ea46
commit
c4c3fad6a5
@ -8,7 +8,7 @@ indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
ij_html_quote_style = double
|
||||
max_line_length = 100
|
||||
max_line_length = 140
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
|
||||
@ -34,9 +34,9 @@ import { configurationInitializer } from '@app-config/configuration.initializer'
|
||||
import { AppConfigService } from '@app-config/app-config.service';
|
||||
import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight-search.component';
|
||||
import { PruningTranslationLoader } from '@utils/pruning-translation-loader';
|
||||
import { HelpModeComponent } from '@components/help-mode/help-mode.component';
|
||||
import { HelpModeDialogComponent } from '@components/help-mode-dialog/help-mode-dialog.component';
|
||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||
import * as links from '../assets/help-mode/links.json';
|
||||
import { HELP_DOCS } from '@iqser/common-ui';
|
||||
|
||||
export function httpLoaderFactory(httpClient: HttpClient) {
|
||||
return new PruningTranslationLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -61,8 +61,6 @@ const components = [
|
||||
ToastComponent,
|
||||
NotificationsComponent,
|
||||
SpotlightSearchComponent,
|
||||
HelpModeComponent,
|
||||
HelpModeDialogComponent,
|
||||
...screens
|
||||
];
|
||||
|
||||
@ -136,6 +134,10 @@ const components = [
|
||||
provide: MissingTranslationHandler,
|
||||
useClass: REDMissingTranslationHandler
|
||||
},
|
||||
{
|
||||
provide: HELP_DOCS,
|
||||
useValue: links
|
||||
},
|
||||
DatePipe
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@ -73,16 +73,16 @@
|
||||
[icon]="'iqser:search'"
|
||||
[tooltip]="'search.header-label' | translate"
|
||||
tooltipPosition="below"
|
||||
redactionHelpMode="search"
|
||||
iqserHelpMode="search"
|
||||
></iqser-circle-button>
|
||||
|
||||
<redaction-notifications redactionHelpMode="notifications"></redaction-notifications>
|
||||
<redaction-notifications iqserHelpMode="notifications"></redaction-notifications>
|
||||
</div>
|
||||
<redaction-user-button
|
||||
[matMenuTriggerFor]="userMenu"
|
||||
[showDot]="fileDownloadService.hasPendingDownloads"
|
||||
[userId]="currentUser.id"
|
||||
redactionHelpMode="user-menu"
|
||||
iqserHelpMode="user-menu"
|
||||
></redaction-user-button>
|
||||
|
||||
<mat-menu #userMenu="matMenu" xPosition="before">
|
||||
|
||||
@ -12,7 +12,7 @@ import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-se
|
||||
import { SpotlightSearchDialogData } from '@components/spotlight-search/spotlight-search-dialog-data';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { distinctUntilChanged, filter, map, startWith } from 'rxjs/operators';
|
||||
import { HelpModeService } from '@shared/services/help-mode.service';
|
||||
import { HelpModeService } from '@iqser/common-ui';
|
||||
|
||||
interface MenuItem {
|
||||
readonly name: string;
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
<section class="dialog">
|
||||
<div class="content">
|
||||
<p class="heading-l pre" [innerHTML]="'help-mode.welcome-to-help-mode' | translate"></p>
|
||||
<img src="assets/illustrations/illustration.gif" alt="" width="335" />
|
||||
<p class="pre" [innerHTML]="'help-mode.clicking-anywhere-on' | translate"></p>
|
||||
</div>
|
||||
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
|
||||
</section>
|
||||
@ -1,18 +0,0 @@
|
||||
@import '../../../assets/styles/variables';
|
||||
|
||||
section {
|
||||
background: $grey-11;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 440px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 30px;
|
||||
line-height: 18px;
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-help-mode-dialog',
|
||||
templateUrl: './help-mode-dialog.component.html',
|
||||
styleUrls: ['./help-mode-dialog.component.scss']
|
||||
})
|
||||
export class HelpModeDialogComponent {
|
||||
constructor() {}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
<div class="help-button" *ngIf="!helpModeService.isHelpModeActive" (click)="helpModeService.activateHelpMode()">
|
||||
<mat-icon svgIcon="red:help-outline"></mat-icon>
|
||||
<div class="text">{{ 'help-mode.button-text' | translate }}</div>
|
||||
</div>
|
||||
<div class="help-mode-border" *ngIf="helpModeService.isHelpModeActive">
|
||||
<div class="bottom">
|
||||
<p class="heading">{{ 'help-mode.text' | translate }}</p>
|
||||
<a class="instructions" *ngIf="!helpModeService.helpModeDialogIsOpened" (click)="helpModeService.openHelpModeDialog()">
|
||||
{{ 'help-mode.instructions' | translate }}
|
||||
</a>
|
||||
<div class="close">
|
||||
(esc)
|
||||
<iqser-circle-button
|
||||
class="dialog-close"
|
||||
icon="iqser:close"
|
||||
(click)="helpModeService.deactivateHelpMode()"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,72 +0,0 @@
|
||||
@import '../../../assets/styles/variables';
|
||||
|
||||
.help-button {
|
||||
width: 44px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
background: $green-2;
|
||||
border-top-left-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
box-shadow: -1px 1px 5px 0 rgba(40, 50, 65, 0.25);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
|
||||
.help-button:hover {
|
||||
cursor: pointer;
|
||||
width: fit-content;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
|
||||
.text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.help-mode-border {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-left: 8px solid $green-2;
|
||||
border-right: 8px solid $green-2;
|
||||
border-top: 8px solid $green-2;
|
||||
border-bottom: 60px solid $green-2;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.bottom {
|
||||
position: fixed;
|
||||
height: 60px;
|
||||
width: 95%;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
pointer-events: visiblePainted;
|
||||
|
||||
a {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
import { Component, HostListener } from '@angular/core';
|
||||
import { HelpModeService } from '@shared/services/help-mode.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-help-mode',
|
||||
templateUrl: './help-mode.component.html',
|
||||
styleUrls: ['./help-mode.component.scss']
|
||||
})
|
||||
export class HelpModeComponent {
|
||||
constructor(readonly helpModeService: HelpModeService) {}
|
||||
|
||||
@HostListener('document:keydown.escape') onEscKeydownHandler() {
|
||||
if (!this.helpModeService.helpModeDialogIsOpened) {
|
||||
this.helpModeService.deactivateHelpMode();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('document:keydown.h', ['$event']) onHKeydownHandler(event) {
|
||||
const node = event?.target?.nodeName?.toLocaleLowerCase();
|
||||
if (!this.helpModeService.isHelpModeActive && node !== 'input' && node !== 'textarea') {
|
||||
this.helpModeService.activateHelpMode();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('click') onClick() {
|
||||
if (this.helpModeService.isHelpModeActive) {
|
||||
this.helpModeService.highlightHelperElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, NestedFilter } from '@iqser/common-ui';
|
||||
import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, IqserEventTarget, NestedFilter } from '@iqser/common-ui';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { CommentsComponent } from '../comments/comments.component';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
@ -26,10 +26,6 @@ import { map } from 'rxjs/operators';
|
||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
|
||||
interface Target extends EventTarget {
|
||||
localName: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-workload',
|
||||
templateUrl: './file-workload.component.html',
|
||||
@ -159,7 +155,7 @@ export class FileWorkloadComponent {
|
||||
}
|
||||
|
||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
||||
if (($event.target as Target).localName === 'input') return;
|
||||
if (($event.target as IqserEventTarget).localName === 'input') return;
|
||||
this.pagesPanelActive = false;
|
||||
this.logAnnotation(annotation);
|
||||
if (this.isSelected(annotation)) {
|
||||
@ -180,7 +176,7 @@ export class FileWorkloadComponent {
|
||||
if (
|
||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
||||
this.dialogRef?.getState() === MatDialogState.OPEN ||
|
||||
($event.target as Target).localName === 'input'
|
||||
($event.target as IqserEventTarget).localName === 'input'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<div class="page-header">
|
||||
<div *ngIf="pageLabel" class="breadcrumb">{{ pageLabel }}</div>
|
||||
|
||||
<div *ngIf="filters$ | async as filters" class="filters" redactionHelpMode="filters">
|
||||
<div *ngIf="filters$ | async as filters" class="filters" iqserHelpMode="filters">
|
||||
<div *ngIf="filters.length && searchPosition !== searchPositions.beforeFilters" translate="filters.filter-by"></div>
|
||||
|
||||
<ng-container *ngIf="searchPosition === searchPositions.beforeFilters" [ngTemplateOutlet]="searchBar"></ng-container>
|
||||
@ -23,7 +23,7 @@
|
||||
[icon]="config.icon"
|
||||
[label]="config.label | translate"
|
||||
[type]="config.type"
|
||||
redactionHelpMode="new-dossier"
|
||||
iqserHelpMode="new-dossier"
|
||||
></iqser-icon-button>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener, Input, OnInit, Renderer2 } from '@angular/core';
|
||||
import { HelpModeService } from '@shared/services/help-mode.service';
|
||||
import * as links from '../../../../assets/help-mode/links.json';
|
||||
import { LanguageService } from '@i18n/language.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[redactionHelpMode]',
|
||||
exportAs: 'redactionHelpMode'
|
||||
})
|
||||
export class HelpModeDirective implements OnInit {
|
||||
@Input('redactionHelpMode') elementName: string;
|
||||
|
||||
constructor(
|
||||
private readonly _elementRef: ElementRef,
|
||||
private readonly _renderer: Renderer2,
|
||||
private readonly _helpModeService: HelpModeService,
|
||||
private readonly _languageService: LanguageService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._createHelperElement();
|
||||
}
|
||||
|
||||
private _createHelperElement() {
|
||||
const element = this._elementRef.nativeElement;
|
||||
|
||||
const helperElement = this._renderer.createElement('div');
|
||||
this._renderer.addClass(helperElement, 'help-mode-on-mouse-over');
|
||||
this._renderer.addClass(helperElement, `help-mode-on-mouse-over-${this.elementName}`);
|
||||
|
||||
this._helpModeService.addElement(this.elementName, element, helperElement);
|
||||
}
|
||||
|
||||
@HostListener('click') onClick(): void {
|
||||
if (this._helpModeService.isHelpModeActive) {
|
||||
const currentLocale = this._languageService.currentLanguage;
|
||||
window.open(links[this.elementName][currentLocale]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';
|
||||
import { HelpModeDialogComponent } from '@components/help-mode-dialog/help-mode-dialog.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
||||
interface Helper {
|
||||
readonly element: HTMLElement;
|
||||
readonly helperElement: HTMLElement;
|
||||
}
|
||||
|
||||
interface HelpElement {
|
||||
[key: string]: Helper;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class HelpModeService {
|
||||
isHelpModeActive = false;
|
||||
helpModeDialogIsOpened = false;
|
||||
|
||||
private _elements: HelpElement = {};
|
||||
|
||||
private readonly _renderer: Renderer2;
|
||||
|
||||
constructor(private readonly _dialog: MatDialog, private readonly _rendererFactory: RendererFactory2) {
|
||||
this._renderer = this._rendererFactory.createRenderer(null, null);
|
||||
}
|
||||
|
||||
openHelpModeDialog() {
|
||||
this.helpModeDialogIsOpened = true;
|
||||
|
||||
const ref = this._dialog.open(HelpModeDialogComponent, {
|
||||
width: '600px'
|
||||
});
|
||||
|
||||
ref.afterClosed().subscribe(() => {
|
||||
this.helpModeDialogIsOpened = false;
|
||||
});
|
||||
}
|
||||
|
||||
activateHelpMode() {
|
||||
this.isHelpModeActive = true;
|
||||
this.openHelpModeDialog();
|
||||
this._enableHelperElements();
|
||||
}
|
||||
|
||||
deactivateHelpMode() {
|
||||
this.isHelpModeActive = false;
|
||||
this._disableHelperElements();
|
||||
}
|
||||
|
||||
highlightHelperElements() {
|
||||
for (const { helperElement } of Object.values(this._elements)) {
|
||||
this._renderer.addClass(helperElement, 'highlight');
|
||||
setTimeout(() => {
|
||||
this._renderer.removeClass(helperElement, 'highlight');
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
addElement(elementName: string, element: HTMLElement, helperElement: HTMLElement) {
|
||||
this._elements[elementName] = { element, helperElement };
|
||||
}
|
||||
|
||||
private _enableHelperElements() {
|
||||
for (const { element, helperElement } of Object.values(this._elements)) {
|
||||
this._renderer.setStyle(element, 'position', 'relative');
|
||||
this._renderer.appendChild(element, helperElement);
|
||||
}
|
||||
}
|
||||
|
||||
private _disableHelperElements() {
|
||||
for (const { element, helperElement } of Object.values(this._elements)) {
|
||||
this._renderer.removeStyle(element, 'position');
|
||||
this._renderer.removeChild(element, helperElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,6 @@ import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
|
||||
import { AssignUserDropdownComponent } from './components/assign-user-dropdown/assign-user-dropdown.component';
|
||||
import { PageHeaderComponent } from './components/page-header/page-header.component';
|
||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||
import { HelpModeDirective } from '@shared/directives/help-mode.directive';
|
||||
|
||||
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
||||
|
||||
@ -50,7 +49,7 @@ const components = [
|
||||
...buttons
|
||||
];
|
||||
|
||||
const utils = [DatePipe, HasScrollbarDirective, NavigateLastDossiersScreenDirective, HelpModeDirective];
|
||||
const utils = [DatePipe, HasScrollbarDirective, NavigateLastDossiersScreenDirective];
|
||||
|
||||
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
|
||||
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
@import 'variables';
|
||||
|
||||
.mat-dialog-container {
|
||||
color: $accent;
|
||||
padding: 0 !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
position: relative;
|
||||
min-height: 80px;
|
||||
|
||||
.dialog-close {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.dialog-header {
|
||||
padding: 32px 60px 0 32px;
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
padding: 24px 32px 40px;
|
||||
}
|
||||
|
||||
.dialog-actions {
|
||||
height: 81px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid $separator;
|
||||
padding: 0 32px;
|
||||
align-items: center;
|
||||
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,18 +29,6 @@ pre {
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
.heading-l {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
@import 'red-material-theme';
|
||||
@import 'red-page-layout';
|
||||
@import 'red-text-styles';
|
||||
@import 'red-dialog';
|
||||
@import 'red-select';
|
||||
@import 'red-autocomplete';
|
||||
@import 'red-list';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user