Feature/add form validation against DTO for activity and account (#3230)
* Add form validation against DTO for activity and account * Update changelog
This commit is contained in:
parent
5d4e2fba8c
commit
9241c04d5a
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- Added a form validation against the DTO in the create or update account dialog
|
||||
- Added a form validation against the DTO in the create or update activity dialog
|
||||
|
||||
### Changed
|
||||
|
||||
- Moved the dividend calculations into the portfolio calculator
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
|
||||
import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
import { Currency } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import {
|
||||
@ -102,7 +103,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
public async onSubmit() {
|
||||
const account: CreateAccountDto | UpdateAccountDto = {
|
||||
balance: this.accountForm.controls['balance'].value,
|
||||
comment: this.accountForm.controls['comment'].value,
|
||||
@ -113,13 +114,29 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
platformId: this.accountForm.controls['platformId'].value?.id ?? null
|
||||
};
|
||||
|
||||
try {
|
||||
if (this.data.account.id) {
|
||||
(account as UpdateAccountDto).id = this.data.account.id;
|
||||
|
||||
await validateObjectForForm({
|
||||
classDto: UpdateAccountDto,
|
||||
form: this.accountForm,
|
||||
object: account
|
||||
});
|
||||
} else {
|
||||
delete (account as CreateAccountDto).id;
|
||||
|
||||
await validateObjectForForm({
|
||||
classDto: CreateAccountDto,
|
||||
form: this.accountForm,
|
||||
object: account
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close({ account });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
|
||||
import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
import { getDateFormatString } from '@ghostfolio/common/helper';
|
||||
import { translate } from '@ghostfolio/ui/i18n';
|
||||
|
||||
@ -451,7 +452,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
public async onSubmit() {
|
||||
const activity: CreateOrderDto | UpdateOrderDto = {
|
||||
accountId: this.activityForm.controls['accountId'].value,
|
||||
assetClass: this.activityForm.controls['assetClass'].value,
|
||||
@ -474,14 +475,32 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
unitPrice: this.activityForm.controls['unitPrice'].value
|
||||
};
|
||||
|
||||
try {
|
||||
if (this.data.activity.id) {
|
||||
(activity as UpdateOrderDto).id = this.data.activity.id;
|
||||
|
||||
await validateObjectForForm({
|
||||
classDto: UpdateOrderDto,
|
||||
form: this.activityForm,
|
||||
ignoreFields: ['dataSource', 'date'],
|
||||
object: activity as UpdateOrderDto
|
||||
});
|
||||
} else {
|
||||
(activity as CreateOrderDto).updateAccountBalance =
|
||||
this.activityForm.controls['updateAccountBalance'].value;
|
||||
|
||||
await validateObjectForForm({
|
||||
classDto: CreateOrderDto,
|
||||
form: this.activityForm,
|
||||
ignoreFields: ['dataSource', 'date'],
|
||||
object: activity
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close({ activity });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
|
38
apps/client/src/app/util/form.util.ts
Normal file
38
apps/client/src/app/util/form.util.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validate } from 'class-validator';
|
||||
|
||||
export async function validateObjectForForm<T>({
|
||||
classDto,
|
||||
form,
|
||||
ignoreFields = [],
|
||||
object
|
||||
}: {
|
||||
classDto: { new (): T };
|
||||
form: FormGroup;
|
||||
ignoreFields?: string[];
|
||||
object: T;
|
||||
}): Promise<void> {
|
||||
const objectInstance = plainToInstance(classDto, object);
|
||||
const errors = await validate(objectInstance as object);
|
||||
|
||||
const nonIgnoredErrors = errors.filter(({ property }) => {
|
||||
return !ignoreFields.includes(property);
|
||||
});
|
||||
|
||||
if (nonIgnoredErrors.length === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
for (const { constraints, property } of nonIgnoredErrors) {
|
||||
const formControl = form.get(property);
|
||||
|
||||
if (formControl) {
|
||||
formControl.setErrors({
|
||||
validationError: Object.values(constraints)[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(nonIgnoredErrors);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user