src/app/modules/navbar/navbar.component.ts
OnInit
selector | app-navbar |
styleUrls | ./navbar.component.scss |
templateUrl | ./navbar.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
Accessors |
constructor(sheetservice: SheetService, configService: ConfigService, store: Store, router: Router, ga: GoogleAnalyticsService, dialog: MatDialog)
|
|||||||||||||||||||||
Parameters :
|
cache | |
Type : boolean
|
|
export | |
Type : EventEmitter
|
|
exportImage | ||||||
exportImage(imageType: string)
|
||||||
Parameters :
Returns :
void
|
getSheetSelection | ||||||
getSheetSelection(sheet: string)
|
||||||
Parameters :
Returns :
void
|
getVersionSelection | ||||||
getVersionSelection(version: string)
|
||||||
Parameters :
Returns :
void
|
onOptionClick |
onOptionClick(type: string, url: string)
|
Returns :
void
|
openMasterDataTables |
openMasterDataTables()
|
Returns :
void
|
openSelectOrgansDialog |
openSelectOrgansDialog()
|
Returns :
void
|
refreshData |
refreshData()
|
Returns :
void
|
toggleCompare |
toggleCompare()
|
Returns :
void
|
toggleDebugLogs |
toggleDebugLogs()
|
Returns :
void
|
toggleIndentedList |
toggleIndentedList()
|
Returns :
void
|
toggleMode |
toggleMode()
|
Returns :
void
|
togglePane |
togglePane()
|
Returns :
void
|
toggleReport |
toggleReport()
|
Returns :
void
|
Public configService |
Type : ConfigService
|
currentSheet |
Type : Sheet
|
Currently selected sheet |
Public dialog |
Type : MatDialog
|
Public ga |
Type : GoogleAnalyticsService
|
imgOptions |
Type : string[]
|
Default value : []
|
Export options |
masterSheetLink |
Type : string
|
mode |
Type : string
|
Currently selecte mode |
mode$ |
Type : Observable<string>
|
Decorators :
@Select(SheetState.getMode)
|
moreOptions |
Type : literal type[]
|
Default value : []
|
Menu options |
omapSelectedOrgans |
Type : string[]
|
Default value : []
|
Currently selected organs |
omapSelectedOrgans$ |
Type : Observable<string[]>
|
Decorators :
@Select(SheetState.getOMAPSelectedOrgans)
|
omapSelectedOrgansValues |
Type : string
|
Currently selected organs joined by comma |
omapSheetConfig |
Type : SheetDetails[]
|
Default value : []
|
omapSheetOptions |
Type : SheetDetails[]
|
Default value : []
|
Sheet configs |
playgroundSheetOptions |
Type : PlaygroundSheetOptions[]
|
Default value : []
|
Public router |
Type : Router
|
selectedOrgans |
Type : string[]
|
Default value : []
|
Currently selected organs |
selectedOrgans$ |
Type : Observable<string[]>
|
Decorators :
@Select(SheetState.getSelectedOrgans)
|
selectedOrgansValues |
Type : string
|
Currently selected organs joined by comma |
selectedSheetOption |
Type : string
|
Organ sheet selected |
selectedVersion |
Type : string | undefined
|
Selected data version |
sheet$ |
Type : Observable<SheetStateModel>
|
Decorators :
@Select(SheetState)
|
sheetConfig |
Type : SheetDetails[]
|
Default value : []
|
sheetOptions |
Type : SheetOptions[]
|
Default value : []
|
Sheet configs |
Public sheetservice |
Type : SheetService
|
Public store |
Type : Store
|
ui$ |
Type : Observable<UIStateModel>
|
Decorators :
@Select(UIState)
|
versions |
Type : Version[]
|
Default value : []
|
Available Data versions (depricated) |
window |
Type : Window
|
Default value : window
|
Document window object |
selectedOrgansLabel |
getselectedOrgansLabel()
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { GoogleAnalyticsService } from 'ngx-google-analytics';
import { Observable } from 'rxjs';
import { ClearSheetLogs } from '../../actions/logs.actions';
import { UpdateGetFromCache } from '../../actions/sheet.actions';
import {
OpenCompare,
ToggleControlPane,
ToggleDebugLogs,
ToggleIndentList,
ToggleReport,
} from '../../actions/ui.actions';
import { ConfigService } from '../../app-config.service';
import { OrganTableSelectorComponent } from '../../components/organ-table-selector/organ-table-selector.component';
import { GaAction, GaCategory } from '../../models/ga.model';
import {
PlaygroundSheetOptions,
Sheet,
SheetDetails,
SheetOptions,
Version,
VersionDetail,
} from '../../models/sheet.model';
import { SheetService } from '../../services/sheet.service';
import { SheetState, SheetStateModel } from '../../store/sheet.state';
import { UIState, UIStateModel } from '../../store/ui.state';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss'],
})
export class NavbarComponent implements OnInit {
/**
* Available Data versions (depricated)
*/
versions: Version[] = [];
/**
* Menu options
*/
moreOptions: { type: string; url: string; name: string }[] = [];
/**
* Export options
*/
imgOptions: string[] = [];
/**
* Sheet configs
*/
sheetOptions: SheetOptions[] = [];
/**
* Sheet configs
*/
omapSheetOptions: SheetDetails[] = [];
/**
* Document window object
*/
window: Window = window;
/**
* Organ sheet selected
*/
selectedSheetOption!: string;
/**
* Selected data version
*/
selectedVersion: string | undefined;
/**
* Currently selected sheet
*/
currentSheet!: Sheet;
/**
* Currently selecte mode
*/
mode!: string;
/**
* Currently selected organs
*/
selectedOrgans: string[] = [];
/**
* Currently selected organs joined by comma
*/
selectedOrgansValues!: string;
/**
* Currently selected organs
*/
omapSelectedOrgans: string[] = [];
/**
* Currently selected organs joined by comma
*/
omapSelectedOrgansValues!: string;
sheetConfig: SheetDetails[] = [];
omapSheetConfig: SheetDetails[] = [];
// state observables
@Select(SheetState) sheet$!: Observable<SheetStateModel>;
@Select(UIState) ui$!: Observable<UIStateModel>;
@Select(SheetState.getMode) mode$!: Observable<string>;
@Select(SheetState.getSelectedOrgans) selectedOrgans$!: Observable<string[]>;
@Select(SheetState.getOMAPSelectedOrgans) omapSelectedOrgans$!: Observable<string[]>;
@Input() cache!: boolean;
@Output() export = new EventEmitter<string>();
get selectedOrgansLabel(): string {
let x = this.selectedOrgansValues?.length > 0 ? 'ASCT+B: ' + this.selectedOrgansValues : '';
x = this.selectedOrgansValues?.length > 0 && this.omapSelectedOrgansValues?.length > 0 ? x + ' | ' : x;
x = this.omapSelectedOrgansValues?.length > 0 ? `${x}OMAP: ${this.omapSelectedOrgansValues}` : x;
if (x.length > 35) {
return `${this.selectedOrgansValues?.split(',').length} ASCT+B Tables, ${this.omapSelectedOrgansValues?.split(',')
.length} OMAPs`;
} else {
return x;
}
}
playgroundSheetOptions: PlaygroundSheetOptions[] = [];
masterSheetLink!: string;
constructor(
public sheetservice: SheetService,
public configService: ConfigService,
public store: Store,
public router: Router,
public ga: GoogleAnalyticsService,
public dialog: MatDialog,
) {
this.configService.sheetConfiguration$.subscribe((sheetOptions) => {
this.sheetConfig = sheetOptions;
this.sheetOptions = sheetOptions as unknown as SheetOptions[];
});
this.configService.omapsheetConfiguration$.subscribe((sheetOptions) => {
this.omapSheetConfig = sheetOptions;
this.omapSheetOptions = sheetOptions;
});
this.configService.config$.subscribe((config) => {
this.versions = config['version'] as Version[];
this.moreOptions = config['moreOptions'] as {
type: string;
url: string;
name: string;
}[];
this.imgOptions = config['imgOptions'] as string[];
this.playgroundSheetOptions = config['playgroundSheetOptions'] as PlaygroundSheetOptions[];
this.masterSheetLink = config['masterSheetLink'] as string;
});
}
ngOnInit(): void {
this.sheet$.subscribe((sheet) => {
if (sheet.sheet) {
this.currentSheet = sheet.sheet;
this.selectedSheetOption = sheet.sheet.display;
this.selectedVersion = this.versions.find((s) => s.folder === sheet.version)?.display;
}
});
this.mode$.subscribe((mode) => {
this.mode = mode;
if (mode === 'playground') {
this.sheetOptions = this.playgroundSheetOptions;
}
});
this.selectedOrgans$.subscribe((organs) => {
const selectedOrgansNames: string[] = [];
this.selectedOrgans = organs;
for (const organ of organs) {
this.sheetConfig.forEach((config: SheetDetails) => {
config.version?.forEach((version: VersionDetail) => {
if (version.value === organ) {
selectedOrgansNames.push(config.display);
}
});
});
}
this.selectedOrgansValues = selectedOrgansNames?.join(', ');
});
this.omapSelectedOrgans$.subscribe((organs) => {
const selectedOrgansNames: string[] = [];
this.omapSelectedOrgans = organs;
for (const organ of organs) {
this.omapSheetConfig.forEach((config: SheetDetails) => {
config.version?.forEach((version: VersionDetail) => {
if (version.value === organ) {
selectedOrgansNames.push(config.display);
}
});
});
}
this.omapSelectedOrgansValues =
selectedOrgansNames?.join(', ').length > 64
? `${organs.length} organs selected`
: selectedOrgansNames?.join(', ');
});
}
getSheetSelection(sheet: string) {
const selectedSheet = this.sheetOptions.find((s) => (s as unknown as { name: string }).name === sheet);
this.store.dispatch(new ClearSheetLogs());
this.router.navigate(['/vis'], {
queryParams: { sheet: selectedSheet?.sheet ?? '' },
queryParamsHandling: 'merge',
});
this.ga.event(GaAction.CLICK, GaCategory.NAVBAR, `Select Organ Set Dropdown: ${selectedSheet?.sheet}`);
}
getVersionSelection(version: string) {
const selectedVersion = this.versions.find((s) => s.display === version);
this.router.navigate(['/vis'], {
queryParams: { version: selectedVersion?.folder },
queryParamsHandling: 'merge',
});
}
openMasterDataTables() {
this.ga.event(GaAction.NAV, GaCategory.NAVBAR, 'Go to Master Data Tables', undefined);
window.open(this.masterSheetLink, '_blank');
}
refreshData() {
this.router.navigate(['/vis'], {
queryParams: {
selectedOrgans: this.selectedOrgans?.join(','),
playground: false,
omapSelectedOrgans: this.omapSelectedOrgans?.join(','),
},
});
this.ga.event(GaAction.CLICK, GaCategory.NAVBAR, 'Refresh Visualization Button', undefined);
}
togglePane() {
this.store.dispatch(new ToggleControlPane());
}
toggleIndentedList() {
this.store.dispatch(new ToggleIndentList());
}
toggleReport() {
this.store.dispatch(new ToggleReport());
}
toggleDebugLogs() {
this.store.dispatch(new ToggleDebugLogs());
}
toggleCompare() {
this.store.dispatch(new OpenCompare());
}
exportImage(imageType: string) {
this.export.emit(imageType);
this.ga.event(GaAction.CLICK, GaCategory.NAVBAR, `Export Image: ${imageType}`, 0);
}
onOptionClick(type: string, url: string) {
switch (type) {
case 'route':
this.router.navigate([url]);
break;
case 'tab':
this.window.open(url, '_blank');
break;
default:
this.window.open(url, '_blank');
break;
}
}
openSelectOrgansDialog() {
const config = new MatDialogConfig();
config.disableClose = true;
config.autoFocus = true;
config.id = 'OrganTableSelector';
config.width = 'fit-content';
config.data = {
organs: this.selectedOrgans,
isIntilalSelect: false,
getFromCache: this.cache,
omapOrgans: this.omapSelectedOrgans,
};
const dialogRef = this.dialog.open(OrganTableSelectorComponent, config);
dialogRef.afterClosed().subscribe(({ organs, cache, omapOrgans }) => {
this.store.dispatch(new UpdateGetFromCache(cache));
if (organs !== false) {
this.router.navigate(['/vis'], {
queryParams: {
selectedOrgans: organs?.join(','),
playground: false,
omapSelectedOrgans: omapOrgans?.join(','),
},
queryParamsHandling: 'merge',
});
}
});
}
toggleMode() {
if (this.mode === 'vis') {
this.router.navigate(['/vis'], {
queryParams: { playground: true, selectedOrgans: 'example' },
queryParamsHandling: 'merge',
});
this.ga.event(GaAction.NAV, GaCategory.NAVBAR, 'Enter Playground Mode', undefined);
} else if (this.mode === 'playground') {
this.router.navigate(['/vis'], {
queryParams: {
selectedOrgans: sessionStorage.getItem('selectedOrgans'),
playground: false,
},
queryParamsHandling: 'merge',
});
this.ga.event(GaAction.NAV, GaCategory.NAVBAR, 'Exit Playground Mode', undefined);
}
}
}
<mat-toolbar
color="secondary"
class="d-flex align-items-center toolbar-nav"
[ngStyle]="{
'border-bottom': (mode$ | async) === 'vis' ? '0.1875rem solid #444a6510' : 'none'
}"
>
<div class="nav-wrapper">
<app-nav-item
[label]="'Toggle'"
(click)="togglePane()"
#tooltip="matTooltip"
[matTooltip]="'Toggle Sidenav'"
matTooltipPosition="below"
>
<mat-icon class="toolbar-icons">menu</mat-icon>
</app-nav-item>
<div *ngIf="(ui$ | async)?.controlPaneOpen === false">
<img
src="./assets/logo.svg"
alt=""
class="px-2"
width="225"
routerLink="/"
matTooltip="Home Page"
matTooltipPosition="below"
/>
</div>
<div class="search ml-1">
<app-search [disabled]="(ui$ | async)?.error?.hasError ?? false"></app-search>
</div>
<button
mat-flat-button
id="selectedorgansBtn"
(click)="openSelectOrgansDialog()"
class="select-organs-button secondary ch"
#tooltip="matTooltip"
[disabled]="(mode$ | async) !== 'vis'"
matTooltip="Select Organ Set"
matTooltipPosition="below"
>
<span> {{ (mode$ | async) === 'vis' ? selectedOrgansLabel : 'Example' }}</span>
<mat-icon>arrow_drop_down</mat-icon>
</button>
<app-nav-item
#tooltip="matTooltip"
matTooltip="Master Data Tables"
matTooltipPosition="below"
[label]="'Data Tables'"
[matMenuTriggerFor]="nestedMenu.childMenu"
>
<mat-icon class="toolbar-icons">table_view</mat-icon>
<app-table-nested-menu
#nestedMenu
[sheetDetails]="(configService.allSheetConfigurations$ | async) ?? []"
></app-table-nested-menu>
</app-nav-item>
<app-nav-item
[label]="'Refresh'"
(click)="refreshData()"
#tooltip="matTooltip"
matTooltip="Refresh"
matTooltipPosition="below"
>
<mat-icon class="toolbar-icons">refresh</mat-icon>
</app-nav-item>
<app-nav-item
[label]="(mode$ | async) === 'vis' ? 'Playground' : 'Exit Playground'"
(click)="toggleMode()"
#tooltip="matTooltip"
[matTooltip]="(mode$ | async) === 'vis' ? 'Playground' : 'Exit Playground'"
matTooltipPosition="below"
>
<mat-icon class="toolbar-icons">{{ (mode$ | async) === 'vis' ? 'edit' : 'exit_to_app' }}</mat-icon>
</app-nav-item>
<app-nav-item
[label]="'Indented List'"
(click)="toggleIndentedList()"
#tooltip="matTooltip"
matTooltip="Indented List"
matTooltipPosition="below"
[disabled]="(ui$ | async)?.error?.hasError ?? false"
mat-icon-button
>
<mat-icon class="toolbar-icons">format_indent_increase</mat-icon>
</app-nav-item>
<app-nav-item
[label]="'Compare'"
[disabled]="(ui$ | async)?.error?.hasError ?? false"
mat-icon-button
(click)="toggleCompare()"
#tooltip="matTooltip"
matTooltip="Compare"
matTooltipPosition="below"
*ngIf="(mode$ | async) !== 'playground'"
>
<mat-icon class="toolbar-icons">compare_arrows</mat-icon>
</app-nav-item>
<app-nav-item
[label]="'Report'"
[disabled]="(ui$ | async)?.error?.hasError ?? false"
mat-icon-button
(click)="toggleReport()"
#tooltip="matTooltip"
matTooltip="Report"
matTooltipPosition="below"
>
<mat-icon class="toolbar-icons">bar_chart</mat-icon>
</app-nav-item>
<app-nav-item
[label]="'Debug Log'"
(click)="toggleDebugLogs()"
#tooltip="matTooltip"
matTooltip="Debug Log"
matTooltipPosition="below"
>
<mat-icon class="toolbar-icons">bug_report</mat-icon>
</app-nav-item>
<app-nav-item
[label]="'Export'"
[disabled]="(ui$ | async)?.error?.hasError ?? false"
autofocus="false"
mat-icon-button
#tooltip="matTooltip"
matTooltip="Export"
matTooltipPosition="below"
[matMenuTriggerFor]="downloadMenu"
>
<mat-icon class="toolbar-icons">get_app</mat-icon>
</app-nav-item>
<mat-menu #downloadMenu="matMenu">
<button mat-menu-item *ngFor="let option of imgOptions" (click)="exportImage(option)">
{{ option }}
</button>
</mat-menu>
<app-nav-item
[label]="'Menu'"
#tooltip="matTooltip"
matTooltip="Menu"
matTooltipPosition="below"
[matMenuTriggerFor]="menu"
>
<mat-icon class="toolbar-icons">more_vert</mat-icon>
</app-nav-item>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let option of moreOptions" (click)="onOptionClick(option.type, option.url)">
{{ option.name }}
</button>
</mat-menu>
</div>
</mat-toolbar>
./navbar.component.scss
.nav-wrapper {
display: flex;
justify-content: flex-start;
width: 100%;
align-items: center;
}
.select-organs-button {
width: 20%;
justify-content: start;
mat-icon {
float: right;
position: absolute;
top: 9px;
right: 10px;
transform: scale(1.4);
}
::ng-deep .mat-button-wrapper {
text-overflow: ellipsis;
display: block;
overflow: hidden;
white-space: nowrap;
padding-right: 10px;
}
span {
letter-spacing: 0.01rem;
font-size: 0.8rem;
}
}
.nav-wrapper > * {
margin-right: 0.625rem;
}
// remove underline from mat-select
::ng-deep .orgon-selection-box .mat-form-field-underline {
display: none;
}
:host ::ng-deep .mat-form-field-wrapper {
margin-bottom: 0 !important;
padding: 0;
}
::ng-deep .mat-form-field-infix {
border-top: none !important;
}
.mat-icon-button {
border-radius: 0.5rem !important;
}
.search {
width: 22%;
}
.label {
font-size: 0.5rem;
}
.toolbar-nav {
padding-right: 3.125rem !important;
display: flex;
align-items: center;
width: 100%;
background-color: white !important;
position: fixed;
z-index: 100;
}
.show-control-pane-button {
background-color: #f5f5f5;
}
.show-control-pane-icon {
margin-bottom: 0.3125rem !important;
}
.orgon-selection-box {
margin-bottom: 0;
}
.orgon-selection-button {
width: 100%;
}
.toolbar-icons {
margin-bottom: -0.3125rem !important;
}
.toolbar-icons-top {
margin-top: -0.3125rem;
}
.label {
font-size: 0.5rem;
}
.index {
z-index: 1;
}