Skip to content

Latest commit

 

History

History
280 lines (232 loc) · 6.16 KB

from-scratch.md

File metadata and controls

280 lines (232 loc) · 6.16 KB

generate Angular project:

npm install -g @angular/cli
ng new mail-front
cd mail-front
ng add @angular/material
ng generate @angular/material:navigation mailmenu

update app.component.html

<router-outlet></router-outlet>

update app.module.ts

import { RouterModule, Routes } from '@angular/router';
...
const appRoutes: Routes = [
  {
    path: 'mail',
    component: MailmenuComponent,
  },
  { path: '',
    redirectTo: '/mail',
    pathMatch: 'full',
  },
];
....
imports: [
      RouterModule.forRoot(appRoutes),
...
]

update mailmenu.component.html, in SideNav tag set attribute fixedInViewport=false

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport=false
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false"

rearrange items in mailmenu.component.html

<mat-toolbar color="primary">
  <button
    type="button"
    aria-label="Toggle sidenav"
    mat-icon-button
    (click)="drawer.toggle()"
    *ngIf="isHandset$ | async">
    <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
  </button>
  <span>mail-front</span>
</mat-toolbar>

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport=false
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <!-- Add Content Here -->
  </mat-sidenav-content>
</mat-sidenav-container>

build maillist

ng generate @angular/material:table maillist

Update routes in app.module.ts

import { MaillistComponent } from './maillist/maillist.component';
...
const appRoutes: Routes = [
  {
    path: 'mail',
    component: MailmenuComponent,
    children: [
      { path: 'list', component: MaillistComponent, outlet: 'side'},
   ]
  },

update mailmenu.component.html

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport=false
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
    <mat-toolbar>Mail</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item [routerLink]="['/mail', {outlets: { side: ['list'] } }]" >List</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <router-outlet name="side"></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

build mailform

ng generate @angular/material:address-form mailform

Update routes in app.module.ts

const appRoutes: Routes = [
  {
    path: 'mails',
    component: MailmenuComponent,
    children: [
      { path: 'list', component: MaillistComponent, outlet: 'side'},
      { path: 'add', component: MailformComponent, outlet: 'side'}
   ]
  },

update mailmenu.component.html

<mat-sidenav-container class="sidenav-container">
...
    <mat-nav-list>
      <a mat-list-item [routerLink]="['/mails', {outlets: { side: ['list'] } }]" >List</a>
      <a mat-list-item [routerLink]="['/mails', {outlets: { side: ['add'] } }]" >Write</a>
    </mat-nav-list>
...
</mat-sidenav-container>

build welcome component

ng generate component welcome

update welcome.component.html

<button class="btn btn-default" (click)="login()">
  Login
</button>

update welcome.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-welcome',
  templateUrl: './welcome.component.html',
  styleUrls: ['./welcome.component.css']
})
export class WelcomeComponent implements OnInit {

  constructor(private router: Router) { }

  public login() {
    this.router.navigate(['./mail']);
  }

  ngOnInit(): void {
  }
}

2 components are avalaible for OIDC :

We will use the most downloaded component : 'angular-oauth2-oidc'

npm i angular-oauth2-oidc --save

update app.module.ts

import { HttpClientModule } from '@angular/common/http';
import { OAuthModule } from 'angular-oauth2-oidc';
...
@NgModule({
...
  imports: [
    RouterModule.forRoot(appRoutes),
    HttpClientModule,
    OAuthModule.forRoot({
      resourceServer: {
          allowedUrls: ['http://localhost:8080/api'],
          sendAccessToken: true
      }
    }),

update app.component.ts

export class AppComponent {
  title = 'mail-front';

  authConfig: AuthConfig = {
    issuer: 'http://localhost:9080/auth/realms/mail',
    redirectUri: window.location.origin + '/mail',
    clientId: 'mail-user',
    scope: 'openid profile email offline_access users',
    responseType: 'code',
    // at_hash is not present in JWT token
    disableAtHashCheck: true,
    showDebugInformation: true
  };

  public signIn() {
    this.oauthService.initLoginFlow();
  }

  public signOut() {
    this.oauthService.logOut();
  }

  public getOAuthService() {
    return this.oauthService;
  }

  private configure() {
    this.oauthService.configure(this.authConfig);
    this.oauthService.tokenValidationHandler = new NullValidationHandler();
    this.oauthService.loadDiscoveryDocumentAndTryLogin();
  }

  constructor(private oauthService: OAuthService) {
    this.configure();
  }
}

update welcome.component.ts

import { NullValidationHandler, OAuthService, AuthConfig } from 'angular-oauth2-oidc';
...
export class WelcomeComponent implements OnInit {

   public login() {
    this.appComponent.signIn();
  }

  constructor(private appComponent: AppComponent) {
  }

  // constructor(private router: Router) { }

  // public login() {
  //   this.router.navigate(['./mail']);
  // }
}