feat: support association-cascader filter form item
This commit is contained in:
parent
5489c9e569
commit
436088d7b9
@ -76,6 +76,7 @@ import {
|
|||||||
SheetBlockToolbar,
|
SheetBlockToolbar,
|
||||||
sheetBlockSettings,
|
sheetBlockSettings,
|
||||||
} from './schema-initializer/blocks/SheetBlockInitializer';
|
} from './schema-initializer/blocks/SheetBlockInitializer';
|
||||||
|
import AssociationCascader from './schema-components/association-cascader/AssociationCascader';
|
||||||
export { usePDFViewerRef } from './schema-initializer';
|
export { usePDFViewerRef } from './schema-initializer';
|
||||||
export * from './components/custom-components/custom-components';
|
export * from './components/custom-components/custom-components';
|
||||||
|
|
||||||
@ -153,6 +154,7 @@ export class PluginCoreClient extends Plugin {
|
|||||||
|
|
||||||
this.app.addComponents({
|
this.app.addComponents({
|
||||||
AdminLayout,
|
AdminLayout,
|
||||||
|
AssociationCascader,
|
||||||
AssociatedField,
|
AssociatedField,
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
CalcResult,
|
CalcResult,
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { Cascader } from 'antd';
|
||||||
|
import { connect, useFieldSchema } from '@formily/react';
|
||||||
|
import { useCollectionManager, useRequest } from '@nocobase/client';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
name: string | number;
|
||||||
|
id: string;
|
||||||
|
children?: Option[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssociationCascader = connect((props) => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const collection = fieldSchema['collectionName'];
|
||||||
|
const associationField = props.associationField;
|
||||||
|
const cm = useCollectionManager();
|
||||||
|
const titleField = cm.getCollection(collection).titleField;
|
||||||
|
const joinTitleField = cm.getCollection(collection + '.' + associationField).titleField;
|
||||||
|
|
||||||
|
const { data } = useRequest<any>({
|
||||||
|
resource: collection,
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
appends: [associationField],
|
||||||
|
fields: [titleField],
|
||||||
|
pageSize: 99999,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = useMemo(() => {
|
||||||
|
const dict = {};
|
||||||
|
data?.data.forEach((item) => {
|
||||||
|
if (item[associationField]) {
|
||||||
|
dict[item[associationField][joinTitleField]] ??= [];
|
||||||
|
dict[item[associationField][joinTitleField]].push(item[titleField]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const options: Option[] = [];
|
||||||
|
_.forEach(dict, (values: any, key) => {
|
||||||
|
options.push({
|
||||||
|
name: key,
|
||||||
|
id: key,
|
||||||
|
children: values.map((value) => ({
|
||||||
|
name: value,
|
||||||
|
id: value,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}, [associationField, joinTitleField, titleField, data?.data]);
|
||||||
|
return <Cascader options={options} {...props} showSearch />;
|
||||||
|
});
|
||||||
|
|
||||||
|
AssociationCascader.displayName = 'AssociationCascader';
|
||||||
|
export default AssociationCascader;
|
@ -22,6 +22,7 @@ import {
|
|||||||
EditComponent,
|
EditComponent,
|
||||||
useFormBlockContext,
|
useFormBlockContext,
|
||||||
useAPIClient,
|
useAPIClient,
|
||||||
|
useCompile,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { ConfigProvider, Radio, Space } from 'antd';
|
import { ConfigProvider, Radio, Space } from 'antd';
|
||||||
import React, { memo, useCallback, useContext, useMemo, Profiler } from 'react';
|
import React, { memo, useCallback, useContext, useMemo, Profiler } from 'react';
|
||||||
@ -36,10 +37,11 @@ import {
|
|||||||
EditTitleField,
|
EditTitleField,
|
||||||
SchemaSettingCollection,
|
SchemaSettingCollection,
|
||||||
SchemaSettingComponent,
|
SchemaSettingComponent,
|
||||||
} from '../../schema-settings';
|
} from '../schema-settings';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove';
|
import { SchemaSettingsRemove } from '../components/FormFilter/SchemaSettingsRemove';
|
||||||
import { useTranslation } from '../../locale';
|
import { tval, useTranslation } from '../locale';
|
||||||
|
import { ContractsController } from 'packages/plugins/@hera/plugin-rental/dist/server/actions';
|
||||||
|
|
||||||
const FieldComponentProps: React.FC = observer(
|
const FieldComponentProps: React.FC = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
@ -133,6 +135,7 @@ export const useFieldComponents = () => {
|
|||||||
{ label: t('Input'), value: 'Input' },
|
{ label: t('Input'), value: 'Input' },
|
||||||
{ label: t('AutoComplete'), value: 'AutoComplete' },
|
{ label: t('AutoComplete'), value: 'AutoComplete' },
|
||||||
{ label: t('Select'), value: 'Select' },
|
{ label: t('Select'), value: 'Select' },
|
||||||
|
{ label: t('AssociationCascader'), value: 'AssociationCascader' },
|
||||||
// { label: t('CustomSelect***'), value: 'CustomSelect' },
|
// { label: t('CustomSelect***'), value: 'CustomSelect' },
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
@ -148,10 +151,11 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { scope, components } = useContext(SchemaOptionsContext);
|
const { scope, components } = useContext(SchemaOptionsContext);
|
||||||
const { theme } = useGlobalTheme();
|
const { theme } = useGlobalTheme();
|
||||||
|
const compile = useCompile();
|
||||||
const { insert } = props;
|
const { insert } = props;
|
||||||
const itemConfig = useSchemaInitializerItem();
|
const itemConfig = useSchemaInitializerItem();
|
||||||
const { getInterface } = useCollectionManager_deprecated();
|
const { getInterface } = useCollectionManager_deprecated();
|
||||||
const { collections } = useCollectionManager_deprecated();
|
const { collections, getCollectionFields } = useCollectionManager_deprecated();
|
||||||
const allCollection = collections.map((value) => {
|
const allCollection = collections.map((value) => {
|
||||||
return {
|
return {
|
||||||
label: value.title,
|
label: value.title,
|
||||||
@ -165,7 +169,18 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
t('Add custom field'),
|
t('Add custom field'),
|
||||||
() => (
|
() => (
|
||||||
<SchemaComponentOptions
|
<SchemaComponentOptions
|
||||||
scope={{ ...scope, useCollectionManager_deprecated }}
|
scope={{
|
||||||
|
...scope,
|
||||||
|
useCollectionManager_deprecated,
|
||||||
|
useAssociationFields(collection?: string | undefined | null) {
|
||||||
|
return (
|
||||||
|
getCollectionFields(collection)?.map((field) => ({
|
||||||
|
value: field.name,
|
||||||
|
label: compile(field.uiSchema?.title),
|
||||||
|
})) ?? []
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}}
|
||||||
components={{ ...components, FieldComponentProps }}
|
components={{ ...components, FieldComponentProps }}
|
||||||
>
|
>
|
||||||
<FormLayout layout={'vertical'}>
|
<FormLayout layout={'vertical'}>
|
||||||
@ -201,6 +216,24 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
description: t('Select a collection field to use metadata of the field'),
|
description: t('Select a collection field to use metadata of the field'),
|
||||||
'x-visible': false,
|
'x-visible': false,
|
||||||
},
|
},
|
||||||
|
associationField: {
|
||||||
|
type: 'string',
|
||||||
|
title: tval('Association field'),
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Select',
|
||||||
|
'x-reactions': [
|
||||||
|
{
|
||||||
|
dependencies: ['collection', 'component'],
|
||||||
|
when: "{{$deps[1] === 'AssociationCascader'}}",
|
||||||
|
fulfill: {
|
||||||
|
schema: {
|
||||||
|
'x-visible': '{{$deps[0] ? true : false}}',
|
||||||
|
enum: '{{ useAssociationFields($deps[0]) }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
title: t('Component properties'),
|
title: t('Component properties'),
|
||||||
@ -225,7 +258,7 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
const name = field.value;
|
const name = field.value;
|
||||||
const collectionComponent = field.query('.collection').take() as Field;
|
const collectionComponent = field.query('.collection').take() as Field;
|
||||||
const propsComponent = field.query('.props').take() as Field;
|
const propsComponent = field.query('.props').take() as Field;
|
||||||
if (name === 'Select' || name === 'AutoComplete') {
|
if (name === 'Select' || name === 'AutoComplete' || name === 'AssociationCascader') {
|
||||||
collectionComponent.setDisplay('visible');
|
collectionComponent.setDisplay('visible');
|
||||||
collectionComponent.setRequired(true);
|
collectionComponent.setRequired(true);
|
||||||
propsComponent.setDisplay('none');
|
propsComponent.setDisplay('none');
|
||||||
@ -244,7 +277,8 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { title, component, collection } = values;
|
const { title, component, collection, associationField } = values;
|
||||||
|
console.log('=-=======', associationField);
|
||||||
const defaultSchema = getInterface(component)?.default?.uiSchema || {};
|
const defaultSchema = getInterface(component)?.default?.uiSchema || {};
|
||||||
let name;
|
let name;
|
||||||
if (component === 'Select' || component === 'AutoComplete') {
|
if (component === 'Select' || component === 'AutoComplete') {
|
||||||
@ -269,6 +303,7 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
},
|
},
|
||||||
|
associationField,
|
||||||
},
|
},
|
||||||
'x-compoent-custom': true,
|
'x-compoent-custom': true,
|
||||||
collectionName: collection,
|
collectionName: collection,
|
@ -1,4 +1,4 @@
|
|||||||
export * from './FilterFormItemCustomInitializer/FilterFormItemCustom';
|
export * from './CustomFilterFormItemInitializer';
|
||||||
export * from './blocks/PDFVIewerBlockInitializer';
|
export * from './blocks/PDFVIewerBlockInitializer';
|
||||||
export * from './actions/OutboundLinkActionInitializer';
|
export * from './actions/OutboundLinkActionInitializer';
|
||||||
export * from './actions/CreateSubmitActionInitializer';
|
export * from './actions/CreateSubmitActionInitializer';
|
||||||
|
Loading…
Reference in New Issue
Block a user