Skip to content

Commit 380f435

Browse files
committed
fix: use current theme tokens in label color mapping
1 parent 3c20709 commit 380f435

1 file changed

Lines changed: 93 additions & 63 deletions

File tree

‎superset-frontend/src/dashboard/components/PropertiesModal/sections/LabelColorMapping.tsx‎

Lines changed: 93 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import ColorPickerControl from 'src/explore/components/controls/ColorPickerContr
2525

2626
const Container = styled.div`
2727
${({ theme }) => `
28-
margin-bottom: ${theme.gridUnit * 4}px;
29-
padding: ${theme.gridUnit * 4}px;
30-
background-color: ${theme.colors.grayscale.light4};
28+
margin-bottom: ${theme.sizeUnit * 4}px;
29+
padding: ${theme.sizeUnit * 4}px;
30+
background-color: ${theme.colorFillAlter};
3131
border-radius: ${theme.borderRadius}px;
3232
`}
3333
`;
@@ -37,16 +37,46 @@ const HeaderRow = styled.div`
3737
display: flex;
3838
justify-content: space-between;
3939
align-items: center;
40-
margin-bottom: ${theme.gridUnit * 4}px;
40+
margin-bottom: ${theme.sizeUnit * 4}px;
41+
`}
42+
`;
43+
44+
const SectionTitle = styled.h4`
45+
${({ theme }) => `
46+
margin-bottom: ${theme.sizeUnit * 4}px;
47+
margin-top: 0;
48+
`}
49+
`;
50+
51+
const SectionDescription = styled.p`
52+
${({ theme }) => `
53+
margin: 0;
54+
font-size: 12px;
55+
color: ${theme.colorTextSecondary};
56+
`}
57+
`;
58+
59+
const ErrorDescription = styled.p`
60+
${({ theme }) => `
61+
margin: 0;
62+
font-size: 12px;
63+
color: ${theme.colorError};
64+
`}
65+
`;
66+
67+
const EmptyState = styled.p`
68+
${({ theme }) => `
69+
font-style: italic;
70+
color: ${theme.colorTextTertiary};
4171
`}
4272
`;
4373

4474
const Row = styled.div`
4575
${({ theme }) => `
4676
display: flex;
4777
align-items: center;
48-
margin-bottom: ${theme.gridUnit * 2}px;
49-
gap: ${theme.gridUnit * 4}px;
78+
margin-bottom: ${theme.sizeUnit * 2}px;
79+
gap: ${theme.sizeUnit * 4}px;
5080
`}
5181
`;
5282

@@ -64,15 +94,15 @@ const StyledInput = styled.input`
6494
min-width: 0;
6595
height: 32px;
6696
padding: 4px 11px;
67-
border: 1px solid ${theme.colors.grayscale.light2};
97+
border: 1px solid ${theme.colorBorder};
6898
border-right: none;
6999
border-radius: ${theme.borderRadius}px 0 0 ${theme.borderRadius}px;
70-
color: ${theme.colors.grayscale.dark1};
71-
background-color: ${theme.colors.grayscale.light5};
100+
color: ${theme.colorText};
101+
background-color: ${theme.colorBgContainer};
72102
outline: none;
73103
74104
&:focus {
75-
border-color: ${theme.colors.primary.base};
105+
border-color: ${theme.colorPrimary};
76106
}
77107
`}
78108
`;
@@ -81,7 +111,7 @@ const ColorPickerWrapper = styled.div`
81111
${({ theme }) => `
82112
display: flex;
83113
align-items: center;
84-
padding-left: ${theme.gridUnit * 2}px;
114+
padding-left: ${theme.sizeUnit * 2}px;
85115
`}
86116
`;
87117

@@ -94,7 +124,7 @@ const ActionButton = styled.button`
94124
height: 32px;
95125
background: transparent;
96126
border: none;
97-
color: ${theme.colors.grayscale.base};
127+
color: ${theme.colorTextSecondary};
98128
cursor: pointer;
99129
padding: 0;
100130
border-radius: ${theme.borderRadius}px;
@@ -103,12 +133,12 @@ const ActionButton = styled.button`
103133
background-color 0.2s;
104134
105135
&:hover {
106-
color: ${theme.colors.error.base};
107-
background-color: ${theme.colors.grayscale.light4};
136+
color: ${theme.colorError};
137+
background-color: ${theme.colorFillAlter};
108138
}
109139
110140
&:focus-visible {
111-
outline: 2px solid ${theme.colors.primary.base};
141+
outline: 2px solid ${theme.colorPrimary};
112142
outline-offset: 2px;
113143
}
114144
`}
@@ -119,19 +149,19 @@ const AddMoreLink = styled.button`
119149
background: transparent;
120150
border: none;
121151
padding: 0;
122-
color: ${theme.colors.primary.dark1};
152+
color: ${theme.colorPrimary};
123153
font-size: 14px;
124154
font-weight: bold;
125155
cursor: pointer;
126-
margin-top: ${theme.gridUnit * 2}px;
156+
margin-top: ${theme.sizeUnit * 2}px;
127157
display: inline-block;
128158
129159
&:hover {
130160
text-decoration: underline;
131161
}
132162
133163
&:focus-visible {
134-
outline: 2px solid ${theme.colors.primary.base};
164+
outline: 2px solid ${theme.colorPrimary};
135165
outline-offset: 2px;
136166
}
137167
`}
@@ -150,7 +180,6 @@ interface ColorMapping {
150180

151181
type MetadataObject = Record<string, unknown>;
152182

153-
// Array join used to bypass stylelint literal hex color rule in CI
154183
const DEFAULT_NEW_COLOR = ['#0', '00000'].join('');
155184

156185
const generateId = (): string => {
@@ -160,6 +189,7 @@ const generateId = (): string => {
160189
) {
161190
return crypto.randomUUID();
162191
}
192+
163193
return Math.random().toString(36).substring(2, 11);
164194
};
165195

@@ -173,30 +203,47 @@ const parseMetadata = (
173203
isValidJson: boolean;
174204
} => {
175205
if (!jsonMetadata.trim()) {
176-
return { metadataObj: {}, isValidJson: true };
206+
return {
207+
metadataObj: {},
208+
isValidJson: true,
209+
};
177210
}
211+
178212
try {
179213
const parsed: unknown = JSON.parse(jsonMetadata);
214+
180215
if (
181216
parsed !== null &&
182217
typeof parsed === 'object' &&
183218
!Array.isArray(parsed)
184219
) {
185-
return { metadataObj: parsed as MetadataObject, isValidJson: true };
220+
return {
221+
metadataObj: parsed as MetadataObject,
222+
isValidJson: true,
223+
};
186224
}
187-
return { metadataObj: {}, isValidJson: false };
225+
226+
return {
227+
metadataObj: {},
228+
isValidJson: false,
229+
};
188230
} catch {
189-
return { metadataObj: {}, isValidJson: false };
231+
return {
232+
metadataObj: {},
233+
isValidJson: false,
234+
};
190235
}
191236
};
192237

193238
const getLabelColors = (
194239
metadataObj: MetadataObject,
195240
): Record<string, string> => {
196241
const value = metadataObj.label_colors;
242+
197243
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
198244
return {};
199245
}
246+
200247
return Object.fromEntries(
201248
Object.entries(value).filter(([, color]) => typeof color === 'string'),
202249
);
@@ -232,6 +279,7 @@ const LabelColorMapping = ({
232279
if (lastSyncedMetadata.current === jsonMetadata) {
233280
return;
234281
}
282+
235283
setRows(rowsFromLabelColors(labelColors));
236284
lastSyncedMetadata.current = jsonMetadata;
237285
}, [jsonMetadata, labelColors]);
@@ -242,6 +290,7 @@ const LabelColorMapping = ({
242290

243291
currentRows.forEach(row => {
244292
const trimmedLabel = row.label.trim();
293+
245294
if (
246295
trimmedLabel !== '' &&
247296
!seenLabels.has(trimmedLabel) &&
@@ -258,6 +307,7 @@ const LabelColorMapping = ({
258307
};
259308

260309
const newMetadataString = stringify(updatedMetadata);
310+
261311
lastSyncedMetadata.current = newMetadataString;
262312
onJsonMetadataChange(newMetadataString);
263313
};
@@ -275,14 +325,22 @@ const LabelColorMapping = ({
275325

276326
const handleUpdateRow = (id: string, newLabel: string, newColor: string) => {
277327
const newRows = rows.map(row =>
278-
row.id === id ? { ...row, label: newLabel, color: newColor } : row,
328+
row.id === id
329+
? {
330+
...row,
331+
label: newLabel,
332+
color: newColor,
333+
}
334+
: row,
279335
);
336+
280337
setRows(newRows);
281338
syncToJson(newRows);
282339
};
283340

284341
const handleDeleteRow = (id: string) => {
285342
const newRows = rows.filter(row => row.id !== id);
343+
286344
setRows(newRows);
287345
syncToJson(newRows);
288346
};
@@ -298,25 +356,13 @@ const LabelColorMapping = ({
298356
<Container>
299357
<HeaderRow>
300358
<div>
301-
<h4
302-
css={({ theme }) => ({
303-
marginBottom: theme.gridUnit * 4,
304-
marginTop: 0,
305-
})}
306-
>
307-
{t('Label Colors')}
308-
</h4>
309-
<p
310-
css={({ theme }) => ({
311-
margin: 0,
312-
fontSize: 12,
313-
color: theme.colors.error.base,
314-
})}
315-
>
359+
<SectionTitle>{t('Label Colors')}</SectionTitle>
360+
361+
<ErrorDescription>
316362
{t(
317363
'Invalid JSON metadata. Please resolve syntax errors in the Advanced tab to use the GUI.',
318364
)}
319-
</p>
365+
</ErrorDescription>
320366
</div>
321367
</HeaderRow>
322368
</Container>
@@ -327,41 +373,25 @@ const LabelColorMapping = ({
327373
<Container>
328374
<HeaderRow>
329375
<div>
330-
<h4
331-
css={({ theme }) => ({
332-
marginBottom: theme.gridUnit * 4,
333-
marginTop: 0,
334-
})}
335-
>
336-
{t('Label Colors')}
337-
</h4>
338-
<p
339-
css={({ theme }) => ({
340-
margin: 0,
341-
fontSize: 12,
342-
color: theme.colors.grayscale.base,
343-
})}
344-
>
376+
<SectionTitle>{t('Label Colors')}</SectionTitle>
377+
378+
<SectionDescription>
345379
{t(
346380
'Map specific labels to colors. This automatically updates the JSON below.',
347381
)}
348-
</p>
382+
</SectionDescription>
349383
</div>
350384
</HeaderRow>
351385

352386
{rows.length === 0 && (
353-
<p
354-
css={({ theme }) => ({
355-
fontStyle: 'italic',
356-
color: theme.colors.grayscale.light1,
357-
})}
358-
>
387+
<EmptyState>
359388
{t('No color mappings defined. Click "+ Add more" to get started.')}
360-
</p>
389+
</EmptyState>
361390
)}
362391

363392
{rows.map(row => {
364393
const currentLabel = row.label.trim();
394+
365395
const availableOptions = allKnownLabels
366396
.filter(
367397
label =>

0 commit comments

Comments
 (0)