File

src/app/modules/navbar/navbar.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(sheetservice: SheetService, configService: ConfigService, store: Store, router: Router, ga: GoogleAnalyticsService, dialog: MatDialog)
Parameters :
Name Type Optional
sheetservice SheetService No
configService ConfigService No
store Store No
router Router No
ga GoogleAnalyticsService No
dialog MatDialog No

Inputs

cache
Type : boolean

Outputs

export
Type : EventEmitter

Methods

exportImage
exportImage(imageType: string)
Parameters :
Name Type Optional
imageType string No
Returns : void
getSheetSelection
getSheetSelection(sheet: string)
Parameters :
Name Type Optional
sheet string No
Returns : void
getVersionSelection
getVersionSelection(version: string)
Parameters :
Name Type Optional
version string No
Returns : void
onOptionClick
onOptionClick(type: string, url: string)
Parameters :
Name Type Optional
type string No
url string No
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

Properties

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

Accessors

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>&nbsp; {{ (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;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""