Async Download
This commit is contained in:
parent
ceaf97414a
commit
99ff8ac6cd
@ -94,7 +94,6 @@ import { RulesScreenComponent } from './screens/admin/rules-screen/rules-screen.
|
||||
import { WatermarkScreenComponent } from './screens/admin/watermark-screen/watermark-screen.component';
|
||||
import { PdfViewerScreenComponent } from './screens/pdf-viewer-screen/pdf-viewer-screen.component';
|
||||
import { HtmlDebugScreenComponent } from './screens/html-debug-screen/html-debug-screen.component';
|
||||
import { ReportDownloadBtnComponent } from './components/buttons/report-download-btn/report-download-btn.component';
|
||||
import { ProjectListingActionsComponent } from './screens/project-listing-screen/project-listing-actions/project-listing-actions.component';
|
||||
import { HasScrollbarDirective } from './utils/has-scrollbar.directive';
|
||||
import { RuleSetsListingScreenComponent } from './screens/admin/rule-sets-listing-screen/rule-sets-listing-screen.component';
|
||||
@ -352,7 +351,6 @@ const matImports = [
|
||||
WatermarkScreenComponent,
|
||||
PdfViewerScreenComponent,
|
||||
HtmlDebugScreenComponent,
|
||||
ReportDownloadBtnComponent,
|
||||
FileDownloadBtnComponent,
|
||||
ProjectListingActionsComponent,
|
||||
RuleSetActionsComponent,
|
||||
|
||||
@ -39,20 +39,8 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<!-- download report-->
|
||||
<redaction-report-download-btn
|
||||
(menuStateChanged)="actionMenuOpen = $event === 'OPEN'"
|
||||
[tooltipClass]="'small'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[file]="fileStatus"
|
||||
[type]="buttonType"
|
||||
[project]="appStateService.activeProject"
|
||||
>
|
||||
</redaction-report-download-btn>
|
||||
|
||||
<!-- download redacted file-->
|
||||
<redaction-file-download-btn
|
||||
(menuStateChanged)="actionMenuOpen = $event === 'OPEN'"
|
||||
[tooltipClass]="'small'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="buttonType"
|
||||
|
||||
@ -196,10 +196,6 @@ export class PermissionsService {
|
||||
return !fileStatus.isError && !fileStatus.isProcessing && !fileStatus.isPending; //&& this.isReviewerOrOwner(fileStatus);
|
||||
}
|
||||
|
||||
canShowRedactionReportDownloadBtn(fileStatus?: FileStatusWrapper) {
|
||||
return this.isManagerAndOwner() && !fileStatus.isError;
|
||||
}
|
||||
|
||||
canAssignReviewer(fileStatus?: FileStatusWrapper) {
|
||||
if (!fileStatus) {
|
||||
fileStatus = this._appStateService.activeFile;
|
||||
|
||||
@ -1,22 +1,9 @@
|
||||
<redaction-circle-button
|
||||
*ngIf="canDownloadRedactedFiles"
|
||||
[matMenuTriggerFor]="menu"
|
||||
(click)="openMenu($event)"
|
||||
[disabled]="!canDownloadFiles"
|
||||
(click)="downloadFiles($event)"
|
||||
[tooltipClass]="tooltipClass"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="type"
|
||||
[tooltip]="'project-overview.download-file'"
|
||||
[tooltip]="canDownloadFiles ? 'project-overview.download-file' : 'project-overview.download-file-disabled'"
|
||||
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>
|
||||
<div (click)="downloadFlatRedactedFiles($event)" mat-menu-item *ngIf="canDownloadFlatRedactedFile">
|
||||
<div [translate]="'project-overview.download-flat-redacted-file'"></div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, Input } 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 { PdfViewerDataService } from '../../../screens/file/service/pdf-viewer-data.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { UserPreferenceService } from '../../../common/service/user-preference.service';
|
||||
|
||||
export type MenuState = 'OPEN' | 'CLOSED';
|
||||
@ -23,8 +21,6 @@ export class FileDownloadBtnComponent {
|
||||
@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,
|
||||
@ -34,16 +30,7 @@ export class FileDownloadBtnComponent {
|
||||
private readonly _fileManagementControllerService: FileManagementControllerService
|
||||
) {}
|
||||
|
||||
openMenu($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.menuStateChanged.emit('OPEN');
|
||||
}
|
||||
|
||||
onMenuClosed() {
|
||||
this.menuStateChanged.emit('CLOSED');
|
||||
}
|
||||
|
||||
get canDownloadRedactedFiles() {
|
||||
get canDownloadFiles() {
|
||||
if (Array.isArray(this.file)) {
|
||||
return this.file.reduce((acc, file) => acc && this._permissionsService.canDownloadRedactedFile(file), true);
|
||||
} else {
|
||||
@ -51,48 +38,12 @@ export class FileDownloadBtnComponent {
|
||||
}
|
||||
}
|
||||
|
||||
downloadRedactedFilesPreview($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
if (Array.isArray(this.file)) {
|
||||
// Bulk Download
|
||||
this._fileDownloadService.downloadProjectFiles(
|
||||
this.file.map((file) => file.fileId),
|
||||
this.project,
|
||||
'PREVIEW'
|
||||
);
|
||||
downloadFiles($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
// Bulk Download
|
||||
this._fileDownloadService.downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.project).subscribe((data) => {
|
||||
this._statusOverlayService.openDownloadStatusOverlay();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
} else {
|
||||
this._fileManagementControllerService
|
||||
.downloadPreviewFile(this.file.projectId, this.file.fileId, true, this.file.lastProcessed, '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));
|
||||
}
|
||||
}
|
||||
|
||||
get canDownloadFlatRedactedFile() {
|
||||
return this._userPreferencesService.areDevFeaturesEnabled && !Array.isArray(this.file);
|
||||
}
|
||||
|
||||
downloadFlatRedactedFiles($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
// this._singleFileDownloadService
|
||||
// .loadFile('FLAT_REDACTED', <FileStatusWrapper>this.file)
|
||||
// .subscribe((data) => saveAs(data, (<FileStatusWrapper>this.file).filename));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
<redaction-circle-button
|
||||
*ngIf="project && permissionsService.isManagerAndOwner(project)"
|
||||
(action)="openMenu($event)"
|
||||
(click)="$event.stopPropagation()"
|
||||
[tooltipClass]="tooltipClass"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="type"
|
||||
[tooltip]="isApproved ? 'report.action.label' : 'report.unavailable'"
|
||||
[disabled]="!isApproved"
|
||||
icon="red:report"
|
||||
></redaction-circle-button>
|
||||
<div #menuTrigger="matMenuTrigger" [matMenuTriggerFor]="menu"></div>
|
||||
|
||||
<mat-menu #menu="matMenu" xPosition="before" (closed)="onMenuClosed()">
|
||||
<div (click)="downloadRedactionReport($event, 'EFSA Template')" mat-menu-item>
|
||||
<div [translate]="'report.action.efsa'"></div>
|
||||
</div>
|
||||
<div (click)="downloadRedactionReport($event, 'Syngenta Template')" mat-menu-item>
|
||||
<div [translate]="'report.action.syngenta'"></div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
@ -1,55 +0,0 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { PermissionsService } from '../../../common/service/permissions.service';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { ProjectWrapper } from '../../../state/model/project.wrapper';
|
||||
import { FileStatusWrapper } from '../../../screens/file/model/file-status.wrapper';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
||||
export type MenuState = 'OPEN' | 'CLOSED';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-report-download-btn',
|
||||
templateUrl: './report-download-btn.component.html',
|
||||
styleUrls: ['./report-download-btn.component.scss']
|
||||
})
|
||||
export class ReportDownloadBtnComponent implements OnInit {
|
||||
@Input() project: ProjectWrapper;
|
||||
@Input() file: FileStatusWrapper;
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Input() tooltipClass: string;
|
||||
|
||||
@Output() menuStateChanged = new EventEmitter<MenuState>();
|
||||
@ViewChild('menuTrigger') menuTrigger: MatMenuTrigger;
|
||||
|
||||
constructor(public readonly permissionsService: PermissionsService, private readonly _appStateService: AppStateService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
openMenu($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.menuTrigger.openMenu();
|
||||
this.menuStateChanged.emit('OPEN');
|
||||
}
|
||||
|
||||
onMenuClosed() {
|
||||
this.menuStateChanged.emit('CLOSED');
|
||||
}
|
||||
|
||||
get isApproved() {
|
||||
if (this.file) {
|
||||
return this.file.isApproved;
|
||||
} else {
|
||||
return this.project.allFilesApproved;
|
||||
}
|
||||
}
|
||||
|
||||
downloadRedactionReport($event: MouseEvent, template: string) {
|
||||
$event.preventDefault();
|
||||
if (this.file) {
|
||||
this._appStateService.downloadFileRedactionReport(this.file, template);
|
||||
} else {
|
||||
this._appStateService.downloadRedactionReport(this.project, template);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
<section *ngIf="appStateService.activeFile">
|
||||
<section *ngIf="appStateService.activeFile" [class.fullscreen]="fullScreen">
|
||||
<div class="page-header">
|
||||
<div class="flex-1">
|
||||
<div
|
||||
@ -150,7 +150,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="red-content-inner" [class.fullscreen]="fullScreen">
|
||||
<div class="red-content-inner">
|
||||
<div class="left-container">
|
||||
<div class="overlay-shadow"></div>
|
||||
<redaction-pdf-viewer
|
||||
|
||||
@ -29,7 +29,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { PdfViewerDataService } from '../service/pdf-viewer-data.service';
|
||||
|
||||
const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'f', 'F'];
|
||||
const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'f', 'F', 'Escape'];
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-screen',
|
||||
@ -139,6 +139,12 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
document.documentElement.addEventListener('fullscreenchange', (event) => {
|
||||
if (!document.fullscreenElement) {
|
||||
this.fullScreen = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.filesAutoUpdateTimer = timer(0, 5000)
|
||||
.pipe(
|
||||
tap(async () => {
|
||||
@ -285,6 +291,11 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
|
||||
|
||||
public toggleFullScreen() {
|
||||
this.fullScreen = !this.fullScreen;
|
||||
if (this.fullScreen) {
|
||||
this._openFullScreen();
|
||||
} else {
|
||||
this._closeFullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:keyup', ['$event'])
|
||||
@ -293,6 +304,11 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
if (['Escape'].includes($event.key)) {
|
||||
this.fullScreen = false;
|
||||
this._closeFullScreen();
|
||||
}
|
||||
|
||||
if (['f', 'F'].includes($event.key)) {
|
||||
this.toggleFullScreen();
|
||||
return;
|
||||
@ -575,6 +591,23 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
|
||||
this.selectPage($event);
|
||||
}
|
||||
|
||||
/* Get the documentElement (<html>) to display the page in fullscreen */
|
||||
|
||||
/* View in fullscreen */
|
||||
private _openFullScreen() {
|
||||
const documentElement = document.documentElement;
|
||||
if (documentElement.requestFullscreen) {
|
||||
documentElement.requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
/* Close fullscreen */
|
||||
private _closeFullScreen() {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
// <!-- Dev Mode Features-->
|
||||
async openSSRFilePreview() {
|
||||
window.open(`/pdf-preview/${this.projectId}/${this.fileId}`, '_blank');
|
||||
|
||||
@ -18,9 +18,6 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-report-download-btn *ngIf="project.files.length > 0" (menuStateChanged)="actionMenuOpen = $event === 'OPEN'" [project]="project">
|
||||
</redaction-report-download-btn>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="openAssignProjectOwnerDialog($event, project)"
|
||||
*ngIf="permissionsService.isManager()"
|
||||
@ -39,6 +36,5 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-file-download-btn (menuStateChanged)="actionMenuOpen = $event === 'OPEN'" [file]="project.files" [project]="project">
|
||||
</redaction-file-download-btn>
|
||||
<redaction-file-download-btn [file]="project.files" [project]="project"> </redaction-file-download-btn>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,6 @@ import { FileStatusWrapper } from '../../file/model/file-status.wrapper';
|
||||
import { FileActionService } from '../../file/service/file-action.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { StatusOverlayService } from '../../../upload-download/status-overlay.service';
|
||||
import { FileDownloadService } from '../../../upload-download/file-download.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-bulk-actions',
|
||||
@ -29,8 +28,7 @@ export class BulkActionsComponent {
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _statusOverlayService: StatusOverlayService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _fileDownloadService: FileDownloadService
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
get project() {
|
||||
|
||||
@ -56,9 +56,6 @@
|
||||
icon="red:assign"
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-report-download-btn *ngIf="appStateService.activeProject.files.length > 0" [project]="appStateService.activeProject">
|
||||
</redaction-report-download-btn>
|
||||
|
||||
<redaction-file-download-btn [project]="appStateService.activeProject" [file]="appStateService.activeProject.files"> </redaction-file-download-btn>
|
||||
|
||||
<redaction-circle-button
|
||||
|
||||
@ -6,7 +6,6 @@ import { FileDropOverlayService } from '../../upload-download/file-drop/service/
|
||||
import { FileUploadModel } from '../../upload-download/model/file-upload.model';
|
||||
import { FileUploadService } from '../../upload-download/file-upload.service';
|
||||
import { StatusOverlayService } from '../../upload-download/status-overlay.service';
|
||||
import { computerize, humanize } from '../../utils/functions';
|
||||
import { DialogService } from '../../dialogs/dialog.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FileActionService } from '../file/service/file-action.service';
|
||||
@ -25,10 +24,8 @@ import { RedactionFilterSorter } from '../../common/sorters/redaction-filter-sor
|
||||
import { StatusSorter } from '../../common/sorters/status-sorter';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounce } from '../../utils/debounce';
|
||||
import { download } from '../../utils/file-download-utils';
|
||||
import { convertFiles, handleFileDrop } from '../../utils/file-drop-utils';
|
||||
import { FilterComponent } from '../../common/filter/filter.component';
|
||||
import { FileDownloadService } from '../../upload-download/file-download.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-overview-screen',
|
||||
@ -68,7 +65,6 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
private readonly _dialogService: DialogService,
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _fileUploadService: FileUploadService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
private readonly _statusOverlayService: StatusOverlayService,
|
||||
private readonly _router: Router,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
|
||||
@ -321,15 +321,6 @@ export class AppStateService {
|
||||
await this._reanalysisControllerService.reanalyzeProject(project.projectId).toPromise();
|
||||
}
|
||||
|
||||
downloadRedactionReport(project?: ProjectWrapper, template?: string) {
|
||||
if (!project) {
|
||||
project = this.activeProject;
|
||||
}
|
||||
this._fileManagementControllerService.downloadRedactionReportForProject(project.projectId, true, template, 'body').subscribe((data) => {
|
||||
saveAs(data, 'redaction-report-' + project.projectName + '.docx');
|
||||
});
|
||||
}
|
||||
|
||||
activateProject(projectId: string) {
|
||||
this._appState.activeFileId = null;
|
||||
this._appState.activeProjectId = projectId;
|
||||
@ -468,15 +459,6 @@ export class AppStateService {
|
||||
}
|
||||
}
|
||||
|
||||
downloadFileRedactionReport(file?: FileStatusWrapper, template?: string) {
|
||||
if (!file) {
|
||||
file = this.activeFile;
|
||||
}
|
||||
this._fileManagementControllerService.downloadRedactionReport({ fileIds: [file.fileId] }, file.projectId, true, template, 'body').subscribe((data) => {
|
||||
saveAs(data, 'redaction-report-' + file.filename + '.docx');
|
||||
});
|
||||
}
|
||||
|
||||
async loadDictionaryDataIfNecessary() {
|
||||
if (!this._dictionaryData) {
|
||||
await this.loadDictionaryData();
|
||||
|
||||
@ -15,47 +15,23 @@
|
||||
</div>
|
||||
<div [hidden]="collapsed">
|
||||
<div class="upload-download-list">
|
||||
<div *ngFor="let model of downloadService.downloads" class="upload-download-list-item">
|
||||
<div *ngFor="let model of downloadService.pendingDownloads" class="upload-download-list-item">
|
||||
<div class="upload-download-line">
|
||||
<div
|
||||
matTooltipPosition="above"
|
||||
[matTooltip]="'download-status.dialog.tooltip' | translate: { len: model.fileIds.length }"
|
||||
[matTooltip]="'download-status.dialog.tooltip' | translate: { len: model.downloadDetails.fileIds.length }"
|
||||
class="upload-download-item-name"
|
||||
>
|
||||
{{ model.project.name }}
|
||||
{{ model.filename }}
|
||||
</div>
|
||||
<mat-spinner *ngIf="!model.completed" class="upload-download-progress" diameter="15" color="primary"></mat-spinner>
|
||||
<div *ngIf="model.completed && model.error" class="upload-download-progress error">
|
||||
<mat-spinner *ngIf="!ready(model)" class="upload-download-progress" diameter="15" color="primary"></mat-spinner>
|
||||
<div *ngIf="hasError(model)" class="upload-download-progress error">
|
||||
<mat-icon svgIcon="red:error"></mat-icon>
|
||||
</div>
|
||||
<div *ngIf="model.completed && !model.error" class="upload-download-progress ok">
|
||||
<div *ngIf="successful(model)" class="upload-download-progress ok">
|
||||
<mat-icon svgIcon="red:check"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="model.completed && model.error" class="upload-download-line">
|
||||
<div matTooltipPosition="above" [matTooltip]="model.error.message" class="upload-download-item-name error">
|
||||
{{ model.error.message }}
|
||||
</div>
|
||||
|
||||
<div class="upload-download-progress">
|
||||
<div
|
||||
(click)="downloadItem(model)"
|
||||
[matTooltip]="'download-status.dialog.actions.re-download' | translate"
|
||||
matTooltipPosition="above"
|
||||
class="error-action pointer"
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</div>
|
||||
<div
|
||||
(click)="cancelItem(model)"
|
||||
[matTooltip]="'download-status.dialog.actions.cancel' | translate"
|
||||
matTooltipPosition="above"
|
||||
class="error-action pointer"
|
||||
>
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { OverlayRef } from '@angular/cdk/overlay';
|
||||
import { FileDownloadService } from '../file-download.service';
|
||||
import { ProjectDownloadModel } from '../model/project-download.model';
|
||||
import { DownloadStatus } from '@redaction/red-ui-http';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-download-status-overlay',
|
||||
@ -22,28 +22,29 @@ export class DownloadStatusOverlay implements OnInit {
|
||||
ngOnInit() {
|
||||
this.downloadStatusInterval = setInterval(() => {
|
||||
// keep only errors
|
||||
this.downloadService.downloads = this.downloadService.downloads.filter((projectDownload) => !projectDownload.completed || projectDownload.error);
|
||||
if (this.downloadService.downloads.length === 0) {
|
||||
if (this.downloadService.pendingDownloads.length === 0) {
|
||||
this.closeDialog();
|
||||
}
|
||||
}, 2500);
|
||||
}
|
||||
|
||||
cancelItem(item: ProjectDownloadModel) {
|
||||
this.downloadService.removeProject(item);
|
||||
}
|
||||
|
||||
downloadItem(item: ProjectDownloadModel) {
|
||||
this.downloadService.scheduleDownload(item);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
closeDialog() {
|
||||
if (this.downloadStatusInterval) {
|
||||
clearInterval(this.downloadStatusInterval);
|
||||
this.downloadStatusInterval = null;
|
||||
}
|
||||
this.downloadService.stopAllDownloads();
|
||||
this._overlayRef.detach();
|
||||
}
|
||||
|
||||
ready(downloadStatus: DownloadStatus) {
|
||||
return downloadStatus.status === 'READY' || downloadStatus.status === 'FAILED';
|
||||
}
|
||||
|
||||
successful(downloadStatus: DownloadStatus) {
|
||||
return downloadStatus.status === 'READY' && downloadStatus.lastDownload;
|
||||
}
|
||||
|
||||
hasError(downloadStatus: DownloadStatus) {
|
||||
return downloadStatus.status === 'FAILED';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,123 +1,77 @@
|
||||
import { ApplicationRef, Injectable } from '@angular/core';
|
||||
import { AppStateService } from '../state/app-state.service';
|
||||
import { FileManagementControllerService } from '@redaction/red-ui-http';
|
||||
import { interval, Subscription } from 'rxjs';
|
||||
import { DownloadControllerService, DownloadStatus, FileManagementControllerService } from '@redaction/red-ui-http';
|
||||
import { interval, Observable } from 'rxjs';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DialogService } from '../dialogs/dialog.service';
|
||||
import { download } from '../utils/file-download-utils';
|
||||
import { computerize } from '../utils/functions';
|
||||
import { ProjectDownloadModel } from './model/project-download.model';
|
||||
import { ProjectWrapper } from '../state/model/project.wrapper';
|
||||
import { FileStatusWrapper } from '../screens/file/model/file-status.wrapper';
|
||||
import { mergeMap, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FileDownloadService {
|
||||
static readonly MAX_PARALLEL_DOWNLOADS = 2;
|
||||
|
||||
activeDownloadsCnt = 0;
|
||||
|
||||
public downloads: ProjectDownloadModel[] = [];
|
||||
private _pendingDownloads: ProjectDownloadModel[] = [];
|
||||
private _activeDownloads: Subscription[] = [];
|
||||
public downloads: DownloadStatus[] = [];
|
||||
public pendingDownloads: DownloadStatus[] = [];
|
||||
private inProgressDownloads = new Set<string>();
|
||||
|
||||
constructor(
|
||||
private readonly _applicationRef: ApplicationRef,
|
||||
private readonly _downloadControllerService: DownloadControllerService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
private readonly _fileManagementControllerService: FileManagementControllerService,
|
||||
private readonly _dialogService: DialogService
|
||||
) {
|
||||
interval(2500).subscribe((val) => {
|
||||
this._handleDownloads();
|
||||
this._getDownloadStatus().subscribe(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
stopAllDownloads() {
|
||||
this.downloads = [];
|
||||
}
|
||||
|
||||
public scheduleDownload(item: ProjectDownloadModel) {
|
||||
item.completed = false;
|
||||
item.error = null;
|
||||
this._pendingDownloads.push(item);
|
||||
}
|
||||
|
||||
private _handleDownloads() {
|
||||
if (this._activeDownloads.length < FileDownloadService.MAX_PARALLEL_DOWNLOADS && this._pendingDownloads.length > 0) {
|
||||
let cnt = FileDownloadService.MAX_PARALLEL_DOWNLOADS - this._activeDownloads.length;
|
||||
while (cnt > 0) {
|
||||
cnt--;
|
||||
const popped = this._pendingDownloads.shift();
|
||||
if (popped) {
|
||||
const sub = this._createSubscription(popped);
|
||||
this._activeDownloads.push(sub);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _createSubscription(downloadModel: ProjectDownloadModel) {
|
||||
this.activeDownloadsCnt++;
|
||||
let obs;
|
||||
if (downloadModel.type === 'REDACTED') {
|
||||
obs = this._fileManagementControllerService.downloadRedactedFiles(
|
||||
{ fileIds: downloadModel.fileIds },
|
||||
downloadModel.project.projectId,
|
||||
false,
|
||||
'response'
|
||||
downloadFiles(fileStatusWrappers: FileStatusWrapper[], project: ProjectWrapper): Observable<any> {
|
||||
return this._downloadControllerService
|
||||
.prepareDownload({
|
||||
fileIds: fileStatusWrappers.map((f) => f.fileId),
|
||||
projectId: project.projectId,
|
||||
reportTypes: ['MULTI_FILE_EFSA_TEMPLATE', 'MULTI_FILE_SYNGENTA_TEMPLATE'],
|
||||
downloadFileTypes: ['PREVIEW', 'REDACTED', 'FLATTEN']
|
||||
})
|
||||
.pipe(
|
||||
mergeMap(() => {
|
||||
return this._getDownloadStatus();
|
||||
})
|
||||
);
|
||||
} else {
|
||||
obs = this._fileManagementControllerService.downloadPreviewFiles(
|
||||
{ fileIds: downloadModel.fileIds },
|
||||
downloadModel.project.projectId,
|
||||
false,
|
||||
'response'
|
||||
);
|
||||
}
|
||||
const subscription = obs.subscribe(
|
||||
async (event) => {
|
||||
if (event.status < 300) {
|
||||
downloadModel.completed = true;
|
||||
if (this.downloads.indexOf(downloadModel) !== -1) {
|
||||
download(event, 'redacted_files_' + computerize(downloadModel.project.name) + '.zip');
|
||||
}
|
||||
|
||||
private _getDownloadStatus() {
|
||||
return this._downloadControllerService.getDownloadStatus().pipe(
|
||||
tap((statusResponse) => {
|
||||
this.downloads = statusResponse.downloadStatus;
|
||||
this.downloads.forEach((d) => {
|
||||
if (!d.lastDownload && d.status === 'READY') {
|
||||
this.inProgressDownloads.add(d.storageId);
|
||||
this.performDownload(d);
|
||||
}
|
||||
} else {
|
||||
downloadModel.completed = true;
|
||||
downloadModel.error = { message: this._translateService.instant('download-status.error.generic') };
|
||||
}
|
||||
this._removeDownload(subscription);
|
||||
},
|
||||
() => {
|
||||
downloadModel.completed = true;
|
||||
downloadModel.error = { message: this._translateService.instant('download-status.error.generic') };
|
||||
this._removeDownload(subscription);
|
||||
}
|
||||
});
|
||||
this.pendingDownloads = this.downloads.filter((d) => !d.lastDownload && !this.inProgressDownloads.has(d.storageId));
|
||||
})
|
||||
);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
private _removeDownload(subscription: Subscription) {
|
||||
const index = this._activeDownloads.indexOf(subscription);
|
||||
if (index > -1) {
|
||||
this._activeDownloads.splice(index, 1);
|
||||
this.activeDownloadsCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
removeProject(item: ProjectDownloadModel) {
|
||||
const index = this.downloads.indexOf(item);
|
||||
if (index > -1) {
|
||||
this.downloads.splice(index, 1);
|
||||
}
|
||||
public performDownload(status: DownloadStatus) {
|
||||
this._downloadControllerService
|
||||
.downloadFile(
|
||||
{
|
||||
storageId: status.storageId
|
||||
},
|
||||
false,
|
||||
'response'
|
||||
)
|
||||
.subscribe((response) => {
|
||||
download(response, status.filename);
|
||||
this.inProgressDownloads.delete(status.storageId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,21 +9,44 @@
|
||||
"app-name": "DDA-R",
|
||||
"dev-mode": "[DEV-MODUS]",
|
||||
"upload-status": {
|
||||
"error": { "file-size": "Datei zu groß. Das Limit ist {{Größe}} MB.", "generic": "Datei konnte nicht hochgeladen werden ..." },
|
||||
"dialog": { "title": "Datei-Uploads ({{len}})", "actions": { "re-upload": "Wiederholen Sie den Upload", "cancel": "Upload abbrechen" } }
|
||||
"error": {
|
||||
"file-size": "Datei zu groß. Das Limit ist {{Größe}} MB.",
|
||||
"generic": "Datei konnte nicht hochgeladen werden ..."
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Datei-Uploads ({{len}})",
|
||||
"actions": {
|
||||
"re-upload": "Wiederholen Sie den Upload",
|
||||
"cancel": "Upload abbrechen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"download-status": {
|
||||
"error": { "generic": "Projekt konnte nicht heruntergeladen werden." },
|
||||
"error": {
|
||||
"generic": "Projekt konnte nicht heruntergeladen werden."
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Downloads ({{len}})",
|
||||
"tooltip": "{{len}} Dateien",
|
||||
"actions": { "re-download": "Download neu versuchen", "cancel": "Download abbrechen" }
|
||||
"actions": {
|
||||
"re-download": "Download neu versuchen",
|
||||
"cancel": "Download abbrechen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pdf-viewer": { "text-popup": { "actions": { "search": "Suche nach Auswahl" } }, "search-in-progress": "Suche läuft ..." },
|
||||
"pdf-viewer": {
|
||||
"text-popup": {
|
||||
"actions": {
|
||||
"search": "Suche nach Auswahl"
|
||||
}
|
||||
},
|
||||
"search-in-progress": "Suche läuft ..."
|
||||
},
|
||||
"common": {
|
||||
"close": "Ansicht schließen",
|
||||
"dialog": { "close": "Dialog schließen" },
|
||||
"dialog": {
|
||||
"close": "Dialog schließen"
|
||||
},
|
||||
"confirmation-dialog": {
|
||||
"title": "Aktion bestätigen",
|
||||
"description": "Diese Aktion muss bestätigt werden. Möchten Sie fortfahren?",
|
||||
@ -38,7 +61,11 @@
|
||||
"my-account": {
|
||||
"children": {
|
||||
"admin": "die Einstellungen",
|
||||
"language": { "label": "Sprache", "english": "Englisch", "german": "Deutsche" },
|
||||
"language": {
|
||||
"label": "Sprache",
|
||||
"english": "Englisch",
|
||||
"german": "Deutsche"
|
||||
},
|
||||
"logout": "Ausloggen"
|
||||
}
|
||||
}
|
||||
@ -58,46 +85,88 @@
|
||||
"report": {
|
||||
"unavailable": "Der Redaktionsbericht ist erst verfügbar, wenn alle Dateien genehmigt wurden.",
|
||||
"unavailable-single": "Der Redaktionsbericht ist erst verfügbar, wenn diese Datei genehmigt wurde.",
|
||||
"action": { "label": "Redaktionsbericht herunterladen", "efsa": "Mit EFSA-Vorlage herunterladen", "syngenta": "Mit Syngenta-Vorlage herunterladen" }
|
||||
"action": {
|
||||
"label": "Redaktionsbericht herunterladen",
|
||||
"efsa": "Mit EFSA-Vorlage herunterladen",
|
||||
"syngenta": "Mit Syngenta-Vorlage herunterladen"
|
||||
}
|
||||
},
|
||||
"project-listing": {
|
||||
"search": "Projektname...",
|
||||
"reanalyse": { "action": "Analysieren Sie das gesamte Projekt" },
|
||||
"assign": { "action": "Eigentümer zuweisen" },
|
||||
"download-files": { "action": "Laden Sie redigierte Dateien herunter" },
|
||||
"table-header": { "title": "{{length}} aktive Projekte", "bulk-select": "Auswahl umschalten", "recent": "Kürzlich" },
|
||||
"table-col-names": { "name": "Dokument", "needs-work": "Analysiert", "owner": "Inhaber", "status": "Status" },
|
||||
"reanalyse": {
|
||||
"action": "Analysieren Sie das gesamte Projekt"
|
||||
},
|
||||
"assign": {
|
||||
"action": "Eigentümer zuweisen"
|
||||
},
|
||||
"download-files": {
|
||||
"action": "Laden Sie redigierte Dateien herunter"
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{{length}} aktive Projekte",
|
||||
"bulk-select": "Auswahl umschalten",
|
||||
"recent": "Kürzlich"
|
||||
},
|
||||
"table-col-names": {
|
||||
"name": "Dokument",
|
||||
"needs-work": "Analysiert",
|
||||
"owner": "Inhaber",
|
||||
"status": "Status"
|
||||
},
|
||||
"stats": {
|
||||
"analyzed-pages": "Seiten",
|
||||
"total-people": "Benutzer insgesamt",
|
||||
"charts": { "projects": "Projekte", "total-documents": "Gesamtdokument (e)" }
|
||||
"charts": {
|
||||
"projects": "Projekte",
|
||||
"total-documents": "Gesamtdokument (e)"
|
||||
}
|
||||
},
|
||||
"add-edit-dialog": {
|
||||
"header-new": "Projekt erstellen",
|
||||
"header-edit": "Projekt bearbeiten",
|
||||
"form": {
|
||||
"name": { "label": "Projektname", "placeholder": "Name eingeben" },
|
||||
"description": { "label": "Beschreibung", "placeholder": "Beschreibung eingeben" },
|
||||
"name": {
|
||||
"label": "Projektname",
|
||||
"placeholder": "Name eingeben"
|
||||
},
|
||||
"description": {
|
||||
"label": "Beschreibung",
|
||||
"placeholder": "Beschreibung eingeben"
|
||||
},
|
||||
"due-date": "Geburtstermin",
|
||||
"template": "Projektvorlage"
|
||||
},
|
||||
"errors": { "project-already-exists": "Projekt mit diesem Namen existiert bereits!", "generic": "Projekt konnte nicht gespeichert werden" },
|
||||
"actions": { "save": "speichern", "save-and-add-members": "Team speichern und bearbeiten" }
|
||||
"errors": {
|
||||
"project-already-exists": "Projekt mit diesem Namen existiert bereits!",
|
||||
"generic": "Projekt konnte nicht gespeichert werden"
|
||||
},
|
||||
"actions": {
|
||||
"save": "speichern",
|
||||
"save-and-add-members": "Team speichern und bearbeiten"
|
||||
}
|
||||
},
|
||||
"header": "Projekte",
|
||||
"edit": { "action": "Projekt bearbeiten" },
|
||||
"delete": { "action": "Projekt löschen", "delete-failed": "Projekt konnte nicht gelöscht werden: {{projectName}}" },
|
||||
"edit": {
|
||||
"action": "Projekt bearbeiten"
|
||||
},
|
||||
"delete": {
|
||||
"action": "Projekt löschen",
|
||||
"delete-failed": "Projekt konnte nicht gelöscht werden: {{projectName}}"
|
||||
},
|
||||
"add-new": "Neues Projekt",
|
||||
"no-projects": "Sie haben derzeit keine Projekte.",
|
||||
"no-projects-match": "Keine Projekte stimmen mit Ihren aktuellen Filtern überein"
|
||||
},
|
||||
"file-details": { "dialog": { "title": "Dateidetails", "actions": { "download-redaction-report": "Redaktionsbericht herunterladen" } } },
|
||||
"project-details": {
|
||||
"title": "Projekt Details",
|
||||
"dialog": {
|
||||
"title": "Projekt Details",
|
||||
"info": { "file-count": "Anzahl der Dateien: {{fileCount}}" },
|
||||
"actions": { "download-redaction-report": "Redaktionsbericht herunterladen", "reanalyse-project": "Projekt analysieren" }
|
||||
"info": {
|
||||
"file-count": "Anzahl der Dateien: {{fileCount}}"
|
||||
},
|
||||
"actions": {
|
||||
"reanalyse-project": "Projekt analysieren"
|
||||
}
|
||||
},
|
||||
"owner": "Inhaber",
|
||||
"members": "Mitglieder",
|
||||
@ -107,7 +176,10 @@
|
||||
"collapse": "Details ausblenden"
|
||||
},
|
||||
"project-overview": {
|
||||
"no-data": { "title": "Es liegen noch keine Dokumente vor.", "action": "Dokument hochladen" },
|
||||
"no-data": {
|
||||
"title": "Es liegen noch keine Dokumente vor.",
|
||||
"action": "Dokument hochladen"
|
||||
},
|
||||
"search": "Dokumentname...",
|
||||
"header-actions": {
|
||||
"edit": "Bearbeiten",
|
||||
@ -131,13 +203,22 @@
|
||||
"label": "Veraltet",
|
||||
"toast": {
|
||||
"message-project": "Erneute Analyse erforderlich:",
|
||||
"actions": { "reanalyse-all": "Analysieren Sie alle", "reanalyse-file": "Analysieren Sie diese Datei", "later": "Später" }
|
||||
"actions": {
|
||||
"reanalyse-all": "Analysieren Sie alle",
|
||||
"reanalyse-file": "Analysieren Sie diese Datei",
|
||||
"later": "Später"
|
||||
}
|
||||
}
|
||||
},
|
||||
"report": { "action": "Redaktionsbericht herunterladen" },
|
||||
"report": {
|
||||
"action": "Redaktionsbericht herunterladen"
|
||||
},
|
||||
"assign": "Prüfer zuweisen",
|
||||
"assign-me": "Zuweisen zu mir",
|
||||
"table-header": { "title": "{{length}} Dokumente", "bulk-select": "Auswahl umschalten" },
|
||||
"table-header": {
|
||||
"title": "{{length}} Dokumente",
|
||||
"bulk-select": "Auswahl umschalten"
|
||||
},
|
||||
"table-col-names": {
|
||||
"name": "Name",
|
||||
"added-on": "Hinzugefügt",
|
||||
@ -149,8 +230,12 @@
|
||||
"upload-error": "Datei konnte nicht hochgeladen werden: {{name}}",
|
||||
"delete-file-error": "Fehler beim Löschen der Datei: {{filename}}",
|
||||
"delete-files-error": "Dateien konnten nicht gelöscht werden.",
|
||||
"reanalyse": { "action": "Datei analysieren" },
|
||||
"delete": { "action": "Datei löschen" },
|
||||
"reanalyse": {
|
||||
"action": "Datei analysieren"
|
||||
},
|
||||
"delete": {
|
||||
"action": "Datei löschen"
|
||||
},
|
||||
"file-listing": {
|
||||
"file-entry": {
|
||||
"status": "Status: {{status}}",
|
||||
@ -164,7 +249,9 @@
|
||||
}
|
||||
},
|
||||
"project-details": {
|
||||
"charts": { "documents-in-project": "Dokumente im Projekt" },
|
||||
"charts": {
|
||||
"documents-in-project": "Dokumente im Projekt"
|
||||
},
|
||||
"stats": {
|
||||
"documents": "{{count}} Dokumente",
|
||||
"analysed-pages": "{{count}} Seiten",
|
||||
@ -194,7 +281,12 @@
|
||||
"reanalyse-notification": "Dieses Dokument wurde nicht mit dem neuesten Regel- / Wörterbuchsatz verarbeitet. Analysieren Sie jetzt, um aktualisierte Anmerkungen zu erhalten.",
|
||||
"reanalyse-file": "Datei-Reanalyse läuft ...",
|
||||
"view-toggle": "Redigierte Ansicht",
|
||||
"tabs": { "quick-navigation": "Schnelle Navigation", "annotations": { "label": "Arbeitsbelastung" } },
|
||||
"tabs": {
|
||||
"quick-navigation": "Schnelle Navigation",
|
||||
"annotations": {
|
||||
"label": "Arbeitsbelastung"
|
||||
}
|
||||
},
|
||||
"reviewer": "Zugewiesen an",
|
||||
"unassigned": "Nicht zugewiesen",
|
||||
"assign-reviewer": "Prüfer zuweisen",
|
||||
@ -210,19 +302,40 @@
|
||||
"annotation-actions": {
|
||||
"message": {
|
||||
"manual-redaction": {
|
||||
"undo": { "success": "Rückgängig machen erfolgreich", "error": "Fehler beim Rückgängigmachen: {{error}}" },
|
||||
"suggest": { "success": "Redaktionsvorschlag gespeichert", "error": "Fehler beim Speichern des Redaktionsvorschlags: {{error}}" },
|
||||
"add": { "success": "Redaktion hinzugefügt!", "error": "Fehler beim Speichern der Redaktion: {{error}}" },
|
||||
"decline": { "success": "Redaktionsvorschlag abgelehnt!", "error": "Redaktion konnte nicht abgelehnt werden: {{error}}" },
|
||||
"approve": { "success": "Redaktionsvorschlag genehmigt!", "error": "Fehler beim Genehmigen der Redaktion: {{error}}" },
|
||||
"undo": {
|
||||
"success": "Rückgängig machen erfolgreich",
|
||||
"error": "Fehler beim Rückgängigmachen: {{error}}"
|
||||
},
|
||||
"suggest": {
|
||||
"success": "Redaktionsvorschlag gespeichert",
|
||||
"error": "Fehler beim Speichern des Redaktionsvorschlags: {{error}}"
|
||||
},
|
||||
"add": {
|
||||
"success": "Redaktion hinzugefügt!",
|
||||
"error": "Fehler beim Speichern der Redaktion: {{error}}"
|
||||
},
|
||||
"decline": {
|
||||
"success": "Redaktionsvorschlag abgelehnt!",
|
||||
"error": "Redaktion konnte nicht abgelehnt werden: {{error}}"
|
||||
},
|
||||
"approve": {
|
||||
"success": "Redaktionsvorschlag genehmigt!",
|
||||
"error": "Fehler beim Genehmigen der Redaktion: {{error}}"
|
||||
},
|
||||
"request-remove": {
|
||||
"success": "Angefordert, Redaktion zu entfernen!",
|
||||
"error": "Fehler beim Anfordern der Entfernung der Redaktion: {{error}}"
|
||||
},
|
||||
"remove": { "success": "Redaktion entfernt!", "error": "Redaktion konnte nicht entfernt werden: {{error}}" }
|
||||
"remove": {
|
||||
"success": "Redaktion entfernt!",
|
||||
"error": "Redaktion konnte nicht entfernt werden: {{error}}"
|
||||
}
|
||||
},
|
||||
"dictionary": {
|
||||
"undo": { "success": "Rückgängig machen erfolgreich", "error": "Fehler beim Rückgängigmachen: {{error}}" },
|
||||
"undo": {
|
||||
"success": "Rückgängig machen erfolgreich",
|
||||
"error": "Fehler beim Rückgängigmachen: {{error}}"
|
||||
},
|
||||
"suggest": {
|
||||
"success": "Vorschlag zur Wörterbuchänderung gespeichert!",
|
||||
"error": "Vorschlag zum Ändern des Wörterbuchs konnte nicht gespeichert werden: {{error}}"
|
||||
@ -231,7 +344,10 @@
|
||||
"success": "Eintrag zum Wörterbuch hinzugefügt. Änderungen werden nach einer erneuten Analyse sichtbar.",
|
||||
"error": "Fehler beim Hinzufügen des Eintrags zum Wörterbuch: {{error}}"
|
||||
},
|
||||
"decline": { "success": "Wörterbuchvorschlag abgelehnt.", "error": "Fehler beim Ablehnen des Wörterbuchvorschlags: {{error}}" },
|
||||
"decline": {
|
||||
"success": "Wörterbuchvorschlag abgelehnt.",
|
||||
"error": "Fehler beim Ablehnen des Wörterbuchvorschlags: {{error}}"
|
||||
},
|
||||
"approve": {
|
||||
"success": "Wörterbucheintrag genehmigt. Änderungen werden nach einer erneuten Analyse sichtbar.",
|
||||
"error": "Wörterbucheintrag konnte nicht genehmigt werden: {{error}}"
|
||||
@ -240,7 +356,10 @@
|
||||
"success": "Angefordert, Wörterbucheintrag zu entfernen!",
|
||||
"error": "Das Entfernen des Wörterbucheintrags konnte nicht angefordert werden: {{error}}"
|
||||
},
|
||||
"remove": { "success": "Wörterbucheintrag entfernt!", "error": "Fehler beim Entfernen des Wörterbucheintrags: {{error}}" }
|
||||
"remove": {
|
||||
"success": "Wörterbucheintrag entfernt!",
|
||||
"error": "Fehler beim Entfernen des Wörterbucheintrags: {{error}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"accept-suggestion": {
|
||||
@ -249,7 +368,9 @@
|
||||
"remove-from-dict": "Genehmigen und aus dem Wörterbuch entfernen",
|
||||
"only-here": "Nur hier genehmigen"
|
||||
},
|
||||
"accept-recommendation": { "label": "Empfehlung annehmen" },
|
||||
"accept-recommendation": {
|
||||
"label": "Empfehlung annehmen"
|
||||
},
|
||||
"suggest-remove-annotation": "Entfernen oder vorschlagen, diesen Eintrag zu entfernen",
|
||||
"reject-suggestion": "Vorschlag ablehnen",
|
||||
"remove-annotation": {
|
||||
@ -263,8 +384,17 @@
|
||||
"undo": "Rückgängig machen",
|
||||
"reject": "Ablehnen"
|
||||
},
|
||||
"initials-avatar": { "unassigned": "Nicht zugewiesen" },
|
||||
"assign-file-owner": { "dialog": { "single-user": "Gutachter", "title": "File Reviewer verwalten", "save": "speichern", "cancel": "Stornieren" } },
|
||||
"initials-avatar": {
|
||||
"unassigned": "Nicht zugewiesen"
|
||||
},
|
||||
"assign-file-owner": {
|
||||
"dialog": {
|
||||
"single-user": "Gutachter",
|
||||
"title": "File Reviewer verwalten",
|
||||
"save": "speichern",
|
||||
"cancel": "Stornieren"
|
||||
}
|
||||
},
|
||||
"assign-project-owner": {
|
||||
"dialog": {
|
||||
"single-user": "Inhaber",
|
||||
@ -277,7 +407,9 @@
|
||||
"no-members": "Noch keine Mitglieder. Wählen Sie aus der folgenden Liste."
|
||||
}
|
||||
},
|
||||
"project-member-guard": { "access-denied": "Sie dürfen nicht auf diese Seite zugreifen." },
|
||||
"project-member-guard": {
|
||||
"access-denied": "Sie dürfen nicht auf diese Seite zugreifen."
|
||||
},
|
||||
"comments": {
|
||||
"comment": "{{count}} Kommentar",
|
||||
"comments": "{{count}} Kommentare",
|
||||
@ -317,7 +449,12 @@
|
||||
"analysis": "Analyse erforderlich",
|
||||
"none": "Keine Anmerkungen"
|
||||
},
|
||||
"filter-menu": { "label": "Filter", "all": "Alle", "none": "Keiner", "filter-types": "Filtertypen" },
|
||||
"filter-menu": {
|
||||
"label": "Filter",
|
||||
"all": "Alle",
|
||||
"none": "Keiner",
|
||||
"filter-types": "Filtertypen"
|
||||
},
|
||||
"sorting": {
|
||||
"recent": "Kürzlich",
|
||||
"oldest": "Älteste",
|
||||
@ -327,7 +464,10 @@
|
||||
"custom": "Benutzerdefiniert"
|
||||
},
|
||||
"readonly-pill": "Schreibgeschützt",
|
||||
"group": { "redactions": "Redaktionswörterbücher", "hints": "Tipp Wörterbücher" },
|
||||
"group": {
|
||||
"redactions": "Redaktionswörterbücher",
|
||||
"hints": "Tipp Wörterbücher"
|
||||
},
|
||||
"annotation-type": {
|
||||
"recommendation": "Empfehlung",
|
||||
"remove-only-here": "Ausstehende Entfernung (nur hier)",
|
||||
@ -353,8 +493,13 @@
|
||||
"false-positive": "Falsch positiv setzen",
|
||||
"request-false-positive": "Falsch positiv anfordern"
|
||||
},
|
||||
"add-redaction": { "success": "Redaktionsvorschlag hinzugefügt!", "failed": "Fehler beim Hinzufügen der Redaktion: {{message}}" },
|
||||
"actions": { "save": "speichern" },
|
||||
"add-redaction": {
|
||||
"success": "Redaktionsvorschlag hinzugefügt!",
|
||||
"failed": "Fehler beim Hinzufügen der Redaktion: {{message}}"
|
||||
},
|
||||
"actions": {
|
||||
"save": "speichern"
|
||||
},
|
||||
"content": {
|
||||
"text": "Ausgewählter Text:",
|
||||
"rectangle": "Benutzerdefiniertes Rechteck",
|
||||
@ -365,24 +510,54 @@
|
||||
"comment": "Kommentar"
|
||||
}
|
||||
},
|
||||
"approve-request": { "success": "Anfrage genehmigt.", "error": "Anfrage konnte nicht genehmigt werden." },
|
||||
"undo": { "success": "Aktion rückgängig gemacht.", "error": "Aktion konnte nicht rückgängig gemacht werden." },
|
||||
"redaction-request": { "success": "Redaktion angefordert.", "error": "Redaktion konnte nicht angefordert werden." },
|
||||
"remove-redaction-request": { "success": "Redaktion entfernt.", "error": "Redaktion konnte nicht entfernt werden." },
|
||||
"redaction-add": { "success": "Redaktion hinzugefügt.", "error": "Redaktion konnte nicht hinzugefügt werden." }
|
||||
"approve-request": {
|
||||
"success": "Anfrage genehmigt.",
|
||||
"error": "Anfrage konnte nicht genehmigt werden."
|
||||
},
|
||||
"undo": {
|
||||
"success": "Aktion rückgängig gemacht.",
|
||||
"error": "Aktion konnte nicht rückgängig gemacht werden."
|
||||
},
|
||||
"redaction-request": {
|
||||
"success": "Redaktion angefordert.",
|
||||
"error": "Redaktion konnte nicht angefordert werden."
|
||||
},
|
||||
"remove-redaction-request": {
|
||||
"success": "Redaktion entfernt.",
|
||||
"error": "Redaktion konnte nicht entfernt werden."
|
||||
},
|
||||
"redaction-add": {
|
||||
"success": "Redaktion hinzugefügt.",
|
||||
"error": "Redaktion konnte nicht hinzugefügt werden."
|
||||
}
|
||||
},
|
||||
"confirmation-dialog": {
|
||||
"delete-file": { "title": "Dokument löschen", "question": "Möchten Sie fortfahren?" },
|
||||
"delete-project": { "title": "Projekt löschen", "question": "Möchten Sie fortfahren?" },
|
||||
"remove-manual-redaction": { "title": "Redaktion entfernen", "question": "Möchten Sie diese Redaktion wirklich entfernen?" },
|
||||
"delete-file": {
|
||||
"title": "Dokument löschen",
|
||||
"question": "Möchten Sie fortfahren?"
|
||||
},
|
||||
"delete-project": {
|
||||
"title": "Projekt löschen",
|
||||
"question": "Möchten Sie fortfahren?"
|
||||
},
|
||||
"remove-manual-redaction": {
|
||||
"title": "Redaktion entfernen",
|
||||
"question": "Möchten Sie diese Redaktion wirklich entfernen?"
|
||||
},
|
||||
"remove-from-dictionary": {
|
||||
"title": "Aus dem Wörterbuch entfernen",
|
||||
"question": "Möchten Sie <b>{{entry}} wirklich</b> aus dem <b>{{dictionary}}</b> Wörterbuch entfernen?"
|
||||
},
|
||||
"remove-only-here": { "title": "Nur hier entfernen", "question": "Möchten Sie <b>{{entry}}</b> nur hier entfernen?" }
|
||||
"remove-only-here": {
|
||||
"title": "Nur hier entfernen",
|
||||
"question": "Möchten Sie <b>{{entry}}</b> nur hier entfernen?"
|
||||
}
|
||||
},
|
||||
"add-edit-dictionary": {
|
||||
"title": { "edit": "Bearbeiten Sie das {{name}} Wörterbuch", "new": "Wörterbuch erstellen" },
|
||||
"title": {
|
||||
"edit": "Bearbeiten Sie das {{name}} Wörterbuch",
|
||||
"new": "Wörterbuch erstellen"
|
||||
},
|
||||
"form": {
|
||||
"name": "Wörterbuchname",
|
||||
"name-placeholder": "Name eingeben",
|
||||
@ -405,7 +580,10 @@
|
||||
"save": "Wörterbuch speichern"
|
||||
},
|
||||
"add-edit-project-template": {
|
||||
"title": { "edit": "Bearbeiten Sie die {{name}} Projektvorlage", "new": "Projektvorlage erstellen" },
|
||||
"title": {
|
||||
"edit": "Bearbeiten Sie die {{name}} Projektvorlage",
|
||||
"new": "Projektvorlage erstellen"
|
||||
},
|
||||
"form": {
|
||||
"name": "Name der Projektvorlage",
|
||||
"name-placeholder": "Name eingeben",
|
||||
@ -416,43 +594,95 @@
|
||||
"save": "Projektvorlage speichern"
|
||||
},
|
||||
"dictionary-overview": {
|
||||
"action": { "delete": "Wörterbuch löschen", "edit": "Wörterbuch bearbeiten", "download": "Wörterbuch herunterladen", "upload": "Wörterbuch hochladen" },
|
||||
"action": {
|
||||
"delete": "Wörterbuch löschen",
|
||||
"edit": "Wörterbuch bearbeiten",
|
||||
"download": "Wörterbuch herunterladen",
|
||||
"upload": "Wörterbuch hochladen"
|
||||
},
|
||||
"error": {
|
||||
"entries-too-short": "Einige Einträge des Wörterbuchs liegen unter der Mindestlänge von 2. Diese sind rot hervorgehoben!",
|
||||
"generic": "Etwas ist schief gelaufen ... Wörterbuch-Update fehlgeschlagen!"
|
||||
},
|
||||
"success": { "generic": "Wörterbuch aktualisiert!" },
|
||||
"success": {
|
||||
"generic": "Wörterbuch aktualisiert!"
|
||||
},
|
||||
"search": "Suche...",
|
||||
"save-changes": "Änderungen speichern",
|
||||
"revert-changes": "Zurückkehren",
|
||||
"compare": "Vergleichen Sie",
|
||||
"dictionary-details": { "description": "Beschreibung" }
|
||||
"dictionary-details": {
|
||||
"description": "Beschreibung"
|
||||
}
|
||||
},
|
||||
"dictionary-listing": {
|
||||
"action": { "delete": "Wörterbuch löschen", "edit": "Wörterbuch bearbeiten" },
|
||||
"action": {
|
||||
"delete": "Wörterbuch löschen",
|
||||
"edit": "Wörterbuch bearbeiten"
|
||||
},
|
||||
"case-sensitive": "Groß- und Kleinschreibung beachten",
|
||||
"add-new": "Neues Wörterbuch",
|
||||
"stats": { "charts": { "types": "Typen", "entries": "Einträge" } },
|
||||
"table-header": { "title": "{{Länge}} Wörterbücher" },
|
||||
"table-col-names": { "type": "Art", "order-of-importance": "Reihenfolge der Wichtigkeit", "hint-redaction": "Hinweis / Redaktion" },
|
||||
"stats": {
|
||||
"charts": {
|
||||
"types": "Typen",
|
||||
"entries": "Einträge"
|
||||
}
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{{Länge}} Wörterbücher"
|
||||
},
|
||||
"table-col-names": {
|
||||
"type": "Art",
|
||||
"order-of-importance": "Reihenfolge der Wichtigkeit",
|
||||
"hint-redaction": "Hinweis / Redaktion"
|
||||
},
|
||||
"search": "Suche...",
|
||||
"no-data": { "title": "Es gibt noch keine Wörterbücher.", "action": "Neues Wörterbuch" }
|
||||
"no-data": {
|
||||
"title": "Es gibt noch keine Wörterbücher.",
|
||||
"action": "Neues Wörterbuch"
|
||||
}
|
||||
},
|
||||
"project-templates": "Projektvorlagen",
|
||||
"project-templates-listing": {
|
||||
"table-header": { "title": "{{Länge}} Projektvorlagen" },
|
||||
"table-header": {
|
||||
"title": "{{Länge}} Projektvorlagen"
|
||||
},
|
||||
"entries": "{{Länge}} Einträge",
|
||||
"dictionaries": "{{Länge}} Wörterbücher",
|
||||
"action": { "delete": "Vorlage löschen", "edit": "Vorlage bearbeiten" },
|
||||
"action": {
|
||||
"delete": "Vorlage löschen",
|
||||
"edit": "Vorlage bearbeiten"
|
||||
},
|
||||
"add-new": "Neue Projektvorlage",
|
||||
"search": "Suche...",
|
||||
"table-col-names": { "name": "Name", "created-by": "Erstellt von", "created-on": "Erstellt am", "modified-on": "Geändert am" }
|
||||
"table-col-names": {
|
||||
"name": "Name",
|
||||
"created-by": "Erstellt von",
|
||||
"created-on": "Erstellt am",
|
||||
"modified-on": "Geändert am"
|
||||
}
|
||||
},
|
||||
"user-listing": {
|
||||
"table-header": {
|
||||
"title": "{{Länge}} Benutzer"
|
||||
},
|
||||
"table-col-names": {
|
||||
"name": "Name",
|
||||
"email": "Email"
|
||||
},
|
||||
"search": "Suche..."
|
||||
},
|
||||
"user-listing": { "table-header": { "title": "{{Länge}} Benutzer" }, "table-col-names": { "name": "Name", "email": "Email" }, "search": "Suche..." },
|
||||
"rules-screen": {
|
||||
"error": { "generic": "Etwas ist schief gelaufen ... Regelaktualisierung fehlgeschlagen!" },
|
||||
"success": { "generic": "Regeln aktualisiert!" },
|
||||
"action": { "download": "Regeln herunterladen", "upload": "Regeln hochladen" },
|
||||
"error": {
|
||||
"generic": "Etwas ist schief gelaufen ... Regelaktualisierung fehlgeschlagen!"
|
||||
},
|
||||
"success": {
|
||||
"generic": "Regeln aktualisiert!"
|
||||
},
|
||||
"action": {
|
||||
"download": "Regeln herunterladen",
|
||||
"upload": "Regeln hochladen"
|
||||
},
|
||||
"save-changes": "Änderungen speichern",
|
||||
"revert-changes": "Zurückkehren"
|
||||
},
|
||||
@ -490,6 +720,11 @@
|
||||
"overwrite-files-dialog": {
|
||||
"title": "Die Datei existiert bereits!",
|
||||
"question": "<b>{{Dateiname}}</b> existiert bereits. Was möchten Sie tun?",
|
||||
"options": { "overwrite": "Überschreiben", "skip": "Überspringen", "cancel": "Stornieren", "remember": "Bewerben Sie sich für alle Uploads" }
|
||||
"options": {
|
||||
"overwrite": "Überschreiben",
|
||||
"skip": "Überspringen",
|
||||
"cancel": "Stornieren",
|
||||
"remember": "Bewerben Sie sich für alle Uploads"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
"title": "Downloads ({{len}})",
|
||||
"tooltip": "{{len}} files",
|
||||
"actions": {
|
||||
"re-download": "Retry Download",
|
||||
"download": "Download now",
|
||||
"cancel": "Cancel Download"
|
||||
}
|
||||
}
|
||||
@ -160,14 +160,6 @@
|
||||
"no-projects": "You currently have no projects.",
|
||||
"no-projects-match": "No Projects match your current filters"
|
||||
},
|
||||
"file-details": {
|
||||
"dialog": {
|
||||
"title": "File Details",
|
||||
"actions": {
|
||||
"download-redaction-report": "Download Redaction Report"
|
||||
}
|
||||
}
|
||||
},
|
||||
"project-details": {
|
||||
"title": "Project Details",
|
||||
"dialog": {
|
||||
@ -176,7 +168,6 @@
|
||||
"file-count": "Number of files: {{fileCount}}"
|
||||
},
|
||||
"actions": {
|
||||
"download-redaction-report": "Download Redaction Report",
|
||||
"reanalyse-project": "Analyze Project"
|
||||
}
|
||||
},
|
||||
@ -200,10 +191,8 @@
|
||||
"upload-document": "Upload Document",
|
||||
"download-redacted-files": "Download Redacted Files"
|
||||
},
|
||||
"download-file": "Download File(s)",
|
||||
"download-redacted-file": "Download Redacted File(s)",
|
||||
"download-flat-redacted-file": "Download Flat Redacted File(s)",
|
||||
"download-redacted-file-preview": "Download Redacted File(s) Preview",
|
||||
"download-file": "Download",
|
||||
"download-file-disabled": "Download is only permitted for approved files",
|
||||
"under-approval": "For Approval",
|
||||
"approve": "Approve",
|
||||
"approve-disabled": "File can only be approved once it has been analysed with the latest dictionaries and all suggestions have been processed",
|
||||
@ -429,7 +418,6 @@
|
||||
"hide-comments": "Hide",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
|
||||
"UNPROCESSED": "Unprocessed",
|
||||
"REPROCESS": "Processing",
|
||||
"PROCESSING": "Processing",
|
||||
|
||||
@ -59,6 +59,17 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen {
|
||||
.page-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.red-content-inner {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
}
|
||||
|
||||
.red-content-inner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -69,10 +80,6 @@ body {
|
||||
z-index: 1;
|
||||
transition: height ease-in-out 0.2s;
|
||||
|
||||
&.fullscreen {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.left-container {
|
||||
overflow: hidden;
|
||||
transition: width ease-in-out 0.2s, min-width ease-in-out 0.2s;
|
||||
|
||||
@ -10,7 +10,7 @@ export const DYNAMIC_CACHES = [
|
||||
},
|
||||
|
||||
{
|
||||
urls: ['/download'],
|
||||
urls: ['/download/original'],
|
||||
name: 'files',
|
||||
maxAge: 3600 * 24 * 7,
|
||||
maxSize: 1000,
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
*/ /* tslint:disable:no-unused-variable member-ordering */
|
||||
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams, HttpResponse, HttpEvent } from '@angular/common/http';
|
||||
import { HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http';
|
||||
import { CustomHttpUrlEncodingCodec } from '../encoder';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
@ -21,7 +21,7 @@ import { DownloadResponse } from '../model/downloadResponse';
|
||||
import { DownloadStatusResponse } from '../model/downloadStatusResponse';
|
||||
import { PrepareDownloadRequest } from '../model/prepareDownloadRequest';
|
||||
|
||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||
import { BASE_PATH } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
|
||||
@Injectable()
|
||||
@ -97,7 +97,8 @@ export class DownloadControllerService {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<any>('post', `${this.basePath}/async/download/get`, {
|
||||
return this.httpClient.request('post', `${this.basePath}/async/download/get`, {
|
||||
responseType: 'blob',
|
||||
body: body,
|
||||
params: queryParameters,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user