Files
twenty/packages/twenty-server/test/integration/constants/page-layout-gql-fields.constants.ts
T
nitin 436084f8f4 Split bar graph into two distinct horizontal and vertical bars (#15061)
### Summary

Split BAR into VERTICAL_BAR and HORIZONTAL_BAR as separate chart types.

### The Problem

Initially wanted a simple vertical/horizontal toggle for bar charts, but
ran into a GraphQL union type
constraint: union types can't have the same field name with different
nullability.

- Vertical bars need groupByFieldMetadataIdX as required (categories on
X)
- Horizontal bars need groupByFieldMetadataIdY as required (categories
on Y)
  - GraphQL schema generation fails with this setup

### The Solution

Use semantic primaryAxis and secondaryAxis naming that's
orientation-agnostic:

- primaryAxisGroupByFieldMetadataId = main grouping field (e.g.,
"Company Name")
- secondaryAxisGroupByFieldMetadataId = optional secondary grouping
(e.g., "Stage")

These fields have consistent meaning regardless of orientation. The
visual mapping happens at the UI layer:
  - Vertical bars: primary data renders on X-axis, secondary on Y-axis
  - Horizontal bars: primary data renders on Y-axis, secondary on X-axis

Both chart types share the same DTO structure with consistent
nullability.

### What Changed

  - Split GraphType.BAR → VERTICAL_BAR | HORIZONTAL_BAR
- Renamed fields: primaryAxisGroupByFieldMetadataId,
secondaryAxisGroupByFieldMetadataId (+ subfield
  variants)
- useChartSettingsValues(): Maps semantic fields to setting values (no
swapping)
- getBarChartSettings(): Dynamically arranges settings panel based on
orientation
- transformGroupByDataToBarChartData(): Maps semantic fields to Nivo's
layout prop
  
  video QA
  

https://github.com/user-attachments/assets/479061b5-712e-4ca6-9858-95273d1f16c1
2025-10-15 11:38:48 +02:00

111 lines
1.9 KiB
TypeScript

export const PAGE_LAYOUT_GQL_FIELDS = `
id
name
type
objectMetadataId
createdAt
updatedAt
deletedAt
`;
export const PAGE_LAYOUT_TAB_GQL_FIELDS = `
id
title
position
pageLayoutId
createdAt
updatedAt
deletedAt
`;
export const PAGE_LAYOUT_WIDGET_CONFIGURATION_FIELDS = `
... on IframeConfiguration {
url
}
... on BarChartConfiguration {
graphType
aggregateFieldMetadataId
aggregateOperation
primaryAxisGroupByFieldMetadataId
primaryAxisGroupBySubFieldName
primaryAxisOrderBy
secondaryAxisGroupByFieldMetadataId
secondaryAxisGroupBySubFieldName
secondaryAxisOrderBy
omitNullValues
axisNameDisplay
displayDataLabel
rangeMin
rangeMax
filter
color
description
}
... on LineChartConfiguration {
graphType
aggregateFieldMetadataId
aggregateOperation
primaryAxisGroupByFieldMetadataId
primaryAxisGroupBySubFieldName
primaryAxisOrderBy
secondaryAxisGroupByFieldMetadataId
secondaryAxisGroupBySubFieldName
secondaryAxisOrderBy
omitNullValues
axisNameDisplay
displayDataLabel
rangeMin
rangeMax
filter
color
description
}
... on PieChartConfiguration {
graphType
groupByFieldMetadataId
aggregateFieldMetadataId
aggregateOperation
orderBy
displayDataLabel
filter
color
description
}
... on NumberChartConfiguration {
graphType
aggregateFieldMetadataId
aggregateOperation
description
filter
format
label
}
... on GaugeChartConfiguration {
graphType
aggregateFieldMetadataId
aggregateOperation
description
filter
}
`;
export const PAGE_LAYOUT_WIDGET_GQL_FIELDS = `
id
title
type
pageLayoutTabId
objectMetadataId
gridPosition {
row
column
rowSpan
columnSpan
}
configuration {
${PAGE_LAYOUT_WIDGET_CONFIGURATION_FIELDS}
}
createdAt
updatedAt
deletedAt
`;