Added preview download and download options
This commit is contained in:
parent
6b7c3cf76c
commit
08719af53c
@ -106,6 +106,7 @@ import { MatSliderModule } from '@angular/material/slider';
|
||||
import { PendingChangesGuard } from './utils/can-deactivate.guard';
|
||||
import { OverwriteFilesDialogComponent } from './dialogs/overwrite-files-dialog/overwrite-files-dialog.component';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { FileDownloadBtnComponent } from './components/buttons/file-download-btn/file-download-btn.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -330,6 +331,7 @@ const matImports = [
|
||||
PdfViewerScreenComponent,
|
||||
HtmlDebugScreenComponent,
|
||||
ReportDownloadBtnComponent,
|
||||
FileDownloadBtnComponent,
|
||||
ProjectListingActionsComponent,
|
||||
RuleSetActionsComponent,
|
||||
RuleSetViewSwitchComponent
|
||||
|
||||
@ -51,17 +51,15 @@
|
||||
</redaction-report-download-btn>
|
||||
|
||||
<!-- download redacted file-->
|
||||
<redaction-circle-button
|
||||
(action)="downloadFile($event, fileStatus)"
|
||||
*ngIf="permissionsService.canDownloadRedactedFile(fileStatus)"
|
||||
<redaction-file-download-btn
|
||||
(menuStateChanged)="actionMenuOpen = $event === 'OPEN'"
|
||||
[tooltipClass]="'small'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="buttonType"
|
||||
icon="red:download"
|
||||
tooltip="project-overview.download-redacted-file"
|
||||
[project]="appStateService.activeProject"
|
||||
[file]="fileStatus"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<!-- file state actions -->
|
||||
</redaction-file-download-btn>
|
||||
|
||||
<!-- Ready for approval-->
|
||||
<redaction-circle-button
|
||||
|
||||
@ -4,8 +4,7 @@ import { FileStatusWrapper } from '../../screens/file/model/file-status.wrapper'
|
||||
import { DialogService } from '../../dialogs/dialog.service';
|
||||
import { AppStateService } from '../../state/app-state.service';
|
||||
import { FileActionService } from '../../screens/file/service/file-action.service';
|
||||
import { FileDownloadService } from '../../screens/file/service/file-download.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { SingleFileDownloadService } from '../../screens/file/service/single-file-download.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-actions',
|
||||
@ -24,7 +23,7 @@ export class FileActionsComponent implements OnInit {
|
||||
public readonly appStateService: AppStateService,
|
||||
private readonly _dialogService: DialogService,
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _fileDownloadService: FileDownloadService
|
||||
private readonly _fileDownloadService: SingleFileDownloadService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -94,11 +93,4 @@ export class FileActionsComponent implements OnInit {
|
||||
this.actionPerformed.emit(action);
|
||||
});
|
||||
}
|
||||
|
||||
downloadFile($event: MouseEvent, fileStatus: FileStatusWrapper) {
|
||||
$event.stopPropagation();
|
||||
this._fileDownloadService.loadFile('REDACTED', fileStatus).subscribe((data) => {
|
||||
saveAs(data, fileStatus.filename);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
<redaction-circle-button
|
||||
*ngIf="canDownloadRedactedFiles"
|
||||
[matMenuTriggerFor]="menu"
|
||||
(click)="openMenu($event)"
|
||||
[tooltipClass]="tooltipClass"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="type"
|
||||
[tooltip]="'project-overview.download-file'"
|
||||
icon="red:download"
|
||||
></redaction-circle-button>
|
||||
|
||||
<mat-menu #menu="matMenu" xPosition="before" (closed)="onMenuClosed()">
|
||||
<div (click)="downloadRedactedFilesPreview($event)" mat-menu-item>
|
||||
<div [translate]="'project-overview.download-redacted-file-preview'"></div>
|
||||
</div>
|
||||
<div (click)="downloadRedactedFiles($event)" mat-menu-item>
|
||||
<div [translate]="'project-overview.download-redacted-file'"></div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
@ -0,0 +1,86 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { PermissionsService } from '../../../common/service/permissions.service';
|
||||
import { ProjectWrapper } from '../../../state/model/project.wrapper';
|
||||
import { FileStatusWrapper } from '../../../screens/file/model/file-status.wrapper';
|
||||
import { FileManagementControllerService } from '@redaction/red-ui-http';
|
||||
import { StatusOverlayService } from '../../../upload-download/status-overlay.service';
|
||||
import { FileDownloadService } from '../../../upload-download/file-download.service';
|
||||
import { SingleFileDownloadService } from '../../../screens/file/service/single-file-download.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
export type MenuState = 'OPEN' | 'CLOSED';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-download-btn',
|
||||
templateUrl: './file-download-btn.component.html',
|
||||
styleUrls: ['./file-download-btn.component.scss']
|
||||
})
|
||||
export class FileDownloadBtnComponent {
|
||||
@Input() project: ProjectWrapper;
|
||||
@Input() file: FileStatusWrapper | FileStatusWrapper[];
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Input() tooltipClass: string;
|
||||
|
||||
@Output() menuStateChanged = new EventEmitter<MenuState>();
|
||||
|
||||
constructor(
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
private readonly _singleFileDownloadService: SingleFileDownloadService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _statusOverlayService: StatusOverlayService,
|
||||
private readonly _fileManagementControllerService: FileManagementControllerService
|
||||
) {}
|
||||
|
||||
openMenu($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.menuStateChanged.emit('OPEN');
|
||||
}
|
||||
|
||||
onMenuClosed() {
|
||||
this.menuStateChanged.emit('CLOSED');
|
||||
}
|
||||
|
||||
get canDownloadRedactedFiles() {
|
||||
if (Array.isArray(this.file)) {
|
||||
return this.file.reduce((acc, file) => acc && this._permissionsService.canDownloadRedactedFile(file), true);
|
||||
} else {
|
||||
return this._permissionsService.canDownloadRedactedFile(this.file);
|
||||
}
|
||||
}
|
||||
|
||||
downloadRedactedFilesPreview($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
if (Array.isArray(this.file)) {
|
||||
// Bulk Download
|
||||
this._fileDownloadService.downloadProjectFiles(
|
||||
this.file.map((file) => file.fileId),
|
||||
this.project,
|
||||
'PREVIEW'
|
||||
);
|
||||
this._statusOverlayService.openDownloadStatusOverlay();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
} else {
|
||||
this._fileManagementControllerService
|
||||
.downloadPreviewFile(this.file.fileId, true, 'body')
|
||||
.subscribe((data) => saveAs(data, (<FileStatusWrapper>this.file).filename));
|
||||
}
|
||||
}
|
||||
|
||||
downloadRedactedFiles($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
if (Array.isArray(this.file)) {
|
||||
// Bulk Download
|
||||
this._fileDownloadService.downloadProjectFiles(
|
||||
this.file.map((file) => file.fileId),
|
||||
this.project,
|
||||
'REDACTED'
|
||||
);
|
||||
this._statusOverlayService.openDownloadStatusOverlay();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
} else {
|
||||
this._singleFileDownloadService.loadFile('REDACTED', this.file).subscribe((data) => saveAs(data, (<FileStatusWrapper>this.file).filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<redaction-circle-button
|
||||
*ngIf="project && permissionsService.isManagerAndOwner(project)"
|
||||
[matMenuTriggerFor]="menu"
|
||||
(click)="openReportMenu($event)"
|
||||
(click)="openMenu($event)"
|
||||
[tooltipClass]="tooltipClass"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="type"
|
||||
|
||||
@ -24,7 +24,7 @@ export class ReportDownloadBtnComponent implements OnInit {
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
openReportMenu($event: MouseEvent) {
|
||||
openMenu($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.menuStateChanged.emit('OPEN');
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@an
|
||||
import { PermissionsService } from '../../../common/service/permissions.service';
|
||||
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { FileDownloadService } from '../../file/service/file-download.service';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
@ -54,7 +53,6 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _watermarkControllerService: WatermarkControllerService,
|
||||
private readonly _notificationService: NotificationService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
private readonly _http: HttpClient,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
|
||||
@ -5,7 +5,6 @@ import { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
||||
import { debounce } from '../../../utils/debounce';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { FileDownloadService } from '../service/file-download.service';
|
||||
import { DialogService } from '../../../dialogs/dialog.service';
|
||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||
import { ManualRedactionEntryWrapper } from '../model/manual-redaction-entry.wrapper';
|
||||
@ -28,6 +27,7 @@ import { UserPreferenceService } from '../../../common/service/user-preference.s
|
||||
import { UserService } from '../../../user/user.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { SingleFileDownloadService } from '../service/single-file-download.service';
|
||||
|
||||
const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'f', 'F'];
|
||||
|
||||
@ -78,7 +78,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
|
||||
private readonly _annotationDrawService: AnnotationDrawService,
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _manualAnnotationService: ManualAnnotationService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
private readonly _fileDownloadService: SingleFileDownloadService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _statusControllerService: StatusControllerService,
|
||||
private readonly ngZone: NgZone
|
||||
|
||||
@ -16,7 +16,6 @@ import { AppConfigService } from '../../../app-config/app-config.service';
|
||||
import { ManualRedactionEntry, Rectangle } from '@redaction/red-ui-http';
|
||||
import WebViewer, { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FileDownloadService } from '../service/file-download.service';
|
||||
import { ManualRedactionEntryWrapper } from '../model/manual-redaction-entry.wrapper';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { AnnotationWrapper } from '../model/annotation.wrapper';
|
||||
@ -27,6 +26,8 @@ import { environment } from '../../../../environments/environment';
|
||||
import { AnnotationDrawService } from '../service/annotation-draw.service';
|
||||
import { AnnotationActionsService } from '../../../common/service/annotation-actions.service';
|
||||
import { UserPreferenceService } from '../../../common/service/user-preference.service';
|
||||
import { translateQuads } from '../../../utils/pdf-coordinates';
|
||||
import { SingleFileDownloadService } from '../service/single-file-download.service';
|
||||
|
||||
export interface ViewerState {
|
||||
displayMode?: any;
|
||||
@ -72,7 +73,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
||||
private readonly kc: KeycloakService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
private readonly _fileDownloadService: SingleFileDownloadService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
private readonly _manualAnnotationService: ManualAnnotationService,
|
||||
private readonly _ngZone: NgZone,
|
||||
@ -294,7 +295,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text);
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE'));
|
||||
}
|
||||
});
|
||||
@ -308,7 +309,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text);
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'DICTIONARY'));
|
||||
}
|
||||
});
|
||||
@ -321,7 +322,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text);
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'REDACTION'));
|
||||
}
|
||||
});
|
||||
@ -339,20 +340,25 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
private _getManualRedactionEntry(quads: any, text: string): ManualRedactionEntry {
|
||||
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): ManualRedactionEntry {
|
||||
text = text.replace(/-\n/gi, '');
|
||||
const entry: ManualRedactionEntry = { positions: [] };
|
||||
for (const key of Object.keys(quads)) {
|
||||
for (const quad of quads[key]) {
|
||||
entry.positions.push(this.toPosition(parseInt(key, 10), quad));
|
||||
const page = parseInt(key, 10);
|
||||
entry.positions.push(this.toPosition(page, convertQuads ? this._translateQuads(page, quad) : quad));
|
||||
}
|
||||
}
|
||||
entry.value = text;
|
||||
return entry;
|
||||
}
|
||||
|
||||
private _translateQuads(page: number, quads: any) {
|
||||
const rotation = this.instance.docViewer.getCompleteRotation(page);
|
||||
return translateQuads(page, rotation, quads);
|
||||
}
|
||||
|
||||
private toPosition(page: number, selectedQuad: any): Rectangle {
|
||||
console.log(selectedQuad);
|
||||
const pageHeight = this.instance.docViewer.getPageHeight(page);
|
||||
const height = selectedQuad.y2 - selectedQuad.y4;
|
||||
return {
|
||||
|
||||
@ -16,7 +16,7 @@ import { PermissionsService } from '../../../common/service/permissions.service'
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FileDownloadService {
|
||||
export class SingleFileDownloadService {
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
@ -1,10 +1,10 @@
|
||||
import { ChangeDetectorRef, Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FileDownloadService } from '../file/service/file-download.service';
|
||||
import { DebugControllerService } from '@redaction/red-ui-http';
|
||||
import { FileType } from '../file/model/file-type';
|
||||
import { FileStatusWrapper } from '../file/model/file-status.wrapper';
|
||||
import { mergeMap } from 'rxjs/operators';
|
||||
import { SingleFileDownloadService } from '../file/service/single-file-download.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-html-debug-screen',
|
||||
@ -21,7 +21,7 @@ export class HtmlDebugScreenComponent {
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _debugControllerService: DebugControllerService,
|
||||
private readonly _fileDownloadService: FileDownloadService
|
||||
private readonly _fileDownloadService: SingleFileDownloadService
|
||||
) {
|
||||
this._activatedRoute.params.subscribe((params) => {
|
||||
this._fileId = params.fileId;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { FileDownloadService } from '../file/service/file-download.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FileType } from '../file/model/file-type';
|
||||
import { FileStatusWrapper } from '../file/model/file-status.wrapper';
|
||||
import { SingleFileDownloadService } from '../file/service/single-file-download.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-pdf-viewer-screen',
|
||||
@ -22,7 +22,7 @@ export class PdfViewerScreenComponent implements OnInit {
|
||||
constructor(
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _fileDownloadService: FileDownloadService
|
||||
private readonly _fileDownloadService: SingleFileDownloadService
|
||||
) {
|
||||
this._activatedRoute.params.subscribe((params) => {
|
||||
this._fileId = params.fileId;
|
||||
|
||||
@ -15,13 +15,7 @@
|
||||
icon="red:assign"
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="downloadRedactedFiles()"
|
||||
*ngIf="canDownloadRedactedFiles"
|
||||
tooltip="project-overview.download-redacted-files"
|
||||
type="dark-bg"
|
||||
icon="red:download"
|
||||
></redaction-circle-button>
|
||||
<redaction-file-download-btn [project]="project" [file]="selectedFiles"> </redaction-file-download-btn>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="setToUnderApproval()"
|
||||
|
||||
@ -33,6 +33,10 @@ export class BulkActionsComponent {
|
||||
private readonly _fileDownloadService: FileDownloadService
|
||||
) {}
|
||||
|
||||
get project() {
|
||||
return this._appStateService?.activeProject;
|
||||
}
|
||||
|
||||
private get selectedFiles(): FileStatusWrapper[] {
|
||||
return this.selectedFileIds.map((fileId) => this._appStateService.getFileById(this._appStateService.activeProject.project.projectId, fileId));
|
||||
}
|
||||
@ -115,20 +119,6 @@ export class BulkActionsComponent {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true);
|
||||
}
|
||||
|
||||
get canDownloadRedactedFiles() {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDownloadRedactedFile(file), true);
|
||||
}
|
||||
|
||||
// Bulk Download
|
||||
downloadRedactedFiles() {
|
||||
this._fileDownloadService.downloadProjectFiles(
|
||||
this.selectedFiles.map((file) => file.fileId),
|
||||
this._appStateService.activeProject
|
||||
);
|
||||
this._statusOverlayService.openDownloadStatusOverlay();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
private _performBulkAction(obs: Observable<any>) {
|
||||
this.loading = true;
|
||||
obs.subscribe().add(() => {
|
||||
|
||||
@ -59,13 +59,8 @@
|
||||
<redaction-report-download-btn *ngIf="appStateService.activeProject.files.length > 0" [project]="appStateService.activeProject">
|
||||
</redaction-report-download-btn>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="downloadRedactedFiles()"
|
||||
*ngIf="canDownloadRedactedFiles"
|
||||
tooltip="project-overview.header-actions.download-redacted-files"
|
||||
tooltipPosition="below"
|
||||
icon="red:download"
|
||||
></redaction-circle-button>
|
||||
<redaction-file-download-btn [project]="appStateService.activeProject" [file]="appStateService.activeProject.files"> </redaction-file-download-btn>
|
||||
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.displayReanalyseBtn()"
|
||||
(action)="reanalyseProject()"
|
||||
|
||||
@ -378,21 +378,4 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
public toggleCollapsedDetails() {
|
||||
this.collapsedDetails = !this.collapsedDetails;
|
||||
}
|
||||
|
||||
// Download Files
|
||||
public downloadRedactedFiles() {
|
||||
this._fileDownloadService.downloadProjectFiles(
|
||||
this.appStateService.activeProject.files.map((file) => file.fileId),
|
||||
this.appStateService.activeProject
|
||||
);
|
||||
this._statusOverlayService.openDownloadStatusOverlay();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
public get canDownloadRedactedFiles() {
|
||||
return (
|
||||
this.appStateService.activeProject.files.length > 0 &&
|
||||
this.appStateService.activeProject.files.reduce((acc, file) => acc && this.permissionsService.canDownloadRedactedFile(file), true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,8 +34,8 @@ export class FileDownloadService {
|
||||
});
|
||||
}
|
||||
|
||||
public downloadProjectFiles(fileIds: string[], project: ProjectWrapper): void {
|
||||
const item = { project, fileIds, completed: false, error: null };
|
||||
public downloadProjectFiles(fileIds: string[], project: ProjectWrapper, type: 'REDACTED' | 'PREVIEW'): void {
|
||||
const item = { project, fileIds, type, completed: false, error: null };
|
||||
this.downloads.push(item);
|
||||
this.scheduleDownload(item);
|
||||
}
|
||||
@ -68,12 +68,22 @@ export class FileDownloadService {
|
||||
|
||||
private _createSubscription(downloadModel: ProjectDownloadModel) {
|
||||
this.activeDownloadsCnt++;
|
||||
const obs = this._fileManagementControllerService.downloadRedactedFiles(
|
||||
{ fileIds: downloadModel.fileIds },
|
||||
downloadModel.project.projectId,
|
||||
false,
|
||||
'response'
|
||||
);
|
||||
let obs;
|
||||
if (downloadModel.type === 'REDACTED') {
|
||||
obs = this._fileManagementControllerService.downloadRedactedFiles(
|
||||
{ fileIds: downloadModel.fileIds },
|
||||
downloadModel.project.projectId,
|
||||
false,
|
||||
'response'
|
||||
);
|
||||
} else {
|
||||
obs = this._fileManagementControllerService.downloadPreviewFiles(
|
||||
{ fileIds: downloadModel.fileIds },
|
||||
downloadModel.project.projectId,
|
||||
false,
|
||||
'response'
|
||||
);
|
||||
}
|
||||
const subscription = obs.subscribe(
|
||||
async (event) => {
|
||||
if (event.status < 300) {
|
||||
|
||||
@ -5,4 +5,5 @@ export interface ProjectDownloadModel {
|
||||
project: ProjectWrapper;
|
||||
completed: boolean;
|
||||
error: any;
|
||||
type: 'REDACTED' | 'PREVIEW';
|
||||
}
|
||||
|
||||
53
apps/red-ui/src/app/utils/pdf-coordinates.ts
Normal file
53
apps/red-ui/src/app/utils/pdf-coordinates.ts
Normal file
@ -0,0 +1,53 @@
|
||||
enum PageRotation {
|
||||
E_0 = 0,
|
||||
E_90 = 1,
|
||||
E_180 = 2,
|
||||
E_270 = 3
|
||||
}
|
||||
|
||||
export function translateQuads(page: number, rotation: number, quads: any) {
|
||||
let result;
|
||||
switch (rotation) {
|
||||
case PageRotation.E_90:
|
||||
result = {
|
||||
x1: quads.x2,
|
||||
x2: quads.x3,
|
||||
x3: quads.x4,
|
||||
x4: quads.x1,
|
||||
y1: quads.y2,
|
||||
y2: quads.y3,
|
||||
y3: quads.y4,
|
||||
y4: quads.y1
|
||||
};
|
||||
break;
|
||||
case PageRotation.E_180:
|
||||
result = {
|
||||
x1: quads.x3,
|
||||
x2: quads.x4,
|
||||
x3: quads.x1,
|
||||
x4: quads.x2,
|
||||
y1: quads.y3,
|
||||
y2: quads.y4,
|
||||
y3: quads.y1,
|
||||
y4: quads.y2
|
||||
};
|
||||
break;
|
||||
case PageRotation.E_270:
|
||||
result = {
|
||||
x1: quads.x4,
|
||||
x2: quads.x1,
|
||||
x3: quads.x2,
|
||||
x4: quads.x3,
|
||||
y1: quads.y4,
|
||||
y2: quads.y1,
|
||||
y3: quads.y2,
|
||||
y4: quads.y3
|
||||
};
|
||||
break;
|
||||
case PageRotation.E_0:
|
||||
default:
|
||||
result = quads;
|
||||
}
|
||||
console.log(quads, result);
|
||||
return result;
|
||||
}
|
||||
@ -197,8 +197,9 @@
|
||||
"upload-document": "Upload Document",
|
||||
"download-redacted-files": "Download Redacted Files"
|
||||
},
|
||||
"download-redacted-file": "Download Redacted File",
|
||||
"download-redacted-files": "Download Redacted Files",
|
||||
"download-file": "Download File(s)",
|
||||
"download-redacted-file": "Download Redacted File(s)",
|
||||
"download-redacted-file-preview": "Download Redacted File(s) Preview",
|
||||
"under-approval": "For Approval",
|
||||
"approve": "Approve",
|
||||
"under-review": "Under Review",
|
||||
|
||||
@ -146,6 +146,138 @@ export class FileManagementControllerService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a downloadable byte stream of the redaction preview file with the specified fileId
|
||||
* Use the optional \"inline\" request parameter to select, if this downloadAnnotated will be opened in the browser.
|
||||
* @param fileId fileId
|
||||
* @param inline inline
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public downloadPreviewFile(fileId: string, inline?: boolean, observe?: 'body', reportProgress?: boolean): Observable<any>;
|
||||
public downloadPreviewFile(fileId: string, inline?: boolean, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
|
||||
public downloadPreviewFile(fileId: string, inline?: boolean, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
|
||||
public downloadPreviewFile(fileId: string, inline?: boolean, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error('Required parameter fileId was null or undefined when calling downloadPreviewFile.');
|
||||
}
|
||||
|
||||
let queryParameters = new HttpParams({ encoder: new CustomHttpUrlEncodingCodec() });
|
||||
if (inline !== undefined && inline !== null) {
|
||||
queryParameters = queryParameters.set('inline', <any>inline);
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken = typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['*/*'];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = [];
|
||||
|
||||
return this.httpClient.request('get', `${this.basePath}/download/preview/${encodeURIComponent(String(fileId))}`, {
|
||||
responseType: 'blob',
|
||||
params: queryParameters,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a downloadable byte stream of the requested files in a zip format
|
||||
* Use the optional \"inline\" request parameter to select, if this report will be opened in the browser.
|
||||
* @param body bulkDownloadRedactedRequest
|
||||
* @param projectId The projectId
|
||||
* @param inline inline
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public downloadPreviewFiles(
|
||||
body: BulkDownloadRedactedRequest,
|
||||
projectId: string,
|
||||
inline?: boolean,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<any>;
|
||||
public downloadPreviewFiles(
|
||||
body: BulkDownloadRedactedRequest,
|
||||
projectId: string,
|
||||
inline?: boolean,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<any>>;
|
||||
public downloadPreviewFiles(
|
||||
body: BulkDownloadRedactedRequest,
|
||||
projectId: string,
|
||||
inline?: boolean,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<any>>;
|
||||
public downloadPreviewFiles(
|
||||
body: BulkDownloadRedactedRequest,
|
||||
projectId: string,
|
||||
inline?: boolean,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
if (body === null || body === undefined) {
|
||||
throw new Error('Required parameter body was null or undefined when calling downloadPreviewFiles.');
|
||||
}
|
||||
|
||||
if (projectId === null || projectId === undefined) {
|
||||
throw new Error('Required parameter projectId was null or undefined when calling downloadPreviewFiles.');
|
||||
}
|
||||
|
||||
let queryParameters = new HttpParams({ encoder: new CustomHttpUrlEncodingCodec() });
|
||||
if (inline !== undefined && inline !== null) {
|
||||
queryParameters = queryParameters.set('inline', <any>inline);
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken = typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['*/*'];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = ['application/json'];
|
||||
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected !== undefined) {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request('post', `${this.basePath}/download/bulk/preview/${encodeURIComponent(String(projectId))}`, {
|
||||
responseType: 'blob',
|
||||
body: body,
|
||||
params: queryParameters,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a downloadable byte stream of the annotated file with the specified fileId
|
||||
* Use the optional \"inline\" request parameter to select, if this downloadAnnotated will be opened in the browser.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user