You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ar...@apache.org on 2024/04/25 14:55:29 UTC
(superset) 05/15: feat(plugin): color option for table with time comparison (#27716)
This is an automated email from the ASF dual-hosted git repository.
arivero pushed a commit to branch table-time-comparison-offset
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 08173d95ae7d505ac62194b0cde00bee14fc2be8
Author: Lily Kuang <li...@preset.io>
AuthorDate: Tue Apr 2 13:19:53 2024 -0700
feat(plugin): color option for table with time comparison (#27716)
- cherry picked from afe7eaf8b3d16ef8aefdc5b2bf8f0953a59d9b60
---
.../plugins/plugin-chart-table/src/TableChart.tsx | 66 +++++++-
.../plugin-chart-table/src/controlPanel.tsx | 171 ++++++++++++++++-----
.../plugin-chart-table/src/transformProps.ts | 134 +++++++++++++++-
.../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, 383 insertions(+), 47 deletions(-)
diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
index 5c0e99b203..dc8221821a 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,
@@ -250,6 +254,8 @@ export default function TableChart<D extends DataRecord = DataRecord>(
onContextMenu,
emitCrossFilters,
isUsingTimeComparison,
+ basicColorFormatters,
+ basicColorColumnFormatters,
} = props;
const comparisonColumns = [
{ key: 'all', label: t('Display all') },
@@ -693,7 +699,13 @@ export default function TableChart<D extends DataRecord = DataRecord>(
Array.isArray(columnColorFormatters) &&
columnColorFormatters.length > 0;
+ const hasBasicColorFormatters =
+ isUsingTimeComparison &&
+ Array.isArray(basicColorFormatters) &&
+ basicColorFormatters.length > 0;
+
const valueRange =
+ !hasBasicColorFormatters &&
!hasColumnColorFormatters &&
(config.showCellBars === undefined
? showCellBars
@@ -727,6 +739,17 @@ export default function TableChart<D extends DataRecord = DataRecord>(
const html = isHtml && allowRenderHtml ? { __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)
@@ -741,6 +764,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};
@@ -772,6 +808,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 = {
'aria-labelledby': `header-${column.key}`,
role: 'cell',
@@ -841,10 +899,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 f5f28d5d38..5859a6a0bf 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -49,6 +49,7 @@ import {
import { isEmpty } from 'lodash';
import { PAGE_SIZE_OPTIONS } from './consts';
+import { ColorSchemeEnum } from './types';
function getQueryMode(controls: ControlStateMapping): QueryMode {
const mode = controls?.query_mode?.value;
@@ -145,6 +146,33 @@ const percentMetricsControl: typeof sharedControls.metrics = {
validators: [],
};
+const processComparisonColumns = (columns: any[], suffix: string) =>
+ columns
+ .map(col => {
+ if (!col.label.includes(suffix)) {
+ 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: [
{
@@ -400,11 +428,70 @@ 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 }) =>
+ isEmpty(controls?.time_compare?.value),
+ },
+ },
+ ],
+ [
+ {
+ name: 'allow_render_html',
+ config: {
+ type: 'CheckboxControl',
+ label: t('Render columns in HTML format'),
+ renderTrigger: true,
+ default: true,
+ description: t('Render data in HTML format if applicable.'),
+ },
+ },
+ ],
+ [
+ {
+ 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(
@@ -426,11 +513,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(
@@ -441,52 +530,41 @@ 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 }) =>
+ !isEmpty(controls?.time_compare?.value),
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 }) =>
- isEmpty(controls?.time_compare?.value),
- },
- },
- ],
- [
- {
- name: 'allow_render_html',
- config: {
- type: 'CheckboxControl',
- label: t('Render columns in HTML format'),
- renderTrigger: true,
- default: true,
- description: t('Render data in HTML format if applicable.'),
},
},
],
[
{
- 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 }) =>
+ !isEmpty(controls?.time_compare?.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.',
+ ),
},
},
],
@@ -496,7 +574,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',
),
@@ -524,9 +612,18 @@ const config: ControlPanelConfig = {
label: verboseMap[colname] ?? colname,
}))
: [];
+ const columnOptions = explore?.controls?.time_compare?.value
+ ? processComparisonColumns(
+ numericColumns || [],
+ ensureIsArray(
+ explore?.controls?.time_compare?.value,
+ )[0]?.toString() || '',
+ )
+ : 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 cf70bfed16..a9ead497c3 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
@@ -36,6 +36,7 @@ import {
} from '@superset-ui/core';
import {
ColorFormatters,
+ ConditionalFormattingConfig,
getColorFormatters,
} from '@superset-ui/chart-controls';
@@ -43,6 +44,8 @@ import { isEmpty } from 'lodash';
import isEqualColumns from './utils/isEqualColumns';
import DateWithFormatter from './utils/DateWithFormatter';
import {
+ BasicColorFormatterType,
+ ColorSchemeEnum,
DataColumnMeta,
TableChartProps,
TableChartTransformedProps,
@@ -390,9 +393,124 @@ const transformProps = (
allow_rearrange_columns: allowRearrangeColumns,
allow_render_html: allowRenderHtml,
time_compare,
+ comparison_color_enabled: comparisonColorEnabled = false,
+ comparison_color_scheme: comparisonColorScheme = ColorSchemeEnum.Green,
} = formData;
const isUsingTimeComparison =
!isEmpty(time_compare) && queryMode === QueryMode.Aggregate;
+
+ 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(ensureIsArray(time_compare)[0]) &&
+ origCol.isNumeric
+ ) {
+ const originalValue = originalItem[origCol.key] || 0;
+ const comparisonValue = origCol.isMetric
+ ? originalItem?.[
+ `${origCol.key}__${ensureIsArray(time_compare)[0]}`
+ ] || 0
+ : originalItem[
+ `%${origCol.key.slice(1)}__${ensureIsArray(time_compare)[0]}`
+ ] || 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 timeGrain = extractTimegrain(formData);
const comparisonSuffix = isUsingTimeComparison
? ensureIsArray(time_compare)[0]
@@ -431,12 +549,22 @@ const transformProps = (
? processComparisonTotals(comparisonSuffix, totalQuery?.data)
: totalQuery?.data[0]
: undefined;
- const columnColorFormatters =
- getColorFormatters(conditionalFormatting, data) ?? defaultColorFormatters;
const passedData = isUsingTimeComparison ? comparisonData || [] : data;
const passedColumns = isUsingTimeComparison ? 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,
@@ -469,6 +597,8 @@ const transformProps = (
allowRenderHtml,
onContextMenu,
isUsingTimeComparison,
+ 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 2abba6815d..7aa14d06ac 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts
@@ -102,6 +102,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;
isUsingTimeComparison?: 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 }[];
};