diff --git a/packages/twenty-sdk/src/cli/utilities/entity/entity-page-layout-template.ts b/packages/twenty-sdk/src/cli/utilities/entity/entity-page-layout-template.ts index 18e6e07232..39e6a524ba 100644 --- a/packages/twenty-sdk/src/cli/utilities/entity/entity-page-layout-template.ts +++ b/packages/twenty-sdk/src/cli/utilities/entity/entity-page-layout-template.ts @@ -10,7 +10,6 @@ export default definePageLayout({ { universalIdentifier: '${uuidv4()}', title: 'Overview', - position: 0, widgets: [], }, ], diff --git a/packages/twenty-sdk/src/sdk/index.ts b/packages/twenty-sdk/src/sdk/index.ts index c4a4d4ffea..ac9ffe0059 100644 --- a/packages/twenty-sdk/src/sdk/index.ts +++ b/packages/twenty-sdk/src/sdk/index.ts @@ -47,9 +47,15 @@ export type { export type { RoutePayload } from './logic-functions/triggers/route-payload-type'; export { defineNavigationMenuItem } from './navigation-menu-items/define-navigation-menu-item'; export { defineObject } from './objects/define-object'; +export { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from './objects/standard-object-ids'; export { definePageLayout } from './page-layouts/define-page-layout'; export type { PageLayoutConfig } from './page-layouts/page-layout-config'; -export { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from './objects/standard-object-ids'; +export { + AggregateOperations, + ObjectRecordGroupByDateGranularity, + PageLayoutTabLayoutMode, +} from 'twenty-shared/types'; +export type { PageLayoutWidgetUniversalConfiguration } from 'twenty-shared/types'; export { defineRole } from './roles/define-role'; export { PermissionFlag } from './roles/permission-flag-type'; export { defineView } from './views/define-view'; diff --git a/packages/twenty-server/src/engine/core-modules/application/utils/from-page-layout-widget-manifest-to-universal-flat-page-layout-widget.util.ts b/packages/twenty-server/src/engine/core-modules/application/utils/from-page-layout-widget-manifest-to-universal-flat-page-layout-widget.util.ts index 5ee1c223ef..0bbc6bb2cb 100644 --- a/packages/twenty-server/src/engine/core-modules/application/utils/from-page-layout-widget-manifest-to-universal-flat-page-layout-widget.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/utils/from-page-layout-widget-manifest-to-universal-flat-page-layout-widget.util.ts @@ -24,7 +24,7 @@ export const fromPageLayoutWidgetManifestToUniversalFlatPageLayoutWidget = ({ pageLayoutWidgetManifest.objectUniversalIdentifier ?? null, conditionalDisplay: pageLayoutWidgetManifest.conditionalDisplay ?? null, gridPosition: { row: 0, column: 0, rowSpan: 1, columnSpan: 1 }, - position: pageLayoutWidgetManifest.position ?? null, + position: null, universalConfiguration: pageLayoutWidgetManifest.configuration as UniversalFlatPageLayoutWidget['universalConfiguration'], createdAt: now, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-configuration-to-universal-configuration.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-configuration-to-universal-configuration.util.ts index 9d35406947..b0c8766e49 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-configuration-to-universal-configuration.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-configuration-to-universal-configuration.util.ts @@ -1,3 +1,7 @@ +import { + type ChartFilter, + type UniversalChartFilter, +} from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { @@ -39,6 +43,33 @@ const getFieldMetadataUniversalIdentifier = ({ return universalIdentifier; }; +const convertChartFilterToUniversalFilter = ({ + filter, + fieldMetadataUniversalIdentifierById, +}: { + filter: ChartFilter | undefined; + fieldMetadataUniversalIdentifierById: Partial>; + shouldThrowOnMissingIdentifier: boolean; +}): UniversalChartFilter | undefined => { + if (!isDefined(filter)) { + return undefined; + } + + return { + ...filter, + recordFilters: filter.recordFilters?.map( + ({ fieldMetadataId, ...rest }) => ({ + ...rest, + fieldMetadataUniversalIdentifier: getFieldMetadataUniversalIdentifier({ + fieldMetadataId, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier: false, + }), + }), + ), + }; +}; + export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ configuration, fieldMetadataUniversalIdentifierById, @@ -52,8 +83,12 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ }): UniversalPageLayoutWidgetConfiguration => { switch (configuration.configurationType) { case WidgetConfigurationType.AGGREGATE_CHART: { - const { aggregateFieldMetadataId, ratioAggregateConfig, ...rest } = - configuration; + const { + aggregateFieldMetadataId, + ratioAggregateConfig, + filter, + ...rest + } = configuration; const aggregateFieldMetadataUniversalIdentifier = getFieldMetadataUniversalIdentifier({ @@ -78,11 +113,16 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ ...rest, aggregateFieldMetadataUniversalIdentifier, ratioAggregateConfig: universalRatioAggregateConfig, + filter: convertChartFilterToUniversalFilter({ + filter, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier, + }), }; } case WidgetConfigurationType.GAUGE_CHART: { - const { aggregateFieldMetadataId, ...rest } = configuration; + const { aggregateFieldMetadataId, filter, ...rest } = configuration; const aggregateFieldMetadataUniversalIdentifier = getFieldMetadataUniversalIdentifier({ @@ -94,12 +134,21 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ return { ...rest, aggregateFieldMetadataUniversalIdentifier, + filter: convertChartFilterToUniversalFilter({ + filter, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier, + }), }; } case WidgetConfigurationType.PIE_CHART: { - const { aggregateFieldMetadataId, groupByFieldMetadataId, ...rest } = - configuration; + const { + aggregateFieldMetadataId, + groupByFieldMetadataId, + filter, + ...rest + } = configuration; const aggregateFieldMetadataUniversalIdentifier = getFieldMetadataUniversalIdentifier({ @@ -119,6 +168,11 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ ...rest, aggregateFieldMetadataUniversalIdentifier, groupByFieldMetadataUniversalIdentifier, + filter: convertChartFilterToUniversalFilter({ + filter, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier, + }), }; } @@ -127,6 +181,7 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId, secondaryAxisGroupByFieldMetadataId, + filter, ...rest } = configuration; @@ -159,6 +214,11 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ aggregateFieldMetadataUniversalIdentifier, primaryAxisGroupByFieldMetadataUniversalIdentifier, secondaryAxisGroupByFieldMetadataUniversalIdentifier, + filter: convertChartFilterToUniversalFilter({ + filter, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier, + }), }; } @@ -167,6 +227,7 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId, secondaryAxisGroupByFieldMetadataId, + filter, ...rest } = configuration; @@ -199,6 +260,11 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({ aggregateFieldMetadataUniversalIdentifier, primaryAxisGroupByFieldMetadataUniversalIdentifier, secondaryAxisGroupByFieldMetadataUniversalIdentifier, + filter: convertChartFilterToUniversalFilter({ + filter, + fieldMetadataUniversalIdentifierById, + shouldThrowOnMissingIdentifier, + }), }; } diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto.ts index 6158c78f3d..df3bbf3ca3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto.ts @@ -17,17 +17,20 @@ import { } from 'class-validator'; import { GraphQLJSON } from 'graphql-type-json'; import { CalendarStartDay } from 'twenty-shared/constants'; -import { AggregateOperations, SerializedRelation } from 'twenty-shared/types'; +import { + type AggregateChartConfiguration, + AggregateOperations, + type ChartFilter, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { RatioAggregateConfigDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('AggregateChartConfiguration') export class AggregateChartConfigurationDTO - implements PageLayoutWidgetConfigurationBase + implements AggregateChartConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.AGGREGATE_CHART]) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto.ts index c97ce1482c..b2e2a9ad84 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto.ts @@ -17,7 +17,12 @@ import { } from 'class-validator'; import { GraphQLJSON } from 'graphql-type-json'; import { CalendarStartDay } from 'twenty-shared/constants'; -import { AggregateOperations, SerializedRelation } from 'twenty-shared/types'; +import { + AggregateOperations, + type BarChartConfiguration, + type ChartFilter, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum'; @@ -26,13 +31,9 @@ import { BarChartLayout } from 'src/engine/metadata-modules/page-layout-widget/e import { ObjectRecordGroupByDateGranularity } from 'src/engine/metadata-modules/page-layout-widget/enums/date-granularity.enum'; import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('BarChartConfiguration') -export class BarChartConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class BarChartConfigurationDTO implements BarChartConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.BAR_CHART]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/calendar-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/calendar-configuration.dto.ts index 1085ac0f2e..3889baf021 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/calendar-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/calendar-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type CalendarConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('CalendarConfiguration') -export class CalendarConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class CalendarConfigurationDTO implements CalendarConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.CALENDAR]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/emails-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/emails-configuration.dto.ts index a77adbde49..0a7761fe61 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/emails-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/emails-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type EmailsConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('EmailsConfiguration') -export class EmailsConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class EmailsConfigurationDTO implements EmailsConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.EMAILS]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-configuration.dto.ts index 9370a87ab8..52523b93a3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type FieldConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('FieldConfiguration') -export class FieldConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class FieldConfigurationDTO implements FieldConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.FIELD]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-rich-text-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-rich-text-configuration.dto.ts index 62f1f9c984..14cff52f34 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-rich-text-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/field-rich-text-configuration.dto.ts @@ -1,13 +1,13 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type FieldRichTextConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('FieldRichTextConfiguration') export class FieldRichTextConfigurationDTO - implements PageLayoutWidgetConfigurationBase + implements FieldRichTextConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.FIELD_RICH_TEXT]) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/fields-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/fields-configuration.dto.ts index e9cc26a55f..1a8027fedb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/fields-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/fields-configuration.dto.ts @@ -9,9 +9,9 @@ import { IsUUID, ValidateNested, } from 'class-validator'; +import { type FieldsConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('NewFieldDefaultConfiguration') export class NewFieldDefaultConfigurationDTO { @@ -26,9 +26,7 @@ export class NewFieldDefaultConfigurationDTO { } @ObjectType('FieldsConfiguration') -export class FieldsConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class FieldsConfigurationDTO implements FieldsConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.FIELDS]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/files-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/files-configuration.dto.ts index 507ecd1b9d..c9c2996b73 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/files-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/files-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type FilesConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('FilesConfiguration') -export class FilesConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class FilesConfigurationDTO implements FilesConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.FILES]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/front-component-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/front-component-configuration.dto.ts index 9cf9502997..284420f0eb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/front-component-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/front-component-configuration.dto.ts @@ -1,14 +1,14 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty, IsUUID } from 'class-validator'; +import { type FrontComponentConfiguration } from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('FrontComponentConfiguration') export class FrontComponentConfigurationDTO - implements PageLayoutWidgetConfigurationBase + implements FrontComponentConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.FRONT_COMPONENT]) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto.ts index 75e757d243..978fd18db4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto.ts @@ -15,17 +15,18 @@ import { } from 'class-validator'; import { GraphQLJSON } from 'graphql-type-json'; import { CalendarStartDay } from 'twenty-shared/constants'; -import { AggregateOperations, SerializedRelation } from 'twenty-shared/types'; +import { + AggregateOperations, + type ChartFilter, + type GaugeChartConfiguration, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('GaugeChartConfiguration') -export class GaugeChartConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class GaugeChartConfigurationDTO implements GaugeChartConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.GAUGE_CHART]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/iframe-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/iframe-configuration.dto.ts index f1e7c81b20..f15a559987 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/iframe-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/iframe-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty, IsOptional, IsString, IsUrl } from 'class-validator'; +import { type IframeConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('IframeConfiguration') -export class IframeConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class IframeConfigurationDTO implements IframeConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.IFRAME]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/grid-position.input.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/grid-position.input.ts index 29523c188c..0c5995be7b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/grid-position.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/grid-position.input.ts @@ -1,8 +1,7 @@ import { Field, InputType } from '@nestjs/graphql'; import { IsInt, IsNotEmpty, Min } from 'class-validator'; - -import { GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; +import { type GridPosition } from 'twenty-shared/types'; @InputType('GridPositionInput') export class GridPositionInput implements GridPosition { diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto.ts index c5e5e3bfc0..ff4b13fbac 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto.ts @@ -17,20 +17,21 @@ import { } from 'class-validator'; import { GraphQLJSON } from 'graphql-type-json'; import { CalendarStartDay } from 'twenty-shared/constants'; -import { AggregateOperations, SerializedRelation } from 'twenty-shared/types'; +import { + AggregateOperations, + type ChartFilter, + type LineChartConfiguration, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum'; import { ObjectRecordGroupByDateGranularity } from 'src/engine/metadata-modules/page-layout-widget/enums/date-granularity.enum'; import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('LineChartConfiguration') -export class LineChartConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class LineChartConfigurationDTO implements LineChartConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.LINE_CHART]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/notes-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/notes-configuration.dto.ts index 1dc159cd88..69d4c09c4e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/notes-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/notes-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type NotesConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('NotesConfiguration') -export class NotesConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class NotesConfigurationDTO implements NotesConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.NOTES]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto.ts index efcabb4b87..597da15f97 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto.ts @@ -16,19 +16,20 @@ import { } from 'class-validator'; import { GraphQLJSON } from 'graphql-type-json'; import { CalendarStartDay } from 'twenty-shared/constants'; -import { AggregateOperations, SerializedRelation } from 'twenty-shared/types'; +import { + AggregateOperations, + type ChartFilter, + type PieChartConfiguration, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ObjectRecordGroupByDateGranularity } from 'src/engine/metadata-modules/page-layout-widget/enums/date-granularity.enum'; import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('PieChartConfiguration') -export class PieChartConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class PieChartConfigurationDTO implements PieChartConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.PIE_CHART]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto.ts index 2260afef6c..970ebd5106 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto.ts @@ -1,12 +1,15 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsNotEmpty, IsString, IsUUID } from 'class-validator'; -import { SerializedRelation } from 'twenty-shared/types'; +import { + type RatioAggregateConfig, + SerializedRelation, +} from 'twenty-shared/types'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; @ObjectType('RatioAggregateConfig') -export class RatioAggregateConfigDTO { +export class RatioAggregateConfigDTO implements RatioAggregateConfig { @Field(() => UUIDScalarType) @IsUUID() @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto.ts index 7efb2db7cc..9970bd639d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/standalone-rich-text-configuration.dto.ts @@ -2,14 +2,14 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { Type } from 'class-transformer'; import { IsIn, IsNotEmpty, ValidateNested } from 'class-validator'; +import { type StandaloneRichTextConfiguration } from 'twenty-shared/types'; import { RichTextV2BodyDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/rich-text-v2-body.dto'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('StandaloneRichTextConfiguration') export class StandaloneRichTextConfigurationDTO - implements PageLayoutWidgetConfigurationBase + implements StandaloneRichTextConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.STANDALONE_RICH_TEXT]) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/tasks-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/tasks-configuration.dto.ts index 86b84cb58b..381c4fd901 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/tasks-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/tasks-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type TasksConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('TasksConfiguration') -export class TasksConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class TasksConfigurationDTO implements TasksConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.TASKS]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/timeline-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/timeline-configuration.dto.ts index c1c16e6ac1..6d80c4a5ea 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/timeline-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/timeline-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type TimelineConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('TimelineConfiguration') -export class TimelineConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class TimelineConfigurationDTO implements TimelineConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.TIMELINE]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/view-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/view-configuration.dto.ts index 76ae15683d..2a435b90fd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/view-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/view-configuration.dto.ts @@ -1,12 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type ViewConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('ViewConfiguration') -export class ViewConfigurationDTO implements PageLayoutWidgetConfigurationBase { +export class ViewConfigurationDTO implements ViewConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.VIEW]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-configuration.dto.ts index 30a25db23b..3d4f9a033a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type WorkflowConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('WorkflowConfiguration') -export class WorkflowConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class WorkflowConfigurationDTO implements WorkflowConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.WORKFLOW]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-run-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-run-configuration.dto.ts index ece2a5bd5c..e48c60479c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-run-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-run-configuration.dto.ts @@ -1,14 +1,12 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type WorkflowRunConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('WorkflowRunConfiguration') -export class WorkflowRunConfigurationDTO - implements PageLayoutWidgetConfigurationBase -{ +export class WorkflowRunConfigurationDTO implements WorkflowRunConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.WORKFLOW_RUN]) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-version-configuration.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-version-configuration.dto.ts index 4cb47c29e1..e5f906f75c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-version-configuration.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/workflow-version-configuration.dto.ts @@ -1,13 +1,13 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsIn, IsNotEmpty } from 'class-validator'; +import { type WorkflowVersionConfiguration } from 'twenty-shared/types'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; -import { PageLayoutWidgetConfigurationBase } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configurationt-base.type'; @ObjectType('WorkflowVersionConfiguration') export class WorkflowVersionConfigurationDTO - implements PageLayoutWidgetConfigurationBase + implements WorkflowVersionConfiguration { @Field(() => WidgetConfigurationType) @IsIn([WidgetConfigurationType.WORKFLOW_VERSION]) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity.ts index c398fa14df..0877ba93a1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity.ts @@ -3,6 +3,7 @@ import { ObjectType } from '@nestjs/graphql'; import { PageLayoutWidgetConditionalDisplay, PageLayoutWidgetPosition, + type GridPosition, } from 'twenty-shared/types'; import { Column, @@ -21,7 +22,6 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity'; import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum'; -import { type GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; import { PageLayoutWidgetConfigurationTypeSettings } from 'src/engine/metadata-modules/page-layout-widget/types/page-layout-widget-configuration.type'; import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/utils/validate-widget-grid-position.util.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/utils/validate-widget-grid-position.util.ts index 2106a71f04..1eaeeb1b17 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/utils/validate-widget-grid-position.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/utils/validate-widget-grid-position.util.ts @@ -1,4 +1,5 @@ import { msg } from '@lingui/core/macro'; +import { type GridPosition } from 'twenty-shared/types'; import { WIDGET_GRID_MAX_COLUMNS } from 'src/engine/metadata-modules/page-layout-widget/constants/widget-grid-max-columns.constant'; import { WIDGET_GRID_MAX_ROWS } from 'src/engine/metadata-modules/page-layout-widget/constants/widget-grid-max-rows.constant'; @@ -9,13 +10,6 @@ import { } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception'; import { type FlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; -type GridPosition = { - row: number; - column: number; - rowSpan: number; - columnSpan: number; -}; - // TODO: remove in favor of validatePageLayoutWidgetGridPosition once gridPosition is deprecated export const validateWidgetGridPosition = ( gridPosition: GridPosition, diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts index fe88fe43d3..022492832d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts @@ -503,7 +503,6 @@ export class PageLayoutUpdateService { flatFieldMetadataMaps.universalIdentifierById, viewFieldGroupUniversalIdentifierById: flatViewFieldGroupMaps.universalIdentifierById, - shouldThrowOnMissingIdentifier: true, }), }; }, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout-tabs.template.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout-tabs.template.ts index 99f4365305..723eff0235 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout-tabs.template.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout-tabs.template.ts @@ -4,10 +4,10 @@ import { type PageLayoutWidgetConditionalDisplay, type PageLayoutWidgetGridPosition, type PageLayoutWidgetVerticalListPosition, + type GridPosition, } from 'twenty-shared/types'; import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum'; -import { type GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; export const CONDITIONAL_DISPLAY_DEVICE_MOBILE = { and: [{ '===': [{ var: 'device' }, 'MOBILE'] }], diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-config/standard-page-layout-config.type.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-config/standard-page-layout-config.type.ts index 85d2f4a148..fae5edee31 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-config/standard-page-layout-config.type.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-config/standard-page-layout-config.type.ts @@ -2,10 +2,10 @@ import { type PageLayoutTabLayoutMode, type PageLayoutWidgetConditionalDisplay, type PageLayoutWidgetPosition, + type GridPosition, } from 'twenty-shared/types'; import { type WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum'; -import { type GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; import { type PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum'; export type StandardPageLayoutWidgetConfig = { diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/compute-my-first-dashboard-widgets.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/compute-my-first-dashboard-widgets.util.ts index 815855e15f..ee3496dd28 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/compute-my-first-dashboard-widgets.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/compute-my-first-dashboard-widgets.util.ts @@ -23,7 +23,7 @@ type DashboardWidgetBuilderArgs = Omit< 'context' >; -const createFilterConfig = ( +const createFilterConfigs = ( filters: Array<{ type: string; label: string; @@ -31,27 +31,44 @@ const createFilterConfig = ( displayValue: string; operand: string; fieldMetadataId: string; + fieldMetadataUniversalIdentifier: string; }>, ) => { const groupId = v4(); + const recordFilterGroups = [ + { + id: groupId, + logicalOperator: 'AND', + }, + ]; + return { - recordFilters: filters.map((filter) => ({ - id: v4(), - type: filter.type, - label: filter.label, - value: filter.value, - displayValue: filter.displayValue, - operand: filter.operand, - fieldMetadataId: filter.fieldMetadataId, - recordFilterGroupId: groupId, - })), - recordFilterGroups: [ - { - id: groupId, - logicalOperator: 'AND', - }, - ], + configuration: { + recordFilters: filters.map((filter) => ({ + type: filter.type, + label: filter.label, + value: filter.value, + displayValue: filter.displayValue, + operand: filter.operand, + fieldMetadataId: filter.fieldMetadataId, + recordFilterGroupId: groupId, + })), + recordFilterGroups, + }, + universal: { + recordFilters: filters.map((filter) => ({ + type: filter.type, + label: filter.label, + value: filter.value, + displayValue: filter.displayValue, + operand: filter.operand, + fieldMetadataUniversalIdentifier: + filter.fieldMetadataUniversalIdentifier, + recordFilterGroupId: groupId, + })), + recordFilterGroups, + }, }; }; @@ -562,7 +579,7 @@ const createDealsCreatedThisMonth = ({ const opportunityObjectId = args.standardObjectMetadataRelatedEntityIds.opportunity.id; - const filterConfig = createFilterConfig([ + const filterConfigs = createFilterConfigs([ { type: 'DATE_TIME', label: 'Creation date', @@ -570,6 +587,8 @@ const createDealsCreatedThisMonth = ({ displayValue: 'THIS_1_MONTH;;UTC;;SUNDAY;;', operand: 'IS_RELATIVE', fieldMetadataId: opportunityFields.createdAt.id, + fieldMetadataUniversalIdentifier: + STANDARD_OBJECTS.opportunity.fields.createdAt.universalIdentifier, }, ]); @@ -596,7 +615,7 @@ const createDealsCreatedThisMonth = ({ aggregateFieldMetadataId: opportunityFields.id.id, aggregateOperation: AggregateOperations.COUNT, displayDataLabel: false, - filter: filterConfig, + filter: filterConfigs.configuration, prefix: '', timezone: 'UTC', firstDayOfTheWeek: CalendarStartDay.SUNDAY, @@ -607,7 +626,7 @@ const createDealsCreatedThisMonth = ({ STANDARD_OBJECTS.opportunity.fields.id.universalIdentifier, aggregateOperation: AggregateOperations.COUNT, displayDataLabel: false, - filter: filterConfig, + filter: filterConfigs.universal, prefix: '', timezone: 'UTC', firstDayOfTheWeek: CalendarStartDay.SUNDAY, @@ -628,7 +647,7 @@ const createDealValueCreatedThisMonth = ({ const opportunityObjectId = args.standardObjectMetadataRelatedEntityIds.opportunity.id; - const filterConfig = createFilterConfig([ + const filterConfigs = createFilterConfigs([ { type: 'DATE_TIME', label: 'Creation date', @@ -636,6 +655,8 @@ const createDealValueCreatedThisMonth = ({ displayValue: 'THIS_1_MONTH;;UTC;;SUNDAY;;', operand: 'IS_RELATIVE', fieldMetadataId: opportunityFields.createdAt.id, + fieldMetadataUniversalIdentifier: + STANDARD_OBJECTS.opportunity.fields.createdAt.universalIdentifier, }, ]); @@ -662,7 +683,7 @@ const createDealValueCreatedThisMonth = ({ aggregateFieldMetadataId: opportunityFields.amount.id, aggregateOperation: AggregateOperations.SUM, displayDataLabel: false, - filter: filterConfig, + filter: filterConfigs.configuration, prefix: '$', timezone: 'UTC', firstDayOfTheWeek: CalendarStartDay.SUNDAY, @@ -673,7 +694,7 @@ const createDealValueCreatedThisMonth = ({ STANDARD_OBJECTS.opportunity.fields.amount.universalIdentifier, aggregateOperation: AggregateOperations.SUM, displayDataLabel: false, - filter: filterConfig, + filter: filterConfigs.universal, prefix: '$', timezone: 'UTC', firstDayOfTheWeek: CalendarStartDay.SUNDAY, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/create-standard-page-layout-widget-flat-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/create-standard-page-layout-widget-flat-metadata.util.ts index 6159bb0e7b..654628748c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/create-standard-page-layout-widget-flat-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/page-layout-widget/create-standard-page-layout-widget-flat-metadata.util.ts @@ -1,6 +1,7 @@ import { type PageLayoutWidgetConditionalDisplay, type PageLayoutWidgetPosition, + type GridPosition, } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; @@ -8,7 +9,6 @@ import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/fl import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type'; import { type WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum'; import { type AllPageLayoutWidgetConfiguration } from 'src/engine/metadata-modules/page-layout-widget/types/all-page-layout-widget-configuration.type'; -import { type GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; import { STANDARD_PAGE_LAYOUTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout.constant'; import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications'; import { type StandardObjectMetadataRelatedEntityIds } from 'src/engine/workspace-manager/twenty-standard-application/utils/get-standard-object-metadata-related-entity-ids.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts index 66baa798b2..5c52ee0005 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts @@ -5,21 +5,21 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; import { PageLayoutTabLayoutMode, PageLayoutWidgetPosition, + type GridPosition, } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; -import { type UniversalFlatPageLayoutTab } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout-tab.type'; import { FlatPageLayoutWidgetTypeValidatorService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service'; import { PageLayoutTabExceptionCode } from 'src/engine/metadata-modules/page-layout-tab/exceptions/page-layout-tab.exception'; import { GraphType } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-type.enum'; 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 { GridPosition } from 'src/engine/metadata-modules/page-layout-widget/types/grid-position.type'; import { validatePageLayoutWidgetGridPosition } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-page-layout-widget-grid-position.util'; import { validatePageLayoutWidgetVerticalListPosition } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-page-layout-widget-vertical-list-position.util'; import { validateWidgetGridPosition } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-widget-grid-position.util'; +import { type UniversalFlatPageLayoutTab } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout-tab.type'; import { FailedFlatEntityValidation, FlatEntityValidationError, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout-widget/services/utils/from-universal-configuration-to-flat-page-layout-widget-configuration.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout-widget/services/utils/from-universal-configuration-to-flat-page-layout-widget-configuration.util.ts index 599359832c..d372c37477 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout-widget/services/utils/from-universal-configuration-to-flat-page-layout-widget-configuration.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout-widget/services/utils/from-universal-configuration-to-flat-page-layout-widget-configuration.util.ts @@ -1,3 +1,7 @@ +import { + type ChartFilter, + type UniversalChartFilter, +} from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { @@ -38,6 +42,31 @@ const resolveFieldMetadataIdOrThrow = ({ return flatFieldMetadata.id; }; +const convertUniversalFilterToChartFilter = ({ + filter, + flatFieldMetadataMaps, +}: { + filter: UniversalChartFilter | undefined; + flatFieldMetadataMaps: MetadataFlatEntityMaps<'fieldMetadata'>; +}): ChartFilter | undefined => { + if (!isDefined(filter)) { + return undefined; + } + + return { + ...filter, + recordFilters: filter.recordFilters?.map( + ({ fieldMetadataUniversalIdentifier, ...rest }) => ({ + ...rest, + fieldMetadataId: resolveFieldMetadataIdOrThrow({ + fieldMetadataUniversalIdentifier, + flatFieldMetadataMaps, + }), + }), + ), + }; +}; + export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ universalConfiguration, flatFieldMetadataMaps, @@ -54,6 +83,7 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ const { aggregateFieldMetadataUniversalIdentifier, ratioAggregateConfig: universalRatioAggregateConfig, + filter, ...rest } = universalConfiguration; @@ -78,11 +108,15 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ ...rest, aggregateFieldMetadataId, ratioAggregateConfig, + filter: convertUniversalFilterToChartFilter({ + filter, + flatFieldMetadataMaps, + }), }; } case WidgetConfigurationType.GAUGE_CHART: { - const { aggregateFieldMetadataUniversalIdentifier, ...rest } = + const { aggregateFieldMetadataUniversalIdentifier, filter, ...rest } = universalConfiguration; const aggregateFieldMetadataId = resolveFieldMetadataIdOrThrow({ @@ -94,6 +128,10 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ return { ...rest, aggregateFieldMetadataId, + filter: convertUniversalFilterToChartFilter({ + filter, + flatFieldMetadataMaps, + }), }; } @@ -101,6 +139,7 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ const { aggregateFieldMetadataUniversalIdentifier, groupByFieldMetadataUniversalIdentifier, + filter, ...rest } = universalConfiguration; @@ -120,6 +159,10 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ ...rest, aggregateFieldMetadataId, groupByFieldMetadataId, + filter: convertUniversalFilterToChartFilter({ + filter, + flatFieldMetadataMaps, + }), }; } @@ -128,6 +171,7 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ aggregateFieldMetadataUniversalIdentifier, primaryAxisGroupByFieldMetadataUniversalIdentifier, secondaryAxisGroupByFieldMetadataUniversalIdentifier, + filter, ...rest } = universalConfiguration; @@ -158,6 +202,10 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId, secondaryAxisGroupByFieldMetadataId, + filter: convertUniversalFilterToChartFilter({ + filter, + flatFieldMetadataMaps, + }), }; } @@ -166,6 +214,7 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ aggregateFieldMetadataUniversalIdentifier, primaryAxisGroupByFieldMetadataUniversalIdentifier, secondaryAxisGroupByFieldMetadataUniversalIdentifier, + filter, ...rest } = universalConfiguration; @@ -196,6 +245,10 @@ export const fromUniversalConfigurationToFlatPageLayoutWidgetConfiguration = ({ aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId, secondaryAxisGroupByFieldMetadataId, + filter: convertUniversalFilterToChartFilter({ + filter, + flatFieldMetadataMaps, + }), }; } diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts index e8d2d65864..715f89d672 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { CalendarStartDay } from 'twenty-shared/constants'; import { AggregateOperations, + type ChartFilter, ObjectRecordGroupByDateGranularity, OrderByWithGroupBy, } from 'twenty-shared/types'; @@ -20,7 +21,6 @@ import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/fl import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum'; -import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; import { GRAPH_DEFAULT_DATE_GRANULARITY } from 'src/modules/dashboard/chart-data/constants/graph-default-date-granularity.constant'; import { GRAPH_DEFAULT_ORDER_BY } from 'src/modules/dashboard/chart-data/constants/graph-default-order-by.constant'; import { diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts b/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts index 1a976c9300..fefb97fe49 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts @@ -1,4 +1,5 @@ import { + type ChartFilter, type CompositeFieldSubFieldName, type FilterableAndTSVectorFieldType, type PartialFieldMetadataItem, @@ -14,11 +15,10 @@ import { import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface'; -import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; -import { type ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type'; type ConvertChartFilterToGqlOperationFilterParams = { filter: ChartFilter | undefined; @@ -72,7 +72,7 @@ export const convertChartFilterToGqlOperationFilter = ({ }) .filter(isDefined); - const convertedRecordFilters: RecordFilter[] = recordFilters.map( + const convertedRecordFilters: Omit[] = recordFilters.map( (recordFilter) => { const field = findFlatEntityByIdInFlatEntityMaps({ flatEntityId: recordFilter.fieldMetadataId, @@ -80,7 +80,6 @@ export const convertChartFilterToGqlOperationFilter = ({ }); return { - id: recordFilter.id, fieldMetadataId: recordFilter.fieldMetadataId, value: recordFilter.value ?? '', type: (field?.type ?? diff --git a/packages/twenty-shared/src/application/pageLayoutManifestType.ts b/packages/twenty-shared/src/application/pageLayoutManifestType.ts index 7ee28f55fb..9d74408150 100644 --- a/packages/twenty-shared/src/application/pageLayoutManifestType.ts +++ b/packages/twenty-shared/src/application/pageLayoutManifestType.ts @@ -2,8 +2,7 @@ import { type SyncableEntityOptions } from '@/application/syncableEntityOptionsT import { type PageLayoutTabLayoutMode, type PageLayoutWidgetConditionalDisplay, - type PageLayoutWidgetPosition, - type PageLayoutWidgetUniversalConfiguration, + type PageLayoutWidgetUniversalConfiguration } from '@/types'; export type PageLayoutWidgetManifest = SyncableEntityOptions & { @@ -11,7 +10,6 @@ export type PageLayoutWidgetManifest = SyncableEntityOptions & { type: string; objectUniversalIdentifier?: string; conditionalDisplay?: PageLayoutWidgetConditionalDisplay; - position?: PageLayoutWidgetPosition; configuration: PageLayoutWidgetUniversalConfiguration; }; diff --git a/packages/twenty-shared/src/types/index.ts b/packages/twenty-shared/src/types/index.ts index f23eb9fee6..90339dda26 100644 --- a/packages/twenty-shared/src/types/index.ts +++ b/packages/twenty-shared/src/types/index.ts @@ -137,6 +137,37 @@ export { ObjectRecordGroupByDateGranularity } from './ObjectRecordGroupByDateGra export type { ObjectsPermissions } from './ObjectsPermissions'; export type { ObjectsPermissionsByRoleId } from './ObjectsPermissionsByRoleId'; export type { OrderBy } from './OrderBy'; +export type { + ChartRecordFilter, + ChartRecordFilterGroup, + ChartFilter, + UniversalChartFilter, +} from './page-layout/chart-filter.type'; +export type { GridPosition } from './page-layout/grid-position.type'; +export type { + AggregateChartConfiguration, + GaugeChartConfiguration, + PieChartConfiguration, + BarChartConfiguration, + LineChartConfiguration, + ViewConfiguration, + FieldConfiguration, + FieldsConfiguration, + FieldRichTextConfiguration, + StandaloneRichTextConfiguration, + IframeConfiguration, + FrontComponentConfiguration, + TimelineConfiguration, + TasksConfiguration, + NotesConfiguration, + FilesConfiguration, + EmailsConfiguration, + CalendarConfiguration, + WorkflowConfiguration, + WorkflowVersionConfiguration, + WorkflowRunConfiguration, + PageLayoutWidgetConfiguration, +} from './page-layout/page-layout-widget-configuration.type'; export type { PageLayoutWidgetGridPosition, PageLayoutWidgetVerticalListPosition, @@ -146,6 +177,7 @@ export type { export type { PageLayoutWidgetUniversalConfiguration } from './page-layout/page-layout-widget-universal-configuration.type'; export { PageLayoutTabLayoutMode } from './page-layout/PageLayoutTabLayoutMode'; export type { PageLayoutWidgetConditionalDisplay } from './page-layout/PageLayoutWidgetConditionalDisplay'; +export type { RatioAggregateConfig } from './page-layout/ratio-aggregate-config.type'; export type { PartialFieldMetadataItem } from './PartialFieldMetadataItem'; export type { PartialFieldMetadataItemOption } from './PartialFieldMetadataOption'; export type { QueryCursorDirection } from './QueryCursorDirection'; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/types/chart-filter.type.ts b/packages/twenty-shared/src/types/page-layout/chart-filter.type.ts similarity index 56% rename from packages/twenty-server/src/engine/metadata-modules/page-layout-widget/types/chart-filter.type.ts rename to packages/twenty-shared/src/types/page-layout/chart-filter.type.ts index 0603a95900..94c693f599 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/types/chart-filter.type.ts +++ b/packages/twenty-shared/src/types/page-layout/chart-filter.type.ts @@ -1,6 +1,8 @@ +import { type FormatRecordSerializedRelationProperties } from '../FormatRecordSerializedRelationProperties.type'; +import { type SerializedRelation } from '../SerializedRelation.type'; + export type ChartRecordFilter = { - id: string; - fieldMetadataId: string; + fieldMetadataId: SerializedRelation; operand: string; value?: string | null; type?: string; @@ -18,3 +20,6 @@ export type ChartFilter = { recordFilters?: ChartRecordFilter[]; recordFilterGroups?: ChartRecordFilterGroup[]; }; + +export type UniversalChartFilter = + FormatRecordSerializedRelationProperties; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/types/grid-position.type.ts b/packages/twenty-shared/src/types/page-layout/grid-position.type.ts similarity index 100% rename from packages/twenty-server/src/engine/metadata-modules/page-layout-widget/types/grid-position.type.ts rename to packages/twenty-shared/src/types/page-layout/grid-position.type.ts diff --git a/packages/twenty-shared/src/types/page-layout/page-layout-widget-configuration.type.ts b/packages/twenty-shared/src/types/page-layout/page-layout-widget-configuration.type.ts new file mode 100644 index 0000000000..a77b6104c6 --- /dev/null +++ b/packages/twenty-shared/src/types/page-layout/page-layout-widget-configuration.type.ts @@ -0,0 +1,188 @@ +import { type AggregateOperations } from '../AggregateOperations'; +import { type ObjectRecordGroupByDateGranularity } from '../ObjectRecordGroupByDateGranularity'; +import { type SerializedRelation } from '../SerializedRelation.type'; + +import { type ChartFilter } from './chart-filter.type'; +import { type RatioAggregateConfig } from './ratio-aggregate-config.type'; + +type BaseChartConfiguration = { + aggregateFieldMetadataId: SerializedRelation; + aggregateOperation: AggregateOperations; + displayDataLabel?: boolean; + description?: string; + color?: string; + filter?: ChartFilter; + timezone?: string; + firstDayOfTheWeek?: number; +}; + +export type AggregateChartConfiguration = BaseChartConfiguration & { + configurationType: 'AGGREGATE_CHART'; + label?: string; + format?: string; + prefix?: string; + suffix?: string; + ratioAggregateConfig?: RatioAggregateConfig; +}; + +export type GaugeChartConfiguration = BaseChartConfiguration & { + configurationType: 'GAUGE_CHART'; +}; + +export type PieChartConfiguration = BaseChartConfiguration & { + configurationType: 'PIE_CHART'; + groupByFieldMetadataId: SerializedRelation; + groupBySubFieldName?: string; + dateGranularity?: ObjectRecordGroupByDateGranularity; + orderBy?: string; + manualSortOrder?: string[]; + showCenterMetric?: boolean; + displayLegend?: boolean; + hideEmptyCategory?: boolean; + splitMultiValueFields?: boolean; +}; + +export type BarChartConfiguration = BaseChartConfiguration & { + configurationType: 'BAR_CHART'; + primaryAxisGroupByFieldMetadataId: SerializedRelation; + primaryAxisGroupBySubFieldName?: string; + primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity; + primaryAxisOrderBy?: string; + primaryAxisManualSortOrder?: string[]; + secondaryAxisGroupByFieldMetadataId?: SerializedRelation; + secondaryAxisGroupBySubFieldName?: string; + secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity; + secondaryAxisOrderBy?: string; + secondaryAxisManualSortOrder?: string[]; + omitNullValues?: boolean; + splitMultiValueFields?: boolean; + axisNameDisplay?: string; + displayLegend?: boolean; + rangeMin?: number; + rangeMax?: number; + groupMode?: string; + layout?: string; + isCumulative?: boolean; +}; + +export type LineChartConfiguration = BaseChartConfiguration & { + configurationType: 'LINE_CHART'; + primaryAxisGroupByFieldMetadataId: SerializedRelation; + primaryAxisGroupBySubFieldName?: string; + primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity; + primaryAxisOrderBy?: string; + primaryAxisManualSortOrder?: string[]; + secondaryAxisGroupByFieldMetadataId?: SerializedRelation; + secondaryAxisGroupBySubFieldName?: string; + secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity; + secondaryAxisOrderBy?: string; + secondaryAxisManualSortOrder?: string[]; + omitNullValues?: boolean; + splitMultiValueFields?: boolean; + axisNameDisplay?: string; + displayLegend?: boolean; + rangeMin?: number; + rangeMax?: number; + isStacked?: boolean; + isCumulative?: boolean; +}; + +export type ViewConfiguration = { + configurationType: 'VIEW'; +}; + +export type FieldConfiguration = { + configurationType: 'FIELD'; +}; + +type NewFieldDefaultConfiguration = { + isVisible: boolean; + viewFieldGroupId: string | null; +}; + +export type FieldsConfiguration = { + configurationType: 'FIELDS'; + viewId?: string | null; + newFieldDefaultConfiguration?: NewFieldDefaultConfiguration | null; +}; + +export type FieldRichTextConfiguration = { + configurationType: 'FIELD_RICH_TEXT'; +}; + +export type StandaloneRichTextConfiguration = { + configurationType: 'STANDALONE_RICH_TEXT'; + body: { + blocknote?: string | null; + markdown: string | null; + }; +}; + +export type IframeConfiguration = { + configurationType: 'IFRAME'; + url?: string; +}; + +export type FrontComponentConfiguration = { + configurationType: 'FRONT_COMPONENT'; + frontComponentId: string; +}; + +export type TimelineConfiguration = { + configurationType: 'TIMELINE'; +}; + +export type TasksConfiguration = { + configurationType: 'TASKS'; +}; + +export type NotesConfiguration = { + configurationType: 'NOTES'; +}; + +export type FilesConfiguration = { + configurationType: 'FILES'; +}; + +export type EmailsConfiguration = { + configurationType: 'EMAILS'; +}; + +export type CalendarConfiguration = { + configurationType: 'CALENDAR'; +}; + +export type WorkflowConfiguration = { + configurationType: 'WORKFLOW'; +}; + +export type WorkflowVersionConfiguration = { + configurationType: 'WORKFLOW_VERSION'; +}; + +export type WorkflowRunConfiguration = { + configurationType: 'WORKFLOW_RUN'; +}; + +export type PageLayoutWidgetConfiguration = + | AggregateChartConfiguration + | GaugeChartConfiguration + | PieChartConfiguration + | BarChartConfiguration + | LineChartConfiguration + | ViewConfiguration + | FieldConfiguration + | FieldsConfiguration + | FieldRichTextConfiguration + | StandaloneRichTextConfiguration + | IframeConfiguration + | FrontComponentConfiguration + | TimelineConfiguration + | TasksConfiguration + | NotesConfiguration + | FilesConfiguration + | EmailsConfiguration + | CalendarConfiguration + | WorkflowConfiguration + | WorkflowVersionConfiguration + | WorkflowRunConfiguration; diff --git a/packages/twenty-shared/src/types/page-layout/page-layout-widget-universal-configuration.type.ts b/packages/twenty-shared/src/types/page-layout/page-layout-widget-universal-configuration.type.ts index 3999e24bdc..b61e0f2192 100644 --- a/packages/twenty-shared/src/types/page-layout/page-layout-widget-universal-configuration.type.ts +++ b/packages/twenty-shared/src/types/page-layout/page-layout-widget-universal-configuration.type.ts @@ -1,207 +1,6 @@ -import { type AggregateOperations } from '../AggregateOperations'; +import { type FormatRecordSerializedRelationProperties } from '../FormatRecordSerializedRelationProperties.type'; -type ChartFilterRecordFilter = { - id: string; - fieldMetadataUniversalIdentifier: string; - operand: string; - value?: string | null; - type?: string; - recordFilterGroupId?: string | null; - subFieldName?: string | null; -}; - -type ChartFilterRecordFilterGroup = { - id: string; - logicalOperator: string; - parentRecordFilterGroupId?: string | null; -}; - -type UniversalChartFilter = { - recordFilters?: ChartFilterRecordFilter[]; - recordFilterGroups?: ChartFilterRecordFilterGroup[]; -}; - -type RatioAggregateConfig = { - fieldMetadataUniversalIdentifier: string | null; - optionValue: string; -}; - -type BaseChartFields = { - aggregateFieldMetadataUniversalIdentifier: string | null; - aggregateOperation: AggregateOperations; - displayDataLabel?: boolean; - description?: string; - color?: string; - filter?: UniversalChartFilter; - timezone?: string; - firstDayOfTheWeek?: number; -}; - -type AggregateChartUniversalConfiguration = BaseChartFields & { - configurationType: 'AGGREGATE_CHART'; - label?: string; - format?: string; - prefix?: string; - suffix?: string; - ratioAggregateConfig?: RatioAggregateConfig; -}; - -type GaugeChartUniversalConfiguration = BaseChartFields & { - configurationType: 'GAUGE_CHART'; -}; - -type PieChartUniversalConfiguration = BaseChartFields & { - configurationType: 'PIE_CHART'; - groupByFieldMetadataUniversalIdentifier: string | null; - groupBySubFieldName?: string; - dateGranularity?: string; - orderBy?: string; - manualSortOrder?: string[]; - showCenterMetric?: boolean; - displayLegend?: boolean; - hideEmptyCategory?: boolean; - splitMultiValueFields?: boolean; -}; - -type BarChartUniversalConfiguration = BaseChartFields & { - configurationType: 'BAR_CHART'; - primaryAxisGroupByFieldMetadataUniversalIdentifier: string | null; - primaryAxisGroupBySubFieldName?: string; - primaryAxisDateGranularity?: string; - primaryAxisOrderBy?: string; - primaryAxisManualSortOrder?: string[]; - secondaryAxisGroupByFieldMetadataUniversalIdentifier?: string | null; - secondaryAxisGroupBySubFieldName?: string; - secondaryAxisGroupByDateGranularity?: string; - secondaryAxisOrderBy?: string; - secondaryAxisManualSortOrder?: string[]; - omitNullValues?: boolean; - splitMultiValueFields?: boolean; - axisNameDisplay?: string; - displayLegend?: boolean; - rangeMin?: number; - rangeMax?: number; - groupMode?: string; - layout?: string; - isCumulative?: boolean; -}; - -type LineChartUniversalConfiguration = BaseChartFields & { - configurationType: 'LINE_CHART'; - primaryAxisGroupByFieldMetadataUniversalIdentifier: string | null; - primaryAxisGroupBySubFieldName?: string; - primaryAxisDateGranularity?: string; - primaryAxisOrderBy?: string; - primaryAxisManualSortOrder?: string[]; - secondaryAxisGroupByFieldMetadataUniversalIdentifier?: string | null; - secondaryAxisGroupBySubFieldName?: string; - secondaryAxisGroupByDateGranularity?: string; - secondaryAxisOrderBy?: string; - secondaryAxisManualSortOrder?: string[]; - omitNullValues?: boolean; - splitMultiValueFields?: boolean; - axisNameDisplay?: string; - displayLegend?: boolean; - rangeMin?: number; - rangeMax?: number; - isStacked?: boolean; - isCumulative?: boolean; -}; - -type ViewUniversalConfiguration = { - configurationType: 'VIEW'; -}; - -type FieldUniversalConfiguration = { - configurationType: 'FIELD'; -}; - -type FieldsUniversalConfiguration = { - configurationType: 'FIELDS'; - viewId?: string | null; - newFieldDefaultConfiguration?: { - isVisible: boolean; - viewFieldGroupId: string | null; - } | null; -}; - -type FieldRichTextUniversalConfiguration = { - configurationType: 'FIELD_RICH_TEXT'; -}; - -type StandaloneRichTextUniversalConfiguration = { - configurationType: 'STANDALONE_RICH_TEXT'; - body: { - blocknote?: string | null; - markdown: string | null; - }; -}; - -type IframeUniversalConfiguration = { - configurationType: 'IFRAME'; - url?: string; -}; - -type FrontComponentUniversalConfiguration = { - configurationType: 'FRONT_COMPONENT'; - frontComponentId: string; -}; - -type TimelineUniversalConfiguration = { - configurationType: 'TIMELINE'; -}; - -type TasksUniversalConfiguration = { - configurationType: 'TASKS'; -}; - -type NotesUniversalConfiguration = { - configurationType: 'NOTES'; -}; - -type FilesUniversalConfiguration = { - configurationType: 'FILES'; -}; - -type EmailsUniversalConfiguration = { - configurationType: 'EMAILS'; -}; - -type CalendarUniversalConfiguration = { - configurationType: 'CALENDAR'; -}; - -type WorkflowUniversalConfiguration = { - configurationType: 'WORKFLOW'; -}; - -type WorkflowVersionUniversalConfiguration = { - configurationType: 'WORKFLOW_VERSION'; -}; - -type WorkflowRunUniversalConfiguration = { - configurationType: 'WORKFLOW_RUN'; -}; +import { type PageLayoutWidgetConfiguration } from './page-layout-widget-configuration.type'; export type PageLayoutWidgetUniversalConfiguration = - | AggregateChartUniversalConfiguration - | GaugeChartUniversalConfiguration - | PieChartUniversalConfiguration - | BarChartUniversalConfiguration - | LineChartUniversalConfiguration - | ViewUniversalConfiguration - | FieldUniversalConfiguration - | FieldsUniversalConfiguration - | FieldRichTextUniversalConfiguration - | StandaloneRichTextUniversalConfiguration - | IframeUniversalConfiguration - | FrontComponentUniversalConfiguration - | TimelineUniversalConfiguration - | TasksUniversalConfiguration - | NotesUniversalConfiguration - | FilesUniversalConfiguration - | EmailsUniversalConfiguration - | CalendarUniversalConfiguration - | WorkflowUniversalConfiguration - | WorkflowVersionUniversalConfiguration - | WorkflowRunUniversalConfiguration; + FormatRecordSerializedRelationProperties; diff --git a/packages/twenty-shared/src/types/page-layout/ratio-aggregate-config.type.ts b/packages/twenty-shared/src/types/page-layout/ratio-aggregate-config.type.ts new file mode 100644 index 0000000000..25b12824fe --- /dev/null +++ b/packages/twenty-shared/src/types/page-layout/ratio-aggregate-config.type.ts @@ -0,0 +1,6 @@ +import { type SerializedRelation } from '../SerializedRelation.type'; + +export type RatioAggregateConfig = { + fieldMetadataId: SerializedRelation; + optionValue: string; +}; diff --git a/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts index 82baec7cb4..e88436986b 100644 --- a/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts +++ b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts @@ -15,7 +15,7 @@ export const computeGqlOperationFilterForEmails = ({ correspondingFieldMetadataItem, subFieldName, }: { - recordFilter: RecordFilter; + recordFilter: Omit; correspondingFieldMetadataItem: Pick< PartialFieldMetadataItem, 'name' | 'type' diff --git a/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts index d082907b75..b7e0b0c879 100644 --- a/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts +++ b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts @@ -13,7 +13,7 @@ export const computeGqlOperationFilterForLinks = ({ correspondingFieldMetadataItem, subFieldName, }: { - recordFilter: RecordFilter; + recordFilter: Omit; correspondingFieldMetadataItem: Pick< PartialFieldMetadataItem, 'name' | 'type' diff --git a/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts index ffcc4730c2..eefcc65cad 100644 --- a/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts +++ b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts @@ -12,7 +12,7 @@ export const computeEmptyGqlOperationFilterForEmails = ({ recordFilter, correspondingFieldMetadataItem, }: { - recordFilter: RecordFilter; + recordFilter: Omit; correspondingFieldMetadataItem: Pick< PartialFieldMetadataItem, 'name' | 'type' diff --git a/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts index f5e5a8c4f4..7e080d1c97 100644 --- a/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts +++ b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts @@ -12,7 +12,7 @@ export const computeEmptyGqlOperationFilterForLinks = ({ recordFilter, correspondingFieldMetadataItem, }: { - recordFilter: RecordFilter; + recordFilter: Omit; correspondingFieldMetadataItem: Pick; }): RecordGqlOperationFilter => { const subFieldName = recordFilter.subFieldName; diff --git a/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts index 7eef2b4654..63980d3779 100644 --- a/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts @@ -17,7 +17,7 @@ export const computeRecordGqlOperationFilter = ({ recordFilterGroups, filterValueDependencies, }: { - recordFilters: RecordFilter[]; + recordFilters: Omit[]; fields: PartialFieldMetadataItem[]; recordFilterGroups: RecordFilterGroup[]; filterValueDependencies: RecordFilterValueDependencies; diff --git a/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts index 9f88d1fd91..4539474330 100644 --- a/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts @@ -35,7 +35,7 @@ export const turnRecordFilterGroupsIntoGqlOperationFilter = ({ currentRecordFilterGroupId, }: { filterValueDependencies: RecordFilterValueDependencies; - filters: RecordFilter[]; + filters: Omit[]; fields: PartialFieldMetadataItem[]; recordFilterGroups: RecordFilterGroup[]; currentRecordFilterGroupId?: string; diff --git a/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts index 93a3675b55..104d848a6a 100644 --- a/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts @@ -63,7 +63,7 @@ type FieldShared = { type TurnRecordFilterIntoRecordGqlOperationFilterParams = { filterValueDependencies: RecordFilterValueDependencies; - recordFilter: RecordFilter; + recordFilter: Omit; fieldMetadataItems: FieldShared[]; }; diff --git a/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts index 46a0d32155..56d45e6c6c 100644 --- a/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts @@ -27,7 +27,7 @@ import { isNonEmptyString } from '@sniptt/guards'; type GetEmptyRecordGqlOperationFilterParams = { operand: ViewFilterOperand; correspondingField: Pick; - recordFilter: RecordFilter; + recordFilter: Omit; }; export const getEmptyRecordGqlOperationFilter = ({