From ba58977844192ee07683a84d07dad0b4075df50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 16 Oct 2020 19:42:41 +0300 Subject: [PATCH 1/6] Project overview chart --- .../simple-doughnut-chart.component.html | 10 ++-- .../simple-doughnut-chart.component.scss | 7 ++- .../simple-doughnut-chart.component.ts | 1 + .../project-listing-screen.component.html | 4 +- .../project-listing-screen.component.ts | 4 +- .../project-overview-screen.component.html | 12 +++- .../project-overview-screen.component.ts | 58 +++++++++++++------ apps/red-ui/src/assets/i18n/en.json | 16 ++++- 8 files changed, 81 insertions(+), 31 deletions(-) diff --git a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.html b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.html index 887c2bdb2..e38588243 100644 --- a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.html +++ b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.html @@ -1,4 +1,4 @@ -
+
-
+
{{ dataTotal }}
-
{{ subtitle }}
+
{{ subtitle | translate }}
-
+
+ [config]="[{ length: val.value, color: val.color, label: val.value + ' ' + (val.label | translate | lowercase) }]">
diff --git a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.scss b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.scss index a1bcc530b..90889090e 100644 --- a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.scss +++ b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.scss @@ -3,8 +3,12 @@ .container { position: relative; display: flex; - flex-direction: column; align-items: center; + gap: 20px; + + &.column { + flex-direction: column; + } } .text-container { @@ -14,6 +18,7 @@ flex-direction: column; justify-content: center; align-items: center; + box-sizing: border-box; } .breakdown-container { diff --git a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.ts b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.ts index 848557486..d3797ecda 100644 --- a/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.ts +++ b/apps/red-ui/src/app/components/simple-doughnut-chart/simple-doughnut-chart.component.ts @@ -19,6 +19,7 @@ export class SimpleDoughnutChartComponent implements OnInit { @Input() angleOffset = -90; @Input() radius = 85; @Input() strokeWidth = 20; + @Input() direction: 'row' | 'column' = 'column'; public chartData: any[] = []; public perimeter: number; diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html index 62c49abe6..4cd931581 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html @@ -105,7 +105,7 @@
@@ -129,7 +129,7 @@
diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts index c44752475..f1b7bd75d 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts @@ -41,8 +41,8 @@ export class ProjectListingScreenComponent implements OnInit { ngOnInit(): void { this.appStateService.reset(); this.projectsChartData = [ - { value: this.activeProjects, color: 'active', label: 'active-projects' }, - { value: this.inactiveProjects, color: 'archived', label: 'Archived' } + { value: this.activeProjects, color: 'active', label: 'active' }, + { value: this.inactiveProjects, color: 'archived', label: 'archived' } ]; this.documentsChartData = [ { value: this.appStateService.totalDocuments, color: 'unassigned', label: 'unassigned' }, diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html index 3797dd911..8af169d8b 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html @@ -53,7 +53,8 @@
-
+
+ +
+ +
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 191695d9a..cd1d40493 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 @@ -1,5 +1,5 @@ -import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {ActivatedRoute, Router} from '@angular/router'; +import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { FileStatus, FileUploadControllerService, @@ -7,19 +7,20 @@ import { ReanalysisControllerService, StatusControllerService } from '@redaction/red-ui-http'; -import {NotificationService, NotificationType} from '../../notification/notification.service'; -import {TranslateService} from '@ngx-translate/core'; -import {ConfirmationDialogComponent} from '../../common/confirmation-dialog/confirmation-dialog.component'; -import {MatDialog} from '@angular/material/dialog'; -import {AppStateService} from '../../state/app-state.service'; -import {ProjectDetailsDialogComponent} from './project-details-dialog/project-details-dialog.component'; -import {FileDropOverlayService} from '../../upload/file-drop/service/file-drop-overlay.service'; -import {FileUploadModel} from "../../upload/model/file-upload.model"; -import {FileUploadService} from "../../upload/file-upload.service"; -import {UploadStatusOverlayService} from "../../upload/upload-status-dialog/service/upload-status-overlay.service"; -import {AddEditProjectDialogComponent} from "../project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component"; -import {UserService} from "../../user/user.service"; +import { NotificationService, NotificationType } from '../../notification/notification.service'; +import { TranslateService } from '@ngx-translate/core'; +import { ConfirmationDialogComponent } from '../../common/confirmation-dialog/confirmation-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { AppStateService } from '../../state/app-state.service'; +import { ProjectDetailsDialogComponent } from './project-details-dialog/project-details-dialog.component'; +import { FileDropOverlayService } from '../../upload/file-drop/service/file-drop-overlay.service'; +import { FileUploadModel } from '../../upload/model/file-upload.model'; +import { FileUploadService } from '../../upload/file-upload.service'; +import { UploadStatusOverlayService } from '../../upload/upload-status-dialog/service/upload-status-overlay.service'; +import { AddEditProjectDialogComponent } from '../project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component'; +import { UserService } from '../../user/user.service'; import { SortingOption } from '../../utils/types'; +import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simple-doughnut-chart.component'; @Component({ @@ -28,7 +29,7 @@ import { SortingOption } from '../../utils/types'; styleUrls: ['./project-overview-screen.component.scss'] }) export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { - @ViewChild('dropzoneComponent', {static: true}) + @ViewChild('dropzoneComponent', { static: true }) dropZoneComponent; dragActive = false; @@ -37,10 +38,12 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { { label: 'project-overview.sorting.recent.label', order: 'desc', column: 'lastUpdated' }, { label: 'project-overview.sorting.alphabetically.label', order: 'asc', column: 'filename' }, { label: 'project-overview.sorting.number-of-pages.label', order: 'asc', column: 'numberOfPages' }, - { label: 'project-overview.sorting.number-of-analyses.label', order: 'desc', column: 'numberOfAnalyses' }, + { label: 'project-overview.sorting.number-of-analyses.label', order: 'desc', column: 'numberOfAnalyses' } ]; public sortingOption: SortingOption = this.sortingOptions[0]; + public documentsChartData: DoughnutChartConfig[] = []; + projectId: string; private _fileStatusInterval; @@ -71,6 +74,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { ngOnInit(): void { this._fileDropOverlayService.initFileDropHandling(); + this._calculateChartConfig(); this._fileStatusInterval = setInterval(() => { this._getFileStatus(); }, 5000); @@ -120,7 +124,23 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } private _getFileStatus() { - this.appStateService.reloadActiveProjectFiles(); + this.appStateService.reloadActiveProjectFiles().then(() => { + this._calculateChartConfig(); + }); + } + + private _calculateChartConfig() { + const obj = this.appStateService.activeProject.files.reduce((acc, file) => { + console.log(file.status); + acc[file.status === 'PROCESSED' ? 'finished' : file.status === 'ERROR' ? 'under-approval' : 'under-review']++; + return acc; + }, { 'finished': 0, 'under-approval': 0, 'under-review': 0 }); + + this.documentsChartData = Object.keys(obj).map((key) => ({ + value: obj[key], + color: key, + label: key + })) as DoughnutChartConfig[]; } fileId(index, item) { @@ -137,7 +157,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { progress: 0, completed: false, error: null - }) + }); } this._fileUploadService.uploadFiles(uploadFiles); @@ -157,7 +177,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { $event.stopPropagation(); const dialogRef = this._dialog.open(ConfirmationDialogComponent, { width: '400px', - maxWidth: '90vw', + maxWidth: '90vw' }); dialogRef.afterClosed().subscribe(result => { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 1e4509e72..6f6c8388e 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -329,6 +329,11 @@ "project-details": { "project-team": { "label": "Project team" + }, + "charts": { + "total-documents": { + "label": "Total Documents" + } } }, "header": { @@ -414,5 +419,14 @@ "unassigned": { "label": "Unassigned" } - } + }, + "unassigned": "Unassigned", + "under-review": "Under review", + "under-approval": "Under approval", + "efsa": "EFSA approval", + "finished": "Finished", + "approved": "Approved", + "submitted": "Submitted", + "active": "Active", + "archived": "Archived" } From e9c60015aeb1422d8d70cb048fdf942208e86d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Sat, 17 Oct 2020 01:53:36 +0300 Subject: [PATCH 2/6] File preview right panel & annotation icons --- apps/red-ui/src/app/app.module.ts | 2 + .../annotation-icon.component.html | 3 + .../annotation-icon.component.scss | 52 ++++ .../annotation-icon.component.ts | 16 ++ .../file-preview-screen.component.html | 174 +++++--------- .../file-preview-screen.component.scss | 223 +++++++++--------- .../file-preview-screen.component.ts | 169 ++++--------- .../screens/file/service/filters.service.ts | 10 +- .../project-overview-screen.component.html | 4 +- .../project-overview-screen.component.ts | 1 - apps/red-ui/src/app/utils/annotation-utils.ts | 57 +++++ apps/red-ui/src/app/utils/types.d.ts | 14 +- apps/red-ui/src/assets/i18n/en.json | 14 +- .../src/assets/styles/red-components.scss | 7 - .../src/assets/styles/red-variables.scss | 11 +- 15 files changed, 373 insertions(+), 384 deletions(-) create mode 100644 apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.html create mode 100644 apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.scss create mode 100644 apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.ts diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index 7f674df20..da16ff037 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -53,6 +53,7 @@ import { SimpleDoughnutChartComponent } from './components/simple-doughnut-chart import { ManualRedactionDialogComponent } from './screens/file/manual-redaction-dialog/manual-redaction-dialog.component'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { AnnotationIconComponent } from './components/annotation-icon/annotation-icon.component'; export function HttpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); @@ -76,6 +77,7 @@ export function HttpLoaderFactory(httpClient: HttpClient) { LogoComponent, SimpleDoughnutChartComponent, ManualRedactionDialogComponent, + AnnotationIconComponent, ], imports: [ BrowserModule, diff --git a/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.html b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.html new file mode 100644 index 000000000..73d7131ff --- /dev/null +++ b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.html @@ -0,0 +1,3 @@ +
+ {{ type[0] }} +
diff --git a/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.scss b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.scss new file mode 100644 index 000000000..5563fd6d6 --- /dev/null +++ b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.scss @@ -0,0 +1,52 @@ +@import "../../../assets/styles/red-variables"; + +.icon { + height: 16px; + width: 16px; + font-size: 11px; + line-height: 14px; + font-weight: 600; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + text-transform: uppercase; + color: $white; +} + +.suggestion { + width: 0; + height: 0; + border: 9px solid transparent; + border-bottom-color: $grey-1; + position: relative; + top: -9px; + + &:after { + content: ''; + position: absolute; + left: -9px; + top: 9px; + width: 0; + height: 0; + border: 9px solid transparent; + border-top-color: $grey-1; + } + + span { + transform: translateY(9px); + z-index: 2; + } +} + +.hint, .comment, .ignore { + border-radius: 50%; +} + +.hint, .redaction, .comment { + background-color: $grey-1; +} + +.ignore { + background-color: $grey-5; +} diff --git a/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.ts b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.ts new file mode 100644 index 000000000..fbc913620 --- /dev/null +++ b/apps/red-ui/src/app/components/annotation-icon/annotation-icon.component.ts @@ -0,0 +1,16 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'redaction-annotation-icon', + templateUrl: './annotation-icon.component.html', + styleUrls: ['./annotation-icon.component.scss'] +}) +export class AnnotationIconComponent implements OnInit { + @Input() public type: 'hint' | 'redaction' | 'suggestion' | 'ignore' | 'comment'; + + constructor() { + } + + ngOnInit(): void { + } +} 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 b5a729533..2201134f7 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 @@ -42,134 +42,76 @@
- - -
-
-
- -
- -
-
-
-
-
-
+
+
+ +
+ +
+
+
+
+
-
- -
- {{ filters[key].symbol }} -
- {{filters[key].label | translate }} -
-
- -
-
- -
- +
+ + + {{"file-preview.filter-menu."+ key + ".label" | translate }} + +
+
- -
-
- +
+
+
+ {{pageNumber}} +
-
-
-
Type: {{getType(annotation.Id)}}
-
Dictionary: {{getDictionary(annotation.Id)}}
-
Page: {{annotation.getPageNumber()}}
-
Content: {{annotation.getContents()}}
- -
- +
+
+
+ {{page}}
-
-
-
- -
-
- -
+
-
- + +
+
{{getType(annotation) | translate}}
+
: {{getDictionary(annotation)}}
+
: + {{annotation.getContents()}}
+
-
-
- - {{appStateService.activeFile.numberOfPages}}
-
- - {{annotations.length}}
-
+
+ {{annotation.getPageNumber()}} +
-
- - -
- -
-
-
- {{appStateService.activeFile.added | date:'medium'}} -
- -
-
-
- {{user.name}} -
- -
-
-
- {{appStateService.activeFile.lastUpdated | date:'medium'}} +
+ +
+
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss index 2b6f7c5a8..b4080f61c 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss @@ -13,142 +13,129 @@ redaction-pdf-viewer { .right-fixed-container { padding: 0; - width: calc(#{$right-container-width} - 1px); - display: flex; + width: $right-container-width; + box-sizing: border-box; - .vertical { - height: 100%; - border-right: 1px solid $separator; + .right-title { + height: 70px; + display: flex; + border-bottom: 1px solid $separator; + align-items: center; + justify-content: space-between; + padding: 0 24px; - &.active { - width: calc(#{$right-container-width} - 80px); - padding-top: 0; + > div { + position: relative; - .tab-title { - height: 70px; - display: flex; + .dot { + background: $primary; + height: 10px; + width: 10px; + border-radius: 50%; + position: absolute; + top: 0; + left: 0; + } + } + + .close-icon { + height: 14px; + width: 14px; + cursor: pointer; + } + } + + .right-content { + height: calc(100vh - 110px - 72px); + box-sizing: border-box; + display: flex; + + .pages, .annotations { + overflow-y: scroll; + + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ + &::-webkit-scrollbar { + width: 0; + background: transparent; /* Chrome/Safari/Webkit */ + } + } + + .pages { + border-right: 1px solid $separator; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + padding: 16px; + min-width: 28px; + } + + .annotations { + width: 100%; + + .page-separator { border-bottom: 1px solid $separator; - align-items: center; - justify-content: space-between; - padding: 0 25px; + height: 40px; + box-sizing: border-box; + padding: 8px 10px; + display: flex; + align-items: flex-end; + background-color: $grey-6; + } - > div { - position: relative; + .annotation { + border-bottom: 1px solid $separator; + padding: 10px; + font-size: 12px; + cursor: pointer; + position: relative; + display: flex; + gap: 10px; - .dot { - background: $primary; - height: 10px; - width: 10px; - border-radius: 50%; - position: absolute; - top: 0; - left: 0; + redaction-annotation-icon { + margin-top: 6px; + } + + &:hover { + background-color: #F9FAFB; + + .annotation-actions { + display: flex; } } - .close-icon { - height: 14px; - width: 14px; - cursor: pointer; + &.active { + border-left: 2px solid $primary; + } + + .annotation-actions { + position: absolute; + right: 0; + top: 0; + bottom: 0; + display: none; + width: 40px; } } - - .tab-content { - overflow-y: scroll; - overflow-x: hidden; - height: calc(100vh - 110px - 73px); - box-sizing: border-box; - - scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ - &::-webkit-scrollbar { - width: 0; - background: transparent; /* Chrome/Safari/Webkit */ - } - } - - .info-container { - padding: 15px; - } - } - - &:not(.active) { - width: 40px; - padding-top: 15px; - cursor: pointer; - - .tab-title { - transform: translateX(27px) rotate(90deg); - transform-origin: 0 0; - position: absolute; - } } } - .assign-reviewer { - margin-left: 12px; - } - - .annotation { - border-bottom: 1px solid $separator; - padding: 14px; - font-size: 12px; - cursor: pointer; - position: relative; - - &:hover { - background-color: #F9FAFB; - - .annotation-actions { - display: flex; - } - } - - &.active { - border-left: 2px solid $primary; - } - - .annotation-actions { - position: absolute; - right: 0; - top: 0; - bottom: 0; - display: none; - width: 40px; - } - } - - .page-navigation { + .page-number { + border: 1px solid $separator; + padding: 5px 10px; display: flex; + justify-content: center; align-items: center; - gap: 12px; - cursor: pointer; - border-bottom: 1px solid $separator; - padding: 14px; - border-left: 4px solid transparent; - - &:hover { - background-color: $grey-2; - } - - .page-number { - border: 1px solid $separator; - padding: 7px; - margin-right: 3px; - width: 14px; - text-align: center; - } - - .page-stats { - display: flex; - justify-content: center; - align-items: center; - gap: 6px; - opacity: 1; - } + height: 28px; + min-height: 28px; + min-width: 14px; + opacity: 0.7; + font-size: 11px; + line-height: 14px; &.active { - border-left: 4px solid $primary; + border: 1px solid $primary; } } } 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 97fded2d9..324ec58c0 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 @@ -1,5 +1,5 @@ -import {ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; -import {ActivatedRoute, Router} from '@angular/router'; +import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { AddRedactionRequest, FileUploadControllerService, @@ -8,34 +8,25 @@ import { ProjectControllerService, StatusControllerService } from '@redaction/red-ui-http'; -import {TranslateService} from '@ngx-translate/core'; -import {NotificationService, NotificationType} from '../../../notification/notification.service'; -import {MatDialog} from '@angular/material/dialog'; -import {AppStateService} from '../../../state/app-state.service'; -import {FileDetailsDialogComponent} from './file-details-dialog/file-details-dialog.component'; -import {ViewerSyncService} from '../service/viewer-sync.service'; -import {Annotations} from '@pdftron/webviewer'; -import {PdfViewerComponent} from '../pdf-viewer/pdf-viewer.component'; -import {AnnotationUtils} from '../../../utils/annotation-utils'; -import {ManualRedactionDialogComponent} from '../manual-redaction-dialog/manual-redaction-dialog.component'; -import {UserService} from '../../../user/user.service'; -import {debounce} from '../../../utils/debounce'; +import { TranslateService } from '@ngx-translate/core'; +import { NotificationService, NotificationType } from '../../../notification/notification.service'; +import { MatDialog } from '@angular/material/dialog'; +import { AppStateService } from '../../../state/app-state.service'; +import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component'; +import { ViewerSyncService } from '../service/viewer-sync.service'; +import { Annotations } from '@pdftron/webviewer'; +import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component'; +import { AnnotationUtils } from '../../../utils/annotation-utils'; +import { ManualRedactionDialogComponent } from '../manual-redaction-dialog/manual-redaction-dialog.component'; +import { UserService } from '../../../user/user.service'; +import { debounce } from '../../../utils/debounce'; import scrollIntoView from 'scroll-into-view-if-needed'; -import {ConfirmationDialogComponent} from '../../../common/confirmation-dialog/confirmation-dialog.component'; -import {AnnotationFilters} from '../../../utils/types'; -import {FiltersService} from '../service/filters.service'; -import {FileDownloadService} from "../service/file-download.service"; -import {saveAs} from 'file-saver'; -import {FileType} from "../model/file-type"; - -class QuickNavigationItem { - pageNumber: number; - hints: number; - redactions: number; - comments: number; - suggestions: number; - ignored: number; -} +import { AnnotationFilters } from '../../../utils/types'; +import { FiltersService } from '../service/filters.service'; +import { FileDownloadService } from '../service/file-download.service'; +import { saveAs } from 'file-saver'; +import { FileType } from '../model/file-type'; +import { ConfirmationDialogComponent } from '../../../common/confirmation-dialog/confirmation-dialog.component'; @Component({ selector: 'redaction-file-preview-screen', @@ -45,28 +36,19 @@ class QuickNavigationItem { export class FilePreviewScreenComponent implements OnInit { private _readyViewers: string[] = []; private projectId: string; - private _selectedTab: 'NAVIGATION' | 'ANNOTATIONS' | 'INFO' = 'NAVIGATION'; private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED'; + private _manualRedactionEntry: ManualRedactionEntry; - @ViewChild(PdfViewerComponent) - private _viewerComponent: PdfViewerComponent; - - @ViewChild('annotationsContainer') - private _annotationsContainer: ElementRef; - - @ViewChild('navigationTabElement') - private _navigationTabElement: ElementRef; + @ViewChild(PdfViewerComponent) private _viewerComponent: PdfViewerComponent; + @ViewChild('annotations') private _annotationsElement: ElementRef; + @ViewChild('quickNavigation') private _quickNavigationElement: ElementRef; public fileId: string; public annotations: Annotations.Annotation[] = []; + public displayedAnnotations: { [key: number]: { annotations: Annotations.Annotation[] } } = {}; public selectedAnnotation: Annotations.Annotation; - public quickNavigation: QuickNavigationItem[] = []; - public filters: AnnotationFilters; - - public get filterKeys() { - return Object.keys(this.filters); - } + public activeViewerPage: number; private _manualRedactionEntry: AddRedactionRequest; @@ -96,10 +78,14 @@ export class FilePreviewScreenComponent implements OnInit { this.filters = _filtersService.filters; } - get user() { + public get user() { return this._userService.user; } + public get filterKeys() { + return Object.keys(this.filters); + } + public get redactedView() { return this._activeViewer === 'REDACTED'; } @@ -141,56 +127,22 @@ export class FilePreviewScreenComponent implements OnInit { this._viewerSyncService.activateViewer(value); } - public selectTab(value: 'ANNOTATIONS' | 'INFO' | 'NAVIGATION', $event?: MouseEvent) { - if ($event) { - $event.stopPropagation(); - } - if (value !== this._selectedTab) { - this._selectedTab = value; - setTimeout(() => { - this._scrollViews(); - }, 50); - } + public applyFilters() { + this.displayedAnnotations = AnnotationUtils.parseAnnotations(this.annotations, this.filters); } public handleAnnotationsAdded(annotations: Annotations.Annotation[]) { this._changeDetectorRef.detectChanges(); - for (const annotation of annotations) { - if (annotation.Id.indexOf(':') > 0) { - this.annotations.push(annotation); - const pageNumber = annotation.getPageNumber(); - let el = this.quickNavigation.find((page) => page.pageNumber === pageNumber); - if (!el) { - el = {pageNumber, redactions: 0, hints: 0, ignored: 0, comments: 0, suggestions: 0}; - this.quickNavigation.push(el); - } - if (annotation.Id.startsWith('hint:')) { - el.hints++; - } - if (annotation.Id.startsWith('ignore:')) { - el.ignored++; - } - if (annotation.Id.startsWith('redaction:')) { - el.redactions++; - } - } - } - this.annotations = AnnotationUtils.sortAnnotations(this.annotations); + AnnotationUtils.addAnnotations(this.annotations, annotations); + this.applyFilters(); } - public showQuickNavigationItem(item: QuickNavigationItem): boolean { - let showItem = false; - Object.keys(this.filters).map((key) => { - if (this.showAnnotations(item, key)) { - showItem = true; - } - }) - return showItem; + public get displayedPages(): number[] { + return Object.keys(this.displayedAnnotations).map(key => Number(key)); } public handleAnnotationSelected(annotation: Annotations.Annotation) { this.selectedAnnotation = annotation; - this.selectTab('ANNOTATIONS'); this.scrollToSelectedAnnotation(); this._changeDetectorRef.detectChanges(); } @@ -204,22 +156,10 @@ export class FilePreviewScreenComponent implements OnInit { if (!this.selectedAnnotation) { return; } - const elements: any[] = this._annotationsContainer.nativeElement.querySelectorAll(`div[annotation-id="${this.selectedAnnotation.Id}"].active`); + const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(`div[annotation-id="${this.selectedAnnotation.Id}"].active`); this._scrollToFirstElement(elements); } - public get navigationTab() { - return this._selectedTab === 'NAVIGATION'; - } - - public get annotationsTab() { - return this._selectedTab === 'ANNOTATIONS'; - } - - public get infoTab() { - return this._selectedTab === 'INFO'; - } - public selectPage(pageNumber: number) { this._viewerComponent.navigateToPage(pageNumber); } @@ -241,7 +181,7 @@ export class FilePreviewScreenComponent implements OnInit { }); } - viewerPageChanged(pageNumber: number) { + public viewerPageChanged(pageNumber: number) { if (Number.isInteger(pageNumber)) { this.activeViewerPage = this._viewerSyncService.activeViewerPage; this._scrollViews(); @@ -251,13 +191,12 @@ export class FilePreviewScreenComponent implements OnInit { @debounce() private _scrollViews() { - console.log('scroll views'); this._scrollQuickNavigation(); this._scrollAnnotations(); } private _scrollQuickNavigation() { - const elements: any[] = this._navigationTabElement.nativeElement.querySelectorAll(`#quick-nav-page-${this.activeViewerPage}`); + const elements: any[] = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${this.activeViewerPage}`); this._scrollToFirstElement(elements); } @@ -265,7 +204,7 @@ export class FilePreviewScreenComponent implements OnInit { if (this.selectedAnnotation?.getPageNumber() === this.activeViewerPage) { return; } - const elements: any[] = this._annotationsContainer.nativeElement.querySelectorAll(`div[annotation-page="${this.activeViewerPage}"]`); + const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(`div[annotation-page="${this.activeViewerPage}"]`); this._scrollToFirstElement(elements); } @@ -280,14 +219,12 @@ export class FilePreviewScreenComponent implements OnInit { } } - getType(id: string) { - const parts = id.split(':'); - return parts.length >= 1 ? parts[0] : 'n/a'; + getType(annotation: Annotations.Annotation): string { + return AnnotationUtils.getType(annotation); } - getDictionary(id: string) { - const parts = id.split(':'); - return parts.length >= 2 ? parts[1] : 'n/a'; + getDictionary(annotation: Annotations.Annotation): string { + return AnnotationUtils.getDictionary(annotation); } // async getText(pageNumber: number, rect) { @@ -332,26 +269,16 @@ export class FilePreviewScreenComponent implements OnInit { public downloadFile(type: FileType | string) { this._fileDownloadService.loadFile(type, this.fileId).subscribe(data => { saveAs(data, this.appStateService.activeFile.filename); - }) + }); } public setAllFilters(value: boolean) { Object.keys(this.filters).map((key) => { - this.filters[key].value = value; + this.filters[key] = value; }); } public get hasActiveFilters(): boolean { - let activeFilters = false; - Object.keys(this.filters).map((key) => { - if (this.filters[key].value) { - activeFilters = true; - } - }); - return activeFilters; - } - - public showAnnotations(item: QuickNavigationItem, type: string): boolean { - return item[type] && (!this.hasActiveFilters || (this.hasActiveFilters && this.filters[type]?.value)); + return AnnotationUtils.hasActiveFilters(this.filters); } } diff --git a/apps/red-ui/src/app/screens/file/service/filters.service.ts b/apps/red-ui/src/app/screens/file/service/filters.service.ts index cc5a7bf90..986fe5d94 100644 --- a/apps/red-ui/src/app/screens/file/service/filters.service.ts +++ b/apps/red-ui/src/app/screens/file/service/filters.service.ts @@ -9,11 +9,11 @@ export class FiltersService { } private _filters: AnnotationFilters = { - hints: { label: 'file-preview.filter-menu.hint.label', value: false, class: 'oval darkgray-white', symbol: 'H' }, - redactions: { label: 'file-preview.filter-menu.redaction.label', value: false, class: 'square darkgray-white', symbol: 'R' }, - comments: { label: 'file-preview.filter-menu.comment.label', value: false, class: 'oval darkgray-white', symbol: 'C' }, - suggestions: { label: 'file-preview.filter-menu.suggestion.label', value: false, class: 'oval red-white', symbol: 'S' }, - ignored: { label: 'file-preview.filter-menu.ignored.label', value: false, class: 'oval lightgray-white', symbol: 'I' }, + hint: false, + redaction: false, + comment: false, + suggestion: false, + ignore: false, } public get filters(): AnnotationFilters { diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html index 8af169d8b..b01f6a8b9 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html @@ -70,8 +70,8 @@
-
R
-
S
+ +
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 cd1d40493..cd90da7a9 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 @@ -131,7 +131,6 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { private _calculateChartConfig() { const obj = this.appStateService.activeProject.files.reduce((acc, file) => { - console.log(file.status); acc[file.status === 'PROCESSED' ? 'finished' : file.status === 'ERROR' ? 'under-approval' : 'under-review']++; return acc; }, { 'finished': 0, 'under-approval': 0, 'under-review': 0 }); diff --git a/apps/red-ui/src/app/utils/annotation-utils.ts b/apps/red-ui/src/app/utils/annotation-utils.ts index d12a5bf59..9d6fdfa92 100644 --- a/apps/red-ui/src/app/utils/annotation-utils.ts +++ b/apps/red-ui/src/app/utils/annotation-utils.ts @@ -1,4 +1,5 @@ import { Annotations } from '@pdftron/webviewer'; +import { AnnotationFilters } from './types'; export class AnnotationUtils { public static sortAnnotations(annotations: Annotations.Annotation[]): Annotations.Annotation[] { @@ -15,4 +16,60 @@ export class AnnotationUtils { return ann1.getPageNumber() < ann2.getPageNumber() ? -1 : 1; }); } + + public static hasActiveFilters(filters: AnnotationFilters): boolean { + return Object.keys(filters).filter(type => filters[type]).length > 0; + } + + public static parseAnnotations(annotations: Annotations.Annotation[], filters: AnnotationFilters): + { [key: number]: { annotations: Annotations.Annotation[] } } { + const obj = {}; + + for (const ann of annotations) { + const pageNumber = ann.getPageNumber(); + const type = this.getType(ann); + + if (this.hasActiveFilters(filters) && !filters[type]) { + continue; + } + + if (!obj[pageNumber]) { + obj[pageNumber] = { + annotations: [], + hint: 0, + redaction: 0, + comment: 0, + suggestion: 0, + ignore: 0 + }; + } + obj[pageNumber].annotations.push(ann); + obj[pageNumber][type]++; + } + + Object.keys(obj).map(page => { + obj[page].annotations = this.sortAnnotations(obj[page].annotations); + }); + + return obj; + } + + + public static addAnnotations(initialAnnotations: Annotations.Annotation[], addedAnnotations: Annotations.Annotation[]) { + for (const annotation of addedAnnotations) { + if (annotation.Id.indexOf(':') > 0) { + initialAnnotations.push(annotation); + } + } + } + + public static getType(annotation: Annotations.Annotation): string { + const parts = annotation.Id.split(':'); + return parts.length >= 1 ? parts[0] : 'n/a'; + } + + public static getDictionary(annotation: Annotations.Annotation): string { + const parts = annotation.Id.split(':'); + return parts.length >= 2 ? parts[1] : 'n/a'; + } } diff --git a/apps/red-ui/src/app/utils/types.d.ts b/apps/red-ui/src/app/utils/types.d.ts index d68b9a903..1409dc7ec 100644 --- a/apps/red-ui/src/app/utils/types.d.ts +++ b/apps/red-ui/src/app/utils/types.d.ts @@ -9,6 +9,13 @@ export type Color = 'active' | 'archived'; +export type AnnotationType = + 'hint' | + 'redaction' | + 'suggestion' | + 'comment' | + 'ignore' + export class SortingOption { label: string; order: string; @@ -16,10 +23,5 @@ export class SortingOption { } export class AnnotationFilters { - [key: string]: { - label: string, - value: boolean, - class: string, - symbol: string - } + [key: AnnotationType]: boolean } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 6f6c8388e..134f76839 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -368,12 +368,12 @@ "label": "Redaction" }, "comment": { - "label": "Comment" + "label": "Comment annotation" }, "suggestion": { "label": "Suggested redaction" }, - "ignored": { + "ignore": { "label": "Ignored redaction" } }, @@ -428,5 +428,13 @@ "approved": "Approved", "submitted": "Submitted", "active": "Active", - "archived": "Archived" + "archived": "Archived", + "hint": "Hint", + "ignore": "Ignore", + "redaction": "Redaction", + "comment": "Comment", + "suggestion": "Suggestion for redaction", + "dictionary": "Dictionary", + "content": "Content", + "page": "Page" } diff --git a/apps/red-ui/src/assets/styles/red-components.scss b/apps/red-ui/src/assets/styles/red-components.scss index 0ffb1d62c..bfec999e1 100644 --- a/apps/red-ui/src/assets/styles/red-components.scss +++ b/apps/red-ui/src/assets/styles/red-components.scss @@ -19,13 +19,6 @@ font-size: 13px; } - &.x-small { - height: 16px; - width: 16px; - font-size: 11px; - line-height: 14px; - } - &.lightgray-dark { background-color: $grey-4; } diff --git a/apps/red-ui/src/assets/styles/red-variables.scss b/apps/red-ui/src/assets/styles/red-variables.scss index 55ef43b4e..6815af85e 100644 --- a/apps/red-ui/src/assets/styles/red-variables.scss +++ b/apps/red-ui/src/assets/styles/red-variables.scss @@ -1,16 +1,12 @@ $white: #FFF; $black: #000; -$primary: #DD4D50; -$accent: #283241; -$light: #FFF; -$dark: #000; - $grey-1: #283241; $grey-2: #F4F5F7; $grey-3: #AAACB3; $grey-4: #E2E4E9; $grey-5: #D3D5DA; +$grey-6: #F0F1F4; $blue-1: #4875F7; $blue-2: #48C9F7; @@ -21,6 +17,11 @@ $yellow-1: #FFB83B; $green-1: #46CE7D; $green-2: #5CE594; +$primary: $red-1; +$accent: $grey-1; +$light: $white; +$dark: $black; + $separator: rgba(226,228,233,0.9); $right-container-inside-width: 340px; From 0979287274de57326abf50ab2100280bedac66f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Sun, 18 Oct 2020 20:45:42 +0300 Subject: [PATCH 3/6] Cleanup some styles --- apps/red-ui/src/app/icons/icons.module.ts | 2 +- .../base-screen/base-screen.component.html | 7 ++-- .../base-screen/base-screen.component.scss | 17 ---------- .../file-preview-screen.component.html | 6 ++-- .../project-listing-screen.component.html | 26 +++++++-------- .../project-overview-screen.component.html | 32 +++++++++---------- .../assets/icons/general/drop-down-arrow.svg | 16 ++++------ apps/red-ui/src/assets/styles/red-button.scss | 13 ++------ .../src/assets/styles/red-page-layout.scss | 8 +++-- 9 files changed, 50 insertions(+), 77 deletions(-) diff --git a/apps/red-ui/src/app/icons/icons.module.ts b/apps/red-ui/src/app/icons/icons.module.ts index 0e45e19d7..b9f2651fe 100644 --- a/apps/red-ui/src/app/icons/icons.module.ts +++ b/apps/red-ui/src/app/icons/icons.module.ts @@ -15,7 +15,7 @@ export class IconsModule { ) { const icons = [ 'add', 'analyse', 'arrow-down', 'arrow-up', 'assign', 'calendar', 'check', - 'close', 'document', 'double-chevron-right', 'download', 'drop-down-arrow', + 'close', 'document', 'double-chevron-right', 'download', 'edit', 'error', 'folder', 'info', 'lightning', 'logout', 'menu', 'pages', 'plus', 'preview', 'refresh', 'report', 'secret', 'sort-asc', 'sort-desc', 'status', 'trash', 'user' diff --git a/apps/red-ui/src/app/screens/base-screen/base-screen.component.html b/apps/red-ui/src/app/screens/base-screen/base-screen.component.html index 4ee93847d..a7c27a36d 100644 --- a/apps/red-ui/src/app/screens/base-screen/base-screen.component.html +++ b/apps/red-ui/src/app/screens/base-screen/base-screen.component.html @@ -40,11 +40,8 @@
-
- - - {{"file-preview.filter-menu."+ key + ".label" | translate }} - +
+
+ + + {{"file-preview.filter-menu." + key + ".label" | translate }} + +
+
+
+ + + {{"file-preview.filter-menu." + key + "." + subkey + ".label" | translate }} + +
+
+
@@ -94,7 +111,7 @@ (click)="selectAnnotation(annotation)" > - +
{{getType(annotation) | translate}}
: {{getDictionary(annotation)}}
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 324ec58c0..d0b873eff 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 @@ -82,7 +82,11 @@ export class FilePreviewScreenComponent implements OnInit { return this._userService.user; } - public get filterKeys() { + public filterKeys(key?: string) { + if (key) { + return Object.keys(this.filters[key]); + } + return Object.keys(this.filters); } @@ -272,13 +276,36 @@ export class FilePreviewScreenComponent implements OnInit { }); } - public setAllFilters(value: boolean) { - Object.keys(this.filters).map((key) => { - this.filters[key] = value; - }); + public setAllFilters(filter: AnnotationFilters, value: boolean, rootKey?: string) { + if (rootKey) { + this.filters[rootKey] = value; + } else { + + for (const key of Object.keys(filter)) { + if (AnnotationUtils.hasSubsections(filter[key])) { + this.setAllFilters(filter[key], value); + } else { + filter[key] = value; + } + } + } + + this.applyFilters(); + } + + public isChecked(key: string): boolean { + return AnnotationUtils.isChecked(this.filters[key]); + } + + public isIndeterminate(key: string): boolean { + return AnnotationUtils.isIndeterminate(this.filters[key]); } public get hasActiveFilters(): boolean { return AnnotationUtils.hasActiveFilters(this.filters); } + + public hasSubsections(filter: AnnotationFilters | boolean) { + return AnnotationUtils.hasSubsections(filter); + } } diff --git a/apps/red-ui/src/app/screens/file/service/filters.service.ts b/apps/red-ui/src/app/screens/file/service/filters.service.ts index 986fe5d94..cb8cb7807 100644 --- a/apps/red-ui/src/app/screens/file/service/filters.service.ts +++ b/apps/red-ui/src/app/screens/file/service/filters.service.ts @@ -9,7 +9,11 @@ export class FiltersService { } private _filters: AnnotationFilters = { - hint: false, + hint: { + hint_only: false, + vertebrate: false, + names: false, + }, redaction: false, comment: false, suggestion: false, diff --git a/apps/red-ui/src/app/utils/annotation-utils.ts b/apps/red-ui/src/app/utils/annotation-utils.ts index 9d6fdfa92..cdfc3fa2e 100644 --- a/apps/red-ui/src/app/utils/annotation-utils.ts +++ b/apps/red-ui/src/app/utils/annotation-utils.ts @@ -17,8 +17,31 @@ export class AnnotationUtils { }); } - public static hasActiveFilters(filters: AnnotationFilters): boolean { - return Object.keys(filters).filter(type => filters[type]).length > 0; + public static hasSubsections(filter: AnnotationFilters | boolean) { + return filter instanceof Object; + } + + public static checkedSubkeys(filter: AnnotationFilters | boolean) { + return Object.keys(filter).filter(subkey => this.isChecked(filter[subkey])).length; + } + + // Only some of the sub-items are selected + public static isIndeterminate(filter: AnnotationFilters | boolean): boolean { + return this.hasSubsections(filter) ? AnnotationUtils.checkedSubkeys(filter) > 0 && !this.isChecked(filter) : false; + } + + // All sub-items are selected + public static isChecked(filter: AnnotationFilters | boolean): boolean { + return this.hasSubsections(filter) ? + AnnotationUtils.checkedSubkeys(filter) === Object.keys(filter).length : + filter as boolean; + } + + public static hasActiveFilters(filter: AnnotationFilters): boolean { + const activeFilters = Object.keys(filter).filter(key => { + return this.isChecked(filter[key]) || this.isIndeterminate(filter[key]); + }); + return activeFilters.length > 0; } public static parseAnnotations(annotations: Annotations.Annotation[], filters: AnnotationFilters): @@ -28,9 +51,16 @@ export class AnnotationUtils { for (const ann of annotations) { const pageNumber = ann.getPageNumber(); const type = this.getType(ann); + const dictionary = this.getDictionary(ann); - if (this.hasActiveFilters(filters) && !filters[type]) { - continue; + if (this.hasActiveFilters(filters)) { + if (!this.hasSubsections(filters[type]) && !filters[type]) { + continue; + } + + if (this.hasSubsections(filters[type]) && !filters[type][dictionary]) { + continue; + } } if (!obj[pageNumber]) { @@ -54,7 +84,6 @@ export class AnnotationUtils { return obj; } - public static addAnnotations(initialAnnotations: Annotations.Annotation[], addedAnnotations: Annotations.Annotation[]) { for (const annotation of addedAnnotations) { if (annotation.Id.indexOf(':') > 0) { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 134f76839..bc41964a8 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -362,7 +362,16 @@ "label": "Filter types" }, "hint": { - "label": "Hint annotation" + "label": "Hint annotation", + "hint_only": { + "label": "Hint only" + }, + "vertebrate": { + "label": "Vertebrate" + }, + "names": { + "label": "Names" + } }, "redaction": { "label": "Redaction" diff --git a/apps/red-ui/src/assets/styles/red-menu.scss b/apps/red-ui/src/assets/styles/red-menu.scss index 755380deb..e030e4d30 100644 --- a/apps/red-ui/src/assets/styles/red-menu.scss +++ b/apps/red-ui/src/assets/styles/red-menu.scss @@ -9,6 +9,10 @@ font-size: 13px; color: $accent; + &.padding-left { + padding-left: 40px; + } + .mat-checkbox-layout { width: 100%; diff --git a/apps/red-ui/src/assets/styles/red-variables.scss b/apps/red-ui/src/assets/styles/red-variables.scss index 6815af85e..c2aedf111 100644 --- a/apps/red-ui/src/assets/styles/red-variables.scss +++ b/apps/red-ui/src/assets/styles/red-variables.scss @@ -14,8 +14,10 @@ $blue-3: #5B97DB; $blue-4: #374C81; $red-1: #DD4D50; $yellow-1: #FFB83B; -$green-1: #46CE7D; +$yellow-2: #FFFF02; +$green-1: #00FF00; $green-2: #5CE594; +$orange-1: #FF801A; $primary: $red-1; $accent: $grey-1; From de19b9a287f10bb8b4b7d753d74f86858e03334c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 19 Oct 2020 00:17:34 +0300 Subject: [PATCH 5/6] Expandable filters --- .../file-preview-screen.component.html | 13 +++++++++---- .../file-preview-screen.component.scss | 2 +- .../file-preview-screen.component.ts | 6 ++++++ apps/red-ui/src/assets/styles/red-menu.scss | 13 +++++++++++-- apps/red-ui/src/assets/styles/red-page-layout.scss | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) 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 29af6b76f..7da724bd3 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 @@ -51,7 +51,7 @@ arrow_drop_down
- +
@@ -62,7 +62,11 @@
-
+
+
+ arrow_drop_down + arrow_right +
-
+
- +
{{getType(annotation) | translate}}
: {{getDictionary(annotation)}}
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss index b4080f61c..7b53dc8a5 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss @@ -143,8 +143,8 @@ redaction-pdf-viewer { .filter-menu-header { display: flex; justify-content: space-between; - width: 250px; padding: 7px 15px 15px; + width: 350px; .actions { display: flex; 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 d0b873eff..28d166832 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 @@ -48,6 +48,7 @@ export class FilePreviewScreenComponent implements OnInit { public displayedAnnotations: { [key: number]: { annotations: Annotations.Annotation[] } } = {}; public selectedAnnotation: Annotations.Annotation; public filters: AnnotationFilters; + public expandedFilters: AnnotationFilters = { hint: false }; public activeViewerPage: number; private _manualRedactionEntry: AddRedactionRequest; @@ -308,4 +309,9 @@ export class FilePreviewScreenComponent implements OnInit { public hasSubsections(filter: AnnotationFilters | boolean) { return AnnotationUtils.hasSubsections(filter); } + + public setExpanded(key: string, value: boolean, $event: MouseEvent) { + $event.stopPropagation(); + this.expandedFilters[key] = value; + } } diff --git a/apps/red-ui/src/assets/styles/red-menu.scss b/apps/red-ui/src/assets/styles/red-menu.scss index e030e4d30..dc12d76f7 100644 --- a/apps/red-ui/src/assets/styles/red-menu.scss +++ b/apps/red-ui/src/assets/styles/red-menu.scss @@ -3,18 +3,27 @@ .mat-menu-panel { border-radius: 8px !important; box-shadow: 0 2px 6px 0 rgba(40, 50, 65, 0.3); + max-width: none !important; .mat-menu-item { font-family: 'Inter', sans-serif; font-size: 13px; color: $accent; + .arrow-wrapper { + width: 24px; + + mat-icon { + width: 14px; + } + } + &.padding-left { - padding-left: 40px; + padding-left: 64px; } .mat-checkbox-layout { - width: 100%; + margin-left: 4px; .mat-checkbox-inner-container { margin-left: 0; diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss index d84095c1f..0263fd26e 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -73,7 +73,7 @@ html, body { } .flex { - display: flex; + display: flex !important; } .flex-1 { From 43510a448f08cf48a6e2c8a235069ca415b2e626 Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Mon, 19 Oct 2020 10:42:59 +0300 Subject: [PATCH 6/6] post rebase code fixes --- .../file/file-preview-screen/file-preview-screen.component.ts | 4 ---- 1 file changed, 4 deletions(-) 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 28d166832..024a54c5b 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 @@ -51,10 +51,6 @@ export class FilePreviewScreenComponent implements OnInit { public expandedFilters: AnnotationFilters = { hint: false }; public activeViewerPage: number; - private _manualRedactionEntry: AddRedactionRequest; - - activeViewerPage: number; - constructor( public readonly appStateService: AppStateService, private readonly _changeDetectorRef: ChangeDetectorRef,