- EntitySelect: 未使用的 searchFields 改为 _searchFields - PluginKanbanPage: DragEndEvent/DragStartEvent 改为 type import, lane_order 改为 optional - PluginDashboardPage: 添加 PluginPageSchema import, 移除未使用的 CHART_COLORS/palette/totalCount - PluginGraphPage: 移除未使用的 Title/textColor, 修复 hovered → hoverState
81 lines
2.0 KiB
TypeScript
81 lines
2.0 KiB
TypeScript
import { Select, Spin } from 'antd';
|
|
import { useState, useEffect, useCallback } from 'react';
|
|
import { listPluginData } from '../api/pluginData';
|
|
|
|
interface EntitySelectProps {
|
|
pluginId: string;
|
|
entity: string;
|
|
labelField: string;
|
|
searchFields?: string[];
|
|
value?: string;
|
|
onChange?: (value: string, label: string) => void;
|
|
cascadeFrom?: string;
|
|
cascadeFilter?: string;
|
|
cascadeValue?: string;
|
|
placeholder?: string;
|
|
}
|
|
|
|
export default function EntitySelect({
|
|
pluginId,
|
|
entity,
|
|
labelField,
|
|
searchFields: _searchFields,
|
|
value,
|
|
onChange,
|
|
cascadeFrom,
|
|
cascadeFilter,
|
|
cascadeValue,
|
|
placeholder,
|
|
}: EntitySelectProps) {
|
|
const [options, setOptions] = useState<{ value: string; label: string }[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const fetchData = useCallback(
|
|
async (keyword?: string) => {
|
|
setLoading(true);
|
|
try {
|
|
const filter: Record<string, string> | undefined =
|
|
cascadeFrom && cascadeFilter && cascadeValue
|
|
? { [cascadeFilter]: cascadeValue }
|
|
: undefined;
|
|
|
|
const result = await listPluginData(pluginId, entity, 1, 20, {
|
|
search: keyword,
|
|
filter,
|
|
});
|
|
|
|
const items = (result.data || []).map((item) => ({
|
|
value: item.id,
|
|
label: String(item.data?.[labelField] ?? item.id),
|
|
}));
|
|
setOptions(items);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
},
|
|
[pluginId, entity, labelField, cascadeFrom, cascadeFilter, cascadeValue],
|
|
);
|
|
|
|
useEffect(() => {
|
|
fetchData();
|
|
}, [fetchData]);
|
|
|
|
return (
|
|
<Select
|
|
showSearch
|
|
value={value}
|
|
placeholder={placeholder || '请选择'}
|
|
loading={loading}
|
|
options={options}
|
|
onSearch={(v) => fetchData(v)}
|
|
onChange={(v) => {
|
|
const opt = options.find((o) => o.value === v);
|
|
onChange?.(v, opt?.label || '');
|
|
}}
|
|
filterOption={false}
|
|
notFoundContent={loading ? <Spin size="small" /> : '无数据'}
|
|
allowClear
|
|
/>
|
|
);
|
|
}
|