Improve AsyncSelect layout and text overflow handling

- Add responsive width container
- Improve text truncation with tooltips
This commit is contained in:
yangdx 2025-10-17 19:10:36 +08:00
parent f555824064
commit 4c3ab58473

View file

@ -175,49 +175,59 @@ const GraphLabels = () => {
> >
<RefreshCw className={`h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} /> <RefreshCw className={`h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
</Button> </Button>
<AsyncSelect<string> <div className="w-full min-w-[280px] max-w-[500px]">
key={selectKey} // Force re-render when data changes <AsyncSelect<string>
className="min-w-[300px]" key={selectKey} // Force re-render when data changes
triggerClassName="max-h-8" className="min-w-[300px]"
searchInputClassName="max-h-8" triggerClassName="max-h-8 w-full overflow-hidden"
triggerTooltip={t('graphPanel.graphLabels.selectTooltip')} searchInputClassName="max-h-8"
fetcher={fetchData} triggerTooltip={t('graphPanel.graphLabels.selectTooltip')}
renderOption={(item) => <div style={{ whiteSpace: 'pre' }}>{item}</div>} fetcher={fetchData}
getOptionValue={(item) => item} renderOption={(item) => (
getDisplayValue={(item) => <div style={{ whiteSpace: 'pre' }}>{item}</div>} <div className="truncate" title={item}>
notFound={<div className="py-6 text-center text-sm">{t('graphPanel.graphLabels.noLabels')}</div>} {item}
ariaLabel={t('graphPanel.graphLabels.label')} </div>
placeholder={t('graphPanel.graphLabels.placeholder')} )}
searchPlaceholder={t('graphPanel.graphLabels.placeholder')} getOptionValue={(item) => item}
noResultsMessage={t('graphPanel.graphLabels.noLabels')} getDisplayValue={(item) => (
value={label !== null ? label : '*'} <div className="min-w-0 flex-1 truncate text-left" title={item}>
onChange={(newLabel) => { {item}
const currentLabel = useSettingsStore.getState().queryLabel; </div>
)}
notFound={<div className="py-6 text-center text-sm">{t('graphPanel.graphLabels.noLabels')}</div>}
ariaLabel={t('graphPanel.graphLabels.label')}
placeholder={t('graphPanel.graphLabels.placeholder')}
searchPlaceholder={t('graphPanel.graphLabels.placeholder')}
noResultsMessage={t('graphPanel.graphLabels.noLabels')}
value={label !== null ? label : '*'}
onChange={(newLabel) => {
const currentLabel = useSettingsStore.getState().queryLabel;
// select the last item means query all // select the last item means query all
if (newLabel === '...') { if (newLabel === '...') {
newLabel = '*'; newLabel = '*';
} }
// Handle reselecting the same label // Handle reselecting the same label
if (newLabel === currentLabel && newLabel !== '*') { if (newLabel === currentLabel && newLabel !== '*') {
newLabel = '*'; newLabel = '*';
} }
// Add selected label to search history (except for special cases) // Add selected label to search history (except for special cases)
if (newLabel && newLabel !== '*' && newLabel !== '...' && newLabel.trim() !== '') { if (newLabel && newLabel !== '*' && newLabel !== '...' && newLabel.trim() !== '') {
SearchHistoryManager.addToHistory(newLabel); SearchHistoryManager.addToHistory(newLabel);
} }
// Reset graphDataFetchAttempted flag to ensure data fetch is triggered // Reset graphDataFetchAttempted flag to ensure data fetch is triggered
useGraphStore.getState().setGraphDataFetchAttempted(false); useGraphStore.getState().setGraphDataFetchAttempted(false);
// Update the label to trigger data loading // Update the label to trigger data loading
useSettingsStore.getState().setQueryLabel(newLabel); useSettingsStore.getState().setQueryLabel(newLabel);
}} }}
clearable={false} // Prevent clearing value on reselect clearable={false} // Prevent clearing value on reselect
debounceTime={500} debounceTime={500}
/> />
</div>
</div> </div>
) )
} }