import React from "react"; import { observer, useForm, useField } from "@formily/react"; import { Input, Button, Dropdown, Menu, Form } from "antd"; import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons'; import { useTranslation } from "react-i18next"; import { css } from "@emotion/css"; import { CollectionField, CollectionProvider, SchemaComponent, useCollectionManager, useCompile } from "@nocobase/client"; import { Operand, parseStringValue, VariableTypes, VariableTypesContext } from "../calculators"; import { lang, NAMESPACE } from "../locale"; function AssociationInput(props) { const { getCollectionFields } = useCollectionManager(); const { path } = useField(); const fieldName = path.segments[path.segments.length - 1] as string; const { values: data } = useForm(); const fields = getCollectionFields(data?.config?.collection); const { type } = fields.find(item => item.name === fieldName); const value = Array.isArray(props.value) ? props.value.join(',') : props.value; function onChange(ev) { const trimed = ev.target.value.trim(); props.onChange(['belongsTo', 'hasOne'].includes(type) ? trimed : trimed.split(/[,\s]+/)); } return ( ); } // NOTE: observer for watching useProps export default observer(({ value, onChange }: any) => { const { t } = useTranslation(); const compile = useCompile(); const { getCollection, getCollectionFields } = useCollectionManager(); const { values: data } = useForm(); const collectionName = data?.config?.collection; const fields = getCollectionFields(collectionName) .filter(field => ( !field.hidden && (field.uiSchema ? !field.uiSchema['x-read-pretty'] : false) // && (!['linkTo', 'hasMany', 'hasOne', 'belongsToMany'].includes(field.type)) )); const unassignedFields = fields.filter(field => !(field.name in value)); return (
.ant-formily-item{ flex-direction: column; > .ant-formily-item-label{ line-height: 32px; } } `}> {fields.length ? ( {fields .filter(field => field.name in value) .map(field => { const VTypes = { ...(['linkTo', 'hasMany', 'belongsToMany'].includes(field.type) ? {} : VariableTypes), constant: { title: `{{t("Constant", { ns: "${NAMESPACE}" })}}`, value: 'constant', options: undefined } }; const operand = typeof value[field.name] === 'string' ? parseStringValue(value[field.name], VTypes) : { type: 'constant', value: value[field.name] }; // constant for associations to use Input, others to use CollectionField // dynamic values only support belongsTo/hasOne association, other association type should disable // TODO: try to use to replace this map return ( { if (next.type !== operand.type && next.type === 'constant') { onChange({ ...value, [field.name]: null }); } else { const { stringify } = VTypes[next.type]; onChange({ ...value, [field.name]: stringify(next) }); } }} > {operand.type === 'constant' ? ( ) // ? : null } ) : null } ) :

{lang('Please select collection first')}

}
); });