From fd138744713744756087ee36be44eb6c394a9b71 Mon Sep 17 00:00:00 2001 From: Florent Poittevin <florent.poittevin@unige.ch> Date: Tue, 18 Jun 2019 09:12:05 +0200 Subject: [PATCH] DLCM-572 Add breadcrumb component --- src/app/access/access-routing.module.ts | 4 + src/app/app-routing.module.ts | 10 ++ src/app/app.component.html | 2 + src/app/app.component.ts | 2 +- .../components/table/table.component.ts | 11 +- src/app/deposit/deposit-routing.module.ts | 10 ++ src/app/deposit/services/deposit.service.ts | 1 - .../components/table/table.component.ts | 21 ++- .../organizational-unit-routing.module.ts | 13 ++ .../breadcrumb/breadcrumb.component.html | 6 + .../breadcrumb/breadcrumb.component.scss | 30 ++++ .../breadcrumb/breadcrumb.component.spec.ts | 25 +++ .../breadcrumb/breadcrumb.component.ts | 90 ++++++++++ .../data-table/data-table.component.html | 2 +- src/app/shared/enums/api.enum.ts | 62 +++---- src/app/shared/models/breadcrumb.model.ts | 4 + src/app/shared/services/api.service.ts | 72 ++++---- src/app/shared/shared.module.ts | 2 + src/assets/i18n/de.json | 87 ++++++--- src/assets/i18n/en.json | 57 ++++-- src/assets/i18n/fr.json | 165 ++++++++++-------- 21 files changed, 486 insertions(+), 190 deletions(-) create mode 100644 src/app/shared/components/breadcrumb/breadcrumb.component.html create mode 100644 src/app/shared/components/breadcrumb/breadcrumb.component.scss create mode 100644 src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts create mode 100644 src/app/shared/components/breadcrumb/breadcrumb.component.ts create mode 100644 src/app/shared/models/breadcrumb.model.ts diff --git a/src/app/access/access-routing.module.ts b/src/app/access/access-routing.module.ts index 5bf54d141..f82bacd88 100644 --- a/src/app/access/access-routing.module.ts +++ b/src/app/access/access-routing.module.ts @@ -1,11 +1,15 @@ import {NgModule} from "@angular/core"; import {RouterModule, Routes} from "@angular/router"; import {AccessView} from "@app/access/views/access/access.view"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; const routes: Routes = [ { path: "", component: AccessView, + data: { + breadcrumb: TRANSLATE("breadcrumb.access.search"), + } }, ]; diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9374c5d26..1d515365f 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -2,6 +2,7 @@ import {NgModule} from "@angular/core"; import {RouterModule, Routes} from "@angular/router"; import {LoginComponent} from "@app/components/login/login.component"; import {PageNotFoundComponent} from "@app/components/page-not-found/page-not-found.component"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; export enum AppRoutesEnum { root = "", @@ -19,14 +20,23 @@ const routes: Routes = [ { path: AppRoutesEnum.access, loadChildren: "./access/access.module#AccessModule", + data: { + breadcrumb: TRANSLATE("breadcrumb.access.root"), + }, }, { path: AppRoutesEnum.deposit, loadChildren: "./deposit/deposit.module#DepositModule", + data: { + breadcrumb: TRANSLATE("breadcrumb.deposit.root"), + }, }, { path: AppRoutesEnum.organizationalUnit, loadChildren: "./organizational-unit/organizational-unit.module#OrganizationalUnitModule", + data: { + breadcrumb: TRANSLATE("breadcrumb.organizationalUnit.root"), + }, }, { path: AppRoutesEnum.login, diff --git a/src/app/app.component.html b/src/app/app.component.html index f6bc02a8a..497bd442c 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -19,6 +19,8 @@ <img [src]="logo" alt="yareta" class="instance-logo"> </div> + <dlcm-breadcrumb (navigateEvent)="navigate($event)"></dlcm-breadcrumb> + <main class="content mat-typography"> <router-outlet></router-outlet> </main> diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 746a9a51a..57a69836e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,5 @@ import {Component} from "@angular/core"; -import {Router, RouterStateSnapshot} from "@angular/router"; +import {Params, Router, RouterStateSnapshot} from "@angular/router"; import {ChangeAppLanguage, Logout} from "@app/app.action"; import {AppStateModel} from "@app/app.state"; import {BaseDirective} from "@app/shared/directives/base.directive"; diff --git a/src/app/deposit/components/table/table.component.ts b/src/app/deposit/components/table/table.component.ts index 61cc06547..9aed9c330 100644 --- a/src/app/deposit/components/table/table.component.ts +++ b/src/app/deposit/components/table/table.component.ts @@ -2,6 +2,7 @@ import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output} import {DepositsModel} from "@app/generated-api"; import {FieldTypeEnum} from "@app/shared/enums/field-type.enum"; import {DataTableColumnsModel} from "@app/shared/models/data-table-columns.model"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; import {TranslateService} from "@ngx-translate/core"; @Component({ @@ -26,11 +27,11 @@ export class TableComponent implements OnInit { ngOnInit() { // TODO Use typeof to get interface propertie name this.columns = [ - {field: "title", header: this.translate.instant("table.header.title")}, - {field: "publicationDate", header: this.translate.instant("table.header.publicationDate"), type: FieldTypeEnum.date}, - {field: "creation.when", header: this.translate.instant("table.header.creation.when"), type: FieldTypeEnum.datetime}, - {field: "lastUpdate.when", header: this.translate.instant("table.header.lastUpdate.when"), type: FieldTypeEnum.datetime}, - {field: "status", header: this.translate.instant("table.header.status")}, + {field: "title", header: TRANSLATE("deposit.table.header.title")}, + {field: "publicationDate", header: TRANSLATE("deposit.table.header.publicationDate"), type: FieldTypeEnum.date}, + {field: "creation.when", header: TRANSLATE("deposit.table.header.creation.when"), type: FieldTypeEnum.datetime}, + {field: "lastUpdate.when", header: TRANSLATE("deposit.table.header.lastUpdate.when"), type: FieldTypeEnum.datetime}, + {field: "status", header: TRANSLATE("deposit.table.header.status")}, ]; } diff --git a/src/app/deposit/deposit-routing.module.ts b/src/app/deposit/deposit-routing.module.ts index fa051c795..484f722fe 100644 --- a/src/app/deposit/deposit-routing.module.ts +++ b/src/app/deposit/deposit-routing.module.ts @@ -5,20 +5,30 @@ import {DetailView} from "@app/deposit/views/detail/detail.view"; import {ListView} from "@app/deposit/views/list/list.view"; import {DepositRoutesEnum} from "@app/shared/enums/routes.enum"; import {AppRoutesEnum} from "@app/app-routing.module"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; const routes: Routes = [ { path: AppRoutesEnum.root, component: ListView, + data: { + breadcrumb: TRANSLATE("breadcrumb.deposit.list"), + } }, { path: DepositRoutesEnum.detail + AppRoutesEnum.separator + AppRoutesEnum.paramId, component: DetailView, + data: { + breadcrumb: TRANSLATE("breadcrumb.deposit.detail"), + } }, { path: DepositRoutesEnum.create, component: CreateView, + data: { + breadcrumb: TRANSLATE("breadcrumb.deposit.create"), + } }, ]; diff --git a/src/app/deposit/services/deposit.service.ts b/src/app/deposit/services/deposit.service.ts index 7dfc8639e..f6cd80b30 100644 --- a/src/app/deposit/services/deposit.service.ts +++ b/src/app/deposit/services/deposit.service.ts @@ -11,7 +11,6 @@ export class DepositService { } getAll(): Observable<any> { - console.log("called"); return this.http.get("/api/preingest/deposits"); } } diff --git a/src/app/organizational-unit/components/table/table.component.ts b/src/app/organizational-unit/components/table/table.component.ts index e8a2f6dca..7490c078a 100644 --- a/src/app/organizational-unit/components/table/table.component.ts +++ b/src/app/organizational-unit/components/table/table.component.ts @@ -1,7 +1,9 @@ import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output} from "@angular/core"; import {DepositsModel, OrganizationalUnitsModel} from "@app/generated-api"; +import {BaseDirective} from "@app/shared/directives/base.directive"; import {FieldTypeEnum} from "@app/shared/enums/field-type.enum"; import {DataTableColumnsModel} from "@app/shared/models/data-table-columns.model"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; import {TranslateService} from "@ngx-translate/core"; @Component({ @@ -10,7 +12,7 @@ import {TranslateService} from "@ngx-translate/core"; styleUrls: ["./table.component.scss"], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class TableComponent implements OnInit { +export class TableComponent extends BaseDirective implements OnInit { @Input() organizationalUnits: OrganizationalUnitsModel[]; @@ -20,15 +22,26 @@ export class TableComponent implements OnInit { columns: DataTableColumnsModel[]; constructor(private translate: TranslateService) { + super(); this.selectEvent = new EventEmitter<string>(); } ngOnInit() { // TODO Use typeof to get interface propertie name this.columns = [ - {field: "name", header: this.translate.instant("table.header.name")}, - {field: "description", header: this.translate.instant("table.header.description")}, - {field: "creation.when", header: this.translate.instant("table.header.creation.when"), type: FieldTypeEnum.datetime}, + { + field: "name", + header: TRANSLATE("organizationalUnit.table.header.name"), + }, + { + field: "description", + header: TRANSLATE("organizationalUnit.table.header.description"), + }, + { + field: "creation.when", + header: TRANSLATE("organizationalUnit.table.header.creation.when"), + type: FieldTypeEnum.datetime, + }, ]; } diff --git a/src/app/organizational-unit/organizational-unit-routing.module.ts b/src/app/organizational-unit/organizational-unit-routing.module.ts index e817ee363..9736948b5 100644 --- a/src/app/organizational-unit/organizational-unit-routing.module.ts +++ b/src/app/organizational-unit/organizational-unit-routing.module.ts @@ -6,23 +6,36 @@ import {CreateView} from "@app/organizational-unit/views/create/create.view"; import {EditView} from "@app/organizational-unit/views/edit/edit.view"; import {ListView} from "@app/organizational-unit/views/list/list.view"; import {DetailView} from "@app/organizational-unit/views/detail/detail.view"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; const routes: Routes = [ { path: "", component: ListView, + data: { + breadcrumb: TRANSLATE("breadcrumb.organizationalUnit.list"), + } }, { path: OrganizationalUnitRoutesEnum.detail + AppRoutesEnum.separator + AppRoutesEnum.paramId, component: DetailView, + data: { + breadcrumb: TRANSLATE("breadcrumb.organizationalUnit.detail"), + } }, { path: OrganizationalUnitRoutesEnum.edit + AppRoutesEnum.separator + AppRoutesEnum.paramId, component: EditView, + data: { + breadcrumb: TRANSLATE("breadcrumb.organizationalUnit.edit"), + } }, { path: OrganizationalUnitRoutesEnum.create, component: CreateView, + data: { + breadcrumb: TRANSLATE("breadcrumb.organizationalUnit.create"), + } }, ]; diff --git a/src/app/shared/components/breadcrumb/breadcrumb.component.html b/src/app/shared/components/breadcrumb/breadcrumb.component.html new file mode 100644 index 000000000..4b4446057 --- /dev/null +++ b/src/app/shared/components/breadcrumb/breadcrumb.component.html @@ -0,0 +1,6 @@ +<ol class="breadcrumb"> + <li *ngFor="let breadcrumb of breadcrumbs$ | async" + class="breadcrumb-item"> + <a (click)="navigate(breadcrumb.url)">{{breadcrumb.label | translate}}</a> + </li> +</ol> diff --git a/src/app/shared/components/breadcrumb/breadcrumb.component.scss b/src/app/shared/components/breadcrumb/breadcrumb.component.scss new file mode 100644 index 000000000..a177177e1 --- /dev/null +++ b/src/app/shared/components/breadcrumb/breadcrumb.component.scss @@ -0,0 +1,30 @@ +@import "abstracts/variables"; + +.breadcrumb { + padding: 10px 25px; + margin: 0; + list-style: none !important; + list-style-type: none; + background-color: $background-grey; +} + +li { + display: inline; + font-size: 14px; +} + +li + li:before { + padding: 8px; + color: $dark-grey; + content: "/\00a0"; +} + +a { + color: $primary-color; + text-decoration: none; + + &:hover { + color: $accent-color; + text-decoration: underline; + } +} diff --git a/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts b/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts new file mode 100644 index 000000000..4ce30c375 --- /dev/null +++ b/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; + +import { BreadcrumbComponent } from "./breadcrumb.component"; + +describe("BreadcrumbComponent", () => { + let component: BreadcrumbComponent; + let fixture: ComponentFixture<BreadcrumbComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BreadcrumbComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BreadcrumbComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/breadcrumb/breadcrumb.component.ts b/src/app/shared/components/breadcrumb/breadcrumb.component.ts new file mode 100644 index 000000000..cea0a4209 --- /dev/null +++ b/src/app/shared/components/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,90 @@ +import {ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output} from "@angular/core"; +import {ActivatedRoute, NavigationEnd, Router} from "@angular/router"; +import {BaseDirective} from "@app/shared/directives/base.directive"; +import {BreadcrumbModel} from "@app/shared/models/breadcrumb.model"; +import {TRANSLATE} from "@app/shared/utils/translate.util"; +import {TranslateService} from "@ngx-translate/core"; +import {Observable} from "rxjs"; +import {distinctUntilChanged} from "rxjs/internal/operators/distinctUntilChanged"; +import {filter, map} from "rxjs/operators"; + +@Component({ + selector: "dlcm-breadcrumb", + templateUrl: "./breadcrumb.component.html", + styleUrls: ["./breadcrumb.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BreadcrumbComponent extends BaseDirective implements OnInit { + breadcrumbs$: Observable<BreadcrumbModel[]>; + + @Output() + navigateEvent: EventEmitter<string>; + + private readonly BREADCRUMB_KEY: string = "breadcrumb"; + private readonly BREADCRUMB_TRANSLATE_HOME: string = TRANSLATE("breadcrumb.home"); + + constructor(private translate: TranslateService, + private router: Router, + private activatedRoute: ActivatedRoute) { + super(); + this.navigateEvent = new EventEmitter<string>(); + } + + ngOnInit() { + this.breadcrumbs$ = this.router.events + .pipe( + filter(event => event instanceof NavigationEnd), + distinctUntilChanged(), + map(event => this.buildBreadCrumb(this.activatedRoute.root)), + ); + } + + buildBreadCrumb(route: ActivatedRoute, + url: string = "", + breadcrumbs: Array<BreadcrumbModel> = []): Array<BreadcrumbModel> { + const label = this.getLabel(route); + const path = this.getPath(route); + + const fullUrl = `${url}${path}/`; + + const breadcrumb: BreadcrumbModel = { + label, + url: fullUrl, + } as BreadcrumbModel; + + const newBreadcrumbs: BreadcrumbModel[] = [...breadcrumbs, breadcrumb]; + if (route.firstChild) { + return this.buildBreadCrumb(route.firstChild, fullUrl, newBreadcrumbs); + } + return newBreadcrumbs; + } + + private getLabel(route: ActivatedRoute): string { + if (route.routeConfig) { + return route.routeConfig.data[this.BREADCRUMB_KEY]; + } + + return this.BREADCRUMB_TRANSLATE_HOME; + } + + private getPath(route: ActivatedRoute) { + if (route.routeConfig) { + let path = route.routeConfig.path; + path = this.insertParametersInPath(route, path); + return path; + } + return ""; + } + + private insertParametersInPath(route: ActivatedRoute, path) { + const params = route.snapshot.params; + for (const key in params) { + path = path.replace(`:${key}`, params[key]); + } + return path; + } + + navigate(url: string): void { + this.navigateEvent.emit(url); + } +} diff --git a/src/app/shared/components/data-table/data-table.component.html b/src/app/shared/components/data-table/data-table.component.html index 57edc05ca..dcff15747 100644 --- a/src/app/shared/components/data-table/data-table.component.html +++ b/src/app/shared/components/data-table/data-table.component.html @@ -2,7 +2,7 @@ <ng-template pTemplate="header" let-columns> <tr> <th *ngFor="let col of columns"> - {{col.header}} + {{col.header | translate}} </th> </tr> </ng-template> diff --git a/src/app/shared/enums/api.enum.ts b/src/app/shared/enums/api.enum.ts index 62d894845..0b3ee6c4a 100644 --- a/src/app/shared/enums/api.enum.ts +++ b/src/app/shared/enums/api.enum.ts @@ -1,55 +1,55 @@ -const separator = '/'; +const separator = "/"; export class ResourceApiEnum { - static access = 'access'; - static admin = 'admin'; - static archivalStorage = 'archival-storage'; - static dataMgmt = 'data-mgmt'; - static ingest = 'ingest'; - static preingest = 'preingest'; - static preservationPlanning = 'preservation-planning'; - static resourceSrv = 'resource-srv'; + static access = "access"; + static admin = "admin"; + static archivalStorage = "archival-storage"; + static dataMgmt = "data-mgmt"; + static ingest = "ingest"; + static preingest = "preingest"; + static preservationPlanning = "preservation-planning"; + static resourceSrv = "resource-srv"; } export class AccessResourceApiEnum extends ResourceApiEnum { - static dip = ResourceApiEnum.access + separator + 'dip'; - static oaiSets = ResourceApiEnum.access + separator + 'oai-sets'; - static orders = ResourceApiEnum.access + separator + 'orders'; + static dip = ResourceApiEnum.access + separator + "dip"; + static oaiSets = ResourceApiEnum.access + separator + "oai-sets"; + static orders = ResourceApiEnum.access + separator + "orders"; } export class AdminResourceApiEnum extends ResourceApiEnum { - static fundingAgencies = ResourceApiEnum.admin + separator + 'funding-agencies'; - static institutions = ResourceApiEnum.admin + separator + 'institutions'; - static languages = ResourceApiEnum.admin + separator + 'languages'; - static licenses = ResourceApiEnum.admin + separator + 'licenses'; - static oauth2Clients = ResourceApiEnum.admin + separator + 'oauth2-clients'; - static organizationalUnits = ResourceApiEnum.admin + separator + 'organizational-units'; - static people = ResourceApiEnum.admin + separator + 'people'; - static preservationPolicies = ResourceApiEnum.admin + separator + 'preservation-policies'; - static roles = ResourceApiEnum.admin + separator + 'roles'; - static submissionAgreements = ResourceApiEnum.admin + separator + 'submission-agreements'; - static submissionPolicies = ResourceApiEnum.admin + separator + 'submission-policies'; - static users = ResourceApiEnum.admin + separator + 'users'; + static fundingAgencies = ResourceApiEnum.admin + separator + "funding-agencies"; + static institutions = ResourceApiEnum.admin + separator + "institutions"; + static languages = ResourceApiEnum.admin + separator + "languages"; + static licenses = ResourceApiEnum.admin + separator + "licenses"; + static oauth2Clients = ResourceApiEnum.admin + separator + "oauth2-clients"; + static organizationalUnits = ResourceApiEnum.admin + separator + "organizational-units"; + static people = ResourceApiEnum.admin + separator + "people"; + static preservationPolicies = ResourceApiEnum.admin + separator + "preservation-policies"; + static roles = ResourceApiEnum.admin + separator + "roles"; + static submissionAgreements = ResourceApiEnum.admin + separator + "submission-agreements"; + static submissionPolicies = ResourceApiEnum.admin + separator + "submission-policies"; + static users = ResourceApiEnum.admin + separator + "users"; } export class ArchivalStorageResourceApiEnum extends ResourceApiEnum { - static aip = ResourceApiEnum.archivalStorage + separator + 'aip'; - static storedAip = ResourceApiEnum.archivalStorage + separator + 'stored-aip'; + static aip = ResourceApiEnum.archivalStorage + separator + "aip"; + static storedAip = ResourceApiEnum.archivalStorage + separator + "stored-aip"; } export class IngestResourceApiEnum extends ResourceApiEnum { - static sip = ResourceApiEnum.ingest + separator + 'sip'; + static sip = ResourceApiEnum.ingest + separator + "sip"; } export class PreIngestResourceApiEnum extends ResourceApiEnum { - static deposits = ResourceApiEnum.preingest + separator + 'deposits'; + static deposits = ResourceApiEnum.preingest + separator + "deposits"; } export class PreservationPlanningResourceApiEnum extends ResourceApiEnum { - static preservationJobs = ResourceApiEnum.preservationPlanning + separator + 'preservation-jobs'; + static preservationJobs = ResourceApiEnum.preservationPlanning + separator + "preservation-jobs"; } export class ResourceSrvResourceApiEnum extends ResourceApiEnum { - static applicationRoles = ResourceApiEnum.resourceSrv + separator + 'application-roles'; - static basicAuthClients = ResourceApiEnum.resourceSrv + separator + 'basic-auth-clients'; + static applicationRoles = ResourceApiEnum.resourceSrv + separator + "application-roles"; + static basicAuthClients = ResourceApiEnum.resourceSrv + separator + "basic-auth-clients"; } diff --git a/src/app/shared/models/breadcrumb.model.ts b/src/app/shared/models/breadcrumb.model.ts new file mode 100644 index 000000000..770f68007 --- /dev/null +++ b/src/app/shared/models/breadcrumb.model.ts @@ -0,0 +1,4 @@ +export interface BreadcrumbModel { + label: string; + url: string; +} diff --git a/src/app/shared/services/api.service.ts b/src/app/shared/services/api.service.ts index b5bbc40a9..9f590bf25 100644 --- a/src/app/shared/services/api.service.ts +++ b/src/app/shared/services/api.service.ts @@ -1,14 +1,14 @@ -import {HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpResponse} from '@angular/common/http'; -import {Inject, Injectable, Optional} from '@angular/core'; -import {BASE_PATH, Configuration} from '@app/generated-api'; -import {CustomHttpUrlEncodingCodec} from '@app/generated-api/encoder'; -import {ResourceApiEnum} from '@app/shared/enums/api.enum'; -import {CollectionTypedModel} from '@app/shared/models/collection-typed.model'; -import {Observable} from 'rxjs'; +import {HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpResponse} from "@angular/common/http"; +import {Inject, Injectable, Optional} from "@angular/core"; +import {BASE_PATH, Configuration} from "@app/generated-api"; +import {CustomHttpUrlEncodingCodec} from "@app/generated-api/encoder"; +import {ResourceApiEnum} from "@app/shared/enums/api.enum"; +import {CollectionTypedModel} from "@app/shared/models/collection-typed.model"; +import {Observable} from "rxjs"; @Injectable() export class ApiService { - protected basePath = 'http://localhost'; + protected basePath = "http://localhost"; public defaultHeaders = new HttpHeaders(); public configuration = new Configuration(); @@ -33,10 +33,10 @@ export class ApiService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: 'body', reportProgress?: boolean): Observable<CollectionTypedModel<T>>; - public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<CollectionTypedModel<T>>>; - public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<CollectionTypedModel<T>>>; - public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe: any = 'body', reportProgress: boolean = false): Observable<any> { + public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: "body", reportProgress?: boolean): Observable<CollectionTypedModel<T>>; + public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<CollectionTypedModel<T>>>; + public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<CollectionTypedModel<T>>>; + public get<T>(path: ResourceApiEnum, size?: number, page?: number, sort?: string, filters?: { [key: string]: string; }, observe: any = "body", reportProgress: boolean = false): Observable<any> { const queryParameters = this.getQueryParameters(size, page, sort, filters); const headers = this.getHeaders(); @@ -62,10 +62,10 @@ export class ApiService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getById<T>(path: ResourceApiEnum, resId: string, observe?: 'body', reportProgress?: boolean): Observable<T>; - public getById<T>(path: ResourceApiEnum, resId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<T>>; - public getById<T>(path: ResourceApiEnum, resId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<T>>; - public getById<T>(path: ResourceApiEnum, resId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> { + public getById<T>(path: ResourceApiEnum, resId: string, observe?: "body", reportProgress?: boolean): Observable<T>; + public getById<T>(path: ResourceApiEnum, resId: string, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; + public getById<T>(path: ResourceApiEnum, resId: string, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; + public getById<T>(path: ResourceApiEnum, resId: string, observe: any = "body", reportProgress: boolean = false): Observable<any> { if (resId === null || resId === undefined) { throw new Error(`Required parameter resId was null or undefined when calling ${path}GetById.`); } @@ -89,10 +89,10 @@ export class ApiService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: 'body', reportProgress?: boolean): Observable<T>; - public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<T>>; - public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<T>>; - public deleteById<T>(path: ResourceApiEnum, resId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> { + public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: "body", reportProgress?: boolean): Observable<T>; + public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; + public deleteById<T>(path: ResourceApiEnum, resId: string, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; + public deleteById<T>(path: ResourceApiEnum, resId: string, observe: any = "body", reportProgress: boolean = false): Observable<any> { if (resId === null || resId === undefined) { throw new Error(`Required parameter resId was null or undefined when calling ${path}DeleteById.`); } @@ -117,12 +117,12 @@ export class ApiService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: 'body', reportProgress?: boolean): Observable<T>; - public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<T>>; - public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<T>>; - public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe: any = 'body', reportProgress: boolean = false): Observable<any> { + public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: "body", reportProgress?: boolean): Observable<T>; + public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; + public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; + public patchById<T>(path: ResourceApiEnum, resId: string, body?: object, observe: any = "body", reportProgress: boolean = false): Observable<any> { if (resId === null || resId === undefined) { - throw new Error('Required parameter resId was null or undefined when calling accessDipPatchById.'); + throw new Error("Required parameter resId was null or undefined when calling accessDipPatchById."); } let headers = this.getHeaders(); headers = this.addContentType(headers); @@ -146,10 +146,10 @@ export class ApiService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public post<T>(path: ResourceApiEnum, body?: object, observe?: 'body', reportProgress?: boolean): Observable<T>; - public post<T>(path: ResourceApiEnum, body?: object, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<T>>; - public post<T>(path: ResourceApiEnum, body?: object, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<T>>; - public post<T>(path: ResourceApiEnum, body?: object, observe: any = 'body', reportProgress: boolean = false): Observable<any> { + public post<T>(path: ResourceApiEnum, body?: object, observe?: "body", reportProgress?: boolean): Observable<T>; + public post<T>(path: ResourceApiEnum, body?: object, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; + public post<T>(path: ResourceApiEnum, body?: object, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; + public post<T>(path: ResourceApiEnum, body?: object, observe: any = "body", reportProgress: boolean = false): Observable<any> { let headers = this.getHeaders(); headers = this.addContentType(headers); @@ -167,13 +167,13 @@ export class ApiService { private getQueryParameters(size: number, page: number, sort: string, filters: { [p: string]: string }) { let queryParameters = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()}); if (size !== undefined && size !== null) { - queryParameters = queryParameters.set('size', size as any); + queryParameters = queryParameters.set("size", size as any); } if (page !== undefined && page !== null) { - queryParameters = queryParameters.set('page', page as any); + queryParameters = queryParameters.set("page", page as any); } if (sort !== undefined && sort !== null) { - queryParameters = queryParameters.set('sort', sort as any); + queryParameters = queryParameters.set("sort", sort as any); } if (filters !== undefined && filters !== null) { for (const key in filters) { @@ -188,22 +188,22 @@ export class ApiService { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/hal+json', + "application/hal+json", ]; const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); if (httpHeaderAcceptSelected !== undefined) { - headers = headers.set('Accept', httpHeaderAcceptSelected); + headers = headers.set("Accept", httpHeaderAcceptSelected); } return headers; } private addContentType(headers) { const consumes: string[] = [ - 'application/json', + "application/json", ]; const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); if (httpContentTypeSelected !== undefined) { - headers = headers.set('Content-Type', httpContentTypeSelected); + headers = headers.set("Content-Type", httpContentTypeSelected); } return headers; } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 02adfb4c4..2832f4afc 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -17,10 +17,12 @@ import {NgxsModule} from "@ngxs/store"; import {PaginatorModule} from "primeng/primeng"; import {TableModule} from "primeng/table"; import {BaseDirective} from "./directives/base.directive"; +import {BreadcrumbComponent} from "./components/breadcrumb/breadcrumb.component"; const components = [ SearchComponent, DataTableComponent, + BreadcrumbComponent, ]; const directives = [ BaseDirective, diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 08aa20924..8b9d973ad 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -1,14 +1,34 @@ { "app": { "login": { - "loginButton": "Log In", - "loginMessage": "You are currently not connected, please login to continue." + "loginButton": "Log in", + "loginMessage": "You are currently not connected, please login to continue." }, "toolbar": { "login": "Login", "logout": "Logout" } }, + "breadcrumb": { + "access": { + "root": "Access", + "search": "Search" + }, + "deposit": { + "create": "Create", + "detail": "Detail", + "list": "List", + "root": "Deposit" + }, + "home": "Home", + "organizationalUnit": { + "create": "Create", + "detail": "Detail", + "edit": "Edit", + "list": "List", + "root": "Organizational Unit" + } + }, "deposit": { "accessLevel": "Access Level", "author": "Author", @@ -27,47 +47,56 @@ "refresh": "Refresh", "submissionPolicy": "Submission Policy", "submit": "Submit", + "table": { + "header": { + "creation": { + "when": "Created date" + }, + "lastUpdate": { + "when": "Last update" + }, + "publicationDate": "Publication date", + "status": "Status", + "title": "Title" + } + }, "title": "Title" }, "organizationalUnit": { - "closingDate": "", - "delete": "", - "description": "", + "closingDate": "Closing Date", + "delete": "Delete", + "description": "Description", "dialog": { "delete": { - "cancel": "", - "confirm": "", - "message": "", - "title": "" + "cancel": "Cancel", + "confirm": "Yes! I'm sure", + "message": "Are you sure you want to delete the organizational units '{{name}}'?", + "title": "Confirm deletion" } }, - "edit": "", + "edit": "Edit", "hint": { - "name": "" + "name": "The name of the organization" }, - "isEmpty": "", - "name": "", + "isEmpty": "Is Empty", + "name": "Name", "new": "Create new organizational unit", - "open": "", - "openingDate": "", + "open": "Open", + "openingDate": "Opening Date", "refresh": "Refresh", - "submit": "" + "submit": "Submit", + "table": { + "header": { + "creation": { + "when": "Created the" + }, + "description": "Description", + "name": "Name" + } + } }, "search": "Search", "table": { - "header": { - "creation": { - "when": "Created the" - }, - "description": "Description", - "lastUpdate": { - "when": "Updated the" - }, - "name": "Name", - "publicationDate": "Publication Date", - "status": "Status", - "title": "Title" - }, "nodata": "There is no data to display" } } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 75e9cbe38..df64e132d 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -9,6 +9,26 @@ "logout": "Logout" } }, + "breadcrumb": { + "access": { + "root": "Access", + "search": "Search" + }, + "deposit": { + "create": "Create", + "detail": "Detail", + "list": "List", + "root": "Deposit" + }, + "home": "Home", + "organizationalUnit": { + "create": "Create", + "detail": "Detail", + "edit": "Edit", + "list": "List", + "root": "Organizational Unit" + } + }, "deposit": { "accessLevel": "Access Level", "author": "Author", @@ -27,6 +47,19 @@ "refresh": "Refresh", "submissionPolicy": "Submission Policy", "submit": "Submit", + "table": { + "header": { + "creation": { + "when": "Created date" + }, + "lastUpdate": { + "when": "Last update" + }, + "publicationDate": "Publication date", + "status": "Status", + "title": "Title" + } + }, "title": "Title" }, "organizationalUnit": { @@ -51,23 +84,19 @@ "open": "Open", "openingDate": "Opening Date", "refresh": "Refresh", - "submit": "Submit" + "submit": "Submit", + "table": { + "header": { + "creation": { + "when": "Created the" + }, + "description": "Description", + "name": "Name" + } + } }, "search": "Search", "table": { - "header": { - "creation": { - "when": "Created the" - }, - "description": "Description", - "lastUpdate": { - "when": "Updated the" - }, - "name": "Name", - "publicationDate": "Publication Date", - "status": "Status", - "title": "Title" - }, "nodata": "There is no data to display" } } diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 735fa029d..2fa4ad53c 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -1,73 +1,102 @@ { - "app": { - "login": { + "app": { + "login": { "loginButton": "Se connecter", "loginMessage": "Vous n'êtes actuellement pas connecté, veuillez vous connecter pour continuer." - }, - "toolbar": { - "login": "Login", + }, + "toolbar": { + "login": "Login", "logout": "Déconnexion" - } - }, - "deposit": { - "accessLevel": "Access Level", - "author": "Author", - "collectionBegin": "Collection Begin", - "collectionEnd": "Collection End", - "description": "Description", - "hasEmbargo": "Has Embargo", - "hint": { - "title": "Title of the deposit" - }, - "language": "Language", - "license": "License", - "new": "Create deposit", - "preservationPolicy": "Preservation Policy", - "publicationDate": "Publication Date", - "refresh": "Refresh", - "submissionPolicy": "Submission Policy", - "submit": "Submit", - "title": "Title" - }, - "organizationalUnit": { - "closingDate": "", - "delete": "", - "description": "", - "dialog": { - "delete": { - "cancel": "", - "confirm": "", - "message": "", - "title": "" - } - }, - "edit": "", - "hint": { - "name": "" - }, - "isEmpty": "", - "name": "", - "new": "Créer nouvelle unité organisationnel", - "open": "", - "openingDate": "", - "refresh": "Refresh", - "submit": "" - }, - "search": "Search", - "table": { - "header": { - "creation": { - "when": "Created the" - }, - "description": "Description", - "lastUpdate": { - "when": "Updated the" - }, - "name": "Nom", - "publicationDate": "Publication Date", - "status": "Status", - "title": "Title" - }, - "nodata": "There is no data to display" - } + } + }, + "breadcrumb": { + "access": { + "root": "Accès", + "search": "Recherche" + }, + "deposit": { + "create": "Création", + "detail": "Détail", + "list": "Liste", + "root": "Dépôts" + }, + "home": "Accueil", + "organizationalUnit": { + "create": "Création", + "detail": "Détail", + "edit": "Edition", + "list": "Liste", + "root": "Unité organisationnel" + } + }, + "deposit": { + "accessLevel": "Access Level", + "author": "Author", + "collectionBegin": "Collection Begin", + "collectionEnd": "Collection End", + "description": "Description", + "hasEmbargo": "Has Embargo", + "hint": { + "title": "Title of the deposit" + }, + "language": "Language", + "license": "License", + "new": "Create deposit", + "preservationPolicy": "Preservation Policy", + "publicationDate": "Date de publication", + "refresh": "Refresh", + "submissionPolicy": "Submission Policy", + "submit": "Submit", + "table": { + "header": { + "creation": { + "when": "Date de création" + }, + "lastUpdate": { + "when": "Dernière mise à jour" + }, + "publicationDate": "Date de publication", + "status": "Statut", + "title": "Titre" + } + }, + "title": "Title" + }, + "organizationalUnit": { + "closingDate": "", + "delete": "", + "description": "", + "dialog": { + "delete": { + "cancel": "", + "confirm": "", + "message": "", + "title": "" + } + }, + "edit": "", + "hint": { + "name": "" + }, + "isEmpty": "", + "name": "", + "new": "Créer nouvelle unité organisationnel", + "open": "", + "openingDate": "", + "refresh": "Refresh", + "submit": "", + "table": { + "header": { + "creation": { + "when": "Créé le" + }, + "description": "Déscription", + "name": "Nom" + } + } + }, + "search": "Search", + "table": { + "nodata": "There is no data to display" + } } -- GitLab