From 3b8b62a8d6d9b8a218d1eae9b674e2480639f6fb Mon Sep 17 00:00:00 2001 From: Alexander Reifschneider <alexander.reifschneider@mgm-tp.com> Date: Thu, 24 Apr 2025 11:00:21 +0200 Subject: [PATCH] OZG-7774 add statistic menu Sub-Task: OZG-8104 --- .../apps/admin/src/app/app.component.html | 3 + .../apps/admin/src/app/app.component.ts | 3 +- .../libs/admin/configuration/src/index.ts | 1 + .../menu-container/menu/menu.component.html | 5 -- .../menu/menu.component.spec.ts | 20 ------- .../statistik-menu-container.component.html | 1 + ...statistik-menu-container.component.spec.ts | 55 +++++++++++++++++++ .../statistik-menu-container.component.ts | 22 ++++++++ .../statistik-menu.component.html | 16 ++++++ .../statistik-menu.component.spec.ts | 53 ++++++++++++++++++ .../statistik-menu.component.ts | 19 +++++++ .../libs/admin/shared/src/lib/routes.ts | 6 +- .../nav-headline/nav-headline.component.ts | 2 +- 13 files changed, 176 insertions(+), 30 deletions(-) create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.html create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.spec.ts create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.ts create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.html create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.spec.ts create mode 100644 alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.ts diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html index e3f678a098..561a68601f 100644 --- a/alfa-client/apps/admin/src/app/app.component.html +++ b/alfa-client/apps/admin/src/app/app.component.html @@ -61,6 +61,9 @@ @if (apiRoot | hasLink: apiRootLinkRel.CONFIGURATION) { <admin-menu-container data-test-id="menu-container"></admin-menu-container> } + @if (apiRoot | hasLink: apiRootLinkRel.CONFIGURATION) { + <admin-statistik-menu-container data-test-id="menu-container" /> + } </ods-navbar> <main class="flex-1 overflow-y-auto bg-white px-6 py-4"> <router-outlet diff --git a/alfa-client/apps/admin/src/app/app.component.ts b/alfa-client/apps/admin/src/app/app.component.ts index 8cc01f4def..8aee55efef 100644 --- a/alfa-client/apps/admin/src/app/app.component.ts +++ b/alfa-client/apps/admin/src/app/app.component.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { MenuContainerComponent } from '@admin-client/configuration'; +import { MenuContainerComponent, StatistikMenuContainerComponent } from '@admin-client/configuration'; import { ConfigurationLinkRel, ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared'; import { ROUTES } from '@admin-client/shared'; import { KeycloakTokenService } from '@admin/keycloak-shared'; @@ -53,6 +53,7 @@ import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/ UnavailablePageComponent, BuildInfoComponent, MenuContainerComponent, + StatistikMenuContainerComponent, RouterLink, HasLinkPipe, ], diff --git a/alfa-client/libs/admin/configuration/src/index.ts b/alfa-client/libs/admin/configuration/src/index.ts index 221b8b7376..63bd38c1b3 100644 --- a/alfa-client/libs/admin/configuration/src/index.ts +++ b/alfa-client/libs/admin/configuration/src/index.ts @@ -1 +1,2 @@ export * from './lib/menu-container/menu-container.component'; +export * from './lib/statistik-menu-container/statistik-menu-container.component'; diff --git a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html index 672cb8f71c..5d7b258f2f 100644 --- a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html +++ b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html @@ -3,8 +3,3 @@ <ods-icon icon name="mailbox" fill="text" /> </ods-nav-item> } -@if (configurationStateResource.resource | hasLink: configurationLinkRel.AGGREGATION_MAPPINGS) { - <ods-nav-item data-test-id="statistik-navigation" caption="Statistik" [path]="'/' + ROUTES.AGGREGATION_MAPPING"> - <ods-icon icon name="statistic" fill="text" /> - </ods-nav-item> -} diff --git a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.spec.ts b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.spec.ts index bc802c253d..5f5b3c7c54 100644 --- a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.spec.ts +++ b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.spec.ts @@ -48,24 +48,4 @@ describe('MenuComponent', () => { notExistsAsHtmlElement(fixture, postfachNavigation); }); }); - - describe('statistic navigation', () => { - it('should show if settings link is present', () => { - component.configurationStateResource = createStateResource( - createConfigurationResource([ConfigurationLinkRel.AGGREGATION_MAPPINGS]), - ); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, statistikNavigationSelector); - }); - - it('should hide if settings link is missing', () => { - component.configurationStateResource = createStateResource(createConfigurationResource()); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, statistikNavigationSelector); - }); - }); }); diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.html b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.html new file mode 100644 index 0000000000..5392d99854 --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.html @@ -0,0 +1 @@ +<admin-statistik-menu [configurationStateResource]="configurationStateResource$ | async" /> diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.spec.ts b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.spec.ts new file mode 100644 index 0000000000..8b521c1b5e --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.spec.ts @@ -0,0 +1,55 @@ +import { ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared'; +import { createStateResource, StateResource } from '@alfa-client/tech-shared'; +import { getMockComponent, mock, Mock } from '@alfa-client/test-utils'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { createConfigurationResource } from '../../../../configuration-shared/test/configuration'; +import { StatistikMenuContainerComponent } from './statistik-menu-container.component'; +import { StatistikMenuComponent } from './statistik-menu/statistik-menu.component'; + +describe('StatistikMenuContainerComponent', () => { + let component: StatistikMenuContainerComponent; + let fixture: ComponentFixture<StatistikMenuContainerComponent>; + + let configurationService: Mock<ConfigurationService>; + + const configurationStateResource: StateResource<ConfigurationResource> = createStateResource(createConfigurationResource()); + + beforeEach(async () => { + configurationService = { ...mock(ConfigurationService), get: jest.fn().mockReturnValue(of(configurationStateResource)) }; + + await TestBed.configureTestingModule({ + imports: [StatistikMenuContainerComponent], + declarations: [MockComponent(StatistikMenuComponent)], + providers: [ + { + provide: ConfigurationService, + useValue: configurationService, + }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(StatistikMenuContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('ngOnInit', () => { + it('should call service', () => { + component.ngOnInit(); + + expect(configurationService.get).toHaveBeenCalled(); + }); + }); + + it('should call menu', () => { + const menu: StatistikMenuComponent = getMockComponent(fixture, StatistikMenuComponent); + + expect(menu.configurationStateResource).toBe(configurationStateResource); + }); +}); diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.ts b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.ts new file mode 100644 index 0000000000..3084cd0801 --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu-container.component.ts @@ -0,0 +1,22 @@ +import { ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; +import { StatistikMenuComponent } from './statistik-menu/statistik-menu.component'; + +@Component({ + selector: 'admin-statistik-menu-container', + standalone: true, + imports: [CommonModule, StatistikMenuComponent], + templateUrl: './statistik-menu-container.component.html', +}) +export class StatistikMenuContainerComponent implements OnInit { + private readonly configurationService = inject(ConfigurationService); + + public configurationStateResource$: Observable<StateResource<ConfigurationResource>>; + + ngOnInit(): void { + this.configurationStateResource$ = this.configurationService.get(); + } +} diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.html b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.html new file mode 100644 index 0000000000..da11f79e80 --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.html @@ -0,0 +1,16 @@ +<ods-nav-headline label="Statistik" /> +@if (configurationStateResource.resource | hasLink: configurationLinkRel.AGGREGATION_MAPPINGS) { + <ods-nav-item data-test-id="statistik-navigation" caption="Auswertungen" [path]="'/' + ROUTES.AGGREGATION_MAPPING"> + <ods-icon icon name="statistic" fill="text" /> + </ods-nav-item> +} +<!-- @if (configurationStateResource.resource | hasLink: configurationLinkRel.**datenanfragen**) { + <ods-nav-item data-test-id="statistik-navigation" caption="Auswertungen" [path]="'/' + **datenanfragen**"> + <ods-icon icon name="statistic" fill="text" /> + </ods-nav-item> +} +@if (configurationStateResource.resource | hasLink: configurationLinkRel.**datenfreigaben**) { + <ods-nav-item data-test-id="statistik-navigation" caption="Auswertungen" [path]="'/' + **datenfreigaben**"> + <ods-icon icon name="statistic" fill="text" /> + </ods-nav-item> +} --> diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.spec.ts b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.spec.ts new file mode 100644 index 0000000000..805ffa7faf --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.spec.ts @@ -0,0 +1,53 @@ +import { ConfigurationLinkRel } from '@admin-client/configuration-shared'; +import { createEmptyStateResource, createStateResource, HasLinkPipe } from '@alfa-client/tech-shared'; +import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { IconComponent, NavItemComponent } from '@ods/system'; +import { createConfigurationResource } from 'libs/admin/configuration-shared/test/configuration'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { MockComponent } from 'ng-mocks'; +import { StatistikMenuComponent } from './statistik-menu.component'; + +describe('StatistikMenuComponent', () => { + let component: StatistikMenuComponent; + let fixture: ComponentFixture<StatistikMenuComponent>; + + const postfachNavigation: string = getDataTestIdOf('postfach-navigation'); + const statistikNavigationSelector: string = getDataTestIdOf('statistik-navigation'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [StatistikMenuComponent, HasLinkPipe], + declarations: [MockComponent(NavItemComponent), MockComponent(IconComponent)], + }).compileComponents(); + + fixture = TestBed.createComponent(StatistikMenuComponent); + component = fixture.componentInstance; + component.configurationStateResource = createEmptyStateResource(); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('statistic navigation', () => { + it('should show if agregation mapping link is present', () => { + component.configurationStateResource = createStateResource( + createConfigurationResource([ConfigurationLinkRel.AGGREGATION_MAPPINGS]), + ); + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, statistikNavigationSelector); + }); + + it('should hide if agregation mapping link is missing', () => { + component.configurationStateResource = createStateResource(createConfigurationResource()); + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, statistikNavigationSelector); + }); + }); +}); diff --git a/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.ts b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.ts new file mode 100644 index 0000000000..75a8bab295 --- /dev/null +++ b/alfa-client/libs/admin/configuration/src/lib/statistik-menu-container/statistik-menu/statistik-menu.component.ts @@ -0,0 +1,19 @@ +import { ConfigurationLinkRel, ConfigurationResource } from '@admin-client/configuration-shared'; +import { ROUTES } from '@admin-client/shared'; +import { HasLinkPipe, StateResource } from '@alfa-client/tech-shared'; +import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { IconComponent, NavHeadlineComponent, NavItemComponent } from '@ods/system'; + +@Component({ + selector: 'admin-statistik-menu', + standalone: true, + imports: [CommonModule, NavItemComponent, IconComponent, HasLinkPipe, NavHeadlineComponent], + templateUrl: './statistik-menu.component.html', +}) +export class StatistikMenuComponent { + @Input() configurationStateResource: StateResource<ConfigurationResource>; + + public readonly configurationLinkRel = ConfigurationLinkRel; + public readonly ROUTES = ROUTES; +} diff --git a/alfa-client/libs/admin/shared/src/lib/routes.ts b/alfa-client/libs/admin/shared/src/lib/routes.ts index 9f1496843e..3f872ee122 100644 --- a/alfa-client/libs/admin/shared/src/lib/routes.ts +++ b/alfa-client/libs/admin/shared/src/lib/routes.ts @@ -28,7 +28,7 @@ export enum ROUTES { BENUTZER_ID = 'benutzer/:userid', ORGANISATIONSEINHEITEN = 'organisationseinheiten', UNAVAILABLE = 'unavailable', - AGGREGATION_MAPPING = 'auswertungen', - AGGREGATION_MAPPING_NEU = 'auswertungen/neu', - AGGREGATION_MAPPING_ID = 'auswertungen/:aggregationMappingId', + AGGREGATION_MAPPING = 'statistik/auswertungen', + AGGREGATION_MAPPING_NEU = 'statistik/auswertungen/neu', + AGGREGATION_MAPPING_ID = 'statistik/auswertungen/:aggregationMappingId', } diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-headline/nav-headline.component.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-headline/nav-headline.component.ts index 052bc70128..a2f538b5db 100644 --- a/alfa-client/libs/design-system/src/lib/navbar/nav-headline/nav-headline.component.ts +++ b/alfa-client/libs/design-system/src/lib/navbar/nav-headline/nav-headline.component.ts @@ -5,7 +5,7 @@ import { Component, Input } from '@angular/core'; selector: 'ods-nav-headline', standalone: true, imports: [CommonModule], - template: `<p class="mx-4 font-medium">{{ label }}</p>`, + template: `<p class="mx-4 my-2 font-medium">{{ label }}</p>`, }) export class NavHeadlineComponent { @Input({ required: true }) label!: string; -- GitLab