File

projects/web-mev/src/app/app/app.component.ts

Implements

OnInit

Metadata

selector mev-root
styleUrls ./app.component.scss
templateUrl ./app.component.html

Index

Properties
Methods

Constructor

constructor(store: Store, storageService: LocalStorageService, router: Router, bnIdle: BnNgIdleService, authenticationService: AuthenticationService)
Parameters :
Name Type Optional
store Store No
storageService LocalStorageService No
router Router No
bnIdle BnNgIdleService No
authenticationService AuthenticationService No

Methods

Private Static isIEorEdgeOrSafari
isIEorEdgeOrSafari()
Returns : any
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onLanguageSelect
onLanguageSelect(undefined)
Parameters :
Name Optional
No
Returns : void
onLogoutClick
onLogoutClick()
Returns : void

Properties

currentUser
Type : User
envName
Default value : env.envName
isAuthenticated
Type : boolean
isAuthenticated$
Type : Observable<boolean>
isProd
Default value : env.production
language$
Type : Observable<string>
languages
Type : []
Default value : ['en']
logo
Default value : require('../../assets/logo.png').default
navigation
Type : []
Default value : [ { link: 'about', label: 'mev.menu.main' }, { link: 'tutorial', label: 'mev.menu.tutorial' }, { link: 'workarea', label: 'Get Started' } ]
navigationSideMenu
Type : []
Default value : [ ...this.navigation, { link: 'settings', label: 'mev.menu.settings' } ]
Private sessionSubscription$
Type : Subscription
sessionTimeout
Default value : 60 * 15
socialUser
stickyHeader$
Type : Observable<boolean>
theme$
Type : Observable<string>
version
Default value : env.versions.app
year
Default value : new Date().getFullYear()
import browser from 'browser-detect';
import { Component, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable, Subscription } from 'rxjs';
import { Router } from '@angular/router';
import { BnNgIdleService } from 'bn-ng-idle';
import { AuthenticationService } from '@app/core/authentication/authentication.service';
import { User } from '@app/_models/user';

import { environment as env } from '../../environments/environment';

import {
  routeAnimations,
  LocalStorageService,
  selectIsAuthenticated,
  selectSettingsStickyHeader,
  selectSettingsLanguage,
  selectEffectiveTheme
} from '../core/core.module';
import {
  actionSettingsChangeAnimationsPageDisabled,
  actionSettingsChangeLanguage
} from '../core/settings/settings.actions';

@Component({
  selector: 'mev-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [routeAnimations]
})
export class AppComponent implements OnInit {
  currentUser: User;
  socialUser;
  isAuthenticated: boolean;
  isProd = env.production;
  envName = env.envName;
  version = env.versions.app;
  year = new Date().getFullYear();
  logo = require('../../assets/logo.png').default;
  languages = ['en'];
  sessionTimeout = 60 * 15; // 15 minutes
  navigation = [
    { link: 'about', label: 'mev.menu.main' },
    { link: 'tutorial', label: 'mev.menu.tutorial' },
    { link: 'workarea', label: 'Get Started' }
  ];
  navigationSideMenu = [
    ...this.navigation,
    { link: 'settings', label: 'mev.menu.settings' }
  ];

  isAuthenticated$: Observable<boolean>;
  stickyHeader$: Observable<boolean>;
  language$: Observable<string>;
  theme$: Observable<string>;
  private sessionSubscription$: Subscription;

  constructor(
    private store: Store,
    private storageService: LocalStorageService,
    private router: Router,
    private bnIdle: BnNgIdleService,
    private authenticationService: AuthenticationService
  ) {
    this.authenticationService.currentUser.subscribe(x => {
      this.isAuthenticated = x !== null;
      this.currentUser = x;
    });
  }

  private static isIEorEdgeOrSafari() {
    return ['ie', 'edge', 'safari'].includes(browser().name);
  }

  onLogoutClick() {
    this.authenticationService.logout();
    this.router.navigate(['/login']);
  }

  ngOnInit(): void {
    this.socialUser = JSON.parse(localStorage.getItem('socialUser'));

    // listen for the user’s idleness
    this.sessionSubscription$ = this.bnIdle
      .startWatching(this.sessionTimeout)
      .subscribe((isTimedOut: boolean) => {
        if (isTimedOut) {
          this.onLogoutClick();
        }
      });

    this.storageService.testLocalStorage();
    if (AppComponent.isIEorEdgeOrSafari()) {
      this.store.dispatch(
        actionSettingsChangeAnimationsPageDisabled({
          pageAnimationsDisabled: true
        })
      );
    }

    this.isAuthenticated$ = this.store.pipe(select(selectIsAuthenticated));
    this.stickyHeader$ = this.store.pipe(select(selectSettingsStickyHeader));
    this.language$ = this.store.pipe(select(selectSettingsLanguage));
    this.theme$ = this.store.pipe(select(selectEffectiveTheme));
  }

  ngOnDestroy(): void {
    if (this.sessionSubscription$) {
      this.sessionSubscription$.unsubscribe();
    }
  }

  onLanguageSelect({ value: language }) {
    this.store.dispatch(actionSettingsChangeLanguage({ language }));
  }
}
<div [class]="'theme-wrapper ' + (theme$ | async)">

  <mat-sidenav-container>

    <mat-sidenav #sidenav mode="push">
      <div class="branding"><img [src]="logo" [alt]="logo"/>
        <span>{{ 'mev.title.short' | translate}}</span></div>
      <mat-nav-list>
        <a mat-list-item *ngFor="let item of navigationSideMenu" (click)="sidenav.close()" [routerLink]="[item.link]"
           routerLinkActive="active">
          {{item.label | translate}}
        </a>
        <a mat-list-item href="https://github.com/dfci-cccb/mev/issues" target="_blank" rel="noopener noreferrer">
          Github
        </a>
      </mat-nav-list>
    </mat-sidenav>

    <div class="wrapper">

      <div class="toolbar" [style.position]="(stickyHeader$ | async) ? 'fixed' : 'inherit'"
           [class.mat-elevation-z4]="(stickyHeader$ | async)">
        <mat-toolbar color="primary">
          <button mat-icon-button class="d-md-none" (click)="sidenav.open()">
            <fa-icon icon="bars"></fa-icon>

          </button>

          <span routerLink="" class="branding spacer center d-inline d-sm-none">
            <img [src]="logo" [alt]="logo"/></span>
          <span routerLink="" class="branding spacer center d-none d-sm-inline d-md-none"><img [src]="logo"
                                                                                               [alt]="logo"/> {{
            'mev.title.short' | translate }}</span>
          <span routerLink="" class="branding spacer d-none d-md-inline"><img [src]="logo" [alt]="logo"/>Web MeV</span>

          <span class="d-none d-md-inline">
            <button mat-button class="nav-button" *ngFor="let item of navigation" [routerLink]="[item.link]"
                    routerLinkActive="active">
              {{item.label | translate}}
            </button>
          </span>

          <!--button mat-button mat-stroked-button color="accent" *ngIf="!(isAuthenticated$ | async)" (click)="onLoginClick()">
            {{ 'mev.menu.login' | translate }}
          </button-->

          <!--button *ngIf="(isAuthenticated$ | async)"
                  mat-icon-button
                  [matMenuTriggerFor]="toolbarUserMenu">
            <fa-icon icon="user-circle"></fa-icon>
          </button-->
          <!--mat-menu #toolbarUserMenu="matMenu">
            <button mat-menu-item (click)="onLogoutClick()">
              <mat-icon><fa-icon icon="power-off"></fa-icon></mat-icon>
              <span>{{ 'mev.menu.logout' | translate }}</span>
            </button>
          </mat-menu-->

          <button mat-button mat-stroked-button color="accent" *ngIf="!isAuthenticated" routerLink="/login">
            {{ 'mev.menu.login' | translate }}
          </button>

          <button *ngIf="isAuthenticated"
                  mat-icon-button
                  [matMenuTriggerFor]="toolbarUserMenu">
            <fa-icon icon="user-circle"></fa-icon>
          </button>

          <mat-menu #toolbarUserMenu="matMenu">

            <button mat-menu-item routerLink="/change-password">
              <span *ngIf="socialUser" class="social-user-info">
                <span class="social-user-info__name">
                 {{ socialUser.name }}
               </span>
               <span class="social-user-info__email">
                 {{ socialUser.email }}
               </span>
               </span>

              <mat-icon>
                <fa-icon icon="lock"></fa-icon>
              </mat-icon>
              <span>Account security</span>
            </button>

            <button mat-menu-item (click)="onLogoutClick()">           
              <mat-icon>
                <fa-icon icon="power-off"></fa-icon>
              </mat-icon>
              <span>{{ 'mev.menu.logout' | translate }}</span>
            </button>

          </mat-menu>
          <!-- <button mat-icon-button routerLink="settings" class="d-none d-sm-inline">
            <fa-icon icon="cog"></fa-icon>
          </button> -->

          <a [matTooltip]="'mev.header.github' | translate"
             matTooltipPosition="before"
             mat-icon-button
             class="link d-none d-sm-inline"
             href="https://github.com/dfci-cccb/mev"
             target="_blank" rel="noopener noreferrer">
            <fa-icon [icon]="['fab','github']"></fa-icon>
          </a>

          <span *ngIf="language$ | async as language">
            <mat-select [ngModel]="language" (selectionChange)="onLanguageSelect($event)">
              <mat-option *ngFor="let l of languages" [value]="l">
                {{ l.toUpperCase() }}
              </mat-option>
            </mat-select>
          </span>
        </mat-toolbar>
      </div>

      <div class="content"
           [@routeAnimations]="o.isActivated && o.activatedRoute.routeConfig.data && o.activatedRoute.routeConfig.data.title">
        <router-outlet #o="outlet"></router-outlet>
        <router-outlet></router-outlet>
      </div>

      <div class="footer">
        <div class="row">
          <div class="col-sm-12 links">
            <a href="https://github.com/dfci-cccb/mev" target="_blank" rel="noopener noreferrer">
              <fa-icon [icon]="['fab','github']"></fa-icon>
              <span>Github</span>
            </a>
            <a href="https://twitter.com/webmev" target="_blank" rel="noopener noreferrer">
              <fa-icon [icon]="['fab','twitter']"></fa-icon>
              <span>Twitter</span>
            </a>
            <a href="https://www.youtube.com/channel/UCFrvYZDDiJ-Z-ZVKCH2pY9A"
               target="_blank" rel="noopener noreferrer">
              <fa-icon [icon]="['fab','youtube']"></fa-icon>
              <span>Youtube</span>
            </a>

          </div>
        </div>

      </div>

    </div>

  </mat-sidenav-container>

</div>

./app.component.scss

@import '../../styles-variables';

.theme-wrapper {
  height: 100%;
  width: 100%;
}

mat-sidenav-container {
  height: 100%;
  width: 100%;

  .toolbar {
    position: fixed;
    width: 100%;
    display: flex;
    z-index: 10;

    .nav-button {
      margin: 0 10px 0 0;
    }

    fa-icon {
      font-size: 24px;
    }

    .branding {
      cursor: pointer;
      overflow: hidden;
      padding-top: 4px;
      text-overflow: ellipsis;

      &.center {
        text-align: center;
      }

      img {
        position: relative;
        top: -2px;
        width: 48px;
        height: 48px;
      }
    }

    .mat-stroked-button {
      margin-right: 10px;
    }

    .spacer {
      flex: 1 1 auto;
    }

    mat-select {
      margin: 0 0 0 20px;
      width: 40px;
      font-size: 14px;
    }

    @media (max-width: map-get($grid-breakpoints, lg)) {
      .nav-button {
        min-width: 0;
        padding: 0 10px;
      }
    }
  }

  .wrapper {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;

    .content {
      flex: 1 0 auto;
      margin-top: 64px;
      overflow: hidden;
    }

    .footer {
      flex: 0 0 auto;
      padding: 0 15px;
      text-align: center;

      .row {
        padding: 10px 0;

        .links {
          a {
            transition: padding 0.5s;
            display: inline-block;
            padding: 0 5px !important;
            line-height: 35px;

            &:hover {
              text-decoration: none;
            }

            fa-icon {
              font-size: 35px;
              vertical-align: top;
            }

            span {
              display: inline-block;
              width: 75px;
              padding: 0 0 0 3px;
              overflow: hidden;
              text-align: left;
              white-space: nowrap;
              transition: width 0.5s;
            }
          }

          @media (min-width: map-get($grid-breakpoints, lg)) {
            a {
              padding: 20px 10px;
            }
          }

          @media (max-width: map-get($grid-breakpoints, md)) {
            a {
              padding: 20px;

              span {
                width: 0;
                padding: 0;
              }
            }
          }

          @media (max-width: map-get($grid-breakpoints, sm)) {
            a {
              padding: 20px 5px;
            }
          }
        }

        @media (min-width: map-get($grid-breakpoints, sm)) {
          .signature {
            position: relative;

            a {
              position: absolute;
              right: 15px;
            }
          }
        }
      }
    }
  }

  @media (max-width: $toolbar-breakpoint) {
    .content {
      margin-top: 56px !important;
    }
  }
}

mat-sidenav {
  width: 250px;

  .branding {
    height: 64px;
    padding: 8px 10px;
    font-size: 20px;
    font-weight: 500;

    img {
      height: 48px;
      margin: 2px 10px 0 0;
    }

    span {
      position: relative;
      top: 3px;
    }
  }

  .mat-nav-list {
    padding-top: 0;
  }
}

.mat-menu-item {
  height: auto;
}

.social-user-info {
  text-align: center;
  text-overflow: ellipsis;
  overflow: hidden;
  color: #202124;
  display: block;
}

.social-user-info__name {
  font-weight: bold;
  font-size: 16px;
  line-height: 22px;
  font-family: 'Google Sans', Roboto, RobotoDraft, Helvetica, Arial, sans-serif;
  display: block;
}

.social-user-info__email {
  font-weight: 400;
  font-size: 14px;
  font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif;
  display: block;
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""