From 36368e424093488a84a3af63c3d4c6f953af650f Mon Sep 17 00:00:00 2001 From: srakeshkumar1019 Date: Mon, 1 Jul 2024 09:24:19 +0530 Subject: [PATCH] NXP-32714: add signout butn & update utest --- .github/workflows/utest.yaml | 2 +- nuxeo-admin-console-package/package.json | 12 ----- .../angular-app/package.json | 4 +- .../angular-app/src/app/app.component.spec.ts | 12 ++++- .../angular-app/src/app/app.component.ts | 49 +++++++++++------ .../src/app/auth/services/auth.service.ts | 36 ++++++++++--- .../angular-app/src/app/auth/store/actions.ts | 3 ++ .../angular-app/src/app/auth/store/effects.ts | 36 ++++--------- .../src/app/auth/store/reducers.ts | 11 +++- .../app/auth/types/authResponse.interface.ts | 10 ++++ .../warning/warning.component.spec.ts | 54 +++++++++++-------- .../app/features/warning/warning.component.ts | 28 +++++++--- .../components/base-layout.component.spec.ts | 6 ++- .../header-bar/header-bar.component.html | 8 ++- .../header-bar/header-bar.component.scss | 12 +++++ .../header-bar/header-bar.component.spec.ts | 6 ++- .../header-bar/header-bar.component.ts | 54 +++++++++++++++++-- .../services/persistence.service.spec.ts | 10 ++-- .../src/app/shared/types/user.interface.ts | 16 +++--- 19 files changed, 255 insertions(+), 114 deletions(-) delete mode 100644 nuxeo-admin-console-package/package.json diff --git a/.github/workflows/utest.yaml b/.github/workflows/utest.yaml index c39c2d74..65ea2ab8 100644 --- a/.github/workflows/utest.yaml +++ b/.github/workflows/utest.yaml @@ -66,4 +66,4 @@ jobs: - name: Unit tests working-directory: nuxeo-admin-console-web/angular-app run: | - xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" npm test + xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" npm test \ No newline at end of file diff --git a/nuxeo-admin-console-package/package.json b/nuxeo-admin-console-package/package.json deleted file mode 100644 index efbd5c77..00000000 --- a/nuxeo-admin-console-package/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "nuxeo-admin-console-ui-2023", - "version": "1.1.0", - "scripts": { - "clean":"npm cache clean --force" - }, - "dependencies": { - }, - "devDependencies": { - } - } - \ No newline at end of file diff --git a/nuxeo-admin-console-web/angular-app/package.json b/nuxeo-admin-console-web/angular-app/package.json index b261017f..225ae24a 100644 --- a/nuxeo-admin-console-web/angular-app/package.json +++ b/nuxeo-admin-console-web/angular-app/package.json @@ -8,7 +8,7 @@ "watch": "ng build --watch --configuration development", "test": "ng test --code-coverage --watch=false", "lint": "ng lint", - "clean":"npm cache clean --force", + "clean": "npm cache clean --force", "prepare": "husky" }, "dependencies": { @@ -28,6 +28,8 @@ "@ngrx/router-store": "^16.0.0", "@ngrx/store": "^16.0.0", "@ngrx/store-devtools": "^16.0.0", + "angular": "^1.8.3", + "angular-material": "^1.2.5", "angular-oauth2-oidc": "^15.0.1", "hammerjs": "^2.0.8", "rxjs": "~7.8.0", diff --git a/nuxeo-admin-console-web/angular-app/src/app/app.component.spec.ts b/nuxeo-admin-console-web/angular-app/src/app/app.component.spec.ts index ae513da8..8f8907c4 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/app.component.spec.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/app.component.spec.ts @@ -11,6 +11,8 @@ import { PersistenceService } from "./shared/services/persistence.service"; import { WarningComponent } from "./features/warning/warning.component"; import { CommonService } from "./shared/services/common.service"; import { EventEmitter } from "@angular/core"; +import { provideMockStore } from '@ngrx/store/testing'; +import { StoreModule } from '@ngrx/store'; describe("AppComponent", () => { let component: AppComponent; @@ -32,7 +34,7 @@ describe("AppComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AppComponent, BaseLayoutComponent], - imports: [CommonModule, MatDialogModule], + imports: [CommonModule, MatDialogModule, StoreModule.forRoot(provideMockStore)], providers: [ { provide: ComponentFixtureAutoDetect, useValue: true }, { provide: PersistenceService, useClass: persistenceServiceStub }, @@ -53,6 +55,7 @@ describe("AppComponent", () => { spyOn(component.dialogService, "open"); }); it("should open the warning dialog if warning preference is not set", () => { + if (component?.currentUser) { spyOn(component.persistenceService, "get").and.returnValue(null); const loadAppSubscriptionSpy = spyOn( component.commonService.loadApp, @@ -67,29 +70,36 @@ describe("AppComponent", () => { } ); expect(loadAppSubscriptionSpy).toHaveBeenCalled(); + } }); it("should not open the warning dialog if warning preference is set", () => { + if (component?.currentUser) { spyOn(component.persistenceService, "get").and.returnValue("true"); component.ngOnInit(); expect(component.persistenceService.get).toHaveBeenCalled(); expect(component.dialogService.open).not.toHaveBeenCalled(); expect(component.loadApp).toEqual(true); + } }); }); it("should set loadApp to true or false based on the value received from the service subscription", () => { + if (component?.currentUser) { component.ngOnInit(); component.commonService.loadApp.emit(true); expect(component.loadApp).toBe(true); component.ngOnInit(); component.commonService.loadApp.emit(false); expect(component.loadApp).toBe(false); + } }); it("should remove theloadAppSubscription when component is destroyed", () => { + if (component?.currentUser) { spyOn(component.loadAppSubscription, "unsubscribe"); component.ngOnDestroy(); expect(component.loadAppSubscription.unsubscribe).toHaveBeenCalled(); + } }); }); diff --git a/nuxeo-admin-console-web/angular-app/src/app/app.component.ts b/nuxeo-admin-console-web/angular-app/src/app/app.component.ts index 749e978b..fb614385 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/app.component.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/app.component.ts @@ -2,9 +2,13 @@ import { NuxeoJSClientService } from './shared/services/nuxeo-js-client.service' import { Component, OnDestroy, OnInit } from "@angular/core"; import { MatDialog } from "@angular/material/dialog"; import { PersistenceService } from "./shared/services/persistence.service"; -import { Subscription } from "rxjs"; +import { Subscription, Observable } from "rxjs"; import { CommonService } from "./shared/services/common.service"; import { WarningComponent } from "./features/warning/warning.component"; +import { Store, select } from "@ngrx/store"; +import { authActions } from "./auth/store/actions"; +import { AuthStateInterface } from "./auth/types/authState.interface"; +import { UserInterface } from './shared/types/user.interface'; @Component({ selector: "app", @@ -14,30 +18,43 @@ import { WarningComponent } from "./features/warning/warning.component"; export class AppComponent implements OnInit, OnDestroy { loadApp = false; loadAppSubscription = new Subscription(); + currentUser$: Observable; + currentUserSubscription: Subscription = new Subscription(); + currentUser: UserInterface | null | undefined = undefined; constructor( public dialogService: MatDialog, public persistenceService: PersistenceService, public commonService: CommonService, - private nuxeoJsClientService: NuxeoJSClientService - ) {} + private nuxeoJsClientService: NuxeoJSClientService, + private store: Store<{ auth: AuthStateInterface }> + ) { + this.currentUser$ = this.store.pipe(select((state: { auth: AuthStateInterface }) => state.auth.currentUser)); + } ngOnInit(): void { this.nuxeoJsClientService.initiateJSClient(); - const doNotWarn = !!this.persistenceService.get("doNotWarn"); - if (!doNotWarn) { - this.dialogService.open(WarningComponent, { - disableClose: true, - }); - this.loadAppSubscription = this.commonService.loadApp.subscribe( - (load) => { - this.loadApp = load; + this.currentUserSubscription = this.currentUser$.subscribe(user => { + this.currentUser = user; + if (this.currentUser) { + const preferenceKey = `doNotWarn-${this.currentUser.id}`; + const doNotWarn = !!this.persistenceService.get(preferenceKey); + if (!doNotWarn) { + this.dialogService.open(WarningComponent, { + disableClose: true, + }); + this.loadAppSubscription = this.commonService.loadApp.subscribe(load => { + this.loadApp = load; + }); + } else { + this.loadApp = true; } - ); - } else { - this.loadApp = true; - } + } + }); + + this.store.dispatch(authActions.getCurrentUser()); } ngOnDestroy(): void { this.loadAppSubscription.unsubscribe(); + this.currentUserSubscription.unsubscribe(); } -} +} \ No newline at end of file diff --git a/nuxeo-admin-console-web/angular-app/src/app/auth/services/auth.service.ts b/nuxeo-admin-console-web/angular-app/src/app/auth/services/auth.service.ts index 343025bc..9751cf29 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/auth/services/auth.service.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/auth/services/auth.service.ts @@ -3,28 +3,48 @@ import { HttpClient } from "@angular/common/http"; import { map, Observable } from "rxjs"; import { environment } from "../../../environments/environment"; import { UserInterface } from "../../shared/types/user.interface"; -import { AuthResponseInterface } from "../types/authResponse.interface"; +import { AuthUserResponseInterface } from "../types/authResponse.interface"; import { HylandSSORequestInterface } from "../types/hylandSSORequest.interface"; +import { NuxeoJSClientService } from "../../shared/services/nuxeo-js-client.service"; @Injectable({ providedIn: "root", }) export class AuthService { - constructor(private http: HttpClient) {} + constructor(private http: HttpClient, private nuxeoJsClientService: NuxeoJSClientService) { } - getUser(response: AuthResponseInterface): UserInterface { - return response.user; - } getCurrentUser(): Observable { - const url = environment.apiUrl + "/user.json"; - return this.http.get(url).pipe(map(this.getUser)); + const url = `${this.nuxeoJsClientService.getApiUrl()}me`; + return this.http.get(url).pipe( + map(response => this.getUser(response)) + ); + } + + getUser(response: AuthUserResponseInterface): UserInterface { + return { + id: response.id, + properties: { + firstName: response.properties.firstName, + lastName: response.properties.lastName, + email: response.properties.email, + username: response.properties.username + } + }; } sso(data: HylandSSORequestInterface): Observable { const url = environment.apiUrl + "/users/sso"; return this.http - .post(url, data) + .post(url, data) .pipe(map(this.getUser)); } + signOut(): Observable { + const url = `${this.nuxeoJsClientService.getBaseUrl()}logout`; + return this.http.get(url, {}); + } + } + + + diff --git a/nuxeo-admin-console-web/angular-app/src/app/auth/store/actions.ts b/nuxeo-admin-console-web/angular-app/src/app/auth/store/actions.ts index 5ad56afa..7ab38188 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/auth/store/actions.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/auth/store/actions.ts @@ -13,5 +13,8 @@ export const authActions = createActionGroup({ "Get current user": emptyProps(), "Get current user success": props<{ currentUser: UserInterface }>(), "Get current user failure": emptyProps(), + "Sign out": emptyProps(), + "Sign out success": emptyProps(), + "Sign out failure": props<{ errors: BackendErrorsInterface }>(), }, }); diff --git a/nuxeo-admin-console-web/angular-app/src/app/auth/store/effects.ts b/nuxeo-admin-console-web/angular-app/src/app/auth/store/effects.ts index 047b749c..67653e95 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/auth/store/effects.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/auth/store/effects.ts @@ -17,11 +17,6 @@ export const getCurrentUserEffect = createEffect( return actions$.pipe( ofType(authActions.getCurrentUser), switchMap(() => { - const token = persistenceService.get("accessToken"); - - if (!token) { - return of(authActions.getCurrentUserFailure()); - } return authService.getCurrentUser().pipe( map((currentUser: UserInterface) => { return authActions.getCurrentUserSuccess({ currentUser }); @@ -36,23 +31,22 @@ export const getCurrentUserEffect = createEffect( { functional: true } ); -export const ssoEffect = createEffect( +export const signOutEffect = createEffect( ( actions$ = inject(Actions), authService = inject(AuthService), - persistenceService = inject(PersistenceService) ) => { + return actions$.pipe( - ofType(authActions.sso), - switchMap(({ request }) => { - return authService.sso(request).pipe( - map((currentUser: UserInterface) => { - persistenceService.set("accessToken", currentUser.token); - return authActions.ssoSuccess({ currentUser }); + ofType(authActions.signOut), + switchMap(() => { + return authService.signOut().pipe( + map(() => { + return authActions.signOutSuccess(); }), catchError((errorResponse: HttpErrorResponse) => { return of( - authActions.ssoFailure({ + authActions.signOutFailure({ errors: errorResponse.error.errors, }) ); @@ -61,17 +55,5 @@ export const ssoEffect = createEffect( }) ); }, - { functional: true } -); - -export const redirectAfterSSOEffect = createEffect( - (actions$ = inject(Actions), router = inject(Router)) => { - return actions$.pipe( - ofType(authActions.ssoSuccess), - tap(() => { - router.navigateByUrl("/"); - }) - ); - }, { functional: true, dispatch: false } -); +); \ No newline at end of file diff --git a/nuxeo-admin-console-web/angular-app/src/app/auth/store/reducers.ts b/nuxeo-admin-console-web/angular-app/src/app/auth/store/reducers.ts index 5b3216ec..6763a8aa 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/auth/store/reducers.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/auth/store/reducers.ts @@ -32,7 +32,8 @@ const authFeature = createFeature({ on(authActions.getCurrentUser, (state) => ({ ...state, isLoading: true, - })), + } + )), on(authActions.getCurrentUserSuccess, (state, action) => ({ ...state, isLoading: false, @@ -46,6 +47,14 @@ const authFeature = createFeature({ on(routerNavigationAction, (state) => ({ ...state, validationErrors: null, + })), + on(authActions.signOutSuccess, (state) => ({ + ...state, + currentUser: null, + })), + on(authActions.signOutFailure, (state, { errors }) => ({ + ...state, + errors, })) ), }); diff --git a/nuxeo-admin-console-web/angular-app/src/app/auth/types/authResponse.interface.ts b/nuxeo-admin-console-web/angular-app/src/app/auth/types/authResponse.interface.ts index 3b5d1e47..ac6a3eec 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/auth/types/authResponse.interface.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/auth/types/authResponse.interface.ts @@ -3,3 +3,13 @@ import { UserInterface } from "../../shared/types/user.interface"; export interface AuthResponseInterface { user: UserInterface; } + +export interface AuthUserResponseInterface{ + id:string, + properties:{ + firstName:string, + lastName:string, + email: string; + username: string; + } +} diff --git a/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.spec.ts b/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.spec.ts index a1b41a64..c245edef 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.spec.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.spec.ts @@ -11,6 +11,8 @@ import { CommonModule } from "@angular/common"; import { PersistenceService } from "../../shared/services/persistence.service"; import { CommonService } from "../../shared/services/common.service"; import { CUSTOM_ELEMENTS_SCHEMA, EventEmitter } from "@angular/core"; +import { StoreModule } from '@ngrx/store'; +import { provideMockStore } from '@ngrx/store/testing'; describe("WarningComponent", () => { let component: WarningComponent; @@ -37,6 +39,7 @@ describe("WarningComponent", () => { MatDialogModule, HyDialogBoxModule, MatCheckboxModule, + StoreModule.forRoot(provideMockStore) ], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [ @@ -55,13 +58,16 @@ describe("WarningComponent", () => { }); it("should initialise the doNotWarn field based on preference saved", () => { - const persistenceServiceGetSpy = spyOn(component.persistenceService, "get"); - persistenceServiceGetSpy.and.returnValue(null); - component.ngOnInit(); - expect(component.doNotWarn).toBe(false); - persistenceServiceGetSpy.and.returnValue("true"); - component.ngOnInit(); - expect(component.doNotWarn).toBe(true); + if (component?.currentUser) { + const persistenceServiceGetSpy = spyOn(component.persistenceService, "get"); + persistenceServiceGetSpy.and.returnValue(null); + component.ngOnInit(); + expect(component.doNotWarn).toBe(false); + persistenceServiceGetSpy.and.returnValue("true"); + component.ngOnInit(); + expect(component.doNotWarn).toBe(true); + } + }); describe("should test confirm click actions", () => { @@ -76,22 +82,28 @@ describe("WarningComponent", () => { }); it("should set preference as true & close dialog & emit loadApp=true, when doNotWarn field is checked", () => { - component.doNotWarn = true; - spyOn(component.dialogService, "closeAll"); - component.onConfirm(); - expect(persistenceServiceSetSpy).toHaveBeenCalledWith( - "doNotWarn", - "true" - ); - expect(commonServiceLoadAppEmitSpy).toHaveBeenCalledWith(true); - expect(component.dialogService.closeAll).toHaveBeenCalled(); + if (component?.currentUser) { + component.doNotWarn = true; + spyOn(component.dialogService, "closeAll"); + component.onConfirm(); + const preferenceKey = `doNotWarn-${component?.currentUser?.id}`; + expect(persistenceServiceSetSpy).toHaveBeenCalledWith( + preferenceKey, + "true" + ); + expect(commonServiceLoadAppEmitSpy).toHaveBeenCalledWith(true); + expect(component.dialogService.closeAll).toHaveBeenCalled(); + } + }); it("should not set preference & close dialog & emit loadApp=true, when doNotWarn field is unchecked", () => { - component.doNotWarn = false; - spyOn(component.dialogService, "closeAll"); - component.onConfirm(); - expect(commonServiceLoadAppEmitSpy).toHaveBeenCalledWith(true); - expect(component.dialogService.closeAll).toHaveBeenCalled(); + if (component?.currentUser) { + component.doNotWarn = false; + spyOn(component.dialogService, "closeAll"); + component.onConfirm(); + expect(commonServiceLoadAppEmitSpy).toHaveBeenCalledWith(true); + expect(component.dialogService.closeAll).toHaveBeenCalled(); + } }); }); }); diff --git a/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.ts b/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.ts index 3f81e4c9..acc11789 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/features/warning/warning.component.ts @@ -3,6 +3,10 @@ import { MatDialog } from "@angular/material/dialog"; import { PersistenceService } from "../../shared/services/persistence.service"; import { CommonService } from "../../shared/services/common.service"; import { HyKeyboardFocusService } from "@hyland/ui/keyboard-focus"; +import { Store, select } from '@ngrx/store'; +import { Observable } from 'rxjs'; +import { AuthStateInterface } from '../../auth/types/authState.interface'; +import { UserInterface } from '../../shared/types/user.interface'; @Component({ selector: "warning", @@ -11,22 +15,34 @@ import { HyKeyboardFocusService } from "@hyland/ui/keyboard-focus"; }) export class WarningComponent implements OnInit { public doNotWarn = false; + public currentUser$: Observable; + public currentUser: UserInterface | null | undefined = undefined; constructor( public dialogService: MatDialog, public persistenceService: PersistenceService, public commonService: CommonService, - private _hyKeyboardFocusService: HyKeyboardFocusService - ) {} + private _hyKeyboardFocusService: HyKeyboardFocusService, + private store: Store<{ auth: AuthStateInterface }> + ) { + this.currentUser$ = this.store.pipe(select((state: { auth: AuthStateInterface }) => state.auth.currentUser)); + } ngOnInit(): void { - const preference = this.persistenceService.get("doNotWarn"); - this.doNotWarn = !!preference && preference === "true"; + this.currentUser$.subscribe(user => { + this.currentUser = user; + if (this.currentUser) { + const preferenceKey = `doNotWarn-${this.currentUser.id}`; + const preference = this.persistenceService.get(preferenceKey); + this.doNotWarn = !!preference && preference === 'true'; + } + }); } onConfirm(): void { - if (this.doNotWarn) { - this.persistenceService.set("doNotWarn", "true"); + if (this.currentUser && this.doNotWarn) { + const preferenceKey = `doNotWarn-${this.currentUser.id}`; + this.persistenceService.set(preferenceKey, 'true'); } this.closeDialog(); this.commonService.loadApp.emit(true); diff --git a/nuxeo-admin-console-web/angular-app/src/app/layouts/base-layout/components/base-layout.component.spec.ts b/nuxeo-admin-console-web/angular-app/src/app/layouts/base-layout/components/base-layout.component.spec.ts index dcdd1727..dee2fac1 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/layouts/base-layout/components/base-layout.component.spec.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/layouts/base-layout/components/base-layout.component.spec.ts @@ -5,6 +5,10 @@ import { RouterModule } from '@angular/router'; import { MenuBarComponent } from "../../menu-bar/menu-bar.component"; import { HeaderBarComponent } from "../../header-bar/header-bar.component"; import { BaseLayoutComponent } from "./base-layout.component"; +import { provideMockStore } from '@ngrx/store/testing'; +import { StoreModule } from '@ngrx/store'; +import { MatIconModule } from "@angular/material/icon"; + import { ComponentFixture, ComponentFixtureAutoDetect, @@ -23,7 +27,7 @@ describe("BaseLayoutComponent", () => { HeaderBarComponent, MenuBarComponent, ], - imports: [CommonModule, RouterModule, MatToolbarModule, MatListModule, MatSidenavModule], + imports: [CommonModule, MatIconModule,RouterModule, MatToolbarModule, MatListModule, MatSidenavModule,StoreModule.forRoot(provideMockStore)], providers: [{ provide: ComponentFixtureAutoDetect, useValue: true }], }).compileComponents(); fixture = TestBed.createComponent(BaseLayoutComponent); diff --git a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.html b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.html index 2fe82302..bd511c42 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.html +++ b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.html @@ -7,7 +7,11 @@ - + \ No newline at end of file diff --git a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.scss b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.scss index ac7729df..1e7aa7a2 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.scss +++ b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.scss @@ -26,6 +26,18 @@ color: #212121; font-size: 20px; } + &__username { + color: #212121; + font-size: 14px; + margin-right: 15px; + &__skeleton { + width: 120px; + height: 24px; + background-color: rgba(175, 169, 169, 0.432); + border-radius: 20px; + margin-right: 15px; + } + } &__profile-icon { height: 58px !important; width: 58px !important; diff --git a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.spec.ts b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.spec.ts index e342238a..830b58b6 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.spec.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.spec.ts @@ -1,5 +1,9 @@ import { HeaderBarComponent } from "./header-bar.component"; import { MatToolbarModule } from "@angular/material/toolbar"; +import { StoreModule } from '@ngrx/store'; +import { provideMockStore } from '@ngrx/store/testing'; +import { HyMaterialIconModule } from "@hyland/ui"; +import { MatIconModule } from "@angular/material/icon"; import { ComponentFixture, ComponentFixtureAutoDetect, @@ -14,7 +18,7 @@ describe("HeaderBarComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [HeaderBarComponent], - imports: [CommonModule, MatToolbarModule], + imports: [CommonModule,MatIconModule, MatToolbarModule,StoreModule.forRoot(provideMockStore)], providers: [{ provide: ComponentFixtureAutoDetect, useValue: true }], }).compileComponents(); fixture = TestBed.createComponent(HeaderBarComponent); diff --git a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.ts b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.ts index 858a3621..a8294b37 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/layouts/header-bar/header-bar.component.ts @@ -1,8 +1,56 @@ -import { Component } from "@angular/core"; - +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Store, select } from '@ngrx/store'; +import { authActions } from '../../auth/store/actions'; +import { Observable, Subscription } from 'rxjs'; +import { AuthStateInterface } from '../../auth/types/authState.interface'; +import { UserInterface } from '../../shared/types/user.interface'; +import { NuxeoJSClientService } from "../../shared/services/nuxeo-js-client.service"; @Component({ selector: "header-bar", templateUrl: "./header-bar.component.html", styleUrls: ["./header-bar.component.scss"], }) -export class HeaderBarComponent {} +export class HeaderBarComponent implements OnInit, OnDestroy { + currentUser$: Observable; + currentUserSubscription: Subscription = new Subscription(); + currentUser: UserInterface | null | undefined = undefined; + displayName: string | undefined; + + constructor(private store: Store<{ auth: AuthStateInterface }>, private nuxeoJsClientService: NuxeoJSClientService,) { + this.currentUser$ = this.store.pipe(select((state: { auth: AuthStateInterface }) => state.auth.currentUser)); + } + + ngOnInit(): void { + this.currentUserSubscription = this.currentUser$.subscribe(currentUser => { + this.currentUser = currentUser; + this.setDisplayName(); + }); + } + + ngOnDestroy(): void { + this.currentUserSubscription.unsubscribe(); + } + + onSignOut(): void { + this.store.dispatch(authActions.signOut()); + this.redirectToHome(); + } + + private redirectToHome(): void { + const _baseURL = this.nuxeoJsClientService.getBaseUrl(); + window.location.href = `${_baseURL}login.jsp?requestedUrl=nuxeoadmin`; + } + + private setDisplayName(): void { + if (this.currentUser) { + const { firstName, lastName, username } = this.currentUser.properties; + if (firstName && lastName) { + this.displayName = `${firstName} ${lastName}`; + } else if (firstName) { + this.displayName = firstName; + } else { + this.displayName = username; + } + } + } +} diff --git a/nuxeo-admin-console-web/angular-app/src/app/shared/services/persistence.service.spec.ts b/nuxeo-admin-console-web/angular-app/src/app/shared/services/persistence.service.spec.ts index b5b3dc54..0e3ae61e 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/shared/services/persistence.service.spec.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/shared/services/persistence.service.spec.ts @@ -34,20 +34,20 @@ describe("PersistenceService", () => { ); }); it("should set key-value pair in localstorage successfully, if there is no error", () => { - service.set("doNotWarn", "true"); - expect(localStorage.getItem("doNotWarn")).toBe('"true"'); + service.set("doNotWarn-Administrator", "true"); + expect(localStorage.getItem("doNotWarn-Administrator")).toBe('"true"'); }); it("should not set key-value pair in localstorage, if there is error", () => { spyOn(service, "set").and.callFake(() => { throw new Error(""); }); - expect(localStorage.getItem("doNotWarn")).toBe(null); + expect(localStorage.getItem("doNotWarn-Administrator")).toBe(null); }); it("should not return value if getting key-value pair from localstorage thorws an error", () => { - localStorage.removeItem("doNotWarn"); - expect(service.get("doNotWarn")).toBe(null); + localStorage.removeItem("doNotWarn-Administrator"); + expect(service.get("doNotWarn-Administrator")).toBe(null); }); }); }); diff --git a/nuxeo-admin-console-web/angular-app/src/app/shared/types/user.interface.ts b/nuxeo-admin-console-web/angular-app/src/app/shared/types/user.interface.ts index 2b8ae156..a422fa8b 100644 --- a/nuxeo-admin-console-web/angular-app/src/app/shared/types/user.interface.ts +++ b/nuxeo-admin-console-web/angular-app/src/app/shared/types/user.interface.ts @@ -1,9 +1,9 @@ export interface UserInterface { - // demo model need to be replaced - email: string; - token: string; - username: string; - usertype: string; - bio: string | null; - image: string | null; -} + id: string, + properties: { + firstName: string, + lastName: string, + email: string; + username: string; + } +} \ No newline at end of file