mirror of
https://github.com/fleetdm/fleet
synced 2026-05-22 16:39:01 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** For #41030 # Details This PR updates front-end routes and redirects the old routes to the new ones. While I typically have shied away from renaming vars and constants in this phase of the renaming work, I chose to rename the path constants here because they're a lot less useful when they have names that don't correspond to the paths they're representing. I did the renames using VSCode's "Rename Symbol" feature which automatically finds and fixes any references. I then asked Claude to verify the changes and it didn't find any dangling references (also the code would fail to compile unless all the new names collided with old ones). # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. n/a ## Testing - [ ] Added/updated automated tests no relevant tests exist - [X] QA'd all new/changed functionality manually ## Reports (formerly Queries) **New routes:** - [x] /reports/manage — Reports list page - [x] /reports/new — New report editor - [x] /reports/new/live — New report live query - [x] /reports/:id — Report details - [x] /reports/:id/edit — Edit report - [x] /reports/:id/live — Live report run **Redirects from old routes:** - [x] /queries → /reports - [x] /queries/manage → /reports/manage - [x] /queries/new → /reports/new - [x] /queries/new/live → /reports/new/live - [x] /queries/:id → /reports/:id - [x] /queries/:id/edit → /reports/:id/edit - [x] /queries/:id/live → /reports/:id/live ## Host Reports (formerly Host Queries) **New routes:** - [x] /hosts/:host_id/reports/:query_id — Host report results **Redirects from old routes:** - [ ] ~/hosts/:host_id/schedule → /hosts/:host_id/reports~ <- this is not a real URL; removed current broken redirect - [x] /hosts/:host_id/queries/:query_id → /hosts/:host_id/reports/:query_id ## Fleets (formerly Teams) **New routes:** - [x] /settings/fleets — Fleets list page - [x] /settings/fleets/users?fleet_id=:id — Fleet users - [x] /settings/fleets/options?fleet_id=:id — Fleet agent options - [x] /settings/fleets/settings?fleet_id=:id — Fleet settings **Redirects from old routes:** - [x] /settings/teams → /settings/fleets - [x] /settings/teams/users → /settings/fleets/users - [x] /settings/teams/options → /settings/fleets/options - [x] /settings/teams/settings → /settings/fleets/settings - [x] /settings/teams/:team_id → /settings/fleets - [x] /settings/teams/:team_id/users → /settings/fleets - [x] /settings/teams/:team_id/options → /settings/fleets **Navigation & Links** - [x] Top nav "Reports" link goes to /reports/manage - [x] User menu team switcher navigates to /settings/fleets/users?fleet_id=:id - [x] Admin sidebar "Fleets" tab goes to /settings/fleets - [x] "Create a fleet" links (user form, transfer host modal) go to /settings/fleets - [x] "Back to fleets" button on fleet details goes to /settings/fleets - [x] Fleet table name links go to /settings/fleets/users?fleet_id=:id - [x] Host details "Add query" button goes to /reports/new - [x] Select query modal links go to /reports/new and /reports/:id/edit - [x] Query report "full report" link goes to /reports/:id - [x] Browser tab titles show correct names for report pages **Query params preserved through redirects** - [x] /queries/:id?fleet_id=1 → /reports/:id?fleet_id=1 - [x] /settings/teams/users?fleet_id=1 → /settings/fleets/users?fleet_id=1 For unreleased bug fixes in a release candidate, one of: - [X] Confirmed that the fix is not expected to adversely impact load test results
107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
import React, { useContext } from "react";
|
|
|
|
import { Tab, Tabs, TabList } from "react-tabs";
|
|
import { InjectedRouter } from "react-router";
|
|
import PATHS from "router/paths";
|
|
import { AppContext } from "context/app";
|
|
|
|
import TabNav from "components/TabNav";
|
|
import MainContent from "components/MainContent";
|
|
import TabText from "components/TabText";
|
|
import classnames from "classnames";
|
|
|
|
interface ISettingSubNavItem {
|
|
name: string;
|
|
pathname: string;
|
|
exclude?: boolean;
|
|
}
|
|
|
|
interface ISettingsWrapperProp {
|
|
children: JSX.Element;
|
|
location: {
|
|
pathname: string;
|
|
};
|
|
router: InjectedRouter; // v3
|
|
}
|
|
|
|
const baseClass = "admin-wrapper";
|
|
|
|
const AdminWrapper = ({
|
|
children,
|
|
location: { pathname },
|
|
router,
|
|
}: ISettingsWrapperProp): JSX.Element => {
|
|
const { isPremiumTier, isSandboxMode } = useContext(AppContext);
|
|
|
|
const settingsSubNav: ISettingSubNavItem[] = [
|
|
{
|
|
name: "Organization settings",
|
|
pathname: PATHS.ADMIN_ORGANIZATION,
|
|
exclude: isSandboxMode,
|
|
},
|
|
{
|
|
name: "Integrations",
|
|
pathname: PATHS.ADMIN_INTEGRATIONS,
|
|
},
|
|
{
|
|
name: "Users",
|
|
pathname: PATHS.ADMIN_USERS,
|
|
exclude: isSandboxMode,
|
|
},
|
|
{
|
|
name: "Fleets",
|
|
pathname: PATHS.ADMIN_FLEETS,
|
|
exclude: !isPremiumTier,
|
|
},
|
|
];
|
|
|
|
const filteredSettingsSubNav = settingsSubNav.filter((navItem) => {
|
|
return !navItem.exclude;
|
|
});
|
|
|
|
const navigateToNav = (i: number): void => {
|
|
const navPath = filteredSettingsSubNav[i].pathname;
|
|
router.push(navPath);
|
|
};
|
|
|
|
const getTabIndex = (path: string): number => {
|
|
return filteredSettingsSubNav.findIndex((navItem) => {
|
|
// tab stays highlighted for paths that start with same pathname
|
|
return path.startsWith(navItem.pathname);
|
|
});
|
|
};
|
|
|
|
// we add a conditional sandbox-mode class here as we will need to make some
|
|
// styling changes on the settings page to have the sticky elements work
|
|
// with the sandbox mode expiry message
|
|
const classNames = classnames(baseClass, { "sandbox-mode": isSandboxMode });
|
|
|
|
return (
|
|
<MainContent className={classNames}>
|
|
<>
|
|
<h1 className="page-header">Settings</h1>
|
|
<TabNav>
|
|
<Tabs
|
|
selectedIndex={getTabIndex(pathname)}
|
|
onSelect={(i) => navigateToNav(i)}
|
|
>
|
|
<TabList>
|
|
{filteredSettingsSubNav.map((navItem) => {
|
|
// Bolding text when the tab is active causes a layout shift
|
|
// so we add a hidden pseudo element with the same text string
|
|
return (
|
|
<Tab key={navItem.name} data-text={navItem.name}>
|
|
<TabText>{navItem.name}</TabText>
|
|
</Tab>
|
|
);
|
|
})}
|
|
</TabList>
|
|
</Tabs>
|
|
</TabNav>
|
|
{children}
|
|
</>
|
|
</MainContent>
|
|
);
|
|
};
|
|
|
|
export default AdminWrapper;
|