- Notifications
You must be signed in to change notification settings - Fork1.1k
feat: create idp sync page skeleton#14543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
b2c3e112de6bfc8298346a75ad85492ca5fb73ad326e39fcff2281e9b83118f2c2f6771eedda83d1fcdb2059be81523025File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -7,6 +7,7 @@ export interface EmptyStateProps extends HTMLAttributes<HTMLDivElement> { | ||
| description?: string | ReactNode; | ||
| cta?: ReactNode; | ||
| image?: ReactNode; | ||
| isCompact?: boolean; | ||
jaaydenh marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| } | ||
| /** | ||
| @@ -19,21 +20,28 @@ export const EmptyState: FC<EmptyStateProps> = ({ | ||
| description, | ||
| cta, | ||
| image, | ||
| isCompact, | ||
| ...attrs | ||
| }) => { | ||
| return ( | ||
| <div | ||
| css={[ | ||
| { | ||
| overflow: "hidden", | ||
| display: "flex", | ||
| flexDirection: "column", | ||
| justifyContent: "center", | ||
| alignItems: "center", | ||
| textAlign: "center", | ||
| minHeight: 360, | ||
| padding: "80px 40px", | ||
| position: "relative", | ||
| }, | ||
| isCompact && { | ||
| minHeight: 180, | ||
| padding: "10px 40px", | ||
| }, | ||
| ]} | ||
| {...attrs} | ||
| > | ||
| <h5 css={{ fontSize: 24, fontWeight: 500, margin: 0 }}>{message}</h5> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { | ||
| HelpTooltip, | ||
| HelpTooltipContent, | ||
| HelpTooltipLink, | ||
| HelpTooltipLinksGroup, | ||
| HelpTooltipText, | ||
| HelpTooltipTitle, | ||
| HelpTooltipTrigger, | ||
| } from "components/HelpTooltip/HelpTooltip"; | ||
| import type { FC } from "react"; | ||
| import { docs } from "utils/docs"; | ||
| export const IdpSyncHelpTooltip: FC = () => { | ||
| return ( | ||
| <HelpTooltip> | ||
| <HelpTooltipTrigger /> | ||
| <HelpTooltipContent> | ||
| <HelpTooltipTitle>What is IdP Sync?</HelpTooltipTitle> | ||
| <HelpTooltipText> | ||
| View the current mappings between your external OIDC provider and | ||
| Coder. Use the Coder CLI to configure these mappings. | ||
| </HelpTooltipText> | ||
| <HelpTooltipLinksGroup> | ||
| <HelpTooltipLink href={docs("/admin/auth#group-sync-enterprise")}> | ||
| Configure IdP Sync | ||
| </HelpTooltipLink> | ||
| </HelpTooltipLinksGroup> | ||
| </HelpTooltipContent> | ||
| </HelpTooltip> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| importAddIconfrom"@mui/icons-material/AddOutlined"; | ||
| importLaunchOutlinedfrom"@mui/icons-material/LaunchOutlined"; | ||
| importButtonfrom"@mui/material/Button"; | ||
| import{SettingsHeader}from"components/SettingsHeader/SettingsHeader"; | ||
| import{Stack}from"components/Stack/Stack"; | ||
| importtype{FC}from"react"; | ||
| import{Helmet}from"react-helmet-async"; | ||
| import{LinkasRouterLink}from"react-router-dom"; | ||
| import{docs}from"utils/docs"; | ||
| import{pageTitle}from"utils/page"; | ||
| import{IdpSyncHelpTooltip}from"./IdpSyncHelpTooltip"; | ||
| importIdpSyncPageViewfrom"./IdpSyncPageView"; | ||
| constmockOIDCConfig={ | ||
| allow_signups:true, | ||
| client_id:"test", | ||
| client_secret:"test", | ||
| client_key_file:"test", | ||
| client_cert_file:"test", | ||
| email_domain:[], | ||
| issuer_url:"test", | ||
| scopes:[], | ||
| ignore_email_verified:true, | ||
| username_field:"", | ||
| name_field:"", | ||
| email_field:"", | ||
| auth_url_params:{}, | ||
| ignore_user_info:true, | ||
| organization_field:"", | ||
| organization_mapping:{}, | ||
| organization_assign_default:true, | ||
| group_auto_create:false, | ||
| group_regex_filter:"^Coder-.*$", | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I know this is a mock value, but could I get more context on where this regex is used? Is it strictly server-controlled? Wondering because the ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. All the data is readonly and for now I just took the value from Steven. Im still learning myself how this feature works. | ||
| group_allow_list:[], | ||
| groups_field:"groups", | ||
| group_mapping:{group1:"developers",group2:"admin",group3:"auditors"}, | ||
| user_role_field:"roles", | ||
| user_role_mapping:{role1:["role1","role2"]}, | ||
| user_roles_default:[], | ||
| sign_in_text:"", | ||
| icon_url:"", | ||
| signups_disabled_text:"string", | ||
| skip_issuer_checks:true, | ||
| }; | ||
| exportconstIdpSyncPage:FC=()=>{ | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Just calling this out because I don't see anything about this in the commented-out code: do we want to do a redirect if the user navigates to this page if I know we're using that property to define whether we show the page link in the side navbar, but is there anything stopping someone from navigating to the page directly? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. @Parkreiner I haven't addressed permissions yet because a permission hasn't been defined for this page. Btw, how do other pages handle this case when the user doesn't have the permissions? | ||
| // feature visibility and permissions to be implemented when integrating with backend | ||
| // const feats = useFeatureVisibility(); | ||
| // const { organization: organizationName } = useParams() as { | ||
| // organization: string; | ||
| // }; | ||
| // const { organizations } = useOrganizationSettings(); | ||
| // const organization = organizations?.find((o) => o.name === organizationName); | ||
| // const permissionsQuery = useQuery(organizationPermissions(organization?.id)); | ||
| // const permissions = permissionsQuery.data; | ||
| // if (!permissions) { | ||
| // return <Loader />; | ||
| // } | ||
| return( | ||
| <> | ||
| <Helmet> | ||
| <title>{pageTitle("IdP Sync")}</title> | ||
| </Helmet> | ||
| <Stack | ||
| alignItems="baseline" | ||
| direction="row" | ||
| justifyContent="space-between" | ||
| > | ||
| <SettingsHeader | ||
| title="IdP Sync" | ||
| description="Group and role sync mappings (configured outside Coder)." | ||
| tooltip={<IdpSyncHelpTooltip/>} | ||
| /> | ||
| <Stackdirection="row"spacing={2}> | ||
| <Button | ||
| startIcon={<LaunchOutlined/>} | ||
| component="a" | ||
| href={docs("/admin/auth#group-sync-enterprise")} | ||
| target="_blank" | ||
| > | ||
| Setup IdP Sync | ||
| </Button> | ||
| <Buttoncomponent={RouterLink}startIcon={<AddIcon/>}to="export"> | ||
| Export Policy | ||
| </Button> | ||
| </Stack> | ||
| </Stack> | ||
| <IdpSyncPageViewoidcConfig={mockOIDCConfig}/> | ||
| </> | ||
| ); | ||
| }; | ||
| exportdefaultIdpSyncPage; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import type { Meta, StoryObj } from "@storybook/react"; | ||
| import { MockOIDCConfig } from "testHelpers/entities"; | ||
| import { IdpSyncPageView } from "./IdpSyncPageView"; | ||
| const meta: Meta<typeof IdpSyncPageView> = { | ||
| title: "pages/OrganizationIdpSyncPage", | ||
| component: IdpSyncPageView, | ||
| }; | ||
| export default meta; | ||
| type Story = StoryObj<typeof IdpSyncPageView>; | ||
| export const Empty: Story = { | ||
| args: { oidcConfig: undefined }, | ||
| }; | ||
| export const Default: Story = { | ||
| args: { oidcConfig: MockOIDCConfig }, | ||
| }; |
Uh oh!
There was an error while loading.Please reload this page.