From 5023c9ad531950bea065d84aa4a40cff0d03f97c Mon Sep 17 00:00:00 2001 From: Timo Date: Sun, 3 Jan 2021 11:55:57 +0200 Subject: [PATCH] fixed various bugs --- .../icon-button/icon-button.component.html | 1 + .../assign-owner-dialog.component.ts | 2 +- .../file-preview-screen.component.html | 6 +++- .../file-preview-screen.component.ts | 15 +++++++-- .../screens/file/model/annotation.wrapper.ts | 10 ++++++ .../file/pdf-viewer/pdf-viewer.component.ts | 32 +++++++++++-------- .../project-overview-screen.component.ts | 8 +++-- .../red-ui/src/app/state/app-state.service.ts | 4 +-- .../upload/file-drop/file-drop.component.ts | 4 ++- .../src/app/upload/file-upload.service.ts | 7 +--- .../src/app/upload/model/file-upload.model.ts | 1 + apps/red-ui/src/app/utils/file-drop-utils.ts | 9 +++--- apps/red-ui/src/assets/i18n/en.json | 1 + apps/red-ui/src/assets/styles/red-editor.scss | 2 +- .../src/assets/styles/red-variables.scss | 1 + 15 files changed, 68 insertions(+), 35 deletions(-) diff --git a/apps/red-ui/src/app/components/buttons/icon-button/icon-button.component.html b/apps/red-ui/src/app/components/buttons/icon-button/icon-button.component.html index 5f7c9657f..1cb7087e1 100644 --- a/apps/red-ui/src/app/components/buttons/icon-button/icon-button.component.html +++ b/apps/red-ui/src/app/components/buttons/icon-button/icon-button.component.html @@ -5,6 +5,7 @@ (click)="action.emit($event)" [class.show-bg]="type === 'show-bg'" [disabled]="disabled" + type="button" > diff --git a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts index ea85626a8..0cb553200 100644 --- a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts +++ b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts @@ -105,7 +105,7 @@ export class AssignOwnerDialogComponent { } } } catch (error) { - this._notificationService.showToastNotification('Failed: ' + error.error.message, null, NotificationType.ERROR); + this._notificationService.showToastNotification('Failed: ' + error.error ? error.error.message : error, null, NotificationType.ERROR); } this.dialogRef.close(); diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html index 9f9fd6847..8901854c4 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html @@ -163,6 +163,7 @@ [canPerformActions]="canPerformAnnotationActions" [fileData]="displayData" [fileStatus]="appStateService.activeFile" + [shouldDeselectAnnotationsOnPageChange]="shouldDeselectAnnotationsOnPageChange" [annotations]="annotations" > @@ -241,7 +242,10 @@ {{ annotation.typeLabel | translate }}
- : {{ annotation.dictionary | humanize: false }} + {{ annotation.descriptor | translate }}: {{ annotation.dictionary | humanize: false }}
: {{ annotation.content }} diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts index 02d47ec80..7ea2c7174 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts @@ -44,6 +44,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { public fullScreen = false; public editingReviewer = false; public reviewerForm: FormGroup; + public shouldDeselectAnnotationsOnPageChange = true; @ViewChild(PdfViewerComponent) private _viewerComponent: PdfViewerComponent; @ViewChild('annotationsElement') private _annotationsElement: ElementRef; @@ -193,6 +194,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { handleAnnotationSelected(annotationId: string) { this.selectedAnnotation = this.annotations.find((a) => a.id === annotationId); this.scrollToSelectedAnnotation(); + console.log('selected: ', annotationId); this._changeDetectorRef.detectChanges(); } @@ -328,9 +330,11 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { // Displayed page doesn't have annotations if ($event.key === 'ArrowDown') { const nextPage = this._nextPageWithAnnotations(); + this.shouldDeselectAnnotationsOnPageChange = false; this.selectAnnotation(this.displayedAnnotations[nextPage].annotations[0]); } else { const prevPage = this._prevPageWithAnnotations(); + this.shouldDeselectAnnotationsOnPageChange = false; const prevPageAnnotations = this.displayedAnnotations[prevPage].annotations; this.selectAnnotation(prevPageAnnotations[prevPageAnnotations.length - 1]); } @@ -348,6 +352,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { } else if (pageIdx + 1 < this.displayedPages.length) { // If not last page const nextPageAnnotations = this.displayedAnnotations[this.displayedPages[pageIdx + 1]].annotations; + this.shouldDeselectAnnotationsOnPageChange = false; this.selectAnnotation(nextPageAnnotations[0]); } } else { @@ -357,6 +362,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { } else if (pageIdx) { // If not first page const prevPageAnnotations = this.displayedAnnotations[this.displayedPages[pageIdx - 1]].annotations; + this.shouldDeselectAnnotationsOnPageChange = false; this.selectAnnotation(prevPageAnnotations[prevPageAnnotations.length - 1]); } } @@ -419,9 +425,12 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { return idx >= 0 ? this.displayedPages[idx] : null; } - viewerPageChanged($event: number) { - this._scrollViews(); - this._changeDetectorRef.detectChanges(); + viewerPageChanged($event: any) { + if (typeof $event === 'number') { + this._scrollViews(); + this.shouldDeselectAnnotationsOnPageChange = true; + this._changeDetectorRef.detectChanges(); + } } viewerReady($event: WebViewerInstance) { diff --git a/apps/red-ui/src/app/screens/file/model/annotation.wrapper.ts b/apps/red-ui/src/app/screens/file/model/annotation.wrapper.ts index 7acf2749d..7cb9ce388 100644 --- a/apps/red-ui/src/app/screens/file/model/annotation.wrapper.ts +++ b/apps/red-ui/src/app/screens/file/model/annotation.wrapper.ts @@ -36,6 +36,16 @@ export class AnnotationWrapper { textAfter?: string; textBefore?: string; + get isDictionaryBased() { + return (this.isHint || this.isRedacted) && !this.isManual; + } + + get descriptor() { + // TODO clarify: RED-894 + // return this.isDictionaryBased ? 'dictionary' : 'type'; + return 'dictionary'; + } + get hasTextAfter() { return this.textAfter && this.textAfter.trim().length > 0; } diff --git a/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts index a4f0b9bd3..65292487b 100644 --- a/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts +++ b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts @@ -37,6 +37,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges { @Input() fileStatus: FileStatusWrapper; @Input() canPerformActions = false; @Input() annotations: AnnotationWrapper[]; + @Input() shouldDeselectAnnotationsOnPageChange = true; @Output() fileReady = new EventEmitter(); @Output() annotationSelected = new EventEmitter(); @@ -107,7 +108,11 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges { } }); - instance.docViewer.on('pageComplete', (p) => { + instance.docViewer.on('pageNumberUpdated', (p) => { + console.log(this.shouldDeselectAnnotationsOnPageChange); + if (this.shouldDeselectAnnotationsOnPageChange) { + this.instance.annotManager.deselectAllAnnotations(); + } this._ngZone.run(() => this.pageChanged.emit(p)); }); @@ -257,19 +262,18 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges { } }); - // Temporary removed false positive action - // this.instance.textPopup.add({ - // type: 'actionButton', - // dataElement: 'add-false-positive', - // img: '/assets/icons/general/pdftron-action-false-positive.svg', - // title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')), - // onClick: () => { - // const selectedQuads = this.instance.docViewer.getSelectedTextQuads(); - // const text = this.instance.docViewer.getSelectedText(); - // const mre = this._getManualRedactionEntry(selectedQuads, text); - // this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')); - // } - // }); + this.instance.textPopup.add({ + type: 'actionButton', + dataElement: 'add-false-positive', + img: '/assets/icons/general/pdftron-action-false-positive.svg', + title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')), + onClick: () => { + const selectedQuads = this.instance.docViewer.getSelectedTextQuads(); + const text = this.instance.docViewer.getSelectedText(); + const mre = this._getManualRedactionEntry(selectedQuads, text); + this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')); + } + }); this.instance.textPopup.add({ type: 'actionButton', diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts index efcb4c2c7..360ca57b6 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts @@ -186,7 +186,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { @HostListener('drop', ['$event']) onDrop(event: DragEvent) { - handleFileDrop(event, this._uploadFiles.bind(this)); + handleFileDrop(event, this.appStateService.activeProjectId, this._uploadFiles.bind(this)); } @HostListener('dragover', ['$event']) @@ -196,7 +196,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } uploadFiles(files: File[] | FileList) { - this._uploadFiles(convertFiles(files)); + this._uploadFiles(convertFiles(files, this.appStateService.activeProjectId)); } private _uploadFiles(files: FileUploadModel[]) { @@ -206,6 +206,10 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } private _computeAllFilters() { + if (!this.appStateService.activeProject) { + return; + } + const allDistinctFileStatusWrapper = new Set(); const allDistinctPeople = new Set(); const allDistinctAddedDates = new Set(); diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index a11731266..32a4d7696 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -345,11 +345,11 @@ export class AppStateService { this._appState.projects.push(foundProject); } this._appState.projects = [...this._appState.projects]; - return foundProject.project; + return foundProject; } catch (error) { this._notificationService.showToastNotification( this._translateService.instant( - error.status === 409 ? 'projects.add-edit-dialog.errors.project-already-exists' : 'projects.add-edit-dialog.errors.generic' + error.status === 409 ? 'project-listing.add-edit-dialog.errors.project-already-exists' : 'project-listing.add-edit-dialog.errors.generic' ), null, NotificationType.ERROR diff --git a/apps/red-ui/src/app/upload/file-drop/file-drop.component.ts b/apps/red-ui/src/app/upload/file-drop/file-drop.component.ts index d424e5de1..193f8558a 100644 --- a/apps/red-ui/src/app/upload/file-drop/file-drop.component.ts +++ b/apps/red-ui/src/app/upload/file-drop/file-drop.component.ts @@ -4,6 +4,7 @@ import { FileUploadModel } from '../model/file-upload.model'; import { OverlayRef } from '@angular/cdk/overlay'; import { UploadStatusOverlayService } from '../upload-status-dialog/service/upload-status-overlay.service'; import { handleFileDrop } from '../../utils/file-drop-utils'; +import { AppStateService } from '../../state/app-state.service'; @Component({ selector: 'redaction-file-drop', @@ -14,6 +15,7 @@ export class FileDropComponent implements OnInit { constructor( private readonly _dialogRef: OverlayRef, private readonly _fileUploadService: FileUploadService, + private readonly _appStateService: AppStateService, private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _uploadStatusOverlayService: UploadStatusOverlayService ) {} @@ -33,7 +35,7 @@ export class FileDropComponent implements OnInit { @HostListener('drop', ['$event']) onDrop(event: DragEvent) { - handleFileDrop(event, this.uploadFiles.bind(this)); + handleFileDrop(event, this._appStateService.activeProjectId, this.uploadFiles.bind(this)); } @HostListener('dragover', ['$event']) diff --git a/apps/red-ui/src/app/upload/file-upload.service.ts b/apps/red-ui/src/app/upload/file-upload.service.ts index e94ead8d4..d02960f80 100644 --- a/apps/red-ui/src/app/upload/file-upload.service.ts +++ b/apps/red-ui/src/app/upload/file-upload.service.ts @@ -77,12 +77,7 @@ export class FileUploadService { private _createSubscription(uploadFile: FileUploadModel) { this.activeUploads++; - const obs = this._fileManagementControllerService.uploadFileForm( - uploadFile.file, - this._appStateService.activeProject.project.projectId, - 'events', - true - ); + const obs = this._fileManagementControllerService.uploadFileForm(uploadFile.file, uploadFile.projectId, 'events', true); const subscription = obs.subscribe( async (event) => { if (event.type === HttpEventType.UploadProgress) { diff --git a/apps/red-ui/src/app/upload/model/file-upload.model.ts b/apps/red-ui/src/app/upload/model/file-upload.model.ts index 7ff1519c9..750f92b02 100644 --- a/apps/red-ui/src/app/upload/model/file-upload.model.ts +++ b/apps/red-ui/src/app/upload/model/file-upload.model.ts @@ -6,4 +6,5 @@ export interface FileUploadModel { retryCount: number; size: number; sizeError: any; + projectId?: string; } diff --git a/apps/red-ui/src/app/utils/file-drop-utils.ts b/apps/red-ui/src/app/utils/file-drop-utils.ts index 937fc245d..83395e26e 100644 --- a/apps/red-ui/src/app/utils/file-drop-utils.ts +++ b/apps/red-ui/src/app/utils/file-drop-utils.ts @@ -1,6 +1,6 @@ import { FileUploadModel } from '../upload/model/file-upload.model'; -export function handleFileDrop(event: DragEvent, uploadFiles: (files: FileUploadModel[]) => void) { +export function handleFileDrop(event: DragEvent, projectId: string, uploadFiles: (files: FileUploadModel[]) => void) { event.preventDefault(); event.stopPropagation(); const { dataTransfer } = event; @@ -16,16 +16,16 @@ export function handleFileDrop(event: DragEvent, uploadFiles: (files: FileUpload } else { files = dataTransfer.files; dataTransfer.clearData(); - uploadFiles(convertFiles(files)); + uploadFiles(convertFiles(files, projectId)); } - const convertedFiles = convertFiles(files); + const convertedFiles = convertFiles(files, projectId); if (convertedFiles.length > 0) { uploadFiles(convertedFiles); } } -export function convertFiles(files: FileList | File[]): FileUploadModel[] { +export function convertFiles(files: FileList | File[], projectId: string): FileUploadModel[] { let uploadFiles: FileUploadModel[] = []; for (let i = 0; i < files.length; i++) { const file = files[i]; @@ -34,6 +34,7 @@ export function convertFiles(files: FileList | File[]): FileUploadModel[] { progress: 0, completed: false, error: null, + projectId: projectId, sizeError: false, retryCount: 0, size: file.size diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index dd85a8b34..4c5e73292 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -422,6 +422,7 @@ "comment": "Comment", "suggestion": "Suggestion for redaction", "dictionary": "Dictionary", + "type": "Type", "content": "Reason", "page": "Page", "annotation": "Annotation", diff --git a/apps/red-ui/src/assets/styles/red-editor.scss b/apps/red-ui/src/assets/styles/red-editor.scss index bc9583aa6..f17edf52a 100644 --- a/apps/red-ui/src/assets/styles/red-editor.scss +++ b/apps/red-ui/src/assets/styles/red-editor.scss @@ -15,7 +15,7 @@ .search-marker { position: absolute; - background: rgba($yellow-1, 0.3); + background: rgba($blue-5, 0.3); z-index: 40; } diff --git a/apps/red-ui/src/assets/styles/red-variables.scss b/apps/red-ui/src/assets/styles/red-variables.scss index d21f0c0d2..0a64ed393 100644 --- a/apps/red-ui/src/assets/styles/red-variables.scss +++ b/apps/red-ui/src/assets/styles/red-variables.scss @@ -13,6 +13,7 @@ $blue-1: #4875f7; $blue-2: #48c9f7; $blue-3: #5b97db; $blue-4: #374c81; +$blue-5: #c5d3eb; $red-1: #dd4d50; $red-2: #f16164; $yellow-1: #ffb83b;