Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Improve the logout experience #4439

Merged
merged 3 commits into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions build/tools/changelog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ function search() {
curl -s "https://api.github.com/search/issues?q=${QUERY}${FILTER}" | jq -r '.items | .[] | "- \(.title) [\\#\(.number)](\(.html_url))"' | tee -a ${CHANGELOG}
}

function breaking_changes() {
FILTER=$1
if [ -n "${FORK_QUERY}" ]; then
curl -s "https://api.github.com/search/issues?q=${FORK_QUERY}${FILTER}" | jq -r '.items | .[] | "- **\(.title)**\n\n \(.body)"' > ${CHANGELOG}.breaking
fi
curl -s "https://api.github.com/search/issues?q=${QUERY}${FILTER}" | jq -r '.items | .[] | "- **\(.title)**\n\n \(.body)"' > ${CHANGELOG}.breaking
}

function log() {
echo $1 | tee -a ${CHANGELOG}
}
Expand All @@ -75,11 +83,11 @@ if [ -n "${FORK}" ]; then
fi

BUGS="+label:bug"
NON_BUGS="+-label:bug"
NON_BUGS="+-label:bug+-label:breaking-change"
BREAKING_CHANGES="+label:breaking-change"

mv ${CHANGELOG} CHANGELOG.old


echo ""
echo -e "${CYAN}${BOLD}Generating Change log - content for version ${MILESTONE} will be shown below"
echo -e "---------------------------------------------------------------------${RESET}"
Expand All @@ -104,6 +112,21 @@ search $BUGS

log ""

rm -f ${CHANGELOG}.breaking

breaking_changes $BREAKING_CHANGES

SIZE=$(wc -c ${CHANGELOG}.breaking | awk '{print $1}')
if [ "$SIZE" -ne 0 ]; then
log "**Breaking Changes:**"
log ""
cat ${CHANGELOG}.breaking | tee -a ${CHANGELOG}
fi

rm -f ${CHANGELOG}.breaking

log ""

tail -n +2 CHANGELOG.old >> ${CHANGELOG}
rm CHANGELOG.old

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Store } from '@ngrx/store';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { createBasicStoreModule } from '@stratosui/store/testing';

import { CoreTestingModule } from '../../../test-framework/core-test.modules';
import { SharedModule } from '../../shared/shared.module';
import { CoreModule } from '../core.module';
import { RouteModule } from './../../app.routing';
import { LogOutDialogComponent } from './log-out-dialog.component';

describe('LogOutDialogComponent', () => {
let component: LogOutDialogComponent;
let fixture: ComponentFixture<LogOutDialogComponent>;
let element: HTMLElement;
let store: any;
let router: any;

class MatDialogRefMock {
}
Expand All @@ -30,6 +32,8 @@ describe('LogOutDialogComponent', () => {
],
imports: [
CoreModule,
RouterTestingModule,
RouteModule,
SharedModule,
MatDialogModule,
NoopAnimationsModule,
Expand All @@ -42,7 +46,7 @@ describe('LogOutDialogComponent', () => {

beforeEach(() => {
fixture = TestBed.createComponent(LogOutDialogComponent);
store = TestBed.get(Store);
router = TestBed.get(Router);
component = fixture.componentInstance;
fixture.detectChanges();
element = fixture.nativeElement;
Expand All @@ -52,8 +56,8 @@ describe('LogOutDialogComponent', () => {
expect(component).toBeTruthy();
});

it('should dispatch logout action after countdown', fakeAsync(() => {
const spy = spyOn(store, 'dispatch');
it('should naivgate after countdown', fakeAsync(() => {
const spy = spyOn(router, 'navigate');

component.data = {
expiryDate: Date.now() + 1000,
Expand All @@ -65,6 +69,7 @@ describe('LogOutDialogComponent', () => {
expect(spy).not.toHaveBeenCalled();
tick(1500);
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledWith(['/login/logout']);
}));

afterEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Component, Inject, OnDestroy, OnInit, Optional } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { Router } from '@angular/router';
import { interval, Subscription } from 'rxjs';
import { tap } from 'rxjs/operators';

import { Logout } from '../../../../store/src/actions/auth.actions';
import { GeneralEntityAppState } from '../../../../store/src/app-state';

@Component({
selector: 'app-log-out-dialog',
templateUrl: './log-out-dialog.component.html',
Expand All @@ -16,7 +13,8 @@ export class LogOutDialogComponent implements OnInit, OnDestroy {
constructor(
public dialogRef: MatDialogRef<LogOutDialogComponent>,
@Optional() @Inject(MAT_DIALOG_DATA) public data: any,
private store: Store<GeneralEntityAppState>) { }
private router: Router
) { }

private autoLogout: Subscription;
private countDown: number;
Expand All @@ -33,7 +31,7 @@ export class LogOutDialogComponent implements OnInit, OnDestroy {
this.countDown = this.calcCountdown();
if (this.countDown <= 0) {
this.autoLogout.unsubscribe();
this.store.dispatch(new Logout());
this.router.navigate(['/login/logout']);
} else {
this.percentage = ((this.countdownTotal - this.countDown) / this.countdownTotal) * 100;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CoreModule } from '../../core/core.module';
import { SharedModule } from '../../shared/shared.module';
import { LoginPageComponent } from './login-page/login-page.component';
import { LoginRoutingModule } from './login.routing';
import { LogoutPageComponent } from './logout-page/logout-page.component';


@NgModule({
Expand All @@ -13,7 +14,8 @@ import { LoginRoutingModule } from './login.routing';
LoginRoutingModule
],
declarations: [
LoginPageComponent
LoginPageComponent,
LogoutPageComponent
]
})
export class LoginModule { }
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { LoginPageComponent } from './login-page/login-page.component';
import { LogoutPageComponent } from './logout-page/logout-page.component';

const loginRoutes: Routes = [
{ path: '', component: LoginPageComponent, }
{ path: '', component: LoginPageComponent, },
{ path: 'logout', component: LogoutPageComponent, }
];

@NgModule({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<app-intro-screen id="app-login-page" class="logout">
<mat-card class="logout__card">
<app-stratos-title></app-stratos-title>
<div class="logout__body" *ngIf="error$ | async; else loading">
<div class="logout__msg">An error occurred logging out</div>
<button (click)="reload()" color="primary" mat-raised-button mat-button>Reload</button>
</div>
<ng-template #loading>
<div class="logout__body">
<div class="logout__msg">Logging out</div>
<div id="logout__loading" class="logout__loading">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div>
</ng-template>
</mat-card>
</app-intro-screen>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.logout {
&__card {
padding: 0;
width: 300px;
}
&__body {
padding: 24px;
text-align: center;
}
&__msg {
font-size: 18px;
padding-bottom: 20px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { CommonModule } from '@angular/common';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CoreModule } from '@angular/flex-layout';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule } from '@ngrx/store';

import { appReducers } from '../../../../../store/src/reducers.module';
import { SharedModule } from '../../../public-api';
import { LogoutPageComponent } from './logout-page.component';

describe('LogoutPageComponent', () => {
let component: LogoutPageComponent;
let fixture: ComponentFixture<LogoutPageComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LogoutPageComponent ],
imports: [
CommonModule,
CoreModule,
SharedModule,
RouterTestingModule,
NoopAnimationsModule,
StoreModule.forRoot(
appReducers
)
]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(LogoutPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { Logout } from '../../../../../store/src/actions/auth.actions';
import { AppState } from '../../../../../store/src/app-state';

@Component({
selector: 'app-logout-page',
templateUrl: './logout-page.component.html',
styleUrls: ['./logout-page.component.scss']
})
export class LogoutPageComponent implements OnInit {

public error$: Observable<boolean>;

constructor(private store: Store<AppState>) {
this.error$ = this.store.select(s => s.auth).pipe(
map(auth => auth.error)
);
}

ngOnInit() {
// Dispatch the logout action after 1 second - give the logging out screen time to show
setTimeout(() => {
this.store.dispatch(new Logout());
}, 1000)
}

reload() {
window.location.assign(window.location.origin);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

import { Logout } from '../../../../../store/src/actions/auth.actions';
import { ToggleSideNav } from '../../../../../store/src/actions/dashboard-actions';
import { AddRecentlyVisitedEntityAction } from '../../../../../store/src/actions/recently-visited.actions';
import { AppState } from '../../../../../store/src/app-state';
Expand Down Expand Up @@ -140,7 +139,7 @@ export class PageHeaderComponent implements OnDestroy, AfterViewInit {
}

logout() {
this.store.dispatch(new Logout());
this.router.navigate(['/login/logout']);
}

public toggleSidenav() {
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/packages/store/src/reducers/auth.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
LOGIN_FAILED,
LOGIN_SUCCESS,
LoginFailed,
LOGOUT_FAILED,
RESET_AUTH,
SESSION_INVALID,
SESSION_VERIFIED,
Expand All @@ -12,6 +13,7 @@ import { RouterActions, RouterNav } from '../actions/router.actions';
import { GET_SYSTEM_INFO_SUCCESS } from '../actions/system.actions';
import { AuthOnlyAppState } from '../app-state';
import { SessionData } from '../types/auth.types';
import { LogoutFailed } from './../actions/auth.actions';
import { RouterRedirect } from './routing.reducer';

export interface AuthUser {
Expand Down Expand Up @@ -51,6 +53,10 @@ export function authReducer(state: AuthState = defaultState, action): AuthState
case LOGIN_FAILED:
const loginFailed = action as LoginFailed;
return { ...state, error: true, errorResponse: loginFailed.error, loggingIn: false, loggedIn: false };
case LOGOUT_FAILED:
const logoutFailed = action as LogoutFailed;
console.error(logoutFailed.error);
return { ...state, loggingIn: false, loggedIn: true, error: true, errorResponse: logoutFailed.error };
case VERIFY_SESSION:
return { ...state, error: false, errorResponse: undefined, verifying: true };
case SESSION_VERIFIED:
Expand Down