diff --git a/alfa-client/apps/admin/src/app/app.routes.ts b/alfa-client/apps/admin/src/app/app.routes.ts index a7ed852a6132c902566603a81021da5d46f2357f..a7325aeea59783051378515f926c8a3bd537a2f7 100644 --- a/alfa-client/apps/admin/src/app/app.routes.ts +++ b/alfa-client/apps/admin/src/app/app.routes.ts @@ -28,6 +28,7 @@ import { Route } from '@angular/router'; import { OrganisationsEinheitFormPageComponent } from '../pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component'; import { OrganisationsEinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component'; import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component'; +import { StatistikFieldsFormPageComponent } from '../pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component'; import { StatistikPageComponent } from '../pages/statistik/statistik-page/statistik-page.component'; import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/unavailable-page.component'; import { UserAddPageComponent } from '../pages/users-roles/user-add-page/user-add-page.component'; @@ -82,4 +83,11 @@ export const appRoutes: Route[] = [ canActivate: [configurationGuard], data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS }, }, + { + path: ROUTES.STATISTIK_NEU, + component: StatistikFieldsFormPageComponent, + title: 'Admin | Statistik weitere Felder auswerten', + canActivate: [configurationGuard], + data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS }, + }, ]; diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.html b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.html new file mode 100644 index 0000000000000000000000000000000000000000..a2e1b29bb93d508d58ca98beaf365e1999e301ab --- /dev/null +++ b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.html @@ -0,0 +1 @@ +<admin-statistik-fields-form data-test-id="evaluate-fields-form"></admin-statistik-fields-form> \ No newline at end of file diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a861afd0728827a45330d8d5d2d78f63e6dfc5d1 --- /dev/null +++ b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts @@ -0,0 +1,37 @@ +import { existsAsHtmlElement } from '@alfa-client/test-utils'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MockComponent } from 'ng-mocks'; +import { AdminStatistikFieldsFormComponent } from '../../../../../../libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component'; +import { getDataTestIdOf } from '../../../../../../libs/tech-shared/test/data-test'; +import { StatistikFieldsFormPageComponent } from './statistik-fields-form-page.component'; + +describe('StatistikFieldsFormPageComponent', () => { + let component: StatistikFieldsFormPageComponent; + let fixture: ComponentFixture<StatistikFieldsFormPageComponent>; + + const evaluateFieldsForm: string = getDataTestIdOf('evaluate-fields-form'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [StatistikFieldsFormPageComponent, MockComponent(AdminStatistikFieldsFormComponent)], + }).compileComponents(); + + fixture = TestBed.createComponent(StatistikFieldsFormPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('template', () => { + describe('weiter felder auswerten form', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, evaluateFieldsForm); + }); + }); + }); +}); diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..e249c034417fc7133d8cc2c5db690ddcb94ea50f --- /dev/null +++ b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { AdminStatistikFieldsFormComponent } from '../../../../../../libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component'; + +@Component({ + selector: 'statistik-fields-form-page', + standalone: true, + imports: [CommonModule, AdminStatistikFieldsFormComponent], + templateUrl: './statistik-fields-form-page.component.html', +}) +export class StatistikFieldsFormPageComponent {} diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-page/statistik-page.component.ts b/alfa-client/apps/admin/src/pages/statistik/statistik-page/statistik-page.component.ts index 1e74b105df36af783a691e857f71f8697c4c95b2..53fd00fc7c8677f8b78216c013f6f191bd24cd76 100644 --- a/alfa-client/apps/admin/src/pages/statistik/statistik-page/statistik-page.component.ts +++ b/alfa-client/apps/admin/src/pages/statistik/statistik-page/statistik-page.component.ts @@ -25,7 +25,7 @@ import { StatistikContainerComponent } from '@admin-client/statistik'; import { Component } from '@angular/core'; @Component({ - selector: 'app-statistik-page', + selector: 'statistik-page', standalone: true, imports: [StatistikContainerComponent], templateUrl: './statistik-page.component.html', diff --git a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts index a8fb7896e27e371c4a968238d92928c70d1370dc..19cf4ef6cf561586b44f3afee70e4c716ec54052 100644 --- a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts +++ b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts @@ -31,8 +31,8 @@ import { Postfach, PostfachResource, PostfachSettingsItem } from './postfach.mod @Injectable() export class PostfachService { - private postfachResourceService = inject(PostfachResourceService) - private snackbarService = inject(SnackBarService) + private postfachResourceService = inject(PostfachResourceService); + private snackbarService = inject(SnackBarService); public get(): Observable<StateResource<PostfachResource>> { return this.postfachResourceService.get(); diff --git a/alfa-client/libs/admin/shared/src/lib/routes.ts b/alfa-client/libs/admin/shared/src/lib/routes.ts index 36d67d9ecc4785084d02668c47a63aa0392cd710..cad5201d211d507ca858dc60dde25a412dfe4ba7 100644 --- a/alfa-client/libs/admin/shared/src/lib/routes.ts +++ b/alfa-client/libs/admin/shared/src/lib/routes.ts @@ -28,4 +28,5 @@ export const ROUTES = { ORGANISATIONSEINHEITEN: 'organisationseinheiten', UNAVAILABLE: 'unavailable', STATISTIK: 'statistik', + STATISTIK_NEU: 'statistik/neu', }; diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html index eb8c0eaa7fd1b08d5028ff9abbd5001ba0f89ea4..77c10ae229f5d8c6430d82349d6f2d213fa72054 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html @@ -24,3 +24,10 @@ --> <h1 class="heading-1" data-test-id="statistik-header-text">Statistik</h1> +<div class="mt-4"> + <ods-button + text="Weitere Felder auswerten" + (clickEmitter)="navigateToStatistikFieldsForm()" + dataTestId="weitere-felder-auswerten-button" + ></ods-button> +</div> diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts index 84b58ee0de584e0b5445a79865b4154cc60bb4c7..b4390c03face2557262e05f6964e02dc40e4cd7a 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts @@ -21,16 +21,34 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { ROUTES } from '@admin-client/shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { existsAsHtmlElement, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { getDataTestIdAttributeOf } from '../../../../../tech-shared/test/data-test'; import { StatistikContainerComponent } from './statistik-container.component'; describe('StatistikContainerComponent', () => { let component: StatistikContainerComponent; let fixture: ComponentFixture<StatistikContainerComponent>; + const evaluateAdditionalFieldsTestId: string = getDataTestIdAttributeOf('weitere-felder-auswerten-button'); + + let navigationService: Mock<NavigationService>; + + beforeEach(() => { + navigationService = mock(NavigationService); + }); + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [StatistikContainerComponent], + providers: [ + { + provide: NavigationService, + useValue: navigationService, + }, + ], }); }); @@ -41,7 +59,44 @@ describe('StatistikContainerComponent', () => { fixture.detectChanges(); }); - it('should create', () => { - expect(component).toBeTruthy(); + describe('component', () => { + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('navigateToStatistikFieldsForm', () => { + it('should call navigation service', () => { + component.navigateToStatistikFieldsForm(); + + expect(navigationService.navigate).toHaveBeenCalledWith(ROUTES.STATISTIK_NEU); + }); + }); + }); + + describe('template', () => { + describe('weiter felder auswerten button', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, evaluateAdditionalFieldsTestId); + }); + + describe('output', () => { + describe('clickEmitter', () => { + it('should call handler', () => { + component.navigateToStatistikFieldsForm = jest.fn(); + fixture.detectChanges(); + + triggerEvent({ + fixture, + elementSelector: evaluateAdditionalFieldsTestId, + name: 'clickEmitter', + }); + + expect(component.navigateToStatistikFieldsForm).toHaveBeenCalled(); + }); + }); + }); + }); }); }); diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts index 05e7e9db912474d8f6991acdf8f20d480b309fe2..a00051de29e86232f267891b6f6c8324a726993a 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts @@ -21,13 +21,22 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { ROUTES } from '@admin-client/shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; +import { ButtonComponent } from '@ods/system'; @Component({ selector: 'admin-statistik-container', templateUrl: './statistik-container.component.html', standalone: true, - imports: [CommonModule], + imports: [CommonModule, ButtonComponent], }) -export class StatistikContainerComponent {} +export class StatistikContainerComponent { + private readonly navigationService = inject(NavigationService); + + public navigateToStatistikFieldsForm(): void { + this.navigationService.navigate(ROUTES.STATISTIK_NEU); + } +} diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d7a8447ea2a8c2078600f1e42e4c3e3346154588 --- /dev/null +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html @@ -0,0 +1,37 @@ +<h2 class="heading-2" data-test-id="statistik-fields-form-header-text">Felder zur Auswertung hinzufügen</h2> + +<div class="flex max-w-4xl flex-col gap-4"> + <ods-text-input + [fieldControl]="formEngineFormControl" + label="Formengine" + placeholder="Tragen Sie hier die Formengine des Formulars ein" + data-test-id="form-engine-input" + ></ods-text-input> + + <ods-text-input + [fieldControl]="formIdFormControl" + label="FormID" + placeholder="Tragen Sie hier die FormID des Formulars ein" + data-test-id="form-id-input" + ></ods-text-input> + + @for (dataFieldControl of dataFieldsFormControls; track $index) { + <ods-text-input + [fieldControl]="dataFieldControl" + label="Pfad des Datenfeldes" + placeholder="Tragen Sie hier den gesamten Pfad des Datenfeldes ein, das Sie auswerten möchten." + [attr.data-test-id]="'data-statistik-field-' + $index" + ></ods-text-input> + } + + <ods-button text="Datenfeld hinzufügen" (clickEmitter)="addDataField()" data-test-id="add-data-field-button"> + <ods-plus-icon icon class="fill-whitetext" /> + </ods-button> + + <div class="mt-4 flex gap-4"> + <ods-button text="Speichern" data-test-id="save-statistik-fields-button"></ods-button> + <ods-button text="Abbrechen" variant="outline" (clickEmitter)="onCancel()" data-test-id="cancel-statistik-fields-button"> + <ods-close-icon icon class="fill-primary" /> + </ods-button> + </div> +</div> diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..457d9c89bea7e5ce5ac254d6bd10040ebcd10de7 --- /dev/null +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts @@ -0,0 +1,202 @@ +import { ROUTES } from '@admin-client/shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormBuilder } from '@angular/forms'; +import { TextInputComponent } from '@ods/system'; +import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; +import { AdminStatistikFieldsFormComponent } from './admin-statistik-fields-form.component'; +import { StatistikFieldsFormService } from './statistik-fields.formservice'; + +describe('AdminStatistikFieldsFormComponent', () => { + let component: AdminStatistikFieldsFormComponent; + let fixture: ComponentFixture<AdminStatistikFieldsFormComponent>; + + const formEngineInputTestId: string = getDataTestIdOf('form-engine-input'); + const formIdInputTestId: string = getDataTestIdOf('form-id-input'); + const addDataFieldButtonTestId: string = getDataTestIdOf('add-data-field-button'); + const saveButtonTestId: string = getDataTestIdOf('save-statistik-fields-button'); + const cancelButtonTestId: string = getDataTestIdOf('cancel-statistik-fields-button'); + const dataField1TestId: string = getDataTestIdOf('data-statistik-field-0'); + + let formService: StatistikFieldsFormService; + let navigationService: Mock<NavigationService>; + + beforeEach(() => { + formService = new StatistikFieldsFormService(new FormBuilder()); + navigationService = mock(NavigationService); + }); + + beforeEach(async () => { + TestBed.overrideComponent(AdminStatistikFieldsFormComponent, { + set: { + providers: [ + { + provide: StatistikFieldsFormService, + useValue: formService, + }, + { + provide: NavigationService, + useValue: navigationService, + }, + ], + }, + }); + + await TestBed.configureTestingModule({ + imports: [AdminStatistikFieldsFormComponent], + providers: [{ provide: StatistikFieldsFormService, useValue: formService }], + }).compileComponents(); + + fixture = TestBed.createComponent(AdminStatistikFieldsFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + describe('component', () => { + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set form controls', () => { + expect(component.formEngineFormControl).toBeDefined(); + expect(component.formIdFormControl).toBeDefined(); + expect(component.dataFieldsFormControls).toBeDefined(); + }); + + describe('addDataField', () => { + it('should call form service', () => { + formService.addDataField = jest.fn(); + + component.addDataField(); + + expect(formService.addDataField).toHaveBeenCalled(); + }); + }); + + describe('onCancel', () => { + it('should call navigation service', () => { + component.onCancel(); + + expect(navigationService.navigate).toHaveBeenCalledWith(ROUTES.STATISTIK); + }); + }); + }); + + describe('template', () => { + describe('form engine input', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, formEngineInputTestId); + }); + + it('should have been called with inputs', () => { + fixture.detectChanges(); + + const formEngineInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>( + fixture, + formEngineInputTestId, + ); + + expect(formEngineInput.fieldControl).toEqual(component.formEngineFormControl); + }); + }); + + describe('form id input', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, formIdInputTestId); + }); + + it('should have been called with inputs', () => { + fixture.detectChanges(); + + const formIdInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>( + fixture, + formIdInputTestId, + ); + + expect(formIdInput.fieldControl).toEqual(component.formIdFormControl); + }); + }); + + describe('data field input', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, dataField1TestId); + }); + + it('should have been called with inputs', () => { + fixture.detectChanges(); + + const dataFieldInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>( + fixture, + dataField1TestId, + ); + + expect(dataFieldInput.fieldControl).toEqual(component.dataFieldsFormControls[0]); + }); + }); + + describe('add data field button', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, addDataFieldButtonTestId); + }); + + describe('output', () => { + describe('clickEmitter', () => { + it('should call handler', () => { + fixture.detectChanges(); + component.addDataField = jest.fn(); + + triggerEvent({ + fixture, + elementSelector: addDataFieldButtonTestId, + name: 'clickEmitter', + }); + + expect(component.addDataField).toHaveBeenCalled(); + }); + }); + }); + }); + + describe('save button', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, saveButtonTestId); + }); + }); + + describe('cancel button', () => { + it('should exists', () => { + fixture.detectChanges(); + + existsAsHtmlElement(fixture, cancelButtonTestId); + }); + + describe('output', () => { + describe('clickEmitter', () => { + it('should call handler', () => { + component.onCancel = jest.fn(); + fixture.detectChanges(); + + triggerEvent({ + fixture, + elementSelector: cancelButtonTestId, + name: 'clickEmitter', + }); + + expect(component.onCancel).toHaveBeenCalled(); + }); + }); + }); + }); + }); +}); diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..59d083f34a2f5f727734c29c02f6b8de13c7d2d6 --- /dev/null +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts @@ -0,0 +1,37 @@ +import { ROUTES } from '@admin-client/shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { CommonModule } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { FormArray, FormControl, ReactiveFormsModule } from '@angular/forms'; +import { ButtonComponent, CloseIconComponent, PlusIconComponent, TextInputComponent } from '@ods/system'; +import { StatistikFieldsFormService } from './statistik-fields.formservice'; + +@Component({ + selector: 'admin-statistik-fields-form', + standalone: true, + imports: [CommonModule, TextInputComponent, ButtonComponent, CloseIconComponent, ReactiveFormsModule, PlusIconComponent], + providers: [StatistikFieldsFormService], + templateUrl: './admin-statistik-fields-form.component.html', +}) +export class AdminStatistikFieldsFormComponent { + private readonly formService = inject(StatistikFieldsFormService); + private readonly navigationService = inject(NavigationService); + + public readonly formEngineFormControl: FormControl = this.formService.form.controls[ + StatistikFieldsFormService.FIELD_FORM_ENGINE + ] as FormControl; + public readonly formIdFormControl: FormControl = this.formService.form.controls[ + StatistikFieldsFormService.FIELD_FORM_ID + ] as FormControl; + public readonly dataFieldsFormControls: FormControl[] = ( + this.formService.form.controls[StatistikFieldsFormService.FIELD_DATA_FIELDS] as FormArray + ).controls as FormControl[]; + + public addDataField(): void { + this.formService.addDataField(); + } + + public onCancel(): void { + this.navigationService.navigate(ROUTES.STATISTIK); + } +} diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts new file mode 100644 index 0000000000000000000000000000000000000000..2f6610d53b9da6db523e167b77d8c5396be6d99d --- /dev/null +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts @@ -0,0 +1,32 @@ +import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared'; +import { Injectable } from '@angular/core'; +import { FormArray, FormControl, UntypedFormGroup } from '@angular/forms'; +import { Resource } from '@ngxp/rest'; +import { EMPTY, Observable } from 'rxjs'; + +@Injectable() +export class StatistikFieldsFormService extends AbstractFormService { + public static readonly FIELD_FORM_ENGINE: string = 'formEngine'; + public static readonly FIELD_FORM_ID: string = 'formId'; + public static readonly FIELD_DATA_FIELDS: string = 'dataFields'; + + protected initForm(): UntypedFormGroup { + return this.formBuilder.group({ + [StatistikFieldsFormService.FIELD_FORM_ENGINE]: new FormControl(EMPTY_STRING), + [StatistikFieldsFormService.FIELD_FORM_ID]: new FormControl(EMPTY_STRING), + [StatistikFieldsFormService.FIELD_DATA_FIELDS]: new FormArray([new FormControl(EMPTY_STRING)]), + }); + } + + protected doSubmit(): Observable<StateResource<Resource>> { + return EMPTY; + } + + protected getPathPrefix(): string { + return 'settingBody'; + } + + public addDataField(): void { + (this.form.controls[StatistikFieldsFormService.FIELD_DATA_FIELDS] as FormArray).push(new FormControl(EMPTY_STRING)); + } +} diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts index 4c577c9087024d16b200f280a1ab6b90d3a8a32d..1f46fdee2bf9ba94f5af17a5ee742be0afe2aa85 100644 --- a/alfa-client/libs/design-system/src/index.ts +++ b/alfa-client/libs/design-system/src/index.ts @@ -62,6 +62,7 @@ export * from './lib/icons/office-icon/office-icon.component'; export * from './lib/icons/orga-unit-icon/orga-unit-icon.component'; export * from './lib/icons/ozg-logo-icon/ozg-logo-icon.component'; export * from './lib/icons/person-icon/person-icon.component'; +export * from './lib/icons/plus-icon/plus-icon.component'; export * from './lib/icons/public-administration-icon/public-administration-icon.component'; export * from './lib/icons/save-icon/save-icon.component'; export * from './lib/icons/search-icon/search-icon.component'; diff --git a/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..1f91573b1d3ec90ca862afc9c4d6f502dab9b6f5 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { PlusIconComponent } from './plus-icon.component'; + +describe('PlusIconComponent', () => { + let component: PlusIconComponent; + let fixture: ComponentFixture<PlusIconComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PlusIconComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(PlusIconComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f5816ec7f3952297c69bf3905b67d9a1cb557748 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.component.ts @@ -0,0 +1,26 @@ +import { NgClass } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { twMerge } from 'tailwind-merge'; +import { iconVariants, IconVariants } from '../iconVariants'; + +@Component({ + selector: 'ods-plus-icon', + standalone: true, + imports: [NgClass], + template: `<svg + [ngClass]="[twMerge(iconVariants({ size }), 'fill-primary', class)]" + aria-hidden="true" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path d="M11 13H5V11H11V5H13V11H19V13H13V19H11V13Z" /> + </svg>`, +}) +export class PlusIconComponent { + @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/plus-icon/plus-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..dbf9d8acaa8669520c43d5541d7d2a9f21b44f97 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icons/plus-icon/plus-icon.stories.ts @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +import type { Meta, StoryObj } from '@storybook/angular'; + +import { PlusIconComponent } from './plus-icon.component'; + +const meta: Meta<PlusIconComponent> = { + title: 'Icons/Plus icon', + component: PlusIconComponent, + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<PlusIconComponent>; + +export const Default: Story = { + args: { size: 'large' }, + 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/tsconfig.base.json b/alfa-client/tsconfig.base.json index deeabaafe3641c159f6a14ebdf3db81c51e267a0..2014ad63b1ebdbf8c2b31b7259bcc0d77011dd4b 100644 --- a/alfa-client/tsconfig.base.json +++ b/alfa-client/tsconfig.base.json @@ -16,8 +16,8 @@ "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { - "@admin-client/configuration-shared": ["libs/admin/configuration-shared/src/index.ts"], "@admin-client/configuration": ["libs/admin/configuration/src/index.ts"], + "@admin-client/configuration-shared": ["libs/admin/configuration-shared/src/index.ts"], "@admin-client/organisations-einheit": ["libs/admin/organisations-einheit/src/index.ts"], "@admin-client/organisations-einheit-shared": ["libs/admin/organisations-einheit-shared/src/index.ts"], "@admin-client/postfach": ["libs/admin/postfach/src/index.ts"],