fix: 将自定义筛选字段移到core/client (#1438)
Co-authored-by: sealday <zhanglin@daoyoucloud.com> Reviewed-on: daoyoucloud/tachybase#1438 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:
parent
1742fa19fb
commit
bffb42601a
@ -22,7 +22,7 @@ import { useCollection_deprecated, useCollectionManager_deprecated } from '../..
|
|||||||
import { useFilterBlock } from '../../filter-provider/FilterProvider';
|
import { useFilterBlock } from '../../filter-provider/FilterProvider';
|
||||||
import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
|
import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
|
||||||
import { useRecord } from '../../record-provider';
|
import { useRecord } from '../../record-provider';
|
||||||
import { removeNullCondition, useActionContext, useCompile } from '../../schema-component';
|
import { getCustomCondition, removeNullCondition, useActionContext, useCompile } from '../../schema-component';
|
||||||
import { isSubMode } from '../../schema-component/antd/association-field/util';
|
import { isSubMode } from '../../schema-component/antd/association-field/util';
|
||||||
import { useCurrentUserContext } from '../../user';
|
import { useCurrentUserContext } from '../../user';
|
||||||
import { useLocalVariables, useVariables } from '../../variables';
|
import { useLocalVariables, useVariables } from '../../variables';
|
||||||
@ -393,7 +393,6 @@ export const useFilterBlockActionProps = () => {
|
|||||||
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
||||||
|
|
||||||
actionField.data = actionField.data || {};
|
actionField.data = actionField.data || {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async onClick() {
|
async onClick() {
|
||||||
const { targets = [], uid } = findFilterTargets(fieldSchema);
|
const { targets = [], uid } = findFilterTargets(fieldSchema);
|
||||||
@ -407,16 +406,44 @@ export const useFilterBlockActionProps = () => {
|
|||||||
if (!target) return;
|
if (!target) return;
|
||||||
|
|
||||||
const param = block.service.params?.[0] || {};
|
const param = block.service.params?.[0] || {};
|
||||||
|
for (const key in form.values) {
|
||||||
|
if (
|
||||||
|
(typeof form.values[key] === 'object' &&
|
||||||
|
(JSON.stringify(form.values[key]) === '{}' || JSON.stringify(form.values[key]) === '[]')) ||
|
||||||
|
!form.values[key]
|
||||||
|
) {
|
||||||
|
delete form.values[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
// 保留原有的 filter
|
// 保留原有的 filter
|
||||||
const storedFilter = block.service.params?.[1]?.filters || {};
|
const storedFilter = block.service.params?.[1]?.filters || {};
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
formValues: {},
|
||||||
|
customValues: {},
|
||||||
|
customFilter: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Object.keys(form.values)?.includes('custom')) {
|
||||||
|
const values = { ...form.values };
|
||||||
|
delete values['custom'];
|
||||||
|
filter.formValues = { ...values };
|
||||||
|
for (const key in form.values['custom']) {
|
||||||
|
if (form.values['custom'][key]) {
|
||||||
|
filter.customValues[key] = form.values['custom'][key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filter.customFilter = getCustomCondition(filter.customValues, fieldSchema);
|
||||||
|
}
|
||||||
|
|
||||||
storedFilter[uid] = removeNullCondition(
|
storedFilter[uid] = removeNullCondition(
|
||||||
transformToFilter(form.values, fieldSchema, getCollectionJoinField, name),
|
transformToFilter(filter.formValues, fieldSchema, getCollectionJoinField, name),
|
||||||
);
|
);
|
||||||
|
|
||||||
const mergedFilter = mergeFilter([
|
const mergedFilter = mergeFilter([
|
||||||
...Object.values(storedFilter).map((filter) => removeNullCondition(filter)),
|
...Object.values(storedFilter).map((filter) => removeNullCondition(filter)),
|
||||||
block.defaultFilter,
|
block.defaultFilter,
|
||||||
|
filter.customFilter,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (block.dataLoadingMode === 'manual' && _.isEmpty(mergedFilter)) {
|
if (block.dataLoadingMode === 'manual' && _.isEmpty(mergedFilter)) {
|
||||||
|
@ -51,11 +51,3 @@ export * from 'react-i18next';
|
|||||||
export { useHotkeys } from 'react-hotkeys-hook';
|
export { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
export * from './modules/blocks/useParentRecordCommon';
|
export * from './modules/blocks/useParentRecordCommon';
|
||||||
|
|
||||||
export * as __UNSAFE__ from './unsafe';
|
|
||||||
export type {
|
|
||||||
DynamicComponentProps as __UNSAFE__DynamicComponentProps,
|
|
||||||
VariablesContextType as __UNSAFE__VariablesContextType,
|
|
||||||
VariableOption as __UNSAFE__VariableOption,
|
|
||||||
Option as __UNSAFE__VariableInputOption,
|
|
||||||
} from './unsafe';
|
|
||||||
|
@ -939,5 +939,15 @@
|
|||||||
"Show Data":"显示数据",
|
"Show Data":"显示数据",
|
||||||
"Setting Down Title":"设置文件名称",
|
"Setting Down Title":"设置文件名称",
|
||||||
"The current return type is not a document type":"当前返回类型不是文档类型",
|
"The current return type is not a document type":"当前返回类型不是文档类型",
|
||||||
"Test Data":"测试数据"
|
"Test Data":"测试数据",
|
||||||
|
"Custom filter field": "自定义筛选字段",
|
||||||
|
"Custom option label": "自定义选项标签",
|
||||||
|
"Add custom field":"添加自定义字段",
|
||||||
|
"Input":"文本",
|
||||||
|
"AutoComplete":"文本选择",
|
||||||
|
"Field collection":"选择数据",
|
||||||
|
"AssociationCascader":"关系型级联选择",
|
||||||
|
"Edit Collection":"修改数据",
|
||||||
|
"Field Component":"字段组件",
|
||||||
|
"Custom filter":"自定义筛选"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,294 @@
|
|||||||
|
import { Field, ISchema, useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../..//collection-manager';
|
||||||
|
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||||
|
import { useFormBlockContext } from '../../../../block-provider';
|
||||||
|
import { useCompile, useDesignable } from '../../../../schema-component';
|
||||||
|
import {
|
||||||
|
EditFormulaTitleField,
|
||||||
|
FilterCustomVariableInput,
|
||||||
|
SchemaSettingCollection,
|
||||||
|
SchemaSettingComponent,
|
||||||
|
SchemaSettingsCustomRemove,
|
||||||
|
SchemaSettingsDataScope,
|
||||||
|
} from '../../../../schema-settings';
|
||||||
|
|
||||||
|
export const FilterItemCustomSettings = new SchemaSettings({
|
||||||
|
name: 'fieldSettings:FilterFormCustomSettings',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'editFieldTitle',
|
||||||
|
type: 'modal',
|
||||||
|
useComponentProps() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
||||||
|
const { getField } = useCollection_deprecated();
|
||||||
|
const collectionField =
|
||||||
|
getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Edit field title'),
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
title: t('Edit field title'),
|
||||||
|
properties: {
|
||||||
|
title: {
|
||||||
|
title: t('Field title'),
|
||||||
|
default: field?.title,
|
||||||
|
description: `${t('Original field title: ')}${collectionField?.uiSchema?.title}`,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input',
|
||||||
|
'x-component-props': {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as ISchema,
|
||||||
|
onSubmit({ title }) {
|
||||||
|
if (title) {
|
||||||
|
field.title = title;
|
||||||
|
fieldSchema.title = title;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
'x-uid': fieldSchema['x-uid'],
|
||||||
|
title: fieldSchema.title,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dn.refresh();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'editDescription',
|
||||||
|
type: 'modal',
|
||||||
|
useComponentProps() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Edit description'),
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
title: t('Edit description'),
|
||||||
|
properties: {
|
||||||
|
description: {
|
||||||
|
// title: t('Description'),
|
||||||
|
default: field?.description,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input.TextArea',
|
||||||
|
'x-component-props': {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onSubmit({ description }) {
|
||||||
|
field.description = description;
|
||||||
|
fieldSchema.description = description;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
'x-uid': fieldSchema['x-uid'],
|
||||||
|
description: fieldSchema.description,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'setTheDataScope',
|
||||||
|
Component: SchemaSettingsDataScope,
|
||||||
|
useComponentProps() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { form } = useFormBlockContext();
|
||||||
|
const field = useField();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const fieldName = fieldSchema['name'] as string;
|
||||||
|
const name = fieldName.includes('custom') ? fieldSchema['collectionName'] : fieldName;
|
||||||
|
return {
|
||||||
|
collectionName: name,
|
||||||
|
defaultFilter: fieldSchema?.['x-component-props']?.params?.filter || {},
|
||||||
|
form: form,
|
||||||
|
onSubmit: ({ filter }) => {
|
||||||
|
_.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'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
useVisible() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const component = fieldSchema['x-component'];
|
||||||
|
return component !== 'Input';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fieldCollection',
|
||||||
|
Component: SchemaSettingCollection,
|
||||||
|
useVisible() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const component = fieldSchema['x-component'];
|
||||||
|
return component === 'Select' || component === 'AutoComplete';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fieldComponent',
|
||||||
|
Component: SchemaSettingComponent,
|
||||||
|
useVisible() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const component = fieldSchema['x-component'];
|
||||||
|
return component === 'Select' || component === 'AutoComplete';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'titleField',
|
||||||
|
type: 'select',
|
||||||
|
useComponentProps() {
|
||||||
|
const { getCollectionFields, getCollectionJoinField } = useCollectionManager_deprecated();
|
||||||
|
const { getField } = useCollection_deprecated();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const compile = useCompile();
|
||||||
|
const collectionManage = useCollectionManager_deprecated();
|
||||||
|
const isCustomFilterItem = ((fieldSchema?.name as string) ?? '').startsWith('custom.');
|
||||||
|
const collectionManageField = isCustomFilterItem
|
||||||
|
? collectionManage.collections.filter((value) => value.name === fieldSchema['x-decorator-props'])[0]
|
||||||
|
: {};
|
||||||
|
const collectionField =
|
||||||
|
getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
|
let targetFields = [];
|
||||||
|
if (collectionField) {
|
||||||
|
targetFields = collectionField?.target
|
||||||
|
? getCollectionFields(collectionField?.target)
|
||||||
|
: getCollectionFields(collectionField?.targetCollection) ?? [];
|
||||||
|
} else if (collectionManageField) {
|
||||||
|
targetFields = collectionManageField['fields'];
|
||||||
|
}
|
||||||
|
const options = targetFields
|
||||||
|
.filter((field) => !field?.target && field.type !== 'boolean')
|
||||||
|
.map((field) => ({
|
||||||
|
value: field?.name,
|
||||||
|
label: compile(field?.uiSchema?.title) || field?.name,
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
title: t('Title field'),
|
||||||
|
options,
|
||||||
|
value: fieldSchema['x-component-props']?.['fieldNames']?.label || 'id',
|
||||||
|
onChange(label) {
|
||||||
|
const schema = {
|
||||||
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
|
};
|
||||||
|
const fieldNames = {
|
||||||
|
...collectionField?.uiSchema?.['x-component-props']?.['fieldNames'],
|
||||||
|
...field.componentProps.fieldNames,
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
if (isCustomFilterItem) fieldNames['value'] = label;
|
||||||
|
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||||
|
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
||||||
|
schema['x-component-props'] = fieldSchema['x-component-props'];
|
||||||
|
field.componentProps = fieldSchema['x-component-props'];
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema,
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
useVisible() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const component = fieldSchema['x-component'];
|
||||||
|
return component === 'Select' || component === 'AutoComplete';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EditFormulaTitleField',
|
||||||
|
Component: EditFormulaTitleField,
|
||||||
|
useVisible() {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const component = fieldSchema['x-component'];
|
||||||
|
return component === 'Select' || component === 'AutoComplete';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EditCustomDefaultValue',
|
||||||
|
type: 'modal',
|
||||||
|
useComponentProps() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const title = fieldSchema.title;
|
||||||
|
return {
|
||||||
|
title: t('Set default value'),
|
||||||
|
schema: {
|
||||||
|
type: 'void',
|
||||||
|
title: t('Set default value'),
|
||||||
|
properties: {
|
||||||
|
default: {
|
||||||
|
title,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': FilterCustomVariableInput,
|
||||||
|
'x-component-props': {
|
||||||
|
fieldSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as ISchema,
|
||||||
|
onSubmit({ default: { value } }) {
|
||||||
|
field.setValue(value);
|
||||||
|
fieldSchema['default'] = value;
|
||||||
|
fieldSchema['x-component-props']['defaultValue'] = value;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
'x-uid': fieldSchema['x-uid'],
|
||||||
|
['x-component-props']: fieldSchema['x-component-props'],
|
||||||
|
default: fieldSchema.default,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'divider',
|
||||||
|
type: 'divider',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'delete',
|
||||||
|
// Component: SchemaSettingsCustomRemove,
|
||||||
|
// useComponentProps() {
|
||||||
|
// const { t } = useTranslation();
|
||||||
|
// return {
|
||||||
|
// key: 'remove',
|
||||||
|
// confirm: {
|
||||||
|
// title: t('Delete field'),
|
||||||
|
// },
|
||||||
|
// removeParentsIfNoChildren: true,
|
||||||
|
// breakRemoveOn: {
|
||||||
|
// 'x-component': 'Grid',
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// },
|
||||||
|
type: 'remove',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
@ -11,3 +11,4 @@ export * from './formActionInitializers';
|
|||||||
export * from './formItemInitializers';
|
export * from './formItemInitializers';
|
||||||
export * from './updateFormActionInitializers';
|
export * from './updateFormActionInitializers';
|
||||||
export * from './createEditFormBlockUISchema';
|
export * from './createEditFormBlockUISchema';
|
||||||
|
export * from './FilterItemCustomSettings';
|
||||||
|
@ -37,6 +37,12 @@ export const filterFormItemInitializers_deprecated = new CompatibleSchemaInitial
|
|||||||
Component: 'MarkdownFormItemInitializer',
|
Component: 'MarkdownFormItemInitializer',
|
||||||
name: 'addText',
|
name: 'addText',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '{{t("Custom filter field")}}',
|
||||||
|
name: 'custom',
|
||||||
|
type: 'item',
|
||||||
|
Component: 'FilterFormItemCustom',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,6 +76,12 @@ export const filterFormItemInitializers = new CompatibleSchemaInitializer(
|
|||||||
Component: 'MarkdownFormItemInitializer',
|
Component: 'MarkdownFormItemInitializer',
|
||||||
name: 'addText',
|
name: 'addText',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '{{t("Custom filter field")}}',
|
||||||
|
name: 'custom',
|
||||||
|
type: 'item',
|
||||||
|
Component: 'FilterFormItemCustom',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
filterFormItemInitializers_deprecated,
|
filterFormItemInitializers_deprecated,
|
||||||
|
@ -20,7 +20,13 @@ import {
|
|||||||
useTitleFieldOptions,
|
useTitleFieldOptions,
|
||||||
} from '../../../../schema-component/antd/form-item/FormItem.Settings';
|
} from '../../../../schema-component/antd/form-item/FormItem.Settings';
|
||||||
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
|
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
|
||||||
import { getShouldChange, VariableInput } from '../../../../schema-settings';
|
import {
|
||||||
|
EditCustomDefaultValue,
|
||||||
|
EditFormulaTitleField,
|
||||||
|
getShouldChange,
|
||||||
|
useFormulaTitleVisible,
|
||||||
|
VariableInput,
|
||||||
|
} from '../../../../schema-settings';
|
||||||
import { useIsShowMultipleSwitch } from '../../../../schema-settings/hooks/useIsShowMultipleSwitch';
|
import { useIsShowMultipleSwitch } from '../../../../schema-settings/hooks/useIsShowMultipleSwitch';
|
||||||
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
|
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
|
||||||
import { SchemaSettingsSortingRule } from '../../../../schema-settings/SchemaSettingsSortingRule';
|
import { SchemaSettingsSortingRule } from '../../../../schema-settings/SchemaSettingsSortingRule';
|
||||||
@ -381,5 +387,14 @@ export const selectComponentFieldSettings = new SchemaSettings({
|
|||||||
return useIsAssociationField() && readPretty;
|
return useIsAssociationField() && readPretty;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'formulatitleField',
|
||||||
|
Component: EditFormulaTitleField,
|
||||||
|
useVisible: useFormulaTitleVisible,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'editDefaultValue',
|
||||||
|
Component: EditCustomDefaultValue,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -20,16 +20,19 @@ import { isInitializersSame, useApp } from '../../../application';
|
|||||||
import { usePlugin } from '../../../application/hooks';
|
import { usePlugin } from '../../../application/hooks';
|
||||||
import { SchemaSettingOptions, SchemaSettings } from '../../../application/schema-settings';
|
import { SchemaSettingOptions, SchemaSettings } from '../../../application/schema-settings';
|
||||||
import { useSchemaToolbar } from '../../../application/schema-toolbar';
|
import { useSchemaToolbar } from '../../../application/schema-toolbar';
|
||||||
import { useFormBlockContext } from '../../../block-provider';
|
import { useFormBlockContext, useFormBlockType } from '../../../block-provider';
|
||||||
import {
|
import {
|
||||||
joinCollectionName,
|
joinCollectionName,
|
||||||
useCollection_deprecated,
|
useCollection_deprecated,
|
||||||
|
useCollectionFilterOptions,
|
||||||
useCollectionManager_deprecated,
|
useCollectionManager_deprecated,
|
||||||
} from '../../../collection-manager';
|
} from '../../../collection-manager';
|
||||||
import { DataSourceProvider, useDataSourceKey } from '../../../data-source';
|
import { DataSourceProvider, useCollection, useDataSourceKey } from '../../../data-source';
|
||||||
import { FlagProvider } from '../../../flag-provider';
|
import { FlagProvider } from '../../../flag-provider';
|
||||||
import { SaveMode } from '../../../modules/actions/submit/createSubmitActionSettings';
|
import { SaveMode } from '../../../modules/actions/submit/createSubmitActionSettings';
|
||||||
|
import { useRecord } from '../../../record-provider';
|
||||||
import { SchemaSettingOpenModeSchemaItems } from '../../../schema-items';
|
import { SchemaSettingOpenModeSchemaItems } from '../../../schema-items';
|
||||||
|
import { FormFilterScope } from '../../../schema-settings/filter-form/FormFilterScope';
|
||||||
import { GeneralSchemaDesigner } from '../../../schema-settings/GeneralSchemaDesigner';
|
import { GeneralSchemaDesigner } from '../../../schema-settings/GeneralSchemaDesigner';
|
||||||
import { DefaultValueProvider } from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
import { DefaultValueProvider } from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
||||||
import {
|
import {
|
||||||
@ -41,6 +44,8 @@ import {
|
|||||||
SchemaSettingsRemove,
|
SchemaSettingsRemove,
|
||||||
SchemaSettingsSwitchItem,
|
SchemaSettingsSwitchItem,
|
||||||
} from '../../../schema-settings/SchemaSettings';
|
} from '../../../schema-settings/SchemaSettings';
|
||||||
|
import { useSchemaTemplateManager } from '../../../schema-templates';
|
||||||
|
import { useLocalVariables, useVariables } from '../../../variables';
|
||||||
import { useLinkageAction } from './hooks';
|
import { useLinkageAction } from './hooks';
|
||||||
import { requestSettingsSchema } from './utils';
|
import { requestSettingsSchema } from './utils';
|
||||||
|
|
||||||
@ -598,6 +603,93 @@ export function WorkflowConfig() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const findGridSchema = (fieldSchema) => {
|
||||||
|
return fieldSchema.reduceProperties((buf, s) => {
|
||||||
|
if (s['x-component'] === 'FormV2') {
|
||||||
|
const f = s.reduceProperties((buf, s) => {
|
||||||
|
if (s['x-component'] === 'Grid' || s['x-component'] === 'BlockTemplate') {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}, null);
|
||||||
|
if (f) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetFilterScopeVisible = () => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
return (
|
||||||
|
fieldSchema['x-component-props']?.useProps === '{{ useFilterBlockActionProps }}' ||
|
||||||
|
fieldSchema['x-use-component-props'] === 'useFilterBlockActionProps'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SetFilterScope = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { collectionName } = props;
|
||||||
|
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
||||||
|
const { form } = useFormBlockContext();
|
||||||
|
const type = props?.type || ['Action', 'Action.Link'].includes(fieldSchema['x-component']) ? 'button' : 'field';
|
||||||
|
const variables = useVariables();
|
||||||
|
const localVariables = useLocalVariables();
|
||||||
|
const record = useRecord();
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
|
const schema = useMemo<ISchema>(
|
||||||
|
() => ({
|
||||||
|
type: 'object',
|
||||||
|
title: t('Custom filter'),
|
||||||
|
properties: {
|
||||||
|
fieldReaction: {
|
||||||
|
'x-component': FormFilterScope,
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: () => {
|
||||||
|
const options = useCollectionFilterOptions(collectionName);
|
||||||
|
return {
|
||||||
|
options,
|
||||||
|
defaultValues: gridSchema?.['x-filter-rules'] || fieldSchema?.['x-filter-rules'],
|
||||||
|
type,
|
||||||
|
collectionName,
|
||||||
|
form,
|
||||||
|
variables,
|
||||||
|
localVariables,
|
||||||
|
record,
|
||||||
|
formBlockType,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
const { getTemplateById } = useSchemaTemplateManager();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
const onSubmit = useCallback(
|
||||||
|
(v) => {
|
||||||
|
const rules = v.fieldReaction.condition;
|
||||||
|
const templateId = gridSchema['x-component'] === 'BlockTemplate' && gridSchema['x-component-props'].templateId;
|
||||||
|
const uid = (templateId && getTemplateById(templateId).uid) || gridSchema['x-uid'];
|
||||||
|
const schema = {
|
||||||
|
['x-uid']: uid,
|
||||||
|
};
|
||||||
|
|
||||||
|
gridSchema['x-filter-rules'] = rules;
|
||||||
|
schema['x-filter-rules'] = rules;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema,
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
},
|
||||||
|
[dn, getTemplateById, gridSchema],
|
||||||
|
);
|
||||||
|
return <SchemaSettingsModalItem title={t('Custom filter')} width={770} schema={schema} onSubmit={onSubmit} />;
|
||||||
|
};
|
||||||
|
|
||||||
export const actionSettingsItems: SchemaSettingOptions['items'] = [
|
export const actionSettingsItems: SchemaSettingOptions['items'] = [
|
||||||
{
|
{
|
||||||
name: 'Customize',
|
name: 'Customize',
|
||||||
@ -735,6 +827,17 @@ export const actionSettingsItems: SchemaSettingOptions['items'] = [
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Customize.setFilterScope',
|
||||||
|
Component: SetFilterScope,
|
||||||
|
useVisible: useSetFilterScopeVisible,
|
||||||
|
useComponentProps() {
|
||||||
|
const collection = useCollection();
|
||||||
|
return {
|
||||||
|
collectionName: collection.name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'remove',
|
name: 'remove',
|
||||||
sort: 100,
|
sort: 100,
|
||||||
|
@ -8,6 +8,7 @@ import { useBlockRequestContext } from '../../../block-provider';
|
|||||||
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager';
|
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager';
|
||||||
import { mergeFilter } from '../../../filter-provider/utils';
|
import { mergeFilter } from '../../../filter-provider/utils';
|
||||||
import { useDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
|
import { useDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
|
||||||
|
import { hasDuplicateKeys } from './utils';
|
||||||
|
|
||||||
export const useGetFilterOptions = () => {
|
export const useGetFilterOptions = () => {
|
||||||
const { getCollectionFields } = useCollectionManager_deprecated();
|
const { getCollectionFields } = useCollectionManager_deprecated();
|
||||||
@ -149,8 +150,42 @@ const isEmpty = (obj) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeNullCondition = (filter) => {
|
export const getCustomCondition = (filter, fieldSchema, customFlat = flat) => {
|
||||||
const items = flat(filter || {});
|
const filterSchema = fieldSchema ? fieldSchema['x-filter-rules'] : '';
|
||||||
|
const filterSchemaItem = customFlat(filterSchema || '') as any;
|
||||||
|
const items = customFlat(filter || {}) as any;
|
||||||
|
const values = {};
|
||||||
|
const isCustomFilter = filterSchema?.$and?.length || filterSchema?.$or?.length;
|
||||||
|
const isFilterCustom = isCustomFilter ? hasDuplicateKeys(items, filterSchemaItem) : false;
|
||||||
|
if (!isFilterCustom) {
|
||||||
|
if (isCustomFilter) {
|
||||||
|
for (const filterKey in filterSchemaItem) {
|
||||||
|
const match = filterSchemaItem[filterKey]?.slice(11, -2);
|
||||||
|
const collection = match?.split('.')[0];
|
||||||
|
const filterItems = Object.keys(items).filter((item) => item.includes(collection))[0];
|
||||||
|
if (filterItems) {
|
||||||
|
filterSchemaItem[filterKey] = items[filterItems];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const item in filterSchemaItem) {
|
||||||
|
if (filterSchemaItem[item].includes('$nFilter')) {
|
||||||
|
delete filterSchemaItem[item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const flatFieldSchema = customFlat.unflatten(filterSchemaItem);
|
||||||
|
flatFieldSchema['$and'] = flatFieldSchema?.['$and']?.filter(Boolean);
|
||||||
|
flatFieldSchema['$or'] = flatFieldSchema?.['$or']?.filter(Boolean);
|
||||||
|
return flatFieldSchema;
|
||||||
|
} else {
|
||||||
|
return customFlat.unflatten({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return customFlat.unflatten(items);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeNullCondition = (filter, customFlat = flat) => {
|
||||||
|
const items = customFlat(filter || {}) as any;
|
||||||
const values = {};
|
const values = {};
|
||||||
for (const key in items) {
|
for (const key in items) {
|
||||||
const value = items[key];
|
const value = items[key];
|
||||||
@ -158,7 +193,7 @@ export const removeNullCondition = (filter) => {
|
|||||||
values[key] = value;
|
values[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flat.unflatten(values);
|
return customFlat.unflatten(values);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFilterActionProps = () => {
|
export const useFilterActionProps = () => {
|
||||||
@ -179,7 +214,7 @@ export const useFilterFieldProps = ({ options, service, params }) => {
|
|||||||
// filter parameter for the block
|
// filter parameter for the block
|
||||||
const defaultFilter = params.filter;
|
const defaultFilter = params.filter;
|
||||||
// filter parameter for the filter action
|
// filter parameter for the filter action
|
||||||
const filter = removeNullCondition(values?.filter);
|
const filter = removeNullCondition(values?.filter) as any;
|
||||||
|
|
||||||
if (dataLoadingMode === 'manual' && _.isEmpty(filter)) {
|
if (dataLoadingMode === 'manual' && _.isEmpty(filter)) {
|
||||||
return service.mutate(undefined);
|
return service.mutate(undefined);
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
// 数组去重
|
||||||
|
const getArrayOfNoDuplicateValue = (arr: Array<string | number>): Array<string | number> => {
|
||||||
|
return [...new Set(arr)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断两个对象是否包含有相同的key
|
||||||
|
export function hasDuplicateKeys(A: Object, B: Object): boolean {
|
||||||
|
const keysA = getArrayOfNoDuplicateValue(Object.keys(A));
|
||||||
|
const keysB = getArrayOfNoDuplicateValue(Object.keys(B));
|
||||||
|
const keysA_B = getArrayOfNoDuplicateValue([...keysA, ...keysB]);
|
||||||
|
return keysA_B.length < keysA.length + keysB.length;
|
||||||
|
}
|
@ -558,23 +558,32 @@ export const EditTitleField = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
|
const collectionManage = useCollectionManager_deprecated();
|
||||||
|
const isCustomFilterItem = ((fieldSchema?.name as string) ?? '').startsWith('custom.');
|
||||||
|
const collectionManageField = isCustomFilterItem
|
||||||
|
? collectionManage.collections.filter((value) => value.name === fieldSchema['x-decorator-props'])[0]
|
||||||
|
: {};
|
||||||
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
const targetFields = collectionField?.target
|
let targetFields = [];
|
||||||
|
if (collectionField) {
|
||||||
|
targetFields = collectionField?.target
|
||||||
? getCollectionFields(collectionField?.target)
|
? getCollectionFields(collectionField?.target)
|
||||||
: getCollectionFields(collectionField?.targetCollection) ?? [];
|
: getCollectionFields(collectionField?.targetCollection) ?? [];
|
||||||
|
} else if (collectionManageField) {
|
||||||
|
targetFields = collectionManageField['fields'];
|
||||||
|
}
|
||||||
const options = targetFields
|
const options = targetFields
|
||||||
.filter((field) => !field?.target && field.type !== 'boolean')
|
.filter((field) => !field?.target && field.type !== 'boolean')
|
||||||
.map((field) => ({
|
.map((field) => ({
|
||||||
value: field?.name,
|
value: field?.name,
|
||||||
label: compile(field?.uiSchema?.title) || field?.name,
|
label: compile(field?.uiSchema?.title) || field?.name,
|
||||||
}));
|
}));
|
||||||
|
return options.length > 0 && (fieldSchema['x-component'] === 'CollectionField' || isCustomFilterItem) ? (
|
||||||
return options.length > 0 && fieldSchema['x-component'] === 'CollectionField' ? (
|
|
||||||
<SchemaSettingsSelectItem
|
<SchemaSettingsSelectItem
|
||||||
key="title-field"
|
key="title-field"
|
||||||
title={t('Title field')}
|
title={t('Title field')}
|
||||||
options={options}
|
options={options}
|
||||||
value={field?.componentProps?.fieldNames?.label}
|
value={fieldSchema['x-component-props']?.['fieldNames']?.label || 'id'}
|
||||||
onChange={(label) => {
|
onChange={(label) => {
|
||||||
const schema = {
|
const schema = {
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
@ -584,10 +593,11 @@ export const EditTitleField = () => {
|
|||||||
...field.componentProps.fieldNames,
|
...field.componentProps.fieldNames,
|
||||||
label,
|
label,
|
||||||
};
|
};
|
||||||
|
if (isCustomFilterItem) fieldNames['value'] = label;
|
||||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||||
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
||||||
schema['x-component-props'] = fieldSchema['x-component-props'];
|
schema['x-component-props'] = fieldSchema['x-component-props'];
|
||||||
field.componentProps.fieldNames = fieldSchema['x-component-props'].fieldNames;
|
field.componentProps = fieldSchema['x-component-props'];
|
||||||
dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
schema,
|
schema,
|
||||||
});
|
});
|
||||||
|
@ -119,6 +119,7 @@ import {
|
|||||||
} from './buttons';
|
} from './buttons';
|
||||||
import * as initializerComponents from './components';
|
import * as initializerComponents from './components';
|
||||||
import * as items from './items';
|
import * as items from './items';
|
||||||
|
import { FilterFormItemCustom } from './items';
|
||||||
|
|
||||||
export * from './buttons';
|
export * from './buttons';
|
||||||
export * from './items';
|
export * from './items';
|
||||||
@ -176,6 +177,7 @@ export class SchemaInitializerPlugin extends Plugin {
|
|||||||
DisassociateActionInitializer,
|
DisassociateActionInitializer,
|
||||||
FilterActionInitializer,
|
FilterActionInitializer,
|
||||||
RefreshActionInitializer,
|
RefreshActionInitializer,
|
||||||
|
FilterFormItemCustom,
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
this.app.schemaInitializerManager.add(blockInitializers_deprecated);
|
this.app.schemaInitializerManager.add(blockInitializers_deprecated);
|
||||||
|
@ -1,32 +1,4 @@
|
|||||||
import React, { memo, Profiler, useCallback, useContext, useMemo } from 'react';
|
import React, { memo, useCallback, useContext, useMemo } from 'react';
|
||||||
import {
|
|
||||||
ACLCollectionFieldProvider,
|
|
||||||
BlockItem,
|
|
||||||
css,
|
|
||||||
cx,
|
|
||||||
EditComponent,
|
|
||||||
EditDescription,
|
|
||||||
FormDialog,
|
|
||||||
FormItem,
|
|
||||||
GeneralSchemaDesigner,
|
|
||||||
gridRowColWrap,
|
|
||||||
HTMLEncode,
|
|
||||||
i18n,
|
|
||||||
SchemaComponent,
|
|
||||||
SchemaComponentOptions,
|
|
||||||
SchemaInitializerItem,
|
|
||||||
SchemaSettingsDataScope,
|
|
||||||
SchemaSettingsDivider,
|
|
||||||
Select,
|
|
||||||
useAPIClient,
|
|
||||||
useCollectionManager,
|
|
||||||
useCollectionManager_deprecated,
|
|
||||||
useCompile,
|
|
||||||
useDesignable,
|
|
||||||
useFormBlockContext,
|
|
||||||
useGlobalTheme,
|
|
||||||
useSchemaInitializerItem,
|
|
||||||
} from '@tachybase/client';
|
|
||||||
import { ArrayItems, FormLayout } from '@tachybase/components';
|
import { ArrayItems, FormLayout } from '@tachybase/components';
|
||||||
import {
|
import {
|
||||||
Field,
|
Field,
|
||||||
@ -37,22 +9,48 @@ import {
|
|||||||
uid,
|
uid,
|
||||||
useField,
|
useField,
|
||||||
useFieldSchema,
|
useFieldSchema,
|
||||||
useForm,
|
|
||||||
} from '@tachybase/schema';
|
} from '@tachybase/schema';
|
||||||
|
|
||||||
import { ConfigProvider, Radio, Space } from 'antd';
|
import { ConfigProvider, Space } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { tval, useTranslation } from '../../locale';
|
import { useAPIClient } from '../../api-client';
|
||||||
|
import { SchemaInitializerItem, useSchemaInitializerItem } from '../../application';
|
||||||
|
import { SchemaSettings } from '../../application/schema-settings/SchemaSettings';
|
||||||
|
import { useFormBlockContext } from '../../block-provider';
|
||||||
|
import { ACLCollectionFieldProvider } from '../../built-in/acl';
|
||||||
|
import { useCollectionManager_deprecated } from '../../collection-manager';
|
||||||
|
import { useCollectionManager } from '../../data-source';
|
||||||
|
import { i18n } from '../../i18n';
|
||||||
import {
|
import {
|
||||||
EditDefaultValue,
|
BlockItem,
|
||||||
EditFormulaTitleField,
|
EditDescription,
|
||||||
EditTitle,
|
EditTitle,
|
||||||
EditTitleField,
|
EditTitleField,
|
||||||
|
FormDialog,
|
||||||
|
FormItem,
|
||||||
|
HTMLEncode,
|
||||||
|
SchemaComponent,
|
||||||
|
SchemaComponentOptions,
|
||||||
|
Select,
|
||||||
|
useCompile,
|
||||||
|
useDesignable,
|
||||||
|
} from '../../schema-component';
|
||||||
|
import {
|
||||||
|
EditCustomDefaultValue,
|
||||||
|
EditFormulaTitleField,
|
||||||
|
GeneralSchemaDesigner,
|
||||||
SchemaSettingCollection,
|
SchemaSettingCollection,
|
||||||
SchemaSettingComponent,
|
SchemaSettingComponent,
|
||||||
|
SchemaSettingsCustomRemove,
|
||||||
|
SchemaSettingsDataScope,
|
||||||
|
SchemaSettingsDivider,
|
||||||
|
SchemaSettingsRemove,
|
||||||
} from '../../schema-settings';
|
} from '../../schema-settings';
|
||||||
import { SchemaSettingsRemove } from '../../schema-settings/SchemaSettingsRemove';
|
import { css, cx } from '../../style';
|
||||||
|
import { useGlobalTheme } from '../../style/theme';
|
||||||
|
import { gridRowColWrap } from '../utils';
|
||||||
|
|
||||||
const FieldComponentProps: React.FC = observer(
|
const FieldComponentProps: React.FC = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
@ -228,7 +226,7 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
},
|
},
|
||||||
associationField: {
|
associationField: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
title: tval('Association field'),
|
title: t('Association field'),
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Select',
|
'x-component': 'Select',
|
||||||
'x-visible': false,
|
'x-visible': false,
|
||||||
@ -290,7 +288,7 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
});
|
});
|
||||||
const { title, component, collection, associationField } = values;
|
const { title, component, collection, associationField } = values;
|
||||||
const defaultSchema = getInterface(component)?.default?.uiSchema || {};
|
const defaultSchema = getInterface(component)?.default?.uiSchema || {};
|
||||||
const titleField = cm.getCollection(collection).titleField;
|
const titleField = cm.getCollection(collection)?.titleField;
|
||||||
const name = uid();
|
const name = uid();
|
||||||
insert(
|
insert(
|
||||||
gridRowColWrap({
|
gridRowColWrap({
|
||||||
@ -300,7 +298,8 @@ export const FilterCustomItemInitializer: React.FC<{
|
|||||||
name: 'custom.' + name,
|
name: 'custom.' + name,
|
||||||
required: false,
|
required: false,
|
||||||
'x-component': component,
|
'x-component': component,
|
||||||
'x-designer': 'FilterItemCustomDesigner',
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FilterFormCustomSettings',
|
||||||
'x-decorator': 'FilterFormItem',
|
'x-decorator': 'FilterFormItem',
|
||||||
'x-decorator-props': collection,
|
'x-decorator-props': collection,
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
@ -364,18 +363,9 @@ export const FilterItemCustomDesigner: React.FC = () => {
|
|||||||
{component === 'Select' || component === 'AutoComplete' ? <SchemaSettingComponent /> : null}
|
{component === 'Select' || component === 'AutoComplete' ? <SchemaSettingComponent /> : null}
|
||||||
{component === 'Select' || component === 'AutoComplete' ? <EditTitleField /> : null}
|
{component === 'Select' || component === 'AutoComplete' ? <EditTitleField /> : null}
|
||||||
{component === 'Select' || component === 'AutoComplete' ? <EditFormulaTitleField /> : null}
|
{component === 'Select' || component === 'AutoComplete' ? <EditFormulaTitleField /> : null}
|
||||||
<EditDefaultValue />
|
<EditCustomDefaultValue />
|
||||||
<SchemaSettingsDivider />
|
<SchemaSettingsDivider />
|
||||||
<SchemaSettingsRemove
|
<SchemaSettingsRemove />
|
||||||
key="remove"
|
|
||||||
confirm={{
|
|
||||||
title: t('Delete field'),
|
|
||||||
}}
|
|
||||||
removeParentsIfNoChildren
|
|
||||||
breakRemoveOn={{
|
|
||||||
'x-component': 'Grid',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</GeneralSchemaDesigner>
|
</GeneralSchemaDesigner>
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -21,3 +21,4 @@ export * from './RecordReadPrettyAssociationFormBlockInitializer';
|
|||||||
export * from './SelectActionInitializer';
|
export * from './SelectActionInitializer';
|
||||||
export * from './SubmitActionInitializer';
|
export * from './SubmitActionInitializer';
|
||||||
export * from './TableActionColumnInitializer';
|
export * from './TableActionColumnInitializer';
|
||||||
|
export * from './CustomFilterFormItemInitializer';
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
import React, { useEffect, useMemo } from 'react';
|
||||||
|
import { Field, useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { SchemaComponent, useDesignable, VariableScopeProvider } from '../schema-component';
|
||||||
|
import { SchemaSettingsModalItem } from './SchemaSettings';
|
||||||
|
import { getShouldChange, useCurrentUserVariable, useDatetimeVariable, VariableInput } from './VariableInput';
|
||||||
|
|
||||||
|
export const EditCustomDefaultValue = () => {
|
||||||
|
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': FilterCustomVariableInput,
|
||||||
|
'x-component-props': {
|
||||||
|
fieldSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onSubmit={({ default: { value } }) => {
|
||||||
|
field.setValue(value);
|
||||||
|
fieldSchema['default'] = value;
|
||||||
|
fieldSchema['x-component-props']['defaultValue'] = value;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
'x-uid': fieldSchema['x-uid'],
|
||||||
|
['x-component-props']: fieldSchema['x-component-props'],
|
||||||
|
default: fieldSchema.default,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FilterCustomVariableInput = (props: any) => {
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,124 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Field, ISchema, useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { useCollection_deprecated, useCollectionManager_deprecated } from '../collection-manager';
|
||||||
|
import { useCompile, useDesignable } from '../schema-component';
|
||||||
|
import { SchemaSettingsModalItem } from './SchemaSettings';
|
||||||
|
|
||||||
|
export const useFormulaTitleOptions = () => {
|
||||||
|
const compile = useCompile();
|
||||||
|
const { getCollectionJoinField, getCollectionFields } = useCollectionManager_deprecated();
|
||||||
|
const { getField } = useCollection_deprecated();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const collectionManage = useCollectionManager_deprecated();
|
||||||
|
const collectionManageField = collectionManage.collections.filter(
|
||||||
|
(value) => value.name === fieldSchema['x-decorator-props'],
|
||||||
|
)[0];
|
||||||
|
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
|
let fields = [];
|
||||||
|
if (collectionField) {
|
||||||
|
fields = getCollectionFields(
|
||||||
|
collectionField
|
||||||
|
? collectionField.target
|
||||||
|
? collectionField.target
|
||||||
|
: collectionField.collectionName
|
||||||
|
: fieldSchema['name'],
|
||||||
|
);
|
||||||
|
} else if (collectionManageField) {
|
||||||
|
fields = collectionManageField['fields'];
|
||||||
|
}
|
||||||
|
const options = [];
|
||||||
|
fields?.forEach((field) => {
|
||||||
|
if (field.interface !== 'm2m') {
|
||||||
|
if (field.uiSchema) {
|
||||||
|
options.push({
|
||||||
|
label: compile(field.uiSchema.title),
|
||||||
|
value: field.name,
|
||||||
|
children:
|
||||||
|
getCollectionFields(field.target)
|
||||||
|
?.filter((subField) => subField.uiSchema)
|
||||||
|
.map((subField) => ({
|
||||||
|
label: subField.uiSchema ? compile(subField.uiSchema.title) : '',
|
||||||
|
value: subField.name,
|
||||||
|
})) ?? [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EditFormulaTitleField = () => {
|
||||||
|
const { getCollectionJoinField, collections } = useCollectionManager_deprecated();
|
||||||
|
const { getField } = useCollection_deprecated();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
|
||||||
|
let collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
|
collectionField = collectionField
|
||||||
|
? collectionField
|
||||||
|
: collections.find((value) => value.name === fieldSchema['x-decorator-props'])?.fields;
|
||||||
|
const options = useFormulaTitleOptions();
|
||||||
|
const editTitle = async (formula) => {
|
||||||
|
const schema = {
|
||||||
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
|
};
|
||||||
|
const fieldNames = {
|
||||||
|
...collectionField?.uiSchema?.['x-component-props']?.['fieldNames'],
|
||||||
|
...field.componentProps.fieldNames,
|
||||||
|
formula,
|
||||||
|
};
|
||||||
|
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||||
|
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
||||||
|
schema['x-component-props'] = fieldSchema['x-component-props'];
|
||||||
|
field.componentProps.fieldNames = fieldSchema['x-component-props'].fieldNames;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema,
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SchemaSettingsModalItem
|
||||||
|
key="edit-field-title"
|
||||||
|
title={t('Custom option label')}
|
||||||
|
schema={
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
title: t('Custom option label'),
|
||||||
|
properties: {
|
||||||
|
formula: {
|
||||||
|
required: true,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Variable.TextArea',
|
||||||
|
'x-component-props': {
|
||||||
|
scope: options,
|
||||||
|
},
|
||||||
|
default: field?.componentProps?.fieldNames?.formula || '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as ISchema
|
||||||
|
}
|
||||||
|
onSubmit={({ formula }) => {
|
||||||
|
if (formula) {
|
||||||
|
editTitle(formula);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFormulaTitleVisible = () => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const options = useFormulaTitleOptions();
|
||||||
|
// FIXME 这里现在只有当设置为 select,默认为 select 的时候看不到
|
||||||
|
return (
|
||||||
|
options.length > 0 &&
|
||||||
|
(fieldSchema['x-component-props']?.mode === 'Select' || fieldSchema['x-component'] === 'CollectionField') &&
|
||||||
|
fieldSchema['x-component-props']?.fieldNames?.value !== undefined
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Field, useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useCollectionManager } from '../data-source';
|
||||||
|
import { useDesignable } from '../schema-component';
|
||||||
|
import { SchemaSettingsSelectItem } from './SchemaSettings';
|
||||||
|
|
||||||
|
export const SchemaSettingCollection = () => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const collections = useCollectionManager();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const options = collections?.dataSource['options']?.collections.map((value) => {
|
||||||
|
return {
|
||||||
|
label: value.title,
|
||||||
|
value: value.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const { dn } = useDesignable();
|
||||||
|
return (
|
||||||
|
<SchemaSettingsSelectItem
|
||||||
|
key="component-field"
|
||||||
|
title="Edit Collection"
|
||||||
|
options={options}
|
||||||
|
value={fieldSchema['collectionName']}
|
||||||
|
onChange={(name) => {
|
||||||
|
field.setValue('');
|
||||||
|
const titleField = collections.getCollection(name).titleField;
|
||||||
|
fieldSchema['collectionName'] = name;
|
||||||
|
fieldSchema.default = '';
|
||||||
|
fieldSchema['x-component-props'] = {
|
||||||
|
...fieldSchema['x-component-props'],
|
||||||
|
collection: name,
|
||||||
|
fieldNames: {
|
||||||
|
label: titleField,
|
||||||
|
value: titleField,
|
||||||
|
},
|
||||||
|
defaultValue: '',
|
||||||
|
};
|
||||||
|
fieldSchema['x-decorator-props'] = name;
|
||||||
|
field.componentProps = fieldSchema['x-component-props'];
|
||||||
|
void dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
|
collectionName: fieldSchema['collectionName'],
|
||||||
|
['x-component-props']: fieldSchema['x-component-props'],
|
||||||
|
['x-decorator-props']: fieldSchema['x-decorator-props'],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useDesignable } from '../schema-component';
|
||||||
|
import { useFieldComponents } from '../schema-initializer';
|
||||||
|
import { SchemaSettingsSelectItem } from './SchemaSettings';
|
||||||
|
|
||||||
|
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) => {
|
||||||
|
field.component = mode;
|
||||||
|
fieldSchema['x-component'] = mode;
|
||||||
|
field.componentProps = fieldSchema['x-component-props'];
|
||||||
|
void dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
|
['x-component']: fieldSchema['x-component'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
@ -23,6 +23,7 @@ import {
|
|||||||
detailsBlockSettings,
|
detailsBlockSettings,
|
||||||
singleDataDetailsBlockSettings,
|
singleDataDetailsBlockSettings,
|
||||||
} from '../modules/blocks/data-blocks/details-single/detailsBlockSettings';
|
} from '../modules/blocks/data-blocks/details-single/detailsBlockSettings';
|
||||||
|
import { FilterItemCustomSettings } from '../modules/blocks/data-blocks/form';
|
||||||
import {
|
import {
|
||||||
createFormBlockSettings,
|
createFormBlockSettings,
|
||||||
creationFormBlockSettings,
|
creationFormBlockSettings,
|
||||||
@ -95,6 +96,7 @@ export class SchemaSettingsPlugin extends Plugin {
|
|||||||
|
|
||||||
// field settings
|
// field settings
|
||||||
this.schemaSettingsManager.add(fieldSettingsFormItem);
|
this.schemaSettingsManager.add(fieldSettingsFormItem);
|
||||||
|
this.schemaSettingsManager.add(FilterItemCustomSettings);
|
||||||
this.schemaSettingsManager.add(tableColumnSettings);
|
this.schemaSettingsManager.add(tableColumnSettings);
|
||||||
this.schemaSettingsManager.add(filterCollapseItemFieldSettings);
|
this.schemaSettingsManager.add(filterCollapseItemFieldSettings);
|
||||||
|
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Form, Schema } from '@tachybase/schema';
|
import { Form, Schema, useField } from '@tachybase/schema';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { CollectionFieldOptions_deprecated } from '../../collection-manager';
|
import { CollectionFieldOptions_deprecated, useCollectionManager_deprecated } from '../../collection-manager';
|
||||||
import { useVariableScope, Variable } from '../../schema-component';
|
import { useCompile, useVariableScope, Variable } from '../../schema-component';
|
||||||
import { useValues } from '../../schema-component/antd/filter/useValues';
|
import { useValues } from '../../schema-component/antd/filter/useValues';
|
||||||
import { VariableOption, VariablesContextType } from '../../variables/types';
|
import { VariableOption, VariablesContextType } from '../../variables/types';
|
||||||
import { isVariable } from '../../variables/utils/isVariable';
|
import { isVariable } from '../../variables/utils/isVariable';
|
||||||
|
import { useDateVariable } from './hooks';
|
||||||
import { useBlockCollection } from './hooks/useBlockCollection';
|
import { useBlockCollection } from './hooks/useBlockCollection';
|
||||||
import { useContextAssociationFields } from './hooks/useContextAssociationFields';
|
import { useContextAssociationFields } from './hooks/useContextAssociationFields';
|
||||||
import { useCurrentRecordVariable } from './hooks/useRecordVariable';
|
import { useCurrentRecordVariable } from './hooks/useRecordVariable';
|
||||||
import { useCurrentUserVariable } from './hooks/useUserVariable';
|
import { useCurrentUserVariable, useUserVariable } from './hooks/useUserVariable';
|
||||||
import { useVariableOptions } from './hooks/useVariableOptions';
|
import { useVariableOptions } from './hooks/useVariableOptions';
|
||||||
import { Option } from './type';
|
import { Option } from './type';
|
||||||
|
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import { Field, useField } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { useFormActiveFields } from '../../../block-provider';
|
||||||
|
import { useFilterContext } from '../../filter-form/context';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变量:`自定义筛选`
|
||||||
|
* @param props
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const useFilterVariable = (props: any = {}) => {
|
||||||
|
const customFilter = useFilterContext();
|
||||||
|
const field = useField<Field>();
|
||||||
|
const { getActiveFieldsName } = useFormActiveFields();
|
||||||
|
const activeFields = getActiveFieldsName('form');
|
||||||
|
const fields = props?.form?.fields;
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const settings = useMemo(() => {
|
||||||
|
const customFields = [];
|
||||||
|
|
||||||
|
for (const field in fields) {
|
||||||
|
customFields.push({
|
||||||
|
key: field,
|
||||||
|
...fields[field],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const options = customFields
|
||||||
|
.filter((value) => value?.props?.name.includes('custom.'))
|
||||||
|
.map((custom) => {
|
||||||
|
if (activeFields.includes(custom?.props?.name)) {
|
||||||
|
const value = custom?.props?.name.replace(/^custom\./, '');
|
||||||
|
return {
|
||||||
|
key: custom?.props?.name,
|
||||||
|
value,
|
||||||
|
label: custom.title,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
return {
|
||||||
|
label: t('Current filter'),
|
||||||
|
value: '$nFilter',
|
||||||
|
key: '$nFilter',
|
||||||
|
children: options,
|
||||||
|
};
|
||||||
|
}, [fields]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
/** 变量配置 */
|
||||||
|
currentCustomFilterSetting: settings,
|
||||||
|
/** 变量值 */
|
||||||
|
currentCustonFilterCtx: field?.value,
|
||||||
|
/** 用于判断是否需要显示配置项 */
|
||||||
|
shouldDisplayCustomFilter: !!customFilter,
|
||||||
|
};
|
||||||
|
};
|
@ -4,6 +4,7 @@ import { Form, ISchema, Schema } from '@tachybase/schema';
|
|||||||
import { CollectionFieldOptions_deprecated } from '../../../collection-manager';
|
import { CollectionFieldOptions_deprecated } from '../../../collection-manager';
|
||||||
import { useBlockCollection } from './useBlockCollection';
|
import { useBlockCollection } from './useBlockCollection';
|
||||||
import { useDatetimeVariable } from './useDateVariable';
|
import { useDatetimeVariable } from './useDateVariable';
|
||||||
|
import { useFilterVariable } from './useFilterVariable';
|
||||||
import { useCurrentFormVariable } from './useFormVariable';
|
import { useCurrentFormVariable } from './useFormVariable';
|
||||||
import { useCurrentObjectVariable } from './useIterationVariable';
|
import { useCurrentObjectVariable } from './useIterationVariable';
|
||||||
import { useCurrentParentRecordVariable } from './useParentRecordVariable';
|
import { useCurrentParentRecordVariable } from './useParentRecordVariable';
|
||||||
@ -96,6 +97,14 @@ export const useVariableOptions = ({
|
|||||||
targetFieldSchema,
|
targetFieldSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { currentCustomFilterSetting, shouldDisplayCustomFilter } = useFilterVariable({
|
||||||
|
schema: uiSchema,
|
||||||
|
form,
|
||||||
|
collectionName: blockParentCollectionName,
|
||||||
|
collectionField,
|
||||||
|
targetFieldSchema,
|
||||||
|
});
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return [
|
||||||
currentUserSettings,
|
currentUserSettings,
|
||||||
@ -106,6 +115,7 @@ export const useVariableOptions = ({
|
|||||||
shouldDisplayCurrentRecord && currentRecordSettings,
|
shouldDisplayCurrentRecord && currentRecordSettings,
|
||||||
shouldDisplayCurrentParentRecord && currentParentRecordSettings,
|
shouldDisplayCurrentParentRecord && currentParentRecordSettings,
|
||||||
shouldDisplayPopupRecord && popupRecordSettings,
|
shouldDisplayPopupRecord && popupRecordSettings,
|
||||||
|
shouldDisplayCustomFilter && currentCustomFilterSetting,
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
}, [
|
}, [
|
||||||
currentUserSettings,
|
currentUserSettings,
|
||||||
@ -121,5 +131,7 @@ export const useVariableOptions = ({
|
|||||||
currentParentRecordSettings,
|
currentParentRecordSettings,
|
||||||
shouldDisplayPopupRecord,
|
shouldDisplayPopupRecord,
|
||||||
popupRecordSettings,
|
popupRecordSettings,
|
||||||
|
currentCustomFilterSetting,
|
||||||
|
shouldDisplayCustomFilter,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
@ -1,34 +1,30 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import {
|
|
||||||
__UNSAFE__DynamicComponentProps,
|
|
||||||
__UNSAFE__VariableOption,
|
|
||||||
__UNSAFE__VariablesContextType,
|
|
||||||
css,
|
|
||||||
FormBlockContext,
|
|
||||||
getShouldChange,
|
|
||||||
RecordProvider,
|
|
||||||
SchemaComponent,
|
|
||||||
useCollectionManager_deprecated,
|
|
||||||
} from '@tachybase/client';
|
|
||||||
import { ArrayCollapse } from '@tachybase/components';
|
import { ArrayCollapse } from '@tachybase/components';
|
||||||
import { Form, observer, useField, useFieldSchema } from '@tachybase/schema';
|
import { Form, observer, useField, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { css } from 'antd-style';
|
||||||
|
|
||||||
|
import { FormBlockContext } from '../../block-provider';
|
||||||
|
import { useCollectionManager_deprecated } from '../../collection-manager';
|
||||||
|
import { RecordProvider } from '../../record-provider';
|
||||||
|
import { SchemaComponent } from '../../schema-component';
|
||||||
|
import { DynamicComponentProps } from '../../schema-component/antd/filter/DynamicComponent';
|
||||||
|
import { VariableOption, VariablesContextType } from '../../variables/types';
|
||||||
|
import { getShouldChange, VariableInput } from '../VariableInput';
|
||||||
import { FilterContext } from './context';
|
import { FilterContext } from './context';
|
||||||
import { VariableInput } from './VariableInput';
|
|
||||||
|
|
||||||
interface usePropsReturn {
|
interface usePropsReturn {
|
||||||
options: any;
|
options: any;
|
||||||
defaultValues: any[];
|
defaultValues: any[];
|
||||||
collectionName: string;
|
collectionName: string;
|
||||||
form: Form;
|
form: Form;
|
||||||
variables: __UNSAFE__VariablesContextType;
|
variables: VariablesContextType;
|
||||||
localVariables: __UNSAFE__VariableOption | __UNSAFE__VariableOption[];
|
localVariables: VariableOption | VariableOption[];
|
||||||
record: Record<string, any>;
|
record: Record<string, any>;
|
||||||
/**
|
/**
|
||||||
* create 表示创建表单,update 表示更新表单
|
* create 表示创建表单,update 表示更新表单
|
||||||
*/
|
*/
|
||||||
formBlockType: 'create' | 'update';
|
formBlockType: 'create' | 'update';
|
||||||
fields: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -40,7 +36,7 @@ export const FormFilterScope = observer(
|
|||||||
(props: Props) => {
|
(props: Props) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { useProps, dynamicComponent } = props;
|
const { useProps, dynamicComponent } = props;
|
||||||
const { options, defaultValues, collectionName, form, formBlockType, variables, localVariables, record, fields } =
|
const { options, defaultValues, collectionName, form, formBlockType, variables, localVariables, record } =
|
||||||
useProps();
|
useProps();
|
||||||
const { getAllCollectionsInheritChain } = useCollectionManager_deprecated();
|
const { getAllCollectionsInheritChain } = useCollectionManager_deprecated();
|
||||||
const components = useMemo(() => ({ ArrayCollapse }), []);
|
const components = useMemo(() => ({ ArrayCollapse }), []);
|
||||||
@ -63,7 +59,7 @@ export const FormFilterScope = observer(
|
|||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
dynamicComponent: (props: __UNSAFE__DynamicComponentProps) => {
|
dynamicComponent: (props: DynamicComponentProps) => {
|
||||||
const { collectionField } = props;
|
const { collectionField } = props;
|
||||||
return (
|
return (
|
||||||
<VariableInput
|
<VariableInput
|
||||||
@ -77,7 +73,6 @@ export const FormFilterScope = observer(
|
|||||||
localVariables,
|
localVariables,
|
||||||
getAllCollectionsInheritChain,
|
getAllCollectionsInheritChain,
|
||||||
})}
|
})}
|
||||||
fields={fields}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -85,15 +80,20 @@ export const FormFilterScope = observer(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[collectionName, defaultValues, form, localVariables, options, props, record, variables, fields],
|
[collectionName, defaultValues, form, localVariables, options, props, record, variables],
|
||||||
);
|
);
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({ field: options, fieldSchema, dynamicComponent, options: options || [] }),
|
() => ({
|
||||||
|
field: options,
|
||||||
|
fieldSchema,
|
||||||
|
dynamicComponent,
|
||||||
|
options: options || [],
|
||||||
|
}),
|
||||||
[dynamicComponent, fieldSchema, options],
|
[dynamicComponent, fieldSchema, options],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormBlockContext.Provider value={{ form, type: formBlockType }}>
|
<FormBlockContext.Provider value={{ form, type: formBlockType, collectionName: collectionName }}>
|
||||||
<RecordProvider record={record}>
|
<RecordProvider record={record}>
|
||||||
<FilterContext.Provider value={value}>
|
<FilterContext.Provider value={value}>
|
||||||
<SchemaComponent components={components} schema={schema} />
|
<SchemaComponent components={components} schema={schema} />
|
@ -1,4 +1,4 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext, useContext } from 'react';
|
||||||
import { ObjectField, Schema } from '@tachybase/schema';
|
import { ObjectField, Schema } from '@tachybase/schema';
|
||||||
|
|
||||||
export interface FilterContextProps {
|
export interface FilterContextProps {
|
||||||
@ -8,8 +8,13 @@ export interface FilterContextProps {
|
|||||||
options?: any[];
|
options?: any[];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
collectionName?: string;
|
collectionName?: string;
|
||||||
|
customFilter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RemoveConditionContext = createContext(null);
|
export const RemoveConditionContext = createContext(null);
|
||||||
export const FilterContext = createContext<FilterContextProps>(null);
|
export const FilterContext = createContext<FilterContextProps>(null);
|
||||||
export const FilterLogicContext = createContext(null);
|
export const FilterLogicContext = createContext(null);
|
||||||
|
|
||||||
|
export const useFilterContext = () => {
|
||||||
|
return useContext(FilterContext);
|
||||||
|
};
|
@ -9,6 +9,10 @@ export * from './SchemaSettingsDataScope';
|
|||||||
export * from './SchemaSettingsDefaultValue';
|
export * from './SchemaSettingsDefaultValue';
|
||||||
export * from './SchemaSettingsDateFormat';
|
export * from './SchemaSettingsDateFormat';
|
||||||
export * from './SchemaSettingsSortingRule';
|
export * from './SchemaSettingsSortingRule';
|
||||||
|
export * from './SchemaSettingCollection';
|
||||||
|
export * from './SchemaSettingComponent';
|
||||||
|
export * from './EditFormulaTitleField';
|
||||||
|
export * from './EditCustomDefaultValue';
|
||||||
|
|
||||||
export { default as useParseDataScopeFilter } from './hooks/useParseDataScopeFilter';
|
export { default as useParseDataScopeFilter } from './hooks/useParseDataScopeFilter';
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
export {
|
|
||||||
removeGridFormItem,
|
|
||||||
useInheritsFormItemInitializerFields,
|
|
||||||
useFormItemInitializerFields,
|
|
||||||
useAssociatedFormItemInitializerFields,
|
|
||||||
useFilterInheritsFormItemInitializerFields,
|
|
||||||
useFilterFormItemInitializerFields,
|
|
||||||
} from './schema-initializer/utils';
|
|
||||||
export { parseVariables } from './schema-component/common/utils/uitls';
|
|
||||||
export { linkageAction } from './schema-component/antd/action/utils';
|
|
||||||
export { useCollectionState } from './schema-settings/DataTemplates/hooks/useCollectionState';
|
|
||||||
export { useSyncFromForm } from './schema-settings/DataTemplates/utils';
|
|
||||||
export { ColumnFieldProvider } from './schema-component/antd/table-v2/components/ColumnFieldProvider';
|
|
||||||
export { default as schema } from './schema-component/antd/association-field/schema';
|
|
||||||
export { ReadPrettyInternalViewer } from './schema-component/antd/association-field/InternalViewer';
|
|
||||||
export { useSetAriaLabelForPopover } from './schema-component/antd/action/hooks/useSetAriaLabelForPopover';
|
|
||||||
export { InternalFileManager } from './schema-component/antd/association-field/FileManager';
|
|
||||||
export { CreateRecordAction } from './schema-component/antd/association-field/components/CreateRecordAction';
|
|
||||||
export { AssociationSelect } from './schema-component/antd/association-field/AssociationSelect';
|
|
||||||
export { AssociationFieldProvider } from './schema-component/antd/association-field/AssociationFieldProvider';
|
|
||||||
export { InternalCascadeSelect } from './schema-component/antd/association-field/InternalCascadeSelect';
|
|
||||||
export { InternalNester } from './schema-component/antd/association-field/InternalNester';
|
|
||||||
export { InternalPicker } from './schema-component/antd/association-field/InternalPicker';
|
|
||||||
export { InternalSubTable } from './schema-component/antd/association-field/InternalSubTable';
|
|
||||||
export { InternaPopoverNester } from './schema-component/antd/association-field/InternalPopoverNester';
|
|
||||||
export { InternalCascader } from './schema-component/antd/association-field/InternalCascader';
|
|
||||||
export { Nester } from './schema-component/antd/association-field/Nester';
|
|
||||||
export { SubTable } from './schema-component/antd/association-field/SubTable';
|
|
||||||
export { ReadPretty } from './schema-component/antd/association-field/ReadPretty';
|
|
||||||
export { SubFormProvider } from './schema-component/antd/association-field/hooks';
|
|
||||||
export { useAssociationFieldContext } from './schema-component/antd/association-field/hooks';
|
|
||||||
export { FlagProvider } from './flag-provider';
|
|
||||||
export { isVariable } from './variables/utils/isVariable';
|
|
||||||
export { transformVariableValue } from './variables/utils/transformVariableValue';
|
|
||||||
export { useVariables } from './variables';
|
|
||||||
export { VariableInput, getShouldChange } from './schema-settings/VariableInput/VariableInput';
|
|
||||||
export { useLocalVariables } from './variables';
|
|
||||||
export { VariablesContext } from './variables/VariablesProvider';
|
|
||||||
export {
|
|
||||||
EditComponent,
|
|
||||||
EditDescription,
|
|
||||||
EditOperator,
|
|
||||||
EditTitle,
|
|
||||||
EditTitleField,
|
|
||||||
EditTooltip,
|
|
||||||
EditValidationRules,
|
|
||||||
} from './schema-component/antd/form-item/SchemaSettingOptions';
|
|
||||||
export type { DynamicComponentProps } from './schema-component/antd/filter/DynamicComponent';
|
|
||||||
export { DetailsBlockProvider, useDetailsBlockContext } from './block-provider/DetailsBlockProvider';
|
|
||||||
export { getInnermostKeyAndValue } from './schema-component/common/utils/uitls';
|
|
||||||
export { default as useServiceOptions } from './schema-component/antd/association-field/hooks';
|
|
||||||
export type { VariablesContextType, VariableOption } from './variables/types';
|
|
||||||
export type { Option } from './schema-settings/VariableInput/type';
|
|
||||||
export { useBlockCollection } from './schema-settings/VariableInput/hooks/useBlockCollection';
|
|
||||||
export { useValues } from './schema-component/antd/filter/useValues';
|
|
||||||
export { useVariableOptions } from './schema-settings/VariableInput/hooks/useVariableOptions';
|
|
||||||
export { useContextAssociationFields } from './schema-settings/VariableInput/hooks/useContextAssociationFields';
|
|
||||||
export { useRecordVariable } from './schema-settings/VariableInput/hooks/useRecordVariable';
|
|
@ -47,11 +47,13 @@ export const nextTick = (fn: () => void) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function fuzzysearch(needle: string, haystack: string): boolean {
|
export function fuzzysearch(needle: string, haystack: string): boolean {
|
||||||
const hlen = haystack.length;
|
if (!needle || !haystack) {
|
||||||
const nlen = needle.length;
|
|
||||||
if (nlen > hlen) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hlen = haystack.length;
|
||||||
|
const nlen = needle.length;
|
||||||
|
|
||||||
if (nlen === hlen) {
|
if (nlen === hlen) {
|
||||||
return needle === haystack;
|
return needle === haystack;
|
||||||
}
|
}
|
||||||
|
@ -1,399 +0,0 @@
|
|||||||
import React, { useCallback, useContext, useMemo } from 'react';
|
|
||||||
import {
|
|
||||||
__UNSAFE__,
|
|
||||||
__UNSAFE__VariableInputOption,
|
|
||||||
__UNSAFE__VariableOption,
|
|
||||||
__UNSAFE__VariablesContextType,
|
|
||||||
CollectionFieldOptions,
|
|
||||||
isVariable,
|
|
||||||
useCollectionManager_deprecated,
|
|
||||||
useCompile,
|
|
||||||
useDateVariable,
|
|
||||||
useUserVariable,
|
|
||||||
useVariableScope,
|
|
||||||
Variable,
|
|
||||||
} from '@tachybase/client';
|
|
||||||
// @ts-ignore
|
|
||||||
import { Form, Schema, SchemaOptionsContext, useField, useFieldSchema } from '@tachybase/schema';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { FilterContext } from './context';
|
|
||||||
|
|
||||||
const { useBlockCollection, useValues, useVariableOptions, useContextAssociationFields, useRecordVariable } =
|
|
||||||
__UNSAFE__;
|
|
||||||
|
|
||||||
interface GetShouldChangeProps {
|
|
||||||
collectionField: CollectionFieldOptions;
|
|
||||||
variables: __UNSAFE__VariablesContextType;
|
|
||||||
localVariables: __UNSAFE__VariableOption | __UNSAFE__VariableOption[];
|
|
||||||
/** `useCollectionManager` 返回的 */
|
|
||||||
getAllCollectionsInheritChain: (collectionName: string) => string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RenderSchemaComponentProps {
|
|
||||||
value: any;
|
|
||||||
onChange: (value: any) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
value: any;
|
|
||||||
onChange: (value: any, optionPath?: any[]) => void;
|
|
||||||
renderSchemaComponent: (props: RenderSchemaComponentProps) => any;
|
|
||||||
schema?: any;
|
|
||||||
/** 消费变量值的字段 */
|
|
||||||
targetFieldSchema?: Schema;
|
|
||||||
children?: any;
|
|
||||||
className?: string;
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
collectionField: CollectionFieldOptions;
|
|
||||||
contextCollectionName?: string;
|
|
||||||
/**指定当前表单数据表 */
|
|
||||||
currentFormCollectionName?: string;
|
|
||||||
/**指定当前对象数据表 */
|
|
||||||
currentIterationCollectionName?: string;
|
|
||||||
/**
|
|
||||||
* 根据 `onChange` 的第一个参数,判断是否需要触发 `onChange`
|
|
||||||
* @param value `onChange` 的第一个参数
|
|
||||||
* @returns 返回为 `true` 时,才会触发 `onChange`
|
|
||||||
*/
|
|
||||||
shouldChange?: (value: any, optionPath?: any[]) => Promise<boolean>;
|
|
||||||
form?: Form;
|
|
||||||
/**
|
|
||||||
* 当前表单的记录,数据来自数据库
|
|
||||||
*/
|
|
||||||
record?: Record<string, any>;
|
|
||||||
/**
|
|
||||||
* 可以用该方法对内部的 scope 进行筛选和修改
|
|
||||||
* @param scope
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
returnScope?: (scope: __UNSAFE__VariableInputOption[]) => any[];
|
|
||||||
fields: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注意:该组件存在以下问题:
|
|
||||||
* - 在选中选项的时候该组件不能触发重渲染
|
|
||||||
* - 如果触发重渲染可能会导致无法展开子选项列表
|
|
||||||
* @param props
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const VariableInput = (props: Props) => {
|
|
||||||
const {
|
|
||||||
value,
|
|
||||||
onChange,
|
|
||||||
renderSchemaComponent: RenderSchemaComponent,
|
|
||||||
style,
|
|
||||||
schema,
|
|
||||||
className,
|
|
||||||
contextCollectionName,
|
|
||||||
collectionField,
|
|
||||||
shouldChange,
|
|
||||||
form,
|
|
||||||
record,
|
|
||||||
returnScope = _.identity,
|
|
||||||
targetFieldSchema,
|
|
||||||
currentFormCollectionName,
|
|
||||||
currentIterationCollectionName,
|
|
||||||
fields,
|
|
||||||
} = props;
|
|
||||||
const { name: blockCollectionName } = useBlockCollection();
|
|
||||||
const scope = useVariableScope();
|
|
||||||
const { operator, schema: uiSchema = collectionField?.uiSchema } = useValues();
|
|
||||||
|
|
||||||
const variableOptions = useVariableOptions({
|
|
||||||
collectionField,
|
|
||||||
form,
|
|
||||||
record,
|
|
||||||
operator,
|
|
||||||
uiSchema,
|
|
||||||
targetFieldSchema,
|
|
||||||
});
|
|
||||||
const contextVariable = useContextAssociationFields({ schema, maxDepth: 2, contextCollectionName, collectionField });
|
|
||||||
const { compatOldVariables } = useCompatOldVariables({
|
|
||||||
collectionField,
|
|
||||||
uiSchema,
|
|
||||||
targetFieldSchema,
|
|
||||||
blockCollectionName,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (contextCollectionName && variableOptions.every((item) => item.value !== contextVariable.value)) {
|
|
||||||
variableOptions.push(contextVariable);
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleChange = useCallback(
|
|
||||||
(value: any, optionPath: any[]) => {
|
|
||||||
if (!shouldChange) {
|
|
||||||
return onChange(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// `shouldChange` 这个函数的运算量比较大,会导致展开变量列表时有明显的卡顿感,在这里加个延迟能有效解决这个问题
|
|
||||||
setTimeout(async () => {
|
|
||||||
if (await shouldChange(value, optionPath)) {
|
|
||||||
onChange(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[onChange, shouldChange],
|
|
||||||
);
|
|
||||||
const options = useVariableCustomOptions(fields);
|
|
||||||
return (
|
|
||||||
<Variable.Input
|
|
||||||
className={className}
|
|
||||||
value={value}
|
|
||||||
onChange={handleChange}
|
|
||||||
scope={options}
|
|
||||||
style={style}
|
|
||||||
changeOnSelect
|
|
||||||
>
|
|
||||||
<RenderSchemaComponent value={value} onChange={onChange} />
|
|
||||||
</Variable.Input>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过限制用户的选择,来防止用户选择错误的变量
|
|
||||||
*/
|
|
||||||
export const getShouldChange = ({
|
|
||||||
collectionField,
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
getAllCollectionsInheritChain,
|
|
||||||
}: GetShouldChangeProps) => {
|
|
||||||
const collectionsInheritChain = collectionField ? getAllCollectionsInheritChain(collectionField.target) : [];
|
|
||||||
|
|
||||||
return async (value: any, optionPath: any[]) => {
|
|
||||||
if (_.isString(value) && value.includes('$nRole')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isVariable(value) || !variables || !collectionField) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// `json` 可以选择任意类型的变量,详见:https://tachybase.feishu.cn/docx/EmNEdEBOnoQohUx2UmBcqIQ5nyh#FPLfdSRDEoXR65xW0mBcdfL5n0c
|
|
||||||
if (collectionField.interface === 'json') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastOption = optionPath[optionPath.length - 1];
|
|
||||||
|
|
||||||
// 点击叶子节点时,必须更新 value
|
|
||||||
if (lastOption && _.isEmpty(lastOption.children) && !lastOption.loadChildren) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const collectionFieldOfVariable = await variables.getCollectionField(value, localVariables);
|
|
||||||
|
|
||||||
if (!collectionField) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// `一对一` 和 `一对多` 的不能用于设置默认值,因为其具有唯一性
|
|
||||||
if (['o2o', 'o2m', 'oho'].includes(collectionFieldOfVariable?.interface)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!collectionField.target && collectionFieldOfVariable?.target) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (collectionField.target && !collectionFieldOfVariable?.target) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
collectionField.target &&
|
|
||||||
collectionFieldOfVariable?.target &&
|
|
||||||
!collectionsInheritChain.includes(collectionFieldOfVariable?.target)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface FormatVariableScopeParam {
|
|
||||||
children: any[];
|
|
||||||
disabled: boolean;
|
|
||||||
name: string;
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FormatVariableScopeReturn {
|
|
||||||
value: string;
|
|
||||||
key: string;
|
|
||||||
label: string;
|
|
||||||
disabled: boolean;
|
|
||||||
children?: any[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 兼容老版本的变量
|
|
||||||
* @param variables
|
|
||||||
*/
|
|
||||||
export function useCompatOldVariables(props: {
|
|
||||||
uiSchema: any;
|
|
||||||
collectionField: CollectionFieldOptions;
|
|
||||||
blockCollectionName: string;
|
|
||||||
noDisabled?: boolean;
|
|
||||||
targetFieldSchema?: Schema;
|
|
||||||
}) {
|
|
||||||
const { uiSchema, collectionField, noDisabled, targetFieldSchema, blockCollectionName } = props;
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const lowLevelUserVariable = useUserVariable({
|
|
||||||
maxDepth: 1,
|
|
||||||
uiSchema: uiSchema,
|
|
||||||
collectionField,
|
|
||||||
noDisabled,
|
|
||||||
targetFieldSchema,
|
|
||||||
});
|
|
||||||
const currentRecordVariable = useRecordVariable({
|
|
||||||
schema: uiSchema,
|
|
||||||
collectionName: blockCollectionName,
|
|
||||||
collectionField,
|
|
||||||
noDisabled,
|
|
||||||
targetFieldSchema,
|
|
||||||
});
|
|
||||||
|
|
||||||
const compatOldVariables = useCallback(
|
|
||||||
(variables: __UNSAFE__VariableInputOption[], { value }) => {
|
|
||||||
if (!isVariable(value)) {
|
|
||||||
return variables;
|
|
||||||
}
|
|
||||||
|
|
||||||
variables = _.cloneDeep(variables);
|
|
||||||
|
|
||||||
const systemVariable: __UNSAFE__VariableInputOption = {
|
|
||||||
value: '$system',
|
|
||||||
key: '$system',
|
|
||||||
label: t('System variables'),
|
|
||||||
isLeaf: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: 'now',
|
|
||||||
key: 'now',
|
|
||||||
label: t('Current time'),
|
|
||||||
isLeaf: true,
|
|
||||||
depth: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
depth: 0,
|
|
||||||
};
|
|
||||||
const currentTime = {
|
|
||||||
value: 'currentTime',
|
|
||||||
label: t('Current time'),
|
|
||||||
children: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (value.includes('$system')) {
|
|
||||||
variables.push(systemVariable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes(`${blockCollectionName}.`)) {
|
|
||||||
const variable = variables.find((item) => item.value === '$nForm' || item.value === '$nRecord');
|
|
||||||
if (variable) {
|
|
||||||
variable.value = blockCollectionName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('$form')) {
|
|
||||||
const variable = variables.find((item) => item.value === '$nForm');
|
|
||||||
if (variable) {
|
|
||||||
variable.value = '$form';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('currentUser')) {
|
|
||||||
const userVariable = variables.find((item) => item.value === '$user');
|
|
||||||
if (userVariable) {
|
|
||||||
userVariable.value = 'currentUser';
|
|
||||||
} else {
|
|
||||||
variables.unshift({ ...lowLevelUserVariable, value: 'currentUser' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('currentRecord')) {
|
|
||||||
const formVariable = variables.find((item) => item.value === '$nRecord');
|
|
||||||
if (formVariable) {
|
|
||||||
formVariable.value = 'currentRecord';
|
|
||||||
} else {
|
|
||||||
variables.unshift({ ...currentRecordVariable, value: 'currentRecord' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('currentTime')) {
|
|
||||||
variables.push(currentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('$date')) {
|
|
||||||
const formVariable = variables.find((item) => item.value === '$nDate');
|
|
||||||
if (formVariable) {
|
|
||||||
formVariable.value = '$date';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return variables;
|
|
||||||
},
|
|
||||||
[blockCollectionName],
|
|
||||||
);
|
|
||||||
|
|
||||||
return { compatOldVariables };
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useVariableCustomOptions = (fields) => {
|
|
||||||
const field = useField<any>();
|
|
||||||
const { operator, schema } = field.data || {};
|
|
||||||
const userVariable = useUserVariable({
|
|
||||||
collectionField: { uiSchema: schema },
|
|
||||||
uiSchema: schema,
|
|
||||||
});
|
|
||||||
const dateVariable = useDateVariable({ operator, schema });
|
|
||||||
const filterVariable = useFilterVariable(fields);
|
|
||||||
|
|
||||||
const result = useMemo(
|
|
||||||
() => [userVariable, dateVariable, filterVariable].filter(Boolean),
|
|
||||||
[dateVariable, userVariable, filterVariable],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!operator || !schema) return [];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFilterVariable = (fields) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const compile = useCompile();
|
|
||||||
const { collections } = useCollectionManager_deprecated();
|
|
||||||
const customFields = [];
|
|
||||||
for (const field in fields) {
|
|
||||||
customFields.push({
|
|
||||||
key: field,
|
|
||||||
...fields[field],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = customFields
|
|
||||||
.filter((value) => value?.props?.name.includes('custom.'))
|
|
||||||
.map((custom) => {
|
|
||||||
const value = custom?.props?.name.replace(/^custom\./, '');
|
|
||||||
return {
|
|
||||||
key: custom?.props?.name,
|
|
||||||
value,
|
|
||||||
label: custom.title,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const result = useMemo(
|
|
||||||
() => ({
|
|
||||||
label: t('Current filter'),
|
|
||||||
value: '$nFilter',
|
|
||||||
key: '$nFilter',
|
|
||||||
children: options,
|
|
||||||
}),
|
|
||||||
[options, t],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!options.length) return null;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
@ -1,57 +0,0 @@
|
|||||||
import { Plugin, useCollection } from '@tachybase/client';
|
|
||||||
|
|
||||||
import { useFilterBlockActionProps } from '../../hooks/useFilterBlockActionProps';
|
|
||||||
import { useFilterFormCustomProps } from '../../hooks/useFilterFormCustomProps';
|
|
||||||
import { tval } from '../../locale';
|
|
||||||
import { FilterFormItem, FilterFormItemCustom, FilterItemCustomDesigner } from '../../schema-initializer';
|
|
||||||
import {
|
|
||||||
EditDefaultValue,
|
|
||||||
EditFormulaTitleField,
|
|
||||||
FilterVariableInput,
|
|
||||||
SetFilterScope,
|
|
||||||
useFormulaTitleVisible,
|
|
||||||
useSetFilterScopeVisible,
|
|
||||||
} from '../../schema-settings';
|
|
||||||
|
|
||||||
export class PluginExtendedFilterForm extends Plugin {
|
|
||||||
async load() {
|
|
||||||
this.app.addScopes({
|
|
||||||
useFilterBlockActionProps,
|
|
||||||
useFilterFormCustomProps,
|
|
||||||
});
|
|
||||||
this.app.addComponents({
|
|
||||||
FilterFormItem,
|
|
||||||
FilterFormItemCustom,
|
|
||||||
FilterItemCustomDesigner,
|
|
||||||
FilterVariableInput,
|
|
||||||
});
|
|
||||||
this.schemaSettingsManager.addItem('fieldSettings:component:Select', 'formulatitleField', {
|
|
||||||
Component: EditFormulaTitleField,
|
|
||||||
useVisible: useFormulaTitleVisible,
|
|
||||||
});
|
|
||||||
this.schemaSettingsManager.addItem('fieldSettings:component:Select', 'editDefaultValue', {
|
|
||||||
Component: EditDefaultValue,
|
|
||||||
});
|
|
||||||
const customItem = {
|
|
||||||
title: tval('Custom filter field'),
|
|
||||||
name: 'custom',
|
|
||||||
type: 'item',
|
|
||||||
Component: 'FilterFormItemCustom',
|
|
||||||
};
|
|
||||||
this.app.schemaInitializerManager.addItem('filterForm:configureFields', 'custom-item-divider', {
|
|
||||||
type: 'divider',
|
|
||||||
});
|
|
||||||
this.app.schemaInitializerManager.addItem('filterForm:configureFields', customItem.name, customItem);
|
|
||||||
|
|
||||||
this.schemaSettingsManager.addItem('ActionSettings', 'Customize.setFilterScope', {
|
|
||||||
Component: SetFilterScope,
|
|
||||||
useVisible: useSetFilterScopeVisible,
|
|
||||||
useComponentProps() {
|
|
||||||
const collection = useCollection();
|
|
||||||
return {
|
|
||||||
collectionName: collection.name,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
import {
|
|
||||||
findFilterTargets,
|
|
||||||
mergeFilter,
|
|
||||||
transformToFilter,
|
|
||||||
useCollection_deprecated,
|
|
||||||
useCollectionManager_deprecated,
|
|
||||||
useFilterBlock,
|
|
||||||
} from '@tachybase/client';
|
|
||||||
import { isEmpty, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
|
||||||
|
|
||||||
import flat from 'flat';
|
|
||||||
|
|
||||||
import { hasDuplicateKeys } from '../utils';
|
|
||||||
|
|
||||||
export const removeNullCondition = (filter, fieldSchema?) => {
|
|
||||||
const filterSchema = fieldSchema ? fieldSchema['x-filter-rules'] : '';
|
|
||||||
const filterSchemaItem = flat(filterSchema || '');
|
|
||||||
const items = flat(filter || {});
|
|
||||||
const values = {};
|
|
||||||
const isCustomFilter = filterSchema?.$and?.length || filterSchema?.$or?.length;
|
|
||||||
const isFilterCustom = isCustomFilter ? hasDuplicateKeys(items, filterSchemaItem) : false;
|
|
||||||
if (!isFilterCustom) {
|
|
||||||
if (isCustomFilter) {
|
|
||||||
for (const filterKey in filterSchemaItem) {
|
|
||||||
const match = filterSchemaItem[filterKey]?.slice(11, -2);
|
|
||||||
const collection = match?.split('.')[0];
|
|
||||||
const filterItems = Object.keys(items).filter((item) => item.includes(collection))[0];
|
|
||||||
if (filterItems) {
|
|
||||||
filterSchemaItem[filterKey] = items[filterItems];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const item in items) {
|
|
||||||
if (!item.includes('custom')) {
|
|
||||||
values[item] = items[item];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const item in filterSchemaItem) {
|
|
||||||
if (filterSchemaItem[item].includes('$nFilter')) {
|
|
||||||
delete filterSchemaItem[item];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const flatValue = flat.unflatten(values);
|
|
||||||
const flatFieldSchema = flat.unflatten(filterSchemaItem);
|
|
||||||
flatValue['$and'] = flatValue['$and']?.filter(Boolean);
|
|
||||||
flatFieldSchema['$and'] = flatFieldSchema['$and']?.filter(Boolean);
|
|
||||||
return {
|
|
||||||
$and: [flatValue, flatFieldSchema],
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
for (const key in items) {
|
|
||||||
const value = items[key];
|
|
||||||
if (!key.includes('custom') && value != null && !isEmpty(value)) {
|
|
||||||
values[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flat.unflatten(values);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return flat.unflatten(items);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFilterBlockActionProps = () => {
|
|
||||||
const form = useForm();
|
|
||||||
const actionField = useField();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const { getDataBlocks } = useFilterBlock();
|
|
||||||
const { name } = useCollection_deprecated();
|
|
||||||
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
|
||||||
|
|
||||||
actionField.data = actionField.data || {};
|
|
||||||
|
|
||||||
return {
|
|
||||||
async onClick() {
|
|
||||||
const { targets = [], uid } = findFilterTargets(fieldSchema);
|
|
||||||
|
|
||||||
actionField.data.loading = true;
|
|
||||||
try {
|
|
||||||
// 收集 filter 的值
|
|
||||||
await Promise.all(
|
|
||||||
getDataBlocks().map(async (block) => {
|
|
||||||
const target = targets.find((target) => target.uid === block.uid);
|
|
||||||
if (!target) return;
|
|
||||||
const param = block.service.params?.[0] || {};
|
|
||||||
for (const key in form.values) {
|
|
||||||
if (
|
|
||||||
(typeof form.values[key] === 'object' &&
|
|
||||||
(JSON.stringify(form.values[key]) === '{}' || JSON.stringify(form.values[key]) === '[]')) ||
|
|
||||||
!form.values[key]
|
|
||||||
) {
|
|
||||||
delete form.values[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 保留原有的 filter
|
|
||||||
const storedFilter = block.service.params?.[1]?.filters || {};
|
|
||||||
storedFilter[uid] = removeNullCondition(
|
|
||||||
transformToFilter(form.values, fieldSchema, getCollectionJoinField, name),
|
|
||||||
fieldSchema,
|
|
||||||
);
|
|
||||||
if (block.defaultFilter) {
|
|
||||||
getDataBlocks().forEach((getblock) => {
|
|
||||||
if (getblock.uid !== block.uid && getblock.collection.name === block.collection.name) {
|
|
||||||
getblock['defaultFilter'] = block.defaultFilter;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const mergedFilter = mergeFilter([
|
|
||||||
...Object.values(storedFilter).map((filter) => removeNullCondition(filter, fieldSchema)),
|
|
||||||
block.defaultFilter,
|
|
||||||
]);
|
|
||||||
return block.doFilter(
|
|
||||||
{
|
|
||||||
...param,
|
|
||||||
page: 1,
|
|
||||||
filter: mergedFilter,
|
|
||||||
},
|
|
||||||
{ filters: storedFilter },
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
actionField.data.loading = false;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
actionField.data.loading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,4 +1,4 @@
|
|||||||
import { EditTitleField, Plugin } from '@tachybase/client';
|
import { Plugin, useFormulaTitleVisible } from '@tachybase/client';
|
||||||
import { CodeMirror } from '@tachybase/components';
|
import { CodeMirror } from '@tachybase/components';
|
||||||
import { autorun, isValid, useFieldSchema } from '@tachybase/schema';
|
import { autorun, isValid, useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
@ -18,10 +18,8 @@ import { PluginAssistant } from './features/assistant';
|
|||||||
import { PluginGroupBlock } from './features/block-group';
|
import { PluginGroupBlock } from './features/block-group';
|
||||||
import { PluginContextMenu } from './features/context-menu';
|
import { PluginContextMenu } from './features/context-menu';
|
||||||
import { PluginCustomComponents } from './features/custom-components';
|
import { PluginCustomComponents } from './features/custom-components';
|
||||||
import { PluginDemo } from './features/demo';
|
|
||||||
import { DepartmentsPlugin } from './features/departments';
|
import { DepartmentsPlugin } from './features/departments';
|
||||||
import { EmbedPlugin } from './features/embed';
|
import { EmbedPlugin } from './features/embed';
|
||||||
import { PluginExtendedFilterForm } from './features/extended-filter-form';
|
|
||||||
import { PluginFieldAppends } from './features/field-appends';
|
import { PluginFieldAppends } from './features/field-appends';
|
||||||
import { PluginHeraVersion } from './features/hera-version';
|
import { PluginHeraVersion } from './features/hera-version';
|
||||||
import { PluginOutbound } from './features/outbound';
|
import { PluginOutbound } from './features/outbound';
|
||||||
@ -45,14 +43,7 @@ import { AutoComplete } from './schema-components';
|
|||||||
import AssociationCascader from './schema-components/association-cascader/AssociationCascader';
|
import AssociationCascader from './schema-components/association-cascader/AssociationCascader';
|
||||||
import { CreateSubmitActionInitializer, SettingBlockInitializer } from './schema-initializer';
|
import { CreateSubmitActionInitializer, SettingBlockInitializer } from './schema-initializer';
|
||||||
import { useCreateActionProps } from './schema-initializer/actions/hooks/useCreateActionProps';
|
import { useCreateActionProps } from './schema-initializer/actions/hooks/useCreateActionProps';
|
||||||
import {
|
import { EditTitle, IsTablePageSize, PageModeSetting, usePaginationVisible } from './schema-settings';
|
||||||
EditFormulaTitleField,
|
|
||||||
EditTitle,
|
|
||||||
IsTablePageSize,
|
|
||||||
PageModeSetting,
|
|
||||||
useFormulaTitleVisible,
|
|
||||||
usePaginationVisible,
|
|
||||||
} from './schema-settings';
|
|
||||||
import { SchemaSettingsDatePickerType } from './schema-settings/SchemaSettingsDatePickerType';
|
import { SchemaSettingsDatePickerType } from './schema-settings/SchemaSettingsDatePickerType';
|
||||||
import {
|
import {
|
||||||
SchemaSettingsDatePresets,
|
SchemaSettingsDatePresets,
|
||||||
@ -77,7 +68,6 @@ export class PluginCoreClient extends Plugin {
|
|||||||
await this.app.pm.add(PluginContextMenu);
|
await this.app.pm.add(PluginContextMenu);
|
||||||
await this.app.pm.add(PluginAssistant);
|
await this.app.pm.add(PluginAssistant);
|
||||||
await this.app.pm.add(PluginPDF);
|
await this.app.pm.add(PluginPDF);
|
||||||
await this.app.pm.add(PluginExtendedFilterForm);
|
|
||||||
await this.app.pm.add(PluginOutbound);
|
await this.app.pm.add(PluginOutbound);
|
||||||
// await this.app.pm.add(PluginModeHighlight);
|
// await this.app.pm.add(PluginModeHighlight);
|
||||||
await this.app.pm.add(PluginFieldAppends);
|
await this.app.pm.add(PluginFieldAppends);
|
||||||
@ -108,10 +98,6 @@ export class PluginCoreClient extends Plugin {
|
|||||||
return v1 || v2;
|
return v1 || v2;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.schemaSettingsManager.addItem('FormItemSettings', 'formulatitleField', {
|
|
||||||
Component: EditFormulaTitleField,
|
|
||||||
useVisible: useFormulaTitleVisible,
|
|
||||||
});
|
|
||||||
this.schemaSettingsManager.addItem('FormItemSettings', 'isTablePageSize', {
|
this.schemaSettingsManager.addItem('FormItemSettings', 'isTablePageSize', {
|
||||||
Component: IsTablePageSize,
|
Component: IsTablePageSize,
|
||||||
useVisible: usePaginationVisible,
|
useVisible: usePaginationVisible,
|
||||||
@ -147,7 +133,6 @@ export class PluginCoreClient extends Plugin {
|
|||||||
CustomComponentStub,
|
CustomComponentStub,
|
||||||
CustomField,
|
CustomField,
|
||||||
EditTitle,
|
EditTitle,
|
||||||
EditTitleField,
|
|
||||||
Expression,
|
Expression,
|
||||||
PageLayout,
|
PageLayout,
|
||||||
SettingBlock: SettingBlockInitializer,
|
SettingBlock: SettingBlockInitializer,
|
||||||
|
@ -10,7 +10,7 @@ import { fuzzysearch } from '../../utils';
|
|||||||
export const AutoComplete = connect((props) => {
|
export const AutoComplete = connect((props) => {
|
||||||
const { fieldNames, params: fieldFilter } = props;
|
const { fieldNames, params: fieldFilter } = props;
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const targetKey = fieldNames.value;
|
const targetKey = fieldNames?.value;
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const [defultOptions, setDefultOptions] = useState([]);
|
const [defultOptions, setDefultOptions] = useState([]);
|
||||||
const [options, setOptions] = useState([]);
|
const [options, setOptions] = useState([]);
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
export * from './items/CustomFilterFormItemInitializer';
|
|
||||||
export * from './actions/CreateSubmitActionInitializer';
|
export * from './actions/CreateSubmitActionInitializer';
|
||||||
export * from './blocks/SettingBlockInitializer';
|
export * from './blocks/SettingBlockInitializer';
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
import React, { FC } from 'react';
|
|
||||||
import { SchemaSettingsItem, useFormActiveFields, useSchemaSettings } from '@tachybase/client';
|
|
||||||
import { Field, ISchema, useField, useFieldSchema, useForm } from '@tachybase/schema';
|
|
||||||
|
|
||||||
import { App, ModalFuncProps } from 'antd';
|
|
||||||
|
|
||||||
import { useTranslation } from '../locale';
|
|
||||||
|
|
||||||
export interface SchemaSettingsRemoveProps {
|
|
||||||
confirm?: ModalFuncProps;
|
|
||||||
removeParentsIfNoChildren?: boolean;
|
|
||||||
breakRemoveOn?: ISchema | ((s: ISchema) => boolean);
|
|
||||||
}
|
|
||||||
export const SchemaSettingsRemove: FC<SchemaSettingsRemoveProps> = (props) => {
|
|
||||||
const { confirm, removeParentsIfNoChildren, breakRemoveOn } = props;
|
|
||||||
const { dn, template } = useSchemaSettings();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const form = useForm();
|
|
||||||
const { modal } = App.useApp();
|
|
||||||
const { removeActiveFieldName } = useFormActiveFields() || {};
|
|
||||||
return (
|
|
||||||
<SchemaSettingsItem
|
|
||||||
title="Delete"
|
|
||||||
eventKey="remove"
|
|
||||||
onClick={() => {
|
|
||||||
modal.confirm({
|
|
||||||
title: t('Delete block'),
|
|
||||||
content: t('Are you sure you want to delete it?'),
|
|
||||||
...confirm,
|
|
||||||
async onOk() {
|
|
||||||
const options = {
|
|
||||||
removeParentsIfNoChildren,
|
|
||||||
breakRemoveOn,
|
|
||||||
};
|
|
||||||
const name = fieldSchema.name as string;
|
|
||||||
const fieldName = name.split('.')[1];
|
|
||||||
const title = fieldSchema.title;
|
|
||||||
if (field?.required) {
|
|
||||||
field.required = false;
|
|
||||||
fieldSchema['required'] = false;
|
|
||||||
}
|
|
||||||
await dn.remove(null, options);
|
|
||||||
await confirm?.onOk?.();
|
|
||||||
if (form.values['custom']) {
|
|
||||||
delete form.values['custom'][fieldName];
|
|
||||||
}
|
|
||||||
for (const key in form.fields) {
|
|
||||||
if (key.includes(name) && form.fields[key].title === title) {
|
|
||||||
delete form.fields[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
removeActiveFieldName?.(fieldSchema.name as string);
|
|
||||||
if (field?.setInitialValue && field?.reset) {
|
|
||||||
field.setInitialValue(null);
|
|
||||||
field.reset();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Delete')}
|
|
||||||
</SchemaSettingsItem>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,23 +1,14 @@
|
|||||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
getShouldChange,
|
getShouldChange,
|
||||||
SchemaComponent,
|
SchemaComponent,
|
||||||
SchemaSettingsModalItem,
|
SchemaSettingsModalItem,
|
||||||
SchemaSettingsSelectItem,
|
|
||||||
SchemaSettingsSwitchItem,
|
SchemaSettingsSwitchItem,
|
||||||
useCollection_deprecated,
|
useCollection_deprecated,
|
||||||
useCollectionManager,
|
|
||||||
useCollectionManager_deprecated,
|
useCollectionManager_deprecated,
|
||||||
useCompile,
|
|
||||||
useCurrentUserVariable,
|
useCurrentUserVariable,
|
||||||
useDatetimeVariable,
|
useDatetimeVariable,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
useFormBlockContext,
|
|
||||||
useFormBlockType,
|
|
||||||
useLocalVariables,
|
|
||||||
useRecord,
|
|
||||||
useSchemaTemplateManager,
|
|
||||||
useVariables,
|
|
||||||
VariableInput,
|
VariableInput,
|
||||||
VariableScopeProvider,
|
VariableScopeProvider,
|
||||||
} from '@tachybase/client';
|
} from '@tachybase/client';
|
||||||
@ -26,227 +17,13 @@ import { Field, ISchema, useField, useFieldSchema } from '@tachybase/schema';
|
|||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { FormFilterScope } from '../components/filter-form/FormFilterScope';
|
|
||||||
import { useTranslation } from '../locale';
|
import { useTranslation } from '../locale';
|
||||||
import { useFieldComponents } from '../schema-initializer';
|
|
||||||
|
|
||||||
export const useFormulaTitleOptions = () => {
|
|
||||||
const compile = useCompile();
|
|
||||||
const { getCollectionJoinField, getCollectionFields } = useCollectionManager_deprecated();
|
|
||||||
const { getField } = useCollection_deprecated();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const collectionManage = useCollectionManager_deprecated();
|
|
||||||
const collectionManageField = collectionManage.collections.filter(
|
|
||||||
(value) => value.name === fieldSchema['x-decorator-props'],
|
|
||||||
)[0];
|
|
||||||
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
|
||||||
let fields = [];
|
|
||||||
if (collectionField) {
|
|
||||||
fields = getCollectionFields(
|
|
||||||
collectionField
|
|
||||||
? collectionField.target
|
|
||||||
? collectionField.target
|
|
||||||
: collectionField.collectionName
|
|
||||||
: fieldSchema['name'],
|
|
||||||
);
|
|
||||||
} else if (collectionManageField) {
|
|
||||||
fields = collectionManageField['fields'];
|
|
||||||
}
|
|
||||||
const options = [];
|
|
||||||
fields?.forEach((field) => {
|
|
||||||
if (field.interface !== 'm2m') {
|
|
||||||
if (field.uiSchema) {
|
|
||||||
options.push({
|
|
||||||
label: compile(field.uiSchema.title),
|
|
||||||
value: field.name,
|
|
||||||
children:
|
|
||||||
getCollectionFields(field.target)
|
|
||||||
?.filter((subField) => subField.uiSchema)
|
|
||||||
.map((subField) => ({
|
|
||||||
label: subField.uiSchema ? compile(subField.uiSchema.title) : '',
|
|
||||||
value: subField.name,
|
|
||||||
})) ?? [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFormulaTitleVisible = () => {
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const options = useFormulaTitleOptions();
|
|
||||||
// FIXME 这里现在只有当设置为 select,默认为 select 的时候看不到
|
|
||||||
return (
|
|
||||||
options.length > 0 &&
|
|
||||||
(fieldSchema['x-component-props']?.mode === 'Select' || fieldSchema['x-component'] === 'CollectionField') &&
|
|
||||||
fieldSchema['x-component-props']?.fieldNames?.value !== undefined
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EditFormulaTitleField = () => {
|
|
||||||
const { getCollectionJoinField, collections } = useCollectionManager_deprecated();
|
|
||||||
const { getField } = useCollection_deprecated();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { dn } = useDesignable();
|
|
||||||
|
|
||||||
let collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
|
||||||
collectionField = collectionField
|
|
||||||
? collectionField
|
|
||||||
: collections.find((value) => value.name === fieldSchema['x-decorator-props'])?.fields;
|
|
||||||
const options = useFormulaTitleOptions();
|
|
||||||
const editTitle = async (formula) => {
|
|
||||||
const schema = {
|
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
|
||||||
};
|
|
||||||
const fieldNames = {
|
|
||||||
...collectionField?.uiSchema?.['x-component-props']?.['fieldNames'],
|
|
||||||
...field.componentProps.fieldNames,
|
|
||||||
formula,
|
|
||||||
};
|
|
||||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
|
||||||
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
|
||||||
schema['x-component-props'] = fieldSchema['x-component-props'];
|
|
||||||
field.componentProps.fieldNames = fieldSchema['x-component-props'].fieldNames;
|
|
||||||
dn.emit('patch', {
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
dn.refresh();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SchemaSettingsModalItem
|
|
||||||
key="edit-field-title"
|
|
||||||
title={t('Custom option label')}
|
|
||||||
schema={
|
|
||||||
{
|
|
||||||
type: 'object',
|
|
||||||
title: t('Custom option label'),
|
|
||||||
properties: {
|
|
||||||
formula: {
|
|
||||||
required: true,
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Variable.TextArea',
|
|
||||||
'x-component-props': {
|
|
||||||
scope: options,
|
|
||||||
},
|
|
||||||
default: field?.componentProps?.fieldNames?.formula || '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as ISchema
|
|
||||||
}
|
|
||||||
onSubmit={({ formula }) => {
|
|
||||||
if (formula) {
|
|
||||||
editTitle(formula);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
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={({ default: { value } }) => {
|
|
||||||
field.setValue(value);
|
|
||||||
fieldSchema['default'] = value;
|
|
||||||
fieldSchema['x-component-props']['defaultValue'] = value;
|
|
||||||
dn.emit('patch', {
|
|
||||||
schema: {
|
|
||||||
'x-uid': fieldSchema['x-uid'],
|
|
||||||
['x-component-props']: fieldSchema['x-component-props'],
|
|
||||||
default: fieldSchema.default,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
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 = () => {
|
export const usePaginationVisible = () => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
return fieldSchema['x-component-props']?.mode === 'SubTable';
|
return fieldSchema['x-component-props']?.mode === 'SubTable';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSetFilterScopeVisible = () => {
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
return (
|
|
||||||
fieldSchema['x-component-props']?.useProps === '{{ useFilterBlockActionProps }}' ||
|
|
||||||
fieldSchema['x-use-component-props'] === 'useFilterBlockActionProps'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EditTitle = () => {
|
export const EditTitle = () => {
|
||||||
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
||||||
const { getField } = useCollection_deprecated();
|
const { getField } = useCollection_deprecated();
|
||||||
@ -294,64 +71,6 @@ export const EditTitle = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditTitleField = () => {
|
|
||||||
const { getCollectionFields, getCollectionJoinField } = useCollectionManager_deprecated();
|
|
||||||
const { getField } = useCollection_deprecated();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { dn } = useDesignable();
|
|
||||||
const compile = useCompile();
|
|
||||||
const collectionManage = useCollectionManager_deprecated();
|
|
||||||
const isCustomFilterItem = ((fieldSchema?.name as string) ?? '').startsWith('custom.');
|
|
||||||
const collectionManageField = isCustomFilterItem
|
|
||||||
? collectionManage.collections.filter((value) => value.name === fieldSchema['x-decorator-props'])[0]
|
|
||||||
: {};
|
|
||||||
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
|
|
||||||
let targetFields = [];
|
|
||||||
if (collectionField) {
|
|
||||||
targetFields = collectionField?.target
|
|
||||||
? getCollectionFields(collectionField?.target)
|
|
||||||
: getCollectionFields(collectionField?.targetCollection) ?? [];
|
|
||||||
} else if (collectionManageField) {
|
|
||||||
targetFields = collectionManageField['fields'];
|
|
||||||
}
|
|
||||||
const options = targetFields
|
|
||||||
.filter((field) => !field?.target && field.type !== 'boolean')
|
|
||||||
.map((field) => ({
|
|
||||||
value: field?.name,
|
|
||||||
label: compile(field?.uiSchema?.title) || field?.name,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return options.length > 0 && (fieldSchema['x-component'] === 'CollectionField' || isCustomFilterItem) ? (
|
|
||||||
<SchemaSettingsSelectItem
|
|
||||||
key="title-field"
|
|
||||||
title={t('Title field')}
|
|
||||||
options={options}
|
|
||||||
value={field?.componentProps?.fieldNames?.label}
|
|
||||||
onChange={(label) => {
|
|
||||||
const schema = {
|
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
|
||||||
};
|
|
||||||
const fieldNames = {
|
|
||||||
...collectionField?.uiSchema?.['x-component-props']?.['fieldNames'],
|
|
||||||
...field.componentProps.fieldNames,
|
|
||||||
label,
|
|
||||||
value: label,
|
|
||||||
};
|
|
||||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
|
||||||
fieldSchema['x-component-props']['fieldNames'] = fieldNames;
|
|
||||||
schema['x-component-props'] = fieldSchema['x-component-props'];
|
|
||||||
field.componentProps.fieldNames = fieldSchema['x-component-props'].fieldNames;
|
|
||||||
dn.emit('patch', {
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
dn.refresh();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const IsTablePageSize = () => {
|
export const IsTablePageSize = () => {
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
@ -382,141 +101,6 @@ export const IsTablePageSize = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const findGridSchema = (fieldSchema) => {
|
|
||||||
return fieldSchema.reduceProperties((buf, s) => {
|
|
||||||
if (s['x-component'] === 'FormV2') {
|
|
||||||
const f = s.reduceProperties((buf, s) => {
|
|
||||||
if (s['x-component'] === 'Grid' || s['x-component'] === 'BlockTemplate') {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}, null);
|
|
||||||
if (f) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useCollectionFilterOptions = (collectionName: string) => {
|
|
||||||
const { getCollectionFields, getInterface } = useCollectionManager_deprecated();
|
|
||||||
const fields = getCollectionFields(collectionName);
|
|
||||||
const field2option = (field, depth) => {
|
|
||||||
if (!field.interface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const fieldInterface = getInterface(field.interface);
|
|
||||||
if (!fieldInterface?.filterable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { nested, children, operators } = fieldInterface.filterable;
|
|
||||||
const option = {
|
|
||||||
name: field.name,
|
|
||||||
title: field?.uiSchema?.title || field.name,
|
|
||||||
schema: field?.uiSchema,
|
|
||||||
operators:
|
|
||||||
operators?.filter?.((operator) => {
|
|
||||||
return !operator?.visible || operator.visible(field);
|
|
||||||
}) || [],
|
|
||||||
interface: field.interface,
|
|
||||||
};
|
|
||||||
if (field.target && depth > 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (depth > 2) {
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
if (children?.length) {
|
|
||||||
option['children'] = children;
|
|
||||||
}
|
|
||||||
if (nested) {
|
|
||||||
const targetFields = getCollectionFields(field.target);
|
|
||||||
const options = getOptions(targetFields, depth + 1).filter(Boolean);
|
|
||||||
option['children'] = option['children'] || [];
|
|
||||||
option['children'].push(...options);
|
|
||||||
}
|
|
||||||
return option;
|
|
||||||
};
|
|
||||||
const getOptions = (fields, depth) => {
|
|
||||||
const options = [];
|
|
||||||
fields.forEach((field) => {
|
|
||||||
const option = field2option(field, depth);
|
|
||||||
if (option) {
|
|
||||||
options.push(option);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
const options = getOptions(fields, 1);
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SetFilterScope = (props) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const fields = field.form.fields;
|
|
||||||
const { collectionName } = props;
|
|
||||||
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
|
||||||
const { form } = useFormBlockContext();
|
|
||||||
const type = props?.type || ['Action', 'Action.Link'].includes(fieldSchema['x-component']) ? 'button' : 'field';
|
|
||||||
const variables = useVariables();
|
|
||||||
const localVariables = useLocalVariables();
|
|
||||||
const record = useRecord();
|
|
||||||
const { type: formBlockType } = useFormBlockType();
|
|
||||||
const schema = useMemo<ISchema>(
|
|
||||||
() => ({
|
|
||||||
type: 'object',
|
|
||||||
title: t('Custom filter'),
|
|
||||||
properties: {
|
|
||||||
fieldReaction: {
|
|
||||||
'x-component': FormFilterScope,
|
|
||||||
'x-component-props': {
|
|
||||||
useProps: () => {
|
|
||||||
const options = useCollectionFilterOptions(collectionName);
|
|
||||||
return {
|
|
||||||
options,
|
|
||||||
defaultValues: gridSchema?.['x-filter-rules'] || fieldSchema?.['x-filter-rules'],
|
|
||||||
type,
|
|
||||||
collectionName,
|
|
||||||
form,
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
record,
|
|
||||||
formBlockType,
|
|
||||||
fields,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
const { getTemplateById } = useSchemaTemplateManager();
|
|
||||||
const { dn } = useDesignable();
|
|
||||||
const onSubmit = useCallback(
|
|
||||||
(v) => {
|
|
||||||
const rules = v.fieldReaction.condition;
|
|
||||||
const templateId = gridSchema['x-component'] === 'BlockTemplate' && gridSchema['x-component-props'].templateId;
|
|
||||||
const uid = (templateId && getTemplateById(templateId).uid) || gridSchema['x-uid'];
|
|
||||||
const schema = {
|
|
||||||
['x-uid']: uid,
|
|
||||||
};
|
|
||||||
|
|
||||||
gridSchema['x-filter-rules'] = rules;
|
|
||||||
schema['x-filter-rules'] = rules;
|
|
||||||
dn.emit('patch', {
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
dn.refresh();
|
|
||||||
},
|
|
||||||
[dn, getTemplateById, gridSchema],
|
|
||||||
);
|
|
||||||
return <SchemaSettingsModalItem title={t('Custom filter')} width={770} schema={schema} onSubmit={onSubmit} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 添加跳转页面选项
|
// 添加跳转页面选项
|
||||||
export const PageModeSetting = () => {
|
export const PageModeSetting = () => {
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
@ -540,74 +124,3 @@ export const PageModeSetting = () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
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) => {
|
|
||||||
field.component = mode;
|
|
||||||
fieldSchema['x-component'] = mode;
|
|
||||||
void dn.emit('patch', {
|
|
||||||
schema: {
|
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
|
||||||
['x-component']: fieldSchema['x-component'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
dn.refresh();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SchemaSettingCollection = () => {
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const collections = useCollectionManager();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const options = collections?.dataSource['options']?.collections.map((value) => {
|
|
||||||
return {
|
|
||||||
label: value.title,
|
|
||||||
value: value.name,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const cm = useCollectionManager();
|
|
||||||
const { dn } = useDesignable();
|
|
||||||
return (
|
|
||||||
<SchemaSettingsSelectItem
|
|
||||||
key="component-field"
|
|
||||||
title="Edit Collection"
|
|
||||||
options={options}
|
|
||||||
value={fieldSchema['collectionName']}
|
|
||||||
onChange={(name) => {
|
|
||||||
field.setValue('');
|
|
||||||
const titleField = cm.getCollection(name).titleField;
|
|
||||||
fieldSchema['collectionName'] = name;
|
|
||||||
fieldSchema.default = '';
|
|
||||||
fieldSchema['x-component-props'] = {
|
|
||||||
...fieldSchema['x-component-props'],
|
|
||||||
fieldNames: {
|
|
||||||
label: titleField,
|
|
||||||
value: titleField,
|
|
||||||
},
|
|
||||||
defaultValue: '',
|
|
||||||
};
|
|
||||||
void dn.emit('patch', {
|
|
||||||
schema: {
|
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
|
||||||
collectionName: fieldSchema['collectionName'],
|
|
||||||
['x-component-props']: fieldSchema['x-component-props'],
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
dn.refresh();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user