mirror of
https://github.com/nocobase/nocobase
synced 2024-11-16 01:45:53 +00:00
fix(InternalAdminLayout): fix the issue of missing left sidebar menu
This commit is contained in:
parent
023aa0ce4f
commit
7efab73f0d
@ -40,6 +40,14 @@ MatchAdminContext.displayName = 'MatchAdminContext';
|
|||||||
const MatchAdminNameContext = React.createContext<PathMatch<string> | null>(null);
|
const MatchAdminNameContext = React.createContext<PathMatch<string> | null>(null);
|
||||||
MatchAdminNameContext.displayName = 'MatchAdminNameContext';
|
MatchAdminNameContext.displayName = 'MatchAdminNameContext';
|
||||||
|
|
||||||
|
const IsInSettingsPageContext = React.createContext<boolean>(false);
|
||||||
|
IsInSettingsPageContext.displayName = 'IsInSettingsPageContext';
|
||||||
|
|
||||||
|
const IsInSettingsPageProvider: FC = ({ children }) => {
|
||||||
|
const isInSettingsPage = useLocation().pathname.includes('/settings');
|
||||||
|
return <IsInSettingsPageContext.Provider value={isInSettingsPage}>{children}</IsInSettingsPageContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
const MatchAdminProvider: FC = ({ children }) => {
|
const MatchAdminProvider: FC = ({ children }) => {
|
||||||
const matchAdmin = useMatch('/admin');
|
const matchAdmin = useMatch('/admin');
|
||||||
return <MatchAdminContext.Provider value={matchAdmin}>{children}</MatchAdminContext.Provider>;
|
return <MatchAdminContext.Provider value={matchAdmin}>{children}</MatchAdminContext.Provider>;
|
||||||
@ -56,8 +64,8 @@ const IsAdminPageProvider: FC = ({ children }) => {
|
|||||||
return <IsAdminPageContext.Provider value={isAdminPage}>{children}</IsAdminPageContext.Provider>;
|
return <IsAdminPageContext.Provider value={isAdminPage}>{children}</IsAdminPageContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CurrentPageUidProvider: FC = ({ children }) => {
|
export const CurrentPageUidProvider: FC = ({ children }) => {
|
||||||
const params = useParams<any>();
|
const params = useParams();
|
||||||
return <CurrentPageUidContext.Provider value={params.name}>{children}</CurrentPageUidContext.Provider>;
|
return <CurrentPageUidContext.Provider value={params.name}>{children}</CurrentPageUidContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,17 +149,21 @@ export const useMatchAdminName = () => {
|
|||||||
return React.useContext(MatchAdminNameContext);
|
return React.useContext(MatchAdminNameContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useIsInSettingsPage = () => {
|
||||||
|
return React.useContext(IsInSettingsPageContext);
|
||||||
|
};
|
||||||
|
|
||||||
export const CustomRouterContextProvider: FC = ({ children }) => {
|
export const CustomRouterContextProvider: FC = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<NavigateNoUpdateProvider>
|
<NavigateNoUpdateProvider>
|
||||||
<LocationNoUpdateProvider>
|
<LocationNoUpdateProvider>
|
||||||
<IsAdminPageProvider>
|
<IsAdminPageProvider>
|
||||||
<LocationSearchProvider>
|
<LocationSearchProvider>
|
||||||
<CurrentPageUidProvider>
|
<MatchAdminProvider>
|
||||||
<MatchAdminProvider>
|
<MatchAdminNameProvider>
|
||||||
<MatchAdminNameProvider>{children}</MatchAdminNameProvider>
|
<IsInSettingsPageProvider>{children}</IsInSettingsPageProvider>
|
||||||
</MatchAdminProvider>
|
</MatchAdminNameProvider>
|
||||||
</CurrentPageUidProvider>
|
</MatchAdminProvider>
|
||||||
</LocationSearchProvider>
|
</LocationSearchProvider>
|
||||||
</IsAdminPageProvider>
|
</IsAdminPageProvider>
|
||||||
</LocationNoUpdateProvider>
|
</LocationNoUpdateProvider>
|
||||||
|
@ -12,7 +12,7 @@ import { useSessionStorageState } from 'ahooks';
|
|||||||
import { App, ConfigProvider, Divider, Layout } from 'antd';
|
import { App, ConfigProvider, Divider, Layout } from 'antd';
|
||||||
import { createGlobalStyle } from 'antd-style';
|
import { createGlobalStyle } from 'antd-style';
|
||||||
import React, { FC, createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { FC, createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { Link, Outlet, useParams } from 'react-router-dom';
|
import { Link, Outlet } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
ACLRolesCheckProvider,
|
ACLRolesCheckProvider,
|
||||||
CurrentAppInfoProvider,
|
CurrentAppInfoProvider,
|
||||||
@ -34,8 +34,9 @@ import {
|
|||||||
useToken,
|
useToken,
|
||||||
} from '../../../';
|
} from '../../../';
|
||||||
import {
|
import {
|
||||||
|
CurrentPageUidProvider,
|
||||||
useCurrentPageUid,
|
useCurrentPageUid,
|
||||||
useLocationNoUpdate,
|
useIsInSettingsPage,
|
||||||
useMatchAdmin,
|
useMatchAdmin,
|
||||||
useMatchAdminName,
|
useMatchAdminName,
|
||||||
useNavigateNoUpdate,
|
useNavigateNoUpdate,
|
||||||
@ -86,9 +87,9 @@ const MenuEditor = (props) => {
|
|||||||
const [, setHasNotice] = useSessionStorageState('plugin-notice', { defaultValue: false });
|
const [, setHasNotice] = useSessionStorageState('plugin-notice', { defaultValue: false });
|
||||||
const { t } = useMenuTranslation();
|
const { t } = useMenuTranslation();
|
||||||
const { setTitle: _setTitle } = useDocumentTitle();
|
const { setTitle: _setTitle } = useDocumentTitle();
|
||||||
const setTitle = useCallback((title) => _setTitle(t(title)), []);
|
const setTitle = useCallback((title) => _setTitle(t(title)), [_setTitle, t]);
|
||||||
const navigate = useNavigateNoUpdate();
|
const navigate = useNavigateNoUpdate();
|
||||||
const location = useLocationNoUpdate();
|
const isInSettingsPage = useIsInSettingsPage();
|
||||||
const isMatchAdmin = useMatchAdmin();
|
const isMatchAdmin = useMatchAdmin();
|
||||||
const isMatchAdminName = useMatchAdminName();
|
const isMatchAdminName = useMatchAdminName();
|
||||||
const currentPageUid = useCurrentPageUid();
|
const currentPageUid = useCurrentPageUid();
|
||||||
@ -97,12 +98,15 @@ const MenuEditor = (props) => {
|
|||||||
const ctx = useACLRoleContext();
|
const ctx = useACLRoleContext();
|
||||||
const [current, setCurrent] = useState(null);
|
const [current, setCurrent] = useState(null);
|
||||||
|
|
||||||
const onSelect = useCallback(({ item }: { item; key; keyPath; domEvent }) => {
|
const onSelect = useCallback(
|
||||||
const schema = item.props.schema;
|
({ item }: { item; key; keyPath; domEvent }) => {
|
||||||
setTitle(schema.title);
|
const schema = item.props.schema;
|
||||||
setCurrent(schema);
|
setTitle(schema.title);
|
||||||
navigate(`/admin/${schema['x-uid']}`);
|
setCurrent(schema);
|
||||||
}, []);
|
navigate(`/admin/${schema['x-uid']}`);
|
||||||
|
},
|
||||||
|
[navigate, setTitle],
|
||||||
|
);
|
||||||
const { render } = useAppSpin();
|
const { render } = useAppSpin();
|
||||||
const adminSchemaUid = useAdminSchemaUid();
|
const adminSchemaUid = useAdminSchemaUid();
|
||||||
const { data, loading } = useRequest<{
|
const { data, loading } = useRequest<{
|
||||||
@ -155,14 +159,13 @@ const MenuEditor = (props) => {
|
|||||||
Object.values(properties).find(
|
Object.values(properties).find(
|
||||||
(item) => item['x-uid'] === currentPageUid && item['x-component'] === 'Menu.Item',
|
(item) => item['x-uid'] === currentPageUid && item['x-component'] === 'Menu.Item',
|
||||||
);
|
);
|
||||||
const isSettingPage = location?.pathname.includes('/settings');
|
if (pageType || isInSettingsPage) {
|
||||||
if (pageType || isSettingPage) {
|
|
||||||
sideMenuRef.current.style.display = 'none';
|
sideMenuRef.current.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
sideMenuRef.current.style.display = 'block';
|
sideMenuRef.current.style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [data?.data, currentPageUid, sideMenuRef, location?.pathname]);
|
}, [current?.root?.properties, currentPageUid, data?.data?.properties, isInSettingsPage, sideMenuRef]);
|
||||||
|
|
||||||
const schema = useMemo(() => {
|
const schema = useMemo(() => {
|
||||||
const s = filterByACL(data?.data, ctx);
|
const s = filterByACL(data?.data, ctx);
|
||||||
@ -221,7 +224,7 @@ const MenuEditor = (props) => {
|
|||||||
|
|
||||||
const scope = useMemo(() => {
|
const scope = useMemo(() => {
|
||||||
return { useMenuProps, onSelect, sideMenuRef, defaultSelectedUid: currentPageUid };
|
return { useMenuProps, onSelect, sideMenuRef, defaultSelectedUid: currentPageUid };
|
||||||
}, []);
|
}, [currentPageUid, onSelect, sideMenuRef]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return render();
|
return render();
|
||||||
@ -322,8 +325,8 @@ const InternalAdminSideBar: FC<{ pageUid: string; sideMenuRef: any }> = memo((pr
|
|||||||
InternalAdminSideBar.displayName = 'InternalAdminSideBar';
|
InternalAdminSideBar.displayName = 'InternalAdminSideBar';
|
||||||
|
|
||||||
const AdminSideBar = ({ sideMenuRef }) => {
|
const AdminSideBar = ({ sideMenuRef }) => {
|
||||||
const params = useParams<any>();
|
const currentPageUid = useCurrentPageUid();
|
||||||
return <InternalAdminSideBar pageUid={params.name} sideMenuRef={sideMenuRef} />;
|
return <InternalAdminSideBar pageUid={currentPageUid} sideMenuRef={sideMenuRef} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AdminDynamicPage = () => {
|
export const AdminDynamicPage = () => {
|
||||||
@ -357,6 +360,60 @@ const layoutContentHeaderClass = css`
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const style1: any = {
|
||||||
|
position: 'relative',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
};
|
||||||
|
|
||||||
|
const style2: any = {
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: 1,
|
||||||
|
flex: '1 1 auto',
|
||||||
|
display: 'flex',
|
||||||
|
height: '100%',
|
||||||
|
};
|
||||||
|
|
||||||
|
const className1 = css`
|
||||||
|
width: 200px;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
const className2 = css`
|
||||||
|
padding: 0 16px;
|
||||||
|
object-fit: contain;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
`;
|
||||||
|
const className3 = css`
|
||||||
|
padding: 0 16px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
`;
|
||||||
|
const className4 = css`
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 0;
|
||||||
|
`;
|
||||||
|
const className5 = css`
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10;
|
||||||
|
`;
|
||||||
|
const theme = {
|
||||||
|
token: {
|
||||||
|
colorSplit: 'rgba(255, 255, 255, 0.1)',
|
||||||
|
},
|
||||||
|
};
|
||||||
export const InternalAdminLayout = () => {
|
export const InternalAdminLayout = () => {
|
||||||
const result = useSystemSettings();
|
const result = useSystemSettings();
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
@ -404,107 +461,48 @@ export const InternalAdminLayout = () => {
|
|||||||
token.colorBgHeader,
|
token.colorBgHeader,
|
||||||
token.colorTextHeaderMenu,
|
token.colorTextHeaderMenu,
|
||||||
]);
|
]);
|
||||||
|
const fontSizeStyle = useMemo(() => ({ fontSize: token.fontSizeHeading3 }), [token.fontSizeHeading3]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<GlobalStyleForAdminLayout />
|
<GlobalStyleForAdminLayout />
|
||||||
<Layout.Header className={layoutHeaderCss}>
|
<CurrentPageUidProvider>
|
||||||
<div
|
<Layout.Header className={layoutHeaderCss}>
|
||||||
style={{
|
<div style={style1}>
|
||||||
position: 'relative',
|
<div style={style2}>
|
||||||
width: '100%',
|
<div className={className1}>
|
||||||
height: '100%',
|
{result?.data?.data?.logo?.url ? (
|
||||||
display: 'flex',
|
<img className={className2} src={result?.data?.data?.logo?.url} />
|
||||||
}}
|
) : (
|
||||||
>
|
<span style={fontSizeStyle} className={className3}>
|
||||||
<div
|
{result?.data?.data?.title}
|
||||||
style={{
|
</span>
|
||||||
position: 'relative',
|
)}
|
||||||
zIndex: 1,
|
</div>
|
||||||
flex: '1 1 auto',
|
<div className={className4}>
|
||||||
display: 'flex',
|
<SetThemeOfHeaderSubmenu>
|
||||||
height: '100%',
|
<MenuEditor sideMenuRef={sideMenuRef} />
|
||||||
}}
|
</SetThemeOfHeaderSubmenu>
|
||||||
>
|
</div>
|
||||||
<div
|
|
||||||
className={css`
|
|
||||||
width: 200px;
|
|
||||||
display: inline-flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
color: #fff;
|
|
||||||
padding: 0;
|
|
||||||
align-items: center;
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{result?.data?.data?.logo?.url ? (
|
|
||||||
<img
|
|
||||||
className={css`
|
|
||||||
padding: 0 16px;
|
|
||||||
object-fit: contain;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
`}
|
|
||||||
src={result?.data?.data?.logo?.url}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span
|
|
||||||
style={{ fontSize: token.fontSizeHeading3 }}
|
|
||||||
className={css`
|
|
||||||
padding: 0 16px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{result?.data?.data?.title}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className={className5}>
|
||||||
className={css`
|
<PinnedPluginList />
|
||||||
flex: 1 1 auto;
|
<ConfigProvider theme={theme}>
|
||||||
width: 0;
|
<Divider type="vertical" />
|
||||||
`}
|
</ConfigProvider>
|
||||||
>
|
<Help />
|
||||||
<SetThemeOfHeaderSubmenu>
|
<CurrentUser />
|
||||||
<MenuEditor sideMenuRef={sideMenuRef} />
|
|
||||||
</SetThemeOfHeaderSubmenu>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
</Layout.Header>
|
||||||
className={css`
|
<AdminSideBar sideMenuRef={sideMenuRef} />
|
||||||
position: relative;
|
{/* Use the "nb-subpages-slot-without-header-and-side" class name to locate the position of the subpages */}
|
||||||
flex-shrink: 0;
|
<Layout.Content className={`${layoutContentClass} nb-subpages-slot-without-header-and-side`}>
|
||||||
height: 100%;
|
<header className={layoutContentHeaderClass}></header>
|
||||||
z-index: 10;
|
<Outlet />
|
||||||
`}
|
{/* {service.contentLoading ? render() : <Outlet />} */}
|
||||||
>
|
</Layout.Content>
|
||||||
<PinnedPluginList />
|
</CurrentPageUidProvider>
|
||||||
<ConfigProvider
|
|
||||||
theme={{
|
|
||||||
token: {
|
|
||||||
colorSplit: 'rgba(255, 255, 255, 0.1)',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
</ConfigProvider>
|
|
||||||
<Help />
|
|
||||||
<CurrentUser />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Layout.Header>
|
|
||||||
<AdminSideBar sideMenuRef={sideMenuRef} />
|
|
||||||
{/* Use the "nb-subpages-slot-without-header-and-side" class name to locate the position of the subpages */}
|
|
||||||
<Layout.Content className={`${layoutContentClass} nb-subpages-slot-without-header-and-side`}>
|
|
||||||
<header className={layoutContentHeaderClass}></header>
|
|
||||||
<Outlet />
|
|
||||||
{/* {service.contentLoading ? render() : <Outlet />} */}
|
|
||||||
</Layout.Content>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user