Skip to content

Commit 5551337

Browse files
authored
Optimize selecting labels (#219)
* update frontend Signed-off-by: kerthcet <kerthcet@gmail.com> * Optimize Signed-off-by: kerthcet <kerthcet@gmail.com> --------- Signed-off-by: kerthcet <kerthcet@gmail.com>
1 parent 5d78a40 commit 5551337

7 files changed

Lines changed: 170 additions & 147 deletions

File tree

dashboard/src/components/ui/multi-select-dropdown.tsx

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ export function MultiSelectDropdown({ values, onChange, options, className, plac
8787
<span className="text-muted-foreground font-medium">{placeholder || "Select labels..."}</span>
8888
) : (
8989
selectedOptions.map((option) => {
90-
// For "Any" options, show the full label. For specific values, show key:value
91-
const displayLabel = option.value.endsWith(':*')
92-
? option.label
93-
: `${option.group}:${option.label}`;
90+
// Show group:label for all options
91+
const displayLabel = option.group
92+
? `${option.group}:${option.label}`
93+
: option.label;
9494

9595
return (
9696
<Badge
@@ -122,34 +122,68 @@ export function MultiSelectDropdown({ values, onChange, options, className, plac
122122
{isOpen && (
123123
<div className="absolute z-50 mt-1 w-full rounded-md border bg-popover shadow-lg">
124124
<div className="max-h-80 overflow-auto p-1">
125-
{Object.entries(groupedOptions).map(([groupName, groupOptions]) => (
126-
<div key={groupName}>
127-
<div className="px-2 py-1.5 text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">
128-
{groupName}
129-
</div>
130-
{groupOptions.map((option) => (
125+
{Object.entries(groupedOptions).map(([groupName, groupOptions]) => {
126+
const groupValues = groupOptions.map(opt => opt.value);
127+
const allGroupSelected = groupValues.every(val => values.includes(val));
128+
129+
const toggleGroupAll = () => {
130+
if (allGroupSelected) {
131+
// Deselect all in this group
132+
onChange(values.filter(v => !groupValues.includes(v)));
133+
} else {
134+
// Select all in this group
135+
const newValues = [...values];
136+
groupValues.forEach(v => {
137+
if (!newValues.includes(v)) {
138+
newValues.push(v);
139+
}
140+
});
141+
onChange(newValues);
142+
}
143+
};
144+
145+
return (
146+
<div key={groupName}>
131147
<button
132-
key={option.value}
133148
type="button"
134-
onClick={() => toggleOption(option.value)}
135-
className={cn(
136-
"w-full rounded-sm px-2 py-1.5 pl-6 text-[13px] text-left cursor-pointer transition-colors flex items-center gap-2",
137-
"hover:bg-accent hover:text-accent-foreground"
138-
)}
149+
onClick={toggleGroupAll}
150+
className="flex items-center gap-2 w-full px-2 py-1.5 hover:bg-accent/50 transition-colors rounded-sm"
151+
title={allGroupSelected ? 'Deselect all' : 'Select all'}
139152
>
140153
<input
141154
type="checkbox"
142-
checked={values.includes(option.value)}
143-
onChange={() => {}}
155+
checked={allGroupSelected}
156+
readOnly
144157
className="h-3.5 w-3.5 rounded border-gray-300"
145158
/>
146-
<span className={cn(values.includes(option.value) && "font-medium")}>
147-
{option.label}
148-
</span>
159+
<div className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">
160+
{groupName}
161+
</div>
149162
</button>
150-
))}
151-
</div>
152-
))}
163+
{groupOptions.map((option) => (
164+
<button
165+
key={option.value}
166+
type="button"
167+
onClick={() => toggleOption(option.value)}
168+
className={cn(
169+
"w-full rounded-sm px-2 py-1.5 pl-6 text-[13px] text-left cursor-pointer transition-colors flex items-center gap-2",
170+
"hover:bg-accent hover:text-accent-foreground"
171+
)}
172+
>
173+
<input
174+
type="checkbox"
175+
checked={values.includes(option.value)}
176+
onChange={() => {}}
177+
className="h-3.5 w-3.5 rounded border-gray-300"
178+
/>
179+
<span className={cn(values.includes(option.value) && "font-medium")}>
180+
{option.label}
181+
</span>
182+
</button>
183+
))}
184+
</div>
185+
);
186+
})}
153187
</div>
154188
</div>
155189
)}

dashboard/src/pages/experiments/index.tsx

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,6 @@ export function ExperimentsPage() {
153153
Array.from(labelsByKey.entries())
154154
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
155155
.forEach(([key, values]) => {
156-
// Add "Any" option for this key
157-
options.push({
158-
value: `${key}:*`,
159-
label: `(Any ${key})`,
160-
group: key
161-
});
162-
163156
// Add specific value options
164157
Array.from(values)
165158
.sort()
@@ -224,16 +217,10 @@ export function ExperimentsPage() {
224217
// Check if experiment matches ALL selected label filters
225218
return labelFilters.every(filter => {
226219
const [labelName, labelValue] = filter.split(':', 2);
227-
228-
if (labelValue === '*') {
229-
// "key:*" means any experiment with this key
230-
return exp.labels?.some(label => label.name === labelName);
231-
} else {
232-
// "key:value" means exact match
233-
return exp.labels?.some(label =>
234-
label.name === labelName && label.value === labelValue
235-
);
236-
}
220+
// "key:value" means exact match
221+
return exp.labels?.some(label =>
222+
label.name === labelName && label.value === labelValue
223+
);
237224
});
238225
});
239226
}

dashboard/static/assets/index-Bzt5UaWS.css

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 104 additions & 102 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/static/assets/index-QJXu-5su.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/static/assets/react-plotly-qYsasf3q.js renamed to dashboard/static/assets/react-plotly-DzZ_l-Vq.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/static/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<link rel="icon" type="image/png" href="/static/assets/logo-D6hHn9pX.png" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
88
<title>AlphaTrion</title>
9-
<script type="module" crossorigin src="/static/assets/index-BCau2aCP.js"></script>
10-
<link rel="stylesheet" crossorigin href="/static/assets/index-Bzt5UaWS.css">
9+
<script type="module" crossorigin src="/static/assets/index-CxT6Jcuc.js"></script>
10+
<link rel="stylesheet" crossorigin href="/static/assets/index-QJXu-5su.css">
1111
</head>
1212

1313
<body>

0 commit comments

Comments
 (0)