Async Download

This commit is contained in:
Timo 2021-02-01 15:34:05 +02:00
parent ceaf97414a
commit 99ff8ac6cd
23 changed files with 444 additions and 436 deletions

View File

@ -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,

View File

@ -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"

View File

@ -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;

View File

@ -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>

View File

@ -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));
});
}
}

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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');

View File

@ -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>

View File

@ -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() {

View File

@ -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

View File

@ -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,

View File

@ -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();

View File

@ -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>

View File

@ -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';
}
}

View File

@ -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);
});
}
}

View File

@ -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"
}
}
}

View File

@ -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",

View File

@ -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;

View File

@ -10,7 +10,7 @@ export const DYNAMIC_CACHES = [
},
{
urls: ['/download'],
urls: ['/download/original'],
name: 'files',
maxAge: 3600 * 24 * 7,
maxSize: 1000,

View File

@ -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,