This commit is contained in:
Timo Bejan 2020-09-22 10:46:37 +03:00
parent 254f5e00b5
commit 2b011a34bb
27 changed files with 1054 additions and 104 deletions

View File

@ -32,7 +32,8 @@
"glob": "**/*",
"input": "apps/red-ui/src/assets/",
"output": "/assets/"
}
},
"apps/red-ui/src/manifest.webmanifest"
],
"styles": [
"apps/red-ui/src/styles.scss"
@ -68,7 +69,9 @@
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
],
"serviceWorker": true,
"ngswConfigPath": "apps/red-ui/ngsw-config.json"
}
}
},
@ -147,7 +150,8 @@
}
},
"cli": {
"defaultCollection": "@nrwl/angular"
"defaultCollection": "@nrwl/angular",
"analytics": false
},
"schematics": {
"@nrwl/angular:application": {
@ -159,4 +163,4 @@
}
},
"defaultProject": "red-ui"
}
}

View File

@ -0,0 +1,30 @@
{
"$schema": "../../node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}

View File

@ -38,6 +38,9 @@ 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';
import {ToastrModule} from "ngx-toastr";
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -100,9 +103,11 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
MatTabsModule,
MatButtonToggleModule,
MatFormFieldModule,
ToastrModule.forRoot(),
MatSelectModule,
NgxDropzoneModule,
MatSidenavModule
MatSidenavModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
],
providers: [{
provide: KeycloakService,

View File

@ -33,4 +33,11 @@ export class LanguageService {
get currentLanguage() {
return this.translateService.currentLang;
}
changeLanguage(language: string) {
localStorage.setItem('redaction.language',language);
document.documentElement.lang = language;
this.translateService.use(language).subscribe(() => {
});
}
}

View File

@ -1,18 +1,36 @@
import {Injectable} from "@angular/core";
import {MatSnackBar} from "@angular/material/snack-bar";
import {ToastrService} from "ngx-toastr";
export enum NotificationType {
SUCCESS = 'SUCCESS', WARNING = 'WARNING', ERROR = 'ERROR', INFO = 'INFO',
}
@Injectable({
providedIn: 'root'
})
export class NotificationService {
constructor(private readonly _snackBar: MatSnackBar) {
constructor(private readonly _snackBar: MatSnackBar,
private readonly _toastr: ToastrService) {
}
showToastNotification(message: string) {
this._snackBar.open(message, null, {
duration: 5000
});
showToastNotification(message: string, title?: string, notificationType: NotificationType = NotificationType.INFO) {
switch (notificationType) {
case NotificationType.ERROR:
this._toastr.error(message, title);
break;
case NotificationType.SUCCESS:
this._toastr.success(message, title);
break;
case NotificationType.WARNING:
this._toastr.warning(message, title);
break
case NotificationType.INFO:
this._toastr.info(message, title);
break
}
}
}

View File

@ -31,6 +31,12 @@
<div class="menu right">
<button mat-button [matMenuTriggerFor]="menu" translate="top-bar.navigation-items.my-account.label"></button>
<mat-menu #menu="matMenu">
<button mat-menu-item [matMenuTriggerFor]="language" translate="top-bar.navigation-items.my-account.children.language.label"></button>
<mat-menu #language="matMenu">
<button mat-menu-item translate="top-bar.navigation-items.my-account.children.language.english.label" (click)="changeLanguage('en')"></button>
<button mat-menu-item translate="top-bar.navigation-items.my-account.children.language.german.label" (click)="changeLanguage('de')"></button>
</mat-menu>
<button mat-menu-item (click)="logout()">
<mat-icon svgIcon="red:logout">
</mat-icon>

View File

@ -5,6 +5,7 @@ import {ActivatedRoute} from "@angular/router";
import {Observable} from "rxjs";
import {map} from "rxjs/operators";
import {AppStateService} from "../../state/app-state.service";
import {LanguageService} from "../../i18n/language.service";
@Component({
selector: 'redaction-base-screen',
@ -16,6 +17,7 @@ export class BaseScreenComponent implements OnInit {
constructor(
public readonly appStateService: AppStateService,
private readonly _languageService: LanguageService,
private readonly _userService: UserService) {
}
@ -27,4 +29,7 @@ export class BaseScreenComponent implements OnInit {
this._userService.logout();
}
changeLanguage(language: string) {
this._languageService.changeLanguage(language);
}
}

View File

@ -2,7 +2,7 @@ import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {Project, ProjectControllerService} from "@redaction/red-ui-http";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {NotificationService} from "../../../notification/notification.service";
import {NotificationService, NotificationType} from "../../../notification/notification.service";
import {TranslateService} from "@ngx-translate/core";
@Component({
@ -37,13 +37,13 @@ export class AddEditProjectDialogComponent implements OnInit {
this._projectControllerService.updateProject(project, this.project.projectId).subscribe(() => {
this.dialogRef.close();
}, () => {
this._notificationService.showToastNotification(this._translateService.instant('projects.add-edit-dialog.errors.save'));
this._notificationService.showToastNotification(this._translateService.instant('projects.add-edit-dialog.errors.save'),null, NotificationType.ERROR);
})
} else {
this._projectControllerService.createProject(project).subscribe(() => {
this.dialogRef.close();
}, () => {
this._notificationService.showToastNotification(this._translateService.instant('projects.add-edit-dialog.errors.save'));
this._notificationService.showToastNotification(this._translateService.instant('projects.add-edit-dialog.errors.save'),null, NotificationType.ERROR);
})
}
}

View File

@ -4,7 +4,7 @@ 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 {NotificationService, NotificationType} from "../../notification/notification.service";
import {AppStateService} from "../../state/app-state.service";
@Component({
@ -62,11 +62,9 @@ export class ProjectListingScreenComponent implements OnInit {
this._projectControllerService.deleteProject(project.projectId).subscribe(result => {
this._reloadProjects();
}, () => {
this._notificationService.showToastNotification(this._translateService.instant('projects.delete.delete-failed.label', project))
this._notificationService.showToastNotification(this._translateService.instant('projects.delete.delete-failed.label', project), null, NotificationType.ERROR)
});
}
});
}
}

View File

@ -6,7 +6,7 @@ import {
ProjectControllerService,
StatusControllerService
} from "@redaction/red-ui-http";
import {NotificationService} from "../../notification/notification.service";
import {NotificationService, NotificationType} 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";
@ -24,13 +24,19 @@ export class ProjectOverviewScreenComponent implements OnInit {
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'
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;
@ -65,7 +71,7 @@ export class ProjectOverviewScreenComponent implements OnInit {
this._fileUploadControllerService.uploadFileForm(file, this.projectId, 'response').subscribe(() => {
this._getFileStatus();
}, () => {
this._notificationService.showToastNotification(this._translateService.instant('project-overview.upload-error.label', file))
this._notificationService.showToastNotification(this._translateService.instant('project-overview.upload-error.label', file), null, NotificationType.ERROR);
})
}
}
@ -88,11 +94,9 @@ export class ProjectOverviewScreenComponent implements OnInit {
this._fileUploadControllerService.deleteFile(fileStatus.projectId, fileStatus.fileId).subscribe(result => {
this._getFileStatus();
}, () => {
this._notificationService.showToastNotification(this._translateService.instant('project-overview.delete-file-error.label', fileStatus))
this._notificationService.showToastNotification(this._translateService.instant('project-overview.delete-file-error.label', fileStatus), null, NotificationType.ERROR);
});
}
});
}
@ -101,12 +105,10 @@ export class ProjectOverviewScreenComponent implements OnInit {
}
dragEnter($event: DragEvent) {
console.log('enter');
this.dragActive = true;
}
dragLeave($event: any) {
console.log('leave', this.dragActive);
this.dragActive = false;
}
}

View File

@ -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-dev.178.63.47.73.xip.io"
"API_URL": ""
}

View File

@ -0,0 +1,142 @@
{
"common": {
"confirmation-dialog": {
"title": {
"label": "Aktion bestätigen"
},
"description": {
"label": "Diese Aktion muss bestätigt werden. Möchten Sie fortfahren?"
},
"confirm": {
"label": "Ja"
},
"deny": {
"label": "Nein"
}
}
},
"top-bar": {
"navigation-items": {
"projects": {
"label": "Projekte"
},
"my-account": {
"label": "Mein Konto",
"children": {
"language": {
"label": "Sprache",
"english": {
"label": "Englisch"
},
"german": {
"label": "Deutsch"
}
},
"logout": {
"label": "Ausloggen"
}
}
}
}
},
"projects": {
"add-edit-dialog": {
"header-new": {
"label": "Neues Projekt"
},
"header-edit": {
"label": "Projekt bearbeiten"
},
"form": {
"description": {
"label": "Beschreibung"
},
"name": {
"label": "Name"
}
},
"actions": {
"save": {
"label": "Projekt speichern"
}
}
},
"header": {
"label": "Projekte"
},
"delete": {
"delete-failed": {
"label": "Projekt konnte nicht gelöscht werden: {{projectName}}"
}
},
"add-new": {
"label": "Neues Projekt"
},
"no-projects": {
"label": "Sie haben derzeit keine Projekte. Sie können Ihre Arbeit beginnen, indem Sie eine neue erstellen!"
}
},
"file-details": {
"dialog": {
"title": {
"label": "Dateidetails"
},
"actions": {
"download-redaction-report": {
"label": "Redaktionsbericht herunterladen"
}
}
}
},
"project-overview": {
"sorting": {
"label": "Sortierung",
"last-updated-desc": {
"label": "Zuletzt aktualisiert (Beschreibung)"
},
"last-updated-asc": {
"label": "Zuletzt aktualisiert (Asc)"
},
"file-name-desc": {
"label": "Name (Beschreibung)"
},
"file-name-asc": {
"label": "Name (Beschreibung)"
}
},
"upload-error": {
"label": "Datei konnte nicht hochgeladen werden: {{name}}"
},
"delete-file-error": {
"label": "Fehler beim Löschen der Datei: {{Dateiname}}"
},
"file-listing": {
"file-entry": {
"status": {
"label": "Status: {{status}}"
},
"number-of-pages": {
"label": "Anzahl der Seiten: {{numberOfPages}}"
},
"number-of-analyses": {
"label": "Anzahl der Analysen: {{numberOfAnalyses}}"
},
"added": {
"label": "Datum hinzugefügt: {{added}}"
},
"last-updated": {
"label": "Letzte Aktualisierung: {{lastUpdated}}"
}
}
},
"header": {
"label": "Projektübersicht"
},
"upload-files": {
"label": "Daten hochladen"
},
"no-project": {
"label": "Angefordertes Projekt: {{projectId}} existiert nicht! <a href='/ui/projects'>Zurück zur Projektliste.</a>"
}
}
}

View File

@ -23,6 +23,15 @@
"my-account": {
"label": "My Account",
"children": {
"language": {
"label": "Language",
"english": {
"label": "English"
},
"german": {
"label": "German"
}
},
"logout": {
"label": "Logout"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

View File

@ -1,13 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta charset="utf-8"/>
<title>Redaction</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<base href="/"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" type="image/x-icon" href="favicon.ico"/>
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#1976d2">
</head>
<body>
<redaction-root></redaction-root>
</body>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
</html>

View File

@ -0,0 +1,59 @@
{
"name": "red-ui",
"short_name": "red-ui",
"theme_color": "#1976d2",
"background_color": "#fafafa",
"display": "standalone",
"scope": "./",
"start_url": "./",
"icons": [
{
"src": "assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
}
]
}

View File

@ -1,5 +1,6 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@300;400;500;700&display=swap');
@import '~ngx-toastr/toastr';
@import "red-material-theme";
@import "page-layout";
@import "red-text-styles";

View File

@ -1,8 +1,14 @@
#!/bin/sh
KEYCLOAK_CLIENT_ID="${KEYCLOAK_CLIENT_ID:-false}"
KEYCLOAK_CLIENT_ID="${KEYCLOAK_CLIENT_ID:-gin-client}"
KEYCLOAK_URL="${KEYCLOAK_URL:-https://keycloak-dev.iqser.cloud/auth}"
KEYCLOAK_REALM="${KEYCLOAK_REALM:-dev}"
API_URL="${API_URL:-}"
echo '{
"KEYCLOAK_CLIENT_ID":"'"$KEYCLOAK_CLIENT_ID"' }' > /usr/share/nginx/html/config.json
"KEYCLOAK_CLIENT_ID":"'"$KEYCLOAK_CLIENT_ID"',
"KEYCLOAK_URL":"'"$KEYCLOAK_URL"',
"KEYCLOAK_REALM":"'"$KEYCLOAK_REALM"',
"API_URL":"'"$API_URL"'}' > /usr/share/nginx/html/config.json
nginx -g 'daemon off;'

View File

@ -31,13 +31,13 @@
"@angular/animations": "^10.0.0",
"@angular/cdk": "^10.2.1",
"@angular/common": "^10.0.0",
"@angular/compiler": "^10.0.0",
"@angular/core": "^10.0.0",
"@angular/forms": "^10.0.0",
"@angular/material": "^10.2.1",
"@angular/platform-browser": "^10.0.0",
"@angular/platform-browser-dynamic": "^10.0.0",
"@angular/router": "^10.0.0",
"@angular/service-worker": "^10.0.0",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@nrwl/angular": "^10.2.0",
@ -47,11 +47,14 @@
"keycloak-js": "10.0.2",
"ngp-sort-pipe": "^0.0.4",
"ngx-dropzone": "^2.2.2",
"ngx-toastr": "^13.0.0",
"rxjs": "~6.5.5",
"zone.js": "^0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1000.0",
"@angular/cli": "^10.1.2",
"@angular/compiler": "^10.0.0",
"@angular/compiler-cli": "^10.0.0",
"@angular/language-service": "^10.0.0",
"@nrwl/cypress": "10.2.0",
@ -63,9 +66,14 @@
"cypress": "^4.1.0",
"dotenv": "6.2.0",
"eslint": "6.8.0",
"google-translate-api-browser": "^1.1.71",
"jest": "26.2.2",
"jest-preset-angular": "8.2.1",
"lodash": "^4.17.20",
"moment": "^2.28.0",
"prettier": "2.0.4",
"superagent": "^6.1.0",
"superagent-promise": "^1.1.0",
"ts-jest": "26.1.4",
"ts-node": "~7.0.0",
"tslint": "~6.0.0",

773
yarn.lock

File diff suppressed because it is too large Load Diff