Skip to content

Commit 498e7ba

Browse files
committed
break out DeploymentSettingsProvider
1 parent 7cb20d7 commit 498e7ba

File tree

14 files changed

+146
-88
lines changed

14 files changed

+146
-88
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { DeploymentConfig } from "api/api";
2+
import { deploymentConfig } from "api/queries/deployment";
3+
import { ErrorAlert } from "components/Alert/ErrorAlert";
4+
import { Loader } from "components/Loader/Loader";
5+
import { useAuthenticated } from "contexts/auth/RequireAuth";
6+
import { RequirePermission } from "contexts/auth/RequirePermission";
7+
import { type FC, createContext, useContext } from "react";
8+
import { useQuery } from "react-query";
9+
import { Outlet } from "react-router-dom";
10+
11+
export const DeploymentSettingsContext = createContext<
12+
DeploymentSettingsValue | undefined
13+
>(undefined);
14+
15+
type DeploymentSettingsValue = Readonly<{
16+
deploymentConfig: DeploymentConfig;
17+
}>;
18+
19+
export const useDeploymentSettings = (): DeploymentSettingsValue => {
20+
const context = useContext(DeploymentSettingsContext);
21+
if (!context) {
22+
throw new Error(
23+
"useDeploymentSettings should be used inside of DeploymentSettingsLayout",
24+
);
25+
}
26+
27+
return context;
28+
};
29+
30+
const DeploymentSettingsProvider: FC = () => {
31+
const { permissions } = useAuthenticated();
32+
const deploymentConfigQuery = useQuery(deploymentConfig());
33+
34+
// The deployment settings page also contains users, audit logs, groups and
35+
// organizations, so this page must be visible if you can see any of these.
36+
const canViewDeploymentSettingsPage =
37+
permissions.viewDeploymentValues ||
38+
permissions.viewAllUsers ||
39+
permissions.editAnyOrganization ||
40+
permissions.viewAnyAuditLog;
41+
42+
if (deploymentConfigQuery.error) {
43+
return <ErrorAlert error={deploymentConfigQuery.error} />;
44+
}
45+
46+
if (!deploymentConfigQuery.data) {
47+
return <Loader />;
48+
}
49+
50+
return (
51+
<RequirePermission isFeatureVisible={canViewDeploymentSettingsPage}>
52+
<DeploymentSettingsContext.Provider
53+
value={{ deploymentConfig: deploymentConfigQuery.data }}
54+
>
55+
<Outlet />
56+
</DeploymentSettingsContext.Provider>
57+
</RequirePermission>
58+
);
59+
};
60+
61+
export default DeploymentSettingsProvider;

site/src/modules/management/ManagementSettingsLayout.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import type { DeploymentConfig } from "api/api";
2-
import { deploymentConfig } from "api/queries/deployment";
31
import type { AuthorizationResponse, Organization } from "api/typesGenerated";
4-
import { ErrorAlert } from "components/Alert/ErrorAlert";
52
import { Loader } from "components/Loader/Loader";
63
import { Margins } from "components/Margins/Margins";
74
import { Stack } from "components/Stack/Stack";
85
import { useAuthenticated } from "contexts/auth/RequireAuth";
96
import { RequirePermission } from "contexts/auth/RequirePermission";
107
import { useDashboard } from "modules/dashboard/useDashboard";
118
import { type FC, Suspense, createContext, useContext } from "react";
12-
import { useQuery } from "react-query";
139
import { Outlet, useParams } from "react-router-dom";
1410
import { Sidebar } from "./Sidebar";
1511

@@ -18,7 +14,6 @@ export const ManagementSettingsContext = createContext<
1814
>(undefined);
1915

2016
type ManagementSettingsValue = Readonly<{
21-
deploymentValues: DeploymentConfig;
2217
organizations: readonly Organization[];
2318
organization?: Organization;
2419
}>;
@@ -48,15 +43,8 @@ export const canEditOrganization = (
4843
);
4944
};
5045

51-
/**
52-
* A multi-org capable settings page layout.
53-
*
54-
* If multi-org is not enabled or licensed, this is the wrong layout to use.
55-
* See DeploySettingsLayoutInner instead.
56-
*/
57-
export const ManagementSettingsLayout: FC = () => {
46+
const ManagementSettingsLayout: FC = () => {
5847
const { permissions } = useAuthenticated();
59-
const deploymentConfigQuery = useQuery(deploymentConfig());
6048
const { organizations } = useDashboard();
6149
const { organization: orgName } = useParams() as {
6250
organization?: string;
@@ -70,14 +58,6 @@ export const ManagementSettingsLayout: FC = () => {
7058
permissions.editAnyOrganization ||
7159
permissions.viewAnyAuditLog;
7260

73-
if (deploymentConfigQuery.error) {
74-
return <ErrorAlert error={deploymentConfigQuery.error} />;
75-
}
76-
77-
if (!deploymentConfigQuery.data) {
78-
return <Loader />;
79-
}
80-
8161
const organization =
8262
organizations && orgName
8363
? organizations.find((org) => org.name === orgName)
@@ -87,7 +67,6 @@ export const ManagementSettingsLayout: FC = () => {
8767
<RequirePermission isFeatureVisible={canViewDeploymentSettingsPage}>
8868
<ManagementSettingsContext.Provider
8969
value={{
90-
deploymentValues: deploymentConfigQuery.data,
9170
organizations,
9271
organization,
9372
}}
@@ -106,3 +85,5 @@ export const ManagementSettingsLayout: FC = () => {
10685
</RequirePermission>
10786
);
10887
};
88+
89+
export default ManagementSettingsLayout;

site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { Loader } from "components/Loader/Loader";
2-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
32
import type { FC } from "react";
43
import { Helmet } from "react-helmet-async";
54
import { pageTitle } from "utils/page";
65
import { ExternalAuthSettingsPageView } from "./ExternalAuthSettingsPageView";
6+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
77

88
const ExternalAuthSettingsPage: FC = () => {
9-
const { deploymentValues } = useManagementSettings();
9+
const { deploymentConfig } = useDeploymentSettings();
1010

1111
return (
1212
<>
1313
<Helmet>
1414
<title>{pageTitle("External Authentication Settings")}</title>
1515
</Helmet>
1616

17-
{deploymentValues ? (
18-
<ExternalAuthSettingsPageView config={deploymentValues.config} />
17+
{deploymentConfig ? (
18+
<ExternalAuthSettingsPageView config={deploymentConfig.config} />
1919
) : (
2020
<Loader />
2121
)}

site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { entitlements } from "api/queries/entitlements";
33
import { availableExperiments, experiments } from "api/queries/experiments";
44
import { Loader } from "components/Loader/Loader";
55
import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata";
6-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
76
import type { FC } from "react";
87
import { Helmet } from "react-helmet-async";
98
import { useQuery } from "react-query";
109
import { pageTitle } from "utils/page";
1110
import { GeneralSettingsPageView } from "./GeneralSettingsPageView";
11+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
1212

1313
const GeneralSettingsPage: FC = () => {
14-
const { deploymentValues } = useManagementSettings();
14+
const { deploymentConfig } = useDeploymentSettings();
1515
const deploymentDAUsQuery = useQuery(deploymentDAUs());
1616
const safeExperimentsQuery = useQuery(availableExperiments());
1717

@@ -30,9 +30,9 @@ const GeneralSettingsPage: FC = () => {
3030
<Helmet>
3131
<title>{pageTitle("General Settings")}</title>
3232
</Helmet>
33-
{deploymentValues ? (
33+
{deploymentConfig ? (
3434
<GeneralSettingsPageView
35-
deploymentOptions={deploymentValues.options}
35+
deploymentOptions={deploymentConfig.options}
3636
deploymentDAUs={deploymentDAUsQuery.data}
3737
deploymentDAUsError={deploymentDAUsQuery.error}
3838
entitlements={entitlementsQuery.data}

site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { Loader } from "components/Loader/Loader";
2-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
32
import type { FC } from "react";
43
import { Helmet } from "react-helmet-async";
54
import { pageTitle } from "utils/page";
65
import { NetworkSettingsPageView } from "./NetworkSettingsPageView";
6+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
77

88
const NetworkSettingsPage: FC = () => {
9-
const { deploymentValues } = useManagementSettings();
9+
const { deploymentConfig } = useDeploymentSettings();
1010

1111
return (
1212
<>
1313
<Helmet>
1414
<title>{pageTitle("Network Settings")}</title>
1515
</Helmet>
1616

17-
{deploymentValues ? (
18-
<NetworkSettingsPageView options={deploymentValues.options} />
17+
{deploymentConfig ? (
18+
<NetworkSettingsPageView options={deploymentConfig.options} />
1919
) : (
2020
<Loader />
2121
)}

site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.stories.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const meta: Meta<typeof NotificationEvents> = {
1414
defaultMethod: "smtp",
1515
availableMethods: ["smtp", "webhook"],
1616
templatesByGroup: selectTemplatesByGroup(MockNotificationTemplates),
17-
deploymentValues: baseMeta.parameters.deploymentValues,
17+
deploymentConfig: baseMeta.parameters.deploymentValues,
1818
},
1919
...baseMeta,
2020
};
@@ -25,7 +25,7 @@ type Story = StoryObj<typeof NotificationEvents>;
2525

2626
export const SMTPNotConfigured: Story = {
2727
args: {
28-
deploymentValues: {
28+
deploymentConfig: {
2929
notifications: {
3030
webhook: {
3131
endpoint: "https://example.com",
@@ -40,7 +40,7 @@ export const SMTPNotConfigured: Story = {
4040

4141
export const WebhookNotConfigured: Story = {
4242
args: {
43-
deploymentValues: {
43+
deploymentConfig: {
4444
notifications: {
4545
webhook: {
4646
endpoint: "",

site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@ type NotificationEventsProps = {
3131
defaultMethod: NotificationMethod;
3232
availableMethods: NotificationMethod[];
3333
templatesByGroup: ReturnType<typeof selectTemplatesByGroup>;
34-
deploymentValues: DeploymentValues;
34+
deploymentConfig: DeploymentValues;
3535
};
3636

3737
export const NotificationEvents: FC<NotificationEventsProps> = ({
3838
defaultMethod,
3939
availableMethods,
4040
templatesByGroup,
41-
deploymentValues,
41+
deploymentConfig,
4242
}) => {
4343
// Webhook
4444
const hasWebhookNotifications = Object.values(templatesByGroup)
4545
.flat()
4646
.some((t) => t.method === "webhook");
47-
const webhookValues = deploymentValues.notifications?.webhook ?? {};
47+
const webhookValues = deploymentConfig.notifications?.webhook ?? {};
4848
const isWebhookConfigured = requiredFieldsArePresent(webhookValues, [
4949
"endpoint",
5050
]);
@@ -53,7 +53,7 @@ export const NotificationEvents: FC<NotificationEventsProps> = ({
5353
const hasSMTPNotifications = Object.values(templatesByGroup)
5454
.flat()
5555
.some((t) => t.method === "smtp");
56-
const smtpValues = deploymentValues.notifications?.email ?? {};
56+
const smtpValues = deploymentConfig.notifications?.email ?? {};
5757
const isSMTPConfigured = requiredFieldsArePresent(smtpValues, [
5858
"smarthost",
5959
"from",

site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
} from "api/queries/notifications";
77
import { Loader } from "components/Loader/Loader";
88
import { TabLink, Tabs, TabsList } from "components/Tabs/Tabs";
9-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
109
import { castNotificationMethod } from "modules/notifications/utils";
1110
import { Section } from "pages/UserSettingsPage/Section";
1211
import type { FC } from "react";
@@ -17,10 +16,11 @@ import { deploymentGroupHasParent } from "utils/deployOptions";
1716
import { pageTitle } from "utils/page";
1817
import OptionsTable from "../OptionsTable";
1918
import { NotificationEvents } from "./NotificationEvents";
19+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
2020

2121
export const NotificationsPage: FC = () => {
2222
const [searchParams] = useSearchParams();
23-
const { deploymentValues } = useManagementSettings();
23+
const { deploymentConfig } = useDeploymentSettings();
2424
const [templatesByGroup, dispatchMethods] = useQueries({
2525
queries: [
2626
{
@@ -31,7 +31,7 @@ export const NotificationsPage: FC = () => {
3131
],
3232
});
3333
const ready =
34-
templatesByGroup.data && dispatchMethods.data && deploymentValues;
34+
templatesByGroup.data && dispatchMethods.data && deploymentConfig;
3535
const tab = searchParams.get("tab") || "events";
3636

3737
return (
@@ -61,7 +61,7 @@ export const NotificationsPage: FC = () => {
6161
tab === "events" ? (
6262
<NotificationEvents
6363
templatesByGroup={templatesByGroup.data}
64-
deploymentValues={deploymentValues.config}
64+
deploymentConfig={deploymentConfig.config}
6565
defaultMethod={castNotificationMethod(
6666
dispatchMethods.data.default,
6767
)}
@@ -71,7 +71,7 @@ export const NotificationsPage: FC = () => {
7171
/>
7272
) : (
7373
<OptionsTable
74-
options={deploymentValues?.options.filter((o) =>
74+
options={deploymentConfig?.options.filter((o) =>
7575
deploymentGroupHasParent(o.group, "Notifications"),
7676
)}
7777
/>

site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Loader } from "components/Loader/Loader";
22
import { useDashboard } from "modules/dashboard/useDashboard";
33
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
4-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
54
import type { FC } from "react";
65
import { Helmet } from "react-helmet-async";
76
import { pageTitle } from "utils/page";
87
import { ObservabilitySettingsPageView } from "./ObservabilitySettingsPageView";
8+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
99

1010
const ObservabilitySettingsPage: FC = () => {
11-
const { deploymentValues } = useManagementSettings();
11+
const { deploymentConfig } = useDeploymentSettings();
1212
const { entitlements } = useDashboard();
1313
const { multiple_organizations: hasPremiumLicense } = useFeatureVisibility();
1414

@@ -18,9 +18,9 @@ const ObservabilitySettingsPage: FC = () => {
1818
<title>{pageTitle("Observability Settings")}</title>
1919
</Helmet>
2020

21-
{deploymentValues ? (
21+
{deploymentConfig ? (
2222
<ObservabilitySettingsPageView
23-
options={deploymentValues.options}
23+
options={deploymentConfig.options}
2424
featureAuditLogEnabled={entitlements.features.audit_log.enabled}
2525
isPremium={hasPremiumLicense}
2626
/>

site/src/pages/DeploymentSettingsPage/SecuritySettingsPage/SecuritySettingsPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { Loader } from "components/Loader/Loader";
22
import { useDashboard } from "modules/dashboard/useDashboard";
3-
import { useManagementSettings } from "modules/management/ManagementSettingsLayout";
43
import type { FC } from "react";
54
import { Helmet } from "react-helmet-async";
65
import { pageTitle } from "utils/page";
76
import { SecuritySettingsPageView } from "./SecuritySettingsPageView";
7+
import { useDeploymentSettings } from "modules/management/DeploymentSettingsProvider";
88

99
const SecuritySettingsPage: FC = () => {
10-
const { deploymentValues } = useManagementSettings();
10+
const { deploymentConfig } = useDeploymentSettings();
1111
const { entitlements } = useDashboard();
1212

1313
return (
@@ -16,9 +16,9 @@ const SecuritySettingsPage: FC = () => {
1616
<title>{pageTitle("Security Settings")}</title>
1717
</Helmet>
1818

19-
{deploymentValues ? (
19+
{deploymentConfig ? (
2020
<SecuritySettingsPageView
21-
options={deploymentValues.options}
21+
options={deploymentConfig.options}
2222
featureBrowserOnlyEnabled={entitlements.features.browser_only.enabled}
2323
/>
2424
) : (

0 commit comments

Comments
 (0)