fleet/frontend/layouts/CoreLayout/CoreLayout.tsx
Carlo 715d963f82
My device page (self-service) for iOS/iPadOS (#35238)
Implements #32247. This is the complete feature branch, consolidating:

- https://github.com/fleetdm/fleet/pull/35018
- https://github.com/fleetdm/fleet/pull/34758
- https://github.com/fleetdm/fleet/pull/35009
- https://github.com/fleetdm/fleet/pull/35181
- https://github.com/fleetdm/fleet/pull/35342

---------

Co-authored-by: Jonathan Katz <44128041+jkatz01@users.noreply.github.com>
Co-authored-by: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
Co-authored-by: Martin Angers <martin.n.angers@gmail.com>
Co-authored-by: jkatz01 <yehonatankatz@gmail.com>
2025-11-07 17:30:51 -05:00

100 lines
2.8 KiB
TypeScript

import React, { useContext } from "react";
import { InjectedRouter } from "react-router";
import UnsupportedScreenSize from "layouts/UnsupportedScreenSize";
import { AppContext } from "context/app";
import { NotificationContext } from "context/notification";
import { TableContext } from "context/table";
import { INotification } from "interfaces/notification";
import classNames from "classnames";
import paths from "router/paths";
import useDeepEffect from "hooks/useDeepEffect";
import FlashMessage from "components/FlashMessage";
import SiteTopNav from "components/top_nav/SiteTopNav";
import { QueryParams } from "utilities/url";
import shouldShowUnsupportedScreen from "layouts/UnsupportedScreenSize/helpers";
interface ICoreLayoutProps {
children: React.ReactNode;
router: InjectedRouter; // v3
// TODO: standardize typing and usage of location across app components
location: {
pathname: string;
search: string;
hash?: string;
query: QueryParams;
};
}
const CoreLayout = ({ children, router, location }: ICoreLayoutProps) => {
const { config, currentUser } = useContext(AppContext);
const { notification, hideFlash } = useContext(NotificationContext);
const { setResetSelectedRows } = useContext(TableContext);
// on success of an action, the table will reset its checkboxes.
// setTimeout is to help with race conditions as table reloads
// in some instances (i.e. Manage Hosts)
useDeepEffect(() => {
if (
notification &&
(notification as INotification).alertType === "success"
) {
setTimeout(() => {
setResetSelectedRows(true);
setTimeout(() => {
setResetSelectedRows(false);
}, 300);
}, 0);
}
}, [notification]);
const onLogoutUser = async () => {
const { LOGOUT } = paths;
router.push(LOGOUT);
};
const onUserMenuItemClick = (path: string) => {
router.push(path);
};
const fullWidthFlash = !currentUser;
if (!currentUser || !config) {
return null;
}
const coreWrapperClassnames = classNames("core-wrapper", {
"low-width-supported": !shouldShowUnsupportedScreen(location.pathname),
});
return (
<div className="app-wrap">
{shouldShowUnsupportedScreen(location.pathname) && (
<UnsupportedScreenSize />
)}
<nav className="site-nav-container">
<SiteTopNav
config={config}
currentUser={currentUser}
location={location}
onLogoutUser={onLogoutUser}
onUserMenuItemClick={onUserMenuItemClick}
/>
</nav>
<div className={coreWrapperClassnames}>
<FlashMessage
fullWidth={fullWidthFlash}
notification={notification}
onRemoveFlash={hideFlash}
pathname={location.pathname}
/>
{children}
</div>
</div>
);
};
export default CoreLayout;