Feature : Adding percentage option to Input Number (#8481)

fixing #7375

---------

Co-authored-by: guillim <guillaume@twenty.com>
This commit is contained in:
Guillim
2024-11-14 14:23:25 +01:00
committed by GitHub
parent 090f612c4b
commit 15b8b9b158
18 changed files with 166 additions and 47 deletions

View File

@ -1,5 +1,14 @@
import { Injectable } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import {
IsEnum,
IsInt,
IsOptional,
Min,
validateOrReject,
} from 'class-validator';
import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
@ -8,13 +17,29 @@ import {
FieldMetadataExceptionCode,
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
enum ValueType {
PERCENTAGE = 'percentage',
NUMBER = 'number',
}
class SettingsValidation {
@IsOptional()
@IsInt()
@Min(0)
decimals?: number;
@IsOptional()
@IsEnum(ValueType)
type?: 'percentage' | 'number';
}
@Injectable()
export class FieldMetadataValidationService<
T extends FieldMetadataType | 'default' = 'default',
> {
constructor() {}
validateSettingsOrThrow({
async validateSettingsOrThrow({
fieldType,
settings,
}: {
@ -23,26 +48,28 @@ export class FieldMetadataValidationService<
}) {
switch (fieldType) {
case FieldMetadataType.NUMBER:
this.validateNumberSettings(settings);
await this.validateNumberSettings(settings);
break;
default:
break;
}
}
private validateNumberSettings(settings: FieldMetadataSettings<T>) {
if ('decimals' in settings) {
const { decimals } = settings;
private async validateNumberSettings(settings: any) {
try {
const settingsInstance = plainToInstance(SettingsValidation, settings);
if (
decimals !== undefined &&
(decimals < 0 || !Number.isInteger(decimals))
) {
throw new FieldMetadataException(
`Decimals value "${decimals}" must be a positive integer`,
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
);
}
await validateOrReject(settingsInstance);
} catch (errors) {
const errorMessages = errors
.map((error: any) => Object.values(error.constraints))
.flat()
.join(', ');
throw new FieldMetadataException(
`Value for settings is invalid: ${errorMessages}`,
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
);
}
}
}

View File

@ -410,7 +410,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
// We're running field update under a transaction, so we can rollback if migration fails
await fieldMetadataRepository.update(id, fieldMetadataForUpdate);
const updatedFieldMetadata = await fieldMetadataRepository.findOne({
const [updatedFieldMetadata] = await fieldMetadataRepository.find({
where: { id },
});

View File

@ -13,6 +13,7 @@ type FieldMetadataDefaultSettings = {
type FieldMetadataNumberSettings = {
dataType: NumberDataType;
decimals?: number;
type?: string;
};
type FieldMetadataDateSettings = {