feat: improve code

This commit is contained in:
chenos 2022-01-21 14:04:15 +08:00
parent 84f3ed1564
commit 4715ba8d22
16 changed files with 90 additions and 54 deletions

View File

@ -473,7 +473,7 @@ export default function App() {
* defaultShowCode: true
* title: RouteSwitch + SchemaComponent
*/
import React, { useMemo } from 'react';
import React, { useMemo, useEffect } from 'react';
import { Link, MemoryRouter as Router } from 'react-router-dom';
import {
RouteRedirectProps,
@ -483,6 +483,7 @@ import {
SchemaComponentProvider,
SchemaComponent,
useDesignable,
useSchemaComponentContext,
} from '@nocobase/client';
import { Spin, Button } from 'antd';
import { observer, Schema } from '@formily/react';
@ -503,6 +504,10 @@ const Hello = observer(({ name }) => {
const RouteSchemaComponent = (props) => {
const route = useRoute();
const { reset } = useSchemaComponentContext();
useEffect(() => {
reset();
}, route.schema);
return <SchemaComponent schema={route.schema}/>
}

View File

@ -27,7 +27,8 @@
"axios": "^0.24.0",
"i18next": "^21.6.0",
"react-helmet": "^6.1.0",
"react-i18next": "^11.15.1"
"react-i18next": "^11.15.1",
"use-deep-compare-effect": "^1.8.1"
},
"peerDependencies": {
"@types/react": ">=16.8.0 || >=17.0.0",

View File

@ -1,28 +1,28 @@
import React from 'react';
import { HashRouter, MemoryRouter } from 'react-router-dom';
import {
i18n,
compose,
useRequest,
AuthLayout,
ACLShortcut,
Action,
AdminLayout,
AntdConfigProvider,
APIClientProvider,
AuthLayout,
CollectionManagerShortcut,
compose,
DesignableSwitch,
DocumentTitleProvider,
i18n,
Menu,
Page,
PluginManagerProvider,
RouteSwitch,
RouteSwitchProvider,
AntdConfigProvider,
SchemaComponentProvider,
Menu,
Action,
PluginManagerProvider,
DesignableSwitch,
CollectionManagerShortcut,
ACLShortcut,
SystemSettingsShortcut,
DocumentTitleProvider,
Page,
useRequest
} from '@nocobase/client';
import { I18nextProvider } from 'react-i18next';
import { Spin } from 'antd';
import React from 'react';
import { I18nextProvider } from 'react-i18next';
import { MemoryRouter } from 'react-router-dom';
import apiClient from './apiClient';
const providers = [

View File

@ -43,11 +43,11 @@ PluginManager.Toolbar = (props: ToolbarProps) => {
<Menu style={{ width: '100%' }} selectable={false} mode={'horizontal'} theme={'dark'}>
{items
.filter((item) => item.pin)
.map((item) => {
.map((item, index) => {
const Action = get(components, item.component);
return (
Action && (
<ToolbarItemContext.Provider value={item}>
<ToolbarItemContext.Provider key={index} value={item}>
<Action />
</ToolbarItemContext.Provider>
)
@ -56,18 +56,18 @@ PluginManager.Toolbar = (props: ToolbarProps) => {
<Menu.SubMenu key={'more'} title={<MoreOutlined />}>
{items
.filter((item) => !item.pin)
.map((item) => {
.map((item, index) => {
const Action = get(components, item.component);
return (
Action && (
<ToolbarItemContext.Provider value={item}>
<ToolbarItemContext.Provider key={index} value={item}>
<Action />
</ToolbarItemContext.Provider>
)
);
})}
<Menu.Divider></Menu.Divider>
<Menu.Item disabled icon={<SettingOutlined />}>
<Menu.Divider key={'divider'}></Menu.Divider>
<Menu.Item key={'plugins'} disabled icon={<SettingOutlined />}>
</Menu.Item>
</Menu.SubMenu>

View File

@ -21,6 +21,7 @@ export const Cascader = connect(
useLoadData = useDefLoadData,
changeOnSelectLast,
changeOnSelect,
maxLevel,
...others
} = props;
const loadData = useLoadData(props);

View File

@ -34,6 +34,7 @@ mock.onGet('/china_regions').reply(200, {
const useAsyncDataSource = (api: APIClient) => (field) => {
field.loading = true;
console.log('useAsyncDataSource');
api.request({ url: 'china_regions' }).then(
action.bound((res) => {
field.dataSource = res?.data?.data || [];

View File

@ -1,8 +1,8 @@
import { DesktopOutlined } from '@ant-design/icons';
import { observer, RecursionField, Schema, useFieldSchema } from '@formily/react';
import { Menu as AntdMenu } from 'antd';
import React, { createContext, useContext, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { Menu as AntdMenu } from 'antd';
import { Schema, observer, useFieldSchema, RecursionField } from '@formily/react';
import { DesktopOutlined } from '@ant-design/icons';
import { findKeysByUid, findMenuItem } from './util';
type ComposedMenu = React.FC<any> & {
@ -22,6 +22,7 @@ export const Menu: ComposedMenu = observer((props) => {
defaultOpenKeys: dOpenKeys,
...others
} = props;
console.log('defaultSelectedUid', defaultSelectedUid)
const schema = useFieldSchema();
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
if (dSelectedKeys) {

View File

@ -1,8 +1,9 @@
import React from 'react';
import { Spin } from 'antd';
import { useRequest } from '../../api-client';
import { SchemaComponent } from './SchemaComponent';
import { Schema } from '@formily/react';
import { Spin } from 'antd';
import React from 'react';
import { useRequest } from '../../api-client';
import { useSchemaComponentContext } from '../hooks';
import { SchemaComponent } from './SchemaComponent';
export interface RemoteSchemaComponentProps {
scope?: any;
@ -15,20 +16,22 @@ export interface RemoteSchemaComponentProps {
const defaultTransform = (s: Schema) => s;
export const RemoteSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) => {
const RequestSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) => {
const { hidden, scope, uid, onSuccess, schemaTransform = defaultTransform } = props;
if (!uid) {
return null;
}
const { reset } = useSchemaComponentContext();
const { data, loading } = useRequest(
{
url: `/ui_schemas:getJsonSchema/${uid}`,
},
{
refreshDeps: [uid],
onSuccess,
onSuccess(data) {
onSuccess && onSuccess(data);
reset && reset();
},
},
);
if (loading) {
return <Spin />;
}
@ -37,3 +40,7 @@ export const RemoteSchemaComponent: React.FC<RemoteSchemaComponentProps> = (prop
}
return <SchemaComponent scope={scope} schema={schemaTransform(data?.data || {})} />;
};
export const RemoteSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) => {
return props.uid ? <RequestSchemaComponent {...props}/> : null;
};

View File

@ -1,5 +1,5 @@
import { ISchemaFieldProps, Schema } from '@formily/react';
import React, { useContext, useEffect, useMemo, useRef } from 'react';
import React, { useContext, useMemo } from 'react';
import { SchemaComponentContext } from '../context';
function toSchema(schema?: any) {
@ -18,16 +18,8 @@ function toSchema(schema?: any) {
}
export function SchemaComponent(props: ISchemaFieldProps) {
const { schema: defaultSchema, ...others } = props;
const { reset, SchemaField } = useContext(SchemaComponentContext);
const schema = useMemo(() => toSchema(defaultSchema), []);
const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
reset();
}
}, [JSON.stringify(defaultSchema)]);
return <SchemaField {...others} schema={schema} />;
const { schema, ...others } = props;
const { SchemaField } = useContext(SchemaComponentContext);
const s = useMemo(() => toSchema(schema), []);
return <SchemaField {...others} schema={s} />;
}

View File

@ -29,7 +29,6 @@ export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (prop
SchemaField,
components,
scope,
refreshFormId: () => setFormId(uid()),
reset: () => setFormId(uid()),
refresh: () => setUid(uid()),
designable: active === 'true',

View File

@ -2,4 +2,5 @@ export * from './useAttach';
export * from './useCompile';
export * from './useDesignable';
export * from './useFieldProps';
export * from './useSchemaComponentContext';

View File

@ -1,9 +1,11 @@
import { useContext } from 'react';
import { compile } from '@formily/json-schema/lib/compiler';
import { useTranslation } from 'react-i18next';
import { SchemaExpressionScopeContext, SchemaOptionsContext } from '@formily/react';
export const useCompile = () => {
const { t } = useTranslation();
const options = useContext(SchemaOptionsContext);
const scope = useContext(SchemaExpressionScopeContext);
return (source: any) => {
return compile(source, { t });
return compile(source, { ...options.scope, ...scope });
};
};

View File

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

View File

@ -17,6 +17,14 @@ group:
## Hooks
### useSchemaComponentContext()
获取 SchemaComponent 的上下文
```ts
const { refresh, reset } = useSchemaComponentContext();
```
### useDesignable()
获取当前 schema 节点设计器的 API

View File

@ -19,7 +19,6 @@ export interface ISchemaComponentContext {
scope?: any;
components?: SchemaReactComponents;
refresh?: () => void;
refreshFormId?: () => void;
reset?: () => void;
designable?: boolean;
setDesignable?: (value: boolean) => void;

View File

@ -5452,6 +5452,11 @@ deprecation@^2.0.0, deprecation@^2.3.1:
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
dequal@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
@ -14631,6 +14636,14 @@ urllib@^2.33.1:
statuses "^1.3.1"
utility "^1.16.1"
use-deep-compare-effect@^1.8.1:
version "1.8.1"
resolved "https://registry.npmjs.org/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz#ef0ce3b3271edb801da1ec23bf0754ef4189d0c6"
integrity sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==
dependencies:
"@babel/runtime" "^7.12.5"
dequal "^2.0.2"
use-subscription@1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"