mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
WIP: sidebar overlay component.
This commit is contained in:
@@ -48,7 +48,7 @@ function App({ locale }) {
|
||||
<div className="App">
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path={'/auth'} component={Authentication} />
|
||||
{/* <Route path={'/auth'} component={Authentication} /> */}
|
||||
<Route path={'/'}>
|
||||
<PrivateRoute component={DashboardPrivatePages} />
|
||||
</Route>
|
||||
|
||||
@@ -17,6 +17,8 @@ import DrawersContainer from 'components/DrawersContainer';
|
||||
* Dashboard page.
|
||||
*/
|
||||
export default function Dashboard() {
|
||||
const dashboardContentRef = React.createRef();
|
||||
|
||||
return (
|
||||
<DashboardProvider>
|
||||
<Switch>
|
||||
@@ -29,8 +31,8 @@ export default function Dashboard() {
|
||||
|
||||
<Route path="/">
|
||||
<DashboardSplitPane>
|
||||
<Sidebar />
|
||||
<DashboardContent />
|
||||
<Sidebar dashboardContentRef={dashboardContentRef} />
|
||||
<DashboardContent ref={dashboardContentRef} />
|
||||
</DashboardSplitPane>
|
||||
</Route>
|
||||
</Switch>
|
||||
|
||||
@@ -5,14 +5,14 @@ import DashboardContentRoute from 'components/Dashboard/DashboardContentRoute';
|
||||
import DashboardFooter from 'components/Dashboard/DashboardFooter';
|
||||
import DashboardErrorBoundary from './DashboardErrorBoundary';
|
||||
|
||||
export default function () {
|
||||
export default React.forwardRef(({}, ref) => {
|
||||
return (
|
||||
<ErrorBoundary FallbackComponent={DashboardErrorBoundary}>
|
||||
<div className="dashboard-content" id="dashboard">
|
||||
<div className="dashboard-content" id="dashboard" ref={ref}>
|
||||
<DashboardTopbar />
|
||||
<DashboardContentRoute />
|
||||
<DashboardFooter />
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,16 +17,16 @@ export default function DashboardPrivatePages() {
|
||||
return (
|
||||
<PrivatePagesProvider>
|
||||
<Switch>
|
||||
<Route path={'/setup'}>
|
||||
{/* <Route path={'/setup'}>
|
||||
<EnsureOrganizationIsNotReady>
|
||||
<SetupWizardPage />
|
||||
</EnsureOrganizationIsNotReady>
|
||||
</Route>
|
||||
</Route> */}
|
||||
|
||||
<Route path='/'>
|
||||
<EnsureOrganizationIsReady>
|
||||
{/* <EnsureOrganizationIsReady> */}
|
||||
<Dashboard />
|
||||
</EnsureOrganizationIsReady>
|
||||
{/* </EnsureOrganizationIsReady> */}
|
||||
</Route>
|
||||
</Switch>
|
||||
</PrivatePagesProvider>
|
||||
|
||||
@@ -7,10 +7,10 @@ import { useCurrentOrganization } from '../../hooks/query/organization';
|
||||
*/
|
||||
export function PrivatePagesProvider({ children }) {
|
||||
// Fetches the current user's organization.
|
||||
const { isLoading } = useCurrentOrganization();
|
||||
// const { isLoading } = useCurrentOrganization();
|
||||
|
||||
return (
|
||||
<DashboardLoadingIndicator isLoading={isLoading}>
|
||||
<DashboardLoadingIndicator isLoading={false}>
|
||||
{children}
|
||||
</DashboardLoadingIndicator>
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Menu, MenuItem } from '@blueprintjs/core';
|
||||
import SidebarContainer from 'components/Sidebar/SidebarContainer';
|
||||
import SidebarHead from 'components/Sidebar/SidebarHead';
|
||||
import SidebarMenu from 'components/Sidebar/SidebarMenu';
|
||||
import SidebarOverlay from 'components/SidebarOverlay';
|
||||
|
||||
import 'style/containers/Dashboard/Sidebar.scss';
|
||||
|
||||
export default function Sidebar() {
|
||||
export default function Sidebar({ dashboardContentRef }) {
|
||||
return (
|
||||
<SidebarContainer>
|
||||
<SidebarHead />
|
||||
@@ -14,10 +14,8 @@ export default function Sidebar() {
|
||||
<div className="sidebar__menu">
|
||||
<SidebarMenu />
|
||||
</div>
|
||||
|
||||
<div class="sidebar__version">
|
||||
0.0.1-beta version.
|
||||
</div>
|
||||
|
||||
<div class="sidebar__version">0.0.1-beta version.</div>
|
||||
</SidebarContainer>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,15 @@ import Icon from 'components/Icon';
|
||||
import MenuItem from 'components/MenuItem';
|
||||
import { MenuItemLabel } from 'components';
|
||||
import classNames from 'classnames';
|
||||
import SidebarOverlay from 'components/SidebarOverlay';
|
||||
|
||||
export default function SidebarMenu() {
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
const [currentItem, setCurrentItem] = React.useState(null);
|
||||
|
||||
const menuItemsMapper = (list) => {
|
||||
return list.map((item, index) => {
|
||||
const children = Array.isArray(item.children)
|
||||
@@ -18,33 +22,41 @@ export default function SidebarMenu() {
|
||||
: null;
|
||||
|
||||
const matchPath = (pathname, path) => {
|
||||
return item.matchExact ? pathname === path : pathname.indexOf(path) !== -1;
|
||||
return item.matchExact
|
||||
? pathname === path
|
||||
: pathname.indexOf(path) !== -1;
|
||||
};
|
||||
const isActive = (item.children) ?
|
||||
item.children.some((c) => matchPath(location.pathname, c.href)) :
|
||||
(item.href && matchPath(location.pathname, item.href));
|
||||
const isActive = item.children
|
||||
? item.children.some((c) => matchPath(location.pathname, c.href))
|
||||
: item.href && matchPath(location.pathname, item.href);
|
||||
|
||||
const handleItemClick = () => {
|
||||
if (item.href) {
|
||||
history.push(item.href);
|
||||
}
|
||||
setIsOpen(true);
|
||||
setCurrentItem(item);
|
||||
};
|
||||
|
||||
const maybeRenderLabel = (item) => item.newTabHref ? (
|
||||
<Button
|
||||
className="menu-item__add-btn"
|
||||
icon={<Icon icon={'plus'} iconSize={16} />}
|
||||
onClick={(event) => {
|
||||
history.push(item.newTabHref);
|
||||
event.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
) : null;
|
||||
const maybeRenderLabel = (item) =>
|
||||
item.newTabHref ? (
|
||||
<Button
|
||||
className="menu-item__add-btn"
|
||||
icon={<Icon icon={'plus'} iconSize={16} />}
|
||||
onClick={(event) => {
|
||||
history.push(item.newTabHref);
|
||||
event.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return item.spacer ? (
|
||||
<div class="bp3-menu-spacer" style={{
|
||||
'height': `${item.spacer}px`,
|
||||
}}></div>
|
||||
<div
|
||||
class="bp3-menu-spacer"
|
||||
style={{
|
||||
height: `${item.spacer}px`,
|
||||
}}
|
||||
></div>
|
||||
) : item.divider ? (
|
||||
<MenuDivider key={index} title={item.title} />
|
||||
) : item.label ? (
|
||||
@@ -72,5 +84,14 @@ export default function SidebarMenu() {
|
||||
};
|
||||
const items = menuItemsMapper(sidebarMenuList);
|
||||
|
||||
return <Menu className="sidebar-menu">{items}</Menu>;
|
||||
return (
|
||||
<div>
|
||||
<Menu className="sidebar-menu">{items}</Menu>{' '}
|
||||
|
||||
<SidebarOverlay
|
||||
isOpen={isOpen}
|
||||
items={currentItem?.children || []}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { Scrollbar } from 'react-scrollbars-custom';
|
||||
|
||||
interface ISidebarOverlayContainerProps {
|
||||
children: JSX.Element | JSX.Element[],
|
||||
}
|
||||
|
||||
/**
|
||||
* Sidebar overlay container.
|
||||
*/
|
||||
export default function SidebarOverlayContainer({ children }: ISidebarOverlayContainerProps) {
|
||||
return (
|
||||
<div className={'sidebar-overlay__scroll-wrapper'}>
|
||||
<Scrollbar noDefaultStyles={true}>
|
||||
<div className="sidebar-overlay__inner">{children}</div>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
90
client/src/components/SidebarOverlay/index.tsx
Normal file
90
client/src/components/SidebarOverlay/index.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import React from 'react';
|
||||
import { Overlay } from '@blueprintjs/core';
|
||||
import { Link } from 'react-router-dom';
|
||||
import SidebarOverlayContainer from './SidebarOverlayContainer';
|
||||
|
||||
interface ISidebarOverlayItem {
|
||||
text: string;
|
||||
href: string;
|
||||
divider?: boolean;
|
||||
label?: boolean
|
||||
}
|
||||
|
||||
interface ISidebarOverlayProps {
|
||||
isOpen: boolean;
|
||||
items: ISidebarOverlayItem[];
|
||||
overlayProps: any;
|
||||
overlayContainerRef: any;
|
||||
}
|
||||
|
||||
interface ISidebarOverlayItemProps {
|
||||
text: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
interface ISidebarOverlayItemDivider {
|
||||
divider: boolean;
|
||||
}
|
||||
/**
|
||||
* Sidebar overlay item.
|
||||
*/
|
||||
function SidebarOverlayItem({ text, href }: ISidebarOverlayItemProps) {
|
||||
return (
|
||||
<div className="sidebar-overlay__item">
|
||||
<Link to={href}>{text}</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ISidebarOverlayItemLabel {
|
||||
text: string;
|
||||
}
|
||||
|
||||
function SidebarOverlayLabel({ text }: ISidebarOverlayItemLabel) {
|
||||
return <div className="sidebar-overlay__label">{text}</div>;
|
||||
}
|
||||
|
||||
function SidebarOverlayDivider() {
|
||||
return <div className={'sidebar-overlay__divider'}></div>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sidebar overlay component.
|
||||
*/
|
||||
export default function SidebarOverlay({
|
||||
isOpen = false,
|
||||
items,
|
||||
}: ISidebarOverlayProps) {
|
||||
//
|
||||
if (!isOpen) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const handleOverlayClose = () => {
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<Overlay
|
||||
isOpen={isOpen}
|
||||
portalContainer={document.getElementById('dashboard') || document.body}
|
||||
onClose={handleOverlayClose}
|
||||
>
|
||||
<div className="sidebar-overlay">
|
||||
<SidebarOverlayContainer>
|
||||
<div className="sidebar-overlay__menu">
|
||||
{items.map((item) =>
|
||||
item.divider ? (
|
||||
<SidebarOverlayDivider />
|
||||
) : item.label ? (
|
||||
<SidebarOverlayLabel text={item.text} />
|
||||
) : (
|
||||
<SidebarOverlayItem text={item.text} href={item.href} />
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</SidebarOverlayContainer>
|
||||
</div>
|
||||
</Overlay>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user