feat: improve code
This commit is contained in:
parent
84f3ed1564
commit
4715ba8d22
@ -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}/>
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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 = [
|
||||
|
@ -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>
|
||||
|
@ -21,6 +21,7 @@ export const Cascader = connect(
|
||||
useLoadData = useDefLoadData,
|
||||
changeOnSelectLast,
|
||||
changeOnSelect,
|
||||
maxLevel,
|
||||
...others
|
||||
} = props;
|
||||
const loadData = useLoadData(props);
|
||||
|
@ -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 || [];
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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} />;
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -2,4 +2,5 @@ export * from './useAttach';
|
||||
export * from './useCompile';
|
||||
export * from './useDesignable';
|
||||
export * from './useFieldProps';
|
||||
export * from './useSchemaComponentContext';
|
||||
|
||||
|
@ -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 });
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,6 @@
|
||||
import { useContext } from 'react';
|
||||
import { SchemaComponentContext } from '../context';
|
||||
|
||||
export function useSchemaComponentContext() {
|
||||
return useContext(SchemaComponentContext);
|
||||
}
|
@ -17,6 +17,14 @@ group:
|
||||
|
||||
## Hooks
|
||||
|
||||
### useSchemaComponentContext()
|
||||
|
||||
获取 SchemaComponent 的上下文
|
||||
|
||||
```ts
|
||||
const { refresh, reset } = useSchemaComponentContext();
|
||||
```
|
||||
|
||||
### useDesignable()
|
||||
|
||||
获取当前 schema 节点设计器的 API
|
||||
|
@ -19,7 +19,6 @@ export interface ISchemaComponentContext {
|
||||
scope?: any;
|
||||
components?: SchemaReactComponents;
|
||||
refresh?: () => void;
|
||||
refreshFormId?: () => void;
|
||||
reset?: () => void;
|
||||
designable?: boolean;
|
||||
setDesignable?: (value: boolean) => void;
|
||||
|
13
yarn.lock
13
yarn.lock
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user