Skip to content
Snippets Groups Projects
Commit c9e24629 authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-5008-Bescheid_bewilligen_ablehnen' (#462) from...

Merge pull request 'OZG-5008-Bescheid_bewilligen_ablehnen' (#462) from OZG-5008-Bescheid_bewilligen_ablehnen into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/alfa/pulls/462


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents c0af44f7 2c89362f
Branches
Tags
No related merge requests found
Showing
with 443 additions and 147 deletions
...@@ -14,6 +14,30 @@ ...@@ -14,6 +14,30 @@
<nav>NAV</nav> <nav>NAV</nav>
</div> </div>
<main class="flex-auto bg-background-50 p-6"> <main class="flex-auto bg-background-50 p-6">
<form id="antrag_bescheiden_form" [formGroup]="exampleForm">
<div class="my-10 flex gap-8">
<ozgdesign-radio-button-card
label="bewilligt"
name="exampleName"
value="bewilligt"
backgroudColorChecked="bg-bewilligt-100"
borderColorChecked="border-bewilligt"
><div>
<!--<mat-icon svgIcon="stamp" class="text-bewilligt"></mat-icon>-->ICON
</div></ozgdesign-radio-button-card
>
<ozgdesign-radio-button-card
label="abgelehnt"
name="exampleName"
value="abgelehnt"
backgroudColorChecked="bg-abgelehnt-100"
borderColorChecked="border-abgelehnt"
><div>
<!--<mat-icon class="text-abgelehnt">close</mat-icon>-->ICON
</div></ozgdesign-radio-button-card
>
</div>
</form>
<app-bescheid-dialog-button></app-bescheid-dialog-button> <app-bescheid-dialog-button></app-bescheid-dialog-button>
<ozg-testbtn /> <ozg-testbtn />
<div class="text-warning">Achtung</div> <div class="text-warning">Achtung</div>
...@@ -33,6 +57,7 @@ ...@@ -33,6 +57,7 @@
<p>sjdkflsd sdjsdsjdlfj</p> <p>sjdkflsd sdjsdsjdlfj</p>
</cdk-step> </cdk-step>
</app-custom-stepper> </app-custom-stepper>
<router-outlet></router-outlet> <router-outlet></router-outlet>
</main> </main>
</div> </div>
......
...@@ -2,11 +2,13 @@ import { Component, HostBinding, effect, signal } from '@angular/core'; ...@@ -2,11 +2,13 @@ import { Component, HostBinding, effect, signal } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { CdkStepperModule } from '@angular/cdk/stepper'; import { CdkStepperModule } from '@angular/cdk/stepper';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { TestbtnComponent } from 'design-system'; import { TestbtnComponent } from 'design-system';
import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.component'; import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.component';
import { BescheidStepperComponent } from './components/bescheid-stepper/bescheid-stepper.component'; import { BescheidStepperComponent } from './components/bescheid-stepper/bescheid-stepper.component';
import { BescheidDialogExampleComponent } from './components/bescheid-dialog/bescheid-dialog.component'; import { BescheidDialogExampleComponent } from './components/bescheid-dialog/bescheid-dialog.component';
import { BescheidPaperComponent } from './components/bescheid-paper/bescheid-paper.component'; import { BescheidPaperComponent } from './components/bescheid-paper/bescheid-paper.component';
import { RadioButtonCardComponent } from 'design-system';
@Component({ @Component({
standalone: true, standalone: true,
...@@ -19,6 +21,8 @@ import { BescheidPaperComponent } from './components/bescheid-paper/bescheid-pap ...@@ -19,6 +21,8 @@ import { BescheidPaperComponent } from './components/bescheid-paper/bescheid-pap
BescheidDialogExampleComponent, BescheidDialogExampleComponent,
BescheidStepperComponent, BescheidStepperComponent,
BescheidPaperComponent, BescheidPaperComponent,
RadioButtonCardComponent,
ReactiveFormsModule,
], ],
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
...@@ -32,6 +36,10 @@ export class AppComponent { ...@@ -32,6 +36,10 @@ export class AppComponent {
return this.darkMode(); return this.darkMode();
} }
exampleForm = new FormGroup({
exampleName: new FormControl('bewilligt'),
});
constructor() { constructor() {
effect(() => { effect(() => {
window.localStorage.setItem('darkMode', JSON.stringify(this.darkMode())); window.localStorage.setItem('darkMode', JSON.stringify(this.darkMode()));
......
export * from './lib/bescheid-shared.module'; export * from './lib/bescheid-shared.module';
export * from './lib/bescheid.model';
import { Resource } from '@ngxp/rest';
export interface Bescheid {
beschiedenAm: Date;
bewilligt: boolean;
bescheidDocument?: string;
attachments?: string[];
nachrichtText?: string;
nachrichtSubject?: string;
}
export interface BescheidResource extends Bescheid, Resource {}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
"error", "error",
{ {
"type": "attribute", "type": "attribute",
"prefix": "lib", "prefix": "ozgdesign",
"style": "camelCase" "style": "camelCase"
} }
], ],
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"error", "error",
{ {
"type": "element", "type": "element",
"prefix": "lib", "prefix": "ozgdesign",
"style": "kebab-case" "style": "kebab-case"
} }
] ]
......
...@@ -6,23 +6,6 @@ ...@@ -6,23 +6,6 @@
"tags": [], "tags": [],
"projectType": "library", "projectType": "library",
"targets": { "targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
"options": {
"project": "libs/design-system/ng-package.json",
"tailwindConfig": "libs/design-system/tailwind.config.js"
},
"configurations": {
"production": {
"tsConfig": "libs/design-system/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "libs/design-system/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
......
export * from './lib/testbtn/testbtn.component'; export * from './lib/testbtn/testbtn.component';
export * from './lib/form/radio-button-card/radio-button-card.component';
<input
type="radio"
class="peer hidden"
id="{{ name }}_{{ value }}"
name="{{ name }}"
formControlName="{{ name }}"
value="{{ value }}"
/>
<label
for="{{ name }}_{{ value }}"
class="flex flex-1 cursor-pointer select-none justify-center gap-2 rounded-lg border border-background bg-mainbg px-12 py-5 text-center align-middle text-base peer-checked:font-semibold"
[ngClass]="
label === 'bewilligt' ? 'peer-checked:border-bewilligt peer-checked:bg-bewilligt-100'
: label === 'abgelehnt' ? 'peer-checked:border-abgelehnt peer-checked:bg-abgelehnt-100'
: 'peer-checked:border-primary peer-checked:bg-background-100'
"
>
<ng-content />
<span>{{ label }}</span>
</label>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RadioButtonCardComponent } from './radio-button-card.component';
import { ReactiveFormsModule } from '@angular/forms';
xdescribe('RadioButtonCardComponent', () => {
let component: RadioButtonCardComponent;
let fixture: ComponentFixture<RadioButtonCardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
}).compileComponents();
fixture = TestBed.createComponent(RadioButtonCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormGroupDirective, ControlContainer, ReactiveFormsModule } from '@angular/forms';
@Component({
selector: 'ozgdesign-radio-button-card',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
templateUrl: './radio-button-card.component.html',
styles: [':host {@apply flex flex-1}'],
viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
})
export class RadioButtonCardComponent {
@Input() label!: string;
@Input() name!: string;
@Input() value!: string;
@Input() btnType: string = 'default';
}
...@@ -10,22 +10,36 @@ ...@@ -10,22 +10,36 @@
--color-background-secondary: 0 0% 98%; --color-background-secondary: 0 0% 98%;
--color-mainbg: 0 0% 100%; --color-mainbg: 0 0% 100%;
--text: 0 0% 0%; --text: 0 0% 0%;
--color-text-white: 0 0% 100%;
--color-primary-600: 212 80% 42%; --color-primary-600: 212 80% 42%;
--color-background-50: 0 0% 100%; --color-background-50: 0 0% 100%;
--color-background-100: 0 0% 98%; --color-background-100: 0 0% 98%;
--color-background-200: 0 0% 90%; --color-background-200: 0 0% 90%;
--color-bewilligt-100: 122 100% 92%;
--color-bewilligt-700: 122 100% 29%;
--color-abgelehnt-100: 0 100% 92%;
--color-abgelehnt-500: 0 100% 60%;
} }
.dark { .dark {
--color-background-secondary: 0 0% 16%; --color-background-secondary: 0 0% 16%;
--color-mainbg: 0 0% 14%; --color-mainbg: 0 0% 14%;
--text: 0 0% 100%; --text: 0 0% 100%;
--color-text-white: 0 0% 0%;
--color-primary-600: 43 96% 58%; --color-primary-600: 43 96% 58%;
--color-background-50: 0 0% 0%; --color-background-50: 0 0% 0%;
--color-background-100: 0 0% 8%; --color-background-100: 0 0% 8%;
--color-background-200: 0 0% 16%; --color-background-200: 0 0% 16%;
--color-bewilligt-100: 122 100% 22%;
--color-bewilligt-700: 122 100% 29%;
--color-abgelehnt-100: 0 100% 22%;
--color-abgelehnt-500: 0 100% 60%;
} }
.bescheid-dialog-backdrop { .bescheid-dialog-backdrop {
......
...@@ -33,12 +33,23 @@ module.exports = { ...@@ -33,12 +33,23 @@ module.exports = {
200: 'hsl(var(--color-background-200) / <alpha-value>)', 200: 'hsl(var(--color-background-200) / <alpha-value>)',
DEFAULT: 'hsl(var(--color-background-100) / <alpha-value>)', DEFAULT: 'hsl(var(--color-background-100) / <alpha-value>)',
}, },
bewilligt: {
100: 'hsl(var(--color-bewilligt-100) / <alpha-value>)',
700: 'hsl(var(--color-bewilligt-700) / <alpha-value>)',
DEFAULT: 'hsl(var(--color-bewilligt-700) / <alpha-value>)',
},
abgelehnt: {
100: 'hsl(var(--color-abgelehnt-100) / <alpha-value>)',
700: 'hsl(var(--color-abgelehnt-500) / <alpha-value>)',
DEFAULT: 'hsl(var(--color-abgelehnt-500) / <alpha-value>)',
},
mainbg: 'hsl(var(--color-mainbg) / <alpha-value>)', mainbg: 'hsl(var(--color-mainbg) / <alpha-value>)',
primary: { primary: {
600: 'hsl(var(--color-primary-600) / <alpha-value>)', 600: 'hsl(var(--color-primary-600) / <alpha-value>)',
DEFAULT: 'hsl(var(--color-primary-600) / <alpha-value>)', DEFAULT: 'hsl(var(--color-primary-600) / <alpha-value>)',
}, },
text: 'hsl(var(--text) / <alpha-value>)', text: 'hsl(var(--text) / <alpha-value>)',
whitetext: 'hsl(var(--color-text-white) / <alpha-value>)',
warning: 'hsl(var(--warning))', warning: 'hsl(var(--warning))',
}, },
}, },
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
import { faker } from '@faker-js/faker'; import { faker } from '@faker-js/faker';
import { import {
allEmpty, allEmpty,
asBoolean,
convertForDataTest, convertForDataTest,
decodeUrlFromEmbedding, decodeUrlFromEmbedding,
EMPTY_STRING, EMPTY_STRING,
...@@ -342,4 +343,18 @@ describe('TechUtil', () => { ...@@ -342,4 +343,18 @@ describe('TechUtil', () => {
expect(hasContent(content)).toBeFalsy(); expect(hasContent(content)).toBeFalsy();
}); });
}); });
describe('asBoolean', () => {
it('should return true', () => {
const value = asBoolean('true');
expect(value).toBeTruthy();
});
it('should return false', () => {
const value = asBoolean('false');
expect(value).toBeFalsy();
});
});
}); });
...@@ -130,3 +130,7 @@ export function allEmpty(value: string, ...values: string[]): boolean { ...@@ -130,3 +130,7 @@ export function allEmpty(value: string, ...values: string[]): boolean {
export function isClipboardReadSupported(): boolean { export function isClipboardReadSupported(): boolean {
return isNotNil(navigator.clipboard.readText); return isNotNil(navigator.clipboard.readText);
} }
export function asBoolean(booleanValue: string): boolean {
return booleanValue === 'true';
}
import { BescheidenFormService } from './bescheiden.formservice';
import { Bescheid } from '@alfa-client/bescheid-shared';
import { UntypedFormBuilder } from '@angular/forms';
import { cold } from 'jest-marbles';
describe('BescheidenFormServiceService', () => {
let service: BescheidenFormService;
const now = new Date();
Date.now = jest.fn().mockReturnValue(now);
beforeEach(() => {
service = new BescheidenFormService(new UntypedFormBuilder());
});
describe('getValue', () => {
it('should have called getFormValue', () => {
const getFormValue = jest.spyOn(service, 'getFormValue');
service.getValue();
expect(getFormValue).toHaveBeenCalled();
});
it('should return bescheid', () => {
const value = service.getValue();
expect(value).toEqual({ bewilligt: true, beschiedenAm: now } as Bescheid);
});
});
describe('getBescheidChanges', () => {
it('should emit initial form value', () => {
expect(service.getBescheidChanges()).toBeObservable(
cold('a', { a: { beschiedenAm: now, bewilligt: true } }),
);
});
});
});
import { Bescheid } from '@alfa-client/bescheid-shared';
import { AbstractFormService, asBoolean, StateResource } from '@alfa-client/tech-shared';
import { Injectable } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { map, Observable, startWith } from 'rxjs';
@Injectable({ providedIn: null })
export class BescheidenFormService extends AbstractFormService {
static readonly FIELD_BESCHIEDEN_AM = 'beschiedenAm';
static readonly FIELD_BEWILLIGT = 'bewilligt';
static readonly FIELD_PATH_PREFIX = 'bescheid';
private readonly bescheid$: Observable<Bescheid>;
constructor(formBuilder: UntypedFormBuilder) {
super(formBuilder);
this.bescheid$ = this.form.valueChanges.pipe(
startWith(this.getFormValue()),
map((value) => ({ ...value, bewilligt: asBoolean(value.bewilligt) })),
);
}
protected initForm(): UntypedFormGroup {
return this.formBuilder.group({
[BescheidenFormService.FIELD_BESCHIEDEN_AM]: new UntypedFormControl(new Date(Date.now())),
[BescheidenFormService.FIELD_BEWILLIGT]: new UntypedFormControl('true'),
});
}
protected getPathPrefix(): string {
return BescheidenFormService.FIELD_PATH_PREFIX;
}
protected doSubmit(): Observable<StateResource<any>> {
return null;
}
public getValue(): Bescheid {
const value = this.getFormValue();
return {
beschiedenAm: value.beschiedenAm,
bewilligt: asBoolean(value.bewilligt),
};
}
public getBescheidChanges(): Observable<Bescheid> {
return this.bescheid$;
}
}
<div class="my-2 text-base font-bold text-primary-600">Bescheid</div>
<p *ngIf="this.formService.getBescheidChanges() | async as bescheid" class="flex text-text">
<span class="flex items-center gap-2" *ngIf="bescheid.bewilligt"
><mat-icon svgIcon="stamp" class="text-bewilligt"></mat-icon>Bewilligt am
{{ bescheid.beschiedenAm | date: 'dd.MM.yyyy' }}
</span>
<span class="flex items-center gap-2" *ngIf="!bescheid.bewilligt"
><mat-icon class="text-abgelehnt">close</mat-icon>Abgelehnt am
{{ bescheid.beschiedenAm | date: 'dd.MM.yyyy' }}
</span>
</p>
import { OzgcloudSvgIconComponent } from '@alfa-client/ui';
import { registerLocaleData } from '@angular/common';
import localeDe from '@angular/common/locales/de';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UntypedFormBuilder } from '@angular/forms';
import { MatIcon } from '@angular/material/icon';
import { MockComponent } from 'ng-mocks';
import { BehaviorSubject } from 'rxjs';
import { BescheidenFormService } from '../../bescheiden.formservice';
import { VorgangDetailBescheidenResultStatusComponent } from './vorgang-detail-bescheiden-result-status.component';
registerLocaleData(localeDe);
describe('VorgangDetailBescheidenResultStatusComponent', () => {
let component: VorgangDetailBescheidenResultStatusComponent;
let fixture: ComponentFixture<VorgangDetailBescheidenResultStatusComponent>;
const formService = new BescheidenFormService(new UntypedFormBuilder());
const bescheidChangesMock = jest.fn();
bescheidChangesMock.mockReturnValue(
new BehaviorSubject({ beschiedenAm: new Date(), bewilligt: false }),
);
formService.getBescheidChanges = bescheidChangesMock;
beforeEach(async () => {
TestBed.overrideComponent(VorgangDetailBescheidenResultStatusComponent, {
set: {
providers: [
{
provide: BescheidenFormService,
useValue: formService,
},
],
},
});
await TestBed.configureTestingModule({
declarations: [
VorgangDetailBescheidenResultStatusComponent,
MatIcon,
MockComponent(OzgcloudSvgIconComponent),
],
}).compileComponents();
fixture = TestBed.createComponent(VorgangDetailBescheidenResultStatusComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component } from '@angular/core';
import { BescheidenFormService } from '../../bescheiden.formservice';
@Component({
selector: 'alfa-vorgang-detail-bescheiden-result-status',
templateUrl: './vorgang-detail-bescheiden-result-status.component.html',
styles: [],
})
export class VorgangDetailBescheidenResultStatusComponent {
constructor(public formService: BescheidenFormService) {}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment