fix: the left menu does not collapse when switching routes
This commit is contained in:
parent
85882f7c7a
commit
4f8cf13d1d
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { Layout, Spin } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import React, { createContext, useContext, useMemo, useRef } from 'react';
|
||||
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||
import {
|
||||
ACLAllowConfigure,
|
||||
@ -11,10 +11,11 @@ import {
|
||||
findMenuItem,
|
||||
PluginManager,
|
||||
RemoteCollectionManagerProvider,
|
||||
RemoteSchemaComponent,
|
||||
RemoteSchemaTemplateManagerProvider,
|
||||
SchemaComponent,
|
||||
useACLRoleContext,
|
||||
useDocumentTitle,
|
||||
useRequest,
|
||||
useRoute,
|
||||
useSystemSettings
|
||||
} from '../../../';
|
||||
@ -27,6 +28,9 @@ const filterByACL = (schema, options) => {
|
||||
return schema;
|
||||
}
|
||||
const filterSchema = (s) => {
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
for (const key in s.properties) {
|
||||
if (Object.prototype.hasOwnProperty.call(s.properties, key)) {
|
||||
const element = s.properties[key];
|
||||
@ -40,23 +44,74 @@ const filterByACL = (schema, options) => {
|
||||
return schema;
|
||||
};
|
||||
|
||||
const SchemaIdContext = createContext(null);
|
||||
const useMenuProps = () => {
|
||||
const defaultSelectedUid = useContext(SchemaIdContext);
|
||||
return {
|
||||
selectedUid: defaultSelectedUid,
|
||||
defaultSelectedUid,
|
||||
};
|
||||
};
|
||||
const MenuEditor = (props) => {
|
||||
const { setTitle } = useDocumentTitle();
|
||||
const history = useHistory();
|
||||
const match = useRouteMatch<any>();
|
||||
const defaultSelectedUid = match.params.name;
|
||||
const { sideMenuRef } = props;
|
||||
const ctx = useACLRoleContext();
|
||||
const route = useRoute();
|
||||
const onSelect = ({ item }) => {
|
||||
const schema = item.props.schema;
|
||||
setTitle(schema.title);
|
||||
history.push(`/admin/${schema['x-uid']}`);
|
||||
};
|
||||
const { data, loading } = useRequest(
|
||||
{
|
||||
url: `/uiSchemas:getJsonSchema/${route.uiSchemaUid}`,
|
||||
},
|
||||
{
|
||||
refreshDeps: [route.uiSchemaUid],
|
||||
onSuccess(data) {
|
||||
const schema = filterByACL(data?.data, ctx);
|
||||
if (defaultSelectedUid) {
|
||||
const s = findByUid(schema, defaultSelectedUid);
|
||||
if (s) {
|
||||
setTitle(s.title);
|
||||
}
|
||||
} else {
|
||||
const s = findMenuItem(schema);
|
||||
if (s) {
|
||||
history.push(`/admin/${s['x-uid']}`);
|
||||
setTitle(s.title);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
const schema = useMemo(() => {
|
||||
const s = filterByACL(data?.data, ctx);
|
||||
if (s?.['x-component-props']) {
|
||||
s['x-component-props']['useProps'] = useMenuProps;
|
||||
}
|
||||
return s;
|
||||
}, [data?.data]);
|
||||
if (loading) {
|
||||
return <Spin />;
|
||||
}
|
||||
return (
|
||||
<SchemaIdContext.Provider value={defaultSelectedUid}>
|
||||
<SchemaComponent memoized scope={{ useMenuProps, onSelect, sideMenuRef, defaultSelectedUid }} schema={schema} />
|
||||
</SchemaIdContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const InternalAdminLayout = (props: any) => {
|
||||
const route = useRoute();
|
||||
const history = useHistory();
|
||||
const match = useRouteMatch<any>();
|
||||
const { setTitle } = useDocumentTitle();
|
||||
const sideMenuRef = useRef();
|
||||
const defaultSelectedUid = match.params.name;
|
||||
const [schema, setSchema] = useState({});
|
||||
const ctx = useACLRoleContext();
|
||||
const onSelect = ({ item }) => {
|
||||
const schema = item.props.schema;
|
||||
console.log('onSelect', schema);
|
||||
setSchema(schema);
|
||||
setTitle(schema.title);
|
||||
history.push(`/admin/${schema['x-uid']}`);
|
||||
};
|
||||
const [hidden, setHidden] = useState(false);
|
||||
|
||||
const result = useSystemSettings();
|
||||
const { service } = useCollectionManager();
|
||||
return (
|
||||
@ -91,40 +146,7 @@ const InternalAdminLayout = (props: any) => {
|
||||
width: 'calc(100% - 590px)',
|
||||
}}
|
||||
>
|
||||
<RemoteSchemaComponent
|
||||
hidden={hidden}
|
||||
uid={route.uiSchemaUid}
|
||||
scope={{ onSelect, sideMenuRef, defaultSelectedUid }}
|
||||
schemaTransform={(data) => {
|
||||
if (!data) {
|
||||
return data;
|
||||
}
|
||||
data['x-component-props'] = data['x-component-props'] || {};
|
||||
data['x-component-props']['defaultSelectedUid'] = defaultSelectedUid;
|
||||
return filterByACL(data, ctx);
|
||||
}}
|
||||
onSuccess={(data) => {
|
||||
if (defaultSelectedUid && defaultSelectedUid.includes('/')) {
|
||||
return;
|
||||
}
|
||||
const schema = filterByACL(data?.data, ctx);
|
||||
if (defaultSelectedUid) {
|
||||
const s = findByUid(schema, defaultSelectedUid);
|
||||
if (s) {
|
||||
setTitle(s.title);
|
||||
return;
|
||||
}
|
||||
}
|
||||
setHidden(true);
|
||||
setTimeout(() => setHidden(false), 11);
|
||||
const s = findMenuItem(schema);
|
||||
if (s) {
|
||||
setSchema(s);
|
||||
setTitle(s.title);
|
||||
history.push(`/admin/${s['x-uid']}`);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<MenuEditor sideMenuRef={sideMenuRef} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ position: 'absolute', top: 0, right: 0 }}>
|
||||
|
@ -13,6 +13,7 @@ import { createPortal } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { createDesignable, DndContext, SortableItem, useDesignable, useDesigner } from '../..';
|
||||
import { Icon, useAPIClient, useSchemaInitializer } from '../../../';
|
||||
import { useProps } from '../../hooks/useProps';
|
||||
import { MenuDesigner } from './Menu.Designer';
|
||||
import { findKeysByUid, findMenuItem } from './util';
|
||||
|
||||
@ -139,12 +140,13 @@ export const Menu: ComposedMenu = observer((props) => {
|
||||
let {
|
||||
onSelect,
|
||||
mode,
|
||||
selectedUid,
|
||||
defaultSelectedUid,
|
||||
sideMenuRefScopeKey,
|
||||
defaultSelectedKeys: dSelectedKeys,
|
||||
defaultOpenKeys: dOpenKeys,
|
||||
...others
|
||||
} = props;
|
||||
} = useProps(props);
|
||||
const { t } = useTranslation();
|
||||
const Designer = useDesigner();
|
||||
const schema = useFieldSchema();
|
||||
@ -178,6 +180,24 @@ export const Menu: ComposedMenu = observer((props) => {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
useEffect(() => {
|
||||
const keys = findKeysByUid(schema, selectedUid);
|
||||
setDefaultSelectedKeys(keys);
|
||||
if (['inline', 'mix'].includes(mode)) {
|
||||
setDefaultOpenKeys(dOpenKeys || keys);
|
||||
}
|
||||
const key = keys?.[0] || null;
|
||||
if (mode === 'mix') {
|
||||
if (key) {
|
||||
const s = schema.properties?.[key];
|
||||
if (s['x-component'] === 'Menu.SubMenu') {
|
||||
setSideMenuSchema(s);
|
||||
}
|
||||
} else {
|
||||
setSideMenuSchema(null);
|
||||
}
|
||||
}
|
||||
}, [selectedUid]);
|
||||
useEffect(() => {
|
||||
if (['inline', 'mix'].includes(mode)) {
|
||||
setDefaultOpenKeys(defaultSelectedKeys);
|
||||
@ -244,8 +264,8 @@ export const Menu: ComposedMenu = observer((props) => {
|
||||
}
|
||||
}}
|
||||
mode={mode === 'mix' ? 'horizontal' : mode}
|
||||
defaultOpenKeys={defaultOpenKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
openKeys={defaultOpenKeys}
|
||||
selectedKeys={defaultSelectedKeys}
|
||||
>
|
||||
{designable && (
|
||||
<AntdMenu.Item disabled style={{ padding: '0 8px', order: 9999 }}>
|
||||
|
Loading…
Reference in New Issue
Block a user