DM-366 fix tooltip nbsp

This commit is contained in:
Dan Percic 2023-08-07 15:25:23 +03:00
parent 9bb8949d9c
commit c831e29fe4
14 changed files with 198 additions and 81 deletions

View File

@ -79,7 +79,6 @@
"accessibility": "no-public"
}
],
"@typescript-eslint/member-ordering": "warn",
"@typescript-eslint/naming-convention": [
"error",
{
@ -133,6 +132,115 @@
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/member-ordering": [
"warn",
{
"default": [
// Index signature
"signature",
"call-signature",
// Fields
"#private-static-field",
"private-static-field",
"protected-static-field",
"public-static-field",
"#private-instance-field",
"private-instance-field",
"protected-instance-field",
"public-instance-field",
"private-decorated-field",
"protected-decorated-field",
"public-decorated-field",
"protected-abstract-field",
"public-abstract-field",
"#private-field",
"private-field",
"protected-field",
"public-field",
"static-field",
"instance-field",
"abstract-field",
"decorated-field",
"field",
// Static initialization
"static-initialization",
// Constructors
"public-constructor",
"protected-constructor",
"private-constructor",
"constructor",
// Getters
"public-static-get",
"protected-static-get",
"private-static-get",
"#private-static-get",
"public-decorated-get",
"protected-decorated-get",
"private-decorated-get",
"public-instance-get",
"protected-instance-get",
"private-instance-get",
"#private-instance-get",
"public-abstract-get",
"protected-abstract-get",
"public-get",
"protected-get",
"private-get",
"#private-get",
"static-get",
"instance-get",
"abstract-get",
"decorated-get",
"get",
// Setters
"public-static-set",
"protected-static-set",
"private-static-set",
"#private-static-set",
"public-decorated-set",
"protected-decorated-set",
"private-decorated-set",
"public-instance-set",
"protected-instance-set",
"private-instance-set",
"#private-instance-set",
"public-abstract-set",
"protected-abstract-set",
"public-set",
"protected-set",
"private-set",
"#private-set",
"static-set",
"instance-set",
"abstract-set",
"decorated-set",
"set",
// Methods
"public-static-method",
"protected-static-method",
"private-static-method",
"#private-static-method",
"public-decorated-method",
"protected-decorated-method",
"private-decorated-method",
"public-instance-method",
"protected-instance-method",
"private-instance-method",
"#private-instance-method",
"public-abstract-method",
"protected-abstract-method",
"public-method",
"protected-method",
"private-method",
"#private-method",
"static-method",
"instance-method",
"abstract-method",
"decorated-method",
"method"
]
}
],
"arrow-body-style": "error",
"arrow-parens": ["error", "as-needed"],
"constructor-super": "error",

View File

@ -10,7 +10,7 @@ interface PreferencesForm {
// preferences
autoExpandFiltersOnActions: boolean;
displaySuggestionsInPreview: boolean;
openStructuredComponentManagementDialogByDefault: boolean;
openScmDialogByDefault: boolean;
tableExtractionType: string;
// warnings preferences
unapprovedSuggestionsWarning: boolean;
@ -52,9 +52,7 @@ export class PreferencesComponent extends BaseFormComponent implements OnInit {
// preferences
autoExpandFiltersOnActions: [this.userPreferenceService.getAutoExpandFiltersOnActions()],
displaySuggestionsInPreview: [this.userPreferenceService.getDisplaySuggestionsInPreview()],
openStructuredComponentManagementDialogByDefault: [
this.userPreferenceService.getOpenStructuredComponentManagementDialogByDefault(),
],
openScmDialogByDefault: [this.userPreferenceService.getOpenScmDialogByDefault()],
tableExtractionType: [this.userPreferenceService.getTableExtractionType()],
// warnings preferences
unapprovedSuggestionsWarning: [this.userPreferenceService.getUnapprovedSuggestionsWarning()],
@ -84,11 +82,8 @@ export class PreferencesComponent extends BaseFormComponent implements OnInit {
if (this.form.controls.displaySuggestionsInPreview.value !== this.userPreferenceService.getDisplaySuggestionsInPreview()) {
await this.userPreferenceService.toggleDisplaySuggestionsInPreview();
}
if (
this.form.controls.openStructuredComponentManagementDialogByDefault.value !==
this.userPreferenceService.getOpenStructuredComponentManagementDialogByDefault()
) {
await this.userPreferenceService.toggleOpenStructuredComponentManagementDialogByDefault();
if (this.form.controls.openScmDialogByDefault.value !== this.userPreferenceService.getOpenScmDialogByDefault()) {
await this.userPreferenceService.toggleOpenScmDialogByDefault();
}
if (this.form.controls.unapprovedSuggestionsWarning.value !== this.userPreferenceService.getUnapprovedSuggestionsWarning()) {
await this.userPreferenceService.toggleUnapprovedSuggestionsWarning();
@ -119,8 +114,7 @@ export class PreferencesComponent extends BaseFormComponent implements OnInit {
this.form.patchValue({
autoExpandFiltersOnActions: this.userPreferenceService.getAutoExpandFiltersOnActions(),
displaySuggestionsInPreview: this.userPreferenceService.getDisplaySuggestionsInPreview(),
openStructuredComponentManagementDialogByDefault:
this.userPreferenceService.getOpenStructuredComponentManagementDialogByDefault(),
openScmDialogByDefault: this.userPreferenceService.getOpenScmDialogByDefault(),
tableExtractionType: this.userPreferenceService.getTableExtractionType(),
unapprovedSuggestionsWarning: this.userPreferenceService.getUnapprovedSuggestionsWarning(),
loadAllAnnotationsWarning: this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),

View File

@ -3,32 +3,32 @@
<hr />
<div class="dialog-content">
<div *ngIf="rssData() | log as rssEntry" class="table output-data">
<div *ngIf="scmData() as scmEntry" class="table output-data">
<div class="table-header">{{ 'rss-dialog.table-header.component' | translate }}</div>
<div class="table-header">{{ 'rss-dialog.table-header.value' | translate }}</div>
<div class="table-header">{{ 'rss-dialog.table-header.transformation-rule' | translate }}</div>
<div class="table-header">{{ 'rss-dialog.table-header.annotation-references' | translate }}</div>
<ng-container *ngFor="let entry of rssEntry.result | keyvalue : originalOrder; let index = index">
<ng-container *ngFor="let entry of scmEntry.result | keyvalue : originalOrder; let index = index">
<div class="bold">{{ entry.key }}</div>
<div [id]="getValueCellId(index)">
<iqser-editable-input
(save)="saveEdit($event, entry.value.originalKey)"
[canEdit]="canEdit"
[buttonsType]="circleButtonTypes.dark"
[canEdit]="canEdit"
[cancelTooltip]="'rss-dialog.actions.cancel-edit' | translate"
[editTooltip]="'rss-dialog.actions.edit' | translate"
[saveTooltip]="'rss-dialog.actions.save' | translate"
[value]="entry.value.value ?? entry.value.originalValue"
[id]="'value-' + index"
[parentId]="getValueCellId(index)"
[saveTooltip]="'rss-dialog.actions.save' | translate"
[value]="entry.value.value ?? entry.value.originalValue"
>
<ng-container slot="editing">
<iqser-circle-button
(action)="undo(entry.value.originalKey)"
*ngIf="entry.value.value && canEdit"
[showDot]="true"
[tooltip]="'rss-dialog.actions.undo' | translate : { value: entry.value.originalValue }"
[tooltip]="'rss-dialog.actions.undo' | translate : { value: entry.value.originalValue } | replaceNbsp"
[type]="circleButtonTypes.dark"
class="ml-2"
icon="red:undo"
@ -83,13 +83,9 @@
></iqser-icon-button>
<div [translate]="'rss-dialog.actions.close'" class="all-caps-label cancel" mat-dialog-close></div>
<mat-checkbox
class="ml-auto"
color="primary"
(change)="toggleOpenStructuredComponentManagementDialogByDefault()"
[checked]="openStructuredComponentManagementDialogByDefault()"
>Display by default when opening documents</mat-checkbox
>
<mat-checkbox (change)="toggleOpenScmDialogByDefault()" [checked]="openScmDialogByDefault()" class="ml-auto" color="primary"
>{{ 'rss-dialog.actions.display-by-default' | translate }}
</mat-checkbox>
</div>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>

View File

@ -1,34 +1,55 @@
import { KeyValuePipe, NgForOf, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, OnInit, signal } from '@angular/core';
import { BaseDialogComponent, CircleButtonTypes } from '@iqser/common-ui';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { RssService } from '@services/files/rss.service';
import { IFile, RssEntry, RssResult, WorkflowFileStatuses } from '@red/domain';
import { firstValueFrom } from 'rxjs';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ReplaceNbspPipe } from '@common-ui/pipes/replace-nbsp.pipe';
import {
BaseDialogComponent,
CircleButtonComponent,
CircleButtonTypes,
EditableInputComponent,
IconButtonComponent,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { IFile, RssEntry, WorkflowFileStatuses } from '@red/domain';
import { FilesMapService } from '@services/files/files-map.service';
import { RssService } from '@services/files/rss.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { firstValueFrom } from 'rxjs';
interface RssData {
interface ScmData {
file: IFile;
}
@Component({
templateUrl: './rss-dialog.component.html',
styleUrls: ['./rss-dialog.component.scss'],
templateUrl: './structured-component-management-dialog.component.html',
styleUrls: ['./structured-component-management-dialog.component.scss'],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
NgIf,
EditableInputComponent,
NgForOf,
KeyValuePipe,
TranslateModule,
CircleButtonComponent,
IconButtonComponent,
MatCheckboxModule,
MatDialogModule,
ReplaceNbspPipe,
],
})
export class RssDialogComponent extends BaseDialogComponent implements OnInit {
export class StructuredComponentManagementDialogComponent extends BaseDialogComponent implements OnInit {
readonly circleButtonTypes = CircleButtonTypes;
readonly rssData = signal<RssEntry | undefined>(undefined);
readonly openStructuredComponentManagementDialogByDefault = signal(
this.userPreferences.getOpenStructuredComponentManagementDialogByDefault(),
);
readonly scmData = signal<RssEntry | undefined>(undefined);
readonly openScmDialogByDefault = signal(this.userPreferences.getOpenScmDialogByDefault());
constructor(
protected readonly _dialogRef: MatDialogRef<RssDialogComponent>,
protected readonly _dialogRef: MatDialogRef<StructuredComponentManagementDialogComponent>,
private readonly _rssService: RssService,
readonly userPreferences: UserPreferenceService,
private readonly _filesMapService: FilesMapService,
@Inject(MAT_DIALOG_DATA) readonly data: RssData,
@Inject(MAT_DIALOG_DATA) readonly data: ScmData,
) {
super(_dialogRef);
}
@ -67,12 +88,10 @@ export class RssDialogComponent extends BaseDialogComponent implements OnInit {
return this.exportJSON();
}
async toggleOpenStructuredComponentManagementDialogByDefault() {
await this.userPreferences.toggleOpenStructuredComponentManagementDialogByDefault();
async toggleOpenScmDialogByDefault() {
await this.userPreferences.toggleOpenScmDialogByDefault();
await this.userPreferences.reload();
this.openStructuredComponentManagementDialogByDefault.set(
this.userPreferences.getOpenStructuredComponentManagementDialogByDefault(),
);
this.openScmDialogByDefault.set(this.userPreferences.getOpenScmDialogByDefault());
}
async undo(originalKey: string) {
@ -90,7 +109,7 @@ export class RssDialogComponent extends BaseDialogComponent implements OnInit {
async #loadData(): Promise<void> {
this._loadingService.start();
const rssData = await firstValueFrom(this._rssService.getRSSData(this.data.file.dossierId, this.data.file.fileId));
this.rssData.set(rssData);
this.scmData.set(rssData);
this._loadingService.stop();
}
}

View File

@ -88,14 +88,8 @@ const textActions = [TextPopups.REDACT_TEXT, TextPopups.ADD_HINT, TextPopups.ADD
})
export class FilePreviewScreenComponent
extends AutoUnsubscribe
implements AfterViewInit, OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate {
@ViewChild('annotationFilterTemplate', {
read: TemplateRef,
static: false,
})
private readonly _filterTemplate: TemplateRef<unknown>;
@ViewChild('actionsWrapper', {static: false}) private readonly _actionsWrapper: ElementRef;
readonly #isDocumine = getConfig().IS_DOCUMINE;
implements AfterViewInit, OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate
{
readonly circleButtonTypes = CircleButtonTypes;
readonly roles = Roles;
fullScreen = false;
@ -103,6 +97,13 @@ export class FilePreviewScreenComponent
readonly dossierId = this.state.dossierId;
readonly lastAssignee = computed(() => this.getLastAssignee());
width: number;
@ViewChild('annotationFilterTemplate', {
read: TemplateRef,
static: false,
})
private readonly _filterTemplate: TemplateRef<unknown>;
@ViewChild('actionsWrapper', { static: false }) private readonly _actionsWrapper: ElementRef;
readonly #isDocumine = getConfig().IS_DOCUMINE;
constructor(
readonly pdf: PdfViewer,
@ -161,7 +162,7 @@ export class FilePreviewScreenComponent
this.viewerReady().then();
}
},
{allowSignalWrites: true},
{ allowSignalWrites: true },
);
effect(() => {
@ -208,7 +209,7 @@ export class FilePreviewScreenComponent
}
getLastAssignee() {
const {isApproved, lastReviewer, lastApprover} = this.state.file();
const { isApproved, lastReviewer, lastApprover } = this.state.file();
const isRss = this._iqserPermissionsService.has(this.roles.getRss);
return isApproved ? (isRss ? lastReviewer : lastApprover) : lastReviewer;
}
@ -329,7 +330,7 @@ export class FilePreviewScreenComponent
this.#subscribeToFileUpdates();
if (file?.analysisRequired && !file.excludedFromAutomaticAnalysis) {
await this._reanalysisService.reanalyzeFilesForDossier([file], this.dossierId, {force: true});
await this._reanalysisService.reanalyzeFilesForDossier([file], this.dossierId, { force: true });
}
this.pdfProxyService.configureElements();
@ -351,7 +352,7 @@ export class FilePreviewScreenComponent
this._dialogService.openDialog(
'manualAnnotation',
{manualRedactionEntryWrapper, dossierId: this.dossierId, file},
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
(result: { annotations: ManualRedactionEntryWrapper[]; dictionary?: Dictionary }) => {
const selectedAnnotations = this._annotationManager.selected;
if (selectedAnnotations.length > 0) {
@ -362,7 +363,7 @@ export class FilePreviewScreenComponent
result.annotations.map(w => w.manualRedactionEntry).filter(e => e.positions[0].page <= file.numberOfPages),
this.dossierId,
this.fileId,
{dictionaryLabel: result.dictionary?.label},
{ dictionaryLabel: result.dictionary?.label },
);
const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file)));
@ -445,13 +446,13 @@ export class FilePreviewScreenComponent
}
}
async downloadOriginalFile({cacheIdentifier, dossierId, fileId, filename}: File) {
async downloadOriginalFile({ cacheIdentifier, dossierId, fileId, filename }: File) {
const originalFile = this._fileManagementService.downloadOriginal(dossierId, fileId, 'response', cacheIdentifier);
download(await firstValueFrom(originalFile), filename);
}
openRSSView() {
this._dialogService.openDialog('rss', {file: this.state.file()});
this._dialogService.openDialog('rss', { file: this.state.file() });
}
loadAnnotations() {
@ -517,7 +518,7 @@ export class FilePreviewScreenComponent
zip.file(filename + '_page' + currentPage + '_table' + (index + 1) + '.csv', blob);
});
saveAs(await zip.generateAsync({type: 'blob'}), filename + '_tables.zip');
saveAs(await zip.generateAsync({ type: 'blob' }), filename + '_tables.zip');
this._loadingService.stop();
}
@ -597,7 +598,7 @@ export class FilePreviewScreenComponent
async #updateQueryParamsPage(page: number): Promise<void> {
const extras: NavigationExtras = {
queryParams: {page},
queryParams: { page },
queryParamsHandling: 'merge',
replaceUrl: true,
};
@ -864,22 +865,19 @@ export class FilePreviewScreenComponent
}
#openRssDialogIfDefault() {
if (
this.permissionsService.canViewRssDialog() &&
this.userPreferenceService.getOpenStructuredComponentManagementDialogByDefault()
) {
if (this.permissionsService.canViewRssDialog() && this.userPreferenceService.getOpenScmDialogByDefault()) {
this.openRSSView();
}
}
#getRedactTextDialog(hint: boolean, data: RedactTextData) {
if (this.#isDocumine) {
return this._iqserDialog.openDefault(AddAnnotationDialogComponent, {data});
return this._iqserDialog.openDefault(AddAnnotationDialogComponent, { data });
}
if (hint) {
return this._iqserDialog.openDefault(AddHintDialogComponent, {data});
return this._iqserDialog.openDefault(AddHintDialogComponent, { data });
}
return this._iqserDialog.openDefault(RedactTextDialogComponent, {data});
return this._iqserDialog.openDefault(RedactTextDialogComponent, { data });
}
#getRedactTextDialogData(manualRedactionEntryWrapper: ManualRedactionEntryWrapper, file: File): RedactTextData {

View File

@ -54,7 +54,6 @@ import { AnnotationReferenceComponent } from './components/annotation-reference/
import { ImportRedactionsDialogComponent } from './dialogs/import-redactions-dialog/import-redactions-dialog';
import { DocumentUnloadedGuard } from './services/document-unloaded.guard';
import { FilePreviewRightContainerComponent } from './components/right-container/file-preview-right-container.component';
import { RssDialogComponent } from './dialogs/rss-dialog/rss-dialog.component';
import { ReadonlyBannerComponent } from './components/readonly-banner/readonly-banner.component';
import { SuggestionsService } from './services/suggestions.service';
import { PagesComponent } from './components/pages/pages.component';
@ -94,7 +93,6 @@ const dialogs = [
AcceptRecommendationDialogComponent,
DocumentInfoDialogComponent,
ImportRedactionsDialogComponent,
RssDialogComponent,
RedactTextDialogComponent,
EditRedactionDialogComponent,
EditAnnotationDialogComponent,

View File

@ -7,7 +7,7 @@ import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-d
import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
import { ConfirmationDialogComponent, DialogConfig, DialogService } from '@iqser/common-ui';
import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component';
import { RssDialogComponent } from '../dialogs/rss-dialog/rss-dialog.component';
import { StructuredComponentManagementDialogComponent } from '../dialogs/structured-component-management-dialog/structured-component-management-dialog.component';
type DialogType =
| 'confirm'
@ -47,7 +47,7 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
component: HighlightActionDialogComponent,
},
rss: {
component: RssDialogComponent,
component: StructuredComponentManagementDialogComponent,
dialogConfig: { width: '90vw' },
},
};

View File

@ -10,7 +10,7 @@ export const PreferencesKeys = {
displaySuggestionsInPreview: 'Display-Suggestions-In-Preview',
unapprovedSuggestionsWarning: 'Unapproved-Suggestions-Warning',
loadAllAnnotationsWarning: 'Load-All-Annotations-Warning',
openStructuredComponentManagementDialogByDefault: 'Open-Structured-Component-Management-By-Default',
openScmDialogByDefault: 'Open-Structured-Component-Management-By-Default',
tableExtractionType: 'Table-Extraction-Type',
} as const;
@ -55,13 +55,13 @@ export class UserPreferenceService extends IqserUserPreferenceService {
await this.save(PreferencesKeys.autoExpandFiltersOnActions, nextValue);
}
getOpenStructuredComponentManagementDialogByDefault(): boolean {
return this._getAttribute(PreferencesKeys.openStructuredComponentManagementDialogByDefault, 'false') === 'true';
getOpenScmDialogByDefault(): boolean {
return this._getAttribute(PreferencesKeys.openScmDialogByDefault, 'false') === 'true';
}
async toggleOpenStructuredComponentManagementDialogByDefault(): Promise<void> {
const nextValue = (!this.getOpenStructuredComponentManagementDialogByDefault()).toString();
await this.save(PreferencesKeys.openStructuredComponentManagementDialogByDefault, nextValue);
async toggleOpenScmDialogByDefault(): Promise<void> {
const nextValue = (!this.getOpenScmDialogByDefault()).toString();
await this.save(PreferencesKeys.openScmDialogByDefault, nextValue);
}
getDisplaySuggestionsInPreview(): boolean {

View File

@ -2199,6 +2199,7 @@
"actions": {
"cancel-edit": "",
"close": "",
"display-by-default": "",
"edit": "",
"export-json": "",
"export-xml": "",

View File

@ -2199,6 +2199,7 @@
"actions": {
"cancel-edit": "Cancel",
"close": "Close",
"display-by-default": "",
"edit": "Edit",
"export-json": "Export JSON",
"export-xml": "Export XML",

View File

@ -2199,6 +2199,7 @@
"actions": {
"cancel-edit": "",
"close": "",
"display-by-default": "",
"edit": "",
"export-json": "",
"export-xml": "",

View File

@ -2199,6 +2199,7 @@
"actions": {
"cancel-edit": "Cancel",
"close": "Close",
"display-by-default": "Display by default when opening documents",
"edit": "Edit",
"export-json": "Export JSON",
"export-xml": "Export XML",

@ -1 +1 @@
Subproject commit 5a4ed98aafcc92c437022664787677fcccaf04eb
Subproject commit c851ab1394fae4863d60424792ea1f8f8f83b1a8