Merge branch 'dan' into 'master'
RED-7393 update logo color See merge request redactmanager/red-ui!37
This commit is contained in:
commit
c0084258b0
@ -131,7 +131,7 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
features: {
|
||||
ANNOTATIONS: {
|
||||
color: 'aqua',
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
level: NgxLoggerLevel.DEBUG,
|
||||
},
|
||||
FILTERS: {
|
||||
@ -147,7 +147,7 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
enabled: true,
|
||||
},
|
||||
FILE: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
},
|
||||
CHANGES: {
|
||||
enabled: false,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Dictionary } from '@red/domain';
|
||||
|
||||
export const canUndo = (annotation: AnnotationWrapper, isApprover: boolean) =>
|
||||
@ -39,7 +39,9 @@ export const canRecategorizeAnnotation = (annotation: AnnotationWrapper, canReca
|
||||
|
||||
export const canResizeAnnotation = (annotation: AnnotationWrapper, canAddRedaction: boolean) =>
|
||||
canAddRedaction &&
|
||||
!annotation.isSkipped &&
|
||||
!annotation.pending &&
|
||||
(((annotation.isRedacted || annotation.isImage) && !annotation.isSuggestion) ||
|
||||
annotation.isSuggestionResize ||
|
||||
annotation.isRecommendation) &&
|
||||
!annotation.pending;
|
||||
annotation.isDictBasedHint ||
|
||||
annotation.isRecommendation);
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { AnnotationWrapper } from './annotation.wrapper';
|
||||
import { Dictionary } from '@red/domain';
|
||||
import { isArray } from 'lodash-es';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { Dictionary } from '@red/domain';
|
||||
import { Roles } from '@users/roles';
|
||||
import { isArray } from 'lodash-es';
|
||||
import {
|
||||
canAcceptRecommendation,
|
||||
canChangeLegalBasis,
|
||||
@ -16,6 +15,7 @@ import {
|
||||
canResizeAnnotation,
|
||||
canUndo,
|
||||
} from './annotation-permissions.utils';
|
||||
import { AnnotationWrapper } from './annotation.wrapper';
|
||||
|
||||
export class AnnotationPermissions {
|
||||
canUndo = true;
|
||||
@ -64,6 +64,22 @@ export class AnnotationPermissions {
|
||||
return summedPermissions;
|
||||
}
|
||||
|
||||
static reduce(permissions: AnnotationPermissions[]): AnnotationPermissions {
|
||||
const result = new AnnotationPermissions();
|
||||
result.canResizeAnnotation = permissions.length === 1 && permissions[0].canResizeAnnotation;
|
||||
result.canChangeLegalBasis = permissions.reduce((acc, next) => acc && next.canChangeLegalBasis, true);
|
||||
result.canRecategorizeAnnotation = permissions.reduce((acc, next) => acc && next.canRecategorizeAnnotation, true);
|
||||
result.canRemoveFromDictionary = permissions.reduce((acc, next) => acc && next.canRemoveFromDictionary, true);
|
||||
result.canAcceptRecommendation = permissions.reduce((acc, next) => acc && next.canAcceptRecommendation, true);
|
||||
result.canMarkAsFalsePositive = permissions.reduce((acc, next) => acc && next.canMarkAsFalsePositive, true);
|
||||
result.canForceRedaction = permissions.reduce((acc, next) => acc && next.canForceRedaction, true);
|
||||
result.canForceHint = permissions.reduce((acc, next) => acc && next.canForceHint, true);
|
||||
result.canRemoveOnlyHere = permissions.reduce((acc, next) => acc && next.canRemoveOnlyHere, true);
|
||||
result.canRemoveRedaction = permissions.reduce((acc, next) => acc && next.canRemoveRedaction, true);
|
||||
result.canUndo = permissions.reduce((acc, next) => acc && next.canUndo, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
private _merge(permissions: AnnotationPermissions) {
|
||||
for (const key of Object.keys(this)) {
|
||||
if (typeof this[key] === 'boolean') {
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
IRectangle,
|
||||
IRedactionLogEntry,
|
||||
LogEntryEngine,
|
||||
LogEntryEngines,
|
||||
LogEntryStatuses,
|
||||
LowLevelFilterTypes,
|
||||
ManualRedactionTypes,
|
||||
@ -180,6 +181,10 @@ export class AnnotationWrapper implements IListable {
|
||||
return 'square';
|
||||
}
|
||||
|
||||
get isDictBasedHint() {
|
||||
return this.isHint && this.engines.includes(LogEntryEngines.DICTIONARY);
|
||||
}
|
||||
|
||||
get isIgnoredHint() {
|
||||
return this.superType === SuperTypes.IgnoredHint;
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
|
||||
import { Dictionary, Dossier, SuperTypes } from '@red/domain';
|
||||
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { Dictionary, SuperTypes } from '@red/domain';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { Roles } from '@users/roles';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { IMAGE_CATEGORIES } from '../../utils/constants';
|
||||
import { getEditRedactionOptions, RedactOrHintOption } from '../../utils/dialog-options';
|
||||
import { EditRedactionData, EditRedactResult } from '../../utils/dialog-types';
|
||||
import { IMAGE_CATEGORIES } from '../../utils/constants';
|
||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: './edit-redaction-dialog.component.html',
|
||||
@ -19,6 +19,8 @@ export class EditRedactionDialogComponent
|
||||
extends IqserDialogComponent<EditRedactionDialogComponent, EditRedactionData, EditRedactResult>
|
||||
implements OnInit
|
||||
{
|
||||
readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
|
||||
readonly #applyToAllDossiers = this.data.applyToAllDossiers;
|
||||
readonly roles = Roles;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly redactedText: string;
|
||||
@ -28,24 +30,17 @@ export class EditRedactionDialogComponent
|
||||
readonly showLegalReason: boolean;
|
||||
readonly isHint: boolean;
|
||||
readonly showExtras: boolean;
|
||||
|
||||
options: DetailsRadioOption<RedactOrHintOption>[] | undefined;
|
||||
legalOptions: LegalBasisOption[] = [];
|
||||
dictionaries: Dictionary[] = [];
|
||||
form: UntypedFormGroup;
|
||||
readonly #dossier: Dossier;
|
||||
|
||||
#applyToAllDossiers: boolean;
|
||||
readonly form;
|
||||
|
||||
constructor(
|
||||
private readonly _justificationsService: JustificationsService,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
) {
|
||||
super();
|
||||
this.#dossier = this._activeDossiersService.find(this.data.dossierId);
|
||||
this.#applyToAllDossiers = this.data.applyToAllDossiers;
|
||||
const annotations = this.data.annotations;
|
||||
const firstEntry = annotations[0];
|
||||
this.isImage = [...IMAGE_CATEGORIES, 'ocr'].includes(firstEntry.type);
|
||||
@ -126,7 +121,7 @@ export class EditRedactionDialogComponent
|
||||
);
|
||||
}
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
#getForm() {
|
||||
return this._formBuilder.group({
|
||||
reason: [null],
|
||||
comment: [null],
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div class="dialog-header heading-l" [translate]="'recategorize-image-dialog.header'"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="iqser-input-group required w-400">
|
||||
<label [translate]="'recategorize-image-dialog.content.type'"></label>
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
[placeholder]="'recategorize-image-dialog.content.type-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="type"
|
||||
>
|
||||
<mat-option *ngFor="let option of typeOptions" [value]="option">
|
||||
{{ translations[option] | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-300">
|
||||
<label [translate]="'recategorize-image-dialog.content.comment'"></label>
|
||||
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
[disabled]="disabled"
|
||||
[label]="'recategorize-image-dialog.actions.save' | translate"
|
||||
[submit]="true"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
|
||||
<div class="all-caps-label cancel" mat-dialog-close [translate]="'recategorize-image-dialog.actions.cancel'"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||
</section>
|
||||
@ -1,41 +0,0 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { imageCategoriesTranslations } from '@translations/image-categories-translations';
|
||||
import { Dossier, ImageCategory } from '@red/domain';
|
||||
import { BaseDialogComponent } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
templateUrl: './recategorize-image-dialog.component.html',
|
||||
})
|
||||
export class RecategorizeImageDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
readonly typeOptions: ImageCategory[] = ['signature', 'logo', 'formula', 'image'];
|
||||
readonly translations = imageCategoriesTranslations;
|
||||
|
||||
constructor(
|
||||
protected readonly _dialogRef: MatDialogRef<RecategorizeImageDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: { annotations: AnnotationWrapper[]; dossier: Dossier },
|
||||
) {
|
||||
super(_dialogRef);
|
||||
}
|
||||
|
||||
get changed(): boolean {
|
||||
return this.form.get('type').value !== this.data.annotations[0].type;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this._formBuilder.group({
|
||||
type: [this.data.annotations[0].type, Validators.required],
|
||||
comment: [null],
|
||||
});
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
save() {
|
||||
this._dialogRef.close({
|
||||
type: this.form.get('type').value,
|
||||
comment: this.form.get('comment').value,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,19 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div
|
||||
[innerHTML]="'resize-redaction.dialog.header' | translate : { type: redaction.hint ? 'hint' : 'redaction' }"
|
||||
[innerHTML]="'resize-redaction.dialog.header' | translate: { type: redaction.hint ? 'hint' : 'redaction' }"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
|
||||
<div class="dialog-content redaction">
|
||||
<div class="iqser-input-group w-450">
|
||||
<div *ngIf="!redaction.isImage" class="iqser-input-group w-450">
|
||||
<label [translate]="'resize-redaction.dialog.content.original-text'" class="selected-text"></label>
|
||||
{{ redaction.value }}
|
||||
<span class="pl-20">{{ redaction.value }}</span>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-450">
|
||||
<div *ngIf="!redaction.isImage" class="iqser-input-group w-450">
|
||||
<label [translate]="'resize-redaction.dialog.content.resized-text'" class="selected-text"></label>
|
||||
{{ data.text }}
|
||||
<span class="pl-20">{{ data.text }}</span>
|
||||
</div>
|
||||
|
||||
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { PendingChangesGuard } from '@guards/can-deactivate.guard';
|
||||
import {
|
||||
CapitalizePipe,
|
||||
CircleButtonComponent,
|
||||
@ -20,58 +23,54 @@ import {
|
||||
RoundCheckboxComponent,
|
||||
StopPropagationDirective,
|
||||
} from '@iqser/common-ui';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { FilePreviewScreenComponent } from './file-preview-screen.component';
|
||||
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
|
||||
import { AnnotationDetailsComponent } from './components/annotation-details/annotation-details.component';
|
||||
import { AnnotationsListComponent } from './components/annotations-list/annotations-list.component';
|
||||
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
|
||||
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
|
||||
import { AnnotationActionsComponent } from './components/annotation-actions/annotation-actions.component';
|
||||
import { CommentsComponent } from './components/comments/comments.component';
|
||||
import { DocumentInfoComponent } from './components/document-info/document-info.component';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { ViewSwitchComponent } from './components/view-switch/view-switch.component';
|
||||
import { UserManagementComponent } from './components/user-management/user-management.component';
|
||||
import { AnnotationReferencesListComponent } from './components/annotation-references-list/annotation-references-list.component';
|
||||
import { AcceptRecommendationDialogComponent } from './dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component';
|
||||
import { AnnotationCardComponent } from './components/annotation-card/annotation-card.component';
|
||||
import { AnnotationReferencesPageIndicatorComponent } from './components/annotation-references-page-indicator/annotation-references-page-indicator.component';
|
||||
import { HighlightsSeparatorComponent } from './components/highlights-separator/highlights-separator.component';
|
||||
import { PendingChangesGuard } from '@guards/can-deactivate.guard';
|
||||
import { ManualAnnotationDialogComponent } from './dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { ForceAnnotationDialogComponent } from './dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
import { ResizeRedactionDialogComponent } from './dialogs/resize-redaction-dialog/resize-redaction-dialog.component';
|
||||
import { ChangeLegalBasisDialogComponent } from './dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||
import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
|
||||
import { HighlightActionDialogComponent } from './dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
|
||||
import { DocumentInfoDialogComponent } from './dialogs/document-info-dialog/document-info-dialog.component';
|
||||
import { ManualRedactionService } from './services/manual-redaction.service';
|
||||
import { AnnotationWrapperComponent } from './components/annotation-wrapper/annotation-wrapper.component';
|
||||
import { AnnotationReferenceComponent } from './components/annotation-reference/annotation-reference.component';
|
||||
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 { ReadonlyBannerComponent } from './components/readonly-banner/readonly-banner.component';
|
||||
import { PagesComponent } from './components/pages/pages.component';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
|
||||
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
|
||||
import { RemoveRedactionDialogComponent } from './dialogs/remove-redaction-dialog/remove-redaction-dialog.component';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { IqserFiltersModule } from '@iqser/common-ui/lib/filtering';
|
||||
import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
|
||||
import { AnnotationActionsComponent } from './components/annotation-actions/annotation-actions.component';
|
||||
import { AnnotationCardComponent } from './components/annotation-card/annotation-card.component';
|
||||
import { AnnotationDetailsComponent } from './components/annotation-details/annotation-details.component';
|
||||
import { AnnotationReferenceComponent } from './components/annotation-reference/annotation-reference.component';
|
||||
import { AnnotationReferencesListComponent } from './components/annotation-references-list/annotation-references-list.component';
|
||||
import { AnnotationReferencesPageIndicatorComponent } from './components/annotation-references-page-indicator/annotation-references-page-indicator.component';
|
||||
import { AnnotationWrapperComponent } from './components/annotation-wrapper/annotation-wrapper.component';
|
||||
import { AnnotationsListComponent } from './components/annotations-list/annotations-list.component';
|
||||
import { CommentsComponent } from './components/comments/comments.component';
|
||||
import { DocumentInfoComponent } from './components/document-info/document-info.component';
|
||||
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
|
||||
import { HighlightsSeparatorComponent } from './components/highlights-separator/highlights-separator.component';
|
||||
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
|
||||
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
|
||||
import { PagesComponent } from './components/pages/pages.component';
|
||||
import { ReadonlyBannerComponent } from './components/readonly-banner/readonly-banner.component';
|
||||
import { FilePreviewRightContainerComponent } from './components/right-container/file-preview-right-container.component';
|
||||
import { UserManagementComponent } from './components/user-management/user-management.component';
|
||||
import { ViewSwitchComponent } from './components/view-switch/view-switch.component';
|
||||
import { AcceptRecommendationDialogComponent } from './dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component';
|
||||
import { AddHintDialogComponent } from './dialogs/add-hint-dialog/add-hint-dialog.component';
|
||||
import { ChangeLegalBasisDialogComponent } from './dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||
import { AddAnnotationDialogComponent } from './dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component';
|
||||
import { EditAnnotationDialogComponent } from './dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component';
|
||||
import { RemoveAnnotationDialogComponent } from './dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component';
|
||||
import { ResizeAnnotationDialogComponent } from './dialogs/docu-mine/resize-annotation-dialog/resize-annotation-dialog.component';
|
||||
import { EditAnnotationDialogComponent } from './dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component';
|
||||
import { DocumentInfoDialogComponent } from './dialogs/document-info-dialog/document-info-dialog.component';
|
||||
import { EditRedactionDialogComponent } from './dialogs/edit-redaction-dialog/edit-redaction-dialog.component';
|
||||
import { TablesService } from './services/tables.service';
|
||||
import { ForceAnnotationDialogComponent } from './dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
import { HighlightActionDialogComponent } from './dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
import { ImportRedactionsDialogComponent } from './dialogs/import-redactions-dialog/import-redactions-dialog';
|
||||
import { ManualAnnotationDialogComponent } from './dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { RedactRecommendationDialogComponent } from './dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component';
|
||||
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
|
||||
import { RemoveRedactionDialogComponent } from './dialogs/remove-redaction-dialog/remove-redaction-dialog.component';
|
||||
import { ResizeRedactionDialogComponent } from './dialogs/resize-redaction-dialog/resize-redaction-dialog.component';
|
||||
import { FilePreviewScreenComponent } from './file-preview-screen.component';
|
||||
import { DocumentUnloadedGuard } from './services/document-unloaded.guard';
|
||||
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
|
||||
import { ManualRedactionService } from './services/manual-redaction.service';
|
||||
import { TablesService } from './services/tables.service';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{
|
||||
@ -87,7 +86,6 @@ const dialogs = [
|
||||
ForceAnnotationDialogComponent,
|
||||
ResizeRedactionDialogComponent,
|
||||
ChangeLegalBasisDialogComponent,
|
||||
RecategorizeImageDialogComponent,
|
||||
HighlightActionDialogComponent,
|
||||
AcceptRecommendationDialogComponent,
|
||||
DocumentInfoDialogComponent,
|
||||
|
||||
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { IqserDialog } from '@common-ui/dialog/iqser-dialog.service';
|
||||
import { getConfig } from '@iqser/common-ui';
|
||||
import { List, log } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import {
|
||||
@ -44,7 +45,7 @@ import { SkippedService } from './skipped.service';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationActionsService {
|
||||
readonly #isDocumine;
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
|
||||
constructor(
|
||||
private readonly _manualRedactionService: ManualRedactionService,
|
||||
@ -59,9 +60,7 @@ export class AnnotationActionsService {
|
||||
private readonly _skippedService: SkippedService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
) {
|
||||
this.#isDocumine = getConfig().IS_DOCUMINE;
|
||||
}
|
||||
) {}
|
||||
|
||||
removeHighlights(highlights: AnnotationWrapper[]): void {
|
||||
const data = this.#getHighlightOperationData(EarmarkOperation.REMOVE, highlights);
|
||||
@ -73,18 +72,6 @@ export class AnnotationActionsService {
|
||||
this._dialogService.openDialog('highlightAction', data);
|
||||
}
|
||||
|
||||
rejectSuggestion(annotations: AnnotationWrapper[]) {
|
||||
const { dossierId, fileId } = this._state;
|
||||
this.#processObsAndEmit(
|
||||
this._manualRedactionService.declineOrRemove(
|
||||
annotations.map(a => a.id),
|
||||
dossierId,
|
||||
fileId,
|
||||
annotations[0].isModifyDictionary,
|
||||
),
|
||||
).then();
|
||||
}
|
||||
|
||||
forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const data = { dossier: this._state.dossier(), annotations, hint };
|
||||
@ -147,7 +134,7 @@ export class AnnotationActionsService {
|
||||
await this.#processObsAndEmit(zip(requests).pipe(log()));
|
||||
}
|
||||
|
||||
async removeRedaction(redaction: AnnotationWrapper, permissions) {
|
||||
async removeRedaction(redaction: AnnotationWrapper, permissions: AnnotationPermissions) {
|
||||
const removePermissions: RemoveRedactionPermissions = {
|
||||
canRemoveOnlyHere: permissions.canRemoveOnlyHere,
|
||||
canRemoveFromDictionary: permissions.canRemoveFromDictionary,
|
||||
@ -181,19 +168,6 @@ export class AnnotationActionsService {
|
||||
}
|
||||
}
|
||||
|
||||
recategorizeImages(annotations: AnnotationWrapper[]) {
|
||||
const data = { annotations, dossier: this._state.dossier() };
|
||||
const { dossierId, fileId } = this._state;
|
||||
this._dialogService.openDialog('recategorizeImage', data, ({ comment, type }: { type: string; comment: string }) => {
|
||||
const body: List<IRecategorizationRequest> = annotations.map(({ id }) => ({
|
||||
annotationId: id,
|
||||
type,
|
||||
comment,
|
||||
}));
|
||||
this.#processObsAndEmit(this._manualRedactionService.recategorizeRedactions(body, dossierId, fileId)).then();
|
||||
});
|
||||
}
|
||||
|
||||
undoDirectAction(annotations: AnnotationWrapper[]) {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const modifyDictionary = annotations[0].isModifyDictionary;
|
||||
@ -231,7 +205,6 @@ export class AnnotationActionsService {
|
||||
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
||||
this._annotationManager.delete(annotationWrapper);
|
||||
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
||||
console.log(rectangleAnnotation);
|
||||
return this._annotationManager.add(rectangleAnnotation);
|
||||
}
|
||||
|
||||
@ -293,11 +266,9 @@ export class AnnotationActionsService {
|
||||
|
||||
async cancelResize(annotationWrapper: AnnotationWrapper) {
|
||||
this._annotationManager.resizingAnnotationId = undefined;
|
||||
this._annotationManager.resizingHasStarted = false;
|
||||
this._annotationManager.delete(annotationWrapper);
|
||||
await this._annotationDrawService.draw([annotationWrapper], this._skippedService.hideSkipped(), this._state.dossierTemplateId);
|
||||
this._annotationManager.deselect();
|
||||
await this._fileDataService.annotationsChanged();
|
||||
}
|
||||
|
||||
#generateRectangle(annotationWrapper: AnnotationWrapper) {
|
||||
@ -333,9 +304,7 @@ export class AnnotationActionsService {
|
||||
}
|
||||
|
||||
async #processObsAndEmit(obs: Observable<unknown>) {
|
||||
await firstValueFrom(obs)
|
||||
.then(() => this._fileDataService.annotationsChanged())
|
||||
.catch(() => this._fileDataService.annotationsChanged());
|
||||
await firstValueFrom(obs).finally(() => this._fileDataService.annotationsChanged());
|
||||
}
|
||||
|
||||
#getFalsePositiveText(annotation: AnnotationWrapper) {
|
||||
@ -389,7 +358,7 @@ export class AnnotationActionsService {
|
||||
rect.topLeft.x + rect.width - 2,
|
||||
rect.topLeft.y + rect.height - percentHeightOffset,
|
||||
);
|
||||
const quadWords = await this._extractTextFromRect(page, pdfNetRect);
|
||||
const quadWords = await this.#extractTextFromRect(page, pdfNetRect);
|
||||
words.push(...quadWords);
|
||||
}
|
||||
|
||||
@ -411,7 +380,7 @@ export class AnnotationActionsService {
|
||||
};
|
||||
}
|
||||
|
||||
private async _extractTextFromRect(page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
|
||||
async #extractTextFromRect(page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
|
||||
const txt = await this._pdf.PDFNet.TextExtractor.create();
|
||||
await txt.begin(page, rect); // Read the page.
|
||||
|
||||
|
||||
@ -1,23 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
import { DocumentInfoDialogComponent } from '../dialogs/document-info-dialog/document-info-dialog.component';
|
||||
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||
import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
|
||||
import { ConfirmationDialogComponent, DialogConfig, DialogService } from '@iqser/common-ui';
|
||||
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||
import { DocumentInfoDialogComponent } from '../dialogs/document-info-dialog/document-info-dialog.component';
|
||||
import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { StructuredComponentManagementDialogComponent } from '../dialogs/structured-component-management-dialog/structured-component-management-dialog.component';
|
||||
|
||||
type DialogType =
|
||||
| 'confirm'
|
||||
| 'documentInfo'
|
||||
| 'rss'
|
||||
| 'recategorizeImage'
|
||||
| 'changeLegalBasis'
|
||||
| 'forceAnnotation'
|
||||
| 'manualAnnotation'
|
||||
| 'highlightAction';
|
||||
type DialogType = 'confirm' | 'documentInfo' | 'rss' | 'changeLegalBasis' | 'forceAnnotation' | 'manualAnnotation' | 'highlightAction';
|
||||
|
||||
@Injectable()
|
||||
export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
@ -30,9 +21,6 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
component: DocumentInfoDialogComponent,
|
||||
dialogConfig: { autoFocus: true },
|
||||
},
|
||||
recategorizeImage: {
|
||||
component: RecategorizeImageDialogComponent,
|
||||
},
|
||||
changeLegalBasis: {
|
||||
component: ChangeLegalBasisDialogComponent,
|
||||
},
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import { inject, Injectable, NgZone } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { IHeaderElement } from '@red/domain';
|
||||
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { IHeaderElement } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
|
||||
import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
|
||||
@Injectable()
|
||||
export class PdfAnnotationActionsService {
|
||||
@ -27,21 +27,18 @@ export class PdfAnnotationActionsService {
|
||||
const permissions = this.#getAnnotationsPermissions(annotations);
|
||||
|
||||
// you can only resize one annotation at a time
|
||||
if (permissions.canResize) {
|
||||
if (permissions.canResizeAnnotation) {
|
||||
const firstAnnotation = annotations[0];
|
||||
// if we already entered resize-mode previously
|
||||
if (firstAnnotation.id === this.#annotationManager.resizingAnnotationId) {
|
||||
if (this.#annotationManager.resizingHasStarted) {
|
||||
const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () =>
|
||||
this.#annotationActionsService.acceptResize(firstAnnotation),
|
||||
);
|
||||
const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () =>
|
||||
this.#annotationActionsService.cancelResize(firstAnnotation),
|
||||
);
|
||||
const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () =>
|
||||
this.#annotationActionsService.acceptResize(firstAnnotation),
|
||||
);
|
||||
const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () =>
|
||||
this.#annotationActionsService.cancelResize(firstAnnotation),
|
||||
);
|
||||
|
||||
return [acceptResizeButton, cancelResizeButton];
|
||||
}
|
||||
return [];
|
||||
return [acceptResizeButton, cancelResizeButton];
|
||||
}
|
||||
|
||||
const resizeButton = this.#getButton('resize', _('annotation-actions.resize.label'), () =>
|
||||
@ -103,22 +100,11 @@ export class PdfAnnotationActionsService {
|
||||
};
|
||||
}
|
||||
|
||||
#getAnnotationsPermissions(annotations: AnnotationWrapper[]) {
|
||||
#getAnnotationsPermissions(annotations: AnnotationWrapper[]): AnnotationPermissions {
|
||||
const dossier = this.#state.dossier();
|
||||
const isApprover = this.#permissionsService.isApprover(dossier);
|
||||
const dictionaries = this.#state.dictionaries;
|
||||
const permissions = annotations.map(a => AnnotationPermissions.forUser(isApprover, a, dictionaries, this.#iqserPermissionsService));
|
||||
return {
|
||||
canResize: permissions.length === 1 && permissions[0].canResizeAnnotation,
|
||||
canChangeLegalBasis: permissions.reduce((acc, next) => acc && next.canChangeLegalBasis, true),
|
||||
canRecategorizeAnnotation: permissions.reduce((acc, next) => acc && next.canRecategorizeAnnotation, true),
|
||||
canRemoveFromDictionary: permissions.reduce((acc, next) => acc && next.canRemoveFromDictionary, true),
|
||||
canAcceptRecommendation: permissions.reduce((acc, next) => acc && next.canAcceptRecommendation, true),
|
||||
canMarkAsFalsePositive: permissions.reduce((acc, next) => acc && next.canMarkAsFalsePositive, true),
|
||||
canForceRedaction: permissions.reduce((acc, next) => acc && next.canForceRedaction, true),
|
||||
canForceHint: permissions.reduce((acc, next) => acc && next.canForceHint, true),
|
||||
canRemoveOnlyHere: permissions.reduce((acc, next) => acc && next.canRemoveOnlyHere, true),
|
||||
canRemoveRedaction: permissions.reduce((acc, next) => acc && next.canRemoveRedaction, true),
|
||||
};
|
||||
return AnnotationPermissions.reduce(permissions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ export class PdfProxyService {
|
||||
this.handleAnnotationSelected([]);
|
||||
}
|
||||
|
||||
#processSelectedAnnotations(annotations: Annotation[], action) {
|
||||
#processSelectedAnnotations(annotations: Annotation[], action: string) {
|
||||
let nextAnnotations: Annotation[];
|
||||
|
||||
if (action === 'deselected') {
|
||||
@ -313,7 +313,10 @@ export class PdfProxyService {
|
||||
nextAnnotations = this._annotationManager.selected;
|
||||
}
|
||||
|
||||
this.#configureAnnotationSpecificActions(nextAnnotations);
|
||||
const annotationWasResized = this._annotationManager.resizingAnnotationId && action === 'modify';
|
||||
if (!this._annotationManager.resizingAnnotationId || annotationWasResized) {
|
||||
this.#configureAnnotationSpecificActions(nextAnnotations);
|
||||
}
|
||||
|
||||
if (!(annotations.length === 1 && annotations[0].ReadOnly)) {
|
||||
this._pdf.enable(TextPopups.ADD_RECTANGLE);
|
||||
@ -344,7 +347,6 @@ export class PdfProxyService {
|
||||
// which is automatically converted to redaction when resized,
|
||||
// so the original annotation(wrapper) is removed
|
||||
this._annotationManager.resizingAnnotationId = undefined;
|
||||
this._annotationManager.resizingHasStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -359,20 +361,20 @@ export class PdfProxyService {
|
||||
}
|
||||
|
||||
#configureAnnotationSpecificActions(viewerAnnotations: Annotation[]) {
|
||||
this._pdf.resetAnnotationActions();
|
||||
|
||||
if (!this.canPerformActions()) {
|
||||
return this._pdf.resetAnnotationActions();
|
||||
return;
|
||||
}
|
||||
|
||||
const annotationWrappers = viewerAnnotations.map(va => this._fileDataService.find(va.Id)).filter(va => !!va);
|
||||
this._pdf.resetAnnotationActions();
|
||||
|
||||
if (annotationWrappers.length === 0) {
|
||||
return this.#configureRectangleAnnotationPopup(viewerAnnotations[0]);
|
||||
}
|
||||
|
||||
// Add hide action as last item
|
||||
const allAnnotationsHaveImageAction = annotationWrappers.reduce((acc, next) => acc && next.isImage, true);
|
||||
if (allAnnotationsHaveImageAction) {
|
||||
const allAreImage = annotationWrappers.reduce((acc, next) => acc && next.isImage, true);
|
||||
if (allAreImage && !this._annotationManager.resizingAnnotationId) {
|
||||
const allAreVisible = viewerAnnotations.reduce((acc, next) => next.isVisible() && acc, true);
|
||||
|
||||
const visibilityButton = {
|
||||
|
||||
@ -4,8 +4,6 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { IRectangle, ISectionRectangle, SuperTypes } from '@red/domain';
|
||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||
import { RedactionLogService } from '@services/files/redaction-log.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { hexToRgb } from '@utils/functions';
|
||||
import { BoundingBox, Table } from '../../file-preview/services/tables.service';
|
||||
import { REDAnnotationManager } from './annotation-manager.service';
|
||||
@ -31,8 +29,6 @@ export function getSectionRectangle(box: BoundingBox): ISectionRectangle {
|
||||
@Injectable()
|
||||
export class AnnotationDrawService {
|
||||
constructor(
|
||||
private readonly _redactionLogService: RedactionLogService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _annotationManager: REDAnnotationManager,
|
||||
private readonly _pdf: PdfViewer,
|
||||
private readonly _documentViewer: REDDocumentViewer,
|
||||
@ -41,7 +37,7 @@ export class AnnotationDrawService {
|
||||
|
||||
async draw(annotations: List<AnnotationWrapper>, hideSkipped: boolean, dossierTemplateId: string) {
|
||||
try {
|
||||
return this._pdf.runWithCleanup(() => this._draw(annotations, hideSkipped, dossierTemplateId));
|
||||
return this._pdf.runWithCleanup(() => this.#draw(annotations, hideSkipped, dossierTemplateId));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@ -70,7 +66,7 @@ export class AnnotationDrawService {
|
||||
async drawTables(tables: Table[], page: number, dossierTemplateId: string) {
|
||||
const sections: Core.Annotations.RectangleAnnotation[] = [];
|
||||
tables.forEach(table => {
|
||||
const section = this._computeSection(page, getSectionRectangle(table.boundingBox), dossierTemplateId);
|
||||
const section = this.#computeSection(page, getSectionRectangle(table.boundingBox), dossierTemplateId);
|
||||
if (table.experimental) {
|
||||
section.StrokeColor = this.convertColor('#800080');
|
||||
} else {
|
||||
@ -80,7 +76,7 @@ export class AnnotationDrawService {
|
||||
table.cellsPerRow
|
||||
.flatMap(row => row)
|
||||
.forEach(row => {
|
||||
const cellSection = this._computeSection(page, getSectionRectangle(row.boundingBox), dossierTemplateId);
|
||||
const cellSection = this.#computeSection(page, getSectionRectangle(row.boundingBox), dossierTemplateId);
|
||||
if (table.experimental) {
|
||||
cellSection.StrokeColor = this.convertColor('#800080');
|
||||
} else {
|
||||
@ -93,10 +89,10 @@ export class AnnotationDrawService {
|
||||
await this._annotationManager.add(sections);
|
||||
}
|
||||
|
||||
private async _draw(annotationWrappers: List<AnnotationWrapper>, hideSkipped: boolean, dossierTemplateId: string) {
|
||||
async #draw(annotationWrappers: List<AnnotationWrapper>, hideSkipped: boolean, dossierTemplateId: string) {
|
||||
const totalPages = this._pdf.totalPages();
|
||||
const annotations = annotationWrappers
|
||||
?.map(annotation => this._computeAnnotation(annotation, hideSkipped, totalPages, dossierTemplateId))
|
||||
?.map(annotation => this.#computeAnnotation(annotation, hideSkipped, totalPages, dossierTemplateId))
|
||||
.filterTruthy();
|
||||
if (!this._documentViewer.loaded()) {
|
||||
return;
|
||||
@ -104,7 +100,7 @@ export class AnnotationDrawService {
|
||||
await this._annotationManager.add(annotations);
|
||||
}
|
||||
|
||||
private _computeSection(pageNumber: number, sectionRectangle: ISectionRectangle, dossierTemplateId: string) {
|
||||
#computeSection(pageNumber: number, sectionRectangle: ISectionRectangle, dossierTemplateId: string) {
|
||||
const rectangleAnnot = this._pdf.rectangle();
|
||||
const pageHeight = this._documentViewer.getHeight(pageNumber);
|
||||
const rectangle: IRectangle = {
|
||||
@ -125,7 +121,7 @@ export class AnnotationDrawService {
|
||||
return rectangleAnnot;
|
||||
}
|
||||
|
||||
private _computeAnnotation(annotationWrapper: AnnotationWrapper, hideSkipped: boolean, totalPages: number, dossierTemplateId: string) {
|
||||
#computeAnnotation(annotationWrapper: AnnotationWrapper, hideSkipped: boolean, totalPages: number, dossierTemplateId: string) {
|
||||
const pageNumber = this._pdf.isCompareMode() ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
|
||||
if (pageNumber > totalPages) {
|
||||
// skip imported annotations from files that have more pages than the current one
|
||||
@ -150,7 +146,7 @@ export class AnnotationDrawService {
|
||||
}
|
||||
|
||||
const annotation = this._pdf.textHighlight();
|
||||
annotation.Quads = this._rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
||||
annotation.Quads = this.#rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
||||
annotation.Opacity = annotationWrapper.isChangeLogRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
||||
annotation.setContents(annotationWrapper.content);
|
||||
annotation.PageNumber = pageNumber;
|
||||
@ -190,12 +186,12 @@ export class AnnotationDrawService {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
private _rectanglesToQuads(positions: IRectangle[], pageNumber: number): Quad[] {
|
||||
#rectanglesToQuads(positions: IRectangle[], pageNumber: number): Quad[] {
|
||||
const pageHeight = this._documentViewer.getHeight(pageNumber);
|
||||
return positions.map(p => this._rectangleToQuad(p, pageHeight));
|
||||
return positions.map(p => this.#rectangleToQuad(p, pageHeight));
|
||||
}
|
||||
|
||||
private _rectangleToQuad(rectangle: IRectangle, pageHeight: number): Quad {
|
||||
#rectangleToQuad(rectangle: IRectangle, pageHeight: number): Quad {
|
||||
const x1 = rectangle.topLeft.x;
|
||||
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { inject, Injectable, signal } from '@angular/core';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import type { List } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationPredicate, DeleteAnnotationsOptions } from '../utils/types';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Subject } from 'rxjs';
|
||||
import { asList, getId, isStringOrWrapper } from '../utils/functions';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { getLast } from '@utils/functions';
|
||||
import { AnnotationToolNames } from '../utils/constants';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { Subject } from 'rxjs';
|
||||
import { AnnotationToolNames } from '../utils/constants';
|
||||
import { asList, getId, isStringOrWrapper } from '../utils/functions';
|
||||
import { AnnotationPredicate, DeleteAnnotationsOptions } from '../utils/types';
|
||||
import AnnotationManager = Core.AnnotationManager;
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
|
||||
@ -19,7 +19,6 @@ export class REDAnnotationManager {
|
||||
readonly #annotationSelected$ = new Subject<[Annotation[], string]>();
|
||||
readonly annotationSelected$ = this.#annotationSelected$.asObservable();
|
||||
resizingAnnotationId?: string = undefined;
|
||||
resizingHasStarted = false;
|
||||
readonly hidden = this.#hidden.asReadonly();
|
||||
|
||||
get selected() {
|
||||
@ -141,14 +140,12 @@ export class REDAnnotationManager {
|
||||
// when a rectangle is drawn,
|
||||
// it returns one annotation with tool name 'AnnotationCreateRectangle;
|
||||
// this will auto select rectangle after drawing
|
||||
if (annotations.length === 1 && annotations[0].ToolName === AnnotationToolNames.AnnotationCreateRectangle) {
|
||||
this.#manager.selectAnnotations(annotations);
|
||||
annotations[0].disableRotationControl();
|
||||
}
|
||||
if (action === 'modify' && options.source === 'resize' && !this.resizingHasStarted) {
|
||||
this.resizingHasStarted = true;
|
||||
this.#annotationSelected$.next([annotations, action]);
|
||||
const annotation = annotations.length === 1 ? annotations[0] : undefined;
|
||||
if (annotation && annotation.ToolName === AnnotationToolNames.AnnotationCreateRectangle) {
|
||||
this.#manager.selectAnnotation(annotation);
|
||||
annotation.disableRotationControl();
|
||||
}
|
||||
this.#annotationSelected$.next([annotations, action]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import { effect, inject, Injectable, Signal, signal } from '@angular/core';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { log } from '@iqser/common-ui/lib/utils';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { RotationType, RotationTypes } from '@red/domain';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { BehaviorSubject, fromEvent, Observable } from 'rxjs';
|
||||
import { filter, tap } from 'rxjs/operators';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { log } from '@iqser/common-ui/lib/utils';
|
||||
import { stopAndPrevent, stopAndPreventIfNotAllowed } from '../utils/functions';
|
||||
import { RotationType, RotationTypes } from '@red/domain';
|
||||
import { AnnotationToolNames } from '../utils/constants';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import DocumentViewer = Core.DocumentViewer;
|
||||
import { stopAndPrevent, stopAndPreventIfNotAllowed } from '../utils/functions';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import Color = Core.Annotations.Color;
|
||||
import DocumentViewer = Core.DocumentViewer;
|
||||
import Quad = Core.Math.Quad;
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
import { DestroyRef, inject, Injectable, signal, Signal } from '@angular/core';
|
||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||
import { ErrorService, getConfig } from '@iqser/common-ui';
|
||||
import { AppConfig, File, IHeaderElement } from '@red/domain';
|
||||
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { combineLatest, fromEvent, Observable } from 'rxjs';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, SEARCH_OPTIONS, USELESS_ELEMENTS } from '../utils/constants';
|
||||
import { Rgb } from '../utils/types';
|
||||
import { asList } from '../utils/functions';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { environment } from '@environments/environment';
|
||||
import { ErrorService, getConfig } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN, shareDistinctLast } from '@iqser/common-ui/lib/utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||
import { AppConfig, File, IHeaderElement } from '@red/domain';
|
||||
import { LicenseService } from '@services/license.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { environment } from '@environments/environment';
|
||||
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { BASE_HREF_FN, shareDistinctLast } from '@iqser/common-ui/lib/utils';
|
||||
import TextTool = Core.Tools.TextTool;
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { combineLatest, fromEvent, Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, SEARCH_OPTIONS, USELESS_ELEMENTS } from '../utils/constants';
|
||||
import { asList } from '../utils/functions';
|
||||
import { Rgb } from '../utils/types';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
import TextHighlightAnnotation = Core.Annotations.TextHighlightAnnotation;
|
||||
import DocumentViewer = Core.DocumentViewer;
|
||||
import Quad = Core.Math.Quad;
|
||||
import TextTool = Core.Tools.TextTool;
|
||||
|
||||
@Injectable()
|
||||
export class PdfViewer {
|
||||
@ -40,6 +40,7 @@ export class PdfViewer {
|
||||
},
|
||||
};
|
||||
readonly #destroyRef = inject(DestroyRef);
|
||||
readonly #logger = inject(NGXLogger);
|
||||
readonly #totalPages = signal<number>(0);
|
||||
readonly currentPage$ = inject(ActivatedRoute).queryParamMap.pipe(
|
||||
map(params => Number(params.get('page') ?? '1')),
|
||||
@ -118,6 +119,7 @@ export class PdfViewer {
|
||||
|
||||
resetAnnotationActions() {
|
||||
if (this.#instance.UI.annotationPopup.getItems().length) {
|
||||
this.#logger.info('[PDF] Reset annotation actions');
|
||||
this.#instance.UI.annotationPopup.update([]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg fill="currentColor" id="ReadactManager_symbol_positive"
|
||||
<svg fill="#dd4d50" id="ReadactManager_symbol_positive"
|
||||
version="1.1" viewBox="0 0 119.476 121.277" x="0px" xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
y="0px">
|
||||
@ -8,5 +8,5 @@
|
||||
s-1.904-4.254-4.254-4.254H28.843H15.793H4.254C1.904,73.401,0,71.496,0,69.146c0-2.349,1.904-4.254,4.254-4.254h24.59h41.062
|
||||
c2.349,0,4.255-1.904,4.255-4.254s-1.906-4.254-4.255-4.254H28.843H4.254C1.904,56.385,0,54.48,0,52.13
|
||||
c0-2.349,1.904-4.254,4.254-4.254h11.539h13.051H52.6c2.349,0,4.254-1.905,4.254-4.254c0-2.35-1.904-4.254-4.254-4.254H28.843
|
||||
h-7.283c-2.349,0-4.254-1.905-4.254-4.254c0-2.349,1.904-4.254,4.254-4.254h7.283V14.712C59.063,14.712,74.16,0,74.16,0z" />
|
||||
h-7.283c-2.349,0-4.254-1.905-4.254-4.254c0-2.349,1.904-4.254,4.254-4.254h7.283V14.712C59.063,14.712,74.16,0,74.16,0z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 942 B |
@ -1 +1 @@
|
||||
Subproject commit c9abddb3017082bb169ef6da2c1a63b0b3cdf837
|
||||
Subproject commit 21d387912ca7788f4dc9675edca1c0cdc40e8bac
|
||||
Loading…
x
Reference in New Issue
Block a user