Browse Source

feat(admin-ui): Implement user menu and log out mechanism

Michael Bromley 7 years ago
parent
commit
0a483d786e

+ 2 - 5
admin-ui/src/app/core/components/app-shell/app-shell.component.html

@@ -13,14 +13,11 @@
             <a href="javascript://" class="nav-link nav-text">Users</a>
         </div>
         <div class="header-actions">
-            <a href="javascript://" class="nav-link nav-icon">
-                <clr-icon shape="cog"></clr-icon>
-            </a>
+            <vdr-user-menu [userName]="userName$ | async"
+                           (logOut)="logOut()"></vdr-user-menu>
         </div>
     </header>
-    <nav class="subnav">
 
-    </nav>
     <div class="content-container">
         <router-outlet></router-outlet>
     </div>

+ 20 - 6
admin-ui/src/app/core/components/app-shell/app-shell.component.ts

@@ -1,15 +1,29 @@
 import { Component, OnInit } from '@angular/core';
+import { StateStore } from '../../../state/state-store.service';
+import { Observable } from 'rxjs';
+import { UserActions } from '../../../state/user/user-actions';
+import { Router } from '@angular/router';
 
 @Component({
-  selector: 'vdr-app-shell',
-  templateUrl: './app-shell.component.html',
-  styleUrls: ['./app-shell.component.scss']
+    selector: 'vdr-app-shell',
+    templateUrl: './app-shell.component.html',
+    styleUrls: ['./app-shell.component.scss']
 })
 export class AppShellComponent implements OnInit {
 
-  constructor() { }
+    userName$: Observable<string>;
 
-  ngOnInit() {
-  }
+    constructor(private store: StateStore,
+                private userActions: UserActions,
+                private router: Router) { }
+
+    ngOnInit() {
+        this.userName$ = this.store.select(state => state.user.username);
+    }
+
+    logOut() {
+        this.userActions.logOut();
+        this.router.navigate(['/login']);
+    }
 
 }

+ 10 - 0
admin-ui/src/app/core/components/user-menu/user-menu.component.html

@@ -0,0 +1,10 @@
+<clr-dropdown>
+    <span class="user-name">{{ userName }}</span>
+    <span class="trigger" clrDropdownTrigger>
+        <clr-icon shape="user" size="24"></clr-icon>
+        <clr-icon shape="caret down"></clr-icon>
+    </span>
+    <clr-dropdown-menu clrPosition="bottom-right" *clrIfOpen>
+        <button type="button" clrDropdownItem (click)="logOut.emit()">Log out</button>
+    </clr-dropdown-menu>
+</clr-dropdown>

+ 16 - 0
admin-ui/src/app/core/components/user-menu/user-menu.component.scss

@@ -0,0 +1,16 @@
+:host {
+    display: flex;
+    align-items: center;
+    margin: 0 0.5rem;
+    height: 2.5rem;
+}
+
+.user-name {
+    color: lightgrey;
+    margin-right: 12px;
+}
+
+.trigger clr-icon {
+    color: white;
+}
+

+ 25 - 0
admin-ui/src/app/core/components/user-menu/user-menu.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UserMenuComponent } from './user-menu.component';
+
+describe('UserMenuComponent', () => {
+  let component: UserMenuComponent;
+  let fixture: ComponentFixture<UserMenuComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ UserMenuComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(UserMenuComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
admin-ui/src/app/core/components/user-menu/user-menu.component.ts

@@ -0,0 +1,15 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+
+@Component({
+    selector: 'vdr-user-menu',
+    templateUrl: './user-menu.component.html',
+    styleUrls: ['./user-menu.component.scss'],
+})
+export class UserMenuComponent {
+
+    @Input()
+    userName = '';
+
+    @Output()
+    logOut = new EventEmitter<void>();
+}

+ 2 - 1
admin-ui/src/app/core/core.module.ts

@@ -12,6 +12,7 @@ import { API_URL } from '../app.config';
 import { LocalStorageService } from './providers/local-storage/local-storage.service';
 import { DataService } from './providers/data/data.service';
 import { AuthGuard } from './providers/guard/auth.guard';
+import { UserMenuComponent } from './components/user-menu/user-menu.component';
 
 export function createApollo(httpLink: HttpLink, ngrxCache: InMemoryCache) {
   return {
@@ -42,6 +43,6 @@ export function createApollo(httpLink: HttpLink, ngrxCache: InMemoryCache) {
         DataService,
         AuthGuard,
     ],
-    declarations: [AppShellComponent],
+    declarations: [AppShellComponent, UserMenuComponent],
 })
 export class CoreModule {}

+ 1 - 0
admin-ui/src/app/state/user/user-actions.ts

@@ -54,6 +54,7 @@ export class UserActions {
     }
 
     logOut(): void {
+        this.localStorageService.remove('authToken');
         this.store.dispatch(new Actions.Logout());
     }