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:
@@ -10,7 +10,6 @@ export default definePageLayout({
|
||||
{
|
||||
universalIdentifier: '${uuidv4()}',
|
||||
title: 'Overview',
|
||||
position: 0,
|
||||
widgets: [],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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';
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+71
-5
@@ -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<Record<string, string>>;
|
||||
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,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -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])
|
||||
|
||||
+7
-6
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-2
@@ -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])
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-2
@@ -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])
|
||||
|
||||
+7
-6
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+1
-2
@@ -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 {
|
||||
|
||||
+7
-6
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+7
-6
@@ -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()
|
||||
|
||||
+5
-2
@@ -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()
|
||||
|
||||
+2
-2
@@ -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])
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-2
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-4
@@ -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()
|
||||
|
||||
+2
-2
@@ -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])
|
||||
|
||||
+1
-1
@@ -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';
|
||||
|
||||
+1
-7
@@ -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,
|
||||
|
||||
-1
@@ -503,7 +503,6 @@ export class PageLayoutUpdateService {
|
||||
flatFieldMetadataMaps.universalIdentifierById,
|
||||
viewFieldGroupUniversalIdentifierById:
|
||||
flatViewFieldGroupMaps.universalIdentifierById,
|
||||
shouldThrowOnMissingIdentifier: true,
|
||||
}),
|
||||
};
|
||||
},
|
||||
|
||||
+1
-1
@@ -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'] }],
|
||||
|
||||
+1
-1
@@ -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 = {
|
||||
|
||||
+44
-23
@@ -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,
|
||||
|
||||
+1
-1
@@ -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';
|
||||
|
||||
+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,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+3
-4
@@ -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<RecordFilter, 'id'>[] = 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 ??
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
+7
-2
@@ -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<ChartFilter>;
|
||||
+188
@@ -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;
|
||||
+3
-204
@@ -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<PageLayoutWidgetConfiguration>;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { type SerializedRelation } from '../SerializedRelation.type';
|
||||
|
||||
export type RatioAggregateConfig = {
|
||||
fieldMetadataId: SerializedRelation;
|
||||
optionValue: string;
|
||||
};
|
||||
+1
-1
@@ -15,7 +15,7 @@ export const computeGqlOperationFilterForEmails = ({
|
||||
correspondingFieldMetadataItem,
|
||||
subFieldName,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
correspondingFieldMetadataItem: Pick<
|
||||
PartialFieldMetadataItem,
|
||||
'name' | 'type'
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ export const computeGqlOperationFilterForLinks = ({
|
||||
correspondingFieldMetadataItem,
|
||||
subFieldName,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
correspondingFieldMetadataItem: Pick<
|
||||
PartialFieldMetadataItem,
|
||||
'name' | 'type'
|
||||
|
||||
@@ -12,7 +12,7 @@ export const computeEmptyGqlOperationFilterForEmails = ({
|
||||
recordFilter,
|
||||
correspondingFieldMetadataItem,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
correspondingFieldMetadataItem: Pick<
|
||||
PartialFieldMetadataItem,
|
||||
'name' | 'type'
|
||||
|
||||
@@ -12,7 +12,7 @@ export const computeEmptyGqlOperationFilterForLinks = ({
|
||||
recordFilter,
|
||||
correspondingFieldMetadataItem,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
correspondingFieldMetadataItem: Pick<PartialFieldMetadataItem, 'name'>;
|
||||
}): RecordGqlOperationFilter => {
|
||||
const subFieldName = recordFilter.subFieldName;
|
||||
|
||||
@@ -17,7 +17,7 @@ export const computeRecordGqlOperationFilter = ({
|
||||
recordFilterGroups,
|
||||
filterValueDependencies,
|
||||
}: {
|
||||
recordFilters: RecordFilter[];
|
||||
recordFilters: Omit<RecordFilter, 'id'>[];
|
||||
fields: PartialFieldMetadataItem[];
|
||||
recordFilterGroups: RecordFilterGroup[];
|
||||
filterValueDependencies: RecordFilterValueDependencies;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export const turnRecordFilterGroupsIntoGqlOperationFilter = ({
|
||||
currentRecordFilterGroupId,
|
||||
}: {
|
||||
filterValueDependencies: RecordFilterValueDependencies;
|
||||
filters: RecordFilter[];
|
||||
filters: Omit<RecordFilter, 'id'>[];
|
||||
fields: PartialFieldMetadataItem[];
|
||||
recordFilterGroups: RecordFilterGroup[];
|
||||
currentRecordFilterGroupId?: string;
|
||||
|
||||
@@ -63,7 +63,7 @@ type FieldShared = {
|
||||
|
||||
type TurnRecordFilterIntoRecordGqlOperationFilterParams = {
|
||||
filterValueDependencies: RecordFilterValueDependencies;
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
fieldMetadataItems: FieldShared[];
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { isNonEmptyString } from '@sniptt/guards';
|
||||
type GetEmptyRecordGqlOperationFilterParams = {
|
||||
operand: ViewFilterOperand;
|
||||
correspondingField: Pick<PartialFieldMetadataItem, 'id' | 'name' | 'type'>;
|
||||
recordFilter: RecordFilter;
|
||||
recordFilter: Omit<RecordFilter, 'id'>;
|
||||
};
|
||||
|
||||
export const getEmptyRecordGqlOperationFilter = ({
|
||||
|
||||
Reference in New Issue
Block a user