feat: 添加组件默认值 (#461)

Reviewed-on: daoyoucloud/tachycode#461
Co-authored-by: wjh <wwwjh0710@163.com>
Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
wjh 2024-03-21 20:48:45 +08:00 committed by sealday
parent 8041ef5b6f
commit 2620acbba7
6 changed files with 177 additions and 26 deletions

View File

@ -35,20 +35,24 @@ export const removeNullCondition = (filter, fieldSchema?) => {
const collection = match?.split('.')[0];
if (Object.keys(items).filter((item) => item.includes(collection)).length) {
for (const key in items) {
if (key.includes(collection)) {
if (key.includes(match)) {
if (Object.keys(items[key]).length) {
filterSchemaItem[filterKey] = items[key];
filterItem[match] = items[key];
}
}
if (key.includes(collection)) delete items[key];
else {
const value = items[key];
if (value != null && !isEmpty(value)) {
values[key] = value;
if (key.includes('custom')) {
if (key.includes(collection)) {
if (key.includes(match)) {
if (Object.keys(items[key]).length) {
filterSchemaItem[filterKey] = items[key];
filterItem[match] = items[key];
}
}
if (key.includes(collection)) delete items[key];
else {
const value = items[key];
if (value != null && !isEmpty(value)) {
values[key] = value;
}
}
}
} else {
values[key] = items[key];
}
}
} else if (Object.keys(items).filter((item) => !item.includes('custom')).length) {
@ -121,6 +125,16 @@ export const useFilterBlockActionProps = () => {
if (!target) return;
const param = block.service.params?.[0] || {};
for (const key in form.values) {
if (
(typeof form.values[key] === 'object' &&
!form.values[key]?.length &&
!Object.keys(form.values[key]).length) ||
!form.values[key]
) {
delete form.values[key];
}
}
// 保留原有的 filter
const storedFilter = block.service.params?.[1]?.filters || {};
storedFilter[uid] = removeNullCondition(

View File

@ -23,6 +23,8 @@ import {
SetFilterScope,
useSetFilterScopeVisible,
AfterSuccess,
FilterVariableInput,
EditDefaultValue,
} from './schema-settings';
import { useCreateActionProps } from './schema-initializer/actions/hooks/useCreateActionProps';
import { useCustomizeUpdateActionProps } from './hooks/useCustomizeUpdateActionProps';
@ -117,6 +119,13 @@ export class PluginCoreClient extends Plugin {
Component: EditFormulaTitleField,
useVisible: useFormulaTitleVisible,
});
this.schemaSettingsManager.addItem('FilterFormItemSettings', 'editDefaultValue', {
Component: EditDefaultValue,
});
this.schemaSettingsManager.addItem('fieldSettings:component:Select', 'editDefaultValue', {
Component: EditDefaultValue,
});
this.schemaSettingsManager.addItem('FormItemSettings', 'hera-divider', {
type: 'divider',
useVisible() {
@ -195,6 +204,7 @@ export class PluginCoreClient extends Plugin {
AdminLayout,
AfterSuccess,
AssociatedField,
RemoteSelect,
AutoComplete,
CalcResult,
CreateSubmitActionInitializer,
@ -216,6 +226,7 @@ export class PluginCoreClient extends Plugin {
GroupBlockInitializer,
GroupBlockProvider,
GroupBlockToolbar,
FilterVariableInput,
Menu: {
...Menu,
// @ts-ignore
@ -226,7 +237,6 @@ export class PluginCoreClient extends Plugin {
PDFViewerProvider,
PDFViwer: InternalPDFViewer,
PageLayout,
RemoteSelect,
Select,
SettingBlock: SettingBlockInitializer,
SignatureInput,

View File

@ -6,6 +6,7 @@ import { useAsyncEffect } from 'ahooks';
export const AutoComplete = (props) => {
const fieldSchema = useFieldSchema();
const comdef = fieldSchema['default'];
const { fieldNames } = fieldSchema['x-component-props'];
const fieldFilter = fieldSchema['x-component-props']['params'];
const [defultValue, setDefultValue] = useState([]);
@ -33,6 +34,10 @@ export const AutoComplete = (props) => {
useEffect(() => {
changLable(defultValue);
}, [fieldNames.label]);
useEffect(() => {
setValue(comdef);
}, [comdef]);
const changLable = (defultOptions) => {
if (defultOptions) {
const item = defultOptions.map((item) => {
@ -69,5 +74,14 @@ export const AutoComplete = (props) => {
setOptions(defultValue);
}
};
return <AntdAutoComplete value={value} options={options} onSearch={onSearch} onChange={onSearch} allowClear />;
return (
<AntdAutoComplete
value={value}
defaultValue={comdef}
options={options}
onSearch={onSearch}
onChange={onSearch}
allowClear
/>
);
};

View File

@ -24,6 +24,7 @@ const ObjectSelect = (props: Props) => {
const { value, options, onChange, fieldNames, mode, loading, rawOptions, defaultValue, ...others } = props;
const [defoptions, setDefOptions] = useState();
const fieldSchema = useFieldSchema();
const comDefult = fieldSchema.default;
const collectionName = fieldSchema['collectionName'];
const filterField = fieldSchema['x-component-props']['params'];
const fieldName = fieldSchema['x-component-props'].fieldNames;
@ -45,6 +46,9 @@ const ObjectSelect = (props: Props) => {
setDefOptions(changOptions);
}
}, [filterField?.filter, collectionName]);
useEffect(() => {
onChange?.(comDefult);
}, [fieldSchema.default]);
const toValue = (v: any) => {
if (isEmptyObject(v)) {
return;
@ -55,10 +59,14 @@ const ObjectSelect = (props: Props) => {
return isPlainObject(val) ? val[fieldNames.value] : val;
});
const currentOptions = getCurrentOptions(values, options, fieldNames)?.map((val) => {
return {
label: val[fieldNames.label],
value: val[fieldNames.value],
};
if (collectionName) {
return val[fieldName.label];
} else {
return {
label: val[fieldNames.label],
value: val[fieldNames.value],
};
}
});
if (['tags', 'multiple'].includes(mode) || props.multiple) {
return currentOptions;
@ -75,7 +83,7 @@ const ObjectSelect = (props: Props) => {
role="button"
data-testid={`select-object-${mode || 'single'}`}
value={toValue(value)}
defaultValue={toValue(defaultValue)}
defaultValue={toValue(defaultValue) || comDefult}
allowClear={{
clearIcon: <CloseCircleFilled role="button" aria-label="icon-close-select" />,
}}
@ -101,8 +109,8 @@ const ObjectSelect = (props: Props) => {
rawOptions || options,
fieldNames,
);
if (fieldSchema.name.toString().includes('custom')) {
onChange?.(changed ? changed['label'] : changed);
if (collectionName) {
onChange?.(changed['label']);
} else {
if (['tags', 'multiple'].includes(mode as string) || props.multiple) {
onChange?.(current);

View File

@ -13,7 +13,6 @@ import {
GeneralSchemaDesigner,
SchemaSettingsDivider,
EditDescription,
EditDefaultValue,
cx,
css,
ACLCollectionFieldProvider,
@ -31,6 +30,7 @@ import { ArrayItems, FormLayout } from '@formily/antd-v5';
import { uid } from '@formily/shared';
import { Field, onFieldValueChange } from '@formily/core';
import {
EditDefaultValue,
EditFormulaTitleField,
EditTitle,
EditTitleField,
@ -298,7 +298,6 @@ export const FilterItemCustomDesigner: React.FC = () => {
<GeneralSchemaDesigner>
<EditTitle />
<EditDescription />
<EditDefaultValue />
{component !== 'Input' ? (
<SchemaSettingsDataScope
collectionName={name}
@ -323,6 +322,7 @@ export const FilterItemCustomDesigner: React.FC = () => {
{component === 'Select' || component === 'AutoComplete' ? <SchemaSettingComponent /> : null}
{component === 'Select' || component === 'AutoComplete' ? <EditTitleField /> : null}
{component === 'Select' || component === 'AutoComplete' ? <EditFormulaTitleField /> : null}
<EditDefaultValue />
<SchemaSettingsDivider />
<SchemaSettingsRemove
key="remove"

View File

@ -1,6 +1,8 @@
import { Field } from '@formily/core';
import { ISchema, useField, useFieldSchema } from '@formily/react';
import { ISchema, useField, useFieldSchema, useForm } from '@formily/react';
import {
getShouldChange,
SchemaComponent,
SchemaSettingsModalItem,
SchemaSettingsSelectItem,
SchemaSettingsSwitchItem,
@ -8,6 +10,8 @@ import {
useCollectionManager,
useCollectionManager_deprecated,
useCompile,
useCurrentUserVariable,
useDatetimeVariable,
useDesignable,
useFormBlockContext,
useFormBlockType,
@ -16,12 +20,16 @@ import {
useRecord,
useSchemaTemplateManager,
useVariables,
VariableInput,
VariableScopeProvider,
} from '@nocobase/client';
import _ from 'lodash';
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useContext, useEffect, useMemo } from 'react';
import { useTranslation } from '../locale';
import { FormFilterScope } from '../components/FormFilter/FormFilterScope';
import { useFieldComponents } from '../schema-initializer';
import { useMemoizedFn } from 'ahooks';
import { fieldsCollection } from '@nocobase/plugin-collection-manager';
export const useFormulaTitleOptions = () => {
const compile = useCompile();
@ -143,6 +151,98 @@ export const EditFormulaTitleField = () => {
);
};
export const EditDefaultValue = () => {
const { t } = useTranslation();
const { dn } = useDesignable();
const field = useField<Field>();
const fieldSchema = useFieldSchema();
const collectionName = fieldSchema['collectionName'];
const title = fieldSchema.title;
return (
<SchemaSettingsModalItem
key="set field default value"
title={t('Set default value')}
schema={{
type: 'void',
title: t('Set default value'),
properties: {
default: {
title,
'x-decorator': 'FormItem',
'x-component': 'FilterVariableInput',
'x-component-props': {
fieldSchema,
},
},
},
}}
onSubmit={(defaultValue) => {
let value;
if (defaultValue.default && !defaultValue.custom) {
value = defaultValue.default.value?.value ? defaultValue.default.value.value : defaultValue.default.value;
} else if (defaultValue.custom) {
value = defaultValue.custom[collectionName];
}
field.setInitialValue(value);
fieldSchema['default'] = value;
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
default: value,
},
});
dn.refresh();
}}
/>
);
};
export const FilterVariableInput: React.FC<any> = (props) => {
const { value, onChange, fieldSchema } = props;
const { currentUserSettings } = useCurrentUserVariable({
collectionField: { uiSchema: fieldSchema },
uiSchema: fieldSchema,
});
const { datetimeSettings } = useDatetimeVariable({
operator: fieldSchema['x-component-props']?.['filter-operator'],
schema: fieldSchema,
noDisabled: true,
});
const options = useMemo(
() => [currentUserSettings, datetimeSettings].filter(Boolean),
[datetimeSettings, currentUserSettings],
);
const schema = {
...fieldSchema,
'x-component': fieldSchema['x-component'] || 'Input',
'x-decorator': '',
title: '',
name: 'value',
};
const componentProps = fieldSchema['x-component-props'] || {};
const handleChange = useMemoizedFn(onChange);
useEffect(() => {
if (fieldSchema.default) {
handleChange({ value: fieldSchema.default });
}
}, [fieldSchema.default, handleChange]);
return (
<VariableScopeProvider scope={options}>
<VariableInput
{...componentProps}
renderSchemaComponent={() => <SchemaComponent schema={schema} />}
fieldNames={{}}
value={value?.value}
scope={options}
onChange={(v: any) => {
onChange({ value: v });
}}
shouldChange={getShouldChange({} as any)}
/>
</VariableScopeProvider>
);
};
export const usePaginationVisible = () => {
const fieldSchema = useFieldSchema();
return fieldSchema['x-component-props']?.mode === 'SubTable';
@ -510,11 +610,14 @@ export const SchemaSettingComponent = () => {
options={options}
value={fieldSchema['x-component']}
onChange={(mode) => {
field.component = mode;
fieldSchema['x-component'] = mode;
fieldSchema.default = '';
const schema = {
['x-uid']: fieldSchema['x-uid'],
['x-component']: mode,
default: '',
};
field.component = mode;
void dn.emit('patch', {
schema,
});
@ -544,10 +647,12 @@ export const SchemaSettingCollection = () => {
onChange={(name) => {
fieldSchema['collectionName'] = name;
fieldSchema['name'] = 'custom.' + name;
fieldSchema.default = '';
const schema = {
['x-uid']: fieldSchema['x-uid'],
collectionName: name,
name: 'custom.' + name,
default: '',
};
void dn.emit('patch', { schema });
dn.refresh();