pdf display
This commit is contained in:
parent
3e52f7e630
commit
ee891e0585
@ -28,17 +28,23 @@ import {MatDialogModule} from '@angular/material/dialog';
|
||||
import {MatSnackBarModule} from "@angular/material/snack-bar";
|
||||
import {MatTooltipModule} from "@angular/material/tooltip";
|
||||
import {ConfirmationDialogComponent} from './common/confirmation-dialog/confirmation-dialog.component';
|
||||
import { FilePreviewScreenComponent } from './screens/file/file-preview-screen/file-preview-screen.component';
|
||||
import { PdfViewerComponent } from './screens/file/pdf-viewer/pdf-viewer.component';
|
||||
import {FilePreviewScreenComponent} from './screens/file/file-preview-screen/file-preview-screen.component';
|
||||
import {PdfViewerComponent} from './screens/file/pdf-viewer/pdf-viewer.component';
|
||||
import {MatTabsModule} from "@angular/material/tabs";
|
||||
import {MatButtonToggleModule} from "@angular/material/button-toggle";
|
||||
import {NgpSortModule} from "ngp-sort-pipe";
|
||||
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||
import {MatSelectModule} from "@angular/material/select";
|
||||
import {NgxDropzoneModule} from "ngx-dropzone";
|
||||
import {MatSidenavModule} from "@angular/material/sidenav";
|
||||
import { FileDetailsDialogComponent } from './screens/file/file-preview-screen/file-details-dialog/file-details-dialog.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent, BaseScreenComponent, ProjectListingScreenComponent, ProjectOverviewScreenComponent, AddEditProjectDialogComponent, ConfirmationDialogComponent, FilePreviewScreenComponent, PdfViewerComponent],
|
||||
declarations: [AppComponent, BaseScreenComponent, ProjectListingScreenComponent, ProjectOverviewScreenComponent, AddEditProjectDialogComponent, ConfirmationDialogComponent, FilePreviewScreenComponent, PdfViewerComponent, FileDetailsDialogComponent],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
@ -84,6 +90,7 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
}
|
||||
|
||||
]),
|
||||
NgpSortModule,
|
||||
MatToolbarModule,
|
||||
MatButtonModule,
|
||||
MatMenuModule,
|
||||
@ -91,7 +98,11 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
MatTooltipModule,
|
||||
MatSnackBarModule,
|
||||
MatTabsModule,
|
||||
MatButtonToggleModule
|
||||
MatButtonToggleModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
NgxDropzoneModule,
|
||||
MatSidenavModule
|
||||
],
|
||||
providers: [{
|
||||
provide: KeycloakService,
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
<section class="dialog">
|
||||
|
||||
<button mat-icon-button class="dialog-close" (click)="dialogRef.close()">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
<div class="dialog-header heading-l"
|
||||
[translate]="confirmationDialogInput.title">
|
||||
</div>
|
||||
@ -16,4 +12,8 @@
|
||||
(click)="confirm()">{{confirmationDialogInput.confirmationText | translate}}</button>
|
||||
<button mat-flat-button color="primary" (click)="deny()">{{confirmationDialogInput.denyText | translate}}</button>
|
||||
</div>
|
||||
|
||||
<button mat-icon-button class="dialog-close" (click)="dialogRef.close()">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@ -43,6 +43,31 @@ export class IconsModule {
|
||||
'preview',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/preview_icon.svg')
|
||||
);
|
||||
iconRegistry.addSvgIconInNamespace(
|
||||
'red',
|
||||
'sort-asc',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/sort-ascending.svg')
|
||||
);
|
||||
iconRegistry.addSvgIconInNamespace(
|
||||
'red',
|
||||
'sort-desc',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/sort-descending.svg')
|
||||
);
|
||||
iconRegistry.addSvgIconInNamespace(
|
||||
'red',
|
||||
'menu',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/menu.svg')
|
||||
);
|
||||
iconRegistry.addSvgIconInNamespace(
|
||||
'red',
|
||||
'chevron-right',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/double-chevron-right.svg')
|
||||
);
|
||||
iconRegistry.addSvgIconInNamespace(
|
||||
'red',
|
||||
'info',
|
||||
sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/info.svg')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,15 +1,29 @@
|
||||
<div class="red-top-bar">
|
||||
<div class="top-bar-row">
|
||||
<div class="menu left">
|
||||
<div class="menu left visible-lt-lg">
|
||||
<button mat-flat-button [matMenuTriggerFor]="menuNav">
|
||||
<mat-icon svgIcon="red:menu"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuNav="matMenu">
|
||||
<button mat-menu-item translate="top-bar.navigation-items.projects.label"
|
||||
routerLink="/ui/projects">
|
||||
</button>
|
||||
<button mat-menu-item *ngIf="appStateService.activeProject"
|
||||
[routerLink]="'/ui/projects/'+appStateService.activeProject.projectId">{{appStateService.activeProject.projectName}}</button>
|
||||
<button mat-menu-item *ngIf="appStateService.activeFile"
|
||||
[routerLink]="'/ui/projects/'+appStateService.activeProject.projectId+'/file/'+appStateService.activeFile.fileId">{{appStateService.activeFile.filename}}</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="menu left visible-lg">
|
||||
<button mat-flat-button color="primary" translate="top-bar.navigation-items.projects.label"
|
||||
routerLink="/ui/projects"></button>
|
||||
<div class="breadcrumb" *ngIf="appStateService.activeProject">
|
||||
>
|
||||
<mat-icon svgIcon="red:chevron-right"></mat-icon>
|
||||
</div>
|
||||
<button mat-flat-button color="accent" *ngIf="appStateService.activeProject"
|
||||
[routerLink]="'/ui/projects/'+appStateService.activeProject.projectId">{{appStateService.activeProject.projectName}}</button>
|
||||
<div class="breadcrumb" *ngIf="appStateService.activeFile">
|
||||
>
|
||||
<mat-icon svgIcon="red:chevron-right"></mat-icon>
|
||||
</div>
|
||||
<button mat-flat-button color="accent" *ngIf="appStateService.activeFile"
|
||||
[routerLink]="'/ui/projects/'+appStateService.activeProject.projectId+'/file/'+appStateService.activeFile.fileId">{{appStateService.activeFile.filename}}</button>
|
||||
|
||||
@ -20,6 +20,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb{
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
color: $yellow-1;
|
||||
|
||||
mat-icon{
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
opacity: 0.15;
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
<section class="dialog">
|
||||
|
||||
<div class="dialog-header heading-l"
|
||||
[translate]="'file-details.dialog.title.label'">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="file-details">
|
||||
<div class="file-row">
|
||||
{{fileStatus.filename}}
|
||||
</div>
|
||||
<div class="file-row">
|
||||
{{'project-overview.file-listing.file-entry.status.label'| translate:fileStatus}}
|
||||
</div>
|
||||
<div class="file-row">
|
||||
{{'project-overview.file-listing.file-entry.number-of-pages.label'| translate:fileStatus}}
|
||||
</div>
|
||||
<div class="file-row">
|
||||
{{'project-overview.file-listing.file-entry.number-of-analyses.label'| translate:fileStatus}}
|
||||
</div>
|
||||
<div class="file-row">
|
||||
{{'project-overview.file-listing.file-entry.added.label'| translate:{added: fileStatus.added | date:'short'} }}
|
||||
</div>
|
||||
<div class="file-row" *ngIf="fileStatus.lastUpdated">
|
||||
{{'project-overview.file-listing.file-entry.last-updated.label'| translate:{lastUpdated: fileStatus.lastUpdated | date:'short'} }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button mat-flat-button color="primary" translate="file-details.dialog.actions.download-redaction-report.label"
|
||||
(click)="downloadRedactionReport()"></button>
|
||||
</div>
|
||||
|
||||
|
||||
<button mat-icon-button class="dialog-close" (click)="dialogRef.close()">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
</section>
|
||||
@ -0,0 +1,18 @@
|
||||
@import "../../../../../../../../assets/styles/red-variables";
|
||||
|
||||
|
||||
.details-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.file-row {
|
||||
opacity: 1;
|
||||
color: $grey-1;
|
||||
font-family: Inconsolata, monospace, monospace;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0;
|
||||
line-height: 14px;
|
||||
height: 18px;
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
import {Component, Inject, OnInit} from '@angular/core';
|
||||
import {
|
||||
FileStatus,
|
||||
FileUploadControllerService,
|
||||
ProjectControllerService,
|
||||
RedactionLogControllerService
|
||||
} from "@redaction/red-ui-http";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {NotificationService} from "../../../../notification/notification.service";
|
||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||
import {download} from "../../../../utils/file-download-utils";
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-details-dialog',
|
||||
templateUrl: './file-details-dialog.component.html',
|
||||
styleUrls: ['./file-details-dialog.component.scss']
|
||||
})
|
||||
export class FileDetailsDialogComponent implements OnInit {
|
||||
|
||||
|
||||
constructor(
|
||||
private readonly _fileUploadControllerService: FileUploadControllerService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _notificationService: NotificationService,
|
||||
public dialogRef: MatDialogRef<FileDetailsDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public fileStatus: FileStatus) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
downloadRedactionReport() {
|
||||
this._fileUploadControllerService.downloadRedactionReport({fileIds:[this.fileStatus.fileId]},true,'response').subscribe(data=>{
|
||||
download(data,'redaction-report-'+this.fileStatus.filename+".docx");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,15 @@
|
||||
<div class="page-header">
|
||||
<div class="heading-l clamp-2">{{appStateService.activeFile?.filename}}</div>
|
||||
<mat-button-toggle-group name="type" #group="matButtonToggleGroup" value="ORIGINAL">
|
||||
<mat-button-toggle value="ORIGINAL">Original</mat-button-toggle>
|
||||
<mat-button-toggle value="ANNOTATED">Annotated</mat-button-toggle>
|
||||
<mat-button-toggle value="REDACTED">Redacted</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<div class="toggle-buttons">
|
||||
<mat-button-toggle-group name="type" #group="matButtonToggleGroup" value="ORIGINAL">
|
||||
<mat-button-toggle value="ORIGINAL">Original</mat-button-toggle>
|
||||
<mat-button-toggle value="ANNOTATED">Annotated</mat-button-toggle>
|
||||
<mat-button-toggle value="REDACTED">Redacted</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
</div>
|
||||
<redaction-pdf-viewer [fileId]="fileId" [fileType]="group.value"></redaction-pdf-viewer>
|
||||
|
||||
<button mat-fab color="primary" aria-label="details" class="details-button" (click)="showDetailsDialog($event)">
|
||||
<mat-icon svgIcon="red:info"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
.mat-tab-body-wrapper{
|
||||
flex-grow: 1;
|
||||
|
||||
.details-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ import {TranslateService} from "@ngx-translate/core";
|
||||
import {NotificationService} from "../../../notification/notification.service";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {AppStateService} from "../../../state/app-state.service";
|
||||
import {ConfirmationDialogComponent} from "../../../common/confirmation-dialog/confirmation-dialog.component";
|
||||
import {FileDetailsDialogComponent} from "./file-details-dialog/file-details-dialog.component";
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-screen',
|
||||
@ -41,4 +43,12 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
showDetailsDialog($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this._dialog.open(FileDetailsDialogComponent, {
|
||||
width: '600px',
|
||||
maxWidth: '90vw',
|
||||
data: this.appStateService.activeFile
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
<section class="dialog">
|
||||
|
||||
<form [formGroup]="projectForm">
|
||||
<button mat-icon-button class="dialog-close" (click)="dialogRef.close()">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
<form [formGroup]="projectForm" (submit)="saveProject()">
|
||||
<div class="dialog-header heading-l"
|
||||
[translate]="project?.projectId ? 'projects.add-edit-dialog.header-edit.label': 'projects.add-edit-dialog.header-new.label'">
|
||||
|
||||
@ -21,10 +18,13 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
|
||||
<button mat-flat-button color="primary" translate="projects.add-edit-dialog.actions.save.label"
|
||||
[disabled]="projectForm.invalid"
|
||||
(click)="saveProject()"></button>
|
||||
[disabled]="projectForm.invalid" type="submit"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<button mat-icon-button class="dialog-close" (click)="dialogRef.close()">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
<div class="listing-subtitle">
|
||||
{{project.description}}
|
||||
</div>
|
||||
<div class="listing-subtitle">
|
||||
{{project.date | date:'short'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-entry-actions">
|
||||
<button mat-icon-button (click)="editProject($event,project)">
|
||||
|
||||
@ -31,7 +31,6 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
const dialogRef = this._dialog.open(AddEditProjectDialogComponent, {
|
||||
width: '400px',
|
||||
maxWidth: '90vw',
|
||||
autoFocus: false,
|
||||
data: project
|
||||
});
|
||||
|
||||
@ -56,7 +55,6 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
const dialogRef = this._dialog.open(ConfirmationDialogComponent, {
|
||||
width: '400px',
|
||||
maxWidth: '90vw',
|
||||
autoFocus: false,
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
|
||||
@ -3,16 +3,32 @@
|
||||
|
||||
|
||||
<div class="page-header" *ngIf="appStateService.activeProject">
|
||||
<div class="heading-xl">{{appStateService.activeProject.projectName}}</div>
|
||||
<div class="heading-xl clamp-1">{{appStateService.activeProject.projectName}}</div>
|
||||
<button mat-flat-button color="accent" translate="project-overview.upload-files.label"
|
||||
(click)="fileInput.click()"></button>
|
||||
<input type="file" class="file-upload-input" #fileInput multiple="true"
|
||||
(change)="handleFileInput($event.target.files)">
|
||||
</div>
|
||||
<div class="heading-l">{{appStateService.activeProject?.description}}</div>
|
||||
<div class="break-40"></div>
|
||||
<div class="listing">
|
||||
<div *ngFor="let fileStatus of appStateService.projectFiles" class="list-entry xl"
|
||||
<div class="flex-row">
|
||||
<div class="heading-l clamp-2">{{appStateService.activeProject?.description}}</div>
|
||||
<mat-form-field *ngIf="appStateService.projectFiles && appStateService.projectFiles.length > 0">
|
||||
<mat-label>{{'project-overview.sorting.label' | translate}}</mat-label>
|
||||
<mat-select color="primary" (valueChange)="sortingChanged($event)" [value]="sorting">
|
||||
<mat-option *ngFor="let option of sortOptions" [value]="option.value">
|
||||
<mat-icon [svgIcon]="option.icon"></mat-icon>
|
||||
{{option.label | translate}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="break-20"></div>
|
||||
<div class="listing" (dragenter)="dragEnter($event)" (mouseout)="dragLeave($event)">
|
||||
<ngx-dropzone (change)="handleFileInput($event.addedFiles)" class="drop-zone" [class.active]="dragActive || (appStateService.projectFiles && appStateService.projectFiles.length === 0)"
|
||||
#dropzoneComponent (dragleave)="dragLeave($event)">
|
||||
<ngx-dropzone-label>{{"project-overview.upload-files.label"| translate}}</ngx-dropzone-label>
|
||||
</ngx-dropzone>
|
||||
<div *ngFor="let fileStatus of appStateService.projectFiles | sortBy: sorting.order:sorting.name"
|
||||
class="list-entry xl"
|
||||
[routerLink]="'/ui/projects/'+projectId+'/file/'+fileStatus.fileId">
|
||||
<div class="list-entry-content">
|
||||
<div class="listing-title one-line slim break-all">
|
||||
@ -30,7 +46,7 @@
|
||||
<div class="listing-subtitle">
|
||||
{{'project-overview.file-listing.file-entry.added.label'| translate:{added: fileStatus.added | date:'short'} }}
|
||||
</div>
|
||||
<div class="listing-subtitle">
|
||||
<div class="listing-subtitle" *ngIf="fileStatus.lastUpdated">
|
||||
{{'project-overview.file-listing.file-entry.last-updated.label'| translate:{lastUpdated: fileStatus.lastUpdated | date:'short'} }}
|
||||
</div>
|
||||
</div>
|
||||
@ -41,4 +57,3 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,4 +1,28 @@
|
||||
|
||||
.file-upload-input{
|
||||
.listing {
|
||||
position: relative;
|
||||
min-height: calc(100vh - (61px + 80px + 70px + 80px));
|
||||
}
|
||||
|
||||
.file-upload-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.drop-zone {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
z-index: 100;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {
|
||||
FileStatus,
|
||||
FileUploadControllerService,
|
||||
Project,
|
||||
ProjectControllerService,
|
||||
StatusControllerService
|
||||
} from "@redaction/red-ui-http";
|
||||
import {Observable} from "rxjs";
|
||||
import {mergeMap, tap} from "rxjs/operators";
|
||||
import {NotificationService} from "../../notification/notification.service";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {ConfirmationDialogComponent} from "../../common/confirmation-dialog/confirmation-dialog.component";
|
||||
@ -22,6 +19,20 @@ import {AppStateService} from "../../state/app-state.service";
|
||||
})
|
||||
export class ProjectOverviewScreenComponent implements OnInit {
|
||||
|
||||
@ViewChild('dropzoneComponent', {static: true}) dropZoneComponent;
|
||||
|
||||
dragActive: boolean = false;
|
||||
|
||||
sortOptions: any[] = [{
|
||||
value: {name: 'lastUpdated', order: 'desc'}, label: 'project-overview.sorting.last-updated-desc.label', icon: 'red:sort-desc'
|
||||
},{
|
||||
value: {name: 'lastUpdated', order: 'asc'}, label: 'project-overview.sorting.last-updated-asc.label', icon: 'red:sort-asc'
|
||||
},{
|
||||
value: { name: 'filename', order: 'desc'}, label: 'project-overview.sorting.file-name-desc.label', icon: 'red:sort-desc'
|
||||
},{
|
||||
value: { name: 'filename', order: 'asc'}, label: 'project-overview.sorting.file-name-asc.label', icon: 'red:sort-asc'
|
||||
}];
|
||||
sorting: any = this.sortOptions[0].value;
|
||||
projectId: string;
|
||||
|
||||
constructor(public readonly appStateService: AppStateService,
|
||||
@ -43,10 +54,12 @@ export class ProjectOverviewScreenComponent implements OnInit {
|
||||
}
|
||||
|
||||
private _loadProject() {
|
||||
this.appStateService.activateProject(this.projectId).subscribe(()=>{});
|
||||
this.appStateService.activateProject(this.projectId).subscribe(() => {
|
||||
});
|
||||
}
|
||||
|
||||
handleFileInput(files: File[]) {
|
||||
handleFileInput(files: FileList | File[]) {
|
||||
this.dragActive = false;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
this._fileUploadControllerService.uploadFileForm(file, this.projectId, 'response').subscribe(() => {
|
||||
@ -58,7 +71,8 @@ export class ProjectOverviewScreenComponent implements OnInit {
|
||||
}
|
||||
|
||||
private _getFileStatus() {
|
||||
this.appStateService.getActiveProjectStatus().subscribe(()=>{});
|
||||
this.appStateService.getActiveProjectStatus().subscribe(() => {
|
||||
});
|
||||
}
|
||||
|
||||
deleteFile($event: MouseEvent, fileStatus: FileStatus) {
|
||||
@ -81,4 +95,18 @@ export class ProjectOverviewScreenComponent implements OnInit {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
sortingChanged($event) {
|
||||
this.sorting = $event;
|
||||
}
|
||||
|
||||
dragEnter($event: DragEvent) {
|
||||
console.log('enter');
|
||||
this.dragActive = true;
|
||||
}
|
||||
|
||||
dragLeave($event: any) {
|
||||
console.log('leave', this.dragActive);
|
||||
this.dragActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
13
apps/red-ui/src/app/utils/file-download-utils.ts
Normal file
13
apps/red-ui/src/app/utils/file-download-utils.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {HttpResponse} from '@angular/common/http';
|
||||
import {saveAs} from 'file-saver';
|
||||
|
||||
export function download(event: HttpResponse<Blob>, altName?: string) {
|
||||
const contentDisposition = event.headers.get('Content-Disposition');
|
||||
let fileName = undefined;
|
||||
try {
|
||||
fileName = contentDisposition ? contentDisposition.split('filename=')[1].replace(/"/g, '') : undefined;
|
||||
} catch (e) {
|
||||
console.log('failed to parse content-disposition: ', contentDisposition);
|
||||
}
|
||||
saveAs(event.body, fileName ? fileName : altName);
|
||||
}
|
||||
@ -67,7 +67,34 @@
|
||||
"label": "You currently have no projects. You can start your work by creating a new one!"
|
||||
}
|
||||
},
|
||||
"file-details": {
|
||||
"dialog": {
|
||||
"title": {
|
||||
"label": "File Details"
|
||||
},
|
||||
"actions": {
|
||||
"download-redaction-report": {
|
||||
"label": "Download Redaction Report"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"project-overview": {
|
||||
"sorting": {
|
||||
"label": "Sorting",
|
||||
"last-updated-desc": {
|
||||
"label": "Last Updated (Desc)"
|
||||
},
|
||||
"last-updated-asc": {
|
||||
"label": "Last Updated (Asc)"
|
||||
},
|
||||
"file-name-desc": {
|
||||
"label": "Name (Desc)"
|
||||
},
|
||||
"file-name-asc": {
|
||||
"label": "Name (Desc)"
|
||||
}
|
||||
},
|
||||
"upload-error": {
|
||||
"label": "Failed to upload file: {{name}}"
|
||||
},
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 330 330" style="enable-background:new 0 0 330 330;" xml:space="preserve">
|
||||
<g id="XMLID_27_">
|
||||
<path id="XMLID_28_" d="M310.607,154.391l-150-149.997c-5.857-5.858-15.355-5.858-21.213,0.001c-5.857,5.858-5.857,15.355,0,21.213
|
||||
l139.393,139.39L139.394,304.394c-5.857,5.858-5.857,15.355,0,21.213c2.929,2.929,6.768,4.393,10.606,4.393
|
||||
s7.678-1.464,10.607-4.394l150-150.003c2.813-2.813,4.393-6.628,4.393-10.606C315,161.019,313.42,157.204,310.607,154.391z"/>
|
||||
<path id="XMLID_29_" d="M195.001,164.996c0-3.979-1.581-7.794-4.394-10.607L40.606,4.393c-5.858-5.858-15.355-5.858-21.213,0.001
|
||||
c-5.857,5.858-5.857,15.355,0.001,21.213l139.394,139.39L19.393,304.394c-5.857,5.858-5.857,15.355,0.001,21.213
|
||||
C22.322,328.536,26.161,330,30,330s7.678-1.464,10.607-4.394l150.001-150.004C193.42,172.79,195.001,168.974,195.001,164.996z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 979 B |
43
apps/red-ui/src/assets/icons/general/info.svg
Normal file
43
apps/red-ui/src/assets/icons/general/info.svg
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M437.02,74.98C388.667,26.629,324.38,0,256,0S123.333,26.629,74.98,74.98C26.629,123.333,0,187.62,0,256
|
||||
s26.629,132.667,74.98,181.02C123.333,485.371,187.62,512,256,512s132.667-26.629,181.02-74.98
|
||||
C485.371,388.667,512,324.38,512,256S485.371,123.333,437.02,74.98z M256,70c30.327,0,55,24.673,55,55c0,30.327-24.673,55-55,55
|
||||
c-30.327,0-55-24.673-55-55C201,94.673,225.673,70,256,70z M326,420H186v-30h30V240h-30v-30h110v180h30V420z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 960 B |
8
apps/red-ui/src/assets/icons/general/menu.svg
Normal file
8
apps/red-ui/src/assets/icons/general/menu.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg height="384pt" viewBox="0 -53 384 384" width="384pt" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="m368 154.667969h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
<path
|
||||
d="m368 32h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
<path
|
||||
d="m368 277.332031h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 525 B |
21
apps/red-ui/src/assets/icons/general/sort-ascending.svg
Normal file
21
apps/red-ui/src/assets/icons/general/sort-ascending.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="612px" height="612px" viewBox="0 0 612 612" style="enable-background:new 0 0 612 612;" xml:space="preserve">
|
||||
<g>
|
||||
<g id="_x39__27_">
|
||||
<g>
|
||||
<path d="M590.905,559.173H295.58c-11.644,0-21.095,9.408-21.095,21.073c0,11.666,9.451,21.116,21.095,21.116h295.326
|
||||
c11.645,0,21.095-9.45,21.095-21.116C612,568.581,602.57,559.173,590.905,559.173z M331.166,215.266
|
||||
c8.27-8.312,8.27-21.77,0-30.061L184.727,16.68c-4.409-4.43-10.273-6.308-16.032-6.012c-5.78-0.296-11.623,1.582-16.032,6.012
|
||||
L6.202,185.185c-8.269,8.312-8.269,21.77,0,30.06c8.27,8.29,21.686,8.312,29.955,0L147.938,86.63v514.712h42.189V87.41
|
||||
l111.105,127.855C309.48,223.556,322.896,223.556,331.166,215.266z M337.769,95.089h253.137c11.645,0,21.095-10.02,21.095-21.686
|
||||
c0-11.665-9.45-21.115-21.095-21.115H337.769c-11.645,0-21.095,9.45-21.095,21.115C316.674,85.069,326.124,95.089,337.769,95.089
|
||||
z M590.905,432.415H295.58c-11.644,0-21.095,9.45-21.095,21.115c0,11.666,9.451,21.116,21.095,21.116h295.326
|
||||
c11.645,0,21.095-9.45,21.095-21.116C612,441.865,602.57,432.415,590.905,432.415z M590.905,305.698H295.58
|
||||
c-11.644,0-21.095,9.451-21.095,21.116c0,11.666,9.451,21.116,21.095,21.116h295.326c11.645,0,21.095-9.45,21.095-21.116
|
||||
C612,315.149,602.57,305.698,590.905,305.698z M590.905,178.982l-168.758,0.464c-11.645,0-21.095,8.986-21.095,20.652
|
||||
c0,11.665,9.45,21.537,21.095,21.537l168.758-0.422c11.645,0,21.095-9.45,21.095-21.115
|
||||
C612,188.433,602.57,178.982,590.905,178.982z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
25
apps/red-ui/src/assets/icons/general/sort-descending.svg
Normal file
25
apps/red-ui/src/assets/icons/general/sort-descending.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px"
|
||||
width="612.021px" height="612.021px" viewBox="0 0 612.021 612.021"
|
||||
style="enable-background:new 0 0 612.021 612.021;"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<g id="_x38__37_">
|
||||
<g>
|
||||
<path d="M590.927,517.491H337.79c-11.645,0-21.095,9.45-21.095,21.116c0,11.665,9.45,21.115,21.095,21.115l253.137-0.611
|
||||
c11.645,0,21.095-8.839,21.095-20.504C612.021,526.941,602.592,517.491,590.927,517.491z M295.601,52.88l295.326-0.042
|
||||
c11.645,0,21.095-9.408,21.095-21.074s-9.45-21.116-21.095-21.116H295.601c-11.645,0-21.095,9.45-21.095,21.116
|
||||
S283.956,52.88,295.601,52.88z M331.188,396.745c-8.27-8.312-21.686-8.312-29.955,0L190.127,524.6V10.648h-42.189v514.711
|
||||
L36.156,396.745c-8.269-8.312-21.686-8.312-29.954,0c-8.27,8.312-8.27,21.77,0,30.06l146.439,168.526
|
||||
c4.409,4.43,10.273,6.307,16.032,6.012c5.779,0.295,11.623-1.582,16.031-6.012l146.44-168.526
|
||||
C339.457,418.515,339.457,405.057,331.188,396.745z M590.927,137.364H295.601c-11.645,0-21.095,9.451-21.095,21.116
|
||||
c0,11.666,9.45,20.926,21.095,20.926h295.326c11.645,0,21.095-9.261,21.095-20.926
|
||||
C612.021,146.815,602.592,137.364,590.927,137.364z M590.927,264.059H295.601c-11.645,0-21.095,9.451-21.095,21.116
|
||||
c0,11.666,9.45,20.778,21.095,20.778l295.326,0.338c11.645,0,21.095-9.451,21.095-21.116
|
||||
C612.021,273.531,602.592,264.059,590.927,264.059z M590.927,390.775H422.169c-11.645,0-21.095,9.45-21.095,21.115
|
||||
c0,11.666,9.45,20.652,21.095,20.652h168.758c11.645,0,21.095-8.986,21.095-20.652
|
||||
C612.021,400.226,602.592,390.775,590.927,390.775z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,6 +1,15 @@
|
||||
@import "red-variables";
|
||||
@import "red-mixins";
|
||||
|
||||
@media only screen and (max-width: 720px) {
|
||||
.listing {
|
||||
.list-entry {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@ -12,7 +21,7 @@ html, body {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 40px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +37,7 @@ html, body {
|
||||
border: 1px solid $grey-1;
|
||||
border-radius: 2px;
|
||||
background-color: $white;
|
||||
padding: 24px;
|
||||
padding: 20px 24px;
|
||||
margin-right: 22px;
|
||||
margin-bottom: 22px;
|
||||
display: flex;
|
||||
@ -51,7 +60,7 @@ html, body {
|
||||
}
|
||||
}
|
||||
|
||||
.listing-title, .listing-subtitle{
|
||||
.listing-title, .listing-subtitle {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
@ -118,9 +127,14 @@ html, body {
|
||||
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.break-40 {
|
||||
height: 40px;
|
||||
.break-20 {
|
||||
height: 20px;
|
||||
background: transparent;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
background-color: #FFFFFF;
|
||||
outline: none;
|
||||
|
||||
:focus {
|
||||
&:focus {
|
||||
border-color: $grey-1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,3 +52,8 @@ $gn-next-mat-theme: mat-light-theme((
|
||||
));
|
||||
|
||||
@include angular-material-theme($gn-next-mat-theme);
|
||||
|
||||
|
||||
.mat-flat-button{
|
||||
min-width: unset!important;
|
||||
}
|
||||
|
||||
17
assets/styles/red-media-queries.scss
Normal file
17
assets/styles/red-media-queries.scss
Normal file
@ -0,0 +1,17 @@
|
||||
@media only screen and (max-width: 800px) {
|
||||
.visible-lg {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.visible-lt-lg {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
.visible-lt-lg {
|
||||
display: flex !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,3 +5,4 @@
|
||||
@import "red-text-styles";
|
||||
@import "red-dialog";
|
||||
@import "red-input";
|
||||
@import "red-media-queries";
|
||||
|
||||
@ -333,13 +333,14 @@ export class FileUploadControllerService {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<any>('post',`${this.basePath}/download/report`,
|
||||
return this.httpClient.request('post',`${this.basePath}/download/report`,
|
||||
{
|
||||
body: body,
|
||||
params: queryParameters,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
responseType: 'blob',
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
|
||||
@ -42,8 +42,11 @@
|
||||
"@ngx-translate/http-loader": "^6.0.0",
|
||||
"@nrwl/angular": "^10.2.0",
|
||||
"@pdftron/webviewer": "^7.0.1",
|
||||
"file-saver": "^2.0.2",
|
||||
"keycloak-angular": "^8.0.1",
|
||||
"keycloak-js": "10.0.2",
|
||||
"ngp-sort-pipe": "^0.0.4",
|
||||
"ngx-dropzone": "^2.2.2",
|
||||
"rxjs": "~6.5.5",
|
||||
"zone.js": "^0.10.2"
|
||||
},
|
||||
|
||||
17
yarn.lock
17
yarn.lock
@ -4668,6 +4668,11 @@ file-loader@6.0.0:
|
||||
loader-utils "^2.0.0"
|
||||
schema-utils "^2.6.5"
|
||||
|
||||
file-saver@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.2.tgz#06d6e728a9ea2df2cce2f8d9e84dfcdc338ec17a"
|
||||
integrity sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
@ -7128,6 +7133,18 @@ next-tick@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||
|
||||
ngp-sort-pipe@^0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/ngp-sort-pipe/-/ngp-sort-pipe-0.0.4.tgz#9d70caff0ee34f32f2ea1df16c7333b72df72b56"
|
||||
integrity sha512-tqyxsjb1mKROKhQB7oIcKaDSamPaNNwQ7norqxnOLRNjMdvG0b+XofIAZQpa/cG+SN6lmdCjtzOvwhOjHzpHmA==
|
||||
|
||||
ngx-dropzone@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ngx-dropzone/-/ngx-dropzone-2.2.2.tgz#450609031efb909461181c6b693d7c5f793a278d"
|
||||
integrity sha512-REuBcPNTY33OtcZD6dw8Fq/jFqwviiYydYaCn74yig8TvDDYhtJ/BPjtvbw7uEgF4BJr/UEHbKMvkdZIyCgsww==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user