|
|
|
|
@ -22,20 +22,70 @@ const arrayTypeOptions = [
|
|
|
|
|
{ label: 'OBJECT', value: 'OBJECT' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function EditableCell({ value, onChange, columnType, record, dataIndex }) {
|
|
|
|
|
const isEmptyValue = (value) => value === undefined || value === null || `${value}`.trim() === '';
|
|
|
|
|
|
|
|
|
|
const getFieldError = (record, dataIndex) => {
|
|
|
|
|
if (dataIndex === 'ident' && isEmptyValue(record.ident)) {
|
|
|
|
|
return '请输入名称';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataIndex === 'type' && isEmptyValue(record.type)) {
|
|
|
|
|
return '请选择数据类型';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataIndex === 'generic' && record.type === 'ARRAY' && isEmptyValue(record.generic)) {
|
|
|
|
|
return '请选择数组类型';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const validateEditableTableData = (tableData = []) => {
|
|
|
|
|
const errors = [];
|
|
|
|
|
|
|
|
|
|
tableData.forEach((item, index) => {
|
|
|
|
|
const rowIndex = index + 1;
|
|
|
|
|
|
|
|
|
|
if (isEmptyValue(item.ident)) {
|
|
|
|
|
errors.push(`第${rowIndex}行请输入名称`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isEmptyValue(item.type)) {
|
|
|
|
|
errors.push(`第${rowIndex}行请选择数据类型`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.type === 'ARRAY' && isEmptyValue(item.generic)) {
|
|
|
|
|
errors.push(`第${rowIndex}行请选择数组类型`);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
valid: errors.length === 0,
|
|
|
|
|
errors
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function EditableCell({ value, onChange, columnType, record, dataIndex, showError, onBlur }) {
|
|
|
|
|
const [error, setError] = useState('');
|
|
|
|
|
const requiredError = getFieldError(record, dataIndex);
|
|
|
|
|
const mergedError = error || (showError ? requiredError : '');
|
|
|
|
|
|
|
|
|
|
// 对于数组类型字段的特殊处理
|
|
|
|
|
if (dataIndex === 'generic') {
|
|
|
|
|
// 仅当数据类型为 ARRAY 时才可编辑
|
|
|
|
|
if (record.type === 'ARRAY') {
|
|
|
|
|
return (
|
|
|
|
|
<Select
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
options={arrayTypeOptions}
|
|
|
|
|
placeholder="请选择数组类型"
|
|
|
|
|
/>
|
|
|
|
|
<div>
|
|
|
|
|
<Select
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
onBlur={onBlur}
|
|
|
|
|
options={arrayTypeOptions}
|
|
|
|
|
placeholder="请选择数组类型"
|
|
|
|
|
status={mergedError ? 'error' : undefined}
|
|
|
|
|
/>
|
|
|
|
|
{mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
@ -64,10 +114,11 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
|
|
|
|
|
<Input
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={handleIdentChange}
|
|
|
|
|
onBlur={onBlur}
|
|
|
|
|
placeholder="请输入(仅支持英文字母、数字和下划线)"
|
|
|
|
|
status={error ? 'error' : undefined}
|
|
|
|
|
status={mergedError ? 'error' : undefined}
|
|
|
|
|
/>
|
|
|
|
|
{error && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{error}</div>}
|
|
|
|
|
{mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
@ -76,6 +127,7 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
|
|
|
|
|
<Input
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
onBlur={onBlur}
|
|
|
|
|
placeholder="请输入"
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
@ -83,20 +135,39 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
|
|
|
|
|
|
|
|
|
|
if (columnType === 'select') {
|
|
|
|
|
return (
|
|
|
|
|
<Select
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
options={dataTypeOptions}
|
|
|
|
|
placeholder="请选择数据类型"
|
|
|
|
|
/>
|
|
|
|
|
<div>
|
|
|
|
|
<Select
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
onBlur={onBlur}
|
|
|
|
|
options={dataTypeOptions}
|
|
|
|
|
placeholder="请选择数据类型"
|
|
|
|
|
status={mergedError ? 'error' : undefined}
|
|
|
|
|
/>
|
|
|
|
|
{mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <span>{value}</span>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
function EditableTable({ onDataUpdate, initialData = [], visible, showValidationErrors = false }) {
|
|
|
|
|
const [data, setData] = useState([]);
|
|
|
|
|
const [touchedFields, setTouchedFields] = useState({});
|
|
|
|
|
|
|
|
|
|
const getFieldKey = (key, dataIndex) => `${key}-${dataIndex}`;
|
|
|
|
|
|
|
|
|
|
const markFieldTouched = (key, dataIndex) => {
|
|
|
|
|
setTouchedFields(prev => ({
|
|
|
|
|
...prev,
|
|
|
|
|
[getFieldKey(key, dataIndex)]: true
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const shouldShowFieldError = (record, dataIndex) => {
|
|
|
|
|
return showValidationErrors || touchedFields[getFieldKey(record.key, dataIndex)];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 当初始数据变化时,更新表格数据
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
@ -112,6 +183,7 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!visible) setData([]);
|
|
|
|
|
if (!visible) setTouchedFields({});
|
|
|
|
|
}, [visible]);
|
|
|
|
|
|
|
|
|
|
const handleValueChange = (key, dataIndex, value) => {
|
|
|
|
|
@ -144,6 +216,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
columnType="input"
|
|
|
|
|
record={record}
|
|
|
|
|
dataIndex="ident"
|
|
|
|
|
showError={shouldShowFieldError(record, 'ident')}
|
|
|
|
|
onBlur={() => markFieldTouched(record.key, 'ident')}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
@ -157,6 +231,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
columnType="select"
|
|
|
|
|
record={record}
|
|
|
|
|
dataIndex="type"
|
|
|
|
|
showError={shouldShowFieldError(record, 'type')}
|
|
|
|
|
onBlur={() => markFieldTouched(record.key, 'type')}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
@ -170,6 +246,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
columnType="select"
|
|
|
|
|
record={record}
|
|
|
|
|
dataIndex="generic"
|
|
|
|
|
showError={shouldShowFieldError(record, 'generic')}
|
|
|
|
|
onBlur={() => markFieldTouched(record.key, 'generic')}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
@ -183,6 +261,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
columnType="input"
|
|
|
|
|
record={record}
|
|
|
|
|
dataIndex="desc"
|
|
|
|
|
showError={false}
|
|
|
|
|
onBlur={() => markFieldTouched(record.key, 'desc')}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
@ -239,4 +319,4 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default EditableTable;
|
|
|
|
|
export default EditableTable;
|
|
|
|
|
|