Refactor page layout types (#18042)
## Refactor page layout widget types into shared package and expose from SDK ### Why Widget configuration types were defined only on the server, forcing SDK consumer apps to import from deep internal `twenty-shared/dist` paths — fragile and breaks on structural changes. Server DTOs also had no compile-time guarantee they matched the canonical types. ### What changed - **`twenty-shared`**: Migrated `ChartFilter`, `GridPosition`, `RatioAggregateConfig` and all 20 widget configuration variants into `twenty-shared/types`. `PageLayoutWidgetConfiguration` (base, with `SerializedRelation`) and `PageLayoutWidgetUniversalConfiguration` (derived via `FormatRecordSerializedRelationProperties`) are now the single source of truth. - **`twenty-sdk`**: Re-exported `AggregateOperations`, `ObjectRecordGroupByDateGranularity`, `PageLayoutTabLayoutMode`, and `PageLayoutWidgetUniversalConfiguration` so consumer apps import from `twenty-sdk` directly. - **`twenty-server`**: All widget DTOs now `implements` their shared type for compile-time enforcement. Added helpers to convert nested `fieldMetadataId` ↔ `fieldMetadataUniversalIdentifier` inside chart filters. Removed redundant local type re-exports.
This commit is contained in:
+2
-2
@@ -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,
|
||||
|
||||
+54
-1
@@ -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,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user