From ff4cf841e34d735292712d252d9bf9209d239773 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 23 Sep 2021 15:20:17 +0300 Subject: [PATCH] move annotations list to a separate component --- .../src/app/models/file/annotation.wrapper.ts | 2 - .../annotations-list.component.html | 60 +++++++++++++ .../annotations-list.component.scss | 89 +++++++++++++++++++ .../annotations-list.component.ts | 48 ++++++++++ .../file-workload.component.html | 73 +++------------ .../file-workload.component.scss | 86 +----------------- .../file-workload/file-workload.component.ts | 44 +-------- .../app/modules/dossier/dossiers.module.ts | 5 +- .../services/annotation-draw.service.ts | 11 +-- 9 files changed, 221 insertions(+), 197 deletions(-) create mode 100644 apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html create mode 100644 apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.scss create mode 100644 apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.ts diff --git a/apps/red-ui/src/app/models/file/annotation.wrapper.ts b/apps/red-ui/src/app/models/file/annotation.wrapper.ts index 5b113dd43..750192ae1 100644 --- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts +++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts @@ -60,8 +60,6 @@ export class AnnotationWrapper { private _origin: RedactionLogEntryWrapper; - constructor() {} - get isChangeLogRemoved() { return this.changeLogType === 'REMOVED'; } diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html new file mode 100644 index 000000000..24afbeede --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html @@ -0,0 +1,60 @@ +
+
+ +
+
+ + +
+
+ {{ annotation.typeLabel | translate }} +
+
+ + {{ annotation.descriptor | translate }}: {{ annotation.type | humanize: false }} +
+
+ : {{ annotation.shortContent }} +
+
+ +
+ +
+
+ +
+
+ + {{ annotation.comments.length }} +
+ +
+ +
+
+ + +
+
diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.scss b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.scss new file mode 100644 index 000000000..36523f550 --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.scss @@ -0,0 +1,89 @@ +@use 'variables'; + +:host { + width: 100%; +} + +.annotation-wrapper { + display: flex; + width: 100%; + border-bottom: 1px solid variables.$separator; + + .active-bar-marker { + min-width: 4px; + min-height: 100%; + } + + .active-icon-marker-container { + min-width: 20px; + } + + &.active { + &:not(.lower-height) .active-bar-marker { + background-color: variables.$primary; + } + } + + .annotation { + padding: 10px 16px 8px 10px; + font-size: 11px; + line-height: 14px; + cursor: pointer; + display: flex; + flex-direction: column; + width: 100%; + + &.removed { + text-decoration: line-through; + color: variables.$grey-7; + } + + .details { + display: flex; + position: relative; + } + + .actions-wrapper { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + min-height: 34px; + padding-left: 18px; + + .comments-counter { + cursor: pointer; + display: flex; + align-items: center; + padding: 0 8px; + transition: background-color 0.2s; + line-height: 13px; + height: 24px; + border-radius: 12px; + + mat-icon { + width: 10px; + height: 10px; + margin-right: 4px; + } + + &:hover { + background-color: variables.$grey-4; + } + } + } + + redaction-type-annotation-icon { + margin-top: 6px; + margin-right: 10px; + } + } + + &:hover { + background-color: variables.$grey-8; + + ::ng-deep .annotation-actions { + display: flex; + } + } +} diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.ts new file mode 100644 index 000000000..391e02415 --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.ts @@ -0,0 +1,48 @@ +import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core'; +import { AnnotationWrapper } from '@models/file/annotation.wrapper'; +import { IqserEventTarget } from '@iqser/common-ui'; + +@Component({ + selector: 'redaction-annotations-list', + templateUrl: './annotations-list.component.html', + styleUrls: ['./annotations-list.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AnnotationsListComponent { + @Input() annotations: AnnotationWrapper[]; + @Input() selectedAnnotations: AnnotationWrapper[]; + @Input() annotationActionsTemplate: TemplateRef; + @Input() multiSelectActive = false; + @Input() activeViewerPage: number; + @Input() canMultiSelect = true; + + @Output() readonly multiSelectActiveChange = new EventEmitter(); + @Output() readonly pagesPanelActive = new EventEmitter(); + @Output() readonly selectAnnotations = new EventEmitter< + AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean } + >(); + @Output() readonly deselectAnnotations = new EventEmitter(); + + annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void { + if (($event.target as IqserEventTarget).localName === 'input') { + return; + } + this.pagesPanelActive.emit(false); + if (this.isSelected(annotation.annotationId)) { + this.deselectAnnotations.emit([annotation]); + } else { + if (this.canMultiSelect && ($event.ctrlKey || $event.metaKey) && this.selectedAnnotations.length > 0) { + this.multiSelectActive = true; + this.multiSelectActiveChange.emit(true); + } + this.selectAnnotations.emit({ + annotations: [annotation], + multiSelect: this.multiSelectActive + }); + } + } + + isSelected(annotationId: string): boolean { + return !!this.selectedAnnotations?.find(a => a?.annotationId === annotationId); + } +} diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html index 27a895164..05ec345ea 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html @@ -1,6 +1,3 @@ - - -
- . @@ -174,62 +170,17 @@
-
-
-
-
- -
-
- {{ annotation.typeLabel | translate }} -
-
- - {{ annotation.descriptor | translate }}: {{ annotation.type | humanize: false }} -
-
- : {{ annotation.shortContent }} -
-
- -
- -
-
- -
-
- - {{ annotation.comments.length }} -
-
- -
-
- -
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.scss b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.scss index e15439435..f96c2b1fd 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.scss +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.scss @@ -157,96 +157,12 @@ align-items: center; flex-direction: column; - .annotation-wrapper { - display: flex; - width: 100%; - border-bottom: 1px solid variables.$separator; - - .active-bar-marker { - min-width: 4px; - min-height: 100%; - } - - .active-icon-marker-container { - min-width: 20px; - } - - &.active { - &:not(.lower-height) .active-bar-marker { - background-color: variables.$primary; - } - } - - .annotation { - padding: 10px 16px 8px 10px; - font-size: 11px; - line-height: 14px; - cursor: pointer; - display: flex; - flex-direction: column; - width: 100%; - - &.removed { - text-decoration: line-through; - color: variables.$grey-7; - } - - .details { - display: flex; - position: relative; - } - - .actions-wrapper { - display: flex; - justify-content: space-between; - align-items: center; - margin-top: 8px; - min-height: 34px; - padding-left: 18px; - - .comments-counter { - cursor: pointer; - display: flex; - align-items: center; - padding: 0 8px; - transition: background-color 0.2s; - line-height: 13px; - height: 24px; - border-radius: 12px; - - mat-icon { - width: 10px; - height: 10px; - margin-right: 4px; - } - - &:hover { - background-color: variables.$grey-4; - } - } - } - - redaction-type-annotation-icon { - margin-top: 6px; - margin-right: 10px; - } - } - - &:hover { - background-color: variables.$grey-8; - - ::ng-deep .annotation-actions { - display: flex; - } - } - } - &:hover { overflow-y: auto; @include common-mixins.scroll-bar; } - &.has-scrollbar:hover .annotation-wrapper .annotation { + &.has-scrollbar:hover::ng-deep .annotation-wrapper .annotation { padding-right: 5px; } } diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts index 112a2cf00..e58b9455b 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts @@ -1,23 +1,10 @@ -import { - ChangeDetectorRef, - Component, - ElementRef, - EventEmitter, - HostListener, - Input, - Output, - QueryList, - TemplateRef, - ViewChild, - ViewChildren -} from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationProcessingService } from '../../services/annotation-processing.service'; import { MatDialogRef, MatDialogState } from '@angular/material/dialog'; import scrollIntoView from 'scroll-into-view-if-needed'; import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, IqserEventTarget, NestedFilter } from '@iqser/common-ui'; import { FileDataModel } from '@models/file/file-data.model'; -import { CommentsComponent } from '../comments/comments.component'; import { PermissionsService } from '@services/permissions.service'; import { WebViewerInstance } from '@pdftron/webviewer'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; @@ -56,7 +43,6 @@ export class FileWorkloadComponent { @Output() readonly actionPerformed = new EventEmitter(); displayedPages: number[] = []; pagesPanelActive = true; - @ViewChildren(CommentsComponent) readonly annotationCommentsComponents: QueryList; @ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef; @ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef; @@ -118,15 +104,6 @@ export class FileWorkloadComponent { } } - isSelected(annotation: AnnotationWrapper) { - return this.selectedAnnotations?.find(a => a?.id === annotation.id); - } - - toggleExpandComments(annotation: AnnotationWrapper, $event: MouseEvent) { - $event.stopPropagation(); - this.annotationCommentsComponents.find(c => c.annotation === annotation).toggleExpandComments(); - } - logAnnotation(annotation: AnnotationWrapper) { console.log(annotation); } @@ -156,25 +133,6 @@ export class FileWorkloadComponent { return this.displayedAnnotations; } - annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void { - if (($event.target as IqserEventTarget).localName === 'input') { - return; - } - this.pagesPanelActive = false; - this.logAnnotation(annotation); - if (this.isSelected(annotation)) { - this.deselectAnnotations.emit([annotation]); - } else { - if (($event.ctrlKey || $event.metaKey) && this.selectedAnnotations.length > 0) { - this.multiSelectActive = true; - } - this.selectAnnotations.emit({ - annotations: [annotation], - multiSelect: this.multiSelectActive - }); - } - } - @HostListener('window:keyup', ['$event']) handleKeyEvent($event: KeyboardEvent): void { if ( diff --git a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts index 4bcf20638..a92fea273 100644 --- a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts +++ b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts @@ -49,6 +49,7 @@ import { DossiersService } from './services/dossiers.service'; import { DossierDetailsStatsComponent } from './components/dossier-details-stats/dossier-details-stats.component'; import { SearchScreenComponent } from './screens/search-screen/search-screen.component'; import { EditDossierDeletedDocumentsComponent } from './dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component'; +import { AnnotationsListComponent } from './components/file-workload/components/annotations-list/annotations-list.component'; const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent, SearchScreenComponent]; @@ -89,6 +90,7 @@ const components = [ PageExclusionComponent, DossierDetailsStatsComponent, EditDossierDeletedDocumentsComponent, + AnnotationsListComponent, ...screens, ...dialogs @@ -111,4 +113,5 @@ const services = [ providers: [...services], imports: [CommonModule, SharedModule, FileUploadDownloadModule, DossiersRoutingModule] }) -export class DossiersModule {} +export class DossiersModule { +} diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts index 42894f3da..471f2f1cb 100644 --- a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts @@ -16,11 +16,12 @@ export class AnnotationDrawService { ) {} drawAnnotations(activeViewer: WebViewerInstance, annotationWrappers: AnnotationWrapper[], hideSkipped = false, compareMode = false) { - const annotations = []; - annotationWrappers.forEach(annotation => { - annotations.push(this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode)); - }); - + if (!activeViewer) { + return; + } + const annotations = annotationWrappers.map(annotation => + this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode) + ); const annotationManager = activeViewer.Core.annotationManager; annotationManager.addAnnotations(annotations, { imported: true }); annotationManager.drawAnnotationsFromList(annotations);