Chart editor - Part 1 (#14820)

This PR is the first part of the creation of the Chart editor.


https://github.com/user-attachments/assets/8b0af8ea-be41-4506-84cb-e40f5521cbf0

Done:
- Bar chart settings (except filters)
- Line chart settings (except filters)

In progress:
- Pie chart settings
- Number chart settings
- Gauge chart settings

Left to do:
- Loosen the backend validation to allow the user to save a partial
configuration, validate the graph configuration in the frontend and
display a error friendly message in the graph if the config is not
completed yet
- Implement the filter edition
- Finish the other graph types settings
This commit is contained in:
Raphaël Bosi
2025-10-03 10:25:45 +02:00
committed by GitHub
parent fc8b4f813c
commit d10ab5f67c
112 changed files with 3046 additions and 503 deletions
@@ -14,10 +14,11 @@ import { GraphQLJSON } from 'graphql-type-json';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
import { GraphOrderBy } from 'src/engine/core-modules/page-layout/enums/graph-order-by.enum';
import { ExtendedAggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/extended-aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { AxisNameDisplay } from 'src/engine/core-modules/page-layout/enums/axis-name-display.enum';
import { GraphOrderBy } from 'src/engine/core-modules/page-layout/enums/graph-order-by.enum';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
@ObjectType('BarChartConfiguration')
export class BarChartConfigurationDTO {
@@ -31,10 +32,10 @@ export class BarChartConfigurationDTO {
@IsNotEmpty()
aggregateFieldMetadataId: string;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@Field(() => ExtendedAggregateOperations)
@IsEnum(ExtendedAggregateOperations)
@IsNotEmpty()
aggregateOperation: AggregateOperations;
aggregateOperation: ExtendedAggregateOperations;
@Field(() => UUIDScalarType)
@IsUUID()
@@ -61,15 +62,15 @@ export class BarChartConfigurationDTO {
@IsOptional()
omitNullValues?: boolean;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
xAxisName?: string;
@Field(() => AxisNameDisplay)
@IsEnum(AxisNameDisplay)
@IsNotEmpty()
axisNameDisplay: AxisNameDisplay;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
yAxisName?: string;
@Field(() => Boolean)
@IsBoolean()
@IsNotEmpty()
displayDataLabel: boolean;
@Field(() => Number, { nullable: true })
@IsNumber()
@@ -1,6 +1,7 @@
import { Field, ObjectType } from '@nestjs/graphql';
import {
IsBoolean,
IsEnum,
IsNotEmpty,
IsObject,
@@ -12,9 +13,9 @@ import { GraphQLJSON } from 'graphql-type-json';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
import { ExtendedAggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/extended-aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
@ObjectType('GaugeChartConfiguration')
export class GaugeChartConfigurationDTO {
@@ -28,20 +29,19 @@ export class GaugeChartConfigurationDTO {
@IsNotEmpty()
aggregateFieldMetadataId: string;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@Field(() => ExtendedAggregateOperations)
@IsEnum(ExtendedAggregateOperations)
@IsNotEmpty()
aggregateOperation: AggregateOperations;
aggregateOperation: ExtendedAggregateOperations;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@IsNotEmpty()
aggregateOperationTotal: AggregateOperations;
@Field(() => Boolean)
@IsBoolean()
displayDataLabel: boolean;
@Field(() => UUIDScalarType)
@IsUUID()
@IsNotEmpty()
aggregateFieldMetadataIdTotal: string;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
color?: string;
@Field(() => String, { nullable: true })
@IsString()
@@ -14,8 +14,9 @@ import { GraphQLJSON } from 'graphql-type-json';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { ExtendedAggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/extended-aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { AxisNameDisplay } from 'src/engine/core-modules/page-layout/enums/axis-name-display.enum';
import { GraphOrderBy } from 'src/engine/core-modules/page-layout/enums/graph-order-by.enum';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
@@ -31,10 +32,10 @@ export class LineChartConfigurationDTO {
@IsNotEmpty()
aggregateFieldMetadataId: string;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@Field(() => ExtendedAggregateOperations)
@IsEnum(ExtendedAggregateOperations)
@IsNotEmpty()
aggregateOperation: AggregateOperations;
aggregateOperation: ExtendedAggregateOperations;
@Field(() => UUIDScalarType)
@IsUUID()
@@ -61,15 +62,15 @@ export class LineChartConfigurationDTO {
@IsOptional()
omitNullValues?: boolean;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
xAxisName?: string;
@Field(() => AxisNameDisplay)
@IsEnum(AxisNameDisplay)
@IsNotEmpty()
axisNameDisplay: AxisNameDisplay;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
yAxisName?: string;
@Field(() => Boolean)
@IsBoolean()
@IsNotEmpty()
displayDataLabel: boolean;
@Field(() => Number, { nullable: true })
@IsNumber()
@@ -1,6 +1,7 @@
import { Field, ObjectType } from '@nestjs/graphql';
import {
IsBoolean,
IsEnum,
IsNotEmpty,
IsObject,
@@ -12,9 +13,9 @@ import { GraphQLJSON } from 'graphql-type-json';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
import { ExtendedAggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/extended-aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
@ObjectType('NumberChartConfiguration')
export class NumberChartConfigurationDTO {
@@ -28,16 +29,21 @@ export class NumberChartConfigurationDTO {
@IsNotEmpty()
aggregateFieldMetadataId: string;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@Field(() => ExtendedAggregateOperations)
@IsEnum(ExtendedAggregateOperations)
@IsNotEmpty()
aggregateOperation: AggregateOperations;
aggregateOperation: ExtendedAggregateOperations;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
label?: string;
@Field(() => Boolean)
@IsBoolean()
@IsNotEmpty()
displayDataLabel: boolean;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
@@ -1,6 +1,7 @@
import { Field, ObjectType } from '@nestjs/graphql';
import {
IsBoolean,
IsEnum,
IsNotEmpty,
IsObject,
@@ -12,10 +13,10 @@ import { GraphQLJSON } from 'graphql-type-json';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
import { GraphOrderBy } from 'src/engine/core-modules/page-layout/enums/graph-order-by.enum';
import { ExtendedAggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/extended-aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { GraphOrderBy } from 'src/engine/core-modules/page-layout/enums/graph-order-by.enum';
import { GraphType } from 'src/engine/core-modules/page-layout/enums/graph-type.enum';
@ObjectType('PieChartConfiguration')
export class PieChartConfigurationDTO {
@@ -29,10 +30,10 @@ export class PieChartConfigurationDTO {
@IsNotEmpty()
aggregateFieldMetadataId: string;
@Field(() => AggregateOperations)
@IsEnum(AggregateOperations)
@Field(() => ExtendedAggregateOperations)
@IsEnum(ExtendedAggregateOperations)
@IsNotEmpty()
aggregateOperation: AggregateOperations;
aggregateOperation: ExtendedAggregateOperations;
@Field(() => UUIDScalarType)
@IsUUID()
@@ -44,6 +45,11 @@ export class PieChartConfigurationDTO {
@IsNotEmpty()
orderBy: GraphOrderBy;
@Field(() => Boolean)
@IsBoolean()
@IsNotEmpty()
displayDataLabel: boolean;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
@@ -0,0 +1,13 @@
import { registerEnumType } from '@nestjs/graphql';
export enum AxisNameDisplay {
NONE = 'NONE',
X = 'X',
Y = 'Y',
BOTH = 'BOTH',
}
registerEnumType(AxisNameDisplay, {
name: 'AxisNameDisplay',
description: 'Which axes should display labels',
});