fix: add SchemaComponentContextProvider

This commit is contained in:
dream2023 2024-03-06 15:22:27 +08:00
parent 2c3a04c5c1
commit 989d11da34
23 changed files with 110 additions and 86 deletions

View File

@ -1,7 +1,7 @@
import { Spin } from 'antd';
import React, { createContext, useContext } from 'react';
import { useRequest } from '../../api-client';
import { SchemaComponent, SchemaComponentContext } from '../../schema-component';
import { SchemaComponent, SchemaComponentContextProvider } from '../../schema-component';
import { MenuItemsProvider } from '../Configuration/MenuItemsProvider';
import { PermissionProvider, SettingCenterPermissionProvider } from '../Configuration/PermisionProvider';
import { roleSchema } from './schemas/roles';
@ -29,14 +29,14 @@ export const useAvailableActions = () => {
export const RoleTable = () => {
return (
<div>
<SchemaComponentContext.Provider value={{ designable: false }}>
<SchemaComponentContextProvider value={{ designable: false }}>
<AvailableActionsProver>
<SchemaComponent
schema={roleSchema}
components={{ MenuItemsProvider, SettingCenterPermissionProvider, PermissionProvider }}
/>
</AvailableActionsProver>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
</div>
);
};

View File

@ -1,6 +1,6 @@
import { merge, omit } from 'lodash';
import React, { ComponentType, useMemo } from 'react';
import { useDesignable, useSchemaComponentContext } from '../../schema-component';
import { useDesignable, useSchemaComponentChangelessContext } from '../../schema-component';
const useDefaultSchemaProps = () => undefined;
@ -12,7 +12,7 @@ export function withDynamicSchemaProps<T = any>(Component: ComponentType<T>, opt
const displayName = options.displayName || Component.displayName || Component.name;
const ComponentWithProps: ComponentType<T> = (props) => {
const { dn, findComponent } = useDesignable();
const { scope } = useSchemaComponentContext();
const { scope } = useSchemaComponentChangelessContext();
const useComponentPropsStr = useMemo(() => {
const xComponent = dn.getSchemaAttribute('x-component');
const xDecorator = dn.getSchemaAttribute('x-decorator');

View File

@ -1,7 +1,7 @@
import { CascaderProps } from 'antd';
import _ from 'lodash';
import { useCallback, useMemo, useState } from 'react';
import { useCompile, useSchemaComponentContext } from '../../schema-component';
import { useCompile, useSchemaComponentChangelessContext } from '../../schema-component';
import { CollectionFieldOptions_deprecated, CollectionOptions } from '../types';
import { InheritanceCollectionMixin } from '../mixins/InheritanceCollectionMixin';
import { uid } from '@formily/shared';
@ -19,7 +19,7 @@ export const useCollectionManager_deprecated = (dataSourceName?: string) => {
const cm = useCollectionManager();
const dataSourceNameValue = dataSourceName || dataSource?.key || undefined;
const [random, setRandom] = useState(uid());
const { refresh } = useSchemaComponentContext();
const { refresh } = useSchemaComponentChangelessContext();
const interfaces = useMemo(
() =>
dm?.collectionFieldInterfaceManager?.getFieldInterfaces().reduce((acc, cur) => {

View File

@ -2,7 +2,7 @@ import React, { FC, ReactNode, createContext, useContext } from 'react';
import type { DataSource } from './DataSource';
import { useDataSourceManager } from './DataSourceManagerProvider';
import { CollectionDeletedPlaceholder } from '../components/CollectionDeletedPlaceholder';
import { CardItem, useSchemaComponentContext } from '../../schema-component';
import { CardItem, useSchemaComponentChangelessContext } from '../../schema-component';
import { Button, Result } from 'antd';
import { LoadingOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
@ -18,7 +18,7 @@ export interface DataSourceProviderProps {
export const DataSourceProvider: FC<DataSourceProviderProps> = ({ children, dataSource }) => {
const dataSourceManager = useDataSourceManager();
const { t } = useTranslation();
const { refresh } = useSchemaComponentContext();
const { refresh } = useSchemaComponentChangelessContext();
const [_, setRandom] = React.useState(0);
const dataSourceValue = dataSourceManager.getDataSource(dataSource);

View File

@ -1,14 +1,14 @@
import { Schema, useFieldSchema } from '@formily/react';
import React, { useContext } from 'react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaComponentContext, createDesignable } from '../..';
import { createDesignable, useSchemaComponentChangelessContext } from '../..';
import { useAPIClient } from '../../../api-client';
import { useBlockRequestContext } from '../../../block-provider';
import { mergeFilter } from '../../../filter-provider/utils';
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
export const ActionBarAssociationFilterAction = (props) => {
const { refresh } = useContext(SchemaComponentContext);
const { refresh } = useSchemaComponentChangelessContext();
const fieldSchema = useFieldSchema();
const api = useAPIClient();
const { t } = useTranslation();

View File

@ -1,13 +1,13 @@
import React, { useContext } from 'react';
import React from 'react';
import { useFieldSchema } from '@formily/react';
import { createDesignable, SchemaComponentContext } from '../..';
import { createDesignable, useSchemaComponentChangelessContext } from '../..';
import { useAPIClient } from '../../../api-client';
import { useTranslation } from 'react-i18next';
import { SchemaInitializerItem, useSchemaInitializerItem } from '../../../application';
export const AssociationFilterDesignerDelete = () => {
const itemConfig = useSchemaInitializerItem();
const { refresh } = useContext(SchemaComponentContext);
const { refresh } = useSchemaComponentChangelessContext();
const fieldSchema = useFieldSchema();
const api = useAPIClient();
const { t } = useTranslation();

View File

@ -31,7 +31,7 @@ const useLazyLoadDisplayAssociationFieldsOfForm = () => {
const { getAssociationAppends } = useAssociationNames();
const schemaName = fieldSchema.name.toString();
const formValue = _.cloneDeep(isInSubForm || isInSubTable ? subFormValue : form.values);
const formValue = isInSubForm || isInSubTable ? subFormValue : form.values;
const collectionFieldRef = useRef(null);
const sourceCollectionFieldRef = useRef(null);

View File

@ -1,5 +0,0 @@
import { createContext } from 'react';
import { ISchemaComponentContext } from './types';
export const SchemaComponentContext = createContext<ISchemaComponentContext>({});
SchemaComponentContext.displayName = 'SchemaComponentContext.Provider';

View File

@ -3,7 +3,7 @@ import { Schema } from '@formily/react';
import { Spin } from 'antd';
import React, { useMemo } from 'react';
import { useRequest } from '../../api-client';
import { useSchemaComponentContext } from '../hooks';
import { useSchemaComponentChangelessContext } from '../hooks';
import { FormProvider } from './FormProvider';
import { SchemaComponent } from './SchemaComponent';
@ -32,7 +32,7 @@ const RequestSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) =>
onSuccess,
schemaTransform = defaultTransform,
} = props;
const { reset } = useSchemaComponentContext();
const { reset } = useSchemaComponentChangelessContext();
const conf = {
url: `/uiSchemas:${onlyRenderProperties ? 'getProperties' : 'getJsonSchema'}/${uid}`,
};

View File

@ -1,6 +1,6 @@
import { IRecursionFieldProps, ISchemaFieldProps, RecursionField, Schema } from '@formily/react';
import React, { memo, useCallback, useContext, useMemo } from 'react';
import { SchemaComponentContext } from '../context';
import { SchemaComponentContext, SchemaComponentContextProvider } from '../context';
import { SchemaComponentOptions } from './SchemaComponentOptions';
type SchemaComponentOnChange = {
@ -35,19 +35,20 @@ const RecursionSchemaComponent = (props: ISchemaFieldProps & SchemaComponentOnCh
props.onChange?.(s);
}, [s, ctx.refresh, props.onChange]);
const contextValue = useMemo(() => ({
...ctx,
refresh
}), [ctx, refresh]);
const contextValue = useMemo(
() => ({
...ctx,
refresh,
}),
[ctx, refresh],
);
return (
<SchemaComponentContext.Provider
value={contextValue}
>
<SchemaComponentContextProvider value={contextValue}>
<SchemaComponentOptions inherit components={components} scope={scope}>
<RecursionField {...others} schema={s} />
</SchemaComponentOptions>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
};
@ -57,14 +58,14 @@ const MemoizedSchemaComponent = (props: ISchemaFieldProps & SchemaComponentOnCha
return <RecursionSchemaComponent {...others} schema={s} />;
};
export const SchemaComponent = memo((
props: (ISchemaFieldProps | IRecursionFieldProps) & { memoized?: boolean } & SchemaComponentOnChange,
) => {
const { memoized, ...others } = props;
if (memoized) {
return <MemoizedSchemaComponent {...others} />;
}
return <RecursionSchemaComponent {...others} />;
});
export const SchemaComponent = memo(
(props: (ISchemaFieldProps | IRecursionFieldProps) & { memoized?: boolean } & SchemaComponentOnChange) => {
const { memoized, ...others } = props;
if (memoized) {
return <MemoizedSchemaComponent {...others} />;
}
return <RecursionSchemaComponent {...others} />;
},
);
SchemaComponent.displayName = 'SchemaComponent';

View File

@ -3,7 +3,7 @@ import { FormProvider, Schema } from '@formily/react';
import { uid } from '@formily/shared';
import React, { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaComponentContext } from '../context';
import { SchemaComponentContextProvider } from '../context';
import { ISchemaComponentProvider } from '../types';
import { SchemaComponentOptions } from './SchemaComponentOptions';
@ -60,12 +60,15 @@ export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (prop
const reset = useCallback(() => {
setFormId(uid());
}, []);
const setDesignable = useCallback((value) => {
if (typeof designable !== 'boolean') {
setActive(value);
}
onDesignableChange?.(value);
}, [designable, onDesignableChange]);
const setDesignable = useCallback(
(value) => {
if (typeof designable !== 'boolean') {
setActive(value);
}
onDesignableChange?.(value);
},
[designable, onDesignableChange],
);
const contextValue = useMemo(() => {
return {
@ -78,16 +81,16 @@ export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (prop
};
// uidValue 虽然没用到,但是这里必须加上,为了让整个页面能够渲染
}, [uidValue, scope, components, reset, refresh, designable, active, setDesignable])
}, [uidValue, scope, components, reset, refresh, designable, active, setDesignable]);
return (
<SchemaComponentContext.Provider value={contextValue}>
<SchemaComponentContextProvider value={contextValue}>
<FormProvider form={form}>
<SchemaComponentOptions inherit scope={scope} components={components}>
{children}
</SchemaComponentOptions>
</FormProvider>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
};
SchemaComponentProvider.displayName = 'SchemaComponentProvider';

View File

@ -8,7 +8,7 @@ import set from 'lodash/set';
import React, { ComponentType, useCallback, useContext, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { APIClient, useAPIClient } from '../../api-client';
import { SchemaComponentContext } from '../context';
import { useSchemaComponentChangelessContext } from './useSchemaComponentContext';
interface CreateDesignableProps {
current: Schema;
@ -701,7 +701,7 @@ export function useFindComponent() {
// TODO
export function useDesignable() {
const { designable, setDesignable, refresh, reset } = useContext(SchemaComponentContext);
const { designable, setDesignable, refresh, reset } = useSchemaComponentChangelessContext();
const schemaOptions = useContext(SchemaOptionsContext);
const components = useMemo(() => schemaOptions?.components || {}, [schemaOptions]);
const DesignableBar = useMemo(

View File

@ -1,6 +1,10 @@
import { useContext } from 'react';
import { SchemaComponentContext } from '../context';
import { SchemaComponentContext, SchemaComponentChangelessContext } from '../context';
export function useSchemaComponentContext() {
return useContext(SchemaComponentContext);
}
export function useSchemaComponentChangelessContext() {
return useContext(SchemaComponentChangelessContext);
}

View File

@ -7,7 +7,7 @@ import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useCollectionManager_deprecated } from '../../collection-manager';
import { mergeFilter } from '../../filter-provider/utils';
import { SchemaComponent, SchemaComponentContext, removeNullCondition } from '../../schema-component';
import { SchemaComponent, SchemaComponentContextProvider, removeNullCondition } from '../../schema-component';
import { ITemplate } from '../../schema-component/antd/form-v2/Templates';
import { VariableInput } from '../VariableInput';
import { AsDefaultTemplate } from './components/AsDefaultTemplate';
@ -259,9 +259,9 @@ export const FormDataTemplates = observer(
);
return (
<SchemaComponentContext.Provider value={{ ...designerCtx, designable: true }}>
<SchemaComponentContextProvider value={{ ...designerCtx, designable: true }}>
<SchemaComponent components={components} scope={scope} schema={schema} />
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
},
{ displayName: 'FormDataTemplates' },

View File

@ -67,6 +67,7 @@ import {
useRecord,
useSchemaSettingsItem,
useSortFields,
useCollection,
} from '..';
import {
BlockRequestContext_deprecated,
@ -144,10 +145,10 @@ interface SchemaSettingsProviderProps {
export const SchemaSettingsProvider: React.FC<SchemaSettingsProviderProps> = (props) => {
const { children, fieldSchema, ...others } = props;
const { getTemplateBySchema } = useSchemaTemplateManager();
const { name } = useCollection_deprecated();
const collection = useCollection();
const template = getTemplateBySchema(fieldSchema);
return (
<SchemaSettingsContext.Provider value={{ collectionName: name, template, fieldSchema, ...others }}>
<SchemaSettingsContext.Provider value={{ collectionName: collection?.name, template, fieldSchema, ...others }}>
{children}
</SchemaSettingsContext.Provider>
);

View File

@ -3,7 +3,7 @@ import { Input, Spin } from 'antd';
import React, { useContext, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useAPIClient, useRequest, useSchemaTemplateManager } from '..';
import { RemoteSchemaComponent, SchemaComponentContext } from '../schema-component';
import { RemoteSchemaComponent, SchemaComponentContext, SchemaComponentContextProvider } from '../schema-component';
const EditableTitle = (props) => {
const [title, setTitle] = useState(props.title);
@ -86,9 +86,9 @@ export const BlockTemplateDetails = () => {
title={<EditableTitle filterByTk={key} title={data?.data?.name} />}
/>
<div style={{ margin: 'var(--nb-spacing)' }}>
<SchemaComponentContext.Provider value={{ ...value, designable: true }}>
<SchemaComponentContextProvider value={{ ...value, designable: true }}>
<RemoteSchemaComponent uid={data?.data?.uid} />
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
</div>
</div>
);

View File

@ -20,6 +20,7 @@ import {
TemplateSummary,
ResourceActionContext,
useDataSourceManager,
SchemaComponentContextProvider,
} from '@nocobase/client';
import { message } from 'antd';
import { getCollectionSchema } from './schema/collections';
@ -157,7 +158,7 @@ export const ConfigurationTable = () => {
return getCollectionSchema(name);
}, [name]);
return (
<SchemaComponentContext.Provider value={{ ...ctx, designable: false }}>
<SchemaComponentContextProvider value={{ ...ctx, designable: false }}>
<SchemaComponent
schema={collectionSchema}
components={{
@ -184,6 +185,6 @@ export const ConfigurationTable = () => {
isPG: database?.dialect === 'postgres',
}}
/>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
};

View File

@ -19,6 +19,7 @@ import {
CollectionCategroriesContext,
FieldSummary,
TemplateSummary,
SchemaComponentContextProvider,
} from '@nocobase/client';
import { CollectionFields } from './CollectionFields';
import { collectionSchema } from './schemas/collections';
@ -166,7 +167,7 @@ export const ConfigurationTable = () => {
const ctx = useContext(SchemaComponentContext);
return (
<SchemaComponentContext.Provider value={{ ...ctx, designable: false }}>
<SchemaComponentContextProvider value={{ ...ctx, designable: false }}>
<SchemaComponent
schema={collectionSchema}
components={{
@ -194,6 +195,6 @@ export const ConfigurationTable = () => {
isPG: database?.dialect === 'postgres',
}}
/>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
};

View File

@ -3,9 +3,9 @@ import React, { createContext, useContext } from 'react';
import {
useRequest,
SchemaComponent,
SchemaComponentContext,
SettingCenterPermissionProvider,
useRecord,
SchemaComponentContextProvider,
} from '@nocobase/client';
import { dataSourceSchema } from './schemas/dataSourceTable';
import { PermissionProvider } from './PermisionProvider';
@ -34,7 +34,7 @@ export const DataSourceTable = () => {
const record = useRecord();
return (
<div>
<SchemaComponentContext.Provider value={{ designable: false }}>
<SchemaComponentContextProvider value={{ designable: false }}>
<AvailableActionsProver>
<SchemaComponent
schema={dataSourceSchema}
@ -42,7 +42,7 @@ export const DataSourceTable = () => {
scope={{ dataSourceKey: record.key }}
/>
</AvailableActionsProver>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
</div>
);
};

View File

@ -1,4 +1,9 @@
import { SchemaComponent, SchemaComponentContext, useSchemaComponentContext } from '@nocobase/client';
import {
SchemaComponent,
SchemaComponentContext,
SchemaComponentContextProvider,
useSchemaComponentContext,
} from '@nocobase/client';
import React from 'react';
import { usersSchema } from './schemas/users';
import { Card } from 'antd';
@ -11,7 +16,7 @@ export const UsersManagement: React.FC = () => {
const { t } = useUsersTranslation();
const scCtx = useSchemaComponentContext();
return (
<SchemaComponentContext.Provider value={{ ...scCtx, designable: false }}>
<SchemaComponentContextProvider value={{ ...scCtx, designable: false }}>
<Card>
<SchemaComponent
schema={usersSchema}
@ -19,6 +24,6 @@ export const UsersManagement: React.FC = () => {
components={{ UserRolesField, PasswordField }}
/>
</Card>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
};

View File

@ -1,9 +1,9 @@
import { observer, useField, useFieldSchema, useForm } from '@formily/react';
import { Space, Spin, Tag } from 'antd';
import dayjs from 'dayjs';
import React, { createContext, useContext, useEffect, useState } from 'react';
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { css, useCompile, usePlugin } from '@nocobase/client';
import { SchemaComponentContextProvider, css, useCompile, usePlugin } from '@nocobase/client';
import {
SchemaComponent,
@ -580,8 +580,12 @@ function Drawer() {
const ctx = useContext(SchemaComponentContext);
const { id, node, workflow, status } = useRecord();
const contextValue = useMemo(() => {
return { ...ctx, reset() {}, designable: false };
}, [ctx]);
return (
<SchemaComponentContext.Provider value={{ ...ctx, reset() {}, designable: false }}>
<SchemaComponentContextProvider value={contextValue}>
<SchemaComponent
components={{
FooterStatus,
@ -613,7 +617,7 @@ function Drawer() {
},
}}
/>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
}

View File

@ -14,6 +14,7 @@ import {
InitializerWithSwitch,
SchemaComponent,
SchemaComponentContext,
SchemaComponentContextProvider,
SchemaInitializer,
SchemaInitializerItem,
SchemaInitializerItemType,
@ -242,6 +243,10 @@ function AssignedFieldValues() {
}, 300);
}
const refresh = useCallback(() => {
setInitialSchema(lodash.get(schema.toJSON(), 'properties.grid'));
}, [schema]);
return (
<>
<SchemaSettingsItem title={title} onClick={() => setOpen(true)}>
@ -273,16 +278,14 @@ function AssignedFieldValues() {
/>
<br />
{open && schema && (
<SchemaComponentContext.Provider
<SchemaComponentContextProvider
value={{
...ctx,
refresh() {
setInitialSchema(lodash.get(schema.toJSON(), 'properties.grid'));
},
refresh,
}}
>
<SchemaComponent schema={schema} components={components} />
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
)}
</FormLayout>
</FormProvider>
@ -484,7 +487,7 @@ export function SchemaConfig({ value, onChange }) {
);
return (
<SchemaComponentContext.Provider
<SchemaComponentContextProvider
value={{
...ctx,
designable: !workflow.executed,
@ -517,7 +520,7 @@ export function SchemaConfig({ value, onChange }) {
useDetailsBlockProps: useFormBlockContext,
}}
/>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
);
}

View File

@ -1,4 +1,10 @@
import { SchemaComponent, SchemaComponentContext, usePlugin, useRecord } from '@nocobase/client';
import {
SchemaComponent,
SchemaComponentContext,
SchemaComponentContextProvider,
usePlugin,
useRecord,
} from '@nocobase/client';
import { Card } from 'antd';
import React, { useContext, useEffect } from 'react';
import { ExecutionLink } from './ExecutionLink';
@ -52,7 +58,7 @@ export function WorkflowPane() {
const { getTriggersOptions } = usePlugin(WorkflowPlugin);
return (
<Card bordered={false}>
<SchemaComponentContext.Provider value={{ ...ctx, designable: false }}>
<SchemaComponentContextProvider value={{ ...ctx, designable: false }}>
<SchemaComponent
schema={workflowSchema}
components={{
@ -68,7 +74,7 @@ export function WorkflowPane() {
getTriggersOptions,
}}
/>
</SchemaComponentContext.Provider>
</SchemaComponentContextProvider>
</Card>
);
}