From 8a75e4dbbc9aad0ec37cd5e4c9dcbcd7b95c5c9c Mon Sep 17 00:00:00 2001 From: Yongtae Park Date: Fri, 29 Nov 2024 09:42:47 +0900 Subject: [PATCH 1/2] feat(widget-field-value-manager): create widget-field-value-manager Signed-off-by: samuel.park --- .../_widget-field-value-manager/index.ts | 77 ++++++++++++++++++ .../_widget-field-value-manager/type.ts | 80 +++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 apps/web/src/common/modules/widgets/_widget-field-value-manager/index.ts create mode 100644 apps/web/src/common/modules/widgets/_widget-field-value-manager/type.ts diff --git a/apps/web/src/common/modules/widgets/_widget-field-value-manager/index.ts b/apps/web/src/common/modules/widgets/_widget-field-value-manager/index.ts new file mode 100644 index 0000000000..f323f3d582 --- /dev/null +++ b/apps/web/src/common/modules/widgets/_widget-field-value-manager/index.ts @@ -0,0 +1,77 @@ +import type { WidgetFieldTypeMap, WidgetFieldValue, WidgetFieldValueMap } from '@/common/modules/widgets/_widget-field-value-manager/type'; + +type FieldValueValidator = (fieldValue: T) => boolean; + +export default class WidgetFieldValueManager { + private originData: WidgetFieldValueMap; + + private modifiedData: WidgetFieldValueMap; + + private fieldValidators: Record>; + + private validationErrors: Record = {}; + + constructor( + originData: WidgetFieldValueMap, + fieldValidators: Record>, + ) { + this.originData = originData; + this.modifiedData = { ...originData }; + this.fieldValidators = fieldValidators; + } + + setFieldValue(key: Key, value: WidgetFieldTypeMap[Key]): boolean { + const field = this.modifiedData[key] || this.originData[key]; + if (!field) { + throw new Error(`Field "${key}" does not exist.`); + } + + this.modifiedData[key] = { ...field, value }; + + const validator = this.fieldValidators[key]; + if (validator) { + const isValid = validator(this.modifiedData[key]); + if (!isValid) { + this.validationErrors[key as string] = `Invalid value for field "${key}"`; + return false; + } + } + + delete this.validationErrors[key as string]; + return true; + } + + validateAll(): boolean { + this.validationErrors = {}; + let isValid = true; + + Object.entries(this.modifiedData).forEach(([key, field]) => { + const validator = this.fieldValidators[key]; + if (validator && !validator(field)) { + this.validationErrors[key] = `Invalid value for field "${key}"`; + isValid = false; + } + }); + + return isValid; + } + + getValidationErrors(): Record { + return this.validationErrors; + } + + getData(): WidgetFieldValueMap { + return this.modifiedData; + } + + resetToOrigin(): void { + this.modifiedData = { ...this.originData }; + this.validationErrors = {}; + } + + setOrigin(data: WidgetFieldValueMap): void { + this.originData = { ...data }; + this.modifiedData = { ...data }; + this.validationErrors = {}; + } +} diff --git a/apps/web/src/common/modules/widgets/_widget-field-value-manager/type.ts b/apps/web/src/common/modules/widgets/_widget-field-value-manager/type.ts new file mode 100644 index 0000000000..04c3a6bc28 --- /dev/null +++ b/apps/web/src/common/modules/widgets/_widget-field-value-manager/type.ts @@ -0,0 +1,80 @@ +import type { AdvancedFormatRulesValue } from '@/common/modules/widgets/_widget-fields/advanced-format-rules/type'; +import type { CategoryByValue } from '@/common/modules/widgets/_widget-fields/category-by/type'; +import type { ColorSchemaValue } from '@/common/modules/widgets/_widget-fields/color-schema/type'; +import type { ComparisonValue } from '@/common/modules/widgets/_widget-fields/comparison/type'; +import type { CustomTableColumnWidthValue } from '@/common/modules/widgets/_widget-fields/custom-table-column-width/type'; +import type { DataFieldHeatmapColorValue } from '@/common/modules/widgets/_widget-fields/data-field-heatmap-color/type'; +import type { DataFieldValue } from '@/common/modules/widgets/_widget-fields/data-field/type'; +import type { DateFormatValue } from '@/common/modules/widgets/_widget-fields/date-format/type'; +import type { DateRangeValue } from '@/common/modules/widgets/_widget-fields/date-range/type'; +import type { DisplayAnnotationValue } from '@/common/modules/widgets/_widget-fields/display-annotation/type'; +import type { DisplaySeriesLabelValue } from '@/common/modules/widgets/_widget-fields/display-series-label/type'; +import type { FormatRulesValue } from '@/common/modules/widgets/_widget-fields/format-rules/type'; +import type { GranularityValue } from '@/common/modules/widgets/_widget-fields/granularity/type'; +import type { GroupByValue } from '@/common/modules/widgets/_widget-fields/group-by/type'; +import type { WidgetHeaderValue } from '@/common/modules/widgets/_widget-fields/header/type'; +import type { IconValue } from '@/common/modules/widgets/_widget-fields/icon/type'; +import type { LegendValue } from '@/common/modules/widgets/_widget-fields/legend/type'; +import type { LineByValue } from '@/common/modules/widgets/_widget-fields/line-by/type'; +import type { MaxValue } from '@/common/modules/widgets/_widget-fields/max/type'; +import type { MinValue } from '@/common/modules/widgets/_widget-fields/min/type'; +import type { MissingValueValue } from '@/common/modules/widgets/_widget-fields/missing-value/type'; +import type { NumberFormatValue } from '@/common/modules/widgets/_widget-fields/number-format/type'; +import type { PieChartTypeValue } from '@/common/modules/widgets/_widget-fields/pie-chart-type/type'; +import type { ProgressBarValue } from '@/common/modules/widgets/_widget-fields/progress-bar/type'; +import type { StackByValue } from '@/common/modules/widgets/_widget-fields/stack-by/type'; +import type { SubTotalValue } from '@/common/modules/widgets/_widget-fields/sub-total/type'; +import type { TableColumnWidthValue } from '@/common/modules/widgets/_widget-fields/table-column-width/type'; +import type { TableDataFieldValue } from '@/common/modules/widgets/_widget-fields/table-data-field/type'; +import type { TextWrapValue } from '@/common/modules/widgets/_widget-fields/text-wrap/type'; +import type { TooltipNumberFormatValue } from '@/common/modules/widgets/_widget-fields/tooltip-number-format/type'; +import type { TotalValue } from '@/common/modules/widgets/_widget-fields/total/type'; +import type { WidgetHeightValue } from '@/common/modules/widgets/_widget-fields/widget-height/type'; +import type { XAxisValue } from '@/common/modules/widgets/_widget-fields/x-axis/type'; +import type { YAxisValue } from '@/common/modules/widgets/_widget-fields/y-axis/type'; + +export interface WidgetFieldValueMap { + [key: string]: WidgetFieldValue; +} + +export interface WidgetFieldValue { + value: any; + meta?: Record; +} + +export interface WidgetFieldTypeMap { + xAxis: XAxisValue; + yAxis: YAxisValue; + widgetHeight: WidgetHeightValue; + total: TotalValue; + tooltipNumberFormat: TooltipNumberFormatValue; + textWrap: TextWrapValue; + tableDataField: TableDataFieldValue; + tableColumnWidth: TableColumnWidthValue; + subTotal: SubTotalValue; + stackBy: StackByValue; + progressVar: ProgressBarValue; + pieChartType: PieChartTypeValue; + numberFormat: NumberFormatValue; + missingValue: MissingValueValue; + min: MinValue; + max: MaxValue; + lineBy: LineByValue; + legend: LegendValue; + icon: IconValue; + header: WidgetHeaderValue; + groupBy: GroupByValue; + granularity: GranularityValue; + formatRules: FormatRulesValue; + displaySeriesLabel: DisplaySeriesLabelValue; + displayAnnotation: DisplayAnnotationValue; + dateRange: DateRangeValue; + dateFormat: DateFormatValue; + dataFieldHeatmapColor: DataFieldHeatmapColorValue; + dataField: DataFieldValue; + customTableColumnWidth: CustomTableColumnWidthValue; + comparison: ComparisonValue; + colorSchema: ColorSchemaValue; + categoryBy: CategoryByValue; + advancedFormatRules: AdvancedFormatRulesValue; +} From 5e15f23f278c7317585b3069b9eccde8d7aff69f Mon Sep 17 00:00:00 2001 From: Yongtae Park Date: Fri, 29 Nov 2024 09:43:01 +0900 Subject: [PATCH 2/2] chore: create temporary type Signed-off-by: samuel.park --- .../modules/widgets/_widget-fields/data-field/type.ts | 5 +++++ .../modules/widgets/_widget-fields/granularity/type.ts | 4 ++++ .../src/common/modules/widgets/_widget-fields/max/type.ts | 5 +++++ .../src/common/modules/widgets/_widget-fields/min/type.ts | 5 +++++ .../modules/widgets/_widget-fields/pie-chart-type/type.ts | 5 +++++ .../common/modules/widgets/_widget-fields/sub-total/type.ts | 6 ++++++ 6 files changed, 30 insertions(+) create mode 100644 apps/web/src/common/modules/widgets/_widget-fields/granularity/type.ts diff --git a/apps/web/src/common/modules/widgets/_widget-fields/data-field/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/data-field/type.ts index fd4137b9a9..ddb3d83a18 100644 --- a/apps/web/src/common/modules/widgets/_widget-fields/data-field/type.ts +++ b/apps/web/src/common/modules/widgets/_widget-fields/data-field/type.ts @@ -1,3 +1,8 @@ + export interface DataFieldOptions { multiSelectable?: boolean; } + +export interface DataFieldValue { + data: string|string[]; +} diff --git a/apps/web/src/common/modules/widgets/_widget-fields/granularity/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/granularity/type.ts new file mode 100644 index 0000000000..b17af39459 --- /dev/null +++ b/apps/web/src/common/modules/widgets/_widget-fields/granularity/type.ts @@ -0,0 +1,4 @@ + +export interface GranularityValue { + granularity: 'YEARLY' | 'MONTHLY' | 'DAILY'; +} diff --git a/apps/web/src/common/modules/widgets/_widget-fields/max/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/max/type.ts index f2b7134617..0673706698 100644 --- a/apps/web/src/common/modules/widgets/_widget-fields/max/type.ts +++ b/apps/web/src/common/modules/widgets/_widget-fields/max/type.ts @@ -1,3 +1,8 @@ + export interface MaxOptions { default?: number; } + +export interface MaxValue { + max: number; +} diff --git a/apps/web/src/common/modules/widgets/_widget-fields/min/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/min/type.ts index ddbed02898..454e9f1291 100644 --- a/apps/web/src/common/modules/widgets/_widget-fields/min/type.ts +++ b/apps/web/src/common/modules/widgets/_widget-fields/min/type.ts @@ -1,3 +1,8 @@ + export interface MinOptions { default?: number; } + +export interface MinValue { + min: number; +} diff --git a/apps/web/src/common/modules/widgets/_widget-fields/pie-chart-type/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/pie-chart-type/type.ts index c9a1d4a917..2d76d5f111 100644 --- a/apps/web/src/common/modules/widgets/_widget-fields/pie-chart-type/type.ts +++ b/apps/web/src/common/modules/widgets/_widget-fields/pie-chart-type/type.ts @@ -1,3 +1,8 @@ + export interface PieChartTypeOptions { default?: string; } + +export interface PieChartTypeValue { + type: 'pie' | 'donut'; +} diff --git a/apps/web/src/common/modules/widgets/_widget-fields/sub-total/type.ts b/apps/web/src/common/modules/widgets/_widget-fields/sub-total/type.ts index 988309fcd6..be97de8ba0 100644 --- a/apps/web/src/common/modules/widgets/_widget-fields/sub-total/type.ts +++ b/apps/web/src/common/modules/widgets/_widget-fields/sub-total/type.ts @@ -3,3 +3,9 @@ export interface SubTotalOptions { default?: boolean; toggle?: boolean; } + + +export interface SubTotalValue { + toggleValue: boolean; + freeze: boolean; +}