import React from 'react' import _ from 'lodash' import { MinusOutlined, PlusOutlined } from '@ant-design/icons'; import { Form } from '@ant-design/compatible'; import '@ant-design/compatible/assets/index.css'; import { Button, Checkbox, Input, InputNumber, Select, AutoComplete } from 'antd'; import { getFieldTypeData, getInputTypeData, getXComponentData, getComponentPropsData, getComponentProps, getInputType, getDefaultValue, getPropertyValue, getExpressionValue, getRuleMessage, fieldTypeDisabled, getDefaultXProps, getDefaultXRules } from '../utils/fieldEditorHelpers' import { InputTypes, ComponentPropsTypes } from '../utils/types' const FormItem = Form.Item const SelectOption = Select.Option const formItemLayout = { labelCol: { span: 24 }, wrapperCol: { span: 24 } } const BLANK_PROPERTY_VALUE = '' interface IFieldEditorProps { isRoot: boolean fieldKey: string onFieldKeyChange: (fieldKey: string) => void schema: any components?: any xProps?: any xRules?: any onChange: (schema: any) => void } interface IFormItemGroupProps extends Partial { title: string propsKey: string } const FormItemGroup: React.FC = ({ title, schema, components, propsKey, onChange }) => { const componentName = schema[ComponentPropsTypes.X_COMPONENT] const inputTypeData = getInputTypeData() const componentPropsData = getComponentPropsData({ schema, components, componentName, propsKey }) const componentProps = getComponentProps({ schema, propsKey }) const handleXComponentPropsValueChange = (value, property) => { let newSchema if (propsKey === ComponentPropsTypes.X_RULES) { const newRules = _.map(schema[propsKey], rule => { if (_.has(rule, property)) { return { ...rule, [property]: value } } return rule }) newSchema = { ...schema, [propsKey]: newRules } } else { newSchema = { ...schema, [propsKey]: { ...schema[propsKey], [property]: value } } } onChange(newSchema) } const handleInputTypeChange = (value, property) => { let newSchema let defaultValue = getDefaultValue(value) if (propsKey === ComponentPropsTypes.X_RULES) { const newRules = _.map(schema[propsKey], rule => { if (_.has(rule, property)) { return { ...rule, [property]: defaultValue } } return rule }) newSchema = { ...schema, [propsKey]: newRules } } else { newSchema = { ...schema, [propsKey]: { ...schema[propsKey], [property]: defaultValue } } } onChange(newSchema) } const handlePropertyChange = (value, property) => { let newComponentProps if (propsKey === ComponentPropsTypes.X_RULES) { newComponentProps = _.map(schema[propsKey], rule => { if (_.has(rule, property)) { return { ..._.omit(rule, property), [value]: rule[property] } } return rule }) } else { newComponentProps = {} _.map(schema[propsKey], (v, k) => { if (k === property) { newComponentProps[value] = v } else if (k !== value) { newComponentProps[k] = v } }) } onChange({ ...schema, [propsKey]: newComponentProps }) } const handleRuleMessageChange = (value, property) => { const newRules = _.map(schema[propsKey], rule => { if (_.has(rule, property)) { return { ...rule, message: value } } return rule }) onChange({ ...schema, [ComponentPropsTypes.X_RULES]: newRules }) } const handleMinusClick = property => { if (propsKey === ComponentPropsTypes.X_RULES) { const newRules = _.reduce( schema[propsKey], (result, rule) => { if (_.has(rule, property)) { return result } return _.concat(result, rule) }, [] ) onChange({ ...schema, [ComponentPropsTypes.X_RULES]: newRules }) } else { onChange({ ..._.omit(schema, `${propsKey}.${property}`) }) } } const handlePlusClick = () => { if (propsKey === ComponentPropsTypes.X_RULES) { onChange({ ...schema, [propsKey]: _.concat(schema[propsKey] || [], { [BLANK_PROPERTY_VALUE]: BLANK_PROPERTY_VALUE }) }) } else { onChange({ ...schema, [propsKey]: { ...schema[propsKey], [BLANK_PROPERTY_VALUE]: BLANK_PROPERTY_VALUE } }) } } return (
{title}
{_.map(componentProps, (property, index) => { const value = getPropertyValue({ schema, propsKey, property }) const inputType = getInputType(value) return (
value )} value={property} filterOption={(inputValue, option) => (option.props.children as string) .toUpperCase() .includes(inputValue.toUpperCase()) } onChange={value => { handlePropertyChange(value, property) }} /> {inputType === InputTypes.INPUT && ( { handleXComponentPropsValueChange( event.target.value, property ) }} /> )} {inputType === InputTypes.NUMBER_PICKER && ( { handleXComponentPropsValueChange(value, property) }} /> )} {inputType === InputTypes.CHECKBOX && ( { handleXComponentPropsValueChange( event.target.checked, property ) }} /> )} {inputType === InputTypes.TEXT_AREA && ( { let value = event.target.value try { value = JSON.parse(value) } catch (error) {} handleXComponentPropsValueChange(value, property) }} /> )} {propsKey === ComponentPropsTypes.X_RULES && ( { handleRuleMessageChange(event.target.value, property) }} /> )}
); })}
); } const FieldEditor: React.FC = ({ isRoot, fieldKey, schema, components, onFieldKeyChange, onChange }) => { // 如果节点类型不是 object 或者 array,则该节点为叶子节点 const isLeafField = !['object', 'array'].includes(schema.type) const fieldTypeData = getFieldTypeData() const xComponentData = getXComponentData(components) return (
字段
{ onFieldKeyChange(event.target.value) }} /> value)} value={schema[ComponentPropsTypes.X_COMPONENT]} filterOption={(inputValue, option) => (option.props.children as string) .toUpperCase() .includes(inputValue.toUpperCase()) } onChange={value => { onChange({ ...schema, [ComponentPropsTypes.X_COMPONENT]: value, [ComponentPropsTypes.X_COMPONENT_PROPS]: {} }) }} /> { onChange({ ...schema, title: event.target.value }) }} /> { onChange({ ...schema, description: event.target.value }) }} />
{isLeafField && ( )} {isLeafField && ( )} {isLeafField && ( )} ) } export default FieldEditor