[PAGE LAYOUTS] Add widgets validation (#16635)
- Add widget validation - Remove 'None' option for primary axis group by - Fix error message parsing by passing the operation type in `useMetadataErrorHandler`
This commit is contained in:
+9
-2
@@ -1,12 +1,19 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { FlatPageLayoutWidgetTypeValidatorService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { WorkspaceFlatPageLayoutWidgetMapCacheService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/workspace-flat-page-layout-widget-map-cache.service';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([PageLayoutWidgetEntity])],
|
||||
providers: [WorkspaceFlatPageLayoutWidgetMapCacheService],
|
||||
exports: [WorkspaceFlatPageLayoutWidgetMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatPageLayoutWidgetMapCacheService,
|
||||
FlatPageLayoutWidgetTypeValidatorService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceFlatPageLayoutWidgetMapCacheService,
|
||||
FlatPageLayoutWidgetTypeValidatorService,
|
||||
],
|
||||
})
|
||||
export class FlatPageLayoutWidgetModule {}
|
||||
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import {
|
||||
type FlatPageLayoutWidgetTypeValidatorForCreation,
|
||||
type FlatPageLayoutWidgetTypeValidatorForUpdate,
|
||||
} from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-type-validator.type';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { rejectWidgetType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/reject-widget-type.util';
|
||||
import { validateGraphFlatPageLayoutWidgetForCreation } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-flat-page-layout-widget-for-creation.util';
|
||||
import { validateGraphFlatPageLayoutWidgetForUpdate } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-flat-page-layout-widget-for-update.util';
|
||||
import { validateIframeFlatPageLayoutWidgetForCreation } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-flat-page-layout-widget-for-creation.util';
|
||||
import { validateIframeFlatPageLayoutWidgetForUpdate } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-flat-page-layout-widget-for-update.util';
|
||||
import { validateStandaloneRichTextFlatPageLayoutWidgetForCreation } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-flat-page-layout-widget-for-creation.util';
|
||||
import { validateStandaloneRichTextFlatPageLayoutWidgetForUpdate } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-flat-page-layout-widget-for-update.util';
|
||||
import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
|
||||
|
||||
export type GenericValidateFlatPageLayoutWidgetTypeSpecificitiesArgs =
|
||||
FlatEntityValidationArgs<'pageLayoutWidget'> & {
|
||||
updates?: FlatEntityPropertiesUpdates<'pageLayoutWidget'>;
|
||||
};
|
||||
|
||||
export type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs =
|
||||
FlatEntityValidationArgs<'pageLayoutWidget'>;
|
||||
|
||||
export type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs =
|
||||
FlatEntityValidationArgs<'pageLayoutWidget'> & {
|
||||
updates: FlatEntityPropertiesUpdates<'pageLayoutWidget'>;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class FlatPageLayoutWidgetTypeValidatorService {
|
||||
constructor() {}
|
||||
|
||||
private readonly PAGE_LAYOUT_WIDGET_TYPE_VALIDATOR_FOR_CREATION_HASHMAP: FlatPageLayoutWidgetTypeValidatorForCreation =
|
||||
{
|
||||
VIEW: rejectWidgetType(
|
||||
WidgetType.VIEW,
|
||||
'Widget type VIEW is not supported yet.',
|
||||
msg`Widget type VIEW is not supported yet.`,
|
||||
),
|
||||
IFRAME: validateIframeFlatPageLayoutWidgetForCreation,
|
||||
FIELD: rejectWidgetType(
|
||||
WidgetType.FIELD,
|
||||
'Widget type FIELD is not supported yet.',
|
||||
msg`Widget type FIELD is not supported yet.`,
|
||||
),
|
||||
FIELDS: rejectWidgetType(
|
||||
WidgetType.FIELDS,
|
||||
'Widget type FIELDS is not supported yet.',
|
||||
msg`Widget type FIELDS is not supported yet.`,
|
||||
),
|
||||
GRAPH: validateGraphFlatPageLayoutWidgetForCreation,
|
||||
STANDALONE_RICH_TEXT:
|
||||
validateStandaloneRichTextFlatPageLayoutWidgetForCreation,
|
||||
TIMELINE: rejectWidgetType(
|
||||
WidgetType.TIMELINE,
|
||||
'Widget type TIMELINE is not supported yet.',
|
||||
msg`Widget type TIMELINE is not supported yet.`,
|
||||
),
|
||||
TASKS: rejectWidgetType(
|
||||
WidgetType.TASKS,
|
||||
'Widget type TASKS is not supported yet.',
|
||||
msg`Widget type TASKS is not supported yet.`,
|
||||
),
|
||||
NOTES: rejectWidgetType(
|
||||
WidgetType.NOTES,
|
||||
'Widget type NOTES is not supported yet.',
|
||||
msg`Widget type NOTES is not supported yet.`,
|
||||
),
|
||||
FILES: rejectWidgetType(
|
||||
WidgetType.FILES,
|
||||
'Widget type FILES is not supported yet.',
|
||||
msg`Widget type FILES is not supported yet.`,
|
||||
),
|
||||
EMAILS: rejectWidgetType(
|
||||
WidgetType.EMAILS,
|
||||
'Widget type EMAILS is not supported yet.',
|
||||
msg`Widget type EMAILS is not supported yet.`,
|
||||
),
|
||||
CALENDAR: rejectWidgetType(
|
||||
WidgetType.CALENDAR,
|
||||
'Widget type CALENDAR is not supported yet.',
|
||||
msg`Widget type CALENDAR is not supported yet.`,
|
||||
),
|
||||
FIELD_RICH_TEXT: rejectWidgetType(
|
||||
WidgetType.FIELD_RICH_TEXT,
|
||||
'Widget type FIELD_RICH_TEXT is not supported yet.',
|
||||
msg`Widget type FIELD_RICH_TEXT is not supported yet.`,
|
||||
),
|
||||
WORKFLOW: rejectWidgetType(
|
||||
WidgetType.WORKFLOW,
|
||||
'Widget type WORKFLOW is not supported yet.',
|
||||
msg`Widget type WORKFLOW is not supported yet.`,
|
||||
),
|
||||
WORKFLOW_VERSION: rejectWidgetType(
|
||||
WidgetType.WORKFLOW_VERSION,
|
||||
'Widget type WORKFLOW_VERSION is not supported yet.',
|
||||
msg`Widget type WORKFLOW_VERSION is not supported yet.`,
|
||||
),
|
||||
WORKFLOW_RUN: rejectWidgetType(
|
||||
WidgetType.WORKFLOW_RUN,
|
||||
'Widget type WORKFLOW_RUN is not supported yet.',
|
||||
msg`Widget type WORKFLOW_RUN is not supported yet.`,
|
||||
),
|
||||
};
|
||||
|
||||
private readonly PAGE_LAYOUT_WIDGET_TYPE_VALIDATOR_FOR_UPDATE_HASHMAP: FlatPageLayoutWidgetTypeValidatorForUpdate =
|
||||
{
|
||||
VIEW: rejectWidgetType(
|
||||
WidgetType.VIEW,
|
||||
'Widget type VIEW is not supported yet.',
|
||||
msg`Widget type VIEW is not supported yet.`,
|
||||
),
|
||||
IFRAME: validateIframeFlatPageLayoutWidgetForUpdate,
|
||||
FIELD: rejectWidgetType(
|
||||
WidgetType.FIELD,
|
||||
'Widget type FIELD is not supported yet.',
|
||||
msg`Widget type FIELD is not supported yet.`,
|
||||
),
|
||||
FIELDS: rejectWidgetType(
|
||||
WidgetType.FIELDS,
|
||||
'Widget type FIELDS is not supported yet.',
|
||||
msg`Widget type FIELDS is not supported yet.`,
|
||||
),
|
||||
GRAPH: validateGraphFlatPageLayoutWidgetForUpdate,
|
||||
STANDALONE_RICH_TEXT:
|
||||
validateStandaloneRichTextFlatPageLayoutWidgetForUpdate,
|
||||
TIMELINE: rejectWidgetType(
|
||||
WidgetType.TIMELINE,
|
||||
'Widget type TIMELINE is not supported yet.',
|
||||
msg`Widget type TIMELINE is not supported yet.`,
|
||||
),
|
||||
TASKS: rejectWidgetType(
|
||||
WidgetType.TASKS,
|
||||
'Widget type TASKS is not supported yet.',
|
||||
msg`Widget type TASKS is not supported yet.`,
|
||||
),
|
||||
NOTES: rejectWidgetType(
|
||||
WidgetType.NOTES,
|
||||
'Widget type NOTES is not supported yet.',
|
||||
msg`Widget type NOTES is not supported yet.`,
|
||||
),
|
||||
FILES: rejectWidgetType(
|
||||
WidgetType.FILES,
|
||||
'Widget type FILES is not supported yet.',
|
||||
msg`Widget type FILES is not supported yet.`,
|
||||
),
|
||||
EMAILS: rejectWidgetType(
|
||||
WidgetType.EMAILS,
|
||||
'Widget type EMAILS is not supported yet.',
|
||||
msg`Widget type EMAILS is not supported yet.`,
|
||||
),
|
||||
CALENDAR: rejectWidgetType(
|
||||
WidgetType.CALENDAR,
|
||||
'Widget type CALENDAR is not supported yet.',
|
||||
msg`Widget type CALENDAR is not supported yet.`,
|
||||
),
|
||||
FIELD_RICH_TEXT: rejectWidgetType(
|
||||
WidgetType.FIELD_RICH_TEXT,
|
||||
'Widget type FIELD_RICH_TEXT is not supported yet.',
|
||||
msg`Widget type FIELD_RICH_TEXT is not supported yet.`,
|
||||
),
|
||||
WORKFLOW: rejectWidgetType(
|
||||
WidgetType.WORKFLOW,
|
||||
'Widget type WORKFLOW is not supported yet.',
|
||||
msg`Widget type WORKFLOW is not supported yet.`,
|
||||
),
|
||||
WORKFLOW_VERSION: rejectWidgetType(
|
||||
WidgetType.WORKFLOW_VERSION,
|
||||
'Widget type WORKFLOW_VERSION is not supported yet.',
|
||||
msg`Widget type WORKFLOW_VERSION is not supported yet.`,
|
||||
),
|
||||
WORKFLOW_RUN: rejectWidgetType(
|
||||
WidgetType.WORKFLOW_RUN,
|
||||
'Widget type WORKFLOW_RUN is not supported yet.',
|
||||
msg`Widget type WORKFLOW_RUN is not supported yet.`,
|
||||
),
|
||||
};
|
||||
|
||||
public validateFlatPageLayoutWidgetTypeSpecificitiesForCreation(
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] {
|
||||
const { flatEntityToValidate } = args;
|
||||
const widgetType = flatEntityToValidate.type;
|
||||
const pageLayoutWidgetTypeValidator =
|
||||
this.PAGE_LAYOUT_WIDGET_TYPE_VALIDATOR_FOR_CREATION_HASHMAP[widgetType];
|
||||
|
||||
if (!isDefined(pageLayoutWidgetTypeValidator)) {
|
||||
return [
|
||||
{
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: `Unsupported page layout widget type ${widgetType}`,
|
||||
value: widgetType,
|
||||
userFriendlyMessage: msg`Unsupported page layout widget type ${widgetType}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return pageLayoutWidgetTypeValidator(args);
|
||||
}
|
||||
|
||||
public validateFlatPageLayoutWidgetTypeSpecificitiesForUpdate(
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] {
|
||||
const { flatEntityToValidate } = args;
|
||||
const widgetType = flatEntityToValidate.type;
|
||||
const pageLayoutWidgetTypeValidator =
|
||||
this.PAGE_LAYOUT_WIDGET_TYPE_VALIDATOR_FOR_UPDATE_HASHMAP[widgetType];
|
||||
|
||||
if (!isDefined(pageLayoutWidgetTypeValidator)) {
|
||||
return [
|
||||
{
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: `Unsupported page layout widget type ${widgetType}`,
|
||||
value: widgetType,
|
||||
userFriendlyMessage: msg`Unsupported page layout widget type ${widgetType}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return pageLayoutWidgetTypeValidator(args);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
type GenericValidateFlatPageLayoutWidgetTypeSpecificitiesArgs,
|
||||
type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
} from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum';
|
||||
|
||||
export type FlatPageLayoutWidgetTypeValidator = {
|
||||
[T in WidgetType]: (
|
||||
args: GenericValidateFlatPageLayoutWidgetTypeSpecificitiesArgs,
|
||||
) => FlatPageLayoutWidgetValidationError[];
|
||||
};
|
||||
|
||||
export type FlatPageLayoutWidgetTypeValidatorForCreation = {
|
||||
[T in WidgetType]: (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
) => FlatPageLayoutWidgetValidationError[];
|
||||
};
|
||||
|
||||
export type FlatPageLayoutWidgetTypeValidatorForUpdate = {
|
||||
[T in WidgetType]: (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
) => FlatPageLayoutWidgetValidationError[];
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
|
||||
import { type PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export type FlatPageLayoutWidgetValidationError = {
|
||||
code: PageLayoutWidgetExceptionCode;
|
||||
message: string;
|
||||
userFriendlyMessage?: MessageDescriptor;
|
||||
value?: unknown;
|
||||
};
|
||||
+6
-2
@@ -3,7 +3,7 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type';
|
||||
import { type CreatePageLayoutWidgetInput } from 'src/engine/metadata-modules/page-layout-widget/dtos/inputs/create-page-layout-widget.input';
|
||||
import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum';
|
||||
import { validateWidgetConfigurationInput } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-widget-configuration-input.util';
|
||||
|
||||
export type FromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreateArgs =
|
||||
{
|
||||
@@ -23,6 +23,10 @@ export const fromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreate = ({
|
||||
['pageLayoutTabId'],
|
||||
);
|
||||
|
||||
validateWidgetConfigurationInput({
|
||||
configuration: createPageLayoutWidgetInput.configuration,
|
||||
});
|
||||
|
||||
const createdAt = new Date().toISOString();
|
||||
const pageLayoutWidgetId = v4();
|
||||
|
||||
@@ -35,7 +39,7 @@ export const fromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreate = ({
|
||||
deletedAt: null,
|
||||
universalIdentifier: pageLayoutWidgetId,
|
||||
title: createPageLayoutWidgetInput.title,
|
||||
type: createPageLayoutWidgetInput.type ?? WidgetType.VIEW,
|
||||
type: createPageLayoutWidgetInput.type,
|
||||
objectMetadataId: createPageLayoutWidgetInput.objectMetadataId ?? null,
|
||||
gridPosition: createPageLayoutWidgetInput.gridPosition,
|
||||
configuration: createPageLayoutWidgetInput.configuration,
|
||||
|
||||
+12
@@ -12,6 +12,7 @@ import {
|
||||
PageLayoutWidgetException,
|
||||
PageLayoutWidgetExceptionCode,
|
||||
} from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
import { validateWidgetConfigurationInput } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-widget-configuration-input.util';
|
||||
import { mergeUpdateInExistingRecord } from 'src/utils/merge-update-in-existing-record.util';
|
||||
|
||||
export type UpdatePageLayoutWidgetInputWithId = {
|
||||
@@ -47,6 +48,17 @@ export const fromUpdatePageLayoutWidgetInputToFlatPageLayoutWidgetToUpdateOrThro
|
||||
FLAT_PAGE_LAYOUT_WIDGET_EDITABLE_PROPERTIES,
|
||||
);
|
||||
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
updatedEditableFieldProperties,
|
||||
'configuration',
|
||||
)
|
||||
) {
|
||||
validateWidgetConfigurationInput({
|
||||
configuration: updatedEditableFieldProperties.configuration,
|
||||
});
|
||||
}
|
||||
|
||||
return mergeUpdateInExistingRecord({
|
||||
existing: existingFlatPageLayoutWidgetToUpdate,
|
||||
properties: FLAT_PAGE_LAYOUT_WIDGET_EDITABLE_PROPERTIES,
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
|
||||
export const VALID_GRAPH_CONFIGURATION_TYPES = [
|
||||
WidgetConfigurationType.AGGREGATE_CHART,
|
||||
WidgetConfigurationType.BAR_CHART,
|
||||
WidgetConfigurationType.LINE_CHART,
|
||||
WidgetConfigurationType.PIE_CHART,
|
||||
WidgetConfigurationType.GAUGE_CHART,
|
||||
] as const;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type GraphConfiguration } from './graph-configuration.type';
|
||||
|
||||
export type BaseGraphConfiguration = Pick<
|
||||
GraphConfiguration,
|
||||
'configurationType' | 'aggregateFieldMetadataId' | 'aggregateOperation'
|
||||
>;
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { type AggregateChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto';
|
||||
import { type BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto';
|
||||
import { type GaugeChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto';
|
||||
import { type LineChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto';
|
||||
import { type PieChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto';
|
||||
|
||||
export type GraphConfiguration =
|
||||
| BarChartConfigurationDTO
|
||||
| LineChartConfigurationDTO
|
||||
| PieChartConfigurationDTO
|
||||
| AggregateChartConfigurationDTO
|
||||
| GaugeChartConfigurationDTO;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
|
||||
export type IframeConfiguration = {
|
||||
configurationType?: WidgetConfigurationType;
|
||||
url?: string;
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { type msg } from '@lingui/core/macro';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const rejectWidgetType = (
|
||||
widgetType: WidgetType,
|
||||
message: string,
|
||||
userFriendlyMessage: ReturnType<typeof msg>,
|
||||
) => {
|
||||
return (): FlatPageLayoutWidgetValidationError[] => {
|
||||
return [
|
||||
{
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message,
|
||||
value: widgetType,
|
||||
userFriendlyMessage,
|
||||
},
|
||||
];
|
||||
};
|
||||
};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateBarChartConfiguration = (
|
||||
configuration: BarChartConfigurationDTO,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.primaryAxisGroupByFieldMetadataId)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Primary axis group by field is required for bar chart widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Primary axis group by field is required for bar chart`,
|
||||
});
|
||||
}
|
||||
|
||||
if (!isDefined(configuration.layout)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Layout is required for bar chart widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Layout is required for bar chart`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type BaseGraphConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/base-graph-configuration.type';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateBaseGraphFields = (
|
||||
configuration: BaseGraphConfiguration,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.aggregateFieldMetadataId)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Aggregate field metadata ID is required for graph widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Aggregate field is required for graph widget`,
|
||||
});
|
||||
}
|
||||
|
||||
if (!isDefined(configuration.aggregateOperation)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Aggregate operation is required for graph widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Aggregate operation is required for graph widget`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type GraphConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/graph-configuration.type';
|
||||
import { validateBarChartConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-bar-chart-configuration.util';
|
||||
import { validateLineChartConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-line-chart-configuration.util';
|
||||
import { validatePieChartConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-pie-chart-configuration.util';
|
||||
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
|
||||
export const validateGraphConfigurationByType = (
|
||||
configuration: GraphConfiguration,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const configurationType = configuration.configurationType;
|
||||
|
||||
switch (configurationType) {
|
||||
case WidgetConfigurationType.BAR_CHART:
|
||||
return validateBarChartConfiguration(configuration, widgetTitle);
|
||||
case WidgetConfigurationType.LINE_CHART:
|
||||
return validateLineChartConfiguration(configuration, widgetTitle);
|
||||
case WidgetConfigurationType.PIE_CHART:
|
||||
return validatePieChartConfiguration(configuration, widgetTitle);
|
||||
case WidgetConfigurationType.AGGREGATE_CHART:
|
||||
case WidgetConfigurationType.GAUGE_CHART:
|
||||
return [];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { VALID_GRAPH_CONFIGURATION_TYPES } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/constants/valid-graph-configuration-types.constant';
|
||||
import { type GraphConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/graph-configuration.type';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateGraphConfigurationType = (
|
||||
configuration: GraphConfiguration,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.configurationType)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration type is required for widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Configuration type is required`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
const isValidGraphConfigurationType =
|
||||
VALID_GRAPH_CONFIGURATION_TYPES.includes(configuration.configurationType);
|
||||
|
||||
if (!isValidGraphConfigurationType) {
|
||||
const expectedConfigurationTypes = VALID_GRAPH_CONFIGURATION_TYPES.map(
|
||||
(type) => type.toString(),
|
||||
).join(', ');
|
||||
|
||||
const configurationTypeString = configuration.configurationType.toString();
|
||||
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Invalid configuration type for graph widget "${widgetTitle}". Expected one of ${expectedConfigurationTypes}, got ${configurationTypeString}`,
|
||||
userFriendlyMessage: msg`Invalid configuration type for graph widget`,
|
||||
value: configuration.configurationType,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type GraphConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/graph-configuration.type';
|
||||
import { validateBaseGraphFields } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-base-graph-fields.util';
|
||||
import { validateGraphConfigurationByType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-configuration-by-type.util';
|
||||
import { validateGraphConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-configuration-type.util';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateGraphFlatPageLayoutWidgetForCreation = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration is required for graph widget "${title}"`,
|
||||
userFriendlyMessage: msg`Configuration is required for graph widget`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
const graphConfiguration = configuration as GraphConfiguration;
|
||||
|
||||
const configurationTypeErrors = validateGraphConfigurationType(
|
||||
graphConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
if (configurationTypeErrors.length > 0) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const baseFieldErrors = validateBaseGraphFields(graphConfiguration, title);
|
||||
|
||||
errors.push(...baseFieldErrors);
|
||||
|
||||
const typeSpecificErrors = validateGraphConfigurationByType(
|
||||
graphConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...typeSpecificErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type GraphConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/graph-configuration.type';
|
||||
import { validateBaseGraphFields } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-base-graph-fields.util';
|
||||
import { validateGraphConfigurationByType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-configuration-by-type.util';
|
||||
import { validateGraphConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-graph-configuration-type.util';
|
||||
|
||||
export const validateGraphFlatPageLayoutWidgetForUpdate = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const graphConfiguration = configuration as GraphConfiguration;
|
||||
|
||||
const configurationTypeErrors = validateGraphConfigurationType(
|
||||
graphConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
if (configurationTypeErrors.length > 0) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const baseFieldErrors = validateBaseGraphFields(graphConfiguration, title);
|
||||
|
||||
errors.push(...baseFieldErrors);
|
||||
|
||||
const typeSpecificErrors = validateGraphConfigurationByType(
|
||||
graphConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...typeSpecificErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type IframeConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/iframe-configuration.type';
|
||||
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateIframeConfigurationType = (
|
||||
configuration: IframeConfiguration,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.configurationType)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration type is required for widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Configuration type is required`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (configuration.configurationType !== WidgetConfigurationType.IFRAME) {
|
||||
const configurationTypeString = configuration.configurationType.toString();
|
||||
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Invalid configuration type for iframe widget "${widgetTitle}". Expected IFRAME, got ${configurationTypeString}`,
|
||||
userFriendlyMessage: msg`Invalid configuration type for iframe widget`,
|
||||
value: configuration.configurationType,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type IframeConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/iframe-configuration.type';
|
||||
import { validateIframeConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-configuration-type.util';
|
||||
import { validateIframeUrl } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-url.util';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateIframeFlatPageLayoutWidgetForCreation = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration is required for iframe widget "${title}"`,
|
||||
userFriendlyMessage: msg`Configuration is required for iframe widget`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
const iframeConfiguration = configuration as IframeConfiguration;
|
||||
|
||||
const configurationTypeErrors = validateIframeConfigurationType(
|
||||
iframeConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
const urlErrors = validateIframeUrl(iframeConfiguration, title);
|
||||
|
||||
errors.push(...urlErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type IframeConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/iframe-configuration.type';
|
||||
import { validateIframeConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-configuration-type.util';
|
||||
import { validateIframeUrl } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-iframe-url.util';
|
||||
|
||||
export const validateIframeFlatPageLayoutWidgetForUpdate = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const iframeConfiguration = configuration as IframeConfiguration;
|
||||
|
||||
const configurationTypeErrors = validateIframeConfigurationType(
|
||||
iframeConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
const urlErrors = validateIframeUrl(iframeConfiguration, title);
|
||||
|
||||
errors.push(...urlErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type IframeConfiguration } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/types/iframe-configuration.type';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateIframeUrl = (
|
||||
configuration: IframeConfiguration,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (isDefined(configuration.url) && typeof configuration.url !== 'string') {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`URL must be a string for widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`URL must be a string`,
|
||||
value: configuration.url,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type LineChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateLineChartConfiguration = (
|
||||
configuration: LineChartConfigurationDTO,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.primaryAxisGroupByFieldMetadataId)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Primary axis group by field is required for line chart widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Primary axis group by field is required for line chart`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type PieChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validatePieChartConfiguration = (
|
||||
configuration: PieChartConfigurationDTO,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.groupByFieldMetadataId)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Group by field is required for pie chart widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Group by field is required for pie chart`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type StandaloneRichTextConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateStandaloneRichTextBody = (
|
||||
configuration: StandaloneRichTextConfigurationDTO,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.body)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Body is required for standalone rich text widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Body is required for standalone rich text widget`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof configuration.body !== 'object' ||
|
||||
Array.isArray(configuration.body)
|
||||
) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Body must be an object for widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Body must be an object`,
|
||||
value: configuration.body,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { type StandaloneRichTextConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto';
|
||||
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateStandaloneRichTextConfigurationType = (
|
||||
configuration: StandaloneRichTextConfigurationDTO,
|
||||
widgetTitle: string,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration.configurationType)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration type is required for widget "${widgetTitle}"`,
|
||||
userFriendlyMessage: msg`Configuration type is required`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (
|
||||
configuration.configurationType !==
|
||||
WidgetConfigurationType.STANDALONE_RICH_TEXT
|
||||
) {
|
||||
const expectedConfigurationType =
|
||||
WidgetConfigurationType.STANDALONE_RICH_TEXT;
|
||||
|
||||
const configurationType = configuration.configurationType;
|
||||
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Invalid configuration type for standalone rich text widget "${widgetTitle}". Expected ${expectedConfigurationType}, got ${configurationType}`,
|
||||
userFriendlyMessage: msg`Invalid configuration type for standalone rich text widget`,
|
||||
value: configuration.configurationType,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { validateStandaloneRichTextBody } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-body.util';
|
||||
import { validateStandaloneRichTextConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-configuration-type.util';
|
||||
import { type StandaloneRichTextConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto';
|
||||
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
|
||||
export const validateStandaloneRichTextFlatPageLayoutWidgetForCreation = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
errors.push({
|
||||
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
|
||||
message: t`Configuration is required for standalone rich text widget "${title}"`,
|
||||
userFriendlyMessage: msg`Configuration is required for standalone rich text widget`,
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
const standaloneRichTextConfiguration =
|
||||
configuration as StandaloneRichTextConfigurationDTO;
|
||||
|
||||
const configurationTypeErrors = validateStandaloneRichTextConfigurationType(
|
||||
standaloneRichTextConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
const bodyErrors = validateStandaloneRichTextBody(
|
||||
standaloneRichTextConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...bodyErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
|
||||
import { type FlatPageLayoutWidgetValidationError } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-validation-error.type';
|
||||
import { validateStandaloneRichTextBody } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-body.util';
|
||||
import { validateStandaloneRichTextConfigurationType } from 'src/engine/metadata-modules/flat-page-layout-widget/validators/utils/validate-standalone-rich-text-configuration-type.util';
|
||||
import { type StandaloneRichTextConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto';
|
||||
|
||||
export const validateStandaloneRichTextFlatPageLayoutWidgetForUpdate = (
|
||||
args: ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs,
|
||||
): FlatPageLayoutWidgetValidationError[] => {
|
||||
const { flatEntityToValidate } = args;
|
||||
const { configuration, title } = flatEntityToValidate;
|
||||
const errors: FlatPageLayoutWidgetValidationError[] = [];
|
||||
|
||||
if (!isDefined(configuration)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const standaloneRichTextConfiguration =
|
||||
configuration as StandaloneRichTextConfigurationDTO;
|
||||
|
||||
const configurationTypeErrors = validateStandaloneRichTextConfigurationType(
|
||||
standaloneRichTextConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...configurationTypeErrors);
|
||||
|
||||
const bodyErrors = validateStandaloneRichTextBody(
|
||||
standaloneRichTextConfiguration,
|
||||
title,
|
||||
);
|
||||
|
||||
errors.push(...bodyErrors);
|
||||
|
||||
return errors;
|
||||
};
|
||||
Reference in New Issue
Block a user