diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index edfd3361e..3076b1191 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -802,6 +802,7 @@ export const useAssociationFilterProps = () => { const fieldSchema = useFieldSchema(); const valueKey = collectionField?.targetKey || 'id'; const labelKey = fieldSchema['x-component-props']?.fieldNames?.label || valueKey; + const field = useField() const collectionFieldName = collectionField.name; const { data, params, run } = useRequest( { @@ -811,18 +812,19 @@ export const useAssociationFilterProps = () => { fields: [labelKey, valueKey], pageSize: 200, page: 1, + ...field.componentProps?.params }, }, { - refreshDeps: [labelKey, valueKey], + refreshDeps: [labelKey, valueKey, JSON.stringify(field.componentProps?.params || {})], debounceWait: 300, }, ); + const list = data?.data || []; const onSelected = (value) => { const filters = service.params?.[1]?.filters || {}; - if (value.length) { filters[`af.${collectionFieldName}`] = { [`${collectionFieldName}.${valueKey}.$in`]: value, @@ -830,7 +832,6 @@ export const useAssociationFilterProps = () => { } else { delete filters[`af.${collectionFieldName}`]; } - service.run( { ...service.params?.[0], @@ -969,6 +970,7 @@ export const useAssociationFilterBlockProps = () => { }); }; + return { /** 渲染 Collapse 的列表数据 */ list, diff --git a/packages/core/client/src/locale/en_US.ts b/packages/core/client/src/locale/en_US.ts index ae173a8e7..d136de79d 100644 --- a/packages/core/client/src/locale/en_US.ts +++ b/packages/core/client/src/locale/en_US.ts @@ -115,6 +115,7 @@ export default { 'Collapse all':'Collapse all', 'Expand all':'Expand all', 'Expand/Collapse':'Expand/Collapse', + 'Default collapse':'Default collapse', "Tree table":"Tree table", "Custom field display name": "Custom field display name", "Display fields": "Display collection fields", diff --git a/packages/core/client/src/locale/zh_CN.ts b/packages/core/client/src/locale/zh_CN.ts index 94bde6e7c..c38696c4f 100644 --- a/packages/core/client/src/locale/zh_CN.ts +++ b/packages/core/client/src/locale/zh_CN.ts @@ -63,6 +63,7 @@ export default { 'Collapse all':'全部收起', 'Expand all':'全部展开', 'Expand/Collapse':'展开/折叠', + 'Default collapse':'默认展开', 'Tree collection': '树结构表', "Tree table":"树表格", 'Parent ID': '父记录ID', diff --git a/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx b/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx index 3f05c0888..48849ebef 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx @@ -4,6 +4,8 @@ import { useTranslation } from 'react-i18next'; import { useAPIClient } from '../../../api-client'; import { createDesignable, SchemaComponentContext, useDesignable } from '../..'; import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { useBlockRequestContext } from '../../../block-provider'; +import { mergeFilter } from '../../../block-provider/SharedFilterProvider'; export const ActionBarAssociationFilterAction = (props) => { const { refresh } = useContext(SchemaComponentContext); @@ -11,12 +13,22 @@ export const ActionBarAssociationFilterAction = (props) => { const api = useAPIClient(); const { t } = useTranslation(); const dn = createDesignable({ t, api, refresh, current: fieldSchema }); + const { service, props: blockProps } = useBlockRequestContext(); + dn.loadAPIClientEvents(); const handleInsert = (s: Schema) => { dn.insertBeforeBegin(s); }; + const handleRemove = (schema, remove) => { + remove(schema); + service.run({ + ...service.params?.[0], + filter: mergeFilter([blockProps?.params?.filter]), + }); + }; + const schema = { type: 'void', 'x-action': 'associateFilter', @@ -28,6 +40,7 @@ export const ActionBarAssociationFilterAction = (props) => { const newProps = { ...props, insert: handleInsert, + remove: handleRemove, wrap: (s) => s, }; diff --git a/packages/core/client/src/schema-component/antd/association-filter/Association.Item.Decorator.tsx b/packages/core/client/src/schema-component/antd/association-filter/Association.Item.Decorator.tsx deleted file mode 100644 index 3b52e6822..000000000 --- a/packages/core/client/src/schema-component/antd/association-filter/Association.Item.Decorator.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useFieldSchema } from '@formily/react'; -import React, { createContext } from 'react'; -import { useRequest } from '../../../api-client'; -import { AssociationFilter } from './AssociationFilter'; - -export const useAssociationFieldService = (props) => { - const collectionField = AssociationFilter.useAssociationField(); - - const fieldSchema = useFieldSchema(); - - const valueKey = collectionField?.targetKey || 'id'; - const labelKey = fieldSchema['x-component-props']?.fieldNames?.label || valueKey; - - const service = useRequest( - { - resource: collectionField.target, - action: 'list', - params: { - fields: [labelKey, valueKey], - pageSize: 200, - page: 1, - ...props.params, - }, - }, - { - refreshDeps: [labelKey, valueKey], - debounceWait: 300, - }, - ); - - return service; -}; - -export type AssociationItemContextValue = { - service: ReturnType; -}; - -export const AssociationItemContext = createContext({ service: undefined! }); - -export const AssociationItemDecorator: React.FC = (props) => { - const service = useAssociationFieldService(props); - - return {props.children}; -}; diff --git a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.Designer.tsx b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.Designer.tsx index f923a9aef..fb66225a2 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.Designer.tsx @@ -1,21 +1,33 @@ -import { ISchema, useFieldSchema } from '@formily/react'; +import { ISchema, useField, useFieldSchema } from '@formily/react'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { useCollectionManager } from '../../../collection-manager'; +import { + useCollection, + useCollectionFilterOptions, + useCollectionManager, + useSortFields, +} from '../../../collection-manager'; import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; import { useCompile, useDesignable } from '../../hooks'; -import { AssociationFilter } from './AssociationFilter'; +import _ from 'lodash'; export const AssociationFilterItemDesigner = (props) => { const fieldSchema = useFieldSchema(); + + const field = useField(); const { t } = useTranslation(); - const collectionField = AssociationFilter.useAssociationField(); + const { getCollectionJoinField } = useCollectionManager(); + const { getField } = useCollection(); + + const collectionField = getField(fieldSchema['name']!) || getCollectionJoinField(fieldSchema['x-collection-field']); + const filterEnum = collectionField?.target ? useCollectionFilterOptions(collectionField?.target) : []; + const defaultFilter = fieldSchema?.['x-component-props']?.params?.filter || {}; const { getCollectionFields } = useCollectionManager(); const compile = useCompile(); const { dn } = useDesignable(); - const targetFields = getCollectionFields(collectionField.target) ?? []; + const targetFields = collectionField?.target ? getCollectionFields(collectionField?.target) : []; const options = targetFields .filter( @@ -42,6 +54,20 @@ export const AssociationFilterItemDesigner = (props) => { dn.refresh(); }; + const sortFields = useSortFields(collectionField?.target); + const defaultSort = fieldSchema?.['x-component-props']?.params?.sort || []; + const sort = defaultSort?.map((item: string) => { + return item.startsWith('-') + ? { + field: item.substring(1), + direction: 'desc', + } + : { + field: item, + direction: 'asc', + }; + }); + return ( { dn.refresh(); }} /> + { + field.componentProps.defaultCollapse = v; + fieldSchema['x-component-props']['defaultCollapse'] = v; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-component-props': fieldSchema['x-component-props'], + }, + }); + dn.refresh(); + }} + /> + { + _.set(field.componentProps, 'params', { + ...field.componentProps?.params, + filter, + }); + fieldSchema['x-component-props']['params'] = field.componentProps.params; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-component-props': fieldSchema['x-component-props'], + }, + }); + }} + /> + { + _.set(field.componentProps, 'params', { + ...field.componentProps?.params, + sort: sort.map((item) => { + return item.direction === 'desc' ? `-${item.field}` : item.field; + }), + }); + fieldSchema['x-component-props']['params'] = field.componentProps.params; + dn.emit('patch', { + schema: fieldSchema, + }); + }} + /> { const collectionField = AssociationFilter.useAssociationField(); // 把一些可定制的状态通过 hook 提取出去了,为了兼容之前添加的 Table 区块,这里加了个默认值 - const { useProps = useAssociationFilterProps } = props; const fieldSchema = useFieldSchema(); const Designer = useDesigner(); const compile = useCompile(); - const { list, onSelected, @@ -28,10 +25,12 @@ export const AssociationFilterItem = (props) => { run, valueKey: _valueKey, labelKey: _labelKey, - } = useProps(); + defaultCollapse, + } = useProps(props); const [searchVisible, setSearchVisible] = useState(false); + const defaultActiveKeyCollapse = useMemo(() => (defaultCollapse ? [collectionField.name] : []), []); const valueKey = _valueKey || collectionField?.targetKey || 'id'; const labelKey = _labelKey || fieldSchema['x-component-props']?.fieldNames?.label || valueKey; @@ -131,11 +130,7 @@ export const AssociationFilterItem = (props) => { )} > - null : undefined} - > + null : undefined}> { } - key={collectionField.uiSchemaUid} + key={defaultActiveKeyCollapse[0]} > { - const { type, schema, item, insert } = props; - const { exists, remove } = useCurrentSchema(schema?.[type] || item?.schema?.[type], type, item.find, item.remove); + const { type, schema, item, insert, remove: passInRemove } = props; + const { exists, remove } = useCurrentSchema( + schema?.[type] || item?.schema?.[type], + type, + item.find, + passInRemove ?? item.remove, + ); return ( { ); }; +SchemaSettings.DefaultSortingRules = (props) => { + const { sort, sortFields, onSubmit } = props; + const { t } = useTranslation(); + + return ( + + ); +}; + SchemaSettings.LinkageRules = (props) => { const { collectionName } = props; const fieldSchema = useFieldSchema();