src/app/shared/components/forms/audit-form/audit-form.component.ts
selector | app-audit-form |
styleUrls | ./audit-form.component.scss |
templateUrl | ./audit-form.component.html |
Properties |
Methods |
Inputs |
Outputs |
Accessors |
constructor(formBuilder: FormBuilder, dialogService: NbDialogService, store: Store)
|
||||||||||||
Parameters :
|
audit | |
Type : Audit
|
|
cancelButtonName | |
Type : string
|
|
Inherited from
AbstractFormComponent
|
|
Defined in
AbstractFormComponent:8
|
submitButtonName | |
Type : string
|
|
Inherited from
AbstractFormComponent
|
|
Defined in
AbstractFormComponent:7
|
formSubmitted | |
Type : EventEmitter
|
|
cancelled | |
Type : EventEmitter
|
|
Inherited from
AbstractFormComponent
|
|
Defined in
AbstractFormComponent:9
|
checkedFacCrits |
checkedFacCrits()
|
Returns :
{}
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onSubmit |
onSubmit()
|
Returns :
void
|
toggleCriteriaChecked | |||||||||
toggleCriteriaChecked(factorId: string, checked)
|
|||||||||
Parameters :
Returns :
void
|
onCancel |
onCancel()
|
Inherited from
AbstractFormComponent
|
Defined in
AbstractFormComponent:15
|
Returns :
void
|
contactPersons$ |
Type : Observable<ContactPerson[]>
|
Decorators :
@Select(ContactPersonState.contactPersons)
|
facCrits$ |
Type : Observable<FacCrit[]>
|
Decorators :
@Select(AuditState.facCrits)
|
formGroup |
Type : FormGroup
|
Inherited from
AbstractFormComponent
|
Defined in
AbstractFormComponent:11
|
name |
getname()
|
startDate |
getstartDate()
|
endDate |
getendDate()
|
contactPersonsControl |
getcontactPersonsControl()
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Validators, FormBuilder, FormControl } from '@angular/forms';
import { Audit, AuditStatus } from 'src/app/core/data/models/audit.model';
import { NbDialogService } from '@nebular/theme';
import { dateRangeValidator } from 'src/app/shared/helpers/form-helpers';
import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
import { FacCrit } from 'src/app/core/data/models/faccrit.model';
import { Select, Store } from '@ngxs/store';
import { AuditState } from 'src/app/core/ngxs/audit.state';
import { Observable } from 'rxjs';
import { AbstractFormComponent } from '../abstract-form-component';
import { ContactPersonState } from 'src/app/core/ngxs/contact-person.state';
const defaultScopeComplement = [8, 14];
@Component({
selector: 'app-audit-form',
templateUrl: './audit-form.component.html',
styleUrls: ['./audit-form.component.scss'],
})
export class AuditFormComponent extends AbstractFormComponent implements OnInit {
@Input() audit: Audit;
@Output() formSubmitted = new EventEmitter<Partial<Audit>>();
@Select(ContactPersonState.contactPersons) contactPersons$: Observable<ContactPerson[]>;
@Select(AuditState.facCrits) facCrits$: Observable<FacCrit[]>;
constructor(
private formBuilder: FormBuilder,
protected dialogService: NbDialogService,
private store: Store,
) {
super(dialogService);
}
get name() {
return this.formGroup.get('name');
}
get startDate() {
return this.formGroup.get('startDate');
}
get endDate() {
return this.formGroup.get('endDate');
}
get contactPersonsControl() {
return this.formGroup.get('contactPersons');
}
ngOnInit() {
const contactPersonsSnapshot = this.store.selectSnapshot(ContactPersonState.contactPersons);
const defaultStartDate = new Date();
defaultStartDate.setHours(0, 0, 0, 0);
this.formGroup = this.formBuilder.group(
{
name: [this.audit?.name, Validators.required],
startDate: [this.audit?.startDate ?? defaultStartDate, Validators.required],
endDate: [this.audit?.endDate],
contactPersons: [
contactPersonsSnapshot?.filter(x => this.audit?.contactPersons.find(f => f.id === x.id)),
],
},
{ validator: dateRangeValidator('startDate', 'endDate') },
);
this.facCrits$.subscribe(facCrits => {
for (const facCrit of facCrits) {
const inAudit = this.audit
? this.audit.scope.findIndex(x => x.id === facCrit.id) != -1
: defaultScopeComplement.includes(facCrit.id) ||
defaultScopeComplement.includes(facCrit.referenceId)
? false
: true;
this.formGroup.addControl(String(facCrit.id), new FormControl(inAudit));
}
});
}
onSubmit() {
const audit: Partial<Audit> = {
name: this.name.value,
endDate: this.endDate.value,
startDate: this.startDate.value,
status: this.audit?.status ?? AuditStatus.Planned,
contactPersons: this.contactPersonsControl.value,
scope: this.checkedFacCrits(),
};
this.formSubmitted.emit(audit);
}
checkedFacCrits() {
const result: FacCrit[] = [];
this.facCrits$.subscribe(facCrits => {
for (const crit of facCrits) {
const checked = this.formGroup.get(String(crit.id)).value;
if (checked) {
result.push(crit);
}
}
});
return result;
}
toggleCriteriaChecked(factorId: string, checked: true) {
this.store.select(AuditState.criteriaByFactorId(+factorId)).subscribe(x => {
for (const crit of x) {
this.formGroup.get(String(crit.id)).setValue(checked);
}
});
}
}
<form [formGroup]="formGroup" data-cy="audit-data-form">
<nb-card>
<nb-card-header>Audit Daten</nb-card-header>
<nb-card-body>
<div class="mb-2">
<label class="label">Auditname</label>
<input [status]="name.invalid && name.touched ? 'danger' : 'basic'" formControlName="name" nbInput fullWidth data-cy="audit-name-input" />
<div *ngIf="name.invalid && name.touched">
<label class="label text-danger" data-cy="auditname-missing-label">Auditnamen eintragen</label>
</div>
</div>
<div class="grid-1-1 mb-2">
<div class="form-item">
<label class="label">Startdatum</label>
<input formControlName="startDate" readonly nbInput fullWidth [nbDatepicker]="datePickerStart" data-cy="audit-start-input" />
<nb-datepicker #datePickerStart></nb-datepicker>
</div>
<div class="form-item">
<label class="label">Enddatum</label>
<input [status]="formGroup.errors?.dateRangeValidator ? 'danger' : 'basic'" formControlName="endDate" readonly nbInput fullWidth [nbDatepicker]="datePickerEnd" data-cy="audit-end-input" />
<nb-datepicker #datePickerEnd></nb-datepicker>
<div *ngIf="formGroup.errors?.dateRangeValidator">
<label class="label text-danger">Startdatum muss vor Enddatum liegen</label>
</div>
</div>
</div>
<div class="mb-2">
<label class="label">Kontaktpersonen</label>
<nb-select formControlName="contactPersons" multiple fullWidth data-cy="audit-contacts">
<nb-option *ngFor="let contactPerson of contactPersons$ | async" [value]="contactPerson" data-cy="audit-contact">{{ contactPerson.forename + ' ' + contactPerson.surname }}</nb-option>
</nb-select>
</div>
<hr style="border-bottom: 3px dotted rgb(228, 233, 242);" />
<nb-accordion>
<nb-accordion-item>
<nb-accordion-item-header class="label" data-cy="audit-scope-header">ISO/IEC 25010 Faktoren / Kriterien</nb-accordion-item-header>
<nb-accordion-item-body>
<div class="wrapper-facCrits mt-2" data-cy="facCrits">
<div *ngFor="let factor of facCrits$ | async | factors">
<nb-checkbox [formControlName]="factor.id" (checkedChange)="toggleCriteriaChecked(factor.id, $event)" data-cy="factor-entry">{{ factor.name }}</nb-checkbox>
<nb-checkbox
(checkedChange)="formGroup.get(factor.id).setValue(true)"
[formControlName]="criteria.id"
*ngFor="let criteria of facCrits$ | async | criterias: factor.id"
data-cy="criteria-entry"
>{{ criteria.name }}</nb-checkbox
>
</div>
</div>
</nb-accordion-item-body>
</nb-accordion-item>
</nb-accordion>
</nb-card-body>
<nb-card-footer data-cy="audit-data-buttons">
<button (click)="onCancel()" hero nbButton data-cy="cancel-audit-data-form">
abbrechen
</button>
<button (click)="onSubmit()" [disabled]="formGroup.invalid" status="primary" hero nbButton data-cy="submit-audit-data-form">
{{ submitButtonName }}
</button>
</nb-card-footer>
</nb-card>
</form>
./audit-form.component.scss
@import 'src/sass/utils';
nb-card-footer {
display: flex;
justify-content: space-between;
border-radius: 0;
padding: 10px 20px 10px 20px;
}
.wrapper-facCrits {
max-width: 600px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
@media screen and(max-width: 500px) {
grid-template-columns: 1fr;
nb-checkbox {
margin: 0px 10px 0px 0px;
}
}
& > div {
nb-checkbox {
display: block;
}
& nb-checkbox:not(:first-child) {
margin-left: 20px;
}
}
}
nb-accordion {
box-shadow: none;
border: 1px solid rgb(228, 233, 242);
}