diff --git a/Jenkinsfile b/Jenkinsfile index deb6ce4266ec36519843962e4f378ed44768e381..1ab8edc5cc6893467c0899840c921efe0f1e550e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -494,4 +494,4 @@ String getRootPomVersion() { String getParentPomVersion(String filePath) { def pom = readMavenPom file: filePath return pom.parent.version -} \ No newline at end of file +} diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html index adbd608ba83644365146d6b241a20848e473f065..66f83dc085317b14d81ad4a3b54fec85b9f88890 100644 --- a/alfa-client/apps/admin/src/app/app.component.html +++ b/alfa-client/apps/admin/src/app/app.component.html @@ -16,12 +16,16 @@ ></user-profile-button-container> </header> <div class="flex h-screen w-full justify-center overflow-y-auto"> - <nav class="h-full w-72 bg-slate-100 p-4"> - <admin-navigation - *ngIf="apiRoot | hasLink: ApiRootLinkRel.CONFIGURATION" - data-test-id="navigation" - ></admin-navigation> - </nav> + <ods-navbar data-test-id="navigation"> + <ng-container *ngIf="apiRoot | hasLink: ApiRootLinkRel.CONFIGURATION"> + <ods-nav-item caption="Organisationseinheiten" to="/organisationseinheiten"> + <ods-orga-unit-icon icon /> + </ods-nav-item> + <ods-nav-item caption="Postfach" to="/postfach"> + <ods-mailbox-icon icon /> + </ods-nav-item> + </ng-container> + </ods-navbar> <main class="flex-1 overflow-y-auto bg-white px-6 py-4"> <router-outlet *ngIf=" 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 d46fcd163a436a5334ed8371f003c6dcc7836194..9dc1460ef48786b4278b89bc2fef350c0e5d45f1 100644 --- a/alfa-client/apps/admin/src/app/app.component.spec.ts +++ b/alfa-client/apps/admin/src/app/app.component.spec.ts @@ -14,7 +14,13 @@ import { } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router, RouterOutlet } from '@angular/router'; -import { AdminLogoIconComponent } from '@ods/system'; +import { + AdminLogoIconComponent, + MailboxIconComponent, + NavItemComponent, + NavbarComponent, + OrgaUnitIconComponent, +} 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'; @@ -50,8 +56,12 @@ describe('AppComponent', () => { AppComponent, MockComponent(NavigationComponent), MockComponent(AdminLogoIconComponent), + MockComponent(OrgaUnitIconComponent), + MockComponent(MailboxIconComponent), MockComponent(UserProfileButtonContainerComponent), MockComponent(UnavailablePageComponent), + MockComponent(NavbarComponent), + MockComponent(NavItemComponent), HasLinkPipe, MockDirective(RouterOutlet), ], @@ -149,20 +159,24 @@ describe('AppComponent', () => { describe('navigation', () => { beforeEach(() => {}); - it('should exist if configuration link exists', () => { + it('should show links if configuration link exists', () => { component.apiRootStateResource$ = of( createStateResource(createApiRootResource([ApiRootLinkRel.CONFIGURATION])), ); - fixture.detectChanges(); - existsAsHtmlElement(fixture, navigationSelector); + const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); + + expect(navbarElement.children.length).toBeGreaterThan(0); }); - it('should not exist if configuration resource not available', () => { + it('should not not show links if configuration resource not available', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource([]))); fixture.detectChanges(); - notExistsAsHtmlElement(fixture, navigationSelector); + const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); + + expect(navbarElement.children.length).toBe(0); }); }); diff --git a/alfa-client/apps/admin/src/app/app.module.ts b/alfa-client/apps/admin/src/app/app.module.ts index 5ef0a45f15848eb7c9c327b28c8ada4d986aefc4..95d953049de72142ddd055ba9fb1cdc1f9283f32 100644 --- a/alfa-client/apps/admin/src/app/app.module.ts +++ b/alfa-client/apps/admin/src/app/app.module.ts @@ -16,6 +16,10 @@ import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { AdminLogoIconComponent, LogoutIconComponent, + MailboxIconComponent, + NavItemComponent, + NavbarComponent, + OrgaUnitIconComponent, PopupComponent, PopupListItemComponent, } from '@ods/system'; @@ -42,7 +46,11 @@ import { appRoutes } from './app.routes'; AdminLogoIconComponent, PopupComponent, PopupListItemComponent, + NavItemComponent, + NavbarComponent, + OrgaUnitIconComponent, LogoutIconComponent, + MailboxIconComponent, RouterModule.forRoot(appRoutes), BrowserModule, BrowserAnimationsModule, diff --git a/alfa-client/apps/admin/src/styles.scss b/alfa-client/apps/admin/src/styles.scss index e9a497ed35ba9c4e1b93a5e8b51ffd2d909d9bd7..d4e151f329f1cefda33709ace138cd39fb383a7a 100644 --- a/alfa-client/apps/admin/src/styles.scss +++ b/alfa-client/apps/admin/src/styles.scss @@ -3,3 +3,11 @@ @tailwind utilities; @import 'libs/design-system/src/lib/tailwind-preset/root.css'; + +.heading-1 { + @apply text-3xl font-medium text-text; +} + +.heading-2 { + @apply py-4 text-2xl font-medium text-text; +} diff --git a/alfa-client/apps/alfa-e2e/docker-compose.yml b/alfa-client/apps/alfa-e2e/docker-compose.yml index e87654d697b9a340f65e9a666dff2fcca1b5ad98..c1084ee33bd694659129af4a90e59dc5d1b0c288 100644 --- a/alfa-client/apps/alfa-e2e/docker-compose.yml +++ b/alfa-client/apps/alfa-e2e/docker-compose.yml @@ -28,6 +28,11 @@ services: - 27018:27017 environment: - MONGODB_EXTRA_FLAGS=--profile=2 + healthcheck: + test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet + interval: 10s + timeout: 10s + retries: 5 vorgang-manager: image: docker.ozg-sh.de/vorgang-manager:${VORGANG_MANAGER_DOCKER_IMAGE:-snapshot-latest} @@ -67,9 +72,13 @@ services: - 9091:9090 depends_on: mongodb: - condition: service_started + condition: service_healthy elastic: condition: service_healthy + smocker: + condition: service_healthy + user-manager: + condition: service_started alfa: image: docker.ozg-sh.de/alfa:${ALFA_DOCKER_IMAGE:-snapshot-latest} @@ -96,12 +105,16 @@ services: - BPL_DEBUG_PORT=5000 - OZGCLOUD_VORGANG_BESCHEID_0_FORM_ENGINE_NAME=FormSolutions - OZGCLOUD_VORGANG_BESCHEID_0_FORM_ID=KFAS_STAGE_KI_10_Haltverbot_LANDESHACKATHON + - OZGCLOUD_FEATURE_COLLABORATION_ENABLED=true + - GRPC_CLIENT_ZUFI-MANAGER_ADDRESS=static://zufi-manager-server:9190 + - GRPC_CLIENT_ZUFI-MANAGER_NEGOTIATIONTYPE=PLAINTEXT ports: - 8080:8080 - 5000:5000 depends_on: - vorgang-manager - user-manager + - zufi-manager-server elastic: image: docker.elastic.co/elasticsearch/elasticsearch:8.3.2 @@ -115,6 +128,7 @@ services: - MEM_LIMIT=1073741824 - xpack.security.enabled=false - xpack.security.http.ssl.enabled=false + - logger.level=WARN ulimits: memlock: soft: -1 @@ -159,10 +173,59 @@ services: - 9092:8080 - 9000:9000 depends_on: - - mongodb + mongodb: + condition: service_healthy + + zufi-manager-pvog: + image: docker.ozg-sh.de/zufi-manager:snapshot-latest + platform: linux/amd64 + environment: + - SPRING_DATA_MONGODB_URI=mongodb://mongodb:27017/local + - SPRING_PROFILES_ACTIVE=$${SPRING_PROFILE:e2e} + - LOGGING_CONFIG=classpath:log4j2-local.xml + - OZGCLOUD_PVOG_URL=http://smocker:8080 + depends_on: + mongodb: + condition: service_healthy + smocker-init: + condition: service_completed_successfully + + zufi-manager-server: + image: docker.ozg-sh.de/zufi-server:snapshot-latest + platform: linux/amd64 + environment: + - SPRING_DATA_MONGODB_URI=mongodb://mongodb:27017/local + - SPRING_PROFILES_ACTIVE=$${SPRING_PROFILE:local} + - LOGGING_CONFIG=classpath:log4j2-local.xml + ports: + - 19090:9190 + depends_on: + mongodb: + condition: service_healthy + zufi-manager-pvog: + condition: service_completed_successfully smocker: image: thiht/smocker ports: - 7080:8080 - 7081:8081 + healthcheck: + test: [ + 'CMD-SHELL', + "wget --spider localhost:8081/version", + ] + interval: 5s + timeout: 5s + retries: 5 + + smocker-init: + image: alpine/curl + volumes: + - ./src/fixtures/smocker:/mocks:ro + command: > + sh -c "curl -X POST http://smocker:8081/mocks -H 'Content-Type: application/x-yaml' --data-binary @/mocks/pvog-mock.yaml && + curl -X POST http://smocker:8081/mocks -H 'Content-Type: application/x-yaml' --data-binary @/mocks/mocks.yaml" + depends_on: + smocker: + condition: service_healthy \ No newline at end of file diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/smocker/Readme.md b/alfa-client/apps/alfa-e2e/src/fixtures/smocker/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..aae89a7493a33efa155461dfeecb55f2df395841 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/fixtures/smocker/Readme.md @@ -0,0 +1,37 @@ +# PVOG-Mock Yaml erzeugen + +- PVOG-Rohdaten für das betreffene Bundesland (z.B. Schleswig-Holstein) herunterladen (XML) +- Den E2E-Tester/die -Testerin nach der gewünschten Behörde fragen (am besten OID, z.B. 9093371) +- In den Rohdaten danach suchen +```bash + grep -niro "schemeID=\"OID\">9093371</xzufi:id>" +``` +- Die Datei im Texteditor öffnen (z.B. Notepad++ mit XMLTools Plugin) +- XMLTools "Pretty Print" anwenden. +- In der Datei nach dem XML-Block suchen: +```xml + <xzufi:schreibe> + <xzufi:organisationseinheit xsi:type="xzufi:OrganisationseinheitErweitert" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <xzufi:id schemeAgencyID="L100012" schemeID="OID">9093371</xzufi:id> + ... + </xzufi:organisationseinheit> + </xzufi:schreibe> +``` +- Diesen Block herauskopieren +- In einer anderen Datei die PVOG-Antwortnachricht vorbereiten, Template: +```xml +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<xzufi:transfer.operation.040502 produktbezeichnung="PVOG" produkthersteller="Dataport AöR" xzufiVersion="2.2.0" xmlns:xzufi="http://xoev.de/schemata/xzufi/2_2_0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink"> + <xzufi:nachrichtenkopf> + <xzufi:nachrichtUUID>ce415b36-8905-372b-ba2f-2d471835d99d</xzufi:nachrichtUUID> + <xzufi:erstelltDatumZeit>2024-08-21T13:36:26.166+02:00</xzufi:erstelltDatumZeit> + </xzufi:nachrichtenkopf> + ... +</xzufi:transfer.operation.040502> +``` +- An die Stelle der 3 Punkte die Organisationseinheit reinkopieren +- (Schritte wiederholen für mehr Organisationseinheiten) +- (opt.) mit XMLTools "Validate XML" anwenden (prüft XML Grundstruktur) +- XMLTools "Linearize" anwenden. +- Suchen und Ersetzen: " -> \\" (Stringifiziert die Double-Quotes) +- Ergebnis in pvog-mock.yaml in die JSON, Feld "xzufiObjekte" einfügen \ No newline at end of file diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/smocker/pvog-mock.yaml b/alfa-client/apps/alfa-e2e/src/fixtures/smocker/pvog-mock.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f4e27c777151e9b16b6778f4c0998a3ea25ff67 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/fixtures/smocker/pvog-mock.yaml @@ -0,0 +1,15 @@ +- request: + method: GET + path: /v2/verwaltungsobjekte + response: + status: 200 + headers: + Content-Type: application/json + body: > + { + "anzahlObjekte": 2, + "naechsterIndex": -1, + "naechsteAnfrageUrl": "", + "vollstaendig": true, + "xzufiObjekte": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><xzufi:transfer.operation.040502 produktbezeichnung=\"PVOG\" produkthersteller=\"Dataport AöR\" xzufiVersion=\"2.2.0\" xmlns:xzufi=\"http://xoev.de/schemata/xzufi/2_2_0\" xmlns:gml=\"http://www.opengis.net/gml/3.2\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><xzufi:nachrichtenkopf><xzufi:nachrichtUUID>ce415b36-8905-372b-ba2f-2d471835d99d</xzufi:nachrichtUUID><xzufi:erstelltDatumZeit>2024-08-21T13:36:26.166+02:00</xzufi:erstelltDatumZeit></xzufi:nachrichtenkopf><xzufi:schreibe><xzufi:organisationseinheit xsi:type=\"xzufi:OrganisationseinheitErweitert\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><xzufi:id schemeAgencyID=\"L100012\" schemeID=\"OID\">9797773</xzufi:id><xzufi:externeOrganisationseinheitsermittlung>false</xzufi:externeOrganisationseinheitsermittlung><xzufi:name><xzufi:name languageCode=\"de\">Wirtschaftsförderung und Technologietransfer Schleswig-Holstein GmbH</xzufi:name></xzufi:name><xzufi:anschrift><xzufi:typ listURI=\"urn:xoev-de:fim:codeliste:xzufi.anschrifttyp\" listVersionID=\"2.0\"><code>001</code></xzufi:typ><xzufi:strasse>Lorentzendamm</xzufi:strasse><xzufi:hausnummer>24</xzufi:hausnummer><xzufi:postleitzahl>24103</xzufi:postleitzahl><xzufi:ort>Kiel</xzufi:ort><xzufi:ortID schemeID=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs\" schemeVersionID=\"2022-09-30\">010020000000</xzufi:ortID><xzufi:verwaltungspolitischeKodierung><xzufi:bundesland listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:bundesland\" listVersionID=\"2010-04-01\"><code>01</code><name>Schleswig-Holstein</name></xzufi:bundesland><xzufi:gemeindeschluessel listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:ags\" listVersionID=\"2018-07-31\"><code>01002000</code><name>Kiel</name></xzufi:gemeindeschluessel><xzufi:regionalschluessel listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs\" listVersionID=\"2022-09-30\"><code>010020000000</code><name>Kiel</name></xzufi:regionalschluessel><xzufi:staat listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:staat\" listVersionID=\"2022-02-18\"><code>000</code><name>Deutschland</name></xzufi:staat></xzufi:verwaltungspolitischeKodierung></xzufi:anschrift><xzufi:erreichbarkeit><xzufi:kanal listURI=\"urn:de:xoev:codeliste:erreichbarkeit\" listVersionID=\"3\"><code>02</code></xzufi:kanal><xzufi:kennung>+49 431 66666-0</xzufi:kennung></xzufi:erreichbarkeit><xzufi:erreichbarkeit><xzufi:kanal listURI=\"urn:de:xoev:codeliste:erreichbarkeit\" listVersionID=\"3\"><code>04</code></xzufi:kanal><xzufi:kennung>+49 431 66666-767</xzufi:kennung></xzufi:erreichbarkeit><xzufi:erreichbarkeit><xzufi:kanal listURI=\"urn:de:xoev:codeliste:erreichbarkeit\" listVersionID=\"3\"><code>01</code></xzufi:kanal><xzufi:kennung>info@wtsh.de</xzufi:kennung></xzufi:erreichbarkeit><xzufi:versionsinformation><xzufi:geaendertDatumZeit>2023-11-06T15:12:53+01:00</xzufi:geaendertDatumZeit></xzufi:versionsinformation><xzufi:sprachversion><xzufi:languageCode>de</xzufi:languageCode><xzufi:sprachbezeichnungDeutsch>Deutsch</xzufi:sprachbezeichnungDeutsch><xzufi:sprachbezeichnungNativ>Deutsch</xzufi:sprachbezeichnungNativ></xzufi:sprachversion></xzufi:organisationseinheit></xzufi:schreibe><xzufi:schreibe><xzufi:organisationseinheit xsi:type=\"xzufi:OrganisationseinheitErweitert\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><xzufi:id schemeAgencyID=\"L100012\" schemeID=\"OID\">9093371</xzufi:id><xzufi:externeOrganisationseinheitsermittlung>false</xzufi:externeOrganisationseinheitsermittlung><xzufi:kategorie><xzufi:klasse><xzufi:id>ORGANISATIONSEINHEITSKATEGORIE</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Organisationseinheitkategorie</xzufi:bezeichnung></xzufi:klasse><xzufi:id schemeAgencyID=\"L100012\" schemeID=\"OID\">9081966</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Land: Landesoberbehörde</xzufi:bezeichnung></xzufi:kategorie><xzufi:kategorie><xzufi:klasse><xzufi:id>ORGANISATIONSEINHEITSKATEGORIE</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Organisationseinheitkategorie</xzufi:bezeichnung></xzufi:klasse><xzufi:id schemeAgencyID=\"L100012\" schemeID=\"OID\">9081931</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Land: MBWK</xzufi:bezeichnung></xzufi:kategorie><xzufi:kategorie><xzufi:klasse><xzufi:id>ORGANISATIONSEINHEITSKATEGORIE</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Organisationseinheitkategorie</xzufi:bezeichnung></xzufi:klasse><xzufi:id schemeAgencyID=\"L100012\" schemeID=\"OID\">219766890</xzufi:id><xzufi:bezeichnung languageCode=\"de\">Landesbehörden A-Z</xzufi:bezeichnung></xzufi:kategorie><xzufi:name><xzufi:name languageCode=\"de\">Landesamt für Denkmalpflege</xzufi:name></xzufi:name><xzufi:infoInternServicecenter languageCode=\"de\">Pflege und Schutz der Kulturdenkm&auml;ler lt. gesetzlichem Auftrag Zust&auml;ndigkeitsbereich: Schleswig-Holstein (ohne Hansestadt L&uuml;beck)</xzufi:infoInternServicecenter><xzufi:anschrift><xzufi:typ listURI=\"urn:xoev-de:fim:codeliste:xzufi.anschrifttyp\" listVersionID=\"2.0\"><code>001</code></xzufi:typ><xzufi:strasse>Wall</xzufi:strasse><xzufi:hausnummer>47/51</xzufi:hausnummer><xzufi:postleitzahl>24103</xzufi:postleitzahl><xzufi:ort>Kiel</xzufi:ort><xzufi:ortID schemeID=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs\" schemeVersionID=\"2022-09-30\">010020000000</xzufi:ortID><xzufi:verwaltungspolitischeKodierung><xzufi:bundesland listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:bundesland\" listVersionID=\"2010-04-01\"><code>01</code><name>Schleswig-Holstein</name></xzufi:bundesland><xzufi:gemeindeschluessel listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:ags\" listVersionID=\"2018-07-31\"><code>01002000</code><name>Kiel</name></xzufi:gemeindeschluessel><xzufi:regionalschluessel listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs\" listVersionID=\"2022-09-30\"><code>010020000000</code><name>Kiel</name></xzufi:regionalschluessel><xzufi:staat listURI=\"urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:staat\" listVersionID=\"2022-02-18\"><code>000</code><name>Deutschland</name></xzufi:staat></xzufi:verwaltungspolitischeKodierung><xzufi:geokodierung><gml:Point srsName=\"EPSG:25832\" axisLabels=\"longitude latitude\"><gml:pos>574309.943999998 6019897.539</gml:pos></gml:Point></xzufi:geokodierung></xzufi:anschrift><xzufi:erreichbarkeit><xzufi:kanal listURI=\"urn:de:xoev:codeliste:erreichbarkeit\" listVersionID=\"3\"><code>02</code></xzufi:kanal><xzufi:kennung>+49 431 69677-60</xzufi:kennung></xzufi:erreichbarkeit><xzufi:internetadresse languageCode=\"de\"><xzufi:uri>http://www.denkmal.schleswig-holstein.de</xzufi:uri><xzufi:titel>www.denkmal.schleswig-holstein.de</xzufi:titel></xzufi:internetadresse><xzufi:versionsinformation><xzufi:geaendertDatumZeit>2012-12-10T14:30:48+01:00</xzufi:geaendertDatumZeit></xzufi:versionsinformation><xzufi:sprachversion><xzufi:languageCode>de</xzufi:languageCode><xzufi:sprachbezeichnungDeutsch>Deutsch</xzufi:sprachbezeichnungDeutsch><xzufi:sprachbezeichnungNativ>Deutsch</xzufi:sprachbezeichnungNativ></xzufi:sprachversion></xzufi:organisationseinheit></xzufi:schreibe></xzufi:transfer.operation.040502>" + } \ No newline at end of file diff --git a/alfa-client/apps/alfa-e2e/start-e2e-environment.sh b/alfa-client/apps/alfa-e2e/start-e2e-environment.sh index ec3c0ee9d10fd0f4bd1e8018b1fc77ce35dc9ca3..cf5367b572152286e9a23fd893f336ba3edb8f8b 100755 --- a/alfa-client/apps/alfa-e2e/start-e2e-environment.sh +++ b/alfa-client/apps/alfa-e2e/start-e2e-environment.sh @@ -25,6 +25,7 @@ SCRIPT_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) +DOCKER_COMPOSE_CMD="docker compose -f ${SCRIPT_DIR}/docker-compose.yml" if nc -z localhost 9091 &> /dev/null then @@ -32,7 +33,7 @@ then exit fi -echo "Using docker compose -f ${SCRIPT_DIR}/docker-compose.yml ..." +echo "Using $DOCKER_COMPOSE_CMD ..." echo if [[ "$OSTYPE" == "linux-gnu"* ]] @@ -40,9 +41,9 @@ then export DOCKER_GATEWAY_HOST=172.17.0.1 fi -docker compose -f ${SCRIPT_DIR}/docker-compose.yml pull +$DOCKER_COMPOSE_CMD pull -docker compose -f ${SCRIPT_DIR}/docker-compose.yml up -d mongodb user-manager elastic smocker --wait +$DOCKER_COMPOSE_CMD up -d mongodb user-manager elastic smocker --wait echo echo "Starting VorgangManager to init search index." @@ -51,7 +52,7 @@ SPRING_PROFILE=local,e2e,initSearchIndex docker compose -f ${SCRIPT_DIR}/docker- echo waitForInitSearchIndex() { - (docker compose -f ${SCRIPT_DIR}/docker-compose.yml logs | grep -F -q 'Successful filled up index - exiting') + ($DOCKER_COMPOSE_CMD logs | grep -F -q 'Successful filled up index - exiting') } echo "Waiting for VorgangManager to finish search index initialisation." @@ -63,12 +64,12 @@ done echo echo -echo "Starting VorgangManager and Alfa Server for normal operations." +echo "Starting VorgangManager, Alfa-Server and Zufi Server and Job for normal operations." -docker compose -f ${SCRIPT_DIR}/docker-compose.yml up -d vorgang-manager alfa +$DOCKER_COMPOSE_CMD up -d vorgang-manager alfa zufi-manager-pvog zufi-manager-server waitForServerStarted() { - (docker compose -f ${SCRIPT_DIR}/docker-compose.yml logs | awk 'BEGIN{RS="\0"} /Started AlfaServerApplication/ && /Started VorgangManagerServerApplication/ { exit 1 }') + ($DOCKER_COMPOSE_CMD logs | awk 'BEGIN{RS="\0"} /Started AlfaServerApplication/ && /Started VorgangManagerServerApplication/ { exit 1 }') } echo @@ -80,14 +81,4 @@ do done echo -echo -echo "Init smocker" -while [ $(curl -sw '%{http_code}' "http://localhost:7081/version" -o /dev/null) -ne 200 ]; do - echo -n "." - sleep 1 -done - -curl -X POST http://localhost:7081/mocks -H 'Content-Type: application/x-yaml' --data-binary @src/fixtures/smocker/mocks.yaml - -echo echo "done." \ No newline at end of file diff --git a/alfa-client/libs/admin-settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html b/alfa-client/libs/admin-settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html index dbc6d9eddd9d63fb982da496a7a4636210670ce8..d324f8d83fe91defe9b5066f4f24d230bc33eb4f 100644 --- a/alfa-client/libs/admin-settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html +++ b/alfa-client/libs/admin-settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html @@ -1,4 +1,4 @@ -<h1 class="text-2xl font-bold">Organisationseinheiten</h1> +<h1 class="heading-1 pb-4">Organisationseinheiten</h1> <p id="absender-desc" class="p-1">Hinterlegen Sie Name und ID der Organisationseinheiten.</p> <admin-organisationseinheit-form diff --git a/alfa-client/libs/admin-settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.html b/alfa-client/libs/admin-settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.html index 5ebfbc7da60ca54abbabb4135ce809216b274f88..cf06ca1af3045314ba30e32d03ac45b8aa5c7203 100644 --- a/alfa-client/libs/admin-settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.html +++ b/alfa-client/libs/admin-settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.html @@ -1,5 +1,6 @@ <form class="form flex-col" [formGroup]="formService.form"> - <h1 class="text-2xl font-bold">Absender</h1> + <h1 class="heading-1">Postfach</h1> + <h2 class="heading-2">Absender</h2> <p id="absender-desc" class="p-1">Hinterlegen Sie Absenderinformationen zu Ihrem Postfach.</p> <div [formGroupName]="PostfachFormService.ASBSENDER_GROUP" @@ -33,7 +34,7 @@ ></text-field> </div> <div class="h-20"></div> - <h1 class="text-2xl font-bold">Signatur</h1> + <h2 class="heading-2">Signatur</h2> <p id="signatur-desc">Erstellen oder ändern Sie die Signatur für Nachrichten.</p> <textarea data-test-id="signatur-text" diff --git a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.html b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.html index 9af9814d5c4b8c0e740290016e4e3c8bdaecd4db..3ec530a875705138b08d5e81fc65c2490cb39d1e 100644 --- a/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.html +++ b/alfa-client/libs/collaboration/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.html @@ -1,7 +1,12 @@ <div class="my-32 flex h-screen flex-col gap-2"> <div class="flex gap-48 py-6 lg:gap-96"> <h1 class="text-xl font-bold text-primary">Zuständige Stelle auswählen</h1> - <ods-button variant="icon" size="fit" (clickEmitter)="closeDialog()"> + <ods-button + variant="icon" + size="fit" + (clickEmitter)="closeDialog()" + dataTestId="close-search-dialog" + > <ods-close-icon class="fill-primary" icon /> </ods-button> </div> diff --git a/alfa-client/libs/design-system/.storybook/styles.scss b/alfa-client/libs/design-system/.storybook/styles.scss index 4a89ff65290c2820edbc6553fd53888807a98bd7..070e34c4f9df1c9fd2e82dba14fe52f4133d4290 100644 --- a/alfa-client/libs/design-system/.storybook/styles.scss +++ b/alfa-client/libs/design-system/.storybook/styles.scss @@ -1 +1,2 @@ -@import '../src/lib/tailwind-preset/root.css'; \ No newline at end of file +@import '../src/lib/tailwind-preset/root.css'; +@import '../../../apps/admin/src/styles.scss'; diff --git a/alfa-client/libs/design-system/nginx.conf b/alfa-client/libs/design-system/nginx.conf index add779e6030ab68ebb8f5dde211d26f25e69a2e4..84da5283449a85072c5d235381383eee86a44d49 100644 --- a/alfa-client/libs/design-system/nginx.conf +++ b/alfa-client/libs/design-system/nginx.conf @@ -32,8 +32,11 @@ http { location / { - root /usr/share/nginx/html/design-system; + root /usr/share/nginx/html/design-system/; index index.html index.htm; + + #add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + #add_header Expires "0"; } diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts index 75cf45074d60ef259b865f81f143896ef3c778c1..8adc00f2d8215c5f947d879874ed17e6f190184a 100644 --- a/alfa-client/libs/design-system/src/index.ts +++ b/alfa-client/libs/design-system/src/index.ts @@ -20,7 +20,9 @@ export * from './lib/icons/exclamation-icon/exclamation-icon.component'; export * from './lib/icons/file-icon/file-icon.component'; export * from './lib/icons/iconVariants'; export * from './lib/icons/logout-icon/logout-icon.component'; +export * from './lib/icons/mailbox-icon/mailbox-icon.component'; export * from './lib/icons/office-icon/office-icon.component'; +export * from './lib/icons/orga-unit-icon/orga-unit-icon.component'; export * from './lib/icons/save-icon/save-icon.component'; export * from './lib/icons/search-icon/search-icon.component'; export * from './lib/icons/send-icon/send-icon.component'; @@ -28,6 +30,8 @@ export * from './lib/icons/spinner-icon/spinner-icon.component'; export * from './lib/icons/stamp-icon/stamp-icon.component'; export * from './lib/instant-search/instant-search/instant-search.component'; export * from './lib/instant-search/instant-search/instant-search.model'; +export * from './lib/navbar/nav-item/nav-item.component'; +export * from './lib/navbar/navbar/navbar.component'; export * from './lib/popup/popup-list-item/popup-list-item.component'; export * from './lib/popup/popup/popup.component'; export * from './lib/testbtn/testbtn.component'; diff --git a/alfa-client/libs/design-system/src/lib/heading/heading.stories.ts b/alfa-client/libs/design-system/src/lib/heading/heading.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..6eac165bb7e17ffa37fb79dcf4372a8273af1609 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/heading/heading.stories.ts @@ -0,0 +1,24 @@ +import { type Meta, type StoryObj } from '@storybook/angular'; + +const meta: Meta = { + title: 'Typography/Heading', + excludeStories: /.*Data$/, + tags: ['autodocs'], + parameters: { + docs: { + description: { + component: + 'The headings are native HTML h-elements, styled with additional classes (see code)', + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => ({ + template: '<h1 class="heading-1">Heading 1</h1><h2 class="heading-2">Heading 2</h2>', + }), +}; diff --git a/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..6dea03dfe7129ed04306522d12d29453ed1f94e5 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MailboxIconComponent } from './mailbox-icon.component'; + +describe('MailboxIconComponent', () => { + let component: MailboxIconComponent; + let fixture: ComponentFixture<MailboxIconComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MailboxIconComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(MailboxIconComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..84f8f446e56ed21aa7d1dfd2119a673b850897e9 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.component.ts @@ -0,0 +1,38 @@ +import { NgClass } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { twMerge } from 'tailwind-merge'; +import { IconVariants, iconVariants } from '../iconVariants'; + +@Component({ + selector: 'ods-mailbox-icon', + standalone: true, + imports: [NgClass], + template: `<svg + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + [ngClass]="twMerge(iconVariants({ size }), 'stroke-text', class)" + > + <path + d="M20 4H4C2.89543 4 2 4.89543 2 6V18C2 19.1046 2.89543 20 4 20H20C21.1046 20 22 19.1046 22 18V6C22 4.89543 21.1046 4 20 4Z" + stroke="black" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + /> + <path + d="M22 7L13.03 12.7C12.7213 12.8934 12.3643 12.996 12 12.996C11.6357 12.996 11.2787 12.8934 10.97 12.7L2 7" + stroke="black" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + /> + </svg>`, +}) +export class MailboxIconComponent { + @Input() size: IconVariants['size'] = 'medium'; + @Input() class: string = undefined; + + readonly iconVariants = iconVariants; + readonly twMerge = twMerge; +} diff --git a/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..929efe4f3565fc8df1f71ea6d68f538c68dcbbe6 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/mailbox-icon/mailbox-icon.stories.ts @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/angular'; + +import { MailboxIconComponent } from './mailbox-icon.component'; + +const meta: Meta<MailboxIconComponent> = { + title: 'Icons/Mailbox icon', + component: MailboxIconComponent, + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<MailboxIconComponent>; + +export const Default: Story = { + args: { size: 'medium' }, + argTypes: { + size: { + control: 'select', + options: ['small', 'medium', 'large', 'extra-large', 'full'], + description: 'Size of icon. Property "full" means 100%', + table: { + defaultValue: { summary: 'medium' }, + }, + }, + }, +}; diff --git a/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..81b21beded9266c229a3819c7c731f54bb90a1ac --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { OrgaUnitIconComponent } from './orga-unit-icon.component'; + +describe('OrgaUnitIconComponent', () => { + let component: OrgaUnitIconComponent; + let fixture: ComponentFixture<OrgaUnitIconComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [OrgaUnitIconComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(OrgaUnitIconComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..43885aef2f634a25e2e2eb1cec1d64447d0c0ee0 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.component.ts @@ -0,0 +1,29 @@ +import { NgClass } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { twMerge } from 'tailwind-merge'; +import { IconVariants, iconVariants } from '../iconVariants'; + +@Component({ + selector: 'ods-orga-unit-icon', + standalone: true, + imports: [NgClass], + template: `<svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="currentColor" + [ngClass]="twMerge(iconVariants({ size }), 'fill-text', class)" + > + <path + fill-rule="evenodd" + d="M3 2.25a.75.75 0 0 0 0 1.5v16.5h-.75a.75.75 0 0 0 0 1.5H15v-18a.75.75 0 0 0 0-1.5H3ZM6.75 19.5v-2.25a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75v2.25a.75.75 0 0 1-.75.75h-3a.75.75 0 0 1-.75-.75ZM6 6.75A.75.75 0 0 1 6.75 6h.75a.75.75 0 0 1 0 1.5h-.75A.75.75 0 0 1 6 6.75ZM6.75 9a.75.75 0 0 0 0 1.5h.75a.75.75 0 0 0 0-1.5h-.75ZM6 12.75a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM10.5 6a.75.75 0 0 0 0 1.5h.75a.75.75 0 0 0 0-1.5h-.75Zm-.75 3.75A.75.75 0 0 1 10.5 9h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM10.5 12a.75.75 0 0 0 0 1.5h.75a.75.75 0 0 0 0-1.5h-.75ZM16.5 6.75v15h5.25a.75.75 0 0 0 0-1.5H21v-12a.75.75 0 0 0 0-1.5h-4.5Zm1.5 4.5a.75.75 0 0 1 .75-.75h.008a.75.75 0 0 1 .75.75v.008a.75.75 0 0 1-.75.75h-.008a.75.75 0 0 1-.75-.75v-.008Zm.75 2.25a.75.75 0 0 0-.75.75v.008c0 .414.336.75.75.75h.008a.75.75 0 0 0 .75-.75v-.008a.75.75 0 0 0-.75-.75h-.008ZM18 17.25a.75.75 0 0 1 .75-.75h.008a.75.75 0 0 1 .75.75v.008a.75.75 0 0 1-.75.75h-.008a.75.75 0 0 1-.75-.75v-.008Z" + clip-rule="evenodd" + /> + </svg>`, +}) +export class OrgaUnitIconComponent { + @Input() size: IconVariants['size'] = 'medium'; + @Input() class: string = undefined; + + readonly iconVariants = iconVariants; + readonly twMerge = twMerge; +} diff --git a/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..c1c03bf3a672409dc5b363bd2f2ffdb0787e6daa --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/orga-unit-icon/orga-unit-icon.stories.ts @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/angular'; + +import { OrgaUnitIconComponent } from './orga-unit-icon.component'; + +const meta: Meta<OrgaUnitIconComponent> = { + title: 'Icons/Orgaunit icon', + component: OrgaUnitIconComponent, + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<OrgaUnitIconComponent>; + +export const Default: Story = { + args: { size: 'medium' }, + argTypes: { + size: { + control: 'select', + options: ['small', 'medium', 'large', 'extra-large', 'full'], + description: 'Size of icon. Property "full" means 100%', + table: { + defaultValue: { summary: 'medium' }, + }, + }, + }, +}; diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f33524b795e39fff7585c3829d8094659429afa2 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts @@ -0,0 +1,64 @@ +import { getElementFromFixture, Mock, mock } from '@alfa-client/test-utils'; +import { importProvidersFrom } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Router, RouterModule } from '@angular/router'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { NavItemComponent } from './nav-item.component'; + +describe('NavItemComponent', () => { + let component: NavItemComponent; + let fixture: ComponentFixture<NavItemComponent>; + + const router: Mock<Router> = mock(Router); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [NavItemComponent], + providers: [ + { + provide: Router, + useValue: router, + }, + importProvidersFrom(RouterModule.forRoot([])), + ], + }).compileComponents(); + + fixture = TestBed.createComponent(NavItemComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('input', () => { + describe('caption', () => { + it('should set link text', () => { + component.caption = 'Test caption'; + fixture.detectChanges(); + + const captionElement: HTMLParagraphElement = getElementFromFixture( + fixture, + getDataTestIdOf('link-caption'), + ); + + expect(captionElement.innerHTML).toBe('Test caption'); + }); + }); + + describe('to', () => { + it('should set href', () => { + component.to = '/'; + fixture.detectChanges(); + + const linkElement: HTMLAnchorElement = getElementFromFixture( + fixture, + getDataTestIdOf('link-to-/'), + ); + + expect(linkElement).toHaveProperty('href'); + }); + }); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..d5f54907fe995fa082505d3449a236d89b6f4ecb --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts @@ -0,0 +1,27 @@ +import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { RouterLink, RouterLinkActive } from '@angular/router'; + +@Component({ + selector: 'ods-nav-item', + standalone: true, + imports: [CommonModule, RouterLink, RouterLinkActive], + template: `<a + [routerLink]="to" + routerLinkActive="bg-selected-light border-selected" + [ngClass]="[ + 'flex min-h-8 items-center gap-2 rounded-2xl px-4 py-2', + 'border border-transparent hover:border-primary', + 'outline-2 outline-offset-4 outline-focus focus-visible:border-background-200', + ]" + role="menuitem" + [attr.data-test-id]="'link-to-' + to" + > + <ng-content select="[icon]" /> + <p class="text-left text-sm text-text" data-test-id="link-caption">{{ caption }}</p> + </a>`, +}) +export class NavItemComponent { + @Input({ required: true }) caption!: string; + @Input() to: string; +} diff --git a/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.spec.ts b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b507306575a10ab3c396eb6680e25e9c8565d472 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NavbarComponent } from './navbar.component'; + +describe('NavbarComponent', () => { + let component: NavbarComponent; + let fixture: ComponentFixture<NavbarComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [NavbarComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(NavbarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.ts b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..434dfd07e04e16bcb5c8c36a5b6e975e8fdfe2f9 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.component.ts @@ -0,0 +1,14 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'ods-navbar', + standalone: true, + imports: [CommonModule], + template: `<nav class="h-full w-72 bg-ozggray p-4"> + <div class="flex flex-col gap-2" role="menubar"> + <ng-content /> + </div> + </nav>`, +}) +export class NavbarComponent {} diff --git a/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa5b213b2e0f14fe9de3643ce21e123f042df68c --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts @@ -0,0 +1,43 @@ +import { APP_BASE_HREF } from '@angular/common'; +import { importProvidersFrom } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { applicationConfig, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; +import { OfficeIconComponent } from '../../icons/office-icon/office-icon.component'; +import { NavItemComponent } from '../nav-item/nav-item.component'; +import { NavbarComponent } from './navbar.component'; + +const meta: Meta<NavbarComponent> = { + title: 'Navbar', + component: NavbarComponent, + excludeStories: /.*Data$/, + tags: ['autodocs'], + decorators: [ + applicationConfig({ + providers: [importProvidersFrom(RouterModule.forRoot([]))], + }), + moduleMetadata({ + imports: [NavItemComponent, OfficeIconComponent], + providers: [ + { + provide: APP_BASE_HREF, + useValue: '/', + }, + ], + }), + ], +}; + +export default meta; +type Story = StoryObj<NavbarComponent>; + +export const Default: Story = { + args: {}, + render: () => ({ + template: `<ods-navbar> + <ods-nav-item caption="First link" to="/"><ods-office-icon icon /></ods-nav-item> + <ods-nav-item caption="Second link" to="/second"><ods-office-icon icon /></ods-nav-item> + <hr /> + <ods-nav-item caption="Third link" to="/third"><ods-office-icon icon /></ods-nav-item> + </ods-navbar>`, + }), +}; 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 f998ef819768fb984e0e5c28789c3b93f769497c..cb8ed07e1d8c25e88620f6a60df143c9e7da8dfb 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 @@ -94,6 +94,10 @@ module.exports = { 700: 'hsl(var(--color-abgelehnt-500) / <alpha-value>)', DEFAULT: 'hsl(var(--color-abgelehnt-500) / <alpha-value>)', }, + selected: { + light: 'hsl(212, 58%, 94%)', + DEFAULT: 'hsl(216, 85%, 34%)', + }, pdf: { DEFAULT: 'hsl(var(--color-pdf) / <alpha-value>)', },