File

src/app/pages/dashboard/dashboard.page.ts

Description

Dashboard-frame of the app. Contains navigation, language selection, theme selection and a link to this app's repository.

Metadata

Index

Properties
Methods

Constructor

Public constructor(store: Store<State>)
Parameters :
Name Type Optional
store Store<State> No

Methods

Public setLanguage
setLanguage(event: MatButtonToggleChange)
Parameters :
Name Type Optional
event MatButtonToggleChange No
Returns : void
Public setSidebar
setSidebar(expanded: boolean)
Parameters :
Name Type Optional
expanded boolean No
Returns : void
Public toggleSidebar
toggleSidebar()
Returns : void
Public toggleTheme
toggleTheme()
Returns : void

Properties

Public Readonly language$
Default value : this.store.select('settings').pipe(map((settings) => settings.language))
Public Readonly routes
Default value : routes.filter((route) => route.name !== undefined)
Public Readonly sidebar$
Default value : this.store.select('settings').pipe(map((settings) => settings.sidebar))
Public Readonly themeButtonIcon$
Default value : this.store.select('settings').pipe(map((settings) => (settings.theme === 'dark-theme' ? 'light_mode' : 'dark_mode')))
import { Component } from '@angular/core';
import { MatButtonToggleChange } from '@angular/material/button-toggle';
import { Store } from '@ngrx/store';
import { map } from 'rxjs/operators';

import { routes } from 'src/app/app-routing.module';
import { setLanguage, setSidebar, toggleSidebar, toggleTheme } from 'src/app/store/actions';
import { State } from 'src/app/store/state';

/**
 * Dashboard-frame of the app.
 * Contains navigation, language selection, theme selection and a link to this app's repository.
 */
@Component({
  selector: 'apollo-dashboard',
  templateUrl: './dashboard.page.html',
  styleUrls: ['./dashboard.page.scss'],
})
export class DashboardPage {
  public readonly routes = routes.filter((route) => route.name !== undefined);

  public readonly language$ = this.store.select('settings').pipe(map((settings) => settings.language));
  public readonly sidebar$ = this.store.select('settings').pipe(map((settings) => settings.sidebar));

  public readonly themeButtonIcon$ = this.store.select('settings').pipe(map((settings) => (settings.theme === 'dark-theme' ? 'light_mode' : 'dark_mode')));

  public constructor(private readonly store: Store<State>) {}

  public setSidebar(expanded: boolean): void {
    this.store.dispatch(setSidebar({ expanded }));
  }

  public toggleSidebar(): void {
    this.store.dispatch(toggleSidebar());
  }

  public setLanguage(event: MatButtonToggleChange): void {
    this.store.dispatch(setLanguage({ language: event.value }));
  }

  public toggleTheme(): void {
    this.store.dispatch(toggleTheme());
  }
}
<div class="container">
  <mat-toolbar color="primary" class="toolbar mat-elevation-z8">
    <button mat-icon-button (click)="toggleSidebar()">
      <mat-icon>menu</mat-icon>
    </button>
    <h1 class="title">{{'app.title' | translate}}</h1>
    <img src="/assets/icons/logo.svg" alt="Logo" width="36px" height="36px" class="logo" [routerLink]="'/'" />
  </mat-toolbar>
  <mat-sidenav-container class="sidenav-container" autosize>
    <mat-sidenav class="sidenav mat-elevation-z6" mode="over" [opened]="sidebar$ | async" (closed)="setSidebar(false)">
      <mat-nav-list>
        <a mat-list-item *ngFor="let route of routes" [routerLink]="route.path" (click)="setSidebar(false)">{{route.name! | translate}}</a>
      </mat-nav-list>
      <mat-button-toggle-group name="language" class="language-button-group" (change)="setLanguage($event)">
        <mat-button-toggle value="en" class="language-button" [checked]="(language$ | async) === 'en'">{{'lang.en' | translate}}</mat-button-toggle>
        <mat-button-toggle value="de" class="language-button" [checked]="(language$ | async) === 'de'">{{'lang.de' | translate}}</mat-button-toggle>
      </mat-button-toggle-group>
      <div class="theme-button-container">
        <button mat-icon-button (click)="toggleTheme()"><mat-icon>{{themeButtonIcon$ | async}}</mat-icon></button>
      </div>
      <a href="https://github.com/DerYeger/apollo-frontend" class="repository-link" target="_blank" rel="noopener noreferrer">
        <svg class="github-logo" height="2rem" width="2rem" xmlns="http://www.w3.org/2000/svg">
          <path
            transform="scale(2)"
            d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z"
          />
        </svg>
        <span>{{'dashboard.github-repository' | translate}}</span>
        <mat-icon>open_in_new</mat-icon>
      </a>
    </mat-sidenav>
    <mat-sidenav-content style="padding: 1rem; height: calc(100% - 2rem)">
      <ng-content></ng-content>
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>

./dashboard.page.scss

@use "@angular/material" as mat;

:host {
  display: block;
  height: 100%;
}

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

.toolbar {
  z-index: 2;
  height: 48px;

  button:first-child {
    margin-left: -0.5rem;
  }
}

h1.title {
  margin-left: 0.5rem;
}

.logo {
  justify-self: flex-end;
  position: absolute;
  right: 1rem;
  cursor: pointer;
}

.sidenav-container {
  flex: 1;
}

.sidenav {
  min-width: 12.5rem;
}

.mat-drawer-transition .mat-drawer-content {
  transition-duration: 0s !important;
}

mat-nav-list {
  padding: 0;
}

.language-button-group {
  width: 100%;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
}

.language-button {
  width: 50%;
}

.theme-button-container {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 1rem;
}

@mixin repository-theme($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $foreground: map-get($theme, foreground);
  $text-color: mat.get-color-from-palette($foreground, text);

  .github-logo {
    width: 2rem;
    height: 2rem;
    fill: $text-color;
  }

  .repository-link {
    align-items: center;
    color: $text-color;
    display: flex;
    justify-content: left;
    margin: 1rem;
    text-decoration: none;

    span {
      margin-left: 0.5rem;
      margin-right: 0.5rem;
    }

    mat-icon {
      transform: scale(0.75);
    }
  }

  .repository-link:visited {
    color: $text-color;
    text-decoration: none;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""