diff --git a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPage.tsx b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPage.tsx
index 0a4272cc47589..5842f6d3696c8 100644
--- a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPage.tsx
+++ b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPage.tsx
@@ -5,11 +5,12 @@ import {
groupIdpSyncSettings,
roleIdpSyncSettings,
} from "api/queries/organizations";
-import { ErrorAlert } from "components/Alert/ErrorAlert";
+import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
import { EmptyState } from "components/EmptyState/EmptyState";
-import { Loader } from "components/Loader/Loader";
+import { Paywall } from "components/Paywall/Paywall";
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
import { Stack } from "components/Stack/Stack";
+import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
import type { FC } from "react";
import { Helmet } from "react-helmet-async";
import { useQueries } from "react-query";
@@ -24,6 +25,8 @@ export const IdpSyncPage: FC = () => {
const { organization: organizationName } = useParams() as {
organization: string;
};
+ // IdP sync does not have its own entitlement and is based on templace_rbac
+ const { template_rbac: isIdpSyncEnabled } = useFeatureVisibility();
const { organizations } = useOrganizationSettings();
const organization = organizations?.find((o) => o.name === organizationName);
@@ -40,26 +43,10 @@ export const IdpSyncPage: FC = () => {
return ;
}
- if (
- groupsQuery.isLoading ||
- groupIdpSyncSettingsQuery.isLoading ||
- roleIdpSyncSettingsQuery.isLoading
- ) {
- return ;
- }
-
const error =
groupIdpSyncSettingsQuery.error ||
roleIdpSyncSettingsQuery.error ||
groupsQuery.error;
- if (
- error ||
- !groupIdpSyncSettingsQuery.data ||
- !roleIdpSyncSettingsQuery.data ||
- !groupsQuery.data
- ) {
- return ;
- }
const groupsMap = new Map();
if (groupsQuery.data) {
@@ -84,25 +71,34 @@ export const IdpSyncPage: FC = () => {
description="Group and role sync mappings (configured using Coder CLI)."
tooltip={}
/>
-
- }
- component="a"
- href={docs("/admin/auth#group-sync-enterprise")}
- target="_blank"
- >
- Setup IdP Sync
-
-
+ }
+ component="a"
+ href={docs("/admin/auth#group-sync-enterprise")}
+ target="_blank"
+ >
+ Setup IdP Sync
+
-
-
+
+
+
+
+
+
+
+
>
);
};
diff --git a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx
index 646e64d763b86..608c62103b543 100644
--- a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx
+++ b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx
@@ -4,6 +4,7 @@ import {
MockGroup2,
MockGroupSyncSettings,
MockGroupSyncSettings2,
+ MockOrganization,
MockRoleSyncSettings,
} from "testHelpers/entities";
import { IdpSyncPageView } from "./IdpSyncPageView";
@@ -24,9 +25,31 @@ for (const group of [MockGroup, MockGroup2]) {
export const Empty: Story = {
args: {
- groupSyncSettings: undefined,
- roleSyncSettings: undefined,
+ groupSyncSettings: {
+ field: "",
+ mapping: {},
+ regex_filter: "",
+ auto_create_missing_groups: false,
+ },
+ roleSyncSettings: {
+ field: "",
+ mapping: {},
+ },
+ groups: [],
groupsMap: undefined,
+ organization: MockOrganization,
+ error: undefined,
+ },
+};
+
+export const HasError: Story = {
+ args: {
+ groupSyncSettings: MockGroupSyncSettings,
+ roleSyncSettings: MockRoleSyncSettings,
+ groups: [MockGroup, MockGroup2],
+ groupsMap,
+ organization: MockOrganization,
+ error: "This is a test error",
},
};
@@ -34,7 +57,10 @@ export const Default: Story = {
args: {
groupSyncSettings: MockGroupSyncSettings,
roleSyncSettings: MockRoleSyncSettings,
+ groups: [MockGroup, MockGroup2],
groupsMap,
+ organization: MockOrganization,
+ error: undefined,
},
};
@@ -42,6 +68,9 @@ export const MissingGroups: Story = {
args: {
groupSyncSettings: MockGroupSyncSettings2,
roleSyncSettings: MockRoleSyncSettings,
+ groups: [MockGroup, MockGroup2],
groupsMap,
+ organization: MockOrganization,
+ error: undefined,
},
};
diff --git a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.tsx b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.tsx
index f73395e254e8b..9d7f4ef0cd515 100644
--- a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.tsx
+++ b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.tsx
@@ -14,9 +14,10 @@ import type {
Organization,
RoleSyncSettings,
} from "api/typesGenerated";
+import { ErrorAlert } from "components/Alert/ErrorAlert";
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
import { EmptyState } from "components/EmptyState/EmptyState";
-import { Paywall } from "components/Paywall/Paywall";
+import { Loader } from "components/Loader/Loader";
import { Stack } from "components/Stack/Stack";
import { StatusIndicator } from "components/StatusIndicator/StatusIndicator";
import {
@@ -37,13 +38,16 @@ interface IdpSyncPageViewProps {
groups: Group[] | undefined;
groupsMap: Map;
organization: Organization;
+ error?: unknown;
}
export const IdpSyncPageView: FC = ({
groupSyncSettings,
roleSyncSettings,
+ groups,
groupsMap,
organization,
+ error,
}) => {
const [searchParams] = useSearchParams();
@@ -60,126 +64,125 @@ export const IdpSyncPageView: FC = ({
? Object.entries(roleSyncSettings.mapping).length
: 0;
+ if (error) {
+ return ;
+ }
+
+ if (!groupSyncSettings || !roleSyncSettings || !groups) {
+ return ;
+ }
+
return (
<>
-
-
-
-
-
-
-
-
-
- Group Sync Settings
-
-
- Role Sync Settings
-
-
-
- {tab === "groups" ? (
- <>
-
-
-
-
-
+
+
+
+ Group Sync Settings
+
+
+ Role Sync Settings
+
+
+
+ {tab === "groups" ? (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {groupSyncSettings?.mapping &&
+ Object.entries(groupSyncSettings.mapping)
+ .sort()
+ .map(([idpGroup, groups]) => (
+
+ ))}
+
+
+ >
+ ) : (
+ <>
+
+
+
+
+
+
+
+
+ {roleSyncSettings?.mapping &&
+ Object.entries(roleSyncSettings.mapping)
+ .sort()
+ .map(([idpRole, roles]) => (
+
-
-
-
-
-
-
-
-
- {groupSyncSettings?.mapping &&
- Object.entries(groupSyncSettings.mapping)
- .sort()
- .map(([idpGroup, groups]) => (
-
- ))}
-
-
- >
- ) : (
- <>
-
-
-
-
-
-
-
-
- {roleSyncSettings?.mapping &&
- Object.entries(roleSyncSettings.mapping)
- .sort()
- .map(([idpRole, roles]) => (
-
- ))}
-
- >
- )}
-
-
-
+ ))}
+
+ >
+ )}
+
>
);
};