From 558eeb8a1eb05c62e568de037df537476bdf14b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 04:24:37 +0200 Subject: [PATCH 1/6] Prevent default fix --- .../file/file-preview-screen/file-preview-screen.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 7b9195f45..0489a2789 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 @@ -418,6 +418,8 @@ export class FilePreviewScreenComponent implements OnInit { } preventArrowDefault($event: KeyboardEvent) { - $event.preventDefault(); + if (KEY_ARRAY.includes($event.key)) { + $event.preventDefault(); + } } } From db8827e3813cd5dc088cfbbdb5d16d0c50946123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 04:25:44 +0200 Subject: [PATCH 2/6] Toggle bulk select and add on project listing --- .../project-listing-screen.component.html | 40 +++++++++++++++---- .../project-listing-screen.component.scss | 11 +++++ .../project-listing-screen.component.ts | 40 ++++++++++++++++++- .../project-overview-screen.component.html | 14 +++++-- .../project-overview-screen.component.scss | 38 +++++------------- .../project-overview-screen.component.ts | 5 +++ .../src/assets/styles/red-components.scss | 13 ++++++ .../src/assets/styles/red-page-layout.scss | 14 +++++++ 8 files changed, 133 insertions(+), 42 deletions(-) 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 c3e16403b..61c600699 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 @@ -52,14 +52,28 @@
- - {{ - 'project-listing.table-header.title.label' - | translate: { length: appStateService.allProjects?.length || 0 } - }} - +
+
+ + {{ + 'project-listing.table-header.title.label' + | translate: { length: appStateService.allProjects?.length || 0 } + }} + +
+
-
+
@@ -70,7 +84,9 @@
-
+
+
+
+
+
+
+
{{ pw.project.projectName }} diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss index ca0443bde..6a39b63a9 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss @@ -13,6 +13,10 @@ .grid-container { grid-template-columns: 2fr 1fr auto; + + &.bulk-select { + grid-template-columns: auto 2fr 1fr auto; + } } .stats-subtitle { @@ -22,6 +26,13 @@ .status-container { width: 160px; } + + .actions { + .active { + font-weight: 600; + color: $primary; + } + } } .right-fixed-container { 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 098f7070e..b13d9372e 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 @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { Project } from '@redaction/red-ui-http'; +import { FileStatus, Project } from '@redaction/red-ui-http'; import { AppStateService, ProjectWrapper } from '../../state/app-state.service'; import { UserService } from '../../user/user.service'; import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simple-doughnut-chart.component'; @@ -15,6 +15,8 @@ import * as moment from 'moment'; styleUrls: ['./project-listing-screen.component.scss'] }) export class ProjectListingScreenComponent implements OnInit { + private _selectedProjectIds: string[] = []; + public projectsChartData: DoughnutChartConfig[] = []; public documentsChartData: DoughnutChartConfig[] = []; public sortingOptions: SortingOption[] = [ @@ -26,6 +28,7 @@ export class ProjectListingScreenComponent implements OnInit { } ]; public sortingOption: SortingOption = this.sortingOptions[0]; + public bulkSelectActive = false; statusFilters: FilterModel[]; dueDateFilters: FilterModel[]; @@ -118,6 +121,10 @@ export class ProjectListingScreenComponent implements OnInit { this._dialogService.openAssignProjectMembersAndOwnerDialog($event, project); } + public toggleBulkSelect() { + this.bulkSelectActive = !this.bulkSelectActive; + } + public getProjectStatusConfig(pw: ProjectWrapper) { const obj = pw.files.reduce((acc, file) => { const status = file.status; @@ -248,4 +255,35 @@ export class ProjectListingScreenComponent implements OnInit { } return filterMatched; } + + public toggleProjectSelected($event: MouseEvent, pw: ProjectWrapper) { + $event.stopPropagation(); + const idx = this._selectedProjectIds.indexOf(pw.project.projectId); + if (idx === -1) { + this._selectedProjectIds.push(pw.project.projectId); + } else { + this._selectedProjectIds.splice(idx, 1); + } + } + + public toggleSelectAll() { + if (this.areAllProjectsSelected()) { + this._selectedProjectIds = []; + } else { + this._selectedProjectIds = this.appStateService.allProjects.map( + (pw) => pw.project.projectId + ); + } + } + + public areAllProjectsSelected(): boolean { + return ( + this.appStateService.allProjects.length !== 0 && + this._selectedProjectIds.length === this.appStateService.allProjects.length + ); + } + + public isProjectSelected(pw: ProjectWrapper): boolean { + return this._selectedProjectIds.indexOf(pw.project.projectId) !== -1; + } } 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 b55b25408..5c9046ed5 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 @@ -48,6 +48,7 @@
-
+
@@ -72,9 +78,9 @@
-
+
-
+
-
+
file.newRule).length) { diff --git a/apps/red-ui/src/assets/styles/red-components.scss b/apps/red-ui/src/assets/styles/red-components.scss index 48797f95f..f61275622 100644 --- a/apps/red-ui/src/assets/styles/red-components.scss +++ b/apps/red-ui/src/assets/styles/red-components.scss @@ -131,3 +131,16 @@ stroke: rgba($red-1, 0.1); background-color: rgba($red-1, 0.1); } + +.select-oval { + width: 20px; + height: 20px; + border-radius: 50%; + border: 1px solid $grey-5; + background-color: $white; + cursor: pointer; + + &.active { + background-color: $primary; + } +} 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 393c23129..db111d584 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -181,3 +181,17 @@ body { .pointer { cursor: pointer; } + +.select-all-container { + display: flex; + gap: 16px; + align-items: center; + + .select-oval { + margin-left: 0; + } +} + +.pr-0 { + padding-right: 0 !important; +} From b03607dd1f2bf1884c56ac93e44a3c4023e9b884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 04:41:03 +0200 Subject: [PATCH 3/6] Filter fixes --- apps/red-ui/src/app/common/filter/filter.component.html | 2 +- apps/red-ui/src/app/common/filter/filter.component.ts | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/red-ui/src/app/common/filter/filter.component.html b/apps/red-ui/src/app/common/filter/filter.component.html index 8c91c5b1f..3573e1023 100644 --- a/apps/red-ui/src/app/common/filter/filter.component.html +++ b/apps/red-ui/src/app/common/filter/filter.component.html @@ -29,7 +29,7 @@
-
+
diff --git a/apps/red-ui/src/app/common/filter/filter.component.ts b/apps/red-ui/src/app/common/filter/filter.component.ts index 66db2bb09..ab5f6a049 100644 --- a/apps/red-ui/src/app/common/filter/filter.component.ts +++ b/apps/red-ui/src/app/common/filter/filter.component.ts @@ -7,7 +7,6 @@ import { SimpleChanges, TemplateRef } from '@angular/core'; -import { ManualRedactions } from '@redaction/red-ui-http'; import { AppStateService } from '../../state/app-state.service'; import { FilterModel } from './model/filter.model'; import { handleCheckedValue } from './utils/filter-utils'; @@ -42,11 +41,11 @@ export class FilterComponent implements OnChanges { } activateAllFilters() { - this._setAlLFilters(true); + this._setAllFilters(true); } deactivateAllFilters() { - this._setAlLFilters(false); + this._setAllFilters(false); } get hasActiveFilters(): boolean { @@ -67,10 +66,10 @@ export class FilterComponent implements OnChanges { filter.expanded = !filter.expanded; } - private _setAlLFilters(value: boolean) { + private _setAllFilters(value: boolean) { this.filters?.forEach((f) => { f.checked = value; - f.indeterminate = value; + f.indeterminate = false; f.filters.forEach((ff) => { ff.checked = value; }); From b60b5154fcd60488b8e2176195207a84f1099f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 05:40:59 +0200 Subject: [PATCH 4/6] Filters in project overview --- .../project-overview-screen.component.html | 56 +++++--- .../project-overview-screen.component.ts | 120 +++++++++++++++++- 2 files changed, 152 insertions(+), 24 deletions(-) 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 5c9046ed5..75acce1d5 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 @@ -9,24 +9,36 @@ +
+
{ - this._calculateChartConfig(); + this._calculateData(); }); } ngOnInit(): void { this._fileDropOverlayService.initFileDropHandling(); - this._calculateChartConfig(); + this._calculateData(); this._displayNewRuleToast(); } @@ -162,10 +170,16 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { private _reloadProjects() { this.appStateService.loadAllProjects().then(() => { - this._calculateChartConfig(); + this._calculateData(); }); } + private _calculateData(): void { + this._computeAllFilters(); + this._filterFiles(); + this._calculateChartConfig(); + } + private _calculateChartConfig() { if (this.appStateService.activeProject) { const groups = groupBy(this.appStateService.activeProject?.files, 'status'); @@ -213,7 +227,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { fileStatus.projectId, fileStatus.fileId, () => { - this._calculateChartConfig(); + this._calculateData(); } ); } @@ -284,6 +298,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { this._fileUploadService.uploadFiles(uploadFiles); this._uploadStatusOverlayService.openStatusOverlay(); } + public canOpenFile(fileStatus: FileStatus): boolean { // TODO check correct condition for this return !this.isError(fileStatus) && !this.isProcessing(fileStatus); @@ -293,4 +308,99 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { const sortedByRecent: boolean = this.sortingOption === this.sortingOptions[0]; this.sortingOption = sortedByRecent ? this.sortingOptions[1] : this.sortingOptions[0]; } + + private _computeAllFilters() { + const allDistinctFileStatus = new Set(); + const allDistinctPeople = new Set(); + const allDistinctAddedDates = new Set(); + + // All people + this.appStateService.activeProject.project.memberIds.forEach((memberId) => + allDistinctPeople.add(memberId) + ); + + // File statuses + this.appStateService.activeProject.files.forEach((file) => + allDistinctFileStatus.add(file.status) + ); + + // Added dates + this.appStateService.activeProject.files.forEach((file) => + allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY')) + ); + + this.statusFilters = []; + allDistinctFileStatus.forEach((status) => { + this.statusFilters.push({ + key: status, + label: humanize(status) + }); + }); + + this.peopleFilters = []; + allDistinctPeople.forEach((userId) => { + this.peopleFilters.push({ + key: userId, + label: this.userService.getNameForId(userId) + }); + }); + + this.addedDateFilters = []; + allDistinctAddedDates.forEach((date) => { + this.addedDateFilters.push({ + key: date, + label: date + }); + }); + } + + filtersChanged() { + this._filterFiles(); + } + + private _filterFiles() { + const filteredFiles = []; + + for (const file of this.appStateService.activeProject.files) { + const statusFilterMatched = this._checkFilter( + file, + this.statusFilters, + (file: FileStatus, filter: FilterModel) => file.status === filter.key + ); + + const peopleFilterMatched = this._checkFilter( + file, + this.peopleFilters, + (file: FileStatus, filter: FilterModel) => file.currentReviewer === filter.key + ); + + const addedFilterMatched = this._checkFilter( + file, + this.peopleFilters, + (file: FileStatus, filter: FilterModel) => + moment(file.added).format('DD/MM/YYYY') === filter.key + ); + + if (statusFilterMatched && peopleFilterMatched && addedFilterMatched) { + filteredFiles.push(file); + } + } + + this.displayedFiles = filteredFiles; + } + + private _checkFilter(file: FileStatus, filters: FilterModel[], validate: Function) { + const hasChecked = filters.find((f) => f.checked); + if (!hasChecked) { + return true; + } + let filterMatched = false; + for (const filter of filters) { + if (filter.checked && validate(file, filter)) { + filterMatched = true; + break; + } + } + return filterMatched; + } } From 4fc0c92753a332066ac6781ea1ae5553f2e43cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 05:48:21 +0200 Subject: [PATCH 5/6] Fixes --- apps/red-ui/src/app/common/filter/filter.component.ts | 2 +- .../project-overview-screen.component.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/red-ui/src/app/common/filter/filter.component.ts b/apps/red-ui/src/app/common/filter/filter.component.ts index ab5f6a049..f1ea84a5b 100644 --- a/apps/red-ui/src/app/common/filter/filter.component.ts +++ b/apps/red-ui/src/app/common/filter/filter.component.ts @@ -70,7 +70,7 @@ export class FilterComponent implements OnChanges { this.filters?.forEach((f) => { f.checked = value; f.indeterminate = false; - f.filters.forEach((ff) => { + f.filters?.forEach((ff) => { ff.checked = value; }); }); 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 d0f10690d..a4d53a3d7 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 @@ -365,20 +365,20 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { const statusFilterMatched = this._checkFilter( file, this.statusFilters, - (file: FileStatus, filter: FilterModel) => file.status === filter.key + (f: FileStatus, filter: FilterModel) => f.status === filter.key ); const peopleFilterMatched = this._checkFilter( file, this.peopleFilters, - (file: FileStatus, filter: FilterModel) => file.currentReviewer === filter.key + (f: FileStatus, filter: FilterModel) => f.currentReviewer === filter.key ); const addedFilterMatched = this._checkFilter( file, - this.peopleFilters, - (file: FileStatus, filter: FilterModel) => - moment(file.added).format('DD/MM/YYYY') === filter.key + this.addedDateFilters, + (f: FileStatus, filter: FilterModel) => + moment(f.added).format('DD/MM/YYYY') === filter.key ); if (statusFilterMatched && peopleFilterMatched && addedFilterMatched) { From a4bcded240e1d5caa8f3de1691396329663105da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 2 Nov 2020 06:34:12 +0200 Subject: [PATCH 6/6] Accept suggestion menu --- apps/red-ui/src/app/dialogs/dialog.service.ts | 4 +- .../file-preview-screen.component.html | 106 ++++++++++++------ .../file-preview-screen.component.scss | 35 +++--- .../file-preview-screen.component.ts | 91 +++++++++------ apps/red-ui/src/assets/i18n/en.json | 10 +- apps/red-ui/src/assets/styles/red-button.scss | 7 ++ apps/red-ui/src/assets/styles/red-menu.scss | 4 + 7 files changed, 167 insertions(+), 90 deletions(-) diff --git a/apps/red-ui/src/app/dialogs/dialog.service.ts b/apps/red-ui/src/app/dialogs/dialog.service.ts index 5f049d3eb..6114a8ece 100644 --- a/apps/red-ui/src/app/dialogs/dialog.service.ts +++ b/apps/red-ui/src/app/dialogs/dialog.service.ts @@ -99,7 +99,7 @@ export class DialogService { return ref; } - public acceptSuggestion( + public openAcceptSuggestionModal( $event: MouseEvent, annotation: AnnotationWrapper ): MatDialogRef { @@ -115,7 +115,7 @@ export class DialogService { return ref; } - public rejectSuggestion( + public openRejectSuggestionModal( $event: MouseEvent, annotation: AnnotationWrapper, rejectCallback: () => 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 61c3f2114..650ab0a9f 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 @@ -1,7 +1,7 @@