Add Breadcrumb to navbar (Ticket #82)

This commit is contained in:
apapachristou 2019-05-16 19:11:41 +03:00
parent f26b3200e3
commit 162d2ef21f
14 changed files with 119 additions and 30 deletions

View File

@ -1,5 +1,6 @@
<div class="wrapper"> <div class="wrapper">
<div class="sidebar sidebar-shadow" data-color="danger" data-background-color="white" data-image="./assets/images/logan-troxell-9187-unsplash.jpg"> <div class="sidebar sidebar-shadow" data-color="danger" data-background-color="white"
data-image="./assets/images/logan-troxell-9187-unsplash.jpg">
<app-sidebar></app-sidebar> <app-sidebar></app-sidebar>
<div class="sidebar-background" style="background-image: url(./assets/images/logan-troxell-9187-unsplash.jpg)"> <div class="sidebar-background" style="background-image: url(./assets/images/logan-troxell-9187-unsplash.jpg)">
</div> </div>
@ -7,6 +8,7 @@
<div class="main-panel"> <div class="main-panel">
<app-navbar></app-navbar> <app-navbar></app-navbar>
<div> <div>
<!-- <app-breadcrumb *ngIf="this.isAuthenticated() && (hasBreadCrumb | async)"></app-breadcrumb> -->
<router-outlet (activate)='onActivate($event)' (deactivate)='onDeactivate($event)'></router-outlet> <router-outlet (activate)='onActivate($event)' (deactivate)='onDeactivate($event)'></router-outlet>
</div> </div>
</div> </div>

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { Router } from '@angular/router'; import { Router, ActivatedRoute, Params } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { BaseComponent } from '../../core/common/base/base.component'; import { BaseComponent } from '../../core/common/base/base.component';
import { RecentActivityType } from '../../core/common/enum/recent-activity-type'; import { RecentActivityType } from '../../core/common/enum/recent-activity-type';
@ -23,13 +22,18 @@ import { ExploreDmpCriteriaModel } from '../../core/query/explore-dmp/explore-dm
import { DatasetListingModel } from '../../core/model/dataset/dataset-listing'; import { DatasetListingModel } from '../../core/model/dataset/dataset-listing';
import { DatasetService } from '../../core/services/dataset/dataset.service'; import { DatasetService } from '../../core/services/dataset/dataset.service';
import { ExploreDatasetCriteriaModel } from '../../core/query/explore-dataset/explore-dataset-criteria'; import { ExploreDatasetCriteriaModel } from '../../core/query/explore-dataset/explore-dataset-criteria';
import { BreadcrumbItem } from '../misc/breadcrumb/definition/breadcrumb-item';
import { IBreadCrumbComponent } from '../misc/breadcrumb/definition/IBreadCrumbComponent';
import { Observable } from 'rxjs';
@Component({ @Component({
selector: 'app-dashboard', selector: 'app-dashboard',
templateUrl: './dashboard.component.html', templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'], styleUrls: ['./dashboard.component.scss'],
}) })
export class DashboardComponent extends BaseComponent implements OnInit { export class DashboardComponent extends BaseComponent implements OnInit, IBreadCrumbComponent {
breadCrumbs: Observable<BreadcrumbItem[]>;
public userInfo: any; public userInfo: any;
datasetActivities: any[]; datasetActivities: any[];
@ -48,6 +52,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
constructor( constructor(
private router: Router, private router: Router,
private route: ActivatedRoute,
private projectService: ProjectService, private projectService: ProjectService,
private dmpService: DmpService, private dmpService: DmpService,
private datasetService: DatasetService, private datasetService: DatasetService,
@ -84,6 +89,9 @@ export class DashboardComponent extends BaseComponent implements OnInit {
// titleFn: (item) => item['label'] // titleFn: (item) => item['label']
// }; // };
const breadCrumbs = [];
this.breadCrumbs = Observable.of(breadCrumbs);
if (!this.isAuthenticated()) { if (!this.isAuthenticated()) {
this.dashboardService.getStatistics() this.dashboardService.getStatistics()
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))

View File

@ -4,7 +4,13 @@ import { DashboardComponent } from './dashboard.component';
import { QuickWizardCreateAdd } from './quick-wizard-create-add/quick-wizard-create-add.component'; import { QuickWizardCreateAdd } from './quick-wizard-create-add/quick-wizard-create-add.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: DashboardComponent }, {
path: '',
component: DashboardComponent,
data: {
breadcrumb: true
},
},
]; ];
@NgModule({ @NgModule({

View File

@ -151,7 +151,8 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.formGroup = this.dmp.buildForm(); this.formGroup = this.dmp.buildForm();
this.registerFormEventsForDmpProfile(this.dmp.definition); this.registerFormEventsForDmpProfile(this.dmp.definition);
if (!this.editMode || this.dmp.status === Status.Inactive) { this.formGroup.disable(); } if (!this.editMode || this.dmp.status === Status.Inactive) { this.formGroup.disable(); }
if (!this.isAuthenticated) { if (this.isAuthenticated) {
// if (!this.isAuthenticated) {
this.breadCrumbs = Observable.of([ this.breadCrumbs = Observable.of([
{ {
parentComponentName: 'DmpListingComponent', parentComponentName: 'DmpListingComponent',
@ -185,7 +186,8 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.formGroup = this.dmp.buildForm(); this.formGroup = this.dmp.buildForm();
this.registerFormEventsForDmpProfile(this.dmp.definition); this.registerFormEventsForDmpProfile(this.dmp.definition);
if (!this.editMode || this.dmp.status === Status.Inactive) { this.formGroup.disable(); } if (!this.editMode || this.dmp.status === Status.Inactive) { this.formGroup.disable(); }
if (!this.isAuthenticated) { if (this.isAuthenticated) {
// if (!this.isAuthenticated) {
this.breadCrumbs = Observable.of([ this.breadCrumbs = Observable.of([
{ {
parentComponentName: 'DmpListingComponent', parentComponentName: 'DmpListingComponent',

View File

@ -71,7 +71,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
{ parentComponentName: null, label: 'DMPs', url: '/plans' }, { parentComponentName: null, label: 'DMPs', url: '/plans' },
); );
} }
//else breadCrumbs.push({ parentComponentName: null, label: 'DMPs', url: "/plans" }) else breadCrumbs.push({ parentComponentName: null, label: 'DMPs', url: "/plans" })
this.breadCrumbs = Observable.of(breadCrumbs); this.breadCrumbs = Observable.of(breadCrumbs);
this.criteria.setCriteria(this.getDefaultCriteria()); this.criteria.setCriteria(this.getDefaultCriteria());

View File

@ -7,6 +7,9 @@ import { DataTableRequest } from '../../core/model/data-table/data-table-request
import { DatasetListingModel } from '../../core/model/dataset/dataset-listing'; import { DatasetListingModel } from '../../core/model/dataset/dataset-listing';
import { ExploreDatasetCriteriaModel } from '../../core/query/explore-dataset/explore-dataset-criteria'; import { ExploreDatasetCriteriaModel } from '../../core/query/explore-dataset/explore-dataset-criteria';
import { DatasetService } from '../../core/services/dataset/dataset.service'; import { DatasetService } from '../../core/services/dataset/dataset.service';
import { IBreadCrumbComponent } from '../misc/breadcrumb/definition/IBreadCrumbComponent';
import { BreadcrumbItem } from '../misc/breadcrumb/definition/breadcrumb-item';
import { Observable } from 'rxjs';
@Component({ @Component({
@ -14,7 +17,7 @@ import { DatasetService } from '../../core/services/dataset/dataset.service';
templateUrl: 'explore-dataset-listing.component.html', templateUrl: 'explore-dataset-listing.component.html',
styleUrls: ['./explore-dataset-listing.component.scss'], styleUrls: ['./explore-dataset-listing.component.scss'],
}) })
export class ExploreDatasetListingComponent extends BaseComponent implements OnInit { export class ExploreDatasetListingComponent extends BaseComponent implements OnInit, IBreadCrumbComponent {
@ViewChild(MatPaginator) _paginator: MatPaginator; @ViewChild(MatPaginator) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
@ -22,6 +25,7 @@ export class ExploreDatasetListingComponent extends BaseComponent implements OnI
totalCount: number; totalCount: number;
listingItems: DatasetListingModel[] = []; listingItems: DatasetListingModel[] = [];
exploreDatasetCriteriaModel: ExploreDatasetCriteriaModel; exploreDatasetCriteriaModel: ExploreDatasetCriteriaModel;
breadCrumbs: Observable<BreadcrumbItem[]>;
constructor( constructor(
private datasetService: DatasetService, private datasetService: DatasetService,
@ -32,6 +36,10 @@ export class ExploreDatasetListingComponent extends BaseComponent implements OnI
ngOnInit() { ngOnInit() {
this.refresh(); this.refresh();
const breadCrumbs = [];
breadCrumbs.push({ parentComponentName: null, label: 'PUBLIC DATASETS', url: "/explore" })
this.breadCrumbs = Observable.of(breadCrumbs);
} }
refresh() { refresh() {

View File

@ -7,13 +7,16 @@ import { DataTableRequest } from "../../core/model/data-table/data-table-request
import { DmpListingModel } from "../../core/model/dmp/dmp-listing"; import { DmpListingModel } from "../../core/model/dmp/dmp-listing";
import { ExploreDmpCriteriaModel } from "../../core/query/explore-dmp/explore-dmp-criteria"; import { ExploreDmpCriteriaModel } from "../../core/query/explore-dmp/explore-dmp-criteria";
import { DmpService } from "../../core/services/dmp/dmp.service"; import { DmpService } from "../../core/services/dmp/dmp.service";
import { Observable } from "rxjs";
import { IBreadCrumbComponent } from "../misc/breadcrumb/definition/IBreadCrumbComponent";
import { BreadcrumbItem } from "../misc/breadcrumb/definition/breadcrumb-item";
@Component({ @Component({
selector: 'app-explore-dmp-listing-component', selector: 'app-explore-dmp-listing-component',
templateUrl: 'explore-dmp-listing.component.html', templateUrl: 'explore-dmp-listing.component.html',
styleUrls: ['./explore-dmp-listing.component.scss'], styleUrls: ['./explore-dmp-listing.component.scss'],
}) })
export class ExploreDmpListingComponent extends BaseComponent implements OnInit { export class ExploreDmpListingComponent extends BaseComponent implements OnInit, IBreadCrumbComponent {
@ViewChild(MatPaginator) _paginator: MatPaginator; @ViewChild(MatPaginator) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
@ -22,6 +25,7 @@ export class ExploreDmpListingComponent extends BaseComponent implements OnInit
titlePrefix: string; titlePrefix: string;
totalCount: number; totalCount: number;
listingItems: DmpListingModel[] = []; listingItems: DmpListingModel[] = [];
breadCrumbs: Observable<BreadcrumbItem[]>;
constructor( constructor(
private dmpService: DmpService, private dmpService: DmpService,
@ -32,6 +36,10 @@ export class ExploreDmpListingComponent extends BaseComponent implements OnInit
ngOnInit() { ngOnInit() {
this.refresh(); this.refresh();
const breadCrumbs = [];
breadCrumbs.push({ parentComponentName: null, label: 'PUBLIC DMPS', url: "/explore-plans" })
this.breadCrumbs = Observable.of(breadCrumbs);
} }
refresh() { refresh() {

View File

@ -1,8 +1,13 @@
<div class="row" *ngIf="(buildBreadCrumb(this.activatedRoute) | async) as items" [class.app-breadcrumb]="items.length > 0"> <div class="row" *ngIf="(buildBreadCrumb(this.activatedRoute) | async) as items" [class.app-breadcrumb]="items.length > 0">
<div *ngFor="let breadcrumb of items; let i = index; let length = count" class="col-auto"> <div *ngFor="let breadcrumb of items; let i = index; let length = count" class="col-auto">
<div class="row"> <div class="row breadcrumb-item">
<a [routerLink]="[breadcrumb.url]" [queryParams]="breadcrumb.params" class="link col-auto"> <a [routerLink]="[breadcrumb.url]" [queryParams]="breadcrumb.params" class="navbar-brand breadcrumb-title col-auto active" *ngIf="currentUrl(breadcrumb)">
{{ breadcrumb.label }} <mat-icon *ngIf="breadcrumb.icon" class="icon mr-2">{{ breadcrumb.icon }}</mat-icon>
<span>{{ breadcrumb.label }}</span>
</a>
<a [routerLink]="[breadcrumb.url]" [queryParams]="breadcrumb.params" class="navbar-brand breadcrumb-title col-auto" *ngIf="!currentUrl(breadcrumb)">
<mat-icon *ngIf="breadcrumb.icon" class="icon mr-2">{{ breadcrumb.icon }}</mat-icon>
<span>{{ breadcrumb.label }}</span>
</a> </a>
<mat-icon class="arrow col-auto">chevron_right</mat-icon> <mat-icon class="arrow col-auto">chevron_right</mat-icon>
</div> </div>

View File

@ -1,9 +1,9 @@
.app-breadcrumb { .app-breadcrumb {
padding: 0.75rem 0.1rem; // padding: 0.75rem 0.1rem;
margin-bottom: 1rem; // margin-bottom: 1rem;
background-color: #e9ecef; // background-color: #e9ecef;
border-radius: 0.25rem; // border-radius: 0.25rem;
margin-top: 2em; // margin-top: 2em;
.arrow { .arrow {
padding-right: 0; padding-right: 0;
@ -14,4 +14,34 @@
.link { .link {
font-size: 1.1em; font-size: 1.1em;
} }
.navbar-brand {
display: flex;
justify-content: center;
align-items: center;
background-color: #f8f8f8;
font-size: 16px;
font-weight: 400;
padding: 0.5em 0.5em;
}
.breadcrumb-title {
height: auto;
line-height: 1em;
}
.breadcrumb-item {
display: flex;
align-items: center;
}
.active {
color: #4687f0;
}
.icon {
font-size: 1em;
width: auto;
height: auto;
}
} }

View File

@ -3,6 +3,9 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BreadcrumbItem } from './definition/breadcrumb-item'; import { BreadcrumbItem } from './definition/breadcrumb-item';
import { BreadCrumbResolverService } from './service/breadcrumb.service'; import { BreadCrumbResolverService } from './service/breadcrumb.service';
import { DashboardService } from '../../../core/services/dashboard/dashboard.service';
import { assertDataInRangeInternal } from '@angular/core/src/render3/util';
import { url } from 'inspector';
@Component({ @Component({
selector: 'app-breadcrumb', selector: 'app-breadcrumb',
@ -29,11 +32,23 @@ export class BreadcrumbComponent implements OnInit {
} }
buildBreadCrumb(route: ActivatedRoute): Observable<BreadcrumbItem[]> { buildBreadCrumb(route: ActivatedRoute): Observable<BreadcrumbItem[]> {
if (this.breadCrumbService.resolve(route)) { return this.breadCrumbService.resolve(route).map(x => { x.unshift({ label: 'Dashboard', url: '/home' }); return x; }); } if (this.breadCrumbService.resolve(route)) {
return this.breadCrumbService.resolve(route).map(x => {
x.unshift({ label: 'HOME', url: '/home', icon: 'dashboard' }); return x;
});
}
return Observable.of([]); return Observable.of([]);
} }
navigate(url, params) { navigate(url, params) {
this.router.navigate([url, params]); this.router.navigate([url, params]);
} }
currentUrl(breadcrumb) {
if (breadcrumb.url == this.router.url) {
return true;
} else {
false
}
}
} }

View File

@ -4,5 +4,6 @@ export class BreadcrumbItem {
label: string; label: string;
url: string; url: string;
params?: any = {}; params?: any = {};
icon?: string;
notFoundResolver?: any[]; notFoundResolver?: any[];
} }

View File

@ -1,10 +1,11 @@
<nav class="navbar navbar-expand-lg fixed-navbar"> <nav class="navbar navbar-expand-lg fixed-navbar">
<div class="container-fluid"> <div class="container-fluid">
<div class="navbar-wrapper"> <div class="navbar-wrapper">
<a routerLink="/home"> <app-breadcrumb></app-breadcrumb>
<!-- <a routerLink="/home">
<i class="material-icons">dashboard</i> <i class="material-icons">dashboard</i>
</a> </a>
<a class="navbar-brand" routerLink="/home">{{ 'NAV-BAR.BREADCRUMB-ROOT' | translate }}</a> <a class="navbar-brand" routerLink="/home">{{ 'NAV-BAR.BREADCRUMB-ROOT' | translate }}</a> -->
</div> </div>
<button class="navbar-toggler" type="button" (click)="sidebarToggle()"> <button class="navbar-toggler" type="button" (click)="sidebarToggle()">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">Toggle navigation</span>

View File

@ -18,4 +18,5 @@ $mat-card-header-size: 40px !default;
.fixed-navbar { .fixed-navbar {
position: fixed; position: fixed;
z-index: 1000; z-index: 1000;
height: 70px;
} }

View File

@ -4,12 +4,14 @@ import { CommonFormsModule } from '../../common/forms/common-forms.module';
import { CommonUiModule } from '../../common/ui/common-ui.module'; import { CommonUiModule } from '../../common/ui/common-ui.module';
import { NavbarComponent } from './navbar.component'; import { NavbarComponent } from './navbar.component';
import { SearchComponent } from '../misc/search/search.component'; import { SearchComponent } from '../misc/search/search.component';
import { BreadcrumbModule } from '../misc/breadcrumb/breadcrumb.module';
@NgModule({ @NgModule({
imports: [ imports: [
CommonUiModule, CommonUiModule,
CommonFormsModule, CommonFormsModule,
RouterModule RouterModule,
BreadcrumbModule
], ],
declarations: [ declarations: [
NavbarComponent, NavbarComponent,