feat: 添加自定义组件可以修改数据来源和组件,修复筛选框清空和重置后的查询问题 (#418)

<!-- Note -->
<!-- This is a template for submitting a new feature.
Use the bug fix template if you're submitting a bug fix pull request by adding `template=bug_fix.md` to your pull request URL. -->

# Description
<!-- Describe the new feature or modification to an existing feature clearly and consciously. -->

# Motivation
<!-- Explain the reason for adding or modifying this feature. -->

# Key changes
<!-- Provide a technically detailed description of the key changes made. -->
- Frontend
- Backend

# Test plan
## Suggestions
<!-- Provide any suggestions or recommendations for improvements in the testing plan. -->

## Underlying risk
<!-- Identify any potential risks or issues that may arise from the new feature or modification. -->

# Showcase
<!-- Including any screenshots of the new feature or modification. -->

Co-authored-by: sealday <sealday@gmail.com>
Reviewed-on: daoyoucloud/tachycode#418
Reviewed-by: sealday <zhanglin@daoyoucloud.com>
Co-authored-by: wjh <wwwjh0710@163.com>
Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
wjh 2024-03-19 11:52:33 +08:00 committed by sealday
parent e5baa89cac
commit f4be99e802
12 changed files with 174 additions and 62 deletions

View File

@ -110,8 +110,6 @@ export const VariableInput = (props: Props) => {
operator, operator,
uiSchema, uiSchema,
targetFieldSchema, targetFieldSchema,
currentFormCollectionName,
currentIterationCollectionName,
}); });
const contextVariable = useContextAssociationFields({ schema, maxDepth: 2, contextCollectionName, collectionField }); const contextVariable = useContextAssociationFields({ schema, maxDepth: 2, contextCollectionName, collectionField });
const { compatOldVariables } = useCompatOldVariables({ const { compatOldVariables } = useCompatOldVariables({

View File

@ -0,0 +1,13 @@
export * from './custom-components/CustomAssociatedField';
export * from './custom-components/CustomComponentDispatcher';
export * from './custom-components/CustomField';
export * from './fields/AssociatedField';
export * from './fields/CalcResult';
export * from './fields/Expression';
export * from './system/MobileLink';
export * from './system/Notifications';
export * from './system/OnlineUserProvider';
export * from './PDFViewer';
export * from './SignatureInput';
export * from './SignaturePad';
export * from './GroupBlockConfigure/GroupBlockConfigure';

View File

@ -137,7 +137,6 @@ export const useFilterBlockActionProps = () => {
...Object.values(storedFilter).map((filter) => removeNullCondition(filter, fieldSchema)), ...Object.values(storedFilter).map((filter) => removeNullCondition(filter, fieldSchema)),
block.defaultFilter, block.defaultFilter,
]); ]);
return block.doFilter( return block.doFilter(
{ {
...param, ...param,

View File

@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import { autorun } from '@formily/reactive';
import { import {
Menu, Menu,
Plugin, Plugin,
@ -9,27 +8,10 @@ import {
useCollection, useCollection,
} from '@nocobase/client'; } from '@nocobase/client';
import { remove } from 'lodash'; import { remove } from 'lodash';
import { CalendarBlockInitializer } from './schema-initializer/CalendarBlockInitializer';
import { MenuDesigner } from './schema-components/deprecated/ExtendedMenuDesigner';
import { InternalPDFViewer } from './schema-components/PDFViewer';
import {
PDFViewerBlockInitializer,
PDFViewerPrintActionInitializer,
PDFViewerProvider,
pdfViewActionInitializer,
usePDFViewerPrintActionProps,
} from './schema-initializer/PDFVIewerBlockInitializer';
import { useCustomizeUpdateActionProps } from './hooks/useCustomizeUpdateActionProps';
import { OutboundButton, OutboundLinkActionInitializer } from './schema-initializer/OutboundLinkActionInitializer';
import { CreateSubmitActionInitializer } from './schema-initializer/CreateSubmitActionInitializer';
import { FilterAssociatedFields } from './schema-initializer/FilterAssociatedFields';
import { useFieldSchema } from '@formily/react'; import { useFieldSchema } from '@formily/react';
import { isValid } from '@formily/shared'; import { isValid } from '@formily/shared';
import { useCreateActionProps } from './hooks/useCreateActionProps'; import { autorun } from '@formily/reactive';
import { useOutboundActionProps } from './hooks/useOutboundActionProps'; import { Locale, tval } from './locale';
import { AssociatedField } from './components/fields/AssociatedField';
import { DatePicker } from './schema-components/date-picker';
import { SettingBlockInitializer } from './schema-initializer/SettingBlockInitializer';
import { import {
SessionSubmit, SessionSubmit,
SessionUpdate, SessionUpdate,
@ -42,45 +24,64 @@ import {
useSetFilterScopeVisible, useSetFilterScopeVisible,
AfterSuccess, AfterSuccess,
} from './schema-settings'; } from './schema-settings';
import { SignatureInput } from './components/SignatureInput'; import { useCreateActionProps } from './hooks/useCreateActionProps';
import { RemoteSelect } from './schema-components/remote-select'; import { useCustomizeUpdateActionProps } from './hooks/useCustomizeUpdateActionProps';
import { Select } from './schema-components/select/Select'; import { useFilterBlockActionProps } from './hooks/useFilterBlockActionProps';
import { Locale, tval } from './locale';
import {
GroupBlockInitializer,
GroupBlockProvider,
GroupBlockToolbar,
groupBlockSettings,
} from './schema-initializer/GroupBlockInitializer';
import { useFilterFormCustomProps } from './hooks/useFilterFormCustomProps'; import { useFilterFormCustomProps } from './hooks/useFilterFormCustomProps';
import { useGetCustomAssociatedComponents } from './hooks/useGetCustomAssociatedComponents';
import { useGetCustomComponents } from './hooks/useGetCustomComponents';
import { useOutboundActionProps } from './hooks/useOutboundActionProps';
import { AdminLayout, DetailsPage, HomePage, OutboundPage, PageLayout } from './pages';
import { Configuration, HomePageConfiguration, LinkManager } from './settings-manager-components';
import { import {
FilterFormItem, AssociatedFieldInterface,
FilterItemCustomDesigner, CalcFieldInterface,
FilterFormItemCustom, CustomFieldInterface,
} from './schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom'; CustomAssociatedFieldInterface,
import { GroupBlock } from './schema-components/GroupBlock'; SignaturePadFieldInterface,
} from './interfaces';
import { import {
AssociatedField,
CalcResult,
CustomAssociatedField,
CustomField,
CustomComponentDispatcher, CustomComponentDispatcher,
CustomComponentStub, CustomComponentStub,
customComponentDispatcherSettings, customComponentDispatcherSettings,
} from './components/custom-components/CustomComponentDispatcher'; Expression,
import { useFilterBlockActionProps } from './hooks/useFilterBlockActionProps'; GroupBlockConfigure,
import { GroupBlockConfigure } from './components/GroupBlockConfigure/GroupBlockConfigure'; SignatureInput,
import { AssociatedFieldInterface } from './interfaces/associated'; } from './components';
import { CalcFieldInterface } from './interfaces/calc'; import {
import { CustomFieldInterface } from './interfaces/custom'; AutoComplete,
import { CustomAssociatedFieldInterface } from './interfaces/customAssociated'; DatePicker,
import { SignaturePadFieldInterface } from './interfaces/signatureSchema'; GroupBlock,
import { CalcResult } from './components/fields/CalcResult'; InternalPDFViewer,
import { CustomAssociatedField } from './components/custom-components/CustomAssociatedField'; MenuDesigner,
import Expression from './components/fields/Expression'; RemoteSelect,
import { CustomField } from './components/custom-components/CustomField'; Select,
import { useGetCustomAssociatedComponents } from './hooks/useGetCustomAssociatedComponents'; } from './schema-components';
import { useGetCustomComponents } from './hooks/useGetCustomComponents'; import {
import { AutoComplete } from './schema-components/AutoComplete/AutoComplete'; CalendarBlockInitializer,
import { AdminLayout, DetailsPage, HomePage, OutboundPage, PageLayout } from './pages'; CreateSubmitActionInitializer,
import { Configuration, HomePageConfiguration, LinkManager } from './settings-manager-components'; FilterAssociatedFields,
export { usePDFViewerRef } from './schema-initializer/PDFVIewerBlockInitializer'; FilterFormItem,
FilterFormItemCustom,
FilterItemCustomDesigner,
GroupBlockInitializer,
GroupBlockProvider,
GroupBlockToolbar,
OutboundButton,
OutboundLinkActionInitializer,
PDFViewerBlockInitializer,
PDFViewerPrintActionInitializer,
PDFViewerProvider,
SettingBlockInitializer,
groupBlockSettings,
pdfViewActionInitializer,
usePDFViewerPrintActionProps,
} from './schema-initializer';
export { usePDFViewerRef } from './schema-initializer';
export * from './components/custom-components/custom-components'; export * from './components/custom-components/custom-components';
export class PluginCoreClient extends Plugin { export class PluginCoreClient extends Plugin {

View File

@ -0,0 +1,5 @@
export * from './associated';
export * from './calc';
export * from './custom';
export * from './customAssociated';
export * from './signatureSchema';

View File

@ -28,7 +28,7 @@ export const AutoComplete = (props) => {
}, },
}); });
changLable(defultOptions?.data?.data); changLable(defultOptions?.data?.data);
}, [fieldFilter?.filter]); }, [fieldFilter?.filter, fieldSchema['collectionName']]);
useEffect(() => { useEffect(() => {
changLable(defultValue); changLable(defultValue);
@ -57,14 +57,15 @@ export const AutoComplete = (props) => {
} }
const valueLabel = options.filter((item) => item.value === data)[0]; const valueLabel = options.filter((item) => item.value === data)[0];
if (valueLabel) { if (valueLabel) {
setValue(valueLabel.label);
form.values.custom[fieldSchema['collectionName']] = valueLabel; form.values.custom[fieldSchema['collectionName']] = valueLabel;
setValue(valueLabel.label);
} else { } else {
setValue(data);
form.values.custom[fieldSchema['collectionName']] = {}; form.values.custom[fieldSchema['collectionName']] = {};
form.values.custom[fieldSchema['collectionName']][fieldNames.label] = data; form.values.custom[fieldSchema['collectionName']][fieldNames.label] = data;
setValue(data);
} }
} else { } else {
form.values.custom[fieldSchema['collectionName']] = {};
setValue(data); setValue(data);
setOptions(defultValue); setOptions(defultValue);
} }

View File

@ -0,0 +1,41 @@
import { useField, useFieldSchema, useForm } from '@formily/react';
import {
SchemaSettingsSelectItem,
useCollection,
useCollectionField,
useCollectionManager,
useDesignable,
} from '@nocobase/client';
import React from 'react';
export const SchemaSettingCollection = () => {
const fieldSchema = useFieldSchema();
const field = useField();
const collections = useCollectionManager();
const options = collections?.dataSource['options']?.collections.map((value) => {
return {
label: value.name,
value: value.name,
};
});
const { dn } = useDesignable();
return (
<SchemaSettingsSelectItem
key="component-field"
title="Edit Collection"
options={options}
value={fieldSchema['collectionName']}
onChange={(name) => {
fieldSchema['collectionName'] = name;
fieldSchema['name'] = 'custom.' + name;
const schema = {
['x-uid']: fieldSchema['x-uid'],
collectionName: name,
name: 'custom.' + name,
};
void dn.emit('patch', { schema });
dn.refresh();
}}
/>
);
};

View File

@ -0,0 +1,30 @@
import { useField, useFieldSchema } from '@formily/react';
import { SchemaSettingsSelectItem, useDesignable } from '@nocobase/client';
import { useFieldComponents } from '../schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom';
import React from 'react';
export const SchemaSettingComponent = () => {
const fieldSchema = useFieldSchema();
const field = useField();
const { options } = useFieldComponents();
const { dn } = useDesignable();
return (
<SchemaSettingsSelectItem
key="component-field"
title="Field Component"
options={options}
value={fieldSchema['x-component']}
onChange={(mode) => {
const schema = {
['x-uid']: fieldSchema['x-uid'],
['x-component']: mode,
};
field.component = mode;
void dn.emit('patch', {
schema,
});
dn.refresh();
}}
/>
);
};

View File

@ -0,0 +1,7 @@
export * from './AutoComplete/AutoComplete';
export * from './GroupBlock';
export * from './PDFViewer';
export * from './date-picker';
export * from './deprecated/ExtendedMenuDesigner';
export * from './remote-select';
export * from './select/Select';

View File

@ -26,6 +26,7 @@ const ObjectSelect = (props: Props) => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const collectionName = fieldSchema['collectionName']; const collectionName = fieldSchema['collectionName'];
const filterField = fieldSchema['x-component-props']['params']; const filterField = fieldSchema['x-component-props']['params'];
const fieldName = fieldSchema['x-component-props'].fieldNames;
const api = useAPIClient(); const api = useAPIClient();
useAsyncEffect(async () => { useAsyncEffect(async () => {
if (collectionName) { if (collectionName) {
@ -36,9 +37,14 @@ const ObjectSelect = (props: Props) => {
filter: filterField ? { ...filterField.filter } : {}, filter: filterField ? { ...filterField.filter } : {},
}, },
}); });
setDefOptions(defValue?.data?.data); const changOptions = defValue?.data?.data.map((value) => {
value['label'] = value[fieldName.label];
value['value'] = value[fieldNames.label];
return value;
});
setDefOptions(changOptions);
} }
}, [filterField?.filter]); }, [filterField?.filter, collectionName]);
const toValue = (v: any) => { const toValue = (v: any) => {
if (isEmptyObject(v)) { if (isEmptyObject(v)) {
return; return;

View File

@ -34,6 +34,8 @@ import { EditFormulaTitleField, EditTitle, EditTitleField } from '../../schema-s
import _ from 'lodash'; import _ from 'lodash';
import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove'; import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove';
import { useTranslation } from '../../locale'; import { useTranslation } from '../../locale';
import { SchemaSettingComponent } from '../../schema-components/SchemaSettingsFieldComponent';
import { SchemaSettingCollection } from '../../schema-components/SchemaSettingsFieldComponent copy';
export const useFieldComponents = () => { export const useFieldComponents = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -182,7 +184,8 @@ export const FilterItemCustomDesigner: React.FC = () => {
}); });
}} }}
/> />
<EditComponent /> <SchemaSettingCollection />
<SchemaSettingComponent />
<EditTitleField /> <EditTitleField />
<EditFormulaTitleField /> <EditFormulaTitleField />
<SchemaSettingsDivider /> <SchemaSettingsDivider />

View File

@ -0,0 +1,8 @@
export * from './FilterFormItemCustomInitializer/FilterFormItemCustom';
export * from './CalendarBlockInitializer';
export * from './PDFVIewerBlockInitializer';
export * from './OutboundLinkActionInitializer';
export * from './CreateSubmitActionInitializer';
export * from './FilterAssociatedFields';
export * from './SettingBlockInitializer';
export * from './GroupBlockInitializer';