Skip to content

Commit 44223f1

Browse files
committed
add trendColorsTooltip to ColorPickerControl, fix test , add normalizeColorToHex
1 parent 5953d13 commit 44223f1

4 files changed

Lines changed: 82 additions & 4 deletions

File tree

superset-frontend/src/explore/components/controls/ColorPickerControl.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ test('resolves colorSuccess theme token correctly when matching color is selecte
204204

205205
await userEvent.click(successPreset!);
206206

207-
expect(onChange).toHaveBeenCalledWith({ a: 1, b: 26, g: 196, r: 82 });
207+
expect(onChange).toHaveBeenCalledWith('colorSuccess');
208208
});
209209

210210
test('handles theme with nested colors object', () => {

superset-frontend/src/explore/components/controls/ColorPickerControl.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const getReverseThemeColorMap = (
5757

5858
Object.entries(themeColors).forEach(([name, value]) => {
5959
if (typeof value === 'string') {
60-
reverseMap[value.toLowerCase()] = name;
60+
reverseMap[normalizeColorToHex(value)] = name;
6161
}
6262
});
6363

@@ -101,6 +101,32 @@ const extractThemeColors = (
101101
return theme as unknown as Record<string, string>;
102102
};
103103

104+
const normalizeColorToHex = (color: string): string => {
105+
if (!color) return '';
106+
107+
if (color.startsWith('#')) {
108+
return color.toLowerCase();
109+
}
110+
111+
const div = document.createElement('div');
112+
div.style.color = color;
113+
const normalized = div.style.color;
114+
115+
const match = normalized.match(
116+
/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/,
117+
);
118+
if (match) {
119+
return rgbaToHex({
120+
r: parseInt(match[1], 10),
121+
g: parseInt(match[2], 10),
122+
b: parseInt(match[3], 10),
123+
a: match[4] !== undefined ? parseFloat(match[4]) : 1,
124+
}).toLowerCase();
125+
}
126+
127+
return color.toLowerCase();
128+
};
129+
104130
export default function ColorPickerControl({
105131
onChange,
106132
value,

superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.test.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,12 @@ test('renders None for operator when Green for increase is selected', async () =
151151

152152
expect(safeGreenPreset).toBeInTheDocument();
153153
await userEvent.click(safeGreenPreset);
154-
const operatorSelect = container.querySelector('[data-test="Operator"]');
155-
expect(operatorSelect).toBeInTheDocument();
156154

155+
const operatorInput = screen.getByLabelText('Operator');
156+
expect(operatorInput).toBeInTheDocument();
157+
158+
const operatorSelect = operatorInput.closest('.ant-select-content');
159+
expect(operatorSelect).toBeInTheDocument();
157160
expect(operatorSelect).toHaveTextContent(/none/i);
158161
});
159162

@@ -328,3 +331,43 @@ test('should hide formatting fields when color scheme is Green', async () => {
328331
expect(screen.queryByText('Formatting object')).not.toBeInTheDocument();
329332
});
330333
});
334+
335+
test('should not display tooltip when extraColorChoices is not provided', async () => {
336+
const { container } = render(
337+
<FormattingPopoverContent onChange={mockOnChange} columns={columns} />,
338+
);
339+
340+
const tooltipIcon = container.querySelector('.ant-form-item-tooltip');
341+
expect(tooltipIcon).not.toBeInTheDocument();
342+
});
343+
344+
test('should display tooltip icon when extraColorChoices is provided', () => {
345+
const { container } = render(
346+
<FormattingPopoverContent
347+
onChange={mockOnChange}
348+
columns={columns}
349+
extraColorChoices={extraColorChoices}
350+
/>,
351+
);
352+
353+
const tooltipIcon = container.querySelector('.ant-form-item-tooltip');
354+
expect(tooltipIcon).toBeInTheDocument();
355+
356+
const questionIcon = tooltipIcon?.querySelector(
357+
'[aria-label="question-circle"]',
358+
);
359+
expect(questionIcon).toBeInTheDocument();
360+
});
361+
362+
test('should not display tooltip icon when extraColorChoices is empty', () => {
363+
const { container } = render(
364+
<FormattingPopoverContent
365+
onChange={mockOnChange}
366+
columns={columns}
367+
extraColorChoices={[]}
368+
/>,
369+
);
370+
371+
const tooltipIcon = container.querySelector('.ant-form-item-tooltip');
372+
expect(tooltipIcon).not.toBeInTheDocument();
373+
});

superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,14 @@ export const FormattingPopoverContent = ({
367367
}
368368
}, [column, columns, previousColumnType]);
369369

370+
const trendColorsTooltip = (
371+
<div>
372+
<div>{t('Trend colors are added (for time-based comparison):')}</div>
373+
<div>{t('green — increase / red — decrease')}</div>
374+
<div>{t('red — increase / green — decrease')}</div>
375+
</div>
376+
);
377+
370378
return (
371379
<Form
372380
form={form}
@@ -398,6 +406,7 @@ export const FormattingPopoverContent = ({
398406
label={t('Color scheme')}
399407
rules={rulesRequired}
400408
initialValue={defaultColorToken}
409+
tooltip={extraColorChoices.length > 0 ? trendColorsTooltip : ''}
401410
>
402411
<ColorPickerControl
403412
ariaLabel={t('Color scheme')}

0 commit comments

Comments
 (0)