update server shared to include new types

This commit is contained in:
Nate Kelley 2025-07-03 15:54:31 -06:00
parent 7364f328d4
commit 4cdde9203f
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
149 changed files with 621 additions and 1759 deletions

View File

@ -1,77 +0,0 @@
import { z } from 'zod/v4';
import { GoalLineSchema, TrendlineSchema } from './annotationInterfaces';
import { ColumnSettingsSchema } from './columnInterfaces';
import { IColumnLabelFormatSchema } from './columnLabelInterfaces';
import { ChartTypeSchema } from './enum';
import { ShowLegendHeadlineSchema } from './etcInterfaces';
import {
CategoryAxisStyleConfigSchema,
XAxisConfigSchema,
Y2AxisConfigSchema,
YAxisConfigSchema
} from './tickInterfaces';
import { DEFAULT_CHART_THEME } from './configColors';
import { BarChartPropsSchema } from './barChartProps';
import { LineChartPropsSchema } from './lineChartProps';
import { ScatterChartPropsSchema } from './scatterChartProps';
import { PieChartPropsSchema } from './pieChartProps';
import { TableChartPropsSchema } from './tableChartProps';
import { ComboChartPropsSchema } from './comboChartProps';
import { MetricChartPropsSchema, DerivedMetricTitleSchema } from './metricChartProps';
export const BusterChartConfigPropsSchema = z.object({
selectedChartType: ChartTypeSchema,
// COLUMN SETTINGS
// OPTIONAL because the defaults will be determined by the UI
columnSettings: z.record(z.string(), z.optional(ColumnSettingsSchema)).default({}),
columnLabelFormats: z.record(z.string(), z.optional(IColumnLabelFormatSchema)).default({}),
// OPTIONAL: default is the buster color palette
colors: z.array(z.string()).default(DEFAULT_CHART_THEME),
// OPTIONAL: default is null and will be true if there are multiple Y axes or if a category axis is used
showLegend: z.nullable(z.boolean()).default(null),
// OPTIONAL: default: true
gridLines: z.boolean().default(true),
// OPTIONAL
showLegendHeadline: ShowLegendHeadlineSchema,
// OPTIONAL: default is no goal lines
goalLines: z.array(GoalLineSchema).default([]),
// OPTIONAL: default is no trendlines
trendlines: z.array(TrendlineSchema).default([]),
// OPTIONAL: default is false
disableTooltip: z.boolean().default(false),
// Spread the shape properties from all schemas
...YAxisConfigSchema.shape,
...XAxisConfigSchema.shape,
...CategoryAxisStyleConfigSchema.shape,
...Y2AxisConfigSchema.shape,
...BarChartPropsSchema.shape,
...LineChartPropsSchema.shape,
...ScatterChartPropsSchema.shape,
...PieChartPropsSchema.shape,
...TableChartPropsSchema.shape,
...ComboChartPropsSchema.shape,
...MetricChartPropsSchema.shape
});
// Re-export schemas for backward compatibility
export {
BarChartPropsSchema,
LineChartPropsSchema,
ScatterChartPropsSchema,
PieChartPropsSchema,
TableChartPropsSchema,
ComboChartPropsSchema,
MetricChartPropsSchema,
DerivedMetricTitleSchema
};
// Export original types for backward compatibility
export type BusterChartConfigProps = z.infer<typeof BusterChartConfigPropsSchema>;
export type DerivedMetricTitle = z.infer<typeof DerivedMetricTitleSchema>;
export type MetricChartProps = z.infer<typeof MetricChartPropsSchema>;
export type BarChartProps = z.infer<typeof BarChartPropsSchema>;
export type LineChartProps = z.infer<typeof LineChartPropsSchema>;
export type ScatterChartProps = z.infer<typeof ScatterChartPropsSchema>;
export type PieChartProps = z.infer<typeof PieChartPropsSchema>;
export type TableChartProps = z.infer<typeof TableChartPropsSchema>;
export type ComboChartProps = z.infer<typeof ComboChartPropsSchema>;

View File

@ -1,125 +0,0 @@
import { DEFAULT_CHART_THEME } from './configColors';
import { BusterChartConfigPropsSchema, type BusterChartConfigProps } from './chartConfigProps';
import { z } from 'zod/v4';
/**
* Extracts all default values from a Zod schema.
* This function creates a partial version of the schema where all fields are optional,
* then parses an empty object to get all the default values.
*/
function getDefaults<T extends z.ZodObject<z.ZodRawShape>>(schema: T): z.infer<T> {
// Create a partial version of the schema where all fields are optional
const partialSchema = schema.partial();
// Parse an empty object through the partial schema
// This will apply all default values without throwing on missing required fields
const defaults = partialSchema.parse({});
// Now try to parse the defaults through the original schema
// This ensures we get the correct type and validates the defaults
try {
return schema.parse(defaults);
} catch {
// If the original schema fails (missing required fields without defaults),
// return what we have as a partial
return defaults as z.infer<T>;
}
}
/**
* Alternative implementation that only returns fields with explicit defaults.
* This is useful when you want to know which fields have defaults vs which are undefined.
*/
function getDefaultsPartial<T extends z.ZodObject<z.ZodRawShape>>(schema: T): Partial<z.infer<T>> {
// Make all fields optional and parse an empty object
const partialSchema = schema.partial();
return partialSchema.parse({}) as Partial<z.infer<T>>;
}
export const DEFAULT_CHART_CONFIG: BusterChartConfigProps = getDefaults(
BusterChartConfigPropsSchema
);
// export const DEFAULT_CHART_CONFIG: BusterChartConfigProps = {
// colors: DEFAULT_CHART_THEME,
// selectedChartType: 'table',
// yAxisShowAxisLabel: true,
// yAxisShowAxisTitle: true,
// yAxisAxisTitle: null,
// yAxisStartAxisAtZero: null,
// yAxisScaleType: 'linear',
// y2AxisShowAxisLabel: true,
// y2AxisAxisTitle: null,
// y2AxisShowAxisTitle: true,
// y2AxisStartAxisAtZero: true,
// y2AxisScaleType: 'linear',
// xAxisTimeInterval: null,
// xAxisShowAxisLabel: true,
// xAxisShowAxisTitle: true,
// xAxisAxisTitle: null,
// xAxisLabelRotation: 'auto',
// xAxisDataZoom: false,
// categoryAxisTitle: null,
// showLegend: null,
// gridLines: true,
// goalLines: [],
// trendlines: [],
// showLegendHeadline: false,
// disableTooltip: false,
// barAndLineAxis: {
// x: [],
// y: [],
// category: [],
// tooltip: null
// },
// scatterAxis: {
// x: [],
// y: [],
// size: [],
// tooltip: null
// },
// comboChartAxis: {
// x: [],
// y: [],
// y2: [],
// tooltip: null
// },
// pieChartAxis: {
// x: [],
// y: [],
// tooltip: null
// },
// //LINE
// lineGroupType: null,
// //SCATTER
// scatterDotSize: [3, 15],
// //BAR
// barSortBy: [],
// barLayout: 'vertical',
// barGroupType: 'group',
// barShowTotalAtTop: false,
// //PIE
// pieShowInnerLabel: true,
// pieInnerLabelAggregate: 'sum',
// pieInnerLabelTitle: 'Total',
// pieLabelPosition: null,
// pieDonutWidth: 40,
// pieMinimumSlicePercentage: 0,
// pieDisplayLabelAs: 'number',
// pieSortBy: 'value',
// //METRIC
// metricColumnId: '',
// metricValueAggregate: 'sum',
// metricHeader: null,
// metricSubHeader: null,
// metricValueLabel: null,
// //TABLE
// tableColumnOrder: null,
// tableColumnWidths: null,
// tableHeaderBackgroundColor: null,
// tableHeaderFontColor: null,
// tableColumnFontColor: null,
// //MUST LOOP THROUGH ALL COLUMNS
// columnSettings: {},
// columnLabelFormats: {}
// };

View File

@ -1,69 +0,0 @@
import { z } from 'zod/v4';
export const IColumnLabelFormatSchema = z.object({
columnType: z.enum(['number', 'text', 'date'] as const),
style: z.enum(['currency', 'percent', 'number', 'date', 'string']),
// All other properties from ColumnLabelFormat
// OPTIONAL: if this is not specifically requested by the user, then you should ignore this and the columnId will be used and formatted
displayName: z.optional(z.string()),
// OPTIONAL: default is ','. You should add this style if the column type requires a unique separator style. This will only apply if the format is set to 'number'.
numberSeparatorStyle: z.optional(z.nullable(z.literal(','))),
// OPTIONAL: default is 0. This is essentially used to set a minimum number of decimal places. This will only apply if the format is set to 'number'.
minimumFractionDigits: z.optional(
z
.number()
.check(
z.gte(0, 'Minimum fraction digits must be at least 0'),
z.lte(20, 'Minimum fraction digits must be at most 20')
)
),
// OPTIONAL: default is 2. This is essentially used to set a maximum number of decimal places. This will only apply if the format is set to 'number'.
maximumFractionDigits: z.optional(
z
.number()
.check(
z.gte(0, 'Maximum fraction digits must be at least 0'),
z.lte(20, 'Maximum fraction digits must be at most 20')
)
),
// OPTIONAL: default is 1. This will only apply if the format is set to 'number', 'currency', or 'percent'.
multiplier: z.optional(
z
.number()
.check(
z.gte(0.001, 'Multiplier must be at least 0.001'),
z.lte(1000000, 'Multiplier must be at most 1,000,000')
)
),
// OPTIONAL: default is ''. This sets a prefix to go in front of each value found within the column. This will only apply if the format is set to 'number' or 'percent'.
prefix: z.optional(z.string()),
// OPTIONAL: default is ''. This sets a suffix to go after each value found within the column. This will only apply if the format is set to 'number' or 'percent'.
suffix: z.optional(z.string()),
// OPTIONAL: default is 0. This will only apply if the format is set to 'number'. This will replace missing data with the specified value.
replaceMissingDataWith: z.optional(z.union([z.literal(0), z.null(), z.string()])),
useRelativeTime: z.optional(z.boolean()),
isUTC: z.optional(z.boolean()),
makeLabelHumanReadable: z.optional(z.boolean()),
// DO NOT SHARE WITH LLM
compactNumbers: z.optional(z.boolean()),
// Currency-specific properties
// OPTIONAL: default is 'USD'. This will only apply if the format is set to 'currency'. It should be the ISO 4217 currency code.
currency: z.optional(z.string()),
// Date-specific properties
// OPTIONAL: default is 'LL'. This will only apply if the format is set to 'date'. This will convert the date to the specified format. This MUST BE IN dayjs format. If you determine that a column type is a date column, you should specify it's date format here.
dateFormat: z.optional(z.union([z.literal('auto'), z.string()])),
// OPTIONAL: default is null. This will only apply if the format is set to 'number'. This will convert the number to a specified date unit. For example, if month_of_year is selected, then the number 0 will be converted to January.
convertNumberTo: z.optional(
z.nullable(z.enum(['day_of_week', 'month_of_year', 'quarter', 'number']))
)
});
// Create ColumnLabelFormatSchema by extending IColumnLabelFormatSchema with optional columnType and style
export const ColumnLabelFormatSchema = IColumnLabelFormatSchema.extend({
columnType: z.optional(z.enum(['number', 'text', 'date'] as const)),
style: z.optional(z.enum(['currency', 'percent', 'number', 'date', 'string']))
});
// Export inferred types
export type ColumnLabelFormat = z.infer<typeof ColumnLabelFormatSchema>;
export type IColumnLabelFormat = z.infer<typeof IColumnLabelFormatSchema>;

View File

@ -1,10 +1 @@
export * from './annotationInterfaces';
export * from './axisInterfaces';
export * from './chartBaseInterfaces';
export * from './chartConfigProps';
export * from './columnInterfaces';
export * from './columnLabelInterfaces';
export * from './enum';
export * from './etcInterfaces';
export * from './interfaces';
export * from './tickInterfaces';

View File

@ -1,6 +1,5 @@
import type { Chart, ChartType, DefaultDataPoint } from 'chart.js';
import type { ColumnMetaData } from '../interfaces';
import type { BusterChartConfigProps } from './chartConfigProps';
import type { ColumnMetaData, ChartConfigProps } from '@buster/server-shared/metrics';
export type BusterChartProps = {
data: Record<string, string | number | null | Date>[] | null;
@ -15,7 +14,7 @@ export type BusterChartProps = {
readOnly?: boolean;
onInitialAnimationEnd?: () => void;
onChartMounted?: (chart?: ChartJSOrUndefined) => void;
} & BusterChartConfigProps;
} & ChartConfigProps;
type ChartJSOrUndefined<
TType extends ChartType = ChartType,

View File

@ -1,36 +0,0 @@
import { z } from 'zod/v4';
import { PieChartAxisSchema } from './axisInterfaces';
import { PieSortBySchema } from './etcInterfaces';
export const PieChartPropsSchema = z.object({
// OPTIONAL: default: value
pieSortBy: PieSortBySchema,
// Required for Pie
pieChartAxis: PieChartAxisSchema,
// OPTIONAL: default: number
pieDisplayLabelAs: z.enum(['percent', 'number']).default('number'),
// OPTIONAL: default true if donut width is set. If the data contains a percentage, set this as false.
pieShowInnerLabel: z.boolean().default(true),
// OPTIONAL: default: sum
pieInnerLabelAggregate: z
.enum(['sum', 'average', 'median', 'max', 'min', 'count'])
.default('sum'),
// OPTIONAL: default is null and will be the name of the pieInnerLabelAggregate
pieInnerLabelTitle: z.string().optional(),
// OPTIONAL: default: outside
pieLabelPosition: z.nullable(z.enum(['inside', 'outside', 'none'])).default(null),
// OPTIONAL: default: 55 | range 0-65 | range represents percent size of the donut hole. If user asks for a pie this should be 0
pieDonutWidth: z
.number()
.min(0, 'Donut width must be at least 0')
.max(65, 'Donut width must be at most 65')
.default(40),
// OPTIONAL: default: 2.5 | range 0-100 | If there are items that are less than this percentage of the pie, they combine to form a single slice.
pieMinimumSlicePercentage: z
.number()
.min(0, 'Minimum slice percentage must be at least 0')
.max(100, 'Minimum slice percentage must be at most 100')
.default(0)
});
export type PieChartProps = z.infer<typeof PieChartPropsSchema>;

View File

@ -1,70 +0,0 @@
import { z } from 'zod/v4';
/**
* Configuration options for the Y-axis of a chart.
*/
export const YAxisConfigSchema = z.object({
// Whether to show the axis label. Defaults to true.
yAxisShowAxisLabel: z.boolean().default(true),
// Whether to show the axis title. Defaults to true.
yAxisShowAxisTitle: z.boolean().default(true),
// The title of the Y-axis. @default null - Uses the name of the first column plotted on the Y-axis
yAxisAxisTitle: z.nullable(z.string()).default(null),
// Whether to start the axis at zero. Defaults to null.
yAxisStartAxisAtZero: z.nullable(z.boolean()).default(null),
// The scale type for the Y-axis. @default "linear"
yAxisScaleType: z.enum(['log', 'linear']).default('linear')
});
//The y2 (or right axis) Y-axis is used for secondary Y-axes in a combo chart.
/**
* Configuration options for the secondary Y-axis (Y2) in a combo chart.
*/
export const Y2AxisConfigSchema = z.object({
// Whether to show the axis label. Defaults to true.
y2AxisShowAxisLabel: z.boolean().default(true),
// Whether to show the axis title. Defaults to true.
y2AxisShowAxisTitle: z.boolean().default(true),
// The title of the secondary Y-axis. @default null - Uses the name of the first column plotted on the Y2-axis
y2AxisAxisTitle: z.nullable(z.string()).default(null),
// Whether to start the axis at zero. Defaults to true.
y2AxisStartAxisAtZero: z.boolean().default(true),
// The scale type for the secondary Y-axis. @default "linear"
y2AxisScaleType: z.enum(['log', 'linear']).default('linear')
});
/**
* Configuration options for the X-axis of a chart.
*/
export const XAxisConfigSchema = z.object({
// The time interval for the X-axis. Only applies to combo and line charts. @default null
xAxisTimeInterval: z.nullable(z.enum(['day', 'week', 'month', 'quarter', 'year'])).default(null),
// Whether to show the axis label. Defaults to true.
xAxisShowAxisLabel: z.boolean().default(true),
// Whether to show the axis title. Defaults to true.
xAxisShowAxisTitle: z.boolean().default(true),
// The title of the X-axis. @default null - Uses a concatenation of all X columns applied to the axis
xAxisAxisTitle: z.nullable(z.string()).default(null),
// The rotation angle for the X-axis labels. @default "auto"
xAxisLabelRotation: z
.union([z.literal(0), z.literal(45), z.literal(90), z.literal('auto')])
.default('auto'),
// Whether to enable data zooming on the X-axis. Should only be set to true by the user. @default false
xAxisDataZoom: z.boolean().default(false)
});
//The category axis works differently than the other axes. It is used to color and group the data.
/**
* Configuration options for styling the category axis.
* The category axis is used to color and group the data.
*/
export const CategoryAxisStyleConfigSchema = z.object({
// The title of the category axis. @default null
categoryAxisTitle: z.nullable(z.string()).default(null)
});
// Export inferred types
export type YAxisConfig = z.infer<typeof YAxisConfigSchema>;
export type Y2AxisConfig = z.infer<typeof Y2AxisConfigSchema>;
export type XAxisConfig = z.infer<typeof XAxisConfigSchema>;
export type CategoryAxisStyleConfig = z.infer<typeof CategoryAxisStyleConfigSchema>;

View File

@ -1,187 +0,0 @@
import { ShareRole } from '../share/shareInterfaces';
import { VerificationStatus } from '../share/verificationInterfaces';
import { type ColumnLabelFormat, type ColumnSettings } from './charts';
import { DEFAULT_CHART_THEME } from './charts/configColors';
import type { ColumnMetaData } from './interfaces';
import type { IBusterMetric, IBusterMetricChartConfig } from './requireInterfaces';
export const DEFAULT_CHART_CONFIG: IBusterMetricChartConfig = {
colors: DEFAULT_CHART_THEME,
selectedChartType: 'table',
yAxisShowAxisLabel: true,
yAxisShowAxisTitle: true,
yAxisAxisTitle: null,
yAxisStartAxisAtZero: null,
yAxisScaleType: 'linear',
y2AxisShowAxisLabel: true,
y2AxisAxisTitle: null,
y2AxisShowAxisTitle: true,
y2AxisStartAxisAtZero: true,
y2AxisScaleType: 'linear',
xAxisTimeInterval: null,
xAxisShowAxisLabel: true,
xAxisShowAxisTitle: true,
xAxisAxisTitle: null,
xAxisLabelRotation: 'auto',
xAxisDataZoom: false,
categoryAxisTitle: null,
showLegend: null,
gridLines: true,
goalLines: [],
trendlines: [],
showLegendHeadline: false,
disableTooltip: false,
barAndLineAxis: {
x: [],
y: [],
category: [],
tooltip: null
},
scatterAxis: {
x: [],
y: [],
category: [],
size: [],
tooltip: null
},
comboChartAxis: {
x: [],
y: [],
y2: [],
category: [],
tooltip: null
},
pieChartAxis: {
x: [],
y: [],
tooltip: null
},
//LINE
lineGroupType: null,
//SCATTER
scatterDotSize: [3, 15],
//BAR
barSortBy: [],
barLayout: 'vertical',
barGroupType: 'group',
barShowTotalAtTop: false,
//PIE
pieShowInnerLabel: true,
pieInnerLabelAggregate: 'sum',
pieInnerLabelTitle: 'Total',
pieLabelPosition: null,
pieDonutWidth: 40,
pieMinimumSlicePercentage: 0,
pieDisplayLabelAs: 'number',
pieSortBy: 'value',
//METRIC
metricColumnId: '',
metricValueAggregate: 'sum',
metricHeader: null,
metricSubHeader: null,
metricValueLabel: null,
//TABLE
tableColumnOrder: null,
tableColumnWidths: null,
tableHeaderBackgroundColor: null,
tableHeaderFontColor: null,
tableColumnFontColor: null,
//MUST LOOP THROUGH ALL COLUMNS
columnSettings: {},
columnLabelFormats: {}
};
export const DEFAULT_COLUMN_SETTINGS: Required<ColumnSettings> = {
showDataLabels: false,
columnVisualization: 'bar',
lineWidth: 2,
lineStyle: 'line',
lineType: 'normal',
lineSymbolSize: 0,
barRoundness: 8,
showDataLabelsAsPercentage: false
};
export const DEFAULT_COLUMN_LABEL_FORMAT: Required<ColumnLabelFormat> = {
style: 'string',
compactNumbers: false,
columnType: 'text',
displayName: '',
numberSeparatorStyle: ',',
minimumFractionDigits: 0,
maximumFractionDigits: 2,
currency: 'USD',
convertNumberTo: null,
dateFormat: 'auto',
useRelativeTime: false,
isUTC: false,
multiplier: 1,
prefix: '',
suffix: '',
replaceMissingDataWith: 0,
makeLabelHumanReadable: true
};
export const ENABLED_DOTS_ON_LINE = 3.5;
export const DEFAULT_CHART_CONFIG_ENTRIES = Object.entries(DEFAULT_CHART_CONFIG);
export const DEFAULT_BAR_ROUNDNESS = DEFAULT_COLUMN_SETTINGS.barRoundness;
export const MIN_DONUT_WIDTH = 15;
export const DEFAULT_DAY_OF_WEEK_FORMAT = 'ddd';
export const DEFAULT_DATE_FORMAT_DAY_OF_WEEK = 'dddd';
export const DEFAULT_DATE_FORMAT_MONTH_OF_YEAR = 'MMMM';
export const DEFAULT_DATE_FORMAT_QUARTER = 'YYYY [Q]Q';
export const ENABLED_DOTS_ON_LINE_SIZE = 4;
export const DEFAULT_COLUMN_METADATA: ColumnMetaData[] = [];
export const DEFAULT_IBUSTER_METRIC: Required<IBusterMetric> = {
id: 'DEFAULT_ID',
type: 'metric',
name: '',
version_number: 1,
description: '',
time_frame: '',
sql: null,
dataset_id: '',
dataset_name: null,
error: null,
data_metadata: null,
status: VerificationStatus.NOT_REQUESTED,
evaluation_score: 'Moderate',
evaluation_summary: '',
file_name: '',
file: '',
data_source_id: '',
created_at: '',
updated_at: '',
sent_by_id: '',
sent_by_name: '',
permission: ShareRole.CAN_VIEW,
sent_by_avatar_url: null,
dashboards: [],
collections: [],
chart_config: DEFAULT_CHART_CONFIG,
individual_permissions: null,
public_expiry_date: null,
public_enabled_by: null,
publicly_accessible: false,
public_password: null,
versions: []
};
export const DEFAULT_TRENDLINE_CONFIG: Required<IBusterMetricChartConfig['trendlines'][number]> = {
id: 'DEFAULT_ID',
columnId: '',
show: true,
showTrendlineLabel: false,
trendlineLabel: null,
type: 'linear_regression',
trendLineColor: '#FF0000',
trendlineLabelPositionOffset: 85,
projection: true,
lineStyle: 'solid',
polynomialOrder: 2,
aggregateAllCategories: true,
offset: 0
};

View File

@ -1,6 +1,4 @@
export * from './charts';
export * from './defaults';
export * from './interfaces';
export * from './listInterfaces';
export * from './metricDataInterfaces';
export * from './requireInterfaces';

View File

@ -1,88 +1,3 @@
import type { BusterShare, VerificationStatus } from '../share';
import type { BusterChartConfigProps } from './charts';
import type { Metric } from '@buster/server-shared/metrics';
export type BusterMetric = {
id: string;
type: 'metric';
name: string;
version_number: number;
description: string | null;
file_name: string;
time_frame: string;
dataset_id: string;
data_source_id: string;
dataset_name: string | null;
error: string | null;
chart_config?: BusterChartConfigProps;
data_metadata: DataMetadata;
status: VerificationStatus;
evaluation_score: 'Moderate' | 'High' | 'Low';
evaluation_summary: string;
file: string; //yaml file
created_at: string;
updated_at: string;
sent_by_id: string;
sent_by_name: string;
sent_by_avatar_url: string | null;
sql: string | null;
dashboards: {
id: string;
name: string;
}[];
collections: {
id: string;
name: string;
}[];
versions: {
version_number: number;
updated_at: string;
}[];
} & BusterShare;
export type DataMetadata = {
column_count: number;
column_metadata: ColumnMetaData[];
row_count: number;
} | null;
export type ColumnMetaData = {
name: string;
min_value: number | string;
max_value: number | string;
unique_values: number;
simple_type: 'text' | 'number' | 'date';
type:
| 'text'
| 'float'
| 'integer'
| 'date'
| 'float8'
| 'timestamp'
| 'timestamptz'
| 'bool'
| 'date'
| 'time'
| 'boolean'
| 'json'
| 'jsonb'
| 'int8'
| 'int4'
| 'int2'
| 'decimal'
| 'char'
| 'character varying'
| 'character'
| 'varchar'
| 'text'
| 'number'
| 'numeric'
| 'tinytext'
| 'mediumtext'
| 'longtext'
| 'nchar'
| 'nvarchat'
| 'ntext'
| 'float4';
};
export type IDataResult = Record<string, null | string | number>[] | null;
export type BusterMetric = Metric;

View File

@ -1,15 +1,3 @@
import type { VerificationStatus } from '../share';
import type { MetricListItem } from '@buster/server-shared/metrics';
export type BusterMetricListItem = {
id: string;
name: string;
last_edited: string;
dataset_name: string;
dataset_uuid: string;
created_by_id: string;
created_by_name: string;
created_by_email: string;
created_by_avatar: string;
status: VerificationStatus;
is_shared: boolean;
};
export type BusterMetricListItem = MetricListItem;

View File

@ -1,14 +1,14 @@
import type { DataMetadata, IDataResult } from './interfaces';
import type { DataMetadata, DataResult } from '@buster/server-shared/metrics';
export type BusterMetricData = {
data: IDataResult | null;
data: DataResult | null;
data_metadata: DataMetadata;
metricId: string;
};
export type IBusterMetricData = {
data: IDataResult | null;
dataFromRerun?: IDataResult; //this is actually only used in the UI. maybe move this to ?
export type BusterMetricDataExtended = {
data: DataResult | null;
dataFromRerun?: DataResult; //this is actually only used in the UI. maybe move this to ?
data_metadata: DataMetadata;
runRunDataMetadata?: DataMetadata;
metricId: string;

View File

@ -1,13 +0,0 @@
import type { BusterChartConfigProps, ColumnSettings, IColumnLabelFormat } from './charts';
import type { BusterMetric } from './interfaces';
export type IBusterMetricChartConfig = Required<
Omit<BusterChartConfigProps, 'columnLabelFormats'>
> & {
columnLabelFormats: Record<string, Required<IColumnLabelFormat>>;
columnSettings: Required<Record<string, Required<ColumnSettings>>>;
};
export interface IBusterMetric extends Required<BusterMetric> {
chart_config: IBusterMetricChartConfig;
}

View File

@ -6,9 +6,9 @@ import {
} from '@tanstack/react-query';
import last from 'lodash/last';
import type {
BusterMetric,
BusterMetricData,
IBusterMetric,
IBusterMetricData
BusterMetricDataExtended
} from '@/api/asset_interfaces/metric';
import { metricsQueryKeys } from '@/api/query_keys/metric';
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
@ -19,7 +19,7 @@ import type { RustApiError } from '../errors';
import { useGetMetricVersionNumber, useMetricQueryStore } from './metricQueryStore';
import { getMetric, getMetricData } from './requests';
export const useGetMetric = <TData = IBusterMetric>(
export const useGetMetric = <TData = BusterMetric>(
{
id,
versionNumber: versionNumberProp
@ -27,7 +27,7 @@ export const useGetMetric = <TData = IBusterMetric>(
id: string | undefined;
versionNumber?: number | null; //if null it will not use a params from the query params
},
params?: Omit<UseQueryOptions<IBusterMetric, RustApiError, TData>, 'queryKey' | 'queryFn'>
params?: Omit<UseQueryOptions<BusterMetric, RustApiError, TData>, 'queryKey' | 'queryFn'>
) => {
const queryClient = useQueryClient();
const setOriginalMetric = useOriginalMetricStore((x) => x.setOriginalMetric);
@ -108,7 +108,7 @@ export const usePrefetchGetMetricClient = () => {
);
};
export const useGetMetricData = <TData = IBusterMetricData>(
export const useGetMetricData = <TData = BusterMetricDataExtended>(
{
id,
versionNumber: versionNumberProp

View File

@ -1,9 +1,9 @@
import type {
BusterChartConfigProps,
BusterMetric,
BusterMetricData,
BusterMetricListItem
} from '@/api/asset_interfaces/metric';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
import type { VerificationStatus } from '@/api/asset_interfaces/share';
import type {
ShareDeleteRequest,
@ -72,7 +72,7 @@ export const updateMetric = async (params: {
/** SQL query associated with the metric */
sql?: string;
/** chart_config to update */
chart_config?: BusterChartConfigProps;
chart_config?: ChartConfigProps;
/** file in yaml format to update */
file?: string;
/** update the version number of the metric - default is true */

View File

@ -1,6 +1,6 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { create } from 'mutative';
import type { IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric } from '@/api/asset_interfaces/metric';
import { collectionQueryKeys } from '@/api/query_keys/collection';
import { metricsQueryKeys } from '@/api/query_keys/metric';
import { useOriginalMetricStore } from '@/context/Metrics/useOriginalMetricStore';
@ -225,9 +225,9 @@ export const useShareMetric = () => {
variables.id,
selectedVersionNumber
).queryKey;
queryClient.setQueryData(queryKey, (previousData: IBusterMetric | undefined) => {
queryClient.setQueryData(queryKey, (previousData: BusterMetric | undefined) => {
if (!previousData) return previousData;
return create(previousData, (draft: IBusterMetric) => {
return create(previousData, (draft: BusterMetric) => {
draft.individual_permissions = [
...variables.params,
...(draft.individual_permissions || [])
@ -260,9 +260,9 @@ export const useUnshareMetric = () => {
variables.id,
selectedVersionNumber
).queryKey;
queryClient.setQueryData(queryKey, (previousData: IBusterMetric | undefined) => {
queryClient.setQueryData(queryKey, (previousData: BusterMetric | undefined) => {
if (!previousData) return previousData;
return create(previousData, (draft: IBusterMetric) => {
return create(previousData, (draft: BusterMetric) => {
draft.individual_permissions =
draft.individual_permissions?.filter((t) => !variables.data.includes(t.email)) || [];
});
@ -293,9 +293,9 @@ export const useUpdateMetricShare = () => {
variables.id,
selectedVersionNumber
).queryKey;
queryClient.setQueryData(queryKey, (previousData: IBusterMetric | undefined) => {
queryClient.setQueryData(queryKey, (previousData: BusterMetric | undefined) => {
if (!previousData) return previousData;
return create(previousData, (draft: IBusterMetric) => {
return create(previousData, (draft: BusterMetric) => {
draft.individual_permissions =
draft.individual_permissions?.map((t) => {
const found = variables.params.users?.find((v) => v.email === t.email);
@ -330,7 +330,7 @@ export const useUpdateMetric = (params: {
const { selectedVersionNumber } = useGetMetricVersionNumber();
const saveMetricToServer = useMemoizedFn(
async (newMetric: IBusterMetric, prevMetric: IBusterMetric) => {
async (newMetric: BusterMetric, prevMetric: BusterMetric) => {
const changedValues = prepareMetricUpdateMetric(newMetric, prevMetric);
if (changedValues) {
await saveMetric({ ...changedValues, update_version: updateVersion });
@ -342,7 +342,7 @@ export const useUpdateMetric = (params: {
({
id: metricId,
...newMetricPartial
}: Omit<Partial<IBusterMetric>, 'status'> & { id: string }) => {
}: Omit<Partial<BusterMetric>, 'status'> & { id: string }) => {
const options = metricsQueryKeys.metricsGetMetric(metricId, selectedVersionNumber);
const prevMetric = getOriginalMetric(metricId);
const newMetric = create(prevMetric, (draft) => {
@ -358,7 +358,7 @@ export const useUpdateMetric = (params: {
);
const mutationFn = useMemoizedFn(
async (newMetricPartial: Omit<Partial<IBusterMetric>, 'status'> & { id: string }) => {
async (newMetricPartial: Omit<Partial<BusterMetric>, 'status'> & { id: string }) => {
const { newMetric, prevMetric } = combineAndSaveMetric(newMetricPartial);
if (newMetric && prevMetric && saveToServer) {
@ -389,13 +389,13 @@ export const useBulkUpdateMetricVerificationStatus = () => {
onMutate: (variables) => {
for (const metric of variables) {
const latestVersionNumber = getLatestMetricVersion(metric.id);
const foundMetric = queryClient.getQueryData<IBusterMetric>(
const foundMetric = queryClient.getQueryData<BusterMetric>(
metricsQueryKeys.metricsGetMetric(metric.id, latestVersionNumber).queryKey
);
if (foundMetric) {
queryClient.setQueryData(
metricsQueryKeys.metricsGetMetric(metric.id, latestVersionNumber).queryKey,
create(foundMetric, (draft: IBusterMetric) => {
create(foundMetric, (draft: BusterMetric) => {
draft.status = metric.status;
})
);

View File

@ -1,13 +1,13 @@
import { queryOptions } from '@tanstack/react-query';
import type {
BusterMetricListItem,
IBusterMetric,
IBusterMetricData
BusterMetric,
BusterMetricDataExtended
} from '@/api/asset_interfaces/metric';
import type { listMetrics } from '../buster_rest/metrics';
export const metricsGetMetric = (metricId: string, version_number: number | null) => {
return queryOptions<IBusterMetric>({
return queryOptions<BusterMetric>({
queryKey: ['metrics', 'get', metricId, version_number || 'INITIAL'] as const,
staleTime: 60 * 1000
});
@ -27,7 +27,7 @@ export const metricsGetList = (
});
export const metricsGetData = (id: string, version_number: number) =>
queryOptions<IBusterMetricData>({
queryOptions<BusterMetricDataExtended>({
queryKey: ['metrics', 'data', id, version_number || 'INITIAL'] as const,
staleTime: 3 * 60 * 60 * 1000 // 3 hours,
});

View File

@ -2,11 +2,11 @@ import type {
BusterCollection,
BusterDashboardResponse,
BusterShare,
IBusterMetric
BusterMetric
} from '@/api/asset_interfaces';
export const getShareAssetConfig = (
message: IBusterMetric | BusterDashboardResponse | BusterCollection | null
message: BusterMetric | BusterDashboardResponse | BusterCollection | null
): BusterShare | null => {
if (!message) return null;

View File

@ -2,7 +2,7 @@
import type React from 'react';
import { useEffect, useMemo, useState, useTransition } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type {
BusterChartProps,
ChartEncodes,
@ -28,7 +28,7 @@ interface UseBusterChartJSLegendProps {
selectedChartType: ChartType;
chartMounted: boolean;
selectedAxis: ChartEncodes | undefined;
showLegendHeadline: IBusterMetricChartConfig['showLegendHeadline'] | undefined;
showLegendHeadline: BusterMetricChartConfig['showLegendHeadline'] | undefined;
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>;
loading: boolean;
lineGroupType: BusterChartProps['lineGroupType'];

View File

@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib/columnFormatter';
import { AXIS_TITLE_SEPARATOR } from '../../../../commonHelpers/axisHelper';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
@ -12,10 +12,10 @@ export const useY2AxisTitle = ({
y2AxisShowAxisTitle
}: {
y2Axis: string[];
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
isSupportedChartForAxisTitles: boolean;
y2AxisAxisTitle: BusterChartConfigProps['y2AxisAxisTitle'];
y2AxisShowAxisTitle: BusterChartConfigProps['y2AxisShowAxisTitle'];
y2AxisAxisTitle: ChartConfigProps['y2AxisAxisTitle'];
y2AxisShowAxisTitle: ChartConfigProps['y2AxisShowAxisTitle'];
}) => {
const y2AxisColumnLabelFormats = useMemo(() => {
return y2Axis.map((y) => columnLabelFormats[y]);

View File

@ -1,11 +1,11 @@
import type { CoreInteractionOptions } from 'chart.js';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types'; // Add this import
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
interface UseInteractionsProps {
selectedChartType: BusterChartConfigProps['selectedChartType'];
barLayout: BusterChartConfigProps['barLayout'];
selectedChartType: ChartConfigProps['selectedChartType'];
barLayout: ChartConfigProps['barLayout'];
}
export const useInteractions = ({ selectedChartType, barLayout }: UseInteractionsProps) => {

View File

@ -1,5 +1,5 @@
import type { Chart, ChartTypeRegistry, TooltipItem } from 'chart.js';
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib';
import type { ITooltipItem } from '../../../../BusterChartTooltip/interfaces';
import { getPercentage } from './helpers';
@ -7,7 +7,7 @@ import { getPercentage } from './helpers';
export const barAndLineTooltipHelper = (
dataPoints: TooltipItem<keyof ChartTypeRegistry>[],
chart: Chart,
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>,
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>,
keyToUsePercentage: string[],
hasMultipleShownDatasets: boolean,
percentageMode: undefined | 'stacked'

View File

@ -1,11 +1,11 @@
import type { ChartTypeRegistry, TooltipItem } from 'chart.js';
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib/columnFormatter';
import type { ITooltipItem } from '../../../../BusterChartTooltip/interfaces';
export const scatterTooltipHelper = (
dataPoints: TooltipItem<keyof ChartTypeRegistry>[],
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>
): ITooltipItem[] => {
return dataPoints.slice(0, 1).flatMap<ITooltipItem>((dataPoint) => {
const dataPointDataset = dataPoint.dataset;

View File

@ -1,18 +1,19 @@
import type { Scale, ScaleChartOptions } from 'chart.js';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import {
type BusterChartConfigProps,
type BusterChartProps,
type ChartEncodes,
ChartType,
type ComboChartAxis,
type IColumnLabelFormat
} from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn } from '@/hooks';
import { formatYAxisLabel, yAxisSimilar } from '../../../commonHelpers';
import { useY2AxisTitle } from './axisHooks/useY2AxisTitle';
import {
DEFAULT_CHART_CONFIG,
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartConfigProps,
type ChartEncodes,
type ChartType,
type ColumnLabelFormat,
type ComboChartAxis
} from '@buster/server-shared/metrics';
import type { BusterChartProps } from '@/api/asset_interfaces';
export const useY2Axis = ({
columnLabelFormats,
@ -24,7 +25,7 @@ export const useY2Axis = ({
y2AxisStartAxisAtZero,
y2AxisScaleType
}: {
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
selectedAxis: ChartEncodes;
selectedChartType: ChartType;
y2AxisAxisTitle: BusterChartProps['y2AxisAxisTitle'];
@ -64,10 +65,10 @@ export const useY2Axis = ({
return y2AxisScaleType === 'log' ? 'logarithmic' : 'linear';
}, [y2AxisScaleType, isSupportedType]);
const y2AxisColumnFormats: Record<string, IColumnLabelFormat> = useMemo(() => {
const y2AxisColumnFormats: Record<string, ColumnLabelFormat> = useMemo(() => {
if (!isSupportedType) return {};
return y2AxisKeys.reduce<Record<string, IColumnLabelFormat>>((acc, y) => {
return y2AxisKeys.reduce<Record<string, ColumnLabelFormat>>((acc, y) => {
acc[y] = columnLabelFormats[y] || DEFAULT_COLUMN_LABEL_FORMAT;
return acc;
}, {});

View File

@ -1,4 +1,4 @@
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { BusterChartProps, ShowLegendHeadline } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { ArrayOperations } from '@/lib/math';
@ -11,7 +11,7 @@ export const addLegendHeadlines = (
showLegendHeadline: ShowLegendHeadline,
columnMetadata: NonNullable<BusterChartProps['columnMetadata']>,
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>,
selectedChartType: IBusterMetricChartConfig['selectedChartType'],
selectedChartType: BusterMetricChartConfig['selectedChartType'],
xAxisKeys: string[]
) => {
const isScatterChart = selectedChartType === 'scatter';

View File

@ -3,7 +3,7 @@ import React, { useCallback } from 'react';
import {
type BusterChartPropsBase,
DEFAULT_CHART_CONFIG,
type IBusterMetricChartConfig
type BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import { AppDataGrid } from '@/components/ui/table/AppDataGrid';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -30,7 +30,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
}) => {
const { onUpdateMetricChartConfig, onInitializeTableColumnWidths } = useUpdateMetricChart();
const onChangeConfig = useMemoizedFn((config: Partial<IBusterMetricChartConfig>) => {
const onChangeConfig = useMemoizedFn((config: Partial<BusterMetricChartConfig>) => {
if (readOnly) return;
onUpdateMetricChartConfig({ chartConfig: config });
if (
@ -42,7 +42,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
});
const onUpdateTableColumnOrder = useMemoizedFn((columns: string[]) => {
const config: Partial<IBusterMetricChartConfig> = {
const config: Partial<BusterMetricChartConfig> = {
tableColumnOrder: columns
};
@ -51,7 +51,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
const onUpdateTableColumnSize = useMemoizedFn((columns: { key: string; size: number }[]) => {
if (readOnly) return;
const config: Partial<IBusterMetricChartConfig> = {
const config: Partial<BusterMetricChartConfig> = {
tableColumnWidths: columns.reduce<Record<string, number>>((acc, { key, size }) => {
acc[key] = Number(size.toFixed(1));
return acc;

View File

@ -1,7 +1,7 @@
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
export const InnerLabelTitleRecord: Record<
NonNullable<BusterChartConfigProps['pieInnerLabelAggregate']>,
NonNullable<ChartConfigProps['pieInnerLabelAggregate']>,
string
> = {
sum: 'Total',
@ -13,8 +13,8 @@ export const InnerLabelTitleRecord: Record<
};
export const getPieInnerLabelTitle = (
pieInnerLabelTitle: BusterChartConfigProps['pieInnerLabelTitle'],
pieInnerLabelAggregate: BusterChartConfigProps['pieInnerLabelAggregate'] = 'sum'
pieInnerLabelTitle: ChartConfigProps['pieInnerLabelTitle'],
pieInnerLabelAggregate: ChartConfigProps['pieInnerLabelAggregate'] = 'sum'
) => {
return pieInnerLabelTitle ?? InnerLabelTitleRecord[pieInnerLabelAggregate];
};

View File

@ -1,13 +1,13 @@
'use client';
import type { BusterDashboardResponse } from '@/api/asset_interfaces/dashboard';
import type { IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric } from '@/api/asset_interfaces/metric';
import { HydrationBoundaryDashboardStore } from '../Dashboards/useOriginalDashboardStore';
import { HydrationBoundaryMetricStore } from '../Metrics/useOriginalMetricStore';
export const HydrationBoundaryAssetStore: React.FC<{
children: React.ReactNode;
asset: IBusterMetric | BusterDashboardResponse | undefined;
asset: BusterMetric | BusterDashboardResponse | undefined;
}> = ({ children, asset }) => {
if (!asset) return <>{children}</>;

View File

@ -1,5 +1,5 @@
import { useQueryClient } from '@tanstack/react-query';
import type { IBusterMetric, IBusterMetricData } from '@/api/asset_interfaces/metric';
import type { BusterMetric, BusterMetricDataExtended } from '@/api/asset_interfaces/metric';
import { useGetMetricVersionNumber } from '@/api/buster_rest/metrics';
import { queryKeys } from '@/api/query_keys';
import { useMemoizedFn } from '@/hooks';
@ -9,7 +9,7 @@ export const useGetMetricMemoized = () => {
const queryClient = useQueryClient();
const { selectedVersionNumber } = useGetMetricVersionNumber();
const getMetricMemoized = useMemoizedFn(
(metricId: string, versionNumberProp?: number): IBusterMetric => {
(metricId: string, versionNumberProp?: number): BusterMetric => {
const options = queryKeys.metricsGetMetric(
metricId,
versionNumberProp || selectedVersionNumber
@ -25,7 +25,7 @@ export const useGetMetricDataMemoized = () => {
const queryClient = useQueryClient();
const { selectedVersionNumber, latestVersionNumber } = useGetMetricVersionNumber();
const getMetricDataMemoized = useMemoizedFn(
(metricId: string, versionNumberProp?: number): IBusterMetricData | undefined => {
(metricId: string, versionNumberProp?: number): BusterMetricDataExtended | undefined => {
const versionNumber = versionNumberProp ?? selectedVersionNumber ?? latestVersionNumber;
if (versionNumber == null) return undefined;
const options = queryKeys.metricsGetData(metricId, versionNumber);

View File

@ -1,6 +1,6 @@
import { act, renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it } from 'vitest';
import type { IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric } from '@/api/asset_interfaces/metric';
import { DEFAULT_CHART_CONFIG } from '@/api/asset_interfaces/metric/defaults';
import { VerificationStatus } from '@/api/asset_interfaces/share';
import { ShareRole } from '@/api/asset_interfaces/share/shareInterfaces';
@ -13,7 +13,7 @@ describe('useOriginalMetricStore', () => {
});
it('should correctly set and get a metric', () => {
const mockMetric: IBusterMetric = {
const mockMetric: BusterMetric = {
id: 'test-metric-1',
type: 'metric' as const,
name: 'Test Metric',

View File

@ -1,27 +1,27 @@
'use client';
import { create } from 'zustand';
import type { IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric } from '@/api/asset_interfaces/metric';
import { useMount } from '@/hooks';
type OriginalMetricStore = {
originalMetrics: Record<string, IBusterMetric>;
bulkAddOriginalMetrics: (metrics: Record<string, IBusterMetric>) => void;
setOriginalMetric: (metric: IBusterMetric) => void;
getOriginalMetric: (metricId: string | undefined) => IBusterMetric | undefined;
originalMetrics: Record<string, BusterMetric>;
bulkAddOriginalMetrics: (metrics: Record<string, BusterMetric>) => void;
setOriginalMetric: (metric: BusterMetric) => void;
getOriginalMetric: (metricId: string | undefined) => BusterMetric | undefined;
removeOriginalMetric: (metricId: string) => void;
};
export const useOriginalMetricStore = create<OriginalMetricStore>((set, get) => ({
originalMetrics: {},
bulkAddOriginalMetrics: (metrics: Record<string, IBusterMetric>) =>
bulkAddOriginalMetrics: (metrics: Record<string, BusterMetric>) =>
set((prev) => ({
originalMetrics: {
...prev.originalMetrics,
...metrics
}
})),
setOriginalMetric: (metric: IBusterMetric) =>
setOriginalMetric: (metric: BusterMetric) =>
set((state) => ({
originalMetrics: {
...state.originalMetrics,

View File

@ -5,7 +5,7 @@ import { useState } from 'react';
import {
type ColumnSettings,
DEFAULT_CHART_CONFIG,
type IBusterMetricChartConfig,
type BusterMetricChartConfig,
type IColumnLabelFormat
} from '@/api/asset_interfaces/metric';
import { useUpdateMetric } from '@/api/buster_rest/metrics';
@ -39,7 +39,7 @@ export const useUpdateMetricChart = (props?: { metricId?: string; chatId?: strin
chartConfig,
ignoreUndoRedo
}: {
chartConfig: Partial<IBusterMetricChartConfig>;
chartConfig: Partial<BusterMetricChartConfig>;
ignoreUndoRedo?: boolean;
}) => {
const currentMetric = getMetricMemoized(metricId);
@ -52,7 +52,7 @@ export const useUpdateMetricChart = (props?: { metricId?: string; chatId?: strin
// });
}
const newChartConfig: IBusterMetricChartConfig = {
const newChartConfig: BusterMetricChartConfig = {
...DEFAULT_CHART_CONFIG,
...currentMetric.chart_config,
...chartConfig
@ -129,10 +129,10 @@ export const useUpdateMetricChart = (props?: { metricId?: string; chatId?: strin
});
const onInitializeTableColumnWidths = useMemoizedFn(
(tableColumnWidths: IBusterMetricChartConfig['tableColumnWidths']) => {
(tableColumnWidths: BusterMetricChartConfig['tableColumnWidths']) => {
const originalMetric = getOriginalMetric(metricId);
if (originalMetric) {
const newChartConfig: IBusterMetricChartConfig = {
const newChartConfig: BusterMetricChartConfig = {
...DEFAULT_CHART_CONFIG,
...originalMetric.chart_config,
tableColumnWidths

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric } from '@/api/asset_interfaces/metric';
import { Button, type ButtonProps } from '@/components/ui/buttons';
import {
CircleCheck,
@ -9,7 +9,7 @@ import {
import { Popover } from '@/components/ui/popover/Popover';
export const MetricChartEvaluation: React.FC<{
evaluationScore: IBusterMetric['evaluation_score'] | undefined;
evaluationScore: BusterMetric['evaluation_score'] | undefined;
evaluationSummary: string | undefined;
}> = React.memo(({ evaluationScore, evaluationSummary }) => {
const text = useMemo(() => {

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
import { useMemoizedFn } from '@/hooks';
import { cn } from '@/lib/utils';
@ -8,7 +8,7 @@ import { MetricStylingAppSegments } from './config';
export const MetricStylingAppSegment: React.FC<{
segment: MetricStylingAppSegments;
setSegment: (segment: MetricStylingAppSegments) => void;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
className?: string;
}> = React.memo(({ segment, setSegment, selectedChartType, className = '' }) => {
const isTable = selectedChartType === 'table';

View File

@ -1,6 +1,6 @@
import isEqual from 'lodash/isEqual';
import React, { useMemo, useState } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { useMemoizedFn } from '@/hooks';
import type { IColorTheme } from '../Common';
import { ThemeList } from '../Common/ThemeList';
@ -8,8 +8,8 @@ import { ColorStyleSegments } from './ColorStyleSegments';
import { COLORFUL_THEMES, ColorAppSegments, MONOCHROME_THEMES } from './config';
export const ColorsApp: React.FC<{
colors: IBusterMetricChartConfig['colors'];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
colors: BusterMetricChartConfig['colors'];
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = ({ colors, onUpdateChartConfig }) => {
const initialSelectedSegment = useMemo(() => {
const isFromColorfulThemes = COLORFUL_THEMES.some((theme) => isEqual(theme.colors, colors));
@ -44,7 +44,7 @@ export const ColorsApp: React.FC<{
const ColorPicker: React.FC<{
selectedSegmentColors: IColorTheme[];
colors: IBusterMetricChartConfig['colors'];
colors: BusterMetricChartConfig['colors'];
onChangeColorTheme: (theme: IColorTheme) => void;
}> = React.memo(({ selectedSegmentColors, colors, onChangeColorTheme }) => {
const themes = useMemo(() => {

View File

@ -1,4 +1,3 @@
import { DEFAULT_CHART_THEME } from '@/api/asset_interfaces/metric/charts/configColors';
import {
BLUE_THEME,
BLUE_TO_ORANGE_GRADIENT,

View File

@ -1,9 +1,9 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Text } from '@/components/ui/typography';
export const PaletteApp: React.FC<{
colors: IBusterMetricChartConfig['colors'];
colors: BusterMetricChartConfig['colors'];
}> = React.memo(({ colors }) => {
return (
<div className="flex h-full min-h-[200px] items-center justify-center">

View File

@ -1,6 +1,6 @@
import { AnimatePresence, motion } from 'framer-motion';
import React, { useState } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { useUpdateMetricChart } from '@/context/Metrics';
import { useMemoizedFn } from '@/hooks';
import { cn } from '@/lib/classMerge';
@ -11,13 +11,13 @@ import { PaletteApp } from './PaletteApp';
export const StylingAppColors: React.FC<{
className: string;
colors: IBusterMetricChartConfig['colors'];
colors: BusterMetricChartConfig['colors'];
}> = React.memo(({ className, colors }) => {
const [selectedTab, setSelectedTab] = useState<StylingAppColorsTab>(StylingAppColorsTab.Colors);
const { onUpdateMetricChartConfig } = useUpdateMetricChart();
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<IBusterMetricChartConfig>) => {
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<BusterMetricChartConfig>) => {
onUpdateMetricChartConfig({ chartConfig });
});

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BarSortBy } from '@/api/asset_interfaces/metric/charts';
import { BarChartSortNoneIcon } from '@/components/ui/icons/customIcons/BarChart_NoSort';
import { BarChartSortAscIcon } from '@/components/ui/icons/customIcons/BarChartSortAscIcon';
@ -27,8 +27,8 @@ const options: SegmentedItem<BarSortBy[0]>[] = [
];
export const EditBarSorting: React.FC<{
barSortBy: IBusterMetricChartConfig['barSortBy'];
onUpdateChartConfig: (v: Partial<IBusterMetricChartConfig>) => void;
barSortBy: BusterMetricChartConfig['barSortBy'];
onUpdateChartConfig: (v: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ barSortBy, onUpdateChartConfig }) => {
const selectedOption = useMemo(() => {
return (

View File

@ -1,12 +1,12 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnSettings } from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn } from '@/hooks';
import { EditBarRoundness } from '../StylingAppVisualize/SelectAxis/SelectAxisColumnContent/EditBarRoundness';
export const EditBarRoundnessGlobal: React.FC<{
columnSettings: IBusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
columnSettings: BusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ columnSettings, onUpdateChartConfig }) => {
const mostPermissiveBarRoundness = useMemo(() => {
return Object.values(columnSettings).reduce((acc, curr) => {
@ -15,9 +15,9 @@ export const EditBarRoundnessGlobal: React.FC<{
}, []);
const onUpdateBarRoundness = useMemoizedFn((v: Partial<ColumnSettings>) => {
const newColumnSettings: IBusterMetricChartConfig['columnSettings'] = Object.keys(
const newColumnSettings: BusterMetricChartConfig['columnSettings'] = Object.keys(
columnSettings
).reduce<IBusterMetricChartConfig['columnSettings']>((acc, curr) => {
).reduce<BusterMetricChartConfig['columnSettings']>((acc, curr) => {
acc[curr] = { ...columnSettings[curr], ...v };
return acc;
}, {});

View File

@ -1,13 +1,13 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { ENABLED_DOTS_ON_LINE } from '@/api/asset_interfaces';
import { Switch } from '@/components/ui/switch';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
export const EditDotsOnLineGlobal: React.FC<{
columnSettings: IBusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
columnSettings: BusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ columnSettings, onUpdateChartConfig }) => {
const allDotsOnLine = useMemo(() => {
return Object.values(columnSettings).some((column) => column.lineSymbolSize > 0);
@ -15,12 +15,13 @@ export const EditDotsOnLineGlobal: React.FC<{
const onChangeAllSmooth = useMemoizedFn((value: boolean) => {
onUpdateChartConfig({
columnSettings: Object.keys(columnSettings).reduce<
IBusterMetricChartConfig['columnSettings']
>((acc, curr) => {
acc[curr] = { ...columnSettings[curr], lineSymbolSize: value ? ENABLED_DOTS_ON_LINE : 0 };
return acc;
}, {})
columnSettings: Object.keys(columnSettings).reduce<BusterMetricChartConfig['columnSettings']>(
(acc, curr) => {
acc[curr] = { ...columnSettings[curr], lineSymbolSize: value ? ENABLED_DOTS_ON_LINE : 0 };
return acc;
},
{}
)
});
});

View File

@ -1,11 +1,11 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Switch } from '@/components/ui/switch';
import { LabelAndInput } from '../Common';
export const EditGridLines: React.FC<{
gridLines: IBusterMetricChartConfig['gridLines'];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
gridLines: BusterMetricChartConfig['gridLines'];
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ gridLines, onUpdateChartConfig }) => {
return (
<LabelAndInput label={'Grid lines'}>

View File

@ -1,7 +1,7 @@
import React, { useMemo, useState } from 'react';
import {
DEFAULT_CHART_CONFIG,
type IBusterMetricChartConfig,
type BusterMetricChartConfig,
MIN_DONUT_WIDTH
} from '@/api/asset_interfaces';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
@ -23,9 +23,9 @@ export const EditPieAppearance = React.memo(
onUpdateChartConfig,
pieChartAxis
}: {
pieDonutWidth: IBusterMetricChartConfig['pieDonutWidth'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieChartAxis: IBusterMetricChartConfig['pieChartAxis'];
pieDonutWidth: BusterMetricChartConfig['pieDonutWidth'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
pieChartAxis: BusterMetricChartConfig['pieChartAxis'];
}) => {
const [showDonutWidthSelector, setShowDonutWidthSelector] = useState(pieDonutWidth > 0);
const [value, setValue] = useState(pieDonutWidth);

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Input } from '@/components/ui/inputs';
import { Select, type SelectItem } from '@/components/ui/select';
import { LabelAndInput } from '../Common';
@ -10,9 +10,9 @@ export const EditPieInnerLabel = React.memo(
pieInnerLabelTitle,
onUpdateChartConfig
}: {
pieInnerLabelAggregate: IBusterMetricChartConfig['pieInnerLabelAggregate'];
pieInnerLabelTitle: IBusterMetricChartConfig['pieInnerLabelTitle'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieInnerLabelAggregate: BusterMetricChartConfig['pieInnerLabelAggregate'];
pieInnerLabelTitle: BusterMetricChartConfig['pieInnerLabelTitle'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}) => {
return (
<>
@ -31,7 +31,7 @@ export const EditPieInnerLabel = React.memo(
);
EditPieInnerLabel.displayName = 'EditPieInnerLabel';
const options: SelectItem<IBusterMetricChartConfig['pieInnerLabelAggregate']>[] = [
const options: SelectItem<BusterMetricChartConfig['pieInnerLabelAggregate']>[] = [
{ label: 'Sum', value: 'sum' },
{ label: 'Average', value: 'average' },
{ label: 'Median', value: 'median' },
@ -41,8 +41,8 @@ const options: SelectItem<IBusterMetricChartConfig['pieInnerLabelAggregate']>[]
];
const EditPieInnerLabelAggregate: React.FC<{
pieInnerLabelAggregate: IBusterMetricChartConfig['pieInnerLabelAggregate'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieInnerLabelAggregate: BusterMetricChartConfig['pieInnerLabelAggregate'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = ({ pieInnerLabelAggregate, onUpdateChartConfig }) => {
const selectedOption = useMemo(() => {
return options.find((option) => option.value === pieInnerLabelAggregate) || options[0];
@ -56,7 +56,7 @@ const EditPieInnerLabelAggregate: React.FC<{
onChange={(value) => {
const label = options.find((option) => option.value === value)?.label;
onUpdateChartConfig({
pieInnerLabelAggregate: value as IBusterMetricChartConfig['pieInnerLabelAggregate'],
pieInnerLabelAggregate: value as BusterMetricChartConfig['pieInnerLabelAggregate'],
pieInnerLabelTitle: label as string
});
}}
@ -66,8 +66,8 @@ const EditPieInnerLabelAggregate: React.FC<{
};
const EditPieInnerLabelTitle: React.FC<{
pieInnerLabelTitle: IBusterMetricChartConfig['pieInnerLabelTitle'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieInnerLabelTitle: BusterMetricChartConfig['pieInnerLabelTitle'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = ({ pieInnerLabelTitle, onUpdateChartConfig }) => {
return (
<LabelAndInput label="Title">

View File

@ -1,11 +1,11 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select, type SelectItem } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
const options: SelectItem<NonNullable<IBusterMetricChartConfig['pieLabelPosition']>>[] = [
const options: SelectItem<NonNullable<BusterMetricChartConfig['pieLabelPosition']>>[] = [
{ label: 'Outside', value: 'outside' },
{ label: 'Inside', value: 'inside' }
];
@ -15,15 +15,15 @@ export const EditPieLabelLocation = React.memo(
pieLabelPosition,
onUpdateChartConfig
}: {
pieLabelPosition: IBusterMetricChartConfig['pieLabelPosition'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieLabelPosition: BusterMetricChartConfig['pieLabelPosition'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}) => {
const selectedLabelPosition = useMemo(() => {
return options.find((option) => option.value === pieLabelPosition)?.value || 'outside';
}, [pieLabelPosition]);
const hideLabel = pieLabelPosition === 'none' || !pieLabelPosition;
const onChangeSelect = useMemoizedFn((value: IBusterMetricChartConfig['pieLabelPosition']) => {
const onChangeSelect = useMemoizedFn((value: BusterMetricChartConfig['pieLabelPosition']) => {
onUpdateChartConfig({ pieLabelPosition: value });
});

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { SliderWithInputNumber } from '@/components/ui/slider';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
@ -9,8 +9,8 @@ export const EditPieMinimumSlicePercentage = React.memo(
pieMinimumSlicePercentage: initialValue,
onUpdateChartConfig
}: {
pieMinimumSlicePercentage: IBusterMetricChartConfig['pieMinimumSlicePercentage'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieMinimumSlicePercentage: BusterMetricChartConfig['pieMinimumSlicePercentage'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}) => {
const [pieMinimumSlicePercentage, setIntermediateValue] = useState(initialValue);

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Switch } from '@/components/ui/switch';
import { LabelAndInput } from '../Common';
@ -8,8 +8,8 @@ export const EditPieShowInnerLabel = React.memo(
pieShowInnerLabel,
onUpdateChartConfig
}: {
pieShowInnerLabel: IBusterMetricChartConfig['pieShowInnerLabel'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieShowInnerLabel: BusterMetricChartConfig['pieShowInnerLabel'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}) => {
return (
<LabelAndInput label="Show inner label">

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { PieSortBy } from '@/api/asset_interfaces/metric/charts';
import { Empty, SortAlphaAscending, SortNumAscending } from '@/components/ui/icons';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
@ -25,8 +25,8 @@ const options: SegmentedItem<NonNullable<PieSortBy> | 'none'>[] = [
];
export const EditPieSorting: React.FC<{
pieSortBy: IBusterMetricChartConfig['pieSortBy'];
onUpdateChartConfig: (v: Partial<IBusterMetricChartConfig>) => void;
pieSortBy: BusterMetricChartConfig['pieSortBy'];
onUpdateChartConfig: (v: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ pieSortBy, onUpdateChartConfig }) => {
const selectedOption = useMemo(() => {
return (

View File

@ -1,12 +1,12 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn } from '@/hooks';
import { EditReplaceMissingData } from '../StylingAppVisualize/SelectAxis/SelectAxisColumnContent/EditReplaceMissingData';
export const EditReplaceMissingValuesWithGlobal: React.FC<{
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ columnLabelFormats, onUpdateChartConfig }) => {
const mostPermissiveMissingWith = useMemo(() => {
return Object.values(columnLabelFormats).some(
@ -17,9 +17,9 @@ export const EditReplaceMissingValuesWithGlobal: React.FC<{
}, [columnLabelFormats]);
const onUpdateColumnLabel = useMemoizedFn((config: Partial<IColumnLabelFormat>) => {
const newColumnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'] = Object.entries(
const newColumnLabelFormats: BusterMetricChartConfig['columnLabelFormats'] = Object.entries(
columnLabelFormats
).reduce<IBusterMetricChartConfig['columnLabelFormats']>((acc, [key, value]) => {
).reduce<BusterMetricChartConfig['columnLabelFormats']>((acc, [key, value]) => {
acc[key] = { ...value, ...config };
return acc;
}, {});

View File

@ -1,15 +1,15 @@
import isEmpty from 'lodash/isEmpty';
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, ScatterAxis } from '@/api/asset_interfaces/metric/charts';
import { Slider } from '@/components/ui/slider';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
export const EditScatterDotSize: React.FC<{
scatterDotSize: IBusterMetricChartConfig['scatterDotSize'];
scatterDotSize: BusterMetricChartConfig['scatterDotSize'];
selectedAxis: ChartEncodes;
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ scatterDotSize, selectedAxis, onUpdateChartConfig }) => {
const hasSize = !isEmpty((selectedAxis as ScatterAxis).size);
const defaultValue = hasSize ? scatterDotSize : scatterDotSize[0];

View File

@ -1,7 +1,7 @@
import { AnimatePresence, motion } from 'framer-motion';
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import type { ColumnMetaData, IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnMetaData, BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, GoalLine } from '@/api/asset_interfaces/metric/charts';
import { Button } from '@/components/ui/buttons';
import { ColorPicker } from '@/components/ui/color-picker';
@ -18,8 +18,8 @@ interface LoopGoalLine extends GoalLine {
}
export const EditGoalLine: React.FC<{
goalLines: IBusterMetricChartConfig['goalLines'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
goalLines: BusterMetricChartConfig['goalLines'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
columnMetadata: ColumnMetaData[] | undefined;
selectedAxis: ChartEncodes;
}> = React.memo(({ goalLines, onUpdateChartConfig, columnMetadata, selectedAxis }) => {

View File

@ -1,11 +1,11 @@
import first from 'lodash/first';
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select, type SelectItem } from '@/components/ui/select';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
const options: SelectItem<IBusterMetricChartConfig['showLegendHeadline'] | 'false'>[] = [
const options: SelectItem<BusterMetricChartConfig['showLegendHeadline'] | 'false'>[] = [
{ label: 'None', value: 'false' },
{ label: 'Total', value: 'total' },
{ label: 'Average', value: 'average' },
@ -21,11 +21,11 @@ const pieOptions: SelectItem<'false' | 'current'>[] = [
];
export const EditShowHeadline: React.FC<{
showLegendHeadline: IBusterMetricChartConfig['showLegendHeadline'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
showLegendHeadline: BusterMetricChartConfig['showLegendHeadline'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
lineGroupType: BusterMetricChartConfig['lineGroupType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
}> = React.memo(
({ showLegendHeadline, onUpdateChartConfig, lineGroupType, barGroupType, selectedChartType }) => {
const isStackPercentage =
@ -56,7 +56,7 @@ export const EditShowHeadline: React.FC<{
onUpdateChartConfig({
showLegend: true,
showLegendHeadline: transformedValue as IBusterMetricChartConfig['showLegendHeadline']
showLegendHeadline: transformedValue as BusterMetricChartConfig['showLegendHeadline']
});
});

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
@ -14,8 +14,8 @@ export const EditShowLabelPieAsPercentage = React.memo(
pieDisplayLabelAs,
onUpdateChartConfig
}: {
pieDisplayLabelAs: IBusterMetricChartConfig['pieDisplayLabelAs'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
pieDisplayLabelAs: BusterMetricChartConfig['pieDisplayLabelAs'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}) => {
const selectedValue = useMemo(() => {
return options.find((option) => option.value === pieDisplayLabelAs)?.value || 'number';

View File

@ -1,15 +1,15 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, ScatterAxis } from '@/api/asset_interfaces/metric/charts';
import { useLegendAutoShow } from '@/components/ui/charts/BusterChartLegend';
import { Switch } from '@/components/ui/switch';
import { LabelAndInput } from '../Common';
export const EditShowLegend: React.FC<{
showLegend: IBusterMetricChartConfig['showLegend'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
showLegend: BusterMetricChartConfig['showLegend'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
selectedAxis: ChartEncodes;
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(
({ showLegend: showLegendProp, selectedAxis, selectedChartType, onUpdateChartConfig }) => {
const categoryAxisColumnNames = (selectedAxis as ScatterAxis)?.category;

View File

@ -1,12 +1,12 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Switch } from '@/components/ui/switch';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../Common';
export const EditSmoothLinesGlobal: React.FC<{
columnSettings: IBusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
columnSettings: BusterMetricChartConfig['columnSettings'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ columnSettings, onUpdateChartConfig }) => {
const allSmooth = useMemo(() => {
return Object.values(columnSettings).every((column) => column.lineType === 'smooth');
@ -14,12 +14,13 @@ export const EditSmoothLinesGlobal: React.FC<{
const onChangeAllSmooth = useMemoizedFn((value: boolean) => {
onUpdateChartConfig({
columnSettings: Object.keys(columnSettings).reduce<
IBusterMetricChartConfig['columnSettings']
>((acc, curr) => {
acc[curr] = { ...columnSettings[curr], lineType: value ? 'smooth' : 'normal' };
return acc;
}, {})
columnSettings: Object.keys(columnSettings).reduce<BusterMetricChartConfig['columnSettings']>(
(acc, curr) => {
acc[curr] = { ...columnSettings[curr], lineType: value ? 'smooth' : 'normal' };
return acc;
},
{}
)
});
});

View File

@ -3,7 +3,7 @@ import isEqual from 'lodash/isEqual';
import React, { useEffect, useMemo, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import type { ColumnMetaData } from '@/api/asset_interfaces';
import { DEFAULT_TRENDLINE_CONFIG, type IBusterMetricChartConfig } from '@/api/asset_interfaces';
import { DEFAULT_TRENDLINE_CONFIG, type BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, ScatterAxis, Trendline } from '@/api/asset_interfaces/metric/charts';
import { Button } from '@/components/ui/buttons';
import { JOIN_CHARACTER } from '@/components/ui/charts/commonHelpers';
@ -30,13 +30,13 @@ export interface LoopTrendline extends Trendline {
}
export const EditTrendline: React.FC<{
trendlines: IBusterMetricChartConfig['trendlines'];
trendlines: BusterMetricChartConfig['trendlines'];
colors: string[];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
selectedAxis: ChartEncodes;
columnMetadata: ColumnMetaData[];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
}> = React.memo(
({
trendlines,
@ -189,12 +189,12 @@ const EditTrendlineItem: React.FC<{
trend: LoopTrendline;
isNewTrend: boolean;
columnMetadata: ColumnMetaData[];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
yAxisEncodes: string[];
xAxisEncodes: string[];
categoryEncodes: string[] | null | undefined;
colors: string[];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
onUpdateExistingTrendline: (trend: LoopTrendline) => void;
onDeleteTrendline: (id: string) => void;
}> = React.memo(
@ -254,8 +254,8 @@ const TrendlineItemContent: React.FC<{
xAxisEncodes: string[];
colors: string[];
categoryEncodes: string[] | null | undefined;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
onUpdateExistingTrendline: (trend: LoopTrendline) => void;
}> = React.memo(
({

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { ColumnMetaData, IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnMetaData, BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select, type SelectItem } from '@/components/ui/select';
import { formatLabel } from '@/lib';
import { LabelAndInput } from '../../Common';
@ -15,7 +15,7 @@ export const TrendlineColumnId = React.memo(
}: {
trend: LoopTrendline;
columnMetadata: ColumnMetaData[];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
onUpdateExistingTrendline: (trend: LoopTrendline) => void;
yAxisEncodes: string[];
}) => {

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartType, Trendline } from '@/api/asset_interfaces/metric/charts';
import { TriangleWarning } from '@/components/ui/icons';
import { Select, type SelectItem } from '@/components/ui/select';
@ -22,7 +22,7 @@ export const EditTrendlineOption = React.memo(
onUpdateExistingTrendline: (trend: LoopTrendline) => void;
yAxisEncodes: string[];
xAxisEncodes: string[];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
selectedChartType: ChartType;
}) => {
const { type } = trend;

View File

@ -1,18 +1,18 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { useMemoizedFn } from '@/hooks';
import { EditAxisScale } from '../StylingAppVisualize/SelectAxis/SelectAxisSettingsContent/EditAxisScale';
export const EditYAxisScaleGlobal: React.FC<{
yAxisScaleType: IBusterMetricChartConfig['yAxisScaleType'];
y2AxisScaleType: IBusterMetricChartConfig['y2AxisScaleType'];
onUpdateChartConfig: (config: Partial<IBusterMetricChartConfig>) => void;
yAxisScaleType: BusterMetricChartConfig['yAxisScaleType'];
y2AxisScaleType: BusterMetricChartConfig['y2AxisScaleType'];
onUpdateChartConfig: (config: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ yAxisScaleType, y2AxisScaleType, onUpdateChartConfig }) => {
const mostPermissiveScale = useMemo(() => {
return yAxisScaleType === y2AxisScaleType ? yAxisScaleType : 'linear';
}, [yAxisScaleType, y2AxisScaleType]);
const onChangeAxisScale = useMemoizedFn((value: IBusterMetricChartConfig['yAxisScaleType']) => {
const onChangeAxisScale = useMemoizedFn((value: BusterMetricChartConfig['yAxisScaleType']) => {
onUpdateChartConfig({
yAxisScaleType: value,
y2AxisScaleType: value

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import { type BarAndLineAxis, ChartType } from '@/api/asset_interfaces/metric/charts';
import { Separator } from '@/components/ui/seperator';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -78,16 +78,16 @@ export const StylingAppStyling: React.FC<
const { onUpdateMetricChartConfig } = useUpdateMetricChart();
const onUpdateDataLabel = useMemoizedFn((v: boolean) => {
const newColumnSettings: IBusterMetricChartConfig['columnSettings'] = Object.keys(
const newColumnSettings: BusterMetricChartConfig['columnSettings'] = Object.keys(
columnSettings
).reduce<IBusterMetricChartConfig['columnSettings']>((acc, curr) => {
).reduce<BusterMetricChartConfig['columnSettings']>((acc, curr) => {
acc[curr] = { ...columnSettings[curr], showDataLabels: v };
return acc;
}, {});
onUpdateChartConfig({ columnSettings: newColumnSettings });
});
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<IBusterMetricChartConfig>) => {
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<BusterMetricChartConfig>) => {
onUpdateMetricChartConfig({ chartConfig });
});
@ -185,9 +185,9 @@ export const StylingAppStyling: React.FC<
const GlobalSettings: React.FC<
{
className: string;
columnSettings: IBusterMetricChartConfig['columnSettings'];
yAxisShowAxisTitle: IBusterMetricChartConfig['yAxisShowAxisTitle'];
yAxisShowAxisLabel: IBusterMetricChartConfig['yAxisShowAxisLabel'];
columnSettings: BusterMetricChartConfig['columnSettings'];
yAxisShowAxisTitle: BusterMetricChartConfig['yAxisShowAxisTitle'];
yAxisShowAxisLabel: BusterMetricChartConfig['yAxisShowAxisLabel'];
} & Parameters<typeof EditShowLegend>[0] &
Parameters<typeof EditGridLines>[0] &
Omit<Parameters<typeof EditHideYAxis>[0], 'hideYAxis'> &
@ -294,9 +294,9 @@ const GlobalSettings: React.FC<
const ChartSpecificSettings: React.FC<
{
className: string;
columnSettings: IBusterMetricChartConfig['columnSettings'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnSettings: BusterMetricChartConfig['columnSettings'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
} & Parameters<typeof EditBarRoundnessGlobal>[0] &
Parameters<typeof EditBarSorting>[0] &
Parameters<typeof EditPieSorting>[0] &
@ -567,7 +567,7 @@ const EtcSettings: React.FC<
const PieSettings: React.FC<
{
className: string;
pieDonutWidth: IBusterMetricChartConfig['pieDonutWidth'];
pieDonutWidth: BusterMetricChartConfig['pieDonutWidth'];
} & Parameters<typeof EditPieShowInnerLabel>[0] &
Parameters<typeof EditPieInnerLabel>[0]
> = React.memo(

View File

@ -1,10 +1,10 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import { Text } from '@/components/ui/typography';
export const StylingAppStylingNotSupported = React.memo(
({ selectedChartType }: { selectedChartType: IBusterMetricChartConfig['selectedChartType'] }) => {
({ selectedChartType }: { selectedChartType: BusterMetricChartConfig['selectedChartType'] }) => {
const title = useMemo(() => {
if (selectedChartType === 'table') {
return 'Styling for tables charts is coming soon';

View File

@ -1,6 +1,6 @@
import isEmpty from 'lodash/isEmpty';
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type {
CategoryAxisStyleConfig,
ChartEncodes,
@ -46,7 +46,7 @@ export const SelectAxis: React.FC<
return Object.assign(acc, { [axis]: zone.items });
}, {} as ChartEncodes);
const newChartConfig: Partial<IBusterMetricChartConfig> = {
const newChartConfig: Partial<BusterMetricChartConfig> = {
[selectedAxisToEdit]: newChartEncodes
};

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { ChartType, type ColumnSettings } from '@/api/asset_interfaces/metric/charts';
import { ChartBarAxisX, ChartLine, ChartScatter } from '@/components/ui/icons';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
@ -40,7 +40,7 @@ const options = [
export const EditDisplayAs: React.FC<{
columnVisualization: Required<ColumnSettings>['columnVisualization'];
onUpdateColumnSettingConfig: (columnSettings: Partial<ColumnSettings>) => void;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
}> = React.memo(({ columnVisualization, onUpdateColumnSettingConfig, selectedChartType }) => {
const selectedOption = useMemo(() => {
if (selectedChartType === 'bar') return 'bar';

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { type ChartEncodes, type ColumnSettings } from '@/api/asset_interfaces/metric/charts';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts/columnLabelInterfaces';
import { useGetCurrencies } from '@/api/buster_rest/currency';
@ -28,14 +28,14 @@ import { EditSuffix } from './EditSuffix';
import { EditTitle } from './EditTitle';
export const SelectAxisDropdownContent: React.FC<{
columnSetting: IBusterMetricChartConfig['columnSettings'][string];
columnSetting: BusterMetricChartConfig['columnSettings'][string];
columnLabelFormat: IColumnLabelFormat;
selectedAxis: ChartEncodes | null;
id: string;
className?: string;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
zoneId: SelectAxisContainerId;
hideTitle?: boolean;
classNames?: {
@ -115,13 +115,13 @@ const ColumnSettingComponent: React.FC<{
formattedTitle: string;
onUpdateColumnConfig: (columnLabelFormat: Partial<IColumnLabelFormat>) => void;
onUpdateColumnSettingConfig: (columnSetting: Partial<ColumnSettings>) => void;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
selectedAxis: ChartEncodes | null;
columnSetting: IBusterMetricChartConfig['columnSettings'][string];
columnSetting: BusterMetricChartConfig['columnSettings'][string];
columnLabelFormat: IColumnLabelFormat;
zoneId: SelectAxisContainerId;
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
rowCount: number;
}> = ({
formattedTitle,
@ -274,7 +274,7 @@ const LabelSettings: React.FC<{
onUpdateColumnConfig: (columnLabelFormat: Partial<IColumnLabelFormat>) => void;
id: string;
zoneId: SelectAxisContainerId;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
}> = ({
columnLabelFormat,
onUpdateColumnConfig,

View File

@ -1,13 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react';
import { HttpResponse, http } from 'msw';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import { type IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Button } from '@/components/ui/buttons/Button';
import { SelectAxisContainerId } from './config';
import {
SelectAxisColumnPopover,
type SelectAxisColumnPopoverProps
} from './SelectAxisColumnPopover';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
const meta: Meta<typeof SelectAxisColumnPopover> = {
title: 'Controllers/EditMetricController/SelectAxisColumnPopover',
@ -60,7 +60,7 @@ const mockProps: SelectAxisColumnPopoverProps = {
replaceMissingDataWith: null,
makeLabelHumanReadable: true,
compactNumbers: false
} satisfies IColumnLabelFormat,
} satisfies ColumnLabelFormat,
columnSetting: {
showDataLabels: false,
showDataLabelsAsPercentage: false,
@ -70,7 +70,7 @@ const mockProps: SelectAxisColumnPopoverProps = {
lineType: 'normal' as const,
lineSymbolSize: 0,
barRoundness: 8
} satisfies IBusterMetricChartConfig['columnSettings'][string],
} satisfies BusterMetricChartConfig['columnSettings'][string],
id: 'test-id',
selectedChartType: 'bar',
barGroupType: 'group',

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { Popover } from '@/components/ui/popover/Popover';
import type { SelectAxisContainerId } from './config';
@ -7,12 +7,12 @@ import { SelectAxisDropdownContent } from './SelectAxisColumnContent';
export interface SelectAxisColumnPopoverProps {
columnLabelFormat: IColumnLabelFormat;
columnSetting: IBusterMetricChartConfig['columnSettings'][string];
columnSetting: BusterMetricChartConfig['columnSettings'][string];
children: React.ReactNode;
id: string;
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
zoneId: SelectAxisContainerId;
selectedAxis: ChartEncodes | null;
rowCount: number;

View File

@ -1,7 +1,7 @@
import type { DraggableAttributes } from '@dnd-kit/core';
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ChartEncodes, IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { Button } from '@/components/ui/buttons';
import { DotsVertical } from '@/components/ui/icons';
@ -59,10 +59,10 @@ export const SelectAxisItemAvailableContainer = React.memo(
const ThreeDotMenu: React.FC<{
isDragging?: boolean;
columnLabelFormat: IColumnLabelFormat;
columnSetting: IBusterMetricChartConfig['columnSettings'][string];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
columnSetting: BusterMetricChartConfig['columnSettings'][string];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
zoneId: SelectAxisContainerId;
selectedAxis: ChartEncodes | null;
id: string;

View File

@ -1,7 +1,6 @@
import type { DraggableAttributes } from '@dnd-kit/core';
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
import React, { useMemo } from 'react';
import type { ChartEncodes, IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { ErrorBoundary } from '@/components/ui/error';
import { useUpdateMetricChart } from '@/context/Metrics';
import { useMemoizedFn } from '@/hooks';
@ -10,6 +9,7 @@ import { chartTypeToAxis, type SelectAxisContainerId, zoneIdToAxis } from './con
import { SelectAxisDropdownContent } from './SelectAxisColumnContent';
import { SelectAxisItemLabel } from './SelectAxisItemLabel';
import { useSelectAxisContextSelector } from './useSelectAxisContext';
import type { ChartEncodes, ColumnLabelFormat } from '@buster/server-shared/metrics';
interface SelectAxisItemContainerProps {
id: string;
@ -25,7 +25,7 @@ interface SelectAxisItemContainerProps {
export const SelectAxisItemContainer = React.memo(
React.forwardRef<HTMLDivElement, SelectAxisItemContainerProps>(
({ id, zoneId, isPlaceholder, ...draggingProps }, ref) => {
const columnLabelFormat: undefined | IColumnLabelFormat = useSelectAxisContextSelector(
const columnLabelFormat: undefined | ColumnLabelFormat = useSelectAxisContextSelector(
(x) => x.columnLabelFormats[id]
);
const selectedAxis = useSelectAxisContextSelector((x) => x.selectedAxis);

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { useUpdateMetricChart } from '@/context/Metrics';
import { useMemoizedFn } from '@/hooks';
import { useSelectAxisContextSelector } from '../useSelectAxisContext';
@ -18,7 +18,7 @@ export const CategoryAxisSettingContent: React.FC = React.memo(() => {
contextOnUpdateMetricChartConfig({ chartConfig: { categoryAxisTitle: value } });
});
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<IBusterMetricChartConfig>) => {
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<BusterMetricChartConfig>) => {
contextOnUpdateMetricChartConfig({ chartConfig });
});

View File

@ -1,10 +1,10 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { AppSegmented, type SegmentedItem } from '@/components/ui/segmented';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../../../Common/LabelAndInput';
const options: SegmentedItem<IBusterMetricChartConfig['xAxisLabelRotation']>[] = [
const options: SegmentedItem<BusterMetricChartConfig['xAxisLabelRotation']>[] = [
{ label: 'Auto', value: 'auto' },
{ label: '0°', value: 0 },
{ label: '45°', value: 45 },
@ -12,17 +12,17 @@ const options: SegmentedItem<IBusterMetricChartConfig['xAxisLabelRotation']>[] =
];
export const EditAxisLabelRotation: React.FC<{
xAxisLabelRotation: IBusterMetricChartConfig['xAxisLabelRotation'];
onChangeLabelRotation: (value: IBusterMetricChartConfig['xAxisLabelRotation']) => void;
xAxisLabelRotation: BusterMetricChartConfig['xAxisLabelRotation'];
onChangeLabelRotation: (value: BusterMetricChartConfig['xAxisLabelRotation']) => void;
}> = React.memo(({ xAxisLabelRotation, onChangeLabelRotation }) => {
const selectedOption: IBusterMetricChartConfig['xAxisLabelRotation'] = useMemo(() => {
const selectedOption: BusterMetricChartConfig['xAxisLabelRotation'] = useMemo(() => {
return (
options.find((option) => option.value === xAxisLabelRotation)?.value ?? options[0]?.value
);
}, [xAxisLabelRotation]);
const onChange = useMemoizedFn((value: SegmentedItem<string>) => {
onChangeLabelRotation(value.value as IBusterMetricChartConfig['xAxisLabelRotation']);
onChangeLabelRotation(value.value as BusterMetricChartConfig['xAxisLabelRotation']);
});
return (

View File

@ -1,18 +1,16 @@
import React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select } from '@/components/ui/select';
import { LabelAndInput } from '../../../Common/LabelAndInput';
const options: { label: string; value: IBusterMetricChartConfig['yAxisScaleType'] }[] = [
const options: { label: string; value: BusterMetricChartConfig['yAxisScaleType'] }[] = [
{ label: 'Linear', value: 'linear' },
{ label: 'Logarithmic', value: 'log' }
];
export const EditAxisScale: React.FC<{
scaleType:
| IBusterMetricChartConfig['yAxisScaleType']
| IBusterMetricChartConfig['y2AxisScaleType'];
onChangeAxisScale: (value: IBusterMetricChartConfig['yAxisScaleType']) => void;
scaleType: BusterMetricChartConfig['yAxisScaleType'] | BusterMetricChartConfig['y2AxisScaleType'];
onChangeAxisScale: (value: BusterMetricChartConfig['yAxisScaleType']) => void;
}> = React.memo(({ scaleType, onChangeAxisScale }) => {
return (
<LabelAndInput label="Scale">

View File

@ -1,28 +1,28 @@
import React, { useMemo, useState } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select, type SelectItem } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../../../Common/LabelAndInput';
const barGroupingOptions: SelectItem<NonNullable<IBusterMetricChartConfig['barGroupType']>>[] = [
const barGroupingOptions: SelectItem<NonNullable<BusterMetricChartConfig['barGroupType']>>[] = [
{ label: 'Grouped', value: 'group' },
{ label: 'Stacked', value: 'stack' }
];
const lineGroupingOptions: SelectItem<
NonNullable<IBusterMetricChartConfig['lineGroupType']> | 'default'
NonNullable<BusterMetricChartConfig['lineGroupType']> | 'default'
>[] = [
{ label: 'Default', value: 'default' },
{ label: 'Stacked', value: 'stack' }
];
export const EditGrouping: React.FC<{
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
onUpdateChartConfig: (value: Partial<IBusterMetricChartConfig>) => void;
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
barShowTotalAtTop: IBusterMetricChartConfig['barShowTotalAtTop'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
onUpdateChartConfig: (value: Partial<BusterMetricChartConfig>) => void;
lineGroupType: BusterMetricChartConfig['lineGroupType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
barShowTotalAtTop: BusterMetricChartConfig['barShowTotalAtTop'];
}> = React.memo(
({ selectedChartType, onUpdateChartConfig, lineGroupType, barGroupType, barShowTotalAtTop }) => {
const isBarChart = selectedChartType === 'bar';
@ -30,9 +30,7 @@ export const EditGrouping: React.FC<{
isBarChart ? barGroupType === 'stack' : lineGroupType === 'stack'
);
const [value, setValue] = useState<
| IBusterMetricChartConfig['lineGroupType']
| 'default'
| IBusterMetricChartConfig['barGroupType']
BusterMetricChartConfig['lineGroupType'] | 'default' | BusterMetricChartConfig['barGroupType']
>(isBarChart ? barGroupType : lineGroupType);
const showTotal = useMemo(() => {
@ -62,21 +60,21 @@ export const EditGrouping: React.FC<{
const onChangeGroupType = useMemoizedFn(
(
value: IBusterMetricChartConfig['lineGroupType'] | IBusterMetricChartConfig['barGroupType']
value: BusterMetricChartConfig['lineGroupType'] | BusterMetricChartConfig['barGroupType']
) => {
if (selectedChartType === 'bar') {
const barGroupType = value as IBusterMetricChartConfig['barGroupType'];
const barGroupType = value as BusterMetricChartConfig['barGroupType'];
onUpdateChartConfig({ barGroupType });
} else {
const lineGroupType = value as IBusterMetricChartConfig['lineGroupType'];
const lineGroupType = value as BusterMetricChartConfig['lineGroupType'];
onUpdateChartConfig({ lineGroupType });
}
}
);
const onChangeGrouping = (value: string) => {
setValue(value as IBusterMetricChartConfig['barGroupType']);
onChangeGroupType(value as IBusterMetricChartConfig['barGroupType']);
setValue(value as BusterMetricChartConfig['barGroupType']);
onChangeGroupType(value as BusterMetricChartConfig['barGroupType']);
};
return (

View File

@ -1,14 +1,12 @@
import React, { useState } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Input } from '@/components/ui/inputs';
import { Switch } from '@/components/ui/switch';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../../../Common/LabelAndInput';
export const EditShowAxisTitle: React.FC<{
axisTitle:
| IBusterMetricChartConfig['xAxisAxisTitle']
| IBusterMetricChartConfig['yAxisAxisTitle'];
axisTitle: BusterMetricChartConfig['xAxisAxisTitle'] | BusterMetricChartConfig['yAxisAxisTitle'];
showAxisTitle: boolean;
formattedColumnTitle: string;
onChangeAxisTitle: (value: string | null) => void;
@ -64,9 +62,9 @@ const EditToggleAxisTitle: React.FC<{
export const EditAxisTitle: React.FC<{
label?: string;
axisTitle:
| IBusterMetricChartConfig['xAxisAxisTitle']
| IBusterMetricChartConfig['yAxisAxisTitle']
| IBusterMetricChartConfig['categoryAxisTitle'];
| BusterMetricChartConfig['xAxisAxisTitle']
| BusterMetricChartConfig['yAxisAxisTitle']
| BusterMetricChartConfig['categoryAxisTitle'];
onChangeTitle: (v: string | null) => void;
formattedColumnTitle: string;
}> = ({ axisTitle, onChangeTitle, formattedColumnTitle, label = 'Axis title' }) => {

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { AXIS_TITLE_SEPARATOR } from '@/components/ui/charts/commonHelpers/axisHelper';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -60,7 +60,7 @@ export const XAxisSettingContent: React.FC = React.memo(() => {
});
const onChangeLabelRotation = useMemoizedFn(
(xAxisLabelRotation: IBusterMetricChartConfig['xAxisLabelRotation']) => {
(xAxisLabelRotation: BusterMetricChartConfig['xAxisLabelRotation']) => {
onUpdateMetricChartConfig({
chartConfig: {
xAxisLabelRotation

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnLabelFormat, ComboChartAxis } from '@/api/asset_interfaces/metric/charts';
import { AXIS_TITLE_SEPARATOR } from '@/components/ui/charts/commonHelpers/axisHelper';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -52,7 +52,7 @@ export const Y2AxisSettingContent: React.FC = React.memo(() => {
});
const onChangeAxisScale = useMemoizedFn(
(y2AxisScaleType: IBusterMetricChartConfig['y2AxisScaleType']) => {
(y2AxisScaleType: BusterMetricChartConfig['y2AxisScaleType']) => {
onUpdateMetricChartConfig({
chartConfig: {
y2AxisScaleType

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { AXIS_TITLE_SEPARATOR } from '@/components/ui/charts/commonHelpers/axisHelper';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -52,7 +52,7 @@ export const YAxisSettingContent: React.FC = React.memo(() => {
});
const onChangeAxisScale = useMemoizedFn(
(yAxisScaleType: IBusterMetricChartConfig['yAxisScaleType']) => {
(yAxisScaleType: BusterMetricChartConfig['yAxisScaleType']) => {
onUpdateMetricChartConfig({
chartConfig: {
yAxisScaleType

View File

@ -1,5 +1,5 @@
import isEmpty from 'lodash/isEmpty';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import { SelectAxisContainerId } from './config';
import type { DropZone } from './SelectAxisDragContainer/interfaces';
@ -60,11 +60,11 @@ const makeY2AxisDropZone = (y2Items: string[] | null | undefined): DropZone =>
makeDropZone(SelectAxisContainerId.Y2Axis, y2Items ?? EMPTY_ARRAY);
export const chartTypeToDropZones: Record<
IBusterMetricChartConfig['selectedChartType'],
BusterMetricChartConfig['selectedChartType'],
(selectedAxis: Parameters<typeof getChartTypeDropZones>[0]['selectedAxis']) => DropZone[]
> = {
['bar']: (selectedAxis) => {
const _selectedAxis = selectedAxis as IBusterMetricChartConfig['barAndLineAxis'];
const _selectedAxis = selectedAxis as BusterMetricChartConfig['barAndLineAxis'];
return [
makeXAxisDropZone(_selectedAxis.x),
makeYAxisDropZone(_selectedAxis.y),
@ -73,7 +73,7 @@ export const chartTypeToDropZones: Record<
];
},
['line']: (selectedAxis) => {
const _selectedAxis = selectedAxis as IBusterMetricChartConfig['barAndLineAxis'];
const _selectedAxis = selectedAxis as BusterMetricChartConfig['barAndLineAxis'];
return [
makeXAxisDropZone(_selectedAxis.x),
makeYAxisDropZone(_selectedAxis.y),
@ -82,7 +82,7 @@ export const chartTypeToDropZones: Record<
];
},
['scatter']: (selectedAxis) => {
const _selectedAxis = selectedAxis as IBusterMetricChartConfig['scatterAxis'];
const _selectedAxis = selectedAxis as BusterMetricChartConfig['scatterAxis'];
return [
makeXAxisDropZone(_selectedAxis.x),
makeYAxisDropZone(_selectedAxis.y),
@ -92,7 +92,7 @@ export const chartTypeToDropZones: Record<
];
},
['pie']: (selectedAxis) => {
const _selectedAxis = selectedAxis as IBusterMetricChartConfig['pieChartAxis'];
const _selectedAxis = selectedAxis as BusterMetricChartConfig['pieChartAxis'];
return [
makeXAxisDropZone(_selectedAxis.x),
makeYAxisDropZone(_selectedAxis.y),
@ -100,7 +100,7 @@ export const chartTypeToDropZones: Record<
];
},
['combo']: (selectedAxis) => {
const _selectedAxis = selectedAxis as IBusterMetricChartConfig['comboChartAxis'];
const _selectedAxis = selectedAxis as BusterMetricChartConfig['comboChartAxis'];
return [
makeXAxisDropZone(_selectedAxis.x),
makeYComboAxisDropZone(_selectedAxis.y),
@ -122,12 +122,12 @@ export const getChartTypeDropZones = ({
chartType,
selectedAxis
}: {
chartType: IBusterMetricChartConfig['selectedChartType'];
chartType: BusterMetricChartConfig['selectedChartType'];
selectedAxis:
| IBusterMetricChartConfig['comboChartAxis']
| IBusterMetricChartConfig['pieChartAxis']
| IBusterMetricChartConfig['scatterAxis']
| IBusterMetricChartConfig['barAndLineAxis'];
| BusterMetricChartConfig['comboChartAxis']
| BusterMetricChartConfig['pieChartAxis']
| BusterMetricChartConfig['scatterAxis']
| BusterMetricChartConfig['barAndLineAxis'];
}): DropZone[] => {
return chartTypeToDropZones[chartType](selectedAxis);
};

View File

@ -1,7 +1,7 @@
import type React from 'react';
import type { PropsWithChildren } from 'react';
import { createContext, useContextSelector } from 'use-context-selector';
import type { ColumnMetaData, IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnMetaData, BusterMetricChartConfig } from '@/api/asset_interfaces';
import type {
CategoryAxisStyleConfig,
ChartEncodes,
@ -16,19 +16,19 @@ export interface ISelectAxisContext
Required<Omit<XAxisConfig, 'xAxisTimeInterval'>>,
Required<CategoryAxisStyleConfig> {
selectedAxis: ChartEncodes | null;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
columnMetadata: ColumnMetaData[];
columnSettings: IBusterMetricChartConfig['columnSettings'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
showLegend: IBusterMetricChartConfig['showLegend'];
showLegendHeadline: IBusterMetricChartConfig['showLegendHeadline'];
gridLines: IBusterMetricChartConfig['gridLines'];
goalLines: IBusterMetricChartConfig['goalLines'];
trendlines: IBusterMetricChartConfig['trendlines'];
barShowTotalAtTop: IBusterMetricChartConfig['barShowTotalAtTop'];
disableTooltip: IBusterMetricChartConfig['disableTooltip'];
columnSettings: BusterMetricChartConfig['columnSettings'];
selectedChartType: BusterMetricChartConfig['selectedChartType'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
showLegend: BusterMetricChartConfig['showLegend'];
showLegendHeadline: BusterMetricChartConfig['showLegendHeadline'];
gridLines: BusterMetricChartConfig['gridLines'];
goalLines: BusterMetricChartConfig['goalLines'];
trendlines: BusterMetricChartConfig['trendlines'];
barShowTotalAtTop: BusterMetricChartConfig['barShowTotalAtTop'];
disableTooltip: BusterMetricChartConfig['disableTooltip'];
rowCount: number;
}

View File

@ -1,5 +1,5 @@
import type React from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import {
type CategoryAxisStyleConfig,
type ChartEncodes,
@ -17,11 +17,11 @@ import { StylingMetric } from './StylingMetric';
export const StylingAppVisualize: React.FC<
{
barLayout: IBusterMetricChartConfig['barLayout'];
barLayout: BusterMetricChartConfig['barLayout'];
selectedAxis: ChartEncodes;
className?: string;
colors: string[];
disableTooltip: IBusterMetricChartConfig['disableTooltip'];
disableTooltip: BusterMetricChartConfig['disableTooltip'];
} & Required<YAxisConfig> &
Required<CategoryAxisStyleConfig> &
Required<Y2AxisConfig> &

View File

@ -1,16 +1,15 @@
import React, { useEffect, useRef } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Input } from '@/components/ui/inputs';
import { LabelAndInput } from '../../Common';
export const EditHeaderTitle: React.FC<{
value: string | undefined;
type: 'header' | 'subHeader';
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ value, onUpdateChartConfig, type }) => {
const inputRef = useRef<HTMLInputElement>(null);
const key: keyof IBusterMetricChartConfig =
type === 'header' ? 'metricHeader' : 'metricSubHeader';
const key: keyof BusterMetricChartConfig = type === 'header' ? 'metricHeader' : 'metricSubHeader';
const title = type === 'header' ? 'Header' : 'Sub-header';
const placeholder = type === 'header' ? 'Enter header' : 'Enter sub-header';

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { DEFAULT_COLUMN_SETTINGS } from '@/api/asset_interfaces';
import { ChartType, type DerivedMetricTitle } from '@/api/asset_interfaces/metric/charts';
import { Button } from '@/components/ui/buttons';
@ -15,15 +15,15 @@ import type { createColumnFieldOptions } from './helpers';
export const EditMetricField: React.FC<{
label?: string;
columnId: IBusterMetricChartConfig['metricColumnId'];
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnId: BusterMetricChartConfig['metricColumnId'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
columnFieldOptions: ReturnType<typeof createColumnFieldOptions>;
rowCount: number;
onUpdateMetricField: (config: {
metricColumnId: string;
metricValueAggregate?: DerivedMetricTitle['aggregate'];
}) => void;
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(
({
columnId,
@ -82,9 +82,9 @@ export const EditMetricField: React.FC<{
EditMetricField.displayName = 'EditMetricField';
const StylingPopover: React.FC<{
metricColumnId: IBusterMetricChartConfig['metricColumnId'];
columnLabelFormat: IBusterMetricChartConfig['columnLabelFormats'][string];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
metricColumnId: BusterMetricChartConfig['metricColumnId'];
columnLabelFormat: BusterMetricChartConfig['columnLabelFormats'][string];
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
rowCount: number;
}> = React.memo(({ metricColumnId, columnLabelFormat, rowCount }) => {
return (

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { Select, type SelectItem } from '@/components/ui/select';
import { useMemoizedFn } from '@/hooks';
import { LabelAndInput } from '../../Common';
@ -26,11 +26,11 @@ const allOptions: SelectItem<'custom' | 'columnTitle' | 'columnValue' | 'none'>[
const onlyCustomOptions = [allOptions[0], allOptions[1]];
export const EditMetricHeader: React.FC<{
header: IBusterMetricChartConfig['metricHeader'] | IBusterMetricChartConfig['metricSubHeader'];
header: BusterMetricChartConfig['metricHeader'] | BusterMetricChartConfig['metricSubHeader'];
type: 'header' | 'subHeader';
firstColumnId: string;
hideDerivedMetricOption: boolean;
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = React.memo(({ header, type, firstColumnId, hideDerivedMetricOption, onUpdateChartConfig }) => {
const selectedOption = useMemo(() => {
if (header === null) return 'none';

View File

@ -1,6 +1,6 @@
import last from 'lodash/last';
import React, { useMemo } from 'react';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import type { SelectItem } from '@/components/ui/select';
import { Select } from '@/components/ui/select';
@ -8,7 +8,7 @@ import { useMemoizedFn } from '@/hooks';
import { isNumericColumnStyle, isNumericColumnType } from '@/lib';
import { LabelAndInput } from '../../Common';
export const AGGREGATE_OPTIONS: SelectItem<IBusterMetricChartConfig['metricValueAggregate']>[] = [
export const AGGREGATE_OPTIONS: SelectItem<BusterMetricChartConfig['metricValueAggregate']>[] = [
{ label: 'Sum', value: 'sum' },
{ label: 'Average', value: 'average' },
{ label: 'Median', value: 'median' },
@ -19,9 +19,9 @@ export const AGGREGATE_OPTIONS: SelectItem<IBusterMetricChartConfig['metricValue
];
export const EditMetricAggregate: React.FC<{
aggregate: IBusterMetricChartConfig['metricValueAggregate'];
aggregate: BusterMetricChartConfig['metricValueAggregate'];
columnId?: string;
onUpdateAggregate: (aggregate: IBusterMetricChartConfig['metricValueAggregate']) => void;
onUpdateAggregate: (aggregate: BusterMetricChartConfig['metricValueAggregate']) => void;
columnLabelFormat: ColumnLabelFormat | undefined;
}> = React.memo(({ aggregate, onUpdateAggregate, columnId, columnLabelFormat }) => {
const isNumberColumn = columnLabelFormat?.columnType
@ -38,7 +38,7 @@ export const EditMetricAggregate: React.FC<{
}, [aggregate, disableOptions]);
const onUpdateMetricValueAggregate = useMemoizedFn((value: string) => {
onUpdateAggregate(value as IBusterMetricChartConfig['metricValueAggregate']);
onUpdateAggregate(value as BusterMetricChartConfig['metricValueAggregate']);
});
return (

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import type { ColumnMetaData, IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnMetaData, BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { DerivedMetricTitle } from '@/api/asset_interfaces/metric/charts';
import { Separator } from '@/components/ui/seperator';
import { useUpdateMetricChart } from '@/context/Metrics';
@ -12,12 +12,12 @@ import { createColumnFieldOptions } from './helpers';
export const StylingMetric: React.FC<{
className?: string;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
metricHeader: IBusterMetricChartConfig['metricHeader'];
metricSubHeader: IBusterMetricChartConfig['metricSubHeader'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
metricHeader: BusterMetricChartConfig['metricHeader'];
metricSubHeader: BusterMetricChartConfig['metricSubHeader'];
rowCount: number;
metricValueAggregate: IBusterMetricChartConfig['metricValueAggregate'];
metricColumnId: IBusterMetricChartConfig['metricColumnId'];
metricValueAggregate: BusterMetricChartConfig['metricValueAggregate'];
metricColumnId: BusterMetricChartConfig['metricColumnId'];
columnMetadata: ColumnMetaData[];
}> = ({
className,
@ -31,7 +31,7 @@ export const StylingMetric: React.FC<{
}) => {
const { onUpdateMetricChartConfig } = useUpdateMetricChart();
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<IBusterMetricChartConfig>) => {
const onUpdateChartConfig = useMemoizedFn((chartConfig: Partial<BusterMetricChartConfig>) => {
onUpdateMetricChartConfig({ chartConfig });
});
@ -82,12 +82,12 @@ export const StylingMetric: React.FC<{
};
const PrimaryMetricStyling: React.FC<{
metricColumnId: IBusterMetricChartConfig['metricColumnId'];
metricValueAggregate: IBusterMetricChartConfig['metricValueAggregate'];
metricColumnId: BusterMetricChartConfig['metricColumnId'];
metricValueAggregate: BusterMetricChartConfig['metricValueAggregate'];
columnFieldOptions: ReturnType<typeof createColumnFieldOptions>;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
rowCount: number;
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = ({
metricColumnId,
columnLabelFormats,
@ -104,7 +104,7 @@ const PrimaryMetricStyling: React.FC<{
metricColumnId: string;
metricValueAggregate?: DerivedMetricTitle['aggregate'];
}) => {
const newConfig: Partial<IBusterMetricChartConfig> = {
const newConfig: Partial<BusterMetricChartConfig> = {
metricColumnId
};
if (metricValueAggregate) {
@ -116,7 +116,7 @@ const PrimaryMetricStyling: React.FC<{
);
const onUpdateAggregate = useMemoizedFn(
(aggregate: IBusterMetricChartConfig['metricValueAggregate']) => {
(aggregate: BusterMetricChartConfig['metricValueAggregate']) => {
onUpdateChartConfig({ metricValueAggregate: aggregate });
}
);
@ -142,12 +142,12 @@ const PrimaryMetricStyling: React.FC<{
};
const HeaderMetricStyling: React.FC<{
header: IBusterMetricChartConfig['metricHeader'] | IBusterMetricChartConfig['metricSubHeader'];
header: BusterMetricChartConfig['metricHeader'] | BusterMetricChartConfig['metricSubHeader'];
columnFieldOptions: ReturnType<typeof createColumnFieldOptions>;
rowCount: number;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'];
type: 'header' | 'subHeader';
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
onUpdateChartConfig: (chartConfig: Partial<BusterMetricChartConfig>) => void;
}> = ({ header, type, columnFieldOptions, rowCount, columnLabelFormats, onUpdateChartConfig }) => {
const isStringHeader = typeof header === 'string';
const isObjectHeader = typeof header === 'object';
@ -187,7 +187,7 @@ const HeaderMetricStyling: React.FC<{
);
const onUpdateAggregate = useMemoizedFn(
(aggregate: IBusterMetricChartConfig['metricValueAggregate']) => {
(aggregate: BusterMetricChartConfig['metricValueAggregate']) => {
const key = type === 'header' ? 'metricHeader' : 'metricSubHeader';
const newConfig: DerivedMetricTitle = {
columnId: (header as DerivedMetricTitle)?.columnId,

View File

@ -1,11 +1,11 @@
import type { ColumnMetaData, IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { ColumnMetaData, BusterMetricChartConfig } from '@/api/asset_interfaces';
import type { SelectItem } from '@/components/ui/select';
import { formatLabel } from '@/lib';
import { ColumnTypeIcon } from '../SelectAxis/config';
export const createColumnFieldOptions = (
columnMetadata: ColumnMetaData[],
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'],
columnLabelFormats: BusterMetricChartConfig['columnLabelFormats'],
iconClass: string
): SelectItem<string>[] => {
return columnMetadata.map<SelectItem<string>>((column) => {

View File

@ -1,13 +1,13 @@
import React, { useMemo } from 'react';
import type { BusterMetricData, DataMetadata, IBusterMetric } from '@/api/asset_interfaces/metric';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { BusterMetricData, BusterMetric } from '@/api/asset_interfaces/metric';
import type { DataMetadata } from '@buster/server-shared/metrics';
import { BusterChart } from '@/components/ui/charts';
import { cn } from '@/lib/classMerge';
import { METRIC_CHART_CONTAINER_ID } from './config';
interface MetricViewChartContentProps {
className?: string;
chartConfig: IBusterMetric['chart_config'];
chartConfig: BusterMetric['chart_config'];
metricData: BusterMetricData['data'];
dataMetadata: DataMetadata | undefined;
fetchedData: boolean;

View File

@ -1,7 +1,7 @@
import type {
ColumnMetaData,
IBusterMetric,
IBusterMetricChartConfig
BusterMetric,
BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import type {
BusterChartConfigProps,
@ -57,9 +57,9 @@ export const didColumnDataChange = (
* @returns A new chart configuration suitable for the changed SQL data
*/
export const simplifyChatConfigForSQLChange = (
chartConfig: IBusterMetricChartConfig,
data_metadata: IBusterMetric['data_metadata']
): IBusterMetricChartConfig => {
chartConfig: BusterMetricChartConfig,
data_metadata: BusterMetric['data_metadata']
): BusterMetricChartConfig => {
// Create a new mapping of column name to format settings
// This preserves existing format settings only when the column type hasn't changed
const columnLabelFormats = data_metadata?.column_metadata?.reduce<

View File

@ -1,6 +1,7 @@
import { useQueryClient } from '@tanstack/react-query';
import { useRef } from 'react';
import type { BusterMetricData, IBusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
import type { BusterMetricData } from '@/api/asset_interfaces/metric';
import type { RunSQLResponse } from '@/api/asset_interfaces/sql';
import { useRunSQL as useRunSQLQuery } from '@/api/buster_rest';
import { useGetLatestMetricVersionMemoized, useUpdateMetric } from '@/api/buster_rest/metrics';
@ -38,7 +39,7 @@ export const useMetricRunSQL = () => {
const getLatestMetricVersion = useGetLatestMetricVersionMemoized();
const originalConfigs = useRef<{
chartConfig: IBusterMetricChartConfig;
chartConfig: ChartConfigProps;
sql: string;
data: BusterMetricData['data'];
dataMetadata: BusterMetricData['data_metadata'];
@ -88,7 +89,7 @@ export const useMetricRunSQL = () => {
const newColumnData = data_metadata?.column_metadata;
const didDataMetadataChange = didColumnDataChange(oldColumnData, newColumnData);
const totallyDefaultChartConfig: IBusterMetricChartConfig = didDataMetadataChange
const totallyDefaultChartConfig: ChartConfigProps = didDataMetadataChange
? simplifyChatConfigForSQLChange(metricMessage.chart_config, data_metadata)
: metricMessage.chart_config;

View File

@ -1,10 +1,10 @@
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
import {
type ColumnLabelFormat,
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_DATE_FORMAT_DAY_OF_WEEK,
DEFAULT_DATE_FORMAT_MONTH_OF_YEAR,
DEFAULT_DATE_FORMAT_QUARTER
} from '@/api/asset_interfaces/metric';
} from '@buster/server-shared/metrics';
import { formatDate } from './date';
import { formatNumber, roundNumber } from './numbers';
import { makeHumanReadble } from './text';

View File

@ -1,12 +1,12 @@
import type React from 'react';
import { useEffect, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import type { BusterMetricData, IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetricData, BusterMetric } from '@/api/asset_interfaces/metric';
import { downloadImageData, exportElementToImage } from './exportUtils';
import { timeout } from './timeout';
export const generateChartDownloadImage = async (
message: IBusterMetric,
message: BusterMetric,
messageData: NonNullable<BusterMetricData['data']>,
isDark = false
) => {
@ -61,7 +61,7 @@ export const generateChartDownloadImage = async (
export const generateChartPreviewImage = async (
message: {
chart_config: IBusterMetric['chart_config'];
chart_config: BusterMetric['chart_config'];
} | null,
messageData: BusterMetricData,
isDark = true
@ -77,7 +77,7 @@ export const generateChartPreviewImage = async (
const container = (
<PreviewImageReactComponent
message={message as IBusterMetric}
message={message as BusterMetric}
messageData={messageData}
isDark={isDark}
/>
@ -149,7 +149,7 @@ const ChartPreviewImage = ({
message,
messageData
}: {
message: IBusterMetric;
message: BusterMetric;
messageData: BusterMetricData;
}) => {
const data = messageData?.data || [];
@ -174,7 +174,7 @@ const ChartPreviewImage = ({
export const PreviewImageReactComponent: React.FC<{
message: {
chart_config: IBusterMetric['chart_config'];
chart_config: BusterMetric['chart_config'];
} | null;
messageData: BusterMetricData;
isDark: boolean;
@ -210,7 +210,7 @@ export const PreviewImageReactComponent: React.FC<{
}`}>
{BusterLogo}
{hasData && message?.chart_config ? (
<ChartPreviewImage message={message as IBusterMetric} messageData={messageData} />
<ChartPreviewImage message={message as BusterMetric} messageData={messageData} />
) : (
<div
className={`${isDark ? 'text-stone-400' : 'text-stone-700'}`}

View File

@ -3,7 +3,7 @@ import {
type ColumnLabelFormat,
type ColumnMetaData,
DEFAULT_COLUMN_LABEL_FORMAT,
type IBusterMetricChartConfig,
type BusterMetricChartConfig,
type IColumnLabelFormat,
type SimplifiedColumnType
} from '@/api/asset_interfaces/metric';
@ -12,7 +12,7 @@ import { isDateColumnType, isNumericColumnType, simplifyColumnType } from '@/lib
export const createDefaultColumnLabelFormats = (
columnLabelFormats: Record<string, IColumnLabelFormat> | undefined,
columnsMetaData: ColumnMetaData[] | undefined
): IBusterMetricChartConfig['columnLabelFormats'] => {
): BusterMetricChartConfig['columnLabelFormats'] => {
if (!columnsMetaData) return {};
return columnsMetaData.reduce(
@ -25,7 +25,7 @@ export const createDefaultColumnLabelFormats = (
});
return acc;
},
{} as IBusterMetricChartConfig['columnLabelFormats']
{} as BusterMetricChartConfig['columnLabelFormats']
);
};

View File

@ -2,17 +2,17 @@ import { create } from 'mutative';
import {
type ColumnMetaData,
DEFAULT_COLUMN_SETTINGS,
type IBusterMetricChartConfig
type BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import type { ColumnSettings } from '@/api/asset_interfaces/metric/charts';
export const createDefaultColumnSettings = (
existingColumnSettings: Record<string, ColumnSettings> | undefined,
columnsMetaData: ColumnMetaData[] | undefined
): IBusterMetricChartConfig['columnSettings'] => {
): BusterMetricChartConfig['columnSettings'] => {
if (!columnsMetaData) return {};
return create({} as IBusterMetricChartConfig['columnSettings'], (draft) => {
return create({} as BusterMetricChartConfig['columnSettings'], (draft) => {
for (const column of columnsMetaData) {
draft[column.name] = create(DEFAULT_COLUMN_SETTINGS, (settingsDraft) => {
if (existingColumnSettings?.[column.name]) {

View File

@ -1,13 +1,12 @@
import isEmpty from 'lodash/isEmpty';
import { create } from 'mutative';
import { type BusterMetric, type BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import {
type BusterMetric,
type DataMetadata,
DEFAULT_CHART_CONFIG,
DEFAULT_CHART_CONFIG_ENTRIES,
type IBusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import type { BusterChartConfigProps } from '@/api/asset_interfaces/metric/charts';
type ChartConfigProps,
type DataMetadata
} from '@buster/server-shared/metrics';
import {
createDefaultBarAndLineAxis,
createDefaultPieAxis,
@ -18,27 +17,27 @@ import { createDefaultColumnSettings } from './createDefaultColumnSettings';
const keySpecificHandlers: Partial<
Record<
keyof IBusterMetricChartConfig,
keyof BusterMetricChartConfig,
(
value: unknown,
dataMetadata: DataMetadata | undefined,
pieChartAxis: IBusterMetricChartConfig['pieChartAxis'] | undefined
pieChartAxis: BusterMetricChartConfig['pieChartAxis'] | undefined
) => unknown
>
> = {
colors: (value: unknown) => {
const colors = value as IBusterMetricChartConfig['colors'];
const colors = value as BusterMetricChartConfig['colors'];
if (isEmpty(colors)) return DEFAULT_CHART_CONFIG.colors;
if (colors.length >= 3) return colors; //we need at least 3 colors for the chart icons
return Array.from({ length: 3 }, (_, index) => colors[index % colors.length]);
},
scatterDotSize: (value: unknown) => {
const scatterDotSize = value as IBusterMetricChartConfig['scatterDotSize'];
const scatterDotSize = value as BusterMetricChartConfig['scatterDotSize'];
if (isEmpty(scatterDotSize)) return DEFAULT_CHART_CONFIG.scatterDotSize;
return scatterDotSize;
},
barAndLineAxis: (value: unknown, dataMetadata) => {
const barAndLineAxis = value as IBusterMetricChartConfig['barAndLineAxis'];
const barAndLineAxis = value as BusterMetricChartConfig['barAndLineAxis'];
if (isEmpty(barAndLineAxis)) {
return createDefaultBarAndLineAxis(dataMetadata?.column_metadata);
}
@ -50,7 +49,7 @@ const keySpecificHandlers: Partial<
};
},
pieChartAxis: (value: unknown, dataMetadata) => {
const pieChartAxis = value as IBusterMetricChartConfig['pieChartAxis'];
const pieChartAxis = value as BusterMetricChartConfig['pieChartAxis'];
if (isEmpty(pieChartAxis)) return createDefaultPieAxis(dataMetadata?.column_metadata);
return {
x: pieChartAxis.x || DEFAULT_CHART_CONFIG.pieChartAxis.x,
@ -59,7 +58,7 @@ const keySpecificHandlers: Partial<
};
},
scatterAxis: (value: unknown, dataMetadata) => {
const scatterAxis = value as IBusterMetricChartConfig['scatterAxis'];
const scatterAxis = value as BusterMetricChartConfig['scatterAxis'];
if (isEmpty(scatterAxis)) return createDefaultScatterAxis(dataMetadata?.column_metadata);
return {
x: scatterAxis.x || DEFAULT_CHART_CONFIG.scatterAxis.x,
@ -70,7 +69,7 @@ const keySpecificHandlers: Partial<
};
},
comboChartAxis: (value: unknown, dataMetadata) => {
const comboChartAxis = value as IBusterMetricChartConfig['comboChartAxis'];
const comboChartAxis = value as BusterMetricChartConfig['comboChartAxis'];
if (isEmpty(comboChartAxis)) return createDefaultBarAndLineAxis(dataMetadata?.column_metadata);
return {
x: comboChartAxis.x || DEFAULT_CHART_CONFIG.comboChartAxis.x,
@ -81,7 +80,7 @@ const keySpecificHandlers: Partial<
};
},
metricColumnId: (value: unknown, dataMetadata) => {
const metricColumnId = value as IBusterMetricChartConfig['metricColumnId'];
const metricColumnId = value as BusterMetricChartConfig['metricColumnId'];
if (isEmpty(metricColumnId)) {
const firstNumberColumn = dataMetadata?.column_metadata?.find(
(m) => m.simple_type === 'number'
@ -91,25 +90,25 @@ const keySpecificHandlers: Partial<
return metricColumnId;
},
metricHeader: (value: unknown) => {
const metricHeader = value as IBusterMetricChartConfig['metricHeader'];
const metricHeader = value as BusterMetricChartConfig['metricHeader'];
if (isEmpty(metricHeader)) return DEFAULT_CHART_CONFIG.metricHeader;
return metricHeader;
},
metricSubHeader: (value: unknown) => {
const metricSubHeader = value as IBusterMetricChartConfig['metricSubHeader'];
const metricSubHeader = value as BusterMetricChartConfig['metricSubHeader'];
if (isEmpty(metricSubHeader)) return DEFAULT_CHART_CONFIG.metricSubHeader;
return metricSubHeader;
},
columnLabelFormats: (value: unknown, dataMetadata) => {
const columnLabelFormats = value as IBusterMetricChartConfig['columnLabelFormats'];
const columnLabelFormats = value as BusterMetricChartConfig['columnLabelFormats'];
return createDefaultColumnLabelFormats(columnLabelFormats, dataMetadata?.column_metadata);
},
columnSettings: (value: unknown, dataMetadata) => {
const columnSettings = value as IBusterMetricChartConfig['columnSettings'];
const columnSettings = value as BusterMetricChartConfig['columnSettings'];
return createDefaultColumnSettings(columnSettings, dataMetadata?.column_metadata);
},
pieLabelPosition: (value: unknown, dataMetadata, pieChartAxis) => {
const pieLabelPosition = value as IBusterMetricChartConfig['pieLabelPosition'];
const pieLabelPosition = value as BusterMetricChartConfig['pieLabelPosition'];
// if (isEmpty(pieLabelPosition)) {
// const firstPieColumn = pieChartAxis?.x?.[0];
// const firstPieColumnMetaData = dataMetadata?.column_metadata?.find(
@ -124,14 +123,14 @@ const keySpecificHandlers: Partial<
export const createDefaultChartConfig = (
message: Pick<BusterMetric, 'chart_config' | 'data_metadata'>
): IBusterMetricChartConfig => {
const chartConfig: BusterChartConfigProps | undefined = message.chart_config;
): BusterMetricChartConfig => {
const chartConfig: ChartConfigProps | undefined = message.chart_config;
const dataMetadata = message.data_metadata;
const pieChartAxis = chartConfig?.pieChartAxis;
const newChartConfig = create(DEFAULT_CHART_CONFIG, (draft) => {
for (const [_key, defaultValue] of DEFAULT_CHART_CONFIG_ENTRIES) {
const key = _key as keyof IBusterMetricChartConfig;
const key = _key as keyof BusterMetricChartConfig;
const chartConfigValue = chartConfig?.[key];
const handler = keySpecificHandlers[key];

View File

@ -1,9 +1,9 @@
import { DEFAULT_IBUSTER_METRIC, type IBusterMetric } from '@/api/asset_interfaces/metric';
import { DEFAULT_IBUSTER_METRIC, type BusterMetric } from '@/api/asset_interfaces/metric';
export const resolveEmptyMetric = (
metric: IBusterMetric | undefined,
metric: BusterMetric | undefined,
metricId: string
): IBusterMetric => {
): BusterMetric => {
if (!metric || !metric?.id) {
return { ...DEFAULT_IBUSTER_METRIC, ...metric, id: metricId };
}

View File

@ -1,10 +1,10 @@
import isEqual from 'lodash/isEqual';
import type { DataMetadata, IBusterMetric } from '@/api/asset_interfaces/metric';
import type { DataMetadata, BusterMetric } from '@/api/asset_interfaces/metric';
import {
DEFAULT_CHART_CONFIG_ENTRIES,
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS,
type IBusterMetricChartConfig
type BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import type {
BarAndLineAxis,
@ -23,15 +23,15 @@ const DEFAULT_COLUMN_SETTINGS_ENTRIES = Object.entries(DEFAULT_COLUMN_SETTINGS);
const DEFAULT_COLUMN_LABEL_FORMATS_ENTRIES = Object.entries(DEFAULT_COLUMN_LABEL_FORMAT);
export const getChangedTopLevelMessageValues = (
newMetric: IBusterMetric,
oldMetric: IBusterMetric
newMetric: BusterMetric,
oldMetric: BusterMetric
) => {
const changes = getChangedValues(oldMetric, newMetric, ['name', 'status', 'sql', 'file']);
return changes;
};
const keySpecificHandlers: Partial<
Record<keyof IBusterMetricChartConfig, (value: unknown) => unknown>
Record<keyof BusterMetricChartConfig, (value: unknown) => unknown>
> = {
barAndLineAxis: (value: unknown) => value as BarAndLineAxis,
scatterAxis: (value: unknown) => value as ScatterAxis,
@ -97,14 +97,14 @@ const keySpecificHandlers: Partial<
}
};
export const getChangesFromDefaultChartConfig = (newMetric: IBusterMetric) => {
export const getChangesFromDefaultChartConfig = (newMetric: BusterMetric) => {
const chartConfig = newMetric.chart_config;
if (!chartConfig) return {} as BusterChartConfigProps;
const diff: Partial<IBusterMetricChartConfig> = {};
const diff: Partial<BusterMetricChartConfig> = {};
for (const [_key, defaultValue] of DEFAULT_CHART_CONFIG_ENTRIES) {
const key = _key as keyof IBusterMetricChartConfig;
const key = _key as keyof BusterMetricChartConfig;
const chartConfigValue = chartConfig[key];
const handler = keySpecificHandlers[key];
@ -127,7 +127,7 @@ export const getChangesFromDefaultChartConfig = (newMetric: IBusterMetric) => {
};
export const combineChangeFromDefaultChartConfig = (
newMetric: IBusterMetric,
newMetric: BusterMetric,
dataMetadata: DataMetadata
) => {
const chartConfig = createDefaultChartConfig({
@ -138,8 +138,8 @@ export const combineChangeFromDefaultChartConfig = (
};
export const prepareMetricUpdateMetric = (
newMetric: IBusterMetric,
prevMetric: IBusterMetric
newMetric: BusterMetric,
prevMetric: BusterMetric
): Parameters<typeof updateMetric>[0] | null => {
const changedTopLevelValues = getChangedTopLevelMessageValues(
newMetric,

View File

@ -2,16 +2,16 @@ import {
ChartEncodes,
ChartType,
ColumnMetaData,
IBusterMetricChartConfig
BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
export interface SelectChartTypeProps {
selectedChartType: ChartType;
lineGroupType: IBusterMetricChartConfig['lineGroupType'];
barGroupType: IBusterMetricChartConfig['barGroupType'];
barLayout: IBusterMetricChartConfig['barLayout'];
lineGroupType: BusterMetricChartConfig['lineGroupType'];
barGroupType: BusterMetricChartConfig['barGroupType'];
barLayout: BusterMetricChartConfig['barLayout'];
colors: string[];
columnMetadata: ColumnMetaData[];
columnSettings: IBusterMetricChartConfig['columnSettings'];
columnSettings: BusterMetricChartConfig['columnSettings'];
selectedAxis: ChartEncodes;
}

View File

@ -1,5 +1,5 @@
import omit from 'lodash/omit';
import type { IBusterMetricChartConfig } from '@/api/asset_interfaces';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import { CHART_ICON_LIST, ChartIconType, DETERMINE_SELECTED_CHART_TYPE_ORDER } from './config';
import type { SelectChartTypeProps } from './chartIcon.types';
@ -37,7 +37,7 @@ export const getSelectedChartTypeConfig = (
const chartTypeMethod: Record<
ChartIconType,
() => Partial<IBusterMetricChartConfig> & {
() => Partial<BusterMetricChartConfig> & {
hasAreaStyle?: boolean;
}
> = {
@ -130,14 +130,14 @@ export const disableTypeMethod: Record<
export const selectedChartTypeMethod = (
chartIconType: ChartIconType,
columnSettings: IBusterMetricChartConfig['columnSettings']
): Partial<IBusterMetricChartConfig> => {
columnSettings: BusterMetricChartConfig['columnSettings']
): Partial<BusterMetricChartConfig> => {
const fullRes = chartTypeMethod[chartIconType]();
const hasAreaStyle = !!fullRes.hasAreaStyle;
const resOmitted = omit(fullRes, 'hasAreaStyle');
if (resOmitted.selectedChartType === 'line') {
const newColumnSettings: IBusterMetricChartConfig['columnSettings'] = Object.fromEntries(
const newColumnSettings: BusterMetricChartConfig['columnSettings'] = Object.fromEntries(
Object.entries(columnSettings).map(([key, value]) => [
key,
{

View File

@ -1,10 +1,10 @@
import type { BusterMetric, IBusterMetric } from '@/api/asset_interfaces/metric';
import type { BusterMetric, BusterMetric } from '@/api/asset_interfaces/metric';
import { createDefaultChartConfig } from './messageAutoChartHandler';
export const upgradeMetricToIMetric = (
metric: BusterMetric,
oldMetric: IBusterMetric | null | undefined
): IBusterMetric => {
oldMetric: BusterMetric | null | undefined
): BusterMetric => {
const chart_config = createDefaultChartConfig(metric);
return {
...oldMetric,

View File

@ -1,12 +1,12 @@
import {
type BusterMetricListItem,
ChartType,
type DataMetadata,
DEFAULT_CHART_CONFIG,
type IBusterMetric,
type IBusterMetricChartConfig
type BusterMetric,
type BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
import { ShareRole, VerificationStatus } from '@/api/asset_interfaces/share';
import type { DataMetadata } from '@buster/server-shared/metrics';
// Utility functions for predictable mock data generation
const CHART_TYPES: ChartType[] = ['bar', 'table', 'line', 'pie', 'scatter', 'metric'];
@ -62,7 +62,7 @@ const generatePredictableEmail = (id: string): string => {
return `${name}.${hash % 100}@${domain}`;
};
const createMockChartConfig = (id: string): IBusterMetricChartConfig => {
const createMockChartConfig = (id: string): BusterMetricChartConfig => {
const hash = Array.from(id).reduce((acc, char) => acc + char.charCodeAt(0), 0);
const chartType: ChartType = CHART_TYPES[hash % CHART_TYPES.length];
@ -126,7 +126,7 @@ const dataMetadata: DataMetadata = {
row_count: 10
};
export const createMockMetric = (id: string): IBusterMetric => {
export const createMockMetric = (id: string): BusterMetric => {
const chart_config = createMockChartConfig(id);
return {

View File

@ -1,4 +1,5 @@
import type { BusterMetricData, DataMetadata } from '@/api/asset_interfaces/metric';
import type { BusterMetricData } from '@/api/asset_interfaces/metric';
import type { DataMetadata } from '@buster/server-shared/metrics';
const PRODUCTS = [
'Laptop',

Some files were not shown because too many files have changed in this diff Show More