mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-13 01:49:41 +08:00
✨ feat(data-grid): 优化字段跳转列匹配与回车定位
- 提取字段跳转目标解析逻辑,优先精确匹配再回退模糊匹配 - 旧版跳转列保留补全下拉,选中或回车即可定位 - 移除旧版多余跳转按钮,统一为输入即补全的交互 - 补充 DataGrid 与 dataGridFind 定向回归覆盖 - Refs #509
This commit is contained in:
@@ -91,6 +91,7 @@ import {
|
||||
findDataGridTextRanges,
|
||||
hasDataGridFindRenderVersionChanged,
|
||||
normalizeDataGridFindQuery,
|
||||
resolveDataGridColumnQuickFindTarget,
|
||||
resolveDataGridFindNavigationIndex,
|
||||
summarizeDataGridFindMatches,
|
||||
type DataGridFindMatch,
|
||||
@@ -6284,13 +6285,9 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
[visibleColumnQuickFindMatches],
|
||||
);
|
||||
|
||||
const resolveColumnQuickFindTarget = useCallback((): string => {
|
||||
const exactMatch = displayColumnNames.find((columnName) => (
|
||||
normalizeDataGridFindQuery(columnName) === normalizedColumnQuickFindText
|
||||
));
|
||||
if (exactMatch) return exactMatch;
|
||||
return visibleColumnQuickFindMatches[0] || '';
|
||||
}, [displayColumnNames, normalizedColumnQuickFindText, visibleColumnQuickFindMatches]);
|
||||
const resolveColumnQuickFindTarget = useCallback((query: string): string => (
|
||||
resolveDataGridColumnQuickFindTarget(displayColumnNames, query)
|
||||
), [displayColumnNames]);
|
||||
|
||||
const highlightColumnQuickFindTarget = useCallback((columnName: string) => {
|
||||
setHighlightedColumnName(columnName);
|
||||
@@ -6530,8 +6527,9 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
syncExternalScrollFromTargets,
|
||||
]);
|
||||
|
||||
const handleSubmitColumnQuickFind = useCallback(() => {
|
||||
const targetColumnName = resolveColumnQuickFindTarget();
|
||||
const handleSubmitColumnQuickFind = useCallback((submittedValue?: string) => {
|
||||
const effectiveQuery = String(submittedValue ?? columnQuickFindText);
|
||||
const targetColumnName = resolveColumnQuickFindTarget(effectiveQuery);
|
||||
if (!targetColumnName) {
|
||||
if (columnQuickFindText.trim()) {
|
||||
void message.warning(`未找到字段列:${columnQuickFindText.trim()}`);
|
||||
@@ -7037,7 +7035,7 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
inputProps={noAutoCapInputProps as Record<string, unknown>}
|
||||
value={columnQuickFindText}
|
||||
options={columnQuickFindOptions}
|
||||
hasTarget={!!resolveColumnQuickFindTarget()}
|
||||
hasTarget={!!resolveColumnQuickFindTarget(columnQuickFindText)}
|
||||
onChange={setColumnQuickFindText}
|
||||
onSubmit={handleSubmitColumnQuickFind}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { AutoComplete, Button, Input, Tooltip } from 'antd';
|
||||
import { AimOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { AutoComplete, Input, Tooltip } from 'antd';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
|
||||
export interface DataGridColumnQuickFindProps {
|
||||
isV2Ui: boolean;
|
||||
@@ -10,68 +10,62 @@ export interface DataGridColumnQuickFindProps {
|
||||
options: Array<{ value: string; label?: React.ReactNode }>;
|
||||
hasTarget: boolean;
|
||||
onChange: (value: string) => void;
|
||||
onSubmit: () => void;
|
||||
onSubmit: (value?: string) => void;
|
||||
}
|
||||
|
||||
const DataGridColumnQuickFind: React.FC<DataGridColumnQuickFindProps> = ({
|
||||
isV2Ui,
|
||||
darkMode,
|
||||
inputProps,
|
||||
value,
|
||||
options,
|
||||
hasTarget,
|
||||
onChange,
|
||||
onSubmit,
|
||||
}) => (
|
||||
<Tooltip title="输入字段名,回车或点定位按钮即可跳到对应列">
|
||||
<div
|
||||
data-grid-column-quick-find="true"
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find' : undefined}
|
||||
style={isV2Ui ? undefined : { display: 'flex', alignItems: 'center', gap: 6 }}
|
||||
>
|
||||
<div className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-row' : undefined}>
|
||||
<div className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-field' : undefined}>
|
||||
<AutoComplete
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-autocomplete' : undefined}
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onSelect={onChange}
|
||||
filterOption={false}
|
||||
popupMatchSelectWidth={280}
|
||||
>
|
||||
<Input
|
||||
{...inputProps}
|
||||
allowClear
|
||||
size="small"
|
||||
variant="borderless"
|
||||
prefix={<SearchOutlined />}
|
||||
placeholder="跳到字段列..."
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
onPressEnter={onSubmit}
|
||||
style={isV2Ui ? undefined : { width: 220 }}
|
||||
/>
|
||||
</AutoComplete>
|
||||
</div>
|
||||
<Button
|
||||
data-grid-column-quick-find-submit="true"
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-submit' : undefined}
|
||||
size="small"
|
||||
icon={<AimOutlined />}
|
||||
disabled={!hasTarget}
|
||||
onClick={onSubmit}
|
||||
}) => {
|
||||
const legacyDropdownOpen = !isV2Ui && String(value || '').trim().length > 0 && options.length > 0;
|
||||
|
||||
return (
|
||||
<Tooltip title="输入字段名,回车或点定位按钮即可跳到对应列">
|
||||
<div
|
||||
data-grid-column-quick-find="true"
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find' : undefined}
|
||||
style={isV2Ui ? undefined : { display: 'flex', alignItems: 'center', minWidth: 0, width: '100%', height: 32 }}
|
||||
>
|
||||
<div
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-row' : undefined}
|
||||
style={isV2Ui ? undefined : { display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, width: '100%', flexWrap: 'nowrap', height: 32 }}
|
||||
>
|
||||
{isV2Ui ? null : '跳转'}
|
||||
</Button>
|
||||
<div className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-field' : undefined} style={isV2Ui ? undefined : { display: 'flex', alignItems: 'center', height: 32 }}>
|
||||
<AutoComplete
|
||||
className={isV2Ui ? 'gn-v2-data-grid-column-quick-find-autocomplete' : undefined}
|
||||
options={options}
|
||||
value={value}
|
||||
open={isV2Ui ? undefined : legacyDropdownOpen}
|
||||
onChange={onChange}
|
||||
onSelect={(nextValue) => {
|
||||
onChange(nextValue);
|
||||
onSubmit(nextValue);
|
||||
}}
|
||||
filterOption={false}
|
||||
popupMatchSelectWidth={280}
|
||||
>
|
||||
<Input
|
||||
{...inputProps}
|
||||
allowClear
|
||||
size="small"
|
||||
variant="borderless"
|
||||
prefix={<SearchOutlined />}
|
||||
placeholder="跳到字段列..."
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
onPressEnter={() => onSubmit(value)}
|
||||
style={isV2Ui ? undefined : { width: 168, height: 32 }}
|
||||
/>
|
||||
</AutoComplete>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!isV2Ui && (
|
||||
<span style={{ fontSize: 12, color: darkMode ? '#999' : '#666', whiteSpace: 'nowrap' }}>
|
||||
定位字段列
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataGridColumnQuickFind;
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
findDataGridTextRanges,
|
||||
hasDataGridFindRenderVersionChanged,
|
||||
normalizeDataGridFindQuery,
|
||||
resolveDataGridColumnQuickFindTarget,
|
||||
resolveDataGridFindNavigationIndex,
|
||||
summarizeDataGridFindMatches,
|
||||
} from './dataGridFind';
|
||||
@@ -89,6 +90,15 @@ describe('dataGridFind', () => {
|
||||
expect(resolveDataGridFindNavigationIndex(0, 0, 'next')).toBe(-1);
|
||||
});
|
||||
|
||||
it('prefers an exact quick-find column match over earlier fuzzy matches', () => {
|
||||
const columnNames = ['user_id', 'username', 'created_at'];
|
||||
|
||||
expect(resolveDataGridColumnQuickFindTarget(columnNames, 'username')).toBe('username');
|
||||
expect(resolveDataGridColumnQuickFindTarget(columnNames, 'user')).toBe('user_id');
|
||||
expect(resolveDataGridColumnQuickFindTarget(columnNames, ' ')).toBe('');
|
||||
expect(resolveDataGridColumnQuickFindTarget(columnNames, 'missing')).toBe('');
|
||||
});
|
||||
|
||||
it('tracks render version changes without exposing metadata as row data', () => {
|
||||
const rows = [{ id: 1, name: 'Alpha' }];
|
||||
|
||||
|
||||
@@ -143,3 +143,20 @@ export const resolveDataGridFindNavigationIndex = (
|
||||
}
|
||||
return currentIndex < 0 || currentIndex >= matchCount - 1 ? 0 : currentIndex + 1;
|
||||
};
|
||||
|
||||
export const resolveDataGridColumnQuickFindTarget = (
|
||||
columnNames: string[],
|
||||
query: string,
|
||||
): string => {
|
||||
const normalizedQuery = normalizeDataGridFindQuery(query);
|
||||
if (!normalizedQuery) return '';
|
||||
|
||||
const exactMatch = columnNames.find((columnName) => (
|
||||
normalizeDataGridFindQuery(columnName) === normalizedQuery
|
||||
));
|
||||
if (exactMatch) return exactMatch;
|
||||
|
||||
return columnNames.find((columnName) => (
|
||||
normalizeDataGridFindQuery(columnName).includes(normalizedQuery)
|
||||
)) || '';
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user