feat: 多对多关系可以添加关联 (#1333)

Co-authored-by: sealday <zhanglin@daoyoucloud.com>
Reviewed-on: daoyoucloud/tachybase#1333
Reviewed-by: sealday <zhanglin@daoyoucloud.com>
Co-authored-by: wjh <wwwjh0710@163.com>
Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
wjh 2024-08-12 11:48:16 +08:00 committed by sealday
parent 9dc412dbf3
commit 27cda38a90
20 changed files with 291 additions and 86 deletions

View File

@ -29,7 +29,6 @@ export const SchemaInitializerItem = memo(
const childrenItems = useSchemaInitializerMenuItems(items, name, onClick);
const { componentCls, hashId } = useSchemaInitializerStyles();
const { attribute } = useAriaAttributeOfMenuItem();
const menuItems = useMemo(() => {
if (!(items && items.length > 0)) return undefined;
return [

View File

@ -1,14 +1,17 @@
import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';
import { createForm, RecursionField, Schema, useField, useFieldSchema } from '@tachybase/schema';
import { createForm, Form, Schema, useField } from '@tachybase/schema';
import { Spin } from 'antd';
import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps';
import { useCollection_deprecated } from '../collection-manager';
import { CollectionRecord, useCollectionParentRecordData, useCollectionRecord } from '../data-source';
import {
CollectionRecord,
useCollectionManager,
useCollectionParentRecordData,
useCollectionRecord,
} from '../data-source';
import { RecordProvider, useRecord } from '../record-provider';
import { useActionContext, useDesignable } from '../schema-component';
import { Templates as DataTemplateSelect } from '../schema-component/antd/form-v2/Templates';
import { useActionContext } from '../schema-component';
import { BlockProvider, useBlockRequestContext } from './BlockProvider';
import { FormActiveFieldsProvider } from './hooks/useFormActiveFields';
@ -29,8 +32,9 @@ export const FormBlockContext = createContext<{
FormBlockContext.displayName = 'FormBlockContext';
const InternalFormBlockProvider = (props) => {
const cm = useCollectionManager();
const ctx = useFormBlockContext();
const { action, readPretty, params, collection } = props;
const { action, readPretty, params, collection, association } = props;
const field = useField();
const form = useMemo(
() =>
@ -55,10 +59,23 @@ const InternalFormBlockProvider = (props) => {
resource,
updateAssociationValues,
formBlockRef,
collectionName: collection,
collectionName: collection || cm.getCollectionField(association)?.target,
formRecord: record,
};
}, [action, collection, ctx, field, form, params, record, resource, service, updateAssociationValues]);
}, [
action,
association,
cm,
collection,
ctx,
field,
form,
params,
record,
resource,
service,
updateAssociationValues,
]);
if (service.loading && Object.keys(form?.initialValues)?.length === 0 && action) {
return <Spin />;
@ -67,21 +84,24 @@ const InternalFormBlockProvider = (props) => {
return (
<FormBlockContext.Provider value={formBlockValue}>
<RecordProvider isNew={record?.isNew} parent={record?.parentRecord?.data} record={record?.data}>
<div ref={formBlockRef}>
<RenderChildrenWithDataTemplates form={form} />
</div>
<div ref={formBlockRef}>{props.children}</div>
</RecordProvider>
</FormBlockContext.Provider>
);
};
/**
* @internal
* update create
* @returns
*/
export const useFormBlockType = () => {
const ctx = useFormBlockContext() || {};
return { type: ctx.type } as { type: 'update' | 'create' };
const res = useMemo(() => {
return { type: ctx.type } as { type: 'update' | 'create' };
}, [ctx.type]);
return res;
};
export const useIsDetailBlock = () => {
@ -91,26 +111,8 @@ export const useIsDetailBlock = () => {
};
export const FormBlockProvider = withDynamicSchemaProps((props) => {
const record = useRecord();
const parentRecordData = useCollectionParentRecordData();
const { collection, isCusomeizeCreate, parentRecord } = props;
const { __collection } = record;
const currentCollection = useCollection_deprecated();
const { designable } = useDesignable();
const isDetailBlock = useIsDetailBlock();
let detailFlag = false;
if (isDetailBlock) {
detailFlag = true;
if (!designable && __collection) {
detailFlag = __collection === collection;
}
}
const createFlag =
(currentCollection.name === (collection?.name || collection) && !isDetailBlock) || !currentCollection.name;
if (!detailFlag && !createFlag && !isCusomeizeCreate) {
return null;
}
const { parentRecord } = props;
return (
<BlockProvider
@ -126,11 +128,18 @@ export const FormBlockProvider = withDynamicSchemaProps((props) => {
);
});
/**
* @internal
* @returns
*/
export const useFormBlockContext = () => {
return useContext(FormBlockContext);
};
export const useFormBlockProps = () => {
/**
* @internal
*/
export const useFormBlockProps = (shouldClearInitialValues = false) => {
const ctx = useFormBlockContext();
const record = useRecord();
const { fieldSchema } = useActionContext();
@ -154,19 +163,9 @@ export const useFormBlockProps = () => {
};
};
const RenderChildrenWithDataTemplates = ({ form }) => {
const FieldSchema = useFieldSchema();
const { findComponent } = useDesignable();
const field = useField();
const Component = findComponent(field.component?.[0]) || React.Fragment;
return (
<Component {...field.componentProps}>
<DataTemplateSelect style={{ marginBottom: 18 }} form={form} />
<RecursionField schema={FieldSchema} onlyRenderProperties />
</Component>
);
};
/**
* @internal
*/
export const findFormBlock = (schema: Schema) => {
while (schema) {
if (schema['x-decorator'] === 'FormBlockProvider') {

View File

@ -236,6 +236,9 @@ export const ACLActionProvider = (props) => {
if (!actionPath) {
return <>{props.children}</>;
}
if (!resource) {
return <>{props.children}</>;
}
const params = parseAction(actionPath, { schema, recordPkValue });
if (!params) {
return <ACLActionParamsContext.Provider value={params}>{props.children}</ACLActionParamsContext.Provider>;

View File

@ -1,6 +1,6 @@
import React, { createContext, FC, ReactNode, useContext } from 'react';
import { CollectionFieldProvider } from '../collection-field';
import { CollectionFieldProvider, useCollectionField } from '../collection-field';
import { CollectionDeletedPlaceholder } from '../components/CollectionDeletedPlaceholder';
import { Collection } from './Collection';
import { useCollectionManager } from './CollectionManagerProvider';
@ -42,3 +42,12 @@ export const AssociationProvider: FC<AssociationProviderProps> = (props) => {
</CollectionProvider>
);
};
/**
* users.roles
* @returns
*/
export const useAssociationName = () => {
const field = useCollectionField();
return field ? `${field.collectionName}.${field.name}` : null;
};

View File

@ -0,0 +1,68 @@
import { Field, useField, useFieldSchema } from '@tachybase/schema';
import _ from 'lodash';
import { useTranslation } from 'react-i18next';
import type { SchemaSettingsItemType } from '../../application';
import { useColumnSchema, useCompile, useDesignable } from '../../schema-component';
import { useCollectionField } from '../collection-field/CollectionFieldProvider';
import { useDataSourceManager } from '../data-source/DataSourceManagerProvider';
export const fieldComponentSettingsItem: SchemaSettingsItemType = {
name: 'fieldComponent',
type: 'select',
useVisible() {
const collectionField = useCollectionField();
const dm = useDataSourceManager();
if (!collectionField) return false;
const collectionInterface = dm.collectionFieldInterfaceManager.getFieldInterface(collectionField?.interface) as any;
return (
Array.isArray(collectionInterface?.componentOptions) &&
collectionInterface.componentOptions.length > 1 &&
collectionInterface.componentOptions.filter((item) => !item.useVisible || item.useVisible()).length > 1
);
},
useComponentProps() {
const { t } = useTranslation();
const field = useField<Field>();
const schema = useFieldSchema();
const collectionField = useCollectionField();
const dm = useDataSourceManager();
const collectionInterface = dm.collectionFieldInterfaceManager.getFieldInterface(collectionField?.interface);
const { fieldSchema: tableColumnSchema } = useColumnSchema();
const fieldSchema = tableColumnSchema || schema;
const { dn } = useDesignable();
const compile = useCompile();
const options =
collectionInterface?.componentOptions
?.filter((item) => !item.useVisible || item.useVisible())
?.map((item) => {
return {
label: compile(item.label),
value: item.value,
useProps: item.useProps,
};
}) || [];
return {
title: t('Field component'),
options,
value: fieldSchema['x-component-props']?.['component'] || options[0]?.value,
onChange(component) {
const componentOptions = options.find((item) => item.value === component);
const componentProps = {
component,
...(componentOptions?.useProps?.() || {}),
};
_.set(fieldSchema, 'x-component-props', componentProps);
field.componentProps = componentProps;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-component-props': componentProps,
},
});
},
};
},
};

View File

@ -0,0 +1 @@
export * from './fieldComponent';

View File

@ -7,3 +7,4 @@ export * from './data-block';
export * from './data-source';
export * from './collection-record';
export * from './utils';
export * from './commonsSettingsItem';

View File

@ -836,5 +836,6 @@
"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"
"Test Data":"Test Data",
"Add associations": "Add associations"
}

View File

@ -32,7 +32,10 @@ export const CreateActionInitializer = () => {
type: 'void',
'x-component': 'Tabs',
'x-component-props': {},
'x-initializer': 'TabPaneInitializersForCreateFormBlock',
'x-initializer': 'popup:addTab',
'x-initializer-props': {
gridInitializer: 'popup:addNew:addBlock',
},
properties: {
tab1: {
type: 'void',

View File

@ -1,4 +1,7 @@
import { useTranslation } from 'react-i18next';
import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection } from '../../../data-source/collection/CollectionProvider';
import { gridRowColWrap } from '../../../schema-initializer/utils';
/**
@ -48,13 +51,36 @@ export const createFormBlockInitializers = new CompatibleSchemaInitializer(
type: 'itemGroup',
title: '{{t("Data blocks")}}',
name: 'dataBlocks',
children: [
{
name: 'form',
title: '{{t("Form")}}',
Component: 'CreateFormBlockInitializer',
},
],
useChildren() {
const currentCollection = useCollection();
const { t } = useTranslation();
return [
{
name: 'form',
title: '{{t("Form")}}',
Component: 'FormBlockInitializer',
collectionName: currentCollection.name,
dataSource: currentCollection.dataSource,
componentProps: {
filterCollections({ collection, associationField }) {
if (associationField) {
return false;
}
if (collection.name === currentCollection.name) {
return true;
}
},
showAssociationFields: true,
onlyCurrentDataSource: true,
hideSearch: true,
componentType: 'FormItem',
currentText: t('Current collection'),
otherText: t('Other collections'),
},
},
];
},
},
{
type: 'itemGroup',

View File

@ -26,7 +26,7 @@ export const ViewActionInitializer = (props) => {
type: 'void',
'x-component': 'Tabs',
'x-component-props': {},
'x-initializer': 'TabPaneInitializers',
'x-initializer': 'popup:addTab',
properties: {
tab1: {
type: 'void',

View File

@ -5,6 +5,7 @@ import { FormOutlined } from '@ant-design/icons';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { useBlockAssociationContext } from '../../../../block-provider';
import { useCollection_deprecated } from '../../../../collection-manager';
import { useAssociationName, useCollectionManager } from '../../../../data-source';
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
import { useSchemaTemplateManager } from '../../../../schema-templates';
import { createDetailsUISchema } from './createDetailsUISchema';
@ -29,8 +30,7 @@ export const RecordReadPrettyFormBlockInitializer = () => {
export function useCreateSingleDetailsSchema() {
const { insert } = useSchemaInitializer();
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
const association = useBlockAssociationContext();
const association = useAssociationName();
const templateWrap = useCallback(
(templateSchema, options) => {
const { item } = options;
@ -38,7 +38,7 @@ export function useCreateSingleDetailsSchema() {
const blockSchema = createDetailsUISchema(
association
? {
association,
association: association,
dataSource: item.dataSource,
templateSchema: templateSchema,
isCurrent: true,

View File

@ -3,6 +3,7 @@ import React, { useCallback } from 'react';
import { FormOutlined } from '@ant-design/icons';
import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { useAssociationName } from '../../../../data-source/collection/AssociationProvider';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { createCreateFormBlockUISchema } from './createCreateFormBlockUISchema';
@ -17,6 +18,8 @@ export const FormBlockInitializer = ({
showAssociationFields,
hideChildrenIfSingleCollection,
hideOtherRecordsInPopup,
currentText,
otherText,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
@ -40,6 +43,10 @@ export const FormBlockInitializer = ({
* Other records
*/
hideOtherRecordsInPopup?: boolean;
/** 用于更改 Current record 的文案 */
currentText?: string;
/** 用于更改 Other records 的文案 */
otherText?: string;
}) => {
const itemConfig = useSchemaInitializerItem();
const { createFormBlock, templateWrap } = useCreateFormBlock();
@ -73,24 +80,47 @@ export const FormBlockInitializer = ({
showAssociationFields={showAssociationFields}
hideChildrenIfSingleCollection={hideChildrenIfSingleCollection}
hideOtherRecordsInPopup={hideOtherRecordsInPopup}
currentText={currentText}
otherText={otherText}
/>
);
};
export const useCreateFormBlock = () => {
const { insert } = useSchemaInitializer();
const itemConfig = useSchemaInitializerItem();
const { isCusomeizeCreate: isCustomizeCreate } = itemConfig;
const association = useAssociationName();
const { isCusomeizeCreate: isCustomizeCreate } = useSchemaInitializerItem();
const createFormBlock = ({ item }) => {
insert(
createCreateFormBlockUISchema({
collectionName: item.collectionName || item.name,
dataSource: item.dataSource,
isCusomeizeCreate: isCustomizeCreate,
}),
);
};
const createFormBlock = useCallback(
({ item, fromOthersInPopup }) => {
if (fromOthersInPopup) {
insert(
createCreateFormBlockUISchema({
collectionName: item.collectionName || item.name,
dataSource: item.dataSource,
isCusomeizeCreate: true,
}),
);
} else {
insert(
createCreateFormBlockUISchema(
association
? {
association,
dataSource: item.dataSource,
isCusomeizeCreate: isCustomizeCreate,
}
: {
collectionName: item.collectionName || item.name,
dataSource: item.dataSource,
isCusomeizeCreate: isCustomizeCreate,
},
),
);
}
},
[association, insert, isCustomizeCreate],
);
const templateWrap = (templateSchema, { item }) => {
const schema = createCreateFormBlockUISchema({

View File

@ -1,10 +1,12 @@
import React, { useCallback } from 'react';
import { useFieldSchema } from '@tachybase/schema';
import { FormOutlined } from '@ant-design/icons';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { useBlockAssociationContext } from '../../../../block-provider';
import { useCollection_deprecated } from '../../../../collection-manager';
import { useAssociationName } from '../../../../data-source';
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
import { useSchemaTemplateManager } from '../../../../schema-templates';
import { createEditFormBlockUISchema } from './createEditFormBlockUISchema';
@ -41,10 +43,10 @@ export const RecordFormBlockInitializer = () => {
export function useCreateEditFormBlock() {
const { insert } = useSchemaInitializer();
const association = useBlockAssociationContext();
const association = useAssociationName();
const createEditFormBlock = useCallback(
({ item }) => {
const collectionName = item.collectionName || item.name;
if (!association && item.associationField) {
const field = item.associationField;
insert(
@ -63,7 +65,7 @@ export function useCreateEditFormBlock() {
isCurrent: true,
}
: {
collectionName: item.collectionName || item.name,
collectionName,
dataSource: item.dataSource,
},
),

View File

@ -1,7 +1,19 @@
import React from 'react';
import _ from 'lodash';
import { GridRowContext } from '../../../../schema-component';
import { SchemaToolbar } from '../../../../schema-settings';
export const TableColumnSchemaToolbar = (props) => {
return <SchemaToolbar initializer={false} showBorder={false} showBackground {...props} />;
return (
<GridRowContext.Provider value={null}>
<SchemaToolbar
initializer={props.initializer || false}
showBorder={false}
showBackground
{..._.omit(props, 'initializer')}
/>
</GridRowContext.Provider>
);
};

View File

@ -15,7 +15,7 @@ export const createTableBlockUISchema = (options: {
return {
type: 'void',
'x-decorator': 'TableBlockProvider',
'x-acl-action': `${collectionName}:list`,
'x-acl-action': `${association || collectionName}:list`,
'x-use-decorator-props': 'useTableBlockDecoratorProps',
'x-decorator-props': {
collection: collectionName,
@ -63,8 +63,16 @@ export const createTableBlockUISchema = (options: {
'x-action-column': 'actions',
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-component-props': {
width: 150,
fixed: 'right',
},
'x-toolbar': 'TableColumnSchemaToolbar',
'x-initializer': 'table:configureItemActions',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-toolbar-props': {
initializer: 'table:configureItemActions',
},
properties: {
[uid()]: {
type: 'void',

View File

@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next';
import { useApp } from '../../../../application';
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
import { useCollectionManager_deprecated } from '../../../../collection-manager';
import { fieldComponentSettingsItem, useCollection } from '../../../../data-source';
import { useDesignable } from '../../../../schema-component';
import { useAssociationFieldContext } from '../../../../schema-component/antd/association-field/hooks';
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
@ -113,12 +114,15 @@ export const tableColumnSettings = new SchemaSettings({
name: 'sortable',
type: 'switch',
useVisible() {
const collection = useCollection();
const { collectionField } = useColumnSchema();
const { getInterface } = useCollectionManager_deprecated();
const interfaceCfg = getInterface(collectionField?.interface);
const { currentMode } = useAssociationFieldContext();
return interfaceCfg?.sortable === true && !currentMode;
return (
interfaceCfg?.sortable === true && !currentMode && collection?.name === collectionField?.collectionName
);
},
useComponentProps() {
const field: any = useField();
@ -151,7 +155,12 @@ export const tableColumnSettings = new SchemaSettings({
name: 'setDefaultValue',
useVisible() {
const { fieldSchema } = useColumnSchema();
return !fieldSchema['x-read-pretty'];
if (!fieldSchema) {
return false;
}
return !fieldSchema?.['x-read-pretty'];
},
Component: SchemaSettingsDefaultValue as any,
useComponentProps() {
@ -167,6 +176,11 @@ export const tableColumnSettings = new SchemaSettings({
useVisible() {
const { uiSchema, fieldSchema } = useColumnSchema();
const field: any = useField();
if (!fieldSchema) {
return false;
}
const isSubTableColumn = ['QuickEdit', 'FormItem'].includes(fieldSchema['x-decorator']);
return isSubTableColumn && !field.readPretty && !uiSchema?.['x-read-pretty'];
},
@ -181,6 +195,10 @@ export const tableColumnSettings = new SchemaSettings({
title: t('Required'),
checked: fieldSchema.required as boolean,
onChange: (required) => {
if (!fieldSchema) {
return console.error('fieldSchema is required');
}
const schema = {
['x-uid']: fieldSchema['x-uid'],
};
@ -204,6 +222,9 @@ export const tableColumnSettings = new SchemaSettings({
useVisible() {
const { fieldSchema, collectionField } = useColumnSchema();
const field: any = useField();
if (!fieldSchema) {
return false;
}
const isSubTableColumn = ['QuickEdit', 'FormItem'].includes(fieldSchema['x-decorator']);
return (
isSubTableColumn &&
@ -218,6 +239,9 @@ export const tableColumnSettings = new SchemaSettings({
const { t } = useTranslation();
const { dn } = useDesignable();
let readOnlyMode = 'editable';
if (!fieldSchema) {
return console.error('fieldSchema is required') as any;
}
if (fieldSchema['x-disabled'] === true) {
readOnlyMode = 'readonly';
}
@ -283,6 +307,7 @@ export const tableColumnSettings = new SchemaSettings({
};
},
},
fieldComponentSettingsItem,
],
},
{

View File

@ -67,7 +67,6 @@ export const Action: ComposedAction = withDynamicSchemaProps(
const designerProps = fieldSchema['x-designer-props'];
const openMode = fieldSchema?.['x-component-props']?.['openMode'];
const openSize = fieldSchema?.['x-component-props']?.['openSize'];
const disabled = form.disabled || field.disabled || field.data?.disabled || propsDisabled;
const linkageRules = useMemo(() => fieldSchema?.['x-linkage-rules'] || [], [fieldSchema]);
const { designable } = useDesignable();
@ -175,7 +174,6 @@ export const Action: ComposedAction = withDynamicSchemaProps(
</ActionContextProvider>
);
// fix /description
if (addChild) {
return wrapSSR(
<RecordProvider record={null} parent={record}>

View File

@ -7,12 +7,12 @@ import cls from 'classnames';
import _ from 'lodash';
import { useToken } from '../__builtins__';
import { useDesignable, useFormBlockContext, useSchemaInitializerRender } from '../../../';
import { SchemaComponent, useDesignable, useFormBlockContext, useSchemaInitializerRender } from '../../../';
import { useFormBlockType } from '../../../block-provider';
import { DndContext } from '../../common/dnd-context';
import useStyles from './Grid.style';
const GridRowContext = createContext<any>({});
export const GridRowContext = createContext<any>({});
GridRowContext.displayName = 'GridRowContext';
const GridColContext = createContext<any>({});
GridColContext.displayName = 'GridColContext';
@ -22,6 +22,9 @@ GridContext.displayName = 'GridContext';
const breakRemoveOnGrid = (s: Schema) => s['x-component'] === 'Grid';
const breakRemoveOnRow = (s: Schema) => s['x-component'] === 'Grid.Row';
const MemorizedRecursionField = React.memo(RecursionField);
MemorizedRecursionField.displayName = 'MemorizedRecursionField';
const ColDivider = (props) => {
const { token } = useToken();
const dragIdRef = useRef<string | null>(null);
@ -306,7 +309,7 @@ export const useGridRowContext = () => {
export const Grid: any = observer(
(props: any) => {
const { showDivider = true } = props;
const { distributed, showDivider = true } = props;
const gridRef = useRef(null);
const field = useField();
const fieldSchema = useFieldSchema();
@ -316,6 +319,10 @@ export const Grid: any = observer(
const rows = useRowProperties();
const { setPrintContent } = useFormBlockContext();
const { wrapSSR, componentCls, hashId } = useStyles();
const distributedValue =
distributed === undefined
? fieldSchema?.parent['x-component'] === 'Page' || fieldSchema?.parent['x-component'] === 'Tabs.TabPane'
: distributed;
useEffect(() => {
gridRef.current && setPrintContent?.(gridRef.current);
@ -343,7 +350,11 @@ export const Grid: any = observer(
{rows.map((schema, index) => {
return (
<React.Fragment key={index}>
<RecursionField name={schema.name} schema={schema} />
{distributedValue ? (
<SchemaComponent name={schema.name} schema={schema} distributed />
) : (
<MemorizedRecursionField name={schema.name} schema={schema} />
)}
{showDivider ? (
<RowDivider
rows={rows}

View File

@ -8,6 +8,14 @@ type SchemaComponentOnChange = {
onChange?: (s: Schema) => void;
};
interface DistributedProps {
/**
*
* @default false
*/
distributed?: boolean;
}
function toSchema(schema?: any) {
if (Schema.isSchemaInstance(schema)) {
return schema;
@ -55,7 +63,8 @@ const MemoizedSchemaComponent = (props: ISchemaFieldProps & SchemaComponentOnCha
};
export const SchemaComponent = (
props: (ISchemaFieldProps | IRecursionFieldProps) & { memoized?: boolean } & SchemaComponentOnChange,
props: (ISchemaFieldProps | IRecursionFieldProps) & { memoized?: boolean } & SchemaComponentOnChange &
DistributedProps,
) => {
const { memoized, ...others } = props;
if (memoized) {