diff --git a/apps/red-ui/src/app/common/service/permissions.service.ts b/apps/red-ui/src/app/common/service/permissions.service.ts
index 4e59f3634..7fa07806c 100644
--- a/apps/red-ui/src/app/common/service/permissions.service.ts
+++ b/apps/red-ui/src/app/common/service/permissions.service.ts
@@ -194,7 +194,8 @@ export class PermissionsService {
if (!fileStatus) {
fileStatus = this._appStateService.activeFile;
}
- return fileStatus.status === 'APPROVED' && this.isManagerAndOwner();
+ const project = this._appStateService.getProjectById(fileStatus.projectId);
+ return fileStatus.status === 'APPROVED' && this.isManagerAndOwner(project);
}
canDeleteProject(project?: ProjectWrapper) {
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 4a3c4cbea..42e3a3a62 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
@@ -152,12 +152,18 @@
icon="red:refresh"
>
+
+
-
-
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 283736669..6a6625700 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,9 +1,9 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
-import { Project } from '@redaction/red-ui-http';
+import { FileManagementControllerService, Project } from '@redaction/red-ui-http';
import { AppStateService } from '../../state/app-state.service';
import { UserService } from '../../user/user.service';
import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simple-doughnut-chart.component';
-import { groupBy, humanize } from '../../utils/functions';
+import { computerize, groupBy, humanize } from '../../utils/functions';
import { DialogService } from '../../dialogs/dialog.service';
import { FilterModel } from '../../common/filter/model/filter.model';
import {
@@ -25,6 +25,7 @@ import { StatusSorter } from '../../common/sorters/status-sorter';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup } from '@angular/forms';
import { debounce } from '../../utils/debounce';
+import { download } from '../../utils/file-download-utils';
@Component({
selector: 'redaction-project-listing-screen',
@@ -60,7 +61,8 @@ export class ProjectListingScreenComponent implements OnInit, OnDestroy {
private readonly _router: Router,
public readonly sortingService: SortingService,
public readonly translateChartService: TranslateChartService,
- private readonly _formBuilder: FormBuilder
+ private readonly _formBuilder: FormBuilder,
+ private readonly _fileManagementControllerService: FileManagementControllerService
) {
this.searchForm = this._formBuilder.group({
query: ['']
@@ -257,7 +259,12 @@ export class ProjectListingScreenComponent implements OnInit, OnDestroy {
const filters = [
{ values: this.statusFilters, checker: projectStatusChecker },
{ values: this.peopleFilters, checker: projectMemberChecker },
- { values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true, checkerArgs: this.permissionsService }
+ {
+ values: this.needsWorkFilters,
+ checker: annotationFilterChecker,
+ matchAll: true,
+ checkerArgs: this.permissionsService
+ }
];
return getFilteredEntities(this.appStateService.allProjects, filters);
}
@@ -282,4 +289,18 @@ export class ProjectListingScreenComponent implements OnInit, OnDestroy {
this._calculateData();
});
}
+
+ // Download Files
+ public downloadRedactedFiles($event: MouseEvent, project: ProjectWrapper) {
+ $event.stopPropagation();
+ this._fileManagementControllerService
+ .downloadRedactedFiles({ fileIds: project.files.map((file) => file.fileId) }, project.projectId, false, 'response')
+ .subscribe((data) => {
+ download(data, 'redacted_files_' + computerize(project.name) + '.zip');
+ });
+ }
+
+ public canDownloadRedactedFiles(project: ProjectWrapper) {
+ return project.files.reduce((acc, file) => acc && this.permissionsService.canDownloadRedactedFile(file), true);
+ }
}
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 48fc4f4cc..0a353e0d5 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
@@ -69,6 +69,15 @@
tooltipPosition="below"
icon="red:refresh"
>
+
+
+
file.fileId) },
+ this.appStateService.activeProjectId,
+ false,
+ 'response'
+ )
+ .subscribe((data) => {
+ download(data, 'redacted_files_' + computerize(this.appStateService.activeProject.name) + '.zip');
+ });
+ }
+
+ public get canDownloadRedactedFiles() {
+ return this.appStateService.activeProject.files.reduce((acc, file) => acc && this.permissionsService.canDownloadRedactedFile(file), true);
+ }
}
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 3304587a5..5cc05496c 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -77,6 +77,9 @@
"assign": {
"action": "Assign Owner & Members"
},
+ "download-files": {
+ "action": "Download Redacted Files"
+ },
"table-header": {
"title": "{{length}} active projects",
"bulk-select": "Toggle Selection",
@@ -155,7 +158,8 @@
"edit": "Edit",
"delete": "Delete",
"assign": "Assign Owner & Members",
- "upload-document": "Upload Document"
+ "upload-document": "Upload Document",
+ "download-redacted-files": "Download Redacted Files"
},
"download-redacted-file": "Download Redacted File",
"download-redacted-files": "Download Redacted Files",