fleet/frontend/pages/admin/OrgSettingsPage/OrgSettingsPage.tsx
Jacob Shandling 1183e47803
UI: Fix a bug in routing index for sandboxMode (#11399)
## Addresses #11394 (and dup #11397)

Lower sandbox reroute logic from router index into OrgSettingsPage,
where the value of AppContext.isSandboxMode can be correctly read

https://www.loom.com/share/8f3eb546a58d4c93a268b4d02b42c54c

## Checklist for submitter
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2023-04-27 15:17:08 -07:00

153 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useCallback, useContext, useState } from "react";
import { InjectedRouter, Params } from "react-router/lib/Router";
import { useQuery } from "react-query";
import { useErrorHandler } from "react-error-boundary";
import { IConfig } from "interfaces/config";
import { IApiError } from "interfaces/errors";
import configAPI from "services/entities/config";
import { AppContext } from "context/app";
import { NotificationContext } from "context/notification";
import deepDifference from "utilities/deep_difference";
import Spinner from "components/Spinner";
import paths from "router/paths";
import SideNav from "../components/SideNav";
import ORG_SETTINGS_NAV_ITEMS from "./OrgSettingsNavItems";
interface IOrgSettingsPageProps {
params: Params;
router: InjectedRouter; // v3
}
export const baseClass = "org-settings";
const OrgSettingsPage = ({ params, router }: IOrgSettingsPageProps) => {
const { section } = params;
const DEFAULT_SETTINGS_SECTION = ORG_SETTINGS_NAV_ITEMS[0];
const [isUpdatingSettings, setIsUpdatingSettings] = useState(false);
const { isFreeTier, isPremiumTier, setConfig, isSandboxMode } = useContext(
AppContext
);
if (isSandboxMode) {
// redirect to Integrations page in sandbox mode
router.push(paths.ADMIN_INTEGRATIONS);
}
const { renderFlash } = useContext(NotificationContext);
const handlePageError = useErrorHandler();
const {
data: appConfig,
isLoading: isLoadingAppConfig,
refetch: refetchConfig,
} = useQuery<IConfig, Error, IConfig>(["config"], () => configAPI.loadAll(), {
select: (data: IConfig) => data,
onSuccess: (data) => {
setConfig(data);
},
});
const onFormSubmit = useCallback(
(formUpdates: Partial<IConfig>) => {
if (!appConfig) {
return false;
}
setIsUpdatingSettings(true);
const diff = deepDifference(formUpdates, appConfig);
// send all formUpdates.agent_options because diff overrides all agent options
diff.agent_options = formUpdates.agent_options;
configAPI
.update(diff)
.then(() => {
renderFlash("success", "Successfully updated settings.");
refetchConfig();
})
.catch((response: { data: IApiError }) => {
if (
response?.data.errors[0].reason.includes("could not dial smtp host")
) {
renderFlash(
"error",
"Could not connect to SMTP server. Please try again."
);
} else if (response?.data.errors) {
const agentOptionsInvalid =
response.data.errors[0].reason.includes(
"unsupported key provided"
) ||
response.data.errors[0].reason.includes("invalid value type");
renderFlash(
"error",
<>
Could not update settings. {response.data.errors[0].reason}
{agentOptionsInvalid && (
<>
<br />
If youre not using the latest osquery, use the fleetctl
apply --force command to override validation.
</>
)}
</>
);
}
})
.finally(() => {
setIsUpdatingSettings(false);
});
},
[appConfig, refetchConfig, renderFlash]
);
// filter out non-premium options
let navItems = ORG_SETTINGS_NAV_ITEMS;
if (!isPremiumTier) {
navItems = ORG_SETTINGS_NAV_ITEMS.filter(
(item) => item.urlSection !== "fleet-desktop"
);
}
const currentFormSection =
navItems.find((item) => item.urlSection === section) ??
DEFAULT_SETTINGS_SECTION;
const CurrentCard = currentFormSection.Card;
if (isFreeTier && section === "fleet-desktop") {
handlePageError({ status: 403 });
return null;
}
return (
<div className={`${baseClass}`}>
<p className={`${baseClass}__page-description`}>
Set your organization information and configure SSO and SMTP
</p>
<SideNav
className={`${baseClass}__side-nav`}
navItems={navItems}
activeItem={currentFormSection.urlSection}
CurrentCard={
!isLoadingAppConfig && appConfig ? (
<CurrentCard
appConfig={appConfig}
handleSubmit={onFormSubmit}
isUpdatingSettings={isUpdatingSettings}
isPremiumTier={isPremiumTier}
/>
) : (
<Spinner />
)
}
/>
</div>
);
};
export default OrgSettingsPage;