This is an automated email from the ASF dual-hosted git repository.
lilykuang pushed a commit to branch table-time-comparison
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/table-time-comparison by this
push:
new 5054e7552d feat(plugin): color option for table with time comparison
(#27716)
5054e7552d is described below
commit 5054e7552d02550096595129dc813e550e955358
Author: Lily Kuang <[email protected]>
AuthorDate: Tue Apr 2 13:19:53 2024 -0700
feat(plugin): color option for table with time comparison (#27716)
---
.../plugins/plugin-chart-table/src/TableChart.tsx | 66 ++++++++-
.../plugin-chart-table/src/controlPanel.tsx | 149 +++++++++++++++++----
.../plugin-chart-table/src/transformProps.ts | 131 +++++++++++++++++-
.../plugins/plugin-chart-table/src/types.ts | 13 ++
.../ConditionalFormattingControl.tsx | 3 +
.../FormattingPopover.tsx | 2 +
.../FormattingPopoverContent.tsx | 39 +++++-
.../controls/ConditionalFormattingControl/types.ts | 2 +
8 files changed, 367 insertions(+), 38 deletions(-)
diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
index c274296ccd..19ca9ef768 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
@@ -59,7 +59,11 @@ import {
} from '@ant-design/icons';
import { isEmpty } from 'lodash';
-import { DataColumnMeta, TableChartTransformedProps } from './types';
+import {
+ ColorSchemeEnum,
+ DataColumnMeta,
+ TableChartTransformedProps,
+} from './types';
import DataTable, {
DataTableProps,
SearchInputProps,
@@ -248,6 +252,8 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
onContextMenu,
emitCrossFilters,
enableTimeComparison,
+ basicColorFormatters,
+ basicColorColumnFormatters,
} = props;
const comparisonColumns = [
{ key: 'all', label: t('Display all') },
@@ -692,7 +698,13 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
Array.isArray(columnColorFormatters) &&
columnColorFormatters.length > 0;
+ const hasBasicColorFormatters =
+ enableTimeComparison &&
+ Array.isArray(basicColorFormatters) &&
+ basicColorFormatters.length > 0;
+
const valueRange =
+ !hasBasicColorFormatters &&
!hasColumnColorFormatters &&
(config.showCellBars === undefined
? showCellBars
@@ -728,6 +740,17 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
const html = isHtml ? { __html: text } : undefined;
let backgroundColor;
+ let arrow = '';
+ const originKey = column.key.substring(column.label.length).trim();
+ if (!hasColumnColorFormatters && hasBasicColorFormatters) {
+ backgroundColor =
+ basicColorFormatters[row.index][originKey]?.backgroundColor;
+ arrow =
+ column.label === comparisonLabels[0]
+ ? basicColorFormatters[row.index][originKey]?.mainArrow
+ : '';
+ }
+
if (hasColumnColorFormatters) {
columnColorFormatters!
.filter(formatter => formatter.column === column.key)
@@ -742,6 +765,19 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
});
}
+ if (
+ basicColorColumnFormatters &&
+ basicColorColumnFormatters?.length > 0
+ ) {
+ backgroundColor =
+ basicColorColumnFormatters[row.index][column.key]
+ ?.backgroundColor || backgroundColor;
+ arrow =
+ column.label === comparisonLabels[0]
+ ? basicColorColumnFormatters[row.index][column.key]?.mainArrow
+ : '';
+ }
+
const StyledCell = styled.td`
text-align: ${sharedStyle.textAlign};
white-space: ${value instanceof Date ? 'nowrap' : undefined};
@@ -773,6 +809,28 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
`}
`;
+ let arrowStyles = css`
+ color: ${basicColorFormatters &&
+ basicColorFormatters[row.index][originKey]?.arrowColor ===
+ ColorSchemeEnum.Green
+ ? theme.colors.success.base
+ : theme.colors.error.base};
+ margin-right: ${theme.gridUnit}px;
+ `;
+
+ if (
+ basicColorColumnFormatters &&
+ basicColorColumnFormatters?.length > 0
+ ) {
+ arrowStyles = css`
+ color: ${basicColorColumnFormatters[row.index][column.key]
+ ?.arrowColor === ColorSchemeEnum.Green
+ ? theme.colors.success.base
+ : theme.colors.error.base};
+ margin-right: ${theme.gridUnit}px;
+ `;
+ }
+
const cellProps = {
// show raw number in title in case of numeric values
title: typeof value === 'number' ? String(value) : undefined,
@@ -838,10 +896,14 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
className="dt-truncate-cell"
style={columnWidth ? { width: columnWidth } : undefined}
>
+ {arrow && <span css={arrowStyles}>{arrow}</span>}
{text}
</div>
) : (
- text
+ <>
+ {arrow && <span css={arrowStyles}>{arrow}</span>}
+ {text}
+ </>
)}
</StyledCell>
);
diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index cf0ad3d952..7778b69ecf 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -50,7 +50,8 @@ import {
getStandardizedControls,
} from '@superset-ui/chart-controls';
-import { PAGE_SIZE_OPTIONS } from './consts';
+import { COMPARISON_PREFIX, PAGE_SIZE_OPTIONS } from './consts';
+import { ColorSchemeEnum } from './types';
function getQueryMode(controls: ControlStateMapping): QueryMode {
const mode = controls?.query_mode?.value;
@@ -153,6 +154,33 @@ const percentMetricsControl: typeof sharedControls.metrics
= {
validators: [],
};
+const processComparisonColumns = (columns: any[]) =>
+ columns
+ .map(col => {
+ if (!col.label.includes(COMPARISON_PREFIX)) {
+ return [
+ {
+ label: `${t('Main')} ${col.label}`,
+ value: `${t('Main')} ${col.value}`,
+ },
+ {
+ label: `# ${col.label}`,
+ value: `# ${col.value}`,
+ },
+ {
+ label: `△ ${col.label}`,
+ value: `△ ${col.value}`,
+ },
+ {
+ label: `% ${col.label}`,
+ value: `% ${col.value}`,
+ },
+ ];
+ }
+ return [];
+ })
+ .flat();
+
const config: ControlPanelConfig = {
controlPanelSections: [
{
@@ -479,11 +507,59 @@ const config: ControlPanelConfig = {
description: t('Whether to include a client-side search box'),
},
},
+ ],
+ [
+ {
+ name: 'allow_rearrange_columns',
+ config: {
+ type: 'CheckboxControl',
+ label: t('Allow columns to be rearranged'),
+ renderTrigger: true,
+ default: false,
+ description: t(
+ "Allow end user to drag-and-drop column headers to rearrange
them. Note their changes won't persist for the next time they open the chart.",
+ ),
+ visibility: ({ controls }) =>
+ !controls?.enable_time_comparison?.value ||
+ !isFeatureEnabled(FeatureFlag.ChartPluginsExperimental),
+ },
+ },
+ ],
+ [
+ {
+ name: 'column_config',
+ config: {
+ type: 'ColumnConfigControl',
+ label: t('Customize columns'),
+ description: t('Further customize how to display each column'),
+ width: 400,
+ height: 320,
+ renderTrigger: true,
+ shouldMapStateToProps() {
+ return true;
+ },
+ mapStateToProps(explore, _, chart) {
+ return {
+ queryResponse: chart?.queriesResponse?.[0] as
+ | ChartDataResponseResult
+ | undefined,
+ };
+ },
+ },
+ },
+ ],
+ ],
+ },
+ {
+ label: t('Visual formatting'),
+ expanded: true,
+ controlSetRows: [
+ [
{
name: 'show_cell_bars',
config: {
type: 'CheckboxControl',
- label: t('Cell bars'),
+ label: t('Show Cell bars'),
renderTrigger: true,
default: true,
description: t(
@@ -505,11 +581,13 @@ const config: ControlPanelConfig = {
),
},
},
+ ],
+ [
{
name: 'color_pn',
config: {
type: 'CheckboxControl',
- label: t('Color +/-'),
+ label: t('add colors to cell bars for +/-'),
renderTrigger: true,
default: true,
description: t(
@@ -520,41 +598,42 @@ const config: ControlPanelConfig = {
],
[
{
- name: 'allow_rearrange_columns',
+ name: 'comparison_color_enabled',
config: {
type: 'CheckboxControl',
- label: t('Allow columns to be rearranged'),
+ label: t('basic conditional formatting'),
renderTrigger: true,
+ visibility: ({ controls }) =>
+ Boolean(controls?.enable_time_comparison?.value) &&
+ isFeatureEnabled(FeatureFlag.ChartPluginsExperimental),
default: false,
description: t(
- "Allow end user to drag-and-drop column headers to rearrange
them. Note their changes won't persist for the next time they open the chart.",
+ 'This will be applied to the whole table. Arrows (↑ and ↓)
will be added to ' +
+ 'main columns for increase and decrease. Basic conditional
formatting can be ' +
+ 'overwritten by conditional formatting below.',
),
- visibility: ({ controls }) =>
- !controls?.enable_time_comparison?.value ||
- !isFeatureEnabled(FeatureFlag.ChartPluginsExperimental),
},
},
],
[
{
- name: 'column_config',
+ name: 'comparison_color_scheme',
config: {
- type: 'ColumnConfigControl',
- label: t('Customize columns'),
- description: t('Further customize how to display each column'),
- width: 400,
- height: 320,
+ type: 'SelectControl',
+ label: t('color type'),
+ default: ColorSchemeEnum.Green,
renderTrigger: true,
- shouldMapStateToProps() {
- return true;
- },
- mapStateToProps(explore, _, chart) {
- return {
- queryResponse: chart?.queriesResponse?.[0] as
- | ChartDataResponseResult
- | undefined,
- };
- },
+ choices: [
+ [ColorSchemeEnum.Green, 'Green for increase, red for
decrease'],
+ [ColorSchemeEnum.Red, 'Red for increase, green for decrease'],
+ ],
+ visibility: ({ controls }) =>
+ Boolean(controls?.enable_time_comparison?.value) &&
+ Boolean(controls?.comparison_color_enabled?.value),
+ description: t(
+ 'Adds color to the chart symbols based on the positive or ' +
+ 'negative change from the comparison value.',
+ ),
},
},
],
@@ -564,7 +643,17 @@ const config: ControlPanelConfig = {
config: {
type: 'ConditionalFormattingControl',
renderTrigger: true,
- label: t('Conditional formatting'),
+ label: t('Custom Conditional Formatting'),
+ extraColorChoices: [
+ {
+ value: ColorSchemeEnum.Green,
+ label: t('Green for increase, red for decrease'),
+ },
+ {
+ value: ColorSchemeEnum.Red,
+ label: t('Red for increase, green for decrease'),
+ },
+ ],
description: t(
'Apply conditional color formatting to numeric columns',
),
@@ -592,9 +681,15 @@ const config: ControlPanelConfig = {
label: verboseMap[colname] ?? colname,
}))
: [];
+
+ const columnOptions = explore?.controls?.enable_time_comparison
+ ?.value
+ ? processComparisonColumns(numericColumns || [])
+ : numericColumns;
+
return {
removeIrrelevantConditions: chartStatus === 'success',
- columnOptions: numericColumns,
+ columnOptions,
verboseMap,
};
},
diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
index 64fb198016..a49c3ac4af 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
@@ -37,12 +37,15 @@ import {
} from '@superset-ui/core';
import {
ColorFormatters,
+ ConditionalFormattingConfig,
getColorFormatters,
} from '@superset-ui/chart-controls';
import isEqualColumns from './utils/isEqualColumns';
import DateWithFormatter from './utils/DateWithFormatter';
import {
+ BasicColorFormatterType,
+ ColorSchemeEnum,
DataColumnMeta,
TableChartProps,
TableChartTransformedProps,
@@ -374,7 +377,118 @@ const transformProps = (
conditional_formatting: conditionalFormatting,
allow_rearrange_columns: allowRearrangeColumns,
enable_time_comparison: enableTimeComparison = false,
+ comparison_color_enabled: comparisonColorEnabled = false,
+ comparison_color_scheme: comparisonColorScheme = ColorSchemeEnum.Green,
} = formData;
+
+ const calculateBasicStyle = (
+ percentDifferenceNum: number,
+ colorOption: ColorSchemeEnum,
+ ) => {
+ if (percentDifferenceNum === 0) {
+ return {
+ arrow: '',
+ arrowColor: '',
+ // eslint-disable-next-line theme-colors/no-literal-colors
+ backgroundColor: '#FFBFA133',
+ };
+ }
+ const isPositive = percentDifferenceNum > 0;
+ const arrow = isPositive ? '↑' : '↓';
+ const arrowColor =
+ colorOption === ColorSchemeEnum.Green
+ ? isPositive
+ ? ColorSchemeEnum.Green
+ : ColorSchemeEnum.Red
+ : isPositive
+ ? ColorSchemeEnum.Red
+ : ColorSchemeEnum.Green;
+ const backgroundColor =
+ colorOption === ColorSchemeEnum.Green
+ ? `rgba(${isPositive ? '0,150,0' : '150,0,0'},0.2)`
+ : `rgba(${isPositive ? '150,0,0' : '0,150,0'},0.2)`;
+
+ return { arrow, arrowColor, backgroundColor };
+ };
+
+ const getBasicColorFormatter = memoizeOne(function getBasicColorFormatter(
+ originalData: DataRecord[] | undefined,
+ originalColumns: DataColumnMeta[],
+ selectedColumns?: ConditionalFormattingConfig[],
+ ) {
+ // Transform data
+ const relevantColumns = selectedColumns
+ ? originalColumns.filter(col =>
+ selectedColumns.some(scol => scol?.column?.includes(col.key)),
+ )
+ : originalColumns;
+
+ return originalData?.map(originalItem => {
+ const item: { [key: string]: BasicColorFormatterType } = {};
+ relevantColumns.forEach(origCol => {
+ if (
+ (origCol.isMetric || origCol.isPercentMetric) &&
+ !origCol.key.includes(COMPARISON_PREFIX) &&
+ origCol.isNumeric
+ ) {
+ const originalValue = originalItem[origCol.key] || 0;
+ const comparisonValue = origCol.isMetric
+ ? originalItem?.[`${COMPARISON_PREFIX}${origCol.key}`] || 0
+ : originalItem[`%${COMPARISON_PREFIX}${origCol.key.slice(1)}`] ||
0;
+ const { percentDifferenceNum } = calculateDifferences(
+ originalValue as number,
+ comparisonValue as number,
+ );
+
+ if (selectedColumns) {
+ selectedColumns.forEach(col => {
+ if (col?.column?.includes(origCol.key)) {
+ const { arrow, arrowColor, backgroundColor } =
+ calculateBasicStyle(
+ percentDifferenceNum,
+ col.colorScheme || comparisonColorScheme,
+ );
+ item[col.column] = {
+ mainArrow: arrow,
+ arrowColor,
+ backgroundColor,
+ };
+ }
+ });
+ } else {
+ const { arrow, arrowColor, backgroundColor } = calculateBasicStyle(
+ percentDifferenceNum,
+ comparisonColorScheme,
+ );
+ item[`${origCol.key}`] = {
+ mainArrow: arrow,
+ arrowColor,
+ backgroundColor,
+ };
+ }
+ }
+ });
+ return item;
+ });
+ });
+
+ const getBasicColorFormatterForColumn = (
+ originalData: DataRecord[] | undefined,
+ originalColumns: DataColumnMeta[],
+ conditionalFormatting?: ConditionalFormattingConfig[],
+ ) => {
+ const selectedColumns = conditionalFormatting?.filter(
+ (config: ConditionalFormattingConfig) =>
+ config.column &&
+ (config.colorScheme === ColorSchemeEnum.Green ||
+ config.colorScheme === ColorSchemeEnum.Red),
+ );
+
+ return selectedColumns?.length
+ ? getBasicColorFormatter(originalData, originalColumns, selectedColumns)
+ : undefined;
+ };
+
const canUseTimeComparison =
enableTimeComparison &&
isFeatureEnabled(FeatureFlag.ChartPluginsExperimental) &&
@@ -407,15 +521,24 @@ const transformProps = (
showTotals && queryMode === QueryMode.Aggregate
? totalQuery?.data[0]
: undefined;
- const columnColorFormatters =
- getColorFormatters(conditionalFormatting, data) ?? defaultColorFormatters;
const comparisonTotals = processComparisonTotals(totals);
-
const passedData = canUseTimeComparison ? comparisonData || [] : data;
const passedTotals = canUseTimeComparison ? comparisonTotals : totals;
const passedColumns = canUseTimeComparison ? comparisonColumns : columns;
+ const basicColorFormatters =
+ comparisonColorEnabled && getBasicColorFormatter(baseQuery?.data, columns);
+ const columnColorFormatters =
+ getColorFormatters(conditionalFormatting, passedData) ??
+ defaultColorFormatters;
+
+ const basicColorColumnFormatters = getBasicColorFormatterForColumn(
+ baseQuery?.data,
+ columns,
+ conditionalFormatting,
+ );
+
return {
height,
width,
@@ -447,6 +570,8 @@ const transformProps = (
allowRearrangeColumns,
onContextMenu,
enableTimeComparison: canUseTimeComparison,
+ basicColorFormatters,
+ basicColorColumnFormatters,
};
};
diff --git a/superset-frontend/plugins/plugin-chart-table/src/types.ts
b/superset-frontend/plugins/plugin-chart-table/src/types.ts
index 1806eddb1a..12349600dd 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts
@@ -103,6 +103,12 @@ export interface TableChartProps extends ChartProps {
queriesData: ChartDataResponseResult[];
}
+export type BasicColorFormatterType = {
+ backgroundColor: string;
+ arrowColor: string;
+ mainArrow: string;
+};
+
export interface TableChartTransformedProps<D extends DataRecord = DataRecord>
{
timeGrain?: TimeGranularity;
height: number;
@@ -137,6 +143,13 @@ export interface TableChartTransformedProps<D extends
DataRecord = DataRecord> {
filters?: ContextMenuFilters,
) => void;
enableTimeComparison?: boolean;
+ basicColorFormatters?: { [Key: string]: BasicColorFormatterType }[];
+ basicColorColumnFormatters?: { [Key: string]: BasicColorFormatterType }[];
+}
+
+export enum ColorSchemeEnum {
+ 'Green' = 'Green',
+ 'Red' = 'Red',
}
export default {};
diff --git
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
index 6c4ae9f412..9bf0c90f7c 100644
---
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
+++
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
@@ -71,6 +71,7 @@ const ConditionalFormattingControl = ({
columnOptions,
verboseMap,
removeIrrelevantConditions,
+ extraColorChoices,
...props
}: ConditionalFormattingControlProps) => {
const theme = useTheme();
@@ -155,6 +156,7 @@ const ConditionalFormattingControl = ({
onEdit(newConfig, index)
}
destroyTooltipOnHide
+ extraColorChoices={extraColorChoices}
>
<OptionControlContainer withCaret>
<Label>{createLabel(config)}</Label>
@@ -170,6 +172,7 @@ const ConditionalFormattingControl = ({
columns={columnOptions}
onChange={onSave}
destroyTooltipOnHide
+ extraColorChoices={extraColorChoices}
>
<AddControlLabel>
<Icons.PlusSmall iconColor={theme.colors.grayscale.light1} />
diff --git
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
index c44ca76235..fda09d4e61 100644
---
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
+++
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
@@ -27,6 +27,7 @@ export const FormattingPopover = ({
onChange,
config,
children,
+ extraColorChoices,
...props
}: FormattingPopoverProps) => {
const [visible, setVisible] = useState(false);
@@ -47,6 +48,7 @@ export const FormattingPopover = ({
onChange={handleSave}
config={config}
columns={columns}
+ extraColorChoices={extraColorChoices}
/>
}
visible={visible}
diff --git
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
index 533e185475..1f17019d8c 100644
---
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
+++
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
@@ -16,8 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React from 'react';
+import React, { useState } from 'react';
import { styled, SupersetTheme, t, useTheme } from '@superset-ui/core';
+import { ColorSchemeEnum } from '@superset-ui/plugin-chart-table';
import {
Comparator,
MultipleValueComparators,
@@ -123,21 +124,24 @@ const shouldFormItemUpdate = (
isOperatorMultiValue(prevValues.operator) !==
isOperatorMultiValue(currentValues.operator);
-const operatorField = (
+const operatorField = (showOnlyNone?: boolean) => (
<FormItem
name="operator"
label={t('Operator')}
rules={rulesRequired}
initialValue={operatorOptions[0].value}
>
- <Select ariaLabel={t('Operator')} options={operatorOptions} />
+ <Select
+ ariaLabel={t('Operator')}
+ options={showOnlyNone ? [operatorOptions[0]] : operatorOptions}
+ />
</FormItem>
);
const renderOperatorFields = ({ getFieldValue }: GetFieldValue) =>
isOperatorNone(getFieldValue('operator')) ? (
<Row gutter={12}>
- <Col span={6}>{operatorField}</Col>
+ <Col span={6}>{operatorField()}</Col>
</Row>
) : isOperatorMultiValue(getFieldValue('operator')) ? (
<Row gutter={12}>
@@ -186,13 +190,26 @@ export const FormattingPopoverContent = ({
config,
onChange,
columns = [],
+ extraColorChoices = [],
}: {
config?: ConditionalFormattingConfig;
onChange: (config: ConditionalFormattingConfig) => void;
columns: { label: string; value: string }[];
+ extraColorChoices?: { label: string; value: string }[];
}) => {
const theme = useTheme();
const colorScheme = colorSchemeOptions(theme);
+ const [showOperatorFields, setShowOperatorFields] = useState(
+ config === undefined ||
+ (config?.colorScheme !== ColorSchemeEnum.Green &&
+ config?.colorScheme !== ColorSchemeEnum.Red),
+ );
+ const handleChange = (event: any) => {
+ setShowOperatorFields(
+ !(event === ColorSchemeEnum.Green || event === ColorSchemeEnum.Red),
+ );
+ };
+
return (
<Form
onFinish={onChange}
@@ -218,12 +235,22 @@ export const FormattingPopoverContent = ({
rules={rulesRequired}
initialValue={colorScheme[0].value}
>
- <Select ariaLabel={t('Color scheme')} options={colorScheme} />
+ <Select
+ onChange={event => handleChange(event)}
+ ariaLabel={t('Color scheme')}
+ options={[...colorScheme, ...extraColorChoices]}
+ />
</FormItem>
</Col>
</Row>
<FormItem noStyle shouldUpdate={shouldFormItemUpdate}>
- {renderOperatorFields}
+ {showOperatorFields ? (
+ renderOperatorFields
+ ) : (
+ <Row gutter={12}>
+ <Col span={6}>{operatorField(true)}</Col>
+ </Row>
+ )}
</FormItem>
<FormItem>
<JustifyEnd>
diff --git
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
index 4edadf99b4..c352ca818b 100644
---
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
+++
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
@@ -38,6 +38,7 @@ export type ConditionalFormattingControlProps =
ControlComponentProps<
verboseMap: Record<string, string>;
label: string;
description: string;
+ extraColorChoices?: { label: string; value: string }[];
};
export type FormattingPopoverProps = PopoverProps & {
@@ -46,4 +47,5 @@ export type FormattingPopoverProps = PopoverProps & {
config?: ConditionalFormattingConfig;
title: string;
children: ReactNode;
+ extraColorChoices?: { label: string; value: string }[];
};