Skip to content

Commit 69ae6aa

Browse files
committed
feat(FR-1355): improve BAIPropertyFilter display with value labels for better UX (#4114)
Resolves #4113 ([FR-1355](https://lablup.atlassian.net/browse/FR-1355)) ## Summary - Enhanced BAIPropertyFilter component to display user-friendly labels instead of raw values in filter tags - Added valueLabel support to FilterInput interface for better UX - Updated tag display logic to prioritize readable labels over raw values - Added permission filter options to VFolderNodeListPage - Maintains full backward compatibility ## Changes Made - **BAIPropertyFilter.tsx**: Added valueLabel field and logic to display user-friendly labels - **VFolderNodeListPage.tsx**: Added permission filter options with proper labels ## Example Improvement - **Before**: "Type: group" (confusing raw value) - **After**: "Type: Project" (user-friendly label) ## Test Plan - [ ] Verify filter tags show readable labels when available - [ ] Verify fallback to raw values when no label is provided - [ ] Test both new and existing filter functionality - [ ] Confirm backward compatibility with existing implementations [FR-1355]: https://lablup.atlassian.net/browse/FR-1355?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent 649937f commit 69ae6aa

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

packages/backend.ai-ui/src/components/BAIPropertyFilter.tsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ interface FilterInput {
5454
operator: string;
5555
value: string;
5656
label?: ReactNode;
57+
valueLabel?: string;
5758
type: FilterProperty['type'];
5859
propertyLabel: string;
5960
}
@@ -215,21 +216,36 @@ const BAIPropertyFilter: React.FC<BAIPropertyFilterProps> = ({
215216
onChange: propOnChange,
216217
});
217218

219+
const generateValueLabel = (label: ReactNode) => {
220+
// Generate a label for the filter value,
221+
// if the label is a string or number, return its string representation.
222+
// Otherwise, return undefined.
223+
return _.isString(label) || _.isNumber(label)
224+
? _.toString(label)
225+
: undefined;
226+
};
227+
218228
const filtersFromValue = useMemo(() => {
219229
if (value === undefined || value === '') return [];
220230
const filters = value.split('&').map((filter) => filter.trim());
221231
return filters.map((filter, index) => {
222232
const { property, operator, value } = parseFilterValue(filter);
233+
const filterProperty = _.find(
234+
filterProperties,
235+
(f) => f.key === property,
236+
);
237+
const option = _.find(
238+
filterProperty?.options,
239+
(o) => o.value === trimFilterValue(value),
240+
);
223241
return {
224242
key: index + value,
225243
property,
226244
operator,
227245
value,
228-
propertyLabel:
229-
_.find(filterProperties, (f) => f.key === property)?.propertyLabel ||
230-
property,
231-
type:
232-
_.find(filterProperties, (f) => f.key === property)?.type || 'string',
246+
valueLabel: generateValueLabel(option?.label),
247+
propertyLabel: filterProperty?.propertyLabel || property,
248+
type: filterProperty?.type || 'string',
233249
};
234250
});
235251
}, [value, filterProperties]);
@@ -297,12 +313,14 @@ const BAIPropertyFilter: React.FC<BAIPropertyFilterProps> = ({
297313
DEFAULT_OPERATOR_OF_TYPES[selectedProperty.type];
298314
const filterValue =
299315
operator === 'ilike' || operator === 'like' ? `%${value}%` : `${value}`;
316+
const option = _.find(selectedProperty.options, (o) => o.value === value);
300317
push({
301318
property: selectedProperty.key,
302319
propertyLabel: selectedProperty.propertyLabel,
303320
operator,
304321
value: filterValue,
305-
label: selectedProperty.options?.find((o) => o.value === value)?.label,
322+
label: option?.label,
323+
valueLabel: generateValueLabel(option?.label),
306324
type: selectedProperty.type,
307325
});
308326
};
@@ -383,7 +401,8 @@ const BAIPropertyFilter: React.FC<BAIPropertyFilterProps> = ({
383401
onClose={() => remove(item.key)}
384402
style={{ margin: 0 }}
385403
>
386-
{item.propertyLabel}: {trimFilterValue(item.value)}
404+
{item.propertyLabel}:{' '}
405+
{item.valueLabel ?? trimFilterValue(item.value)}
387406
</Tag>
388407
))}
389408
{filtersFromValue.length > 1 && (

react/src/pages/VFolderNodeListPage.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,18 @@ const VFolderNodeListPage: React.FC<VFolderNodeListPageProps> = ({
565565
key: 'permission',
566566
propertyLabel: t('data.Permission'),
567567
type: 'string',
568+
strictSelection: true,
569+
defaultOperator: '==',
570+
options: [
571+
{
572+
label: t('data.ReadOnly'),
573+
value: 'ro',
574+
},
575+
{
576+
label: t('data.ReadWrite'),
577+
value: 'rw',
578+
},
579+
],
568580
},
569581
]}
570582
value={queryParams.filter || undefined}

0 commit comments

Comments
 (0)