feat: improve code
This commit is contained in:
parent
84f3ed1564
commit
4715ba8d22
@ -473,7 +473,7 @@ export default function App() {
|
|||||||
* defaultShowCode: true
|
* defaultShowCode: true
|
||||||
* title: RouteSwitch + SchemaComponent
|
* title: RouteSwitch + SchemaComponent
|
||||||
*/
|
*/
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useEffect } from 'react';
|
||||||
import { Link, MemoryRouter as Router } from 'react-router-dom';
|
import { Link, MemoryRouter as Router } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
RouteRedirectProps,
|
RouteRedirectProps,
|
||||||
@ -483,6 +483,7 @@ import {
|
|||||||
SchemaComponentProvider,
|
SchemaComponentProvider,
|
||||||
SchemaComponent,
|
SchemaComponent,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
|
useSchemaComponentContext,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { Spin, Button } from 'antd';
|
import { Spin, Button } from 'antd';
|
||||||
import { observer, Schema } from '@formily/react';
|
import { observer, Schema } from '@formily/react';
|
||||||
@ -503,6 +504,10 @@ const Hello = observer(({ name }) => {
|
|||||||
|
|
||||||
const RouteSchemaComponent = (props) => {
|
const RouteSchemaComponent = (props) => {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const { reset } = useSchemaComponentContext();
|
||||||
|
useEffect(() => {
|
||||||
|
reset();
|
||||||
|
}, route.schema);
|
||||||
return <SchemaComponent schema={route.schema}/>
|
return <SchemaComponent schema={route.schema}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"i18next": "^21.6.0",
|
"i18next": "^21.6.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-i18next": "^11.15.1"
|
"react-i18next": "^11.15.1",
|
||||||
|
"use-deep-compare-effect": "^1.8.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": ">=16.8.0 || >=17.0.0",
|
"@types/react": ">=16.8.0 || >=17.0.0",
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
import React from 'react';
|
|
||||||
import { HashRouter, MemoryRouter } from 'react-router-dom';
|
|
||||||
import {
|
import {
|
||||||
i18n,
|
ACLShortcut,
|
||||||
compose,
|
Action,
|
||||||
useRequest,
|
|
||||||
AuthLayout,
|
|
||||||
AdminLayout,
|
AdminLayout,
|
||||||
|
AntdConfigProvider,
|
||||||
APIClientProvider,
|
APIClientProvider,
|
||||||
|
AuthLayout,
|
||||||
|
CollectionManagerShortcut,
|
||||||
|
compose,
|
||||||
|
DesignableSwitch,
|
||||||
|
DocumentTitleProvider,
|
||||||
|
i18n,
|
||||||
|
Menu,
|
||||||
|
Page,
|
||||||
|
PluginManagerProvider,
|
||||||
RouteSwitch,
|
RouteSwitch,
|
||||||
RouteSwitchProvider,
|
RouteSwitchProvider,
|
||||||
AntdConfigProvider,
|
|
||||||
SchemaComponentProvider,
|
SchemaComponentProvider,
|
||||||
Menu,
|
|
||||||
Action,
|
|
||||||
PluginManagerProvider,
|
|
||||||
DesignableSwitch,
|
|
||||||
CollectionManagerShortcut,
|
|
||||||
ACLShortcut,
|
|
||||||
SystemSettingsShortcut,
|
SystemSettingsShortcut,
|
||||||
DocumentTitleProvider,
|
useRequest
|
||||||
Page,
|
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { I18nextProvider } from 'react-i18next';
|
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import apiClient from './apiClient';
|
import apiClient from './apiClient';
|
||||||
|
|
||||||
const providers = [
|
const providers = [
|
||||||
|
@ -43,11 +43,11 @@ PluginManager.Toolbar = (props: ToolbarProps) => {
|
|||||||
<Menu style={{ width: '100%' }} selectable={false} mode={'horizontal'} theme={'dark'}>
|
<Menu style={{ width: '100%' }} selectable={false} mode={'horizontal'} theme={'dark'}>
|
||||||
{items
|
{items
|
||||||
.filter((item) => item.pin)
|
.filter((item) => item.pin)
|
||||||
.map((item) => {
|
.map((item, index) => {
|
||||||
const Action = get(components, item.component);
|
const Action = get(components, item.component);
|
||||||
return (
|
return (
|
||||||
Action && (
|
Action && (
|
||||||
<ToolbarItemContext.Provider value={item}>
|
<ToolbarItemContext.Provider key={index} value={item}>
|
||||||
<Action />
|
<Action />
|
||||||
</ToolbarItemContext.Provider>
|
</ToolbarItemContext.Provider>
|
||||||
)
|
)
|
||||||
@ -56,18 +56,18 @@ PluginManager.Toolbar = (props: ToolbarProps) => {
|
|||||||
<Menu.SubMenu key={'more'} title={<MoreOutlined />}>
|
<Menu.SubMenu key={'more'} title={<MoreOutlined />}>
|
||||||
{items
|
{items
|
||||||
.filter((item) => !item.pin)
|
.filter((item) => !item.pin)
|
||||||
.map((item) => {
|
.map((item, index) => {
|
||||||
const Action = get(components, item.component);
|
const Action = get(components, item.component);
|
||||||
return (
|
return (
|
||||||
Action && (
|
Action && (
|
||||||
<ToolbarItemContext.Provider value={item}>
|
<ToolbarItemContext.Provider key={index} value={item}>
|
||||||
<Action />
|
<Action />
|
||||||
</ToolbarItemContext.Provider>
|
</ToolbarItemContext.Provider>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<Menu.Divider></Menu.Divider>
|
<Menu.Divider key={'divider'}></Menu.Divider>
|
||||||
<Menu.Item disabled icon={<SettingOutlined />}>
|
<Menu.Item key={'plugins'} disabled icon={<SettingOutlined />}>
|
||||||
管理插件
|
管理插件
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
|
@ -21,6 +21,7 @@ export const Cascader = connect(
|
|||||||
useLoadData = useDefLoadData,
|
useLoadData = useDefLoadData,
|
||||||
changeOnSelectLast,
|
changeOnSelectLast,
|
||||||
changeOnSelect,
|
changeOnSelect,
|
||||||
|
maxLevel,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
const loadData = useLoadData(props);
|
const loadData = useLoadData(props);
|
||||||
|
@ -34,6 +34,7 @@ mock.onGet('/china_regions').reply(200, {
|
|||||||
|
|
||||||
const useAsyncDataSource = (api: APIClient) => (field) => {
|
const useAsyncDataSource = (api: APIClient) => (field) => {
|
||||||
field.loading = true;
|
field.loading = true;
|
||||||
|
console.log('useAsyncDataSource');
|
||||||
api.request({ url: 'china_regions' }).then(
|
api.request({ url: 'china_regions' }).then(
|
||||||
action.bound((res) => {
|
action.bound((res) => {
|
||||||
field.dataSource = res?.data?.data || [];
|
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 React, { createContext, useContext, useEffect, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
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';
|
import { findKeysByUid, findMenuItem } from './util';
|
||||||
|
|
||||||
type ComposedMenu = React.FC<any> & {
|
type ComposedMenu = React.FC<any> & {
|
||||||
@ -22,6 +22,7 @@ export const Menu: ComposedMenu = observer((props) => {
|
|||||||
defaultOpenKeys: dOpenKeys,
|
defaultOpenKeys: dOpenKeys,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
|
console.log('defaultSelectedUid', defaultSelectedUid)
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
|
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
|
||||||
if (dSelectedKeys) {
|
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 { 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 {
|
export interface RemoteSchemaComponentProps {
|
||||||
scope?: any;
|
scope?: any;
|
||||||
@ -15,20 +16,22 @@ export interface RemoteSchemaComponentProps {
|
|||||||
|
|
||||||
const defaultTransform = (s: Schema) => s;
|
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;
|
const { hidden, scope, uid, onSuccess, schemaTransform = defaultTransform } = props;
|
||||||
if (!uid) {
|
const { reset } = useSchemaComponentContext();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const { data, loading } = useRequest(
|
const { data, loading } = useRequest(
|
||||||
{
|
{
|
||||||
url: `/ui_schemas:getJsonSchema/${uid}`,
|
url: `/ui_schemas:getJsonSchema/${uid}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
refreshDeps: [uid],
|
refreshDeps: [uid],
|
||||||
onSuccess,
|
onSuccess(data) {
|
||||||
|
onSuccess && onSuccess(data);
|
||||||
|
reset && reset();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <Spin />;
|
return <Spin />;
|
||||||
}
|
}
|
||||||
@ -37,3 +40,7 @@ export const RemoteSchemaComponent: React.FC<RemoteSchemaComponentProps> = (prop
|
|||||||
}
|
}
|
||||||
return <SchemaComponent scope={scope} schema={schemaTransform(data?.data || {})} />;
|
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 { ISchemaFieldProps, Schema } from '@formily/react';
|
||||||
import React, { useContext, useEffect, useMemo, useRef } from 'react';
|
import React, { useContext, useMemo } from 'react';
|
||||||
import { SchemaComponentContext } from '../context';
|
import { SchemaComponentContext } from '../context';
|
||||||
|
|
||||||
function toSchema(schema?: any) {
|
function toSchema(schema?: any) {
|
||||||
@ -18,16 +18,8 @@ function toSchema(schema?: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SchemaComponent(props: ISchemaFieldProps) {
|
export function SchemaComponent(props: ISchemaFieldProps) {
|
||||||
const { schema: defaultSchema, ...others } = props;
|
const { schema, ...others } = props;
|
||||||
const { reset, SchemaField } = useContext(SchemaComponentContext);
|
const { SchemaField } = useContext(SchemaComponentContext);
|
||||||
const schema = useMemo(() => toSchema(defaultSchema), []);
|
const s = useMemo(() => toSchema(schema), []);
|
||||||
const isInitialMount = useRef(true);
|
return <SchemaField {...others} schema={s} />;
|
||||||
useEffect(() => {
|
|
||||||
if (isInitialMount.current) {
|
|
||||||
isInitialMount.current = false;
|
|
||||||
} else {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
}, [JSON.stringify(defaultSchema)]);
|
|
||||||
return <SchemaField {...others} schema={schema} />;
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (prop
|
|||||||
SchemaField,
|
SchemaField,
|
||||||
components,
|
components,
|
||||||
scope,
|
scope,
|
||||||
refreshFormId: () => setFormId(uid()),
|
|
||||||
reset: () => setFormId(uid()),
|
reset: () => setFormId(uid()),
|
||||||
refresh: () => setUid(uid()),
|
refresh: () => setUid(uid()),
|
||||||
designable: active === 'true',
|
designable: active === 'true',
|
||||||
|
@ -2,4 +2,5 @@ export * from './useAttach';
|
|||||||
export * from './useCompile';
|
export * from './useCompile';
|
||||||
export * from './useDesignable';
|
export * from './useDesignable';
|
||||||
export * from './useFieldProps';
|
export * from './useFieldProps';
|
||||||
|
export * from './useSchemaComponentContext';
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import { useContext } from 'react';
|
||||||
import { compile } from '@formily/json-schema/lib/compiler';
|
import { compile } from '@formily/json-schema/lib/compiler';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { SchemaExpressionScopeContext, SchemaOptionsContext } from '@formily/react';
|
||||||
|
|
||||||
export const useCompile = () => {
|
export const useCompile = () => {
|
||||||
const { t } = useTranslation();
|
const options = useContext(SchemaOptionsContext);
|
||||||
|
const scope = useContext(SchemaExpressionScopeContext);
|
||||||
return (source: any) => {
|
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
|
## Hooks
|
||||||
|
|
||||||
|
### useSchemaComponentContext()
|
||||||
|
|
||||||
|
获取 SchemaComponent 的上下文
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const { refresh, reset } = useSchemaComponentContext();
|
||||||
|
```
|
||||||
|
|
||||||
### useDesignable()
|
### useDesignable()
|
||||||
|
|
||||||
获取当前 schema 节点设计器的 API
|
获取当前 schema 节点设计器的 API
|
||||||
|
@ -19,7 +19,6 @@ export interface ISchemaComponentContext {
|
|||||||
scope?: any;
|
scope?: any;
|
||||||
components?: SchemaReactComponents;
|
components?: SchemaReactComponents;
|
||||||
refresh?: () => void;
|
refresh?: () => void;
|
||||||
refreshFormId?: () => void;
|
|
||||||
reset?: () => void;
|
reset?: () => void;
|
||||||
designable?: boolean;
|
designable?: boolean;
|
||||||
setDesignable?: (value: boolean) => void;
|
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"
|
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||||
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
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:
|
des.js@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
|
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"
|
statuses "^1.3.1"
|
||||||
utility "^1.16.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:
|
use-subscription@1.5.1:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
|
resolved "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
|
||||||
|
Loading…
Reference in New Issue
Block a user