diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html index 391909c5e860ed7f5eb6749338db9db91d570fd8..79145a12445e249aef7ca4b4930b2ef73dec2984 100644 --- a/alfa-client/apps/admin/src/app/app.component.html +++ b/alfa-client/apps/admin/src/app/app.component.html @@ -7,6 +7,7 @@ class="rounded border-2 border-transparent p-1 outline-2 outline-offset-2 hover:border-primary focus-visible:border-gray-200 focus-visible:outline-focus" aria-label="OZG-Cloud Administration" routerLink="/" + data-test-id="logo-link" ><ods-admin-logo-icon /></a> <div> diff --git a/alfa-client/apps/admin/src/app/app.component.spec.ts b/alfa-client/apps/admin/src/app/app.component.spec.ts index a8dfa9a539e491d0e62a2b1e76170d08911315e9..d46fcd163a436a5334ed8371f003c6dcc7836194 100644 --- a/alfa-client/apps/admin/src/app/app.component.spec.ts +++ b/alfa-client/apps/admin/src/app/app.component.spec.ts @@ -6,19 +6,20 @@ import { } from '@alfa-client/tech-shared'; import { Mock, + dispatchEventFromFixture, existsAsHtmlElement, getElementFromFixture, mock, notExistsAsHtmlElement, } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { Router, RouterOutlet } from '@angular/router'; +import { AdminLogoIconComponent } from '@ods/system'; import { AuthenticationService } from 'authentication'; import { NavigationComponent } from 'libs/admin-settings/src/lib/navigation/navigation.component'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; +import { MockComponent, MockDirective } from 'ng-mocks'; import { of } from 'rxjs'; import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component'; import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/unavailable-page.component'; @@ -32,6 +33,7 @@ describe('AppComponent', () => { const buildVersionSelector: string = getDataTestIdOf('build-version'); const userProfileButtonSelector: string = getDataTestIdOf('user-profile-button'); const navigationSelector: string = getDataTestIdOf('navigation'); + const logoLink: string = getDataTestIdOf('logo-link'); const routerOutletSelector: string = getDataTestIdOf('router-outlet'); const authenticationService: Mock<AuthenticationService> = { @@ -47,11 +49,12 @@ describe('AppComponent', () => { declarations: [ AppComponent, MockComponent(NavigationComponent), + MockComponent(AdminLogoIconComponent), MockComponent(UserProfileButtonContainerComponent), MockComponent(UnavailablePageComponent), HasLinkPipe, + MockDirective(RouterOutlet), ], - imports: [RouterTestingModule], providers: [ { provide: AuthenticationService, @@ -129,6 +132,21 @@ describe('AppComponent', () => { }); }); + describe('administration logo', () => { + const apiResource: ApiRootResource = createApiRootResource(); + + beforeEach(() => { + component.apiRootStateResource$ = of(createStateResource(apiResource)); + fixture.detectChanges(); + }); + + it('should navigate to start page on click', () => { + dispatchEventFromFixture(fixture, logoLink, 'click'); + + expect(router.navigate).toHaveBeenCalledWith(['/']); + }); + }); + describe('navigation', () => { beforeEach(() => {}); it('should exist if configuration link exists', () => { diff --git a/alfa-client/apps/admin/src/app/app.module.ts b/alfa-client/apps/admin/src/app/app.module.ts index b5444792c8a70fcb7d2d6cc63478bb50a33255cf..425e65dea56d027a0883b0de1f49249c13e5049b 100644 --- a/alfa-client/apps/admin/src/app/app.module.ts +++ b/alfa-client/apps/admin/src/app/app.module.ts @@ -13,7 +13,12 @@ import { EffectsModule } from '@ngrx/effects'; import { StoreRouterConnectingModule } from '@ngrx/router-store'; import { StoreModule } from '@ngrx/store'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; -import { AdminLogoIconComponent } from '@ods/system'; +import { + AdminLogoIconComponent, + LogoutIconComponent, + PopupComponent, + PopupListItemComponent, +} from '@ods/system'; import { OAuthModule } from 'angular-oauth2-oidc'; import { HttpUnauthorizedInterceptor } from 'libs/authentication/src/lib/http-unauthorized.interceptor'; import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component'; @@ -35,6 +40,9 @@ import { appRoutes } from './app.routes'; imports: [ CommonModule, AdminLogoIconComponent, + PopupComponent, + PopupListItemComponent, + LogoutIconComponent, RouterModule.forRoot(appRoutes), BrowserModule, BrowserAnimationsModule, diff --git a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.html b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.html index e27ec82f62a522e589002e75ed0830ed483ed079..436ac2a76728c0b0b9b9da7d5e67d8bc0765a98d 100644 --- a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.html +++ b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.html @@ -1,10 +1,18 @@ -<div class="dropdown"> - <button (click)="showDropDown()" class="dropbtn" data-test-id="drop-down-button"> - {{ currentUserInitials }} - </button> - <div id="myDropdown" class="dropdown-content"> - <span style="cursor: pointer" (click)="authenticationService.logout()" data-test-id="logout" - >Abmelden</span - > +<ods-popup buttonClass="rounded-full"> + <div + button-content + role="img" + class="flex size-9 items-center justify-center rounded-full border-2 border-transparent bg-ozggray-900 hover:border-primary" + > + <p class="font-semibold text-whitetext" data-test-id="popup-button-content"> + {{ currentUserInitials }} + </p> </div> -</div> + <ods-popup-list-item + caption="Abmelden" + (itemClicked)="authenticationService.logout()" + data-test-id="popup-logout-button" + > + <ods-logout-icon icon /> + </ods-popup-list-item> +</ods-popup> diff --git a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.scss b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.scss deleted file mode 100644 index 1e97f8cf7a58771514150ec93379a467bb902e2f..0000000000000000000000000000000000000000 --- a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -.dropbtn { - background-color: #666666; - color: white; - padding: 16px; - cursor: pointer; - border-radius: 30px; -} - -.dropbtn:hover, -.dropbtn:focus { - background-color: #666666; -} - -.dropdown-content { - display: none; - position: absolute; - background-color: #f1f1f1; - z-index: 1; -} - -.show { - display: block; -} diff --git a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.spec.ts b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.spec.ts index bf2390e5130e235721a9eeaacbef88f7cb49f7b9..70c324948070f3e79d92bf51dca0f8f8f577d821 100644 --- a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.spec.ts +++ b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile-button-container.component.spec.ts @@ -6,8 +6,10 @@ import { } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { LogoutIconComponent, PopupComponent, PopupListItemComponent } from '@ods/system'; import { AuthenticationService } from 'authentication'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { MockComponent } from 'ng-mocks'; import { UserProfileButtonContainerComponent } from './user-profile.button-container.component'; describe('UserProfileButtonContainerComponent', () => { @@ -16,13 +18,18 @@ describe('UserProfileButtonContainerComponent', () => { const authenticationService: Mock<AuthenticationService> = mock(AuthenticationService); - const dropDownButton: string = getDataTestIdOf('drop-down-button'); - const logout: string = getDataTestIdOf('logout'); + const popupButtonContent: string = getDataTestIdOf('popup-button-content'); + const popupLogoutButton: string = getDataTestIdOf('popup-logout-button'); beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [UserProfileButtonContainerComponent], - imports: [RouterTestingModule], + imports: [ + RouterTestingModule, + MockComponent(PopupComponent), + MockComponent(PopupListItemComponent), + MockComponent(LogoutIconComponent), + ], providers: [ { provide: AuthenticationService, @@ -50,29 +57,23 @@ describe('UserProfileButtonContainerComponent', () => { }); }); - describe('button', () => { - it('should call showDropDown on click', () => { - component.showDropDown = jest.fn(); - - dispatchEventFromFixture(fixture, dropDownButton, 'click'); - - expect(component.showDropDown).toHaveBeenCalled(); - }); - + describe('popup button', () => { it('should show initials', () => { - const userInitials: string = 'AV'; - component.currentUserInitials = userInitials; - + component.currentUserInitials = 'AV'; fixture.detectChanges(); - const buttonElement: HTMLElement = getElementFromFixture(fixture, dropDownButton); - expect(buttonElement.textContent.trim()).toEqual('AV'); + const popupButtonContentElement: HTMLElement = getElementFromFixture( + fixture, + popupButtonContent, + ); + + expect(popupButtonContentElement.textContent.trim()).toEqual('AV'); }); }); - describe('abmelden', () => { + describe('logout', () => { it('should call authService logout', () => { - dispatchEventFromFixture(fixture, logout, 'click'); + dispatchEventFromFixture(fixture, popupLogoutButton, 'itemClicked'); expect(authenticationService.logout).toHaveBeenCalled(); }); diff --git a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile.button-container.component.ts b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile.button-container.component.ts index e61c01de1c3797616a0fad8d69ccc375af2bb39d..4b5e3c28a54eff2f89c9328bcb1559fa9a8348eb 100644 --- a/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile.button-container.component.ts +++ b/alfa-client/apps/admin/src/common/user-profile-button-container/user-profile.button-container.component.ts @@ -4,7 +4,6 @@ import { AuthenticationService } from 'libs/authentication/src/lib/authenticatio @Component({ selector: 'user-profile-button-container', templateUrl: './user-profile-button-container.component.html', - styleUrls: ['./user-profile-button-container.component.scss'], }) export class UserProfileButtonContainerComponent implements OnInit { public currentUserInitials: string; @@ -14,8 +13,4 @@ export class UserProfileButtonContainerComponent implements OnInit { ngOnInit(): void { this.currentUserInitials = this.authenticationService.getCurrentUserInitials(); } - - public showDropDown(): void { - document.getElementById('myDropdown').classList.toggle('show'); - } } diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js index b17ef3c855216e3e735314a6e0b17984d4b3068f..f998ef819768fb984e0e5c28789c3b93f769497c 100644 --- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js +++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js @@ -71,6 +71,7 @@ module.exports = { 600: 'hsla(0, 0%, 0%, 0.4)', 700: 'hsl(213, 27%, 84%)', 800: 'hsl(0, 0%, 43%)', + 900: 'hsl(0, 0%, 24%)', DEFAULT: 'hsl(0, 0%, 98%)', }, background: {