diff --git a/apps/red-ui/proxy.conf.json b/apps/red-ui/proxy.conf.json new file mode 100644 index 000000000..6bead218d --- /dev/null +++ b/apps/red-ui/proxy.conf.json @@ -0,0 +1,32 @@ +{ + "/project": { + "target": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io", + "secure": false, + "changeOrigin": true, + "logLevel": "debug" + }, + "/upload": { + "target": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io", + "secure": false, + "changeOrigin": true, + "logLevel": "debug" + }, + "/download": { + "target": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io", + "secure": false, + "changeOrigin": true, + "logLevel": "debug" + }, + "/delete": { + "target": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io", + "secure": false, + "changeOrigin": true, + "logLevel": "debug" + }, + "/status": { + "target": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io", + "secure": false, + "changeOrigin": true, + "logLevel": "debug" + } +} diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index 667488f85..9c37a2137 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -27,13 +27,18 @@ import {AddEditProjectDialogComponent} from './screens/project-listing-screen/ad 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 {MatTabsModule} from "@angular/material/tabs"; +import {MatButtonToggleModule} from "@angular/material/button-toggle"; export function HttpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); } @NgModule({ - declarations: [AppComponent, BaseScreenComponent, ProjectListingScreenComponent, ProjectOverviewScreenComponent, AddEditProjectDialogComponent], + declarations: [AppComponent, BaseScreenComponent, ProjectListingScreenComponent, ProjectOverviewScreenComponent, AddEditProjectDialogComponent, ConfirmationDialogComponent, FilePreviewScreenComponent, PdfViewerComponent], imports: [ BrowserModule, BrowserAnimationsModule, @@ -66,9 +71,14 @@ export function HttpLoaderFactory(httpClient: HttpClient) { canActivate: [RedKeycloakAuthGuard] }, { - path: 'projects/:id', + path: 'projects/:projectId', component: ProjectOverviewScreenComponent, canActivate: [RedKeycloakAuthGuard] + }, + { + path: 'projects/:projectId/file/:fileId', + component: FilePreviewScreenComponent, + canActivate: [RedKeycloakAuthGuard] } ] } @@ -79,7 +89,9 @@ export function HttpLoaderFactory(httpClient: HttpClient) { MatMenuModule, MatIconModule, MatTooltipModule, - MatSnackBarModule + MatSnackBarModule, + MatTabsModule, + MatButtonToggleModule ], providers: [{ provide: KeycloakService, diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html b/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html new file mode 100644 index 000000000..244f6ea60 --- /dev/null +++ b/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html @@ -0,0 +1,19 @@ +
+ + +
+
+ +
+

+
+ +
+ + +
+
diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.scss b/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts b/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts new file mode 100644 index 000000000..21a700350 --- /dev/null +++ b/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts @@ -0,0 +1,56 @@ +import {Component, Inject, OnInit} from '@angular/core'; +import {TranslateService} from "@ngx-translate/core"; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; + + +export class ConfirmationDialogInput { + + public title?: string; + public question?: string; + public confirmationText?: string; + public denyText?: string; + + constructor(options: ConfirmationDialogInput) { + this.title = options.title || ConfirmationDialogInput.default().title; + this.question = options.question || ConfirmationDialogInput.default().question; + this.confirmationText = options.confirmationText || ConfirmationDialogInput.default().confirmationText; + this.denyText = options.denyText || ConfirmationDialogInput.default().denyText; + } + + static default(){ + return new ConfirmationDialogInput({ + title:'common.confirmation-dialog.title.label', + question:'common.confirmation-dialog.description.label', + confirmationText:'common.confirmation-dialog.confirm.label', + denyText:'common.confirmation-dialog.deny.label' + }); + } +} + +@Component({ + selector: 'redaction-confirmation-dialog', + templateUrl: './confirmation-dialog.component.html', + styleUrls: ['./confirmation-dialog.component.scss'] +}) +export class ConfirmationDialogComponent implements OnInit { + + constructor( + private readonly _translateService: TranslateService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public confirmationDialogInput: ConfirmationDialogInput) { + if(!confirmationDialogInput){ + this.confirmationDialogInput = ConfirmationDialogInput.default(); + } + } + + ngOnInit(): void { + } + + deny() { + this.dialogRef.close(); + } + + confirm() { + this.dialogRef.close(true); + } +} diff --git a/apps/red-ui/src/app/icons/icons.module.ts b/apps/red-ui/src/app/icons/icons.module.ts index dd95c2bb9..e27f7acd1 100644 --- a/apps/red-ui/src/app/icons/icons.module.ts +++ b/apps/red-ui/src/app/icons/icons.module.ts @@ -23,6 +23,26 @@ export class IconsModule { 'close', sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/close_icon.svg') ); + iconRegistry.addSvgIconInNamespace( + 'red', + 'edit', + sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/edit_icon.svg') + ); + iconRegistry.addSvgIconInNamespace( + 'red', + 'delete', + sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/trash_icon.svg') + ); + iconRegistry.addSvgIconInNamespace( + 'red', + 'logout', + sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/logout_icon.svg') + ); + iconRegistry.addSvgIconInNamespace( + 'red', + 'preview', + sanitizer.bypassSecurityTrustResourceUrl('/assets/icons/general/preview_icon.svg') + ); } diff --git a/apps/red-ui/src/app/interceptor/api-path-interceptor.service.ts b/apps/red-ui/src/app/interceptor/api-path-interceptor.service.ts index d436ab4ac..322d9db50 100644 --- a/apps/red-ui/src/app/interceptor/api-path-interceptor.service.ts +++ b/apps/red-ui/src/app/interceptor/api-path-interceptor.service.ts @@ -11,14 +11,16 @@ export class ApiPathInterceptorService implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { - if (req.url.startsWith('/redaction-gateway-v1')) { - const updatedRequest = req.clone({ - url: this._appConfigService.getConfig(AppConfigKey.API_URL) + req.url - }) - - return next.handle(updatedRequest); - } else { + // if (!req.url.startsWith('/assets')) { + // const updatedRequest = req.clone({ + // url: this._appConfigService.getConfig(AppConfigKey.API_URL) + req.url + // }) + // + // console.log(req); + // + // return next.handle(updatedRequest); + // } else { return next.handle(req); - } + // } } } diff --git a/apps/red-ui/src/app/screens/base-screen/base-screen.component.html b/apps/red-ui/src/app/screens/base-screen/base-screen.component.html index 19ca00af0..76b22c7d3 100644 --- a/apps/red-ui/src/app/screens/base-screen/base-screen.component.html +++ b/apps/red-ui/src/app/screens/base-screen/base-screen.component.html @@ -3,11 +3,26 @@ diff --git a/apps/red-ui/src/app/screens/base-screen/base-screen.component.ts b/apps/red-ui/src/app/screens/base-screen/base-screen.component.ts index 6db3bbf98..e09a5df39 100644 --- a/apps/red-ui/src/app/screens/base-screen/base-screen.component.ts +++ b/apps/red-ui/src/app/screens/base-screen/base-screen.component.ts @@ -1,5 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {UserService} from "../../user/user.service"; +import {FileStatus, Project, ProjectControllerService, StatusControllerService} from "@redaction/red-ui-http"; +import {ActivatedRoute} from "@angular/router"; +import {Observable} from "rxjs"; +import {map} from "rxjs/operators"; +import {AppStateService} from "../../state/app-state.service"; @Component({ selector: 'redaction-base-screen', @@ -8,13 +13,18 @@ import {UserService} from "../../user/user.service"; }) export class BaseScreenComponent implements OnInit { - constructor(private readonly _userService: UserService) { } + + constructor( + public readonly appStateService: AppStateService, + private readonly _userService: UserService) { + + } ngOnInit(): void { } - async logout() { - await this._userService.logout(); + logout() { + this._userService.logout(); } } diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html new file mode 100644 index 000000000..05d7a2cc0 --- /dev/null +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html @@ -0,0 +1,9 @@ + + diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss new file mode 100644 index 000000000..c3da23d9c --- /dev/null +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss @@ -0,0 +1,3 @@ +.mat-tab-body-wrapper{ + flex-grow: 1; +} diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts new file mode 100644 index 000000000..0f894471f --- /dev/null +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts @@ -0,0 +1,44 @@ +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute, Router} from "@angular/router"; +import { + FileStatus, + FileUploadControllerService, + ProjectControllerService, + StatusControllerService +} from "@redaction/red-ui-http"; +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"; + +@Component({ + selector: 'redaction-file-preview-screen', + templateUrl: './file-preview-screen.component.html', + styleUrls: ['./file-preview-screen.component.scss'] +}) +export class FilePreviewScreenComponent implements OnInit { + + projectId: string; + fileId: string; + + constructor( + public readonly appStateService: AppStateService, + private readonly _activatedRoute: ActivatedRoute, + private readonly _statusControllerService: StatusControllerService, + private readonly _translateService: TranslateService, + private readonly _notificationService: NotificationService, + private readonly _dialog: MatDialog, + private readonly _router: Router, + private readonly _fileUploadControllerService: FileUploadControllerService, + private readonly _projectControllerService: ProjectControllerService) { + this._activatedRoute.params.subscribe(params => { + this.projectId = params.projectId; + this.fileId = params.fileId; + this.appStateService.activateFile(this.projectId,this.fileId).subscribe(()=>{}); + }); + } + + ngOnInit(): void { + } + +} diff --git a/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.html b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.html new file mode 100644 index 000000000..1ea295a43 --- /dev/null +++ b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.scss b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.scss new file mode 100644 index 000000000..beb2531bc --- /dev/null +++ b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.scss @@ -0,0 +1,11 @@ +.page { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; +} + +.viewer { + width: 100%; + height: calc(100vh - (61px + 80px + 50px + 40px)) +} diff --git a/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts new file mode 100644 index 000000000..d47d81b7a --- /dev/null +++ b/apps/red-ui/src/app/screens/file/pdf-viewer/pdf-viewer.component.ts @@ -0,0 +1,96 @@ +import {AfterViewInit, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core'; +import {KeycloakService} from "keycloak-angular"; +import {AppConfigService} from "../../../app-config/app-config.service"; +import {FileStatus, FileUploadControllerService} from "@redaction/red-ui-http"; +import {Observable, of} from "rxjs"; +import {tap} from "rxjs/operators"; + +declare const WebViewer: any; + +export enum FileType { + ORIGINAL = 'ORIGINAL', + ANNOTATED = 'ANNOTATED', + REDACTED = 'REDACTED' +} + +@Component({ + selector: 'redaction-pdf-viewer', + templateUrl: './pdf-viewer.component.html', + styleUrls: ['./pdf-viewer.component.scss'] +}) +export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges { + + @Input() fileId: string; + @Input() fileType: FileType; + @Input() fileStatus: FileStatus; + + @ViewChild('viewer', {static: true}) viewer: ElementRef; + wvInstance: any; + + _annotatedFileData: Blob; + _originalFileData: Blob; + _redactedFileData: Blob; + + + constructor(private readonly _keycloak: KeycloakService, + private readonly _fileUploadControllerService: FileUploadControllerService, + private readonly _appConfigService: AppConfigService) { + } + + ngOnInit() { + this.wvDocumentLoadedHandler = this.wvDocumentLoadedHandler.bind(this); + } + + wvDocumentLoadedHandler(): void { + const docViewer = this.wvInstance; + const annotManager = this.wvInstance.annotManager; + } + + ngAfterViewInit(): void { + this._loadFile().subscribe(data => { + this._loadViewer(data); + }); + } + + private _loadViewer(pdfBlob: any) { + WebViewer({ + path: '/assets/wv-resources', + }, this.viewer.nativeElement).then(instance => { + this.wvInstance = instance; + instance.docViewer.on('documentLoaded', this.wvDocumentLoadedHandler) + instance.loadDocument(pdfBlob, {filename: 'myfile.pdf'}); + }) + } + + ngOnChanges(changes: SimpleChanges): void { + if (this.wvInstance) { + this._loadFile().subscribe(data => { + this.wvInstance.loadDocument(data, {filename: 'myfile.pdf'}); + }); + } + } + + private _loadFile(): Observable { + let fileObs$: Observable; + switch (this.fileType) { + case FileType.ANNOTATED: + fileObs$ = this._annotatedFileData ? of(this._annotatedFileData) : this._fileUploadControllerService.downloadAnnotatedFile(this.fileId, true, 'body').pipe(tap(data => { + this._annotatedFileData = data; + })); + break; + case FileType.REDACTED: + fileObs$ = this._redactedFileData ? of(this._redactedFileData) : this._fileUploadControllerService.downloadRedactedFile(this.fileId, true, 'body').pipe(tap(data => { + this._redactedFileData = data; + })); + break; + case FileType.ORIGINAL: + default: + fileObs$ = this._originalFileData ? of(this._originalFileData) : this._fileUploadControllerService.downloadOriginalFile(this.fileId, true, 'body') + .pipe(tap(data => { + this._originalFileData = data; + })); + break; + } + return fileObs$; + } +} diff --git a/apps/red-ui/src/app/screens/project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component.html b/apps/red-ui/src/app/screens/project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component.html index edf406ad5..55386946e 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component.html +++ b/apps/red-ui/src/app/screens/project-listing-screen/add-edit-project-dialog/add-edit-project-dialog.component.html @@ -5,7 +5,7 @@
+ [translate]="project?.projectId ? 'projects.add-edit-dialog.header-edit.label': 'projects.add-edit-dialog.header-new.label'">
diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html index e79ffc9bd..7b6c70bc2 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html @@ -1,17 +1,26 @@ - -
-
-
-
- {{project.projectName}} +
+
+
+
+
+ {{project.projectName}} +
+
+ {{project.description}} +
-
- {{project.description}} +
+ +
diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss index e43ff3dcf..feae31111 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.scss @@ -1,57 +1,2 @@ @import "../../../../../../assets/styles/red-mixins"; - -.project-listing { - display: inline-flex; - - flex-wrap: wrap; - - .project { - box-sizing: border-box; - height: 122px; - width: 260px; - border: 1px solid $grey-1; - border-radius: 2px; - background-color: $white; - padding: 24px; - margin-right: 22px; - margin-bottom: 22px; - - transition: background-color 0.35s ease-in-out; - - &:hover { - background-color: $grey-1; - cursor: pointer; - * { - color: $white !important; - } - } - - .project-name { - height: 44px; - color: #283241; - font-family: Inter, sans-serf, serif; - font-size: 18px; - font-weight: bold; - letter-spacing: 0; - margin-bottom: 17px; - line-height: 22px; - @include line-clamp(2); - transition: color 0.35s ease-in-out; - - } - - .project-description { - height: 12px; - opacity: 0.7; - color: #283241; - font-family: Inconsolata, monospace, monospace; - font-size: 12px; - letter-spacing: 0; - line-height: 12px; - @include line-clamp(1); - transition: color 0.35s ease-in-out; - } - } - -} diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts index 465f6de15..32093da7e 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts @@ -1,8 +1,11 @@ import {Component, OnInit} from '@angular/core'; import {Project, ProjectControllerService} from "@redaction/red-ui-http"; -import {Observable} from "rxjs"; import {MatDialog} from "@angular/material/dialog"; import {AddEditProjectDialogComponent} from "./add-edit-project-dialog/add-edit-project-dialog.component"; +import {ConfirmationDialogComponent} from "../../common/confirmation-dialog/confirmation-dialog.component"; +import {TranslateService} from "@ngx-translate/core"; +import {NotificationService} from "../../notification/notification.service"; +import {AppStateService} from "../../state/app-state.service"; @Component({ selector: 'redaction-project-listing-screen', @@ -11,20 +14,25 @@ import {AddEditProjectDialogComponent} from "./add-edit-project-dialog/add-edit- }) export class ProjectListingScreenComponent implements OnInit { - projects$: Observable; - constructor(private readonly _projectControllerService: ProjectControllerService, private readonly _dialog: MatDialog) { + constructor( + public readonly appStateService: AppStateService, + private readonly _projectControllerService: ProjectControllerService, + private readonly _translateService: TranslateService, + private readonly _notificationService: NotificationService, + private readonly _dialog: MatDialog) { } ngOnInit(): void { this._reloadProjects(); } - openAddProjectDialog(): void { + openAddProjectDialog(project?: Project): void { const dialogRef = this._dialog.open(AddEditProjectDialogComponent, { width: '400px', maxWidth: '90vw', - autoFocus: false + autoFocus: false, + data: project }); dialogRef.afterClosed().subscribe(result => { @@ -33,7 +41,34 @@ export class ProjectListingScreenComponent implements OnInit { } private _reloadProjects() { - this.projects$ = this._projectControllerService.getProjects(); + this.appStateService.reset(); + this.appStateService.loadAllProjects().subscribe(() => { + }); } + editProject($event: MouseEvent, project: Project) { + $event.stopPropagation(); + this.openAddProjectDialog(project); + } + + deleteProject($event: MouseEvent, project: Project) { + $event.stopPropagation(); + const dialogRef = this._dialog.open(ConfirmationDialogComponent, { + width: '400px', + maxWidth: '90vw', + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this._projectControllerService.deleteProject(project.projectId).subscribe(result => { + this._reloadProjects(); + }, () => { + this._notificationService.showToastNotification(this._translateService.instant('projects.delete.delete-failed.label', project)) + }); + } + + + }); + } } diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html index fe70ac3ef..cd1655470 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html @@ -1 +1,44 @@ -

project-overview-screen works!

+
+ + + +
{{appStateService.activeProject?.description}}
+
+
+
+
+
+ {{fileStatus.filename}} +
+
+ {{'project-overview.file-listing.file-entry.status.label'| translate:fileStatus}} +
+
+ {{'project-overview.file-listing.file-entry.number-of-pages.label'| translate:fileStatus}} +
+
+ {{'project-overview.file-listing.file-entry.number-of-analyses.label'| translate:fileStatus}} +
+
+ {{'project-overview.file-listing.file-entry.added.label'| translate:{added: fileStatus.added | date:'short'} }} +
+
+ {{'project-overview.file-listing.file-entry.last-updated.label'| translate:{lastUpdated: fileStatus.lastUpdated | date:'short'} }} +
+
+
+ +
+
+
+ diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss index e69de29bb..4ed1690b6 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss @@ -0,0 +1,4 @@ + +.file-upload-input{ + display: none; +} diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts index 06eb44984..f5c0f0988 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts @@ -1,4 +1,19 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit} 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"; +import {MatDialog} from "@angular/material/dialog"; +import {AppStateService} from "../../state/app-state.service"; @Component({ selector: 'redaction-project-overview-screen', @@ -7,9 +22,63 @@ import { Component, OnInit } from '@angular/core'; }) export class ProjectOverviewScreenComponent implements OnInit { - constructor() { } + projectId: string; + + constructor(public readonly appStateService: AppStateService, + private readonly _activatedRoute: ActivatedRoute, + private readonly _statusControllerService: StatusControllerService, + private readonly _translateService: TranslateService, + private readonly _notificationService: NotificationService, + private readonly _dialog: MatDialog, + private readonly _router: Router, + private readonly _fileUploadControllerService: FileUploadControllerService, + private readonly _projectControllerService: ProjectControllerService) { + this._activatedRoute.params.subscribe(params => { + this.projectId = params.projectId; + this._loadProject(); + }); + } ngOnInit(): void { } + private _loadProject() { + this.appStateService.activateProject(this.projectId).subscribe(()=>{}); + } + + handleFileInput(files: File[]) { + for (let i = 0; i < files.length; i++) { + const file = files[i]; + this._fileUploadControllerService.uploadFileForm(file, this.projectId, 'response').subscribe(() => { + this._getFileStatus(); + }, () => { + this._notificationService.showToastNotification(this._translateService.instant('project-overview.upload-error.label', file)) + }) + } + } + + private _getFileStatus() { + this.appStateService.getActiveProjectStatus().subscribe(()=>{}); + } + + deleteFile($event: MouseEvent, fileStatus: FileStatus) { + $event.stopPropagation(); + const dialogRef = this._dialog.open(ConfirmationDialogComponent, { + width: '400px', + maxWidth: '90vw', + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this._fileUploadControllerService.deleteFile(fileStatus.projectId, fileStatus.fileId).subscribe(result => { + this._getFileStatus(); + }, () => { + this._notificationService.showToastNotification(this._translateService.instant('project-overview.delete-file-error.label', fileStatus)) + }); + } + + + }); + } } diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts new file mode 100644 index 000000000..bed41832d --- /dev/null +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -0,0 +1,73 @@ +import {Injectable} from "@angular/core"; +import {FileStatus, Project, ProjectControllerService, StatusControllerService} from "@redaction/red-ui-http"; +import {map, mergeMap, tap} from "rxjs/operators"; +import {File} from "@angular/compiler-cli/src/ngtsc/file_system/testing/src/mock_file_system"; + +@Injectable({ + providedIn: 'root' +}) +export class AppStateService { + + private _projects: Project[]; + private _activeProject: Project; + private _activeProjectFiles: FileStatus[]; + private _activeFile: FileStatus; + + constructor(private readonly _projectControllerService: ProjectControllerService, + private readonly _statusControllerService: StatusControllerService) { + } + + loadAllProjects() { + return this._projectControllerService.getProjects().pipe(tap((projects: Project[]) => { + this._projects = projects; + })); + } + + activateProject(projectId: string) { + this._activeProjectFiles = null; + this._activeFile = null; + return this._projectControllerService.getProject(projectId).pipe(tap(project => { + this._activeProject = project; + })).pipe(mergeMap(() => { + return this.getActiveProjectStatus(); + })); + } + + getActiveProjectStatus() { + return this._statusControllerService.getProjectStatus(this._activeProject.projectId).pipe(tap((files: FileStatus[]) => { + this._activeProjectFiles = files; + })) + } + + activateFile(projectId: string, fileId: string) { + return this.activateProject(projectId).pipe(map((files: FileStatus[]) => { + const file = files.find(f => f.fileId === fileId); + this._activeFile = file; + return file; + })); + } + + + get allProjects(): Project[] { + return this._projects; + } + + get activeProject(): Project { + return this._activeProject; + } + + get projectFiles(): FileStatus[] { + return this._activeProjectFiles; + } + + get activeFile(): FileStatus { + return this._activeFile; + } + + reset() { + this._activeProject = null; + this._activeProjectFiles = null; + this._activeFile = null; + } + +} diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 6d9fccc45..24d8a9642 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -2,5 +2,5 @@ "KEYCLOAK_URL": "https://keycloak-dev.iqser.cloud/auth", "KEYCLOAK_REALM": "dev", "KEYCLOAK_CLIENT_ID": "gin-client", - "API_URL": "http://ingress.redaction-timo.178.63.47.73.xip.io" + "API_URL": "http://ingress.redaction-timo-dev.178.63.47.73.xip.io" } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 3d4d1f0f8..b180a81ed 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -1,4 +1,20 @@ { + "common": { + "confirmation-dialog": { + "title": { + "label": "Confirm Action" + }, + "description": { + "label": "This action requires confirmation, do you wish to proceed?" + }, + "confirm": { + "label": "Yes" + }, + "deny": { + "label": "No" + } + } + }, "top-bar": { "navigation-items": { "projects": { @@ -20,7 +36,7 @@ "label": "New Project" }, "header-edit": { - "label": "New Project" + "label": "Edit Project" }, "form": { "description": { @@ -39,11 +55,52 @@ "header": { "label": "Projects" }, + "delete": { + "delete-failed": { + "label": "Failed to delete project: {{projectName}}" + } + }, "add-new": { "label": "New Project" }, "no-projects": { "label": "You currently have no projects. You can start your work by creating a new one!" } + }, + "project-overview": { + "upload-error": { + "label": "Failed to upload file: {{name}}" + }, + "delete-file-error": { + "label": "Failed to delete file: {{filename}}" + }, + "file-listing": { + "file-entry": { + "status": { + "label": "Status: {{status}}" + }, + "number-of-pages": { + "label": "Number of pages: {{numberOfPages}}" + }, + "number-of-analyses": { + "label": "Analysis count: {{numberOfAnalyses}}" + }, + "added": { + "label": "Date added: {{added}}" + }, + "last-updated": { + "label": "Last updated: {{lastUpdated}}" + } + } + }, + "header": { + "label": "Project Overview" + }, + "upload-files": { + "label": "Upload Files" + }, + "no-project": { + "label": "Requested project: {{projectId}} does not exist! Back to Project Listing. " + } } } diff --git a/apps/red-ui/src/assets/icons/general/download_icon.svg b/apps/red-ui/src/assets/icons/general/download_icon.svg new file mode 100755 index 000000000..2c72353f2 --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/download_icon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/apps/red-ui/src/assets/icons/general/edit_icon.svg b/apps/red-ui/src/assets/icons/general/edit_icon.svg new file mode 100755 index 000000000..cfed2c3eb --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/edit_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/red-ui/src/assets/icons/general/logout_icon.svg b/apps/red-ui/src/assets/icons/general/logout_icon.svg new file mode 100755 index 000000000..1e5920d58 --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/logout_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/red-ui/src/assets/icons/general/preview_icon.svg b/apps/red-ui/src/assets/icons/general/preview_icon.svg new file mode 100644 index 000000000..0b444d8fc --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/preview_icon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/apps/red-ui/src/assets/icons/general/trash_icon.svg b/apps/red-ui/src/assets/icons/general/trash_icon.svg new file mode 100755 index 000000000..98fbf50bc --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/trash_icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/styles/page-layout.scss b/assets/styles/page-layout.scss index 17bc3f38f..ec49ef12d 100644 --- a/assets/styles/page-layout.scss +++ b/assets/styles/page-layout.scss @@ -1,3 +1,6 @@ +@import "red-variables"; +@import "red-mixins"; + html, body { margin: 0; padding: 0; @@ -5,9 +8,119 @@ html, body { font-family: 'Inter', sans-serif; } -.page-header{ +.page-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 40px; } + + +.listing { + width: 100%; + display: inline-flex; + flex-wrap: wrap; + + .list-entry { + box-sizing: border-box; + height: 122px; + width: 310px; + border: 1px solid $grey-1; + border-radius: 2px; + background-color: $white; + padding: 24px; + margin-right: 22px; + margin-bottom: 22px; + display: flex; + flex-direction: row; + transition: background-color 0.35s ease-in-out; + + &.xl { + width: 100%; + padding: 16px 24px; + } + + &:hover { + background-color: $grey-1; + cursor: pointer; + color: $white; + + .list-entry-actions { + mat-icon { + opacity: 1; + } + } + + .listing-title, .listing-subtitle{ + color: $white; + } + } + + .list-entry-content { + display: flex; + flex: 1; + flex-direction: column; + } + + .list-entry-actions { + width: 18px; + margin-left: 22px; + display: flex; + flex-direction: column; + margin-top: -4px; + + mat-icon { + opacity: 0; + transition: opacity 0.35s ease-in-out; + width: 18px; + height: 18px; + } + } + + .listing-title { + height: 44px; + color: #283241; + font-family: Inter, sans-serf, serif; + font-size: 18px; + font-weight: bold; + letter-spacing: 0; + margin-bottom: 17px; + line-height: 22px; + @include line-clamp(2); + transition: color 0.35s ease-in-out; + + &.one-line { + height: 22px; + @include line-clamp(1); + } + + &.slim { + margin-bottom: 9px; + } + + &.break-all { + word-break: break-all; + } + } + + .listing-subtitle { + height: 12px; + opacity: 0.7; + color: #283241; + font-family: Inconsolata, monospace, monospace; + font-size: 12px; + letter-spacing: 0; + line-height: 12px; + @include line-clamp(1); + transition: color 0.35s ease-in-out; + } + } + +} + + +.break-40 { + height: 40px; + background: transparent; + display: block; +} diff --git a/assets/styles/red-dialog.scss b/assets/styles/red-dialog.scss index 3fc5ed717..d9df8879e 100644 --- a/assets/styles/red-dialog.scss +++ b/assets/styles/red-dialog.scss @@ -24,5 +24,9 @@ .dialog-actions { padding-top: 12px; + + > * { + margin-right: 16px + } } } diff --git a/assets/styles/red-text-styles.scss b/assets/styles/red-text-styles.scss index e263b2d0a..30d4b3221 100644 --- a/assets/styles/red-text-styles.scss +++ b/assets/styles/red-text-styles.scss @@ -1,13 +1,21 @@ @import "red-variables"; +@import "red-mixins"; button { font-family: Inconsolata, monospace !important; font-weight: 700 !important; } +a { + color: $blue-1; + + &:hover { + color: lighten($blue-1, 10%) + } + +} + .heading-xl { - height: 39px; - width: 130px; color: $grey-1; font-family: Inter, sans-serf; font-size: 32px; @@ -16,8 +24,7 @@ button { line-height: 39px; } -.heading-l{ - height: 22px; +.heading-l { color: #283241; font-family: Inter, sans-serf; font-size: 18px; @@ -25,3 +32,12 @@ button { letter-spacing: 0; line-height: 22px; } + + +.clamp-1{ + @include line-clamp(1); +} + +.clamp-2{ + @include line-clamp(2); +} diff --git a/libs/red-ui-http/src/lib/api/debugController.service.ts b/libs/red-ui-http/src/lib/api/debugController.service.ts index 95d758aa9..5a4f6ce78 100644 --- a/libs/red-ui-http/src/lib/api/debugController.service.ts +++ b/libs/red-ui-http/src/lib/api/debugController.service.ts @@ -119,7 +119,7 @@ export class DebugControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/debug/classification`, + return this.httpClient.request('post',`${this.basePath}/debug/classification`, { body: convertFormParamsToString ? formParams.toString() : formParams, params: queryParameters, @@ -196,7 +196,7 @@ export class DebugControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/debug/htmlTables`, + return this.httpClient.request('post',`${this.basePath}/debug/htmlTables`, { body: convertFormParamsToString ? formParams.toString() : formParams, params: queryParameters, @@ -273,7 +273,7 @@ export class DebugControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/debug/sections`, + return this.httpClient.request('post',`${this.basePath}/debug/sections`, { body: convertFormParamsToString ? formParams.toString() : formParams, params: queryParameters, @@ -355,7 +355,7 @@ export class DebugControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/debug/redaction`, + return this.httpClient.request('post',`${this.basePath}/debug/redaction`, { body: convertFormParamsToString ? formParams.toString() : formParams, params: queryParameters, diff --git a/libs/red-ui-http/src/lib/api/dictionaryController.service.ts b/libs/red-ui-http/src/lib/api/dictionaryController.service.ts index 3f8a04337..061a9aa34 100644 --- a/libs/red-ui-http/src/lib/api/dictionaryController.service.ts +++ b/libs/red-ui-http/src/lib/api/dictionaryController.service.ts @@ -106,7 +106,7 @@ export class DictionaryControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/dictionary/${encodeURIComponent(String(type))}`, + return this.httpClient.request('post',`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, { body: body, withCredentials: this.configuration.withCredentials, @@ -160,7 +160,7 @@ export class DictionaryControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/dictionary/type`, + return this.httpClient.request('post',`${this.basePath}/dictionary/type`, { body: body, withCredentials: this.configuration.withCredentials, @@ -219,7 +219,7 @@ export class DictionaryControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('delete',`${this.basePath}/redaction-gateway-v1/dictionary/${encodeURIComponent(String(type))}`, + return this.httpClient.request('delete',`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, { body: body, withCredentials: this.configuration.withCredentials, @@ -268,7 +268,7 @@ export class DictionaryControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('delete',`${this.basePath}/redaction-gateway-v1/dictionary/type/${encodeURIComponent(String(type))}`, + return this.httpClient.request('delete',`${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -317,7 +317,7 @@ export class DictionaryControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/dictionary/download/${encodeURIComponent(String(type))}`, + return this.httpClient.request('get',`${this.basePath}/dictionary/download/${encodeURIComponent(String(type))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -361,7 +361,7 @@ export class DictionaryControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/dictionary/type`, + return this.httpClient.request('get',`${this.basePath}/dictionary/type`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -405,7 +405,7 @@ export class DictionaryControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/color`, + return this.httpClient.request('get',`${this.basePath}/color`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -454,7 +454,7 @@ export class DictionaryControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/dictionary/${encodeURIComponent(String(type))}`, + return this.httpClient.request('get',`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -507,7 +507,7 @@ export class DictionaryControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/color`, + return this.httpClient.request('post',`${this.basePath}/color`, { body: body, withCredentials: this.configuration.withCredentials, @@ -566,7 +566,7 @@ export class DictionaryControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/dictionary/type/${encodeURIComponent(String(type))}`, + return this.httpClient.request('post',`${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`, { body: body, withCredentials: this.configuration.withCredentials, @@ -639,7 +639,7 @@ export class DictionaryControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/dictionary/upload/${encodeURIComponent(String(type))}`, + return this.httpClient.request('post',`${this.basePath}/dictionary/upload/${encodeURIComponent(String(type))}`, { body: convertFormParamsToString ? formParams.toString() : formParams, withCredentials: this.configuration.withCredentials, diff --git a/libs/red-ui-http/src/lib/api/fileUploadController.service.ts b/libs/red-ui-http/src/lib/api/fileUploadController.service.ts index c2b354c19..3b9e2ac30 100644 --- a/libs/red-ui-http/src/lib/api/fileUploadController.service.ts +++ b/libs/red-ui-http/src/lib/api/fileUploadController.service.ts @@ -98,7 +98,7 @@ export class FileUploadControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('delete',`${this.basePath}/redaction-gateway-v1/delete/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('delete',`${this.basePath}/delete/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -154,8 +154,9 @@ export class FileUploadControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/download/annotated/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('get',`${this.basePath}/download/annotated/${encodeURIComponent(String(fileId))}`, { + responseType: 'blob', params: queryParameters, withCredentials: this.configuration.withCredentials, headers: headers, @@ -211,8 +212,9 @@ export class FileUploadControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/download/original/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('get',`${this.basePath}/download/original/${encodeURIComponent(String(fileId))}`, { + responseType: 'blob', params: queryParameters, withCredentials: this.configuration.withCredentials, headers: headers, @@ -268,8 +270,9 @@ export class FileUploadControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/download/redacted/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('get',`${this.basePath}/download/redacted/${encodeURIComponent(String(fileId))}`, { + responseType: 'blob', params: queryParameters, withCredentials: this.configuration.withCredentials, headers: headers, @@ -330,7 +333,7 @@ export class FileUploadControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/download/report`, + return this.httpClient.request('post',`${this.basePath}/download/report`, { body: body, params: queryParameters, @@ -388,7 +391,7 @@ export class FileUploadControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/download/report/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('get',`${this.basePath}/download/report/${encodeURIComponent(String(projectId))}`, { params: queryParameters, withCredentials: this.configuration.withCredentials, @@ -462,12 +465,13 @@ export class FileUploadControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/upload/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('post',`${this.basePath}/upload/${encodeURIComponent(String(projectId))}`, { body: convertFormParamsToString ? formParams.toString() : formParams, withCredentials: this.configuration.withCredentials, headers: headers, - observe: observe, + observe: 'response', + responseType: 'text', reportProgress: reportProgress } ); diff --git a/libs/red-ui-http/src/lib/api/licenseReportController.service.ts b/libs/red-ui-http/src/lib/api/licenseReportController.service.ts index a0171e25a..e62ad4937 100644 --- a/libs/red-ui-http/src/lib/api/licenseReportController.service.ts +++ b/libs/red-ui-http/src/lib/api/licenseReportController.service.ts @@ -112,7 +112,7 @@ export class LicenseReportControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/report/license`, + return this.httpClient.request('post',`${this.basePath}/report/license`, { body: body, params: queryParameters, diff --git a/libs/red-ui-http/src/lib/api/manualRedactionController.service.ts b/libs/red-ui-http/src/lib/api/manualRedactionController.service.ts index dbd24cfc3..c3774d8fa 100644 --- a/libs/red-ui-http/src/lib/api/manualRedactionController.service.ts +++ b/libs/red-ui-http/src/lib/api/manualRedactionController.service.ts @@ -99,7 +99,7 @@ export class ManualRedactionControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/manualRedaction/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('get',`${this.basePath}/manualRedaction/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -162,7 +162,7 @@ export class ManualRedactionControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/manualRedaction/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('post',`${this.basePath}/manualRedaction/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, { body: body, withCredentials: this.configuration.withCredentials, diff --git a/libs/red-ui-http/src/lib/api/pdfMetaDataConfigurationController.service.ts b/libs/red-ui-http/src/lib/api/pdfMetaDataConfigurationController.service.ts index 161ecf805..8925fa9a6 100644 --- a/libs/red-ui-http/src/lib/api/pdfMetaDataConfigurationController.service.ts +++ b/libs/red-ui-http/src/lib/api/pdfMetaDataConfigurationController.service.ts @@ -89,7 +89,7 @@ export class PdfMetaDataConfigurationControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/metaData`, + return this.httpClient.request('get',`${this.basePath}/metaData`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -142,7 +142,7 @@ export class PdfMetaDataConfigurationControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/metaData`, + return this.httpClient.request('post',`${this.basePath}/metaData`, { body: body, withCredentials: this.configuration.withCredentials, diff --git a/libs/red-ui-http/src/lib/api/projectController.service.ts b/libs/red-ui-http/src/lib/api/projectController.service.ts index d8fc7b4ab..b1f3f3d2a 100644 --- a/libs/red-ui-http/src/lib/api/projectController.service.ts +++ b/libs/red-ui-http/src/lib/api/projectController.service.ts @@ -100,7 +100,7 @@ export class ProjectControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/project`, + return this.httpClient.request('post',`${this.basePath}/project`, { body: body, withCredentials: this.configuration.withCredentials, @@ -149,7 +149,7 @@ export class ProjectControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('delete',`${this.basePath}/redaction-gateway-v1/project/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('delete',`${this.basePath}/project/${encodeURIComponent(String(projectId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -198,7 +198,7 @@ export class ProjectControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/project/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('get',`${this.basePath}/project/${encodeURIComponent(String(projectId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -242,7 +242,7 @@ export class ProjectControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/redaction-gateway-v1/project`, + return this.httpClient.request>('get',`${this.basePath}/project`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -301,7 +301,7 @@ export class ProjectControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/project/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('post',`${this.basePath}/project/${encodeURIComponent(String(projectId))}`, { body: body, withCredentials: this.configuration.withCredentials, diff --git a/libs/red-ui-http/src/lib/api/reanalysisController.service.ts b/libs/red-ui-http/src/lib/api/reanalysisController.service.ts index b5d49b807..779d4c6cc 100644 --- a/libs/red-ui-http/src/lib/api/reanalysisController.service.ts +++ b/libs/red-ui-http/src/lib/api/reanalysisController.service.ts @@ -97,7 +97,7 @@ export class ReanalysisControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/reanalyse/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('post',`${this.basePath}/reanalyse/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -145,7 +145,7 @@ export class ReanalysisControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/reanalyse/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request('post',`${this.basePath}/reanalyse/${encodeURIComponent(String(projectId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, diff --git a/libs/red-ui-http/src/lib/api/redactionLogController.service.ts b/libs/red-ui-http/src/lib/api/redactionLogController.service.ts index f975e95ae..2f81c8e27 100644 --- a/libs/red-ui-http/src/lib/api/redactionLogController.service.ts +++ b/libs/red-ui-http/src/lib/api/redactionLogController.service.ts @@ -94,7 +94,7 @@ export class RedactionLogControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/redactionLog/${encodeURIComponent(String(fileId))}`, + return this.httpClient.request('get',`${this.basePath}/redactionLog/${encodeURIComponent(String(fileId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, diff --git a/libs/red-ui-http/src/lib/api/rulesController.service.ts b/libs/red-ui-http/src/lib/api/rulesController.service.ts index 13c7dfa38..80288338c 100644 --- a/libs/red-ui-http/src/lib/api/rulesController.service.ts +++ b/libs/red-ui-http/src/lib/api/rulesController.service.ts @@ -89,7 +89,7 @@ export class RulesControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/rules`, + return this.httpClient.request('get',`${this.basePath}/rules`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -133,7 +133,7 @@ export class RulesControllerService { const consumes: string[] = [ ]; - return this.httpClient.request('get',`${this.basePath}/redaction-gateway-v1/rules/download`, + return this.httpClient.request('get',`${this.basePath}/rules/download`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -186,7 +186,7 @@ export class RulesControllerService { headers = headers.set('Content-Type', httpContentTypeSelected); } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/rules`, + return this.httpClient.request('post',`${this.basePath}/rules`, { body: body, withCredentials: this.configuration.withCredentials, @@ -254,7 +254,7 @@ export class RulesControllerService { formParams = formParams.append('file', file) as any || formParams; } - return this.httpClient.request('post',`${this.basePath}/redaction-gateway-v1/rules/upload`, + return this.httpClient.request('post',`${this.basePath}/rules/upload`, { body: convertFormParamsToString ? formParams.toString() : formParams, withCredentials: this.configuration.withCredentials, diff --git a/libs/red-ui-http/src/lib/api/statusController.service.ts b/libs/red-ui-http/src/lib/api/statusController.service.ts index 0b455e95c..85b7c7cf9 100644 --- a/libs/red-ui-http/src/lib/api/statusController.service.ts +++ b/libs/red-ui-http/src/lib/api/statusController.service.ts @@ -94,7 +94,7 @@ export class StatusControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/redaction-gateway-v1/status/${encodeURIComponent(String(projectId))}`, + return this.httpClient.request>('get',`${this.basePath}/status/${encodeURIComponent(String(projectId))}`, { withCredentials: this.configuration.withCredentials, headers: headers, diff --git a/workspace.json b/workspace.json index a3fa20529..3b9543f85 100644 --- a/workspace.json +++ b/workspace.json @@ -23,10 +23,23 @@ "aot": true, "assets": [ "apps/red-ui/src/favicon.ico", - { "glob": "**/*", "input": "apps/red-ui/src/assets/", "output": "/assets/" } + { + "glob": "**/*", + "input": "node_modules/@pdftron/webviewer/public/", + "output": "/assets/wv-resources/" + }, + { + "glob": "**/*", + "input": "apps/red-ui/src/assets/", + "output": "/assets/" + } ], - "styles": ["apps/red-ui/src/styles.scss"], - "scripts": [] + "styles": [ + "apps/red-ui/src/styles.scss" + ], + "scripts": [ + "node_modules/@pdftron/webviewer/webviewer.min.js" + ] }, "configurations": { "production": { @@ -62,7 +75,8 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "red-ui:build" + "browserTarget": "red-ui:build", + "proxyConfig": "apps/red-ui/proxy.conf.json" }, "configurations": { "production": { @@ -83,7 +97,10 @@ "apps/red-ui/tsconfig.app.json", "apps/red-ui/tsconfig.spec.json" ], - "exclude": ["**/node_modules/**", "!apps/red-ui/**/*"] + "exclude": [ + "**/node_modules/**", + "!apps/red-ui/**/*" + ] } }, "test": { @@ -108,7 +125,10 @@ "libs/red-ui-http/tsconfig.lib.json", "libs/red-ui-http/tsconfig.spec.json" ], - "exclude": ["**/node_modules/**", "!libs/red-ui-http/**/*"] + "exclude": [ + "**/node_modules/**", + "!libs/red-ui-http/**/*" + ] } }, "test": {