-
Notifications
You must be signed in to change notification settings - Fork 929
feat: integrate backend with idp sync page #14755
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
a40ba7d
feat: idp sync initial commit
jaaydenh 7ff9a07
fix: hookup backend data for groups and roles
jaaydenh 6e303f4
chore: cleanup
jaaydenh 310726b
feat: separate groups and roles into tabs
jaaydenh 615c8d3
feat: implement export policy button
jaaydenh 45f4d13
feat: handle missing groups
jaaydenh 080b032
chore: add story for missing groups
jaaydenh 8e1e021
chore: add stories for export policy button
jaaydenh c863619
fix: updates for PR review
jaaydenh 41631f0
chore: update tests
jaaydenh 3db9f48
chore: document uuid regex
jaaydenh 431beea
chore: remove unused
jaaydenh f166784
fix: fix stories
jaaydenh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix: hookup backend data for groups and roles
- Loading branch information
commit 7ff9a07c17edd0dfd8b41a0ac9479444b7cbf5bf
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ import TableContainer from "@mui/material/TableContainer"; | |
import TableHead from "@mui/material/TableHead"; | ||
import TableRow from "@mui/material/TableRow"; | ||
import type { | ||
OIDCConfig, | ||
Group, | ||
GroupSyncSettings, | ||
RoleSyncSettings, | ||
} from "api/typesGenerated"; | ||
|
@@ -26,20 +26,32 @@ import { | |
import type { FC } from "react"; | ||
import { MONOSPACE_FONT_FAMILY } from "theme/constants"; | ||
import { docs } from "utils/docs"; | ||
import { PillList } from "./PillList"; | ||
|
||
export type IdpSyncPageViewProps = { | ||
oidcConfig: OIDCConfig | undefined; | ||
groupSyncSettings: GroupSyncSettings | undefined; | ||
roleSyncSettings: RoleSyncSettings | undefined; | ||
groups: Group[] | undefined; | ||
}; | ||
|
||
export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({ | ||
oidcConfig, | ||
groupSyncSettings, | ||
roleSyncSettings, | ||
groups, | ||
}) => { | ||
const theme = useTheme(); | ||
const { user_role_field } = oidcConfig || {}; | ||
// const theme = useTheme(); | ||
|
||
const groupsMap = new Map<string, string>(); | ||
if (groups) { | ||
for (const group of groups) { | ||
groupsMap.set(group.id, group.display_name || group.name); | ||
} | ||
} |
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. Would it make sense to lift this up to the page component? I don't expect this map to change all that often, and putting it there should limit re-renders more without having to resort to |
|
|
||
const getGroupNames = (groupIds: readonly string[]) => { | ||
return groupIds.map((groupId) => groupsMap.get(groupId) || groupId); | ||
}; | ||
|
||
return ( | ||
<> | ||
<ChooseOne> | ||
|
@@ -67,13 +79,13 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({ | |
fieldText={ | ||
typeof groupSyncSettings?.regex_filter === "string" | ||
? groupSyncSettings?.regex_filter | ||
: "" | ||
: "none" | ||
} | ||
/> | ||
<IdpField | ||
name={"Auto Create"} | ||
fieldText={String( | ||
groupSyncSettings?.auto_create_missing_groups, | ||
groupSyncSettings?.auto_create_missing_groups || "n/a", | ||
)} | ||
/> | ||
</Stack> | ||
|
@@ -83,46 +95,46 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({ | |
<Stack direction={"row"} alignItems={"center"} spacing={3}> | ||
<IdpField | ||
name={"Sync Field"} | ||
fieldText={user_role_field} | ||
fieldText={roleSyncSettings?.field} | ||
showStatusIndicator | ||
/> | ||
</Stack> | ||
</fieldset> | ||
</Stack> | ||
<Stack spacing={6}> | ||
<IdpMappingTable | ||
type="Role" | ||
type="Group" | ||
isEmpty={Boolean( | ||
!oidcConfig?.user_role_mapping || | ||
Object.entries(oidcConfig?.user_role_mapping).length === 0, | ||
!groupSyncSettings?.mapping || | ||
Object.entries(groupSyncSettings?.mapping).length === 0, | ||
)} | ||
> | ||
{oidcConfig?.user_role_mapping && | ||
Object.entries(oidcConfig.user_role_mapping) | ||
{groupSyncSettings?.mapping && | ||
Object.entries(groupSyncSettings.mapping) | ||
.sort() | ||
.map(([idpRole, roles]) => ( | ||
<RoleRow | ||
key={idpRole} | ||
idpRole={idpRole} | ||
coderRoles={roles} | ||
.map(([idpGroup, groups]) => ( | ||
<GroupRow | ||
key={idpGroup} | ||
idpGroup={idpGroup} | ||
coderGroup={getGroupNames(groups)} | ||
/> | ||
))} | ||
</IdpMappingTable> | ||
<IdpMappingTable | ||
type="Group" | ||
type="Role" | ||
isEmpty={Boolean( | ||
!oidcConfig?.group_mapping || | ||
Object.entries(oidcConfig?.group_mapping).length === 0, | ||
!roleSyncSettings?.mapping || | ||
Object.entries(roleSyncSettings?.mapping).length === 0, | ||
)} | ||
> | ||
{oidcConfig?.user_role_mapping && | ||
Object.entries(oidcConfig.group_mapping) | ||
{roleSyncSettings?.mapping && | ||
Object.entries(roleSyncSettings.mapping) | ||
.sort() | ||
.map(([idpGroup, group]) => ( | ||
<GroupRow | ||
key={idpGroup} | ||
idpGroup={idpGroup} | ||
coderGroup={group} | ||
.map(([idpRole, roles]) => ( | ||
<RoleRow | ||
key={idpRole} | ||
idpRole={idpRole} | ||
coderRoles={roles} | ||
/> | ||
))} | ||
</IdpMappingTable> | ||
|
@@ -226,28 +238,32 @@ const IdpMappingTable: FC<IdpMappingTableProps> = ({ | |
|
||
interface GroupRowProps { | ||
idpGroup: string; | ||
coderGroup: string; | ||
coderGroup: readonly string[]; | ||
} | ||
|
||
const GroupRow: FC<GroupRowProps> = ({ idpGroup, coderGroup }) => { | ||
return ( | ||
<TableRow data-testid={`group-${idpGroup}`}> | ||
<TableCell>{idpGroup}</TableCell> | ||
<TableCell>{coderGroup}</TableCell> | ||
<TableCell> | ||
<PillList roles={coderGroup} /> | ||
</TableCell> | ||
</TableRow> | ||
); | ||
}; | ||
|
||
interface RoleRowProps { | ||
idpRole: string; | ||
coderRoles: ReadonlyArray<string>; | ||
coderRoles: readonly string[]; | ||
} | ||
|
||
const RoleRow: FC<RoleRowProps> = ({ idpRole, coderRoles }) => { | ||
return ( | ||
<TableRow data-testid={`role-${idpRole}`}> | ||
<TableCell>{idpRole}</TableCell> | ||
<TableCell>coderRoles Placeholder</TableCell> | ||
<TableCell> | ||
<PillList roles={coderRoles} /> | ||
</TableCell> | ||
</TableRow> | ||
); | ||
}; | ||
|
91 changes: 91 addit
10000
ions & 0 deletions
91
site/src/pages/ManagementSettingsPage/IdpSyncPage/PillList.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { type Interpolation, type Theme, useTheme } from "@emotion/react"; | ||
import Stack from "@mui/material/Stack"; | ||
import { Pill } from "components/Pill/Pill"; | ||
import { | ||
Popover, | ||
PopoverContent, | ||
PopoverTrigger, | ||
} from "components/Popover/Popover"; | ||
import type { FC } from "react"; | ||
|
||
interface PillListProps { | ||
roles: readonly string[]; | ||
} | ||
|
||
export const PillList: FC<PillListProps> = ({ roles }) => { | ||
return ( | ||
<Stack direction="row" spacing={1}> | ||
{roles.length > 0 ? ( | ||
<Pill css={styles.pill}>{roles[0]}</Pill> | ||
) : ( | ||
<p>None</p> | ||
)} | ||
|
||
{roles.length > 1 && <OverflowPill roles={roles.slice(1)} />} | ||
</Stack> | ||
); | ||
}; | ||
|
||
type OverflowPillProps = { | ||
roles: string[]; | ||
}; | ||
|
||
const OverflowPill: FC<OverflowPillProps> = ({ roles }) => { | ||
const theme = useTheme(); | ||
|
||
return ( | ||
<Popover mode="hover"> | ||
<PopoverTrigger> | ||
<Pill | ||
css={{ | ||
backgroundColor: theme.palette.background.paper, | ||
borderColor: theme.palette.divider, | ||
}} | ||
data-testid="overflow-pill" | ||
> | ||
+{roles.length} more | ||
</Pill> | ||
</PopoverTrigger> | ||
|
||
<PopoverContent | ||
disableRestoreFocus | ||
disableScrollLock | ||
css={{ | ||
".MuiPaper-root": { | ||
display: "flex", | ||
flexFlow: "column wrap", | ||
columnGap: 8, | ||
rowGap: 12, | ||
padding: "12px 16px", | ||
alignContent: "space-around", | ||
minWidth: "auto", | ||
backgroundColor: theme.palette.background.default, | ||
}, | ||
}} | ||
anchorOrigin={{ | ||
vertical: -4, | ||
horizontal: "center", | ||
}} | ||
transformOrigin={{ | ||
vertical: "bottom", | ||
horizontal: "center", | ||
}} | ||
> | ||
{roles.map((role) => ( | ||
<Pill key={role} css={styles.pill}> | ||
{role} | ||
</Pill> | ||
))} | ||
</PopoverContent> | ||
</Popover> | ||
); | ||
}; | ||
|
||
const styles = { | ||
pill: (theme) => ({ | ||
backgroundColor: theme.experimental.pillDefault.background, | ||
borderColor: theme.experimental.pillDefault.outline, | ||
color: theme.experimental.pillDefault.text, | ||
width: "fit-content", | ||
}), | ||
} satisfies Record<string, Interpolation<Theme>>; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have to put the comment here because the code was already in place previously, and it's not selectable for review:
I think we need to add some CSS optical adjustments to the key-value pairs for the
IdpField
component. Since we're using two different typefaces, their baselines are slightly different. And when you place them right next to each other on the same line, there's enough variation that the text looks sloppyYou might have to open this in a new tab, but the baselines are ever so slightly off, and the cap-heights are, too:

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though a slightly easier and probably much more manageable alternative would be to set all the text in monospace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The monospace font was supposed to be a temporary measure until this page becomes a form and these would become fields. I'll see if I can improve it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a temporary fix, I can add some padding to make the baselines match. I really wanted to use the monospace font on only the field value to signify that it is the value of the configuration.