RED-10563: fixed key actions not prevented when input is focused.
Also updated config.json with documine stack and properties.
This commit is contained in:
parent
a890e4c5bc
commit
584a6b7bd0
@ -1,7 +1,6 @@
|
|||||||
import { Component, computed, ElementRef, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, computed, ElementRef, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { getConfig, HasScrollbarDirective } from '@iqser/common-ui';
|
import { getConfig, HasScrollbarDirective } from '@iqser/common-ui';
|
||||||
import { FilterService } from '@iqser/common-ui/lib/filtering';
|
import { FilterService } from '@iqser/common-ui/lib/filtering';
|
||||||
import { IqserEventTarget } from '@iqser/common-ui/lib/utils';
|
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { ListItem } from '@models/file/list-item';
|
import { ListItem } from '@models/file/list-item';
|
||||||
import { EarmarkGroup } from '@red/domain';
|
import { EarmarkGroup } from '@red/domain';
|
||||||
@ -15,6 +14,7 @@ import { NgForOf, NgIf } from '@angular/common';
|
|||||||
import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component';
|
import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component';
|
||||||
import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component';
|
import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component';
|
||||||
import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component';
|
import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component';
|
||||||
|
import { isTargetInput } from '@utils/functions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-annotations-list',
|
selector: 'redaction-annotations-list',
|
||||||
@ -52,7 +52,7 @@ export class AnnotationsListComponent extends HasScrollbarDirective {
|
|||||||
console.log('Selected Annotation:', annotation);
|
console.log('Selected Annotation:', annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($event?.target as IqserEventTarget)?.localName === 'input') {
|
if (isTargetInput($event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import {
|
|||||||
Component,
|
Component,
|
||||||
computed,
|
computed,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
HostListener,
|
|
||||||
Input,
|
Input,
|
||||||
NgZone,
|
NgZone,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
@ -19,7 +18,6 @@ import {
|
|||||||
getConfig,
|
getConfig,
|
||||||
HelpModeService,
|
HelpModeService,
|
||||||
IqserAllowDirective,
|
IqserAllowDirective,
|
||||||
IqserDialog,
|
|
||||||
IqserPermissionsService,
|
IqserPermissionsService,
|
||||||
isIqserDevMode,
|
isIqserDevMode,
|
||||||
LoadingService,
|
LoadingService,
|
||||||
@ -51,6 +49,7 @@ import { ALL_HOTKEYS } from '../../utils/constants';
|
|||||||
import { AnnotationDrawService } from '../../../pdf-viewer/services/annotation-draw.service';
|
import { AnnotationDrawService } from '../../../pdf-viewer/services/annotation-draw.service';
|
||||||
import { FileManagementService } from '@services/files/file-management.service';
|
import { FileManagementService } from '@services/files/file-management.service';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { isTargetInput, isTargetTextArea } from '@utils/functions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-file-header',
|
selector: 'redaction-file-header',
|
||||||
@ -105,6 +104,7 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
document.documentElement.addEventListener('fullscreenchange', this.fullscreenListener);
|
document.documentElement.addEventListener('fullscreenchange', this.fullscreenListener);
|
||||||
|
this._pdf.instance.UI.iframeWindow.addEventListener('keyup', this.handleKeyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
@ -116,10 +116,12 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD
|
|||||||
|
|
||||||
ngOnDetach() {
|
ngOnDetach() {
|
||||||
document.documentElement.removeEventListener('fullscreenchange', this.fullscreenListener);
|
document.documentElement.removeEventListener('fullscreenchange', this.fullscreenListener);
|
||||||
|
this._pdf.instance.UI.iframeWindow.removeEventListener('keyup', this.handleKeyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
document.documentElement.removeEventListener('fullscreenchange', this.fullscreenListener);
|
document.documentElement.removeEventListener('fullscreenchange', this.fullscreenListener);
|
||||||
|
this._pdf.instance.UI.iframeWindow.removeEventListener('keyup', this.handleKeyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadOriginalFile({ cacheIdentifier, dossierId, fileId, filename }: File) {
|
async downloadOriginalFile({ cacheIdentifier, dossierId, fileId, filename }: File) {
|
||||||
@ -177,7 +179,7 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('document:keyup', ['$event'])
|
@Bind()
|
||||||
handleKeyEvent($event: KeyboardEvent) {
|
handleKeyEvent($event: KeyboardEvent) {
|
||||||
if (this._router.url.indexOf('/file/') < 0) {
|
if (this._router.url.indexOf('/file/') < 0) {
|
||||||
return;
|
return;
|
||||||
@ -208,19 +210,20 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD
|
|||||||
this._changeRef.markForCheck();
|
this._changeRef.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($event.key === 'F5') {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTargetInput($event) || isTargetTextArea($event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$event.ctrlKey && !$event.metaKey && ['f', 'F'].includes($event.key)) {
|
if (!$event.ctrlKey && !$event.metaKey && ['f', 'F'].includes($event.key)) {
|
||||||
// if you type in an input, don't toggle full-screen
|
|
||||||
if ($event.target instanceof HTMLInputElement || $event.target instanceof HTMLTextAreaElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.toggleFullScreen();
|
this.toggleFullScreen();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['h', 'H'].includes($event.key)) {
|
if (['h', 'H'].includes($event.key)) {
|
||||||
if ($event.target instanceof HTMLInputElement || $event.target instanceof HTMLTextAreaElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
window.focus();
|
window.focus();
|
||||||
this._helpModeService.activateHelpMode(false);
|
this._helpModeService.activateHelpMode(false);
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import {
|
|||||||
PreventDefaultDirective,
|
PreventDefaultDirective,
|
||||||
} from '@iqser/common-ui';
|
} from '@iqser/common-ui';
|
||||||
import { FilterService, INestedFilter, PopupFilterComponent } from '@iqser/common-ui/lib/filtering';
|
import { FilterService, INestedFilter, PopupFilterComponent } from '@iqser/common-ui/lib/filtering';
|
||||||
import { AutoUnsubscribe, Debounce, IqserEventTarget } from '@iqser/common-ui/lib/utils';
|
import { AutoUnsubscribe, Debounce } from '@iqser/common-ui/lib/utils';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { ListItem } from '@models/file/list-item';
|
import { ListItem } from '@models/file/list-item';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@ -57,6 +57,7 @@ import { PageExclusionComponent } from '../page-exclusion/page-exclusion.compone
|
|||||||
import { PagesComponent } from '../pages/pages.component';
|
import { PagesComponent } from '../pages/pages.component';
|
||||||
import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component';
|
import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component';
|
||||||
import { DocumentInfoComponent } from '../document-info/document-info.component';
|
import { DocumentInfoComponent } from '../document-info/document-info.component';
|
||||||
|
import { isTargetInput } from '@utils/functions';
|
||||||
|
|
||||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||||
@ -89,10 +90,7 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
|
export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
|
||||||
private readonly _annotationsElement = viewChild<ElementRef>('annotationsElement');
|
|
||||||
private readonly _quickNavigationElement = viewChild<ElementRef>('quickNavigation');
|
|
||||||
readonly multiSelectTemplate = viewChild<TemplateRef<any>>('multiSelect');
|
readonly multiSelectTemplate = viewChild<TemplateRef<any>>('multiSelect');
|
||||||
readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode;
|
|
||||||
protected readonly iconButtonTypes = IconButtonTypes;
|
protected readonly iconButtonTypes = IconButtonTypes;
|
||||||
protected readonly circleButtonTypes = CircleButtonTypes;
|
protected readonly circleButtonTypes = CircleButtonTypes;
|
||||||
protected readonly displayedAnnotations$: Observable<Map<number, ListItem<AnnotationWrapper>[]>>;
|
protected readonly displayedAnnotations$: Observable<Map<number, ListItem<AnnotationWrapper>[]>>;
|
||||||
@ -106,6 +104,9 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
protected displayedPages: number[] = [];
|
protected displayedPages: number[] = [];
|
||||||
protected pagesPanelActive = true;
|
protected pagesPanelActive = true;
|
||||||
protected enabledFilters = [];
|
protected enabledFilters = [];
|
||||||
|
private readonly _annotationsElement = viewChild<ElementRef>('annotationsElement');
|
||||||
|
private readonly _quickNavigationElement = viewChild<ElementRef>('quickNavigation');
|
||||||
|
readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode;
|
||||||
#displayedPagesChanged = false;
|
#displayedPagesChanged = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -245,11 +246,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
|
|
||||||
@HostListener('window:keyup', ['$event'])
|
@HostListener('window:keyup', ['$event'])
|
||||||
handleKeyEvent($event: KeyboardEvent): void {
|
handleKeyEvent($event: KeyboardEvent): void {
|
||||||
if (
|
if (!ALL_HOTKEY_ARRAY.includes($event.key) || this._dialog.openDialogs.length || isTargetInput($event)) {
|
||||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
|
||||||
this._dialog.openDialogs.length ||
|
|
||||||
($event.target as IqserEventTarget).localName === 'input'
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +328,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
}
|
}
|
||||||
|
|
||||||
preventKeyDefault($event: KeyboardEvent): void {
|
preventKeyDefault($event: KeyboardEvent): void {
|
||||||
if (COMMAND_KEY_ARRAY.includes($event.key) && !(($event.target as any).localName === 'input')) {
|
if (COMMAND_KEY_ARRAY.includes($event.key) && !isTargetInput($event)) {
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { PdfViewer } from './pdf-viewer.service';
|
|||||||
import Color = Core.Annotations.Color;
|
import Color = Core.Annotations.Color;
|
||||||
import DocumentViewer = Core.DocumentViewer;
|
import DocumentViewer = Core.DocumentViewer;
|
||||||
import Quad = Core.Math.Quad;
|
import Quad = Core.Math.Quad;
|
||||||
|
import { isTargetInput } from '@utils/functions';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class REDDocumentViewer {
|
export class REDDocumentViewer {
|
||||||
@ -71,12 +72,12 @@ export class REDDocumentViewer {
|
|||||||
return fromEvent<KeyboardEvent>(this.#document, 'keyUp').pipe(
|
return fromEvent<KeyboardEvent>(this.#document, 'keyUp').pipe(
|
||||||
tap(stopAndPreventIfNotAllowed),
|
tap(stopAndPreventIfNotAllowed),
|
||||||
filter($event => {
|
filter($event => {
|
||||||
if (($event.target as HTMLElement)?.tagName?.toLowerCase() === 'input') {
|
if (isTargetInput($event)) {
|
||||||
if ($event.key === 'Escape') {
|
if ($event.key === 'Escape') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ($event.target as HTMLElement)?.tagName?.toLowerCase() !== 'input';
|
return isTargetInput($event);
|
||||||
}),
|
}),
|
||||||
filter($event => $event.key.startsWith('Arrow') || ['f', 'h', 'H', 'Escape'].includes($event.key)),
|
filter($event => $event.key.startsWith('Arrow') || ['f', 'h', 'H', 'Escape'].includes($event.key)),
|
||||||
tap<KeyboardEvent>(stopAndPrevent),
|
tap<KeyboardEvent>(stopAndPrevent),
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { ITrackable } from '@iqser/common-ui';
|
import { ITrackable } from '@iqser/common-ui';
|
||||||
import type { List } from '@iqser/common-ui/lib/utils';
|
import type { IqserEventTarget, List } from '@iqser/common-ui/lib/utils';
|
||||||
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { Dayjs } from 'dayjs';
|
import { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
@ -143,3 +143,11 @@ export function urlFileId() {
|
|||||||
const fileId = splitUrl[splitUrl.length - 1];
|
const fileId = splitUrl[splitUrl.length - 1];
|
||||||
return fileId.split('?')[0];
|
return fileId.split('?')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isTargetInput(event: Event) {
|
||||||
|
return (event?.target as IqserEventTarget)?.localName === 'input';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTargetTextArea(event: Event) {
|
||||||
|
return (event?.target as IqserEventTarget)?.localName === 'textarea';
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"ADMIN_CONTACT_NAME": null,
|
"ADMIN_CONTACT_NAME": null,
|
||||||
"ADMIN_CONTACT_URL": null,
|
"ADMIN_CONTACT_URL": null,
|
||||||
"API_URL": "https://dan2.iqser.cloud",
|
"API_URL": "https://frontend2.iqser.cloud",
|
||||||
"APP_NAME": "RedactManager",
|
"APP_NAME": "RedactManager",
|
||||||
"IS_DOCUMINE": false,
|
"IS_DOCUMINE": true,
|
||||||
"RULE_EDITOR_DEV_ONLY": false,
|
"RULE_EDITOR_DEV_ONLY": false,
|
||||||
"AUTO_READ_TIME": 3,
|
"AUTO_READ_TIME": 3,
|
||||||
"BACKEND_APP_VERSION": "4.4.40",
|
"BACKEND_APP_VERSION": "4.4.40",
|
||||||
@ -13,13 +13,13 @@
|
|||||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||||
"OAUTH_CLIENT_ID": "redaction",
|
"OAUTH_CLIENT_ID": "redaction",
|
||||||
"OAUTH_IDP_HINT": null,
|
"OAUTH_IDP_HINT": null,
|
||||||
"OAUTH_URL": "https://dan2.iqser.cloud/auth",
|
"OAUTH_URL": "https://frontend2.iqser.cloud/auth",
|
||||||
"RECENT_PERIOD_IN_HOURS": 24,
|
"RECENT_PERIOD_IN_HOURS": 24,
|
||||||
"SELECTION_MODE": "structural",
|
"SELECTION_MODE": "structural",
|
||||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
||||||
"ANNOTATIONS_THRESHOLD": 1000,
|
"ANNOTATIONS_THRESHOLD": 1000,
|
||||||
"THEME": "redact",
|
"THEME": "scm",
|
||||||
"BASE_TRANSLATIONS_DIRECTORY": "/assets/i18n/redact/",
|
"BASE_TRANSLATIONS_DIRECTORY": "/assets/i18n/scm/",
|
||||||
"AVAILABLE_NOTIFICATIONS_DAYS": 30,
|
"AVAILABLE_NOTIFICATIONS_DAYS": 30,
|
||||||
"AVAILABLE_OLD_NOTIFICATIONS_MINUTES": 60,
|
"AVAILABLE_OLD_NOTIFICATIONS_MINUTES": 60,
|
||||||
"NOTIFICATIONS_THRESHOLD": 1000,
|
"NOTIFICATIONS_THRESHOLD": 1000,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user