Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ff9a07

Browse files
committed
fix: hookup backend data for groups and roles
1 parenta40ba7d commit7ff9a07

File tree

5 files changed

+206
-109
lines changed

5 files changed

+206
-109
lines changed

‎site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPage.tsx

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,27 @@
11
importAddIconfrom"@mui/icons-material/AddOutlined";
22
importLaunchOutlinedfrom"@mui/icons-material/LaunchOutlined";
33
importButtonfrom"@mui/material/Button";
4+
import{groupsByOrganization}from"api/queries/groups";
5+
import{
6+
groupIdpSyncSettings,
7+
organizationsPermissions,
8+
roleIdpSyncSettings,
9+
}from"api/queries/organizations";
10+
import{EmptyState}from"components/EmptyState/EmptyState";
411
import{FeatureStageBadge}from"components/FeatureStageBadge/FeatureStageBadge";
12+
import{Loader}from"components/Loader/Loader";
513
import{SettingsHeader}from"components/SettingsHeader/SettingsHeader";
614
import{Stack}from"components/Stack/Stack";
15+
import{useDashboard}from"modules/dashboard/useDashboard";
716
importtype{FC}from"react";
817
import{Helmet}from"react-helmet-async";
18+
import{useQuery}from"react-query";
919
import{LinkasRouterLink,useParams}from"react-router-dom";
1020
import{docs}from"utils/docs";
1121
import{pageTitle}from"utils/page";
22+
import{useOrganizationSettings}from"../ManagementSettingsLayout";
1223
import{IdpSyncHelpTooltip}from"./IdpSyncHelpTooltip";
1324
importIdpSyncPageViewfrom"./IdpSyncPageView";
14-
import{
15-
organizationsPermissions,
16-
groupIdpSyncSettings,
17-
roleIdpSyncSettings,
18-
}from"api/queries/organizations";
19-
import{useQuery}from"react-query";
20-
import{useOrganizationSettings}from"../ManagementSettingsLayout";
21-
import{Loader}from"components/Loader/Loader";
22-
import{EmptyState}from"components/EmptyState/EmptyState";
23-
24-
constmockOIDCConfig={
25-
allow_signups:true,
26-
client_id:"test",
27-
client_secret:"test",
28-
client_key_file:"test",
29-
client_cert_file:"test",
30-
email_domain:[],
31-
issuer_url:"test",
32-
scopes:[],
33-
ignore_email_verified:true,
34-
username_field:"",
35-
name_field:"",
36-
email_field:"",
37-
auth_url_params:{},
38-
ignore_user_info:true,
39-
organization_field:"",
40-
organization_mapping:{},
41-
organization_assign_default:true,
42-
group_auto_create:false,
43-
group_regex_filter:"^Coder-.*$",
44-
group_allow_list:[],
45-
groups_field:"groups",
46-
group_mapping:{group1:"developers",group2:"admin",group3:"auditors"},
47-
user_role_field:"roles",
48-
user_role_mapping:{role1:["role1","role2"]},
49-
user_roles_default:[],
50-
sign_in_text:"",
51-
icon_url:"",
52-
signups_disabled_text:"string",
53-
skip_issuer_checks:true,
54-
};
5525

5626
exportconstIdpSyncPage:FC=()=>{
5727
const{organization:organizationName}=useParams()as{
@@ -64,16 +34,20 @@ export const IdpSyncPage: FC = () => {
6434
// organization: string;
6535
// };
6636
const{ organizations}=useOrganizationSettings();
37+
6738
constorganization=organizations?.find((o)=>o.name===organizationName);
6839
constpermissionsQuery=useQuery(
6940
organizationsPermissions(organizations?.map((o)=>o.id)),
7041
);
7142
constgroupIdpSyncSettingsQuery=useQuery(
7243
groupIdpSyncSettings(organizationName),
7344
);
45+
46+
constgroupsQuery=useQuery(groupsByOrganization(organizationName));
7447
constroleIdpSyncSettingsQuery=useQuery(
7548
roleIdpSyncSettings(organizationName),
7649
);
50+
7751
// const permissions = permissionsQuery.data;
7852

7953
if(!organization){
@@ -121,9 +95,9 @@ export const IdpSyncPage: FC = () => {
12195
</Stack>
12296

12397
<IdpSyncPageView
124-
oidcConfig={mockOIDCConfig}
12598
groupSyncSettings={groupIdpSyncSettingsQuery.data}
12699
roleSyncSettings={roleIdpSyncSettingsQuery.data}
100+
groups={groupsQuery.data}
127101
/>
128102
</>
129103
);

‎site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
2-
import{MockOIDCConfig}from"testHelpers/entities";
2+
import{
3+
MockGroup,
4+
MockGroup2,
5+
MockGroupSyncSettings,
6+
MockRoleSyncSettings,
7+
}from"testHelpers/entities";
38
import{IdpSyncPageView}from"./IdpSyncPageView";
49

510
constmeta:Meta<typeofIdpSyncPageView>={
@@ -11,9 +16,17 @@ export default meta;
1116
typeStory=StoryObj<typeofIdpSyncPageView>;
1217

1318
exportconstEmpty:Story={
14-
args:{oidcConfig:undefined},
19+
args:{
20+
groupSyncSettings:undefined,
21+
roleSyncSettings:undefined,
22+
groups:[MockGroup,MockGroup2],
23+
},
1524
};
1625

1726
exportconstDefault:Story={
18-
args:{oidcConfig:MockOIDCConfig},
27+
args:{
28+
groupSyncSettings:MockGroupSyncSettings,
29+
roleSyncSettings:MockRoleSyncSettings,
30+
groups:[MockGroup,MockGroup2],
31+
},
1932
};

‎site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.tsx

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import TableContainer from "@mui/material/TableContainer";
1010
importTableHeadfrom"@mui/material/TableHead";
1111
importTableRowfrom"@mui/material/TableRow";
1212
importtype{
13-
OIDCConfig,
13+
Group,
1414
GroupSyncSettings,
1515
RoleSyncSettings,
1616
}from"api/typesGenerated";
@@ -26,20 +26,32 @@ import {
2626
importtype{FC}from"react";
2727
import{MONOSPACE_FONT_FAMILY}from"theme/constants";
2828
import{docs}from"utils/docs";
29+
import{PillList}from"./PillList";
2930

3031
exporttypeIdpSyncPageViewProps={
31-
oidcConfig:OIDCConfig|undefined;
3232
groupSyncSettings:GroupSyncSettings|undefined;
3333
roleSyncSettings:RoleSyncSettings|undefined;
34+
groups:Group[]|undefined;
3435
};
3536

3637
exportconstIdpSyncPageView:FC<IdpSyncPageViewProps>=({
37-
oidcConfig,
3838
groupSyncSettings,
3939
roleSyncSettings,
40+
groups,
4041
})=>{
41-
consttheme=useTheme();
42-
const{ user_role_field}=oidcConfig||{};
42+
// const theme = useTheme();
43+
44+
constgroupsMap=newMap<string,string>();
45+
if(groups){
46+
for(constgroupofgroups){
47+
groupsMap.set(group.id,group.display_name||group.name);
48+
}
49+
}
50+
51+
constgetGroupNames=(groupIds:readonlystring[])=>{
52+
returngroupIds.map((groupId)=>groupsMap.get(groupId)||groupId);
53+
};
54+
4355
return(
4456
<>
4557
<ChooseOne>
@@ -67,13 +79,13 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
6779
fieldText={
6880
typeofgroupSyncSettings?.regex_filter==="string"
6981
?groupSyncSettings?.regex_filter
70-
:""
82+
:"none"
7183
}
7284
/>
7385
<IdpField
7486
name={"Auto Create"}
7587
fieldText={String(
76-
groupSyncSettings?.auto_create_missing_groups,
88+
groupSyncSettings?.auto_create_missing_groups||"n/a",
7789
)}
7890
/>
7991
</Stack>
@@ -83,46 +95,46 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
8395
<Stackdirection={"row"}alignItems={"center"}spacing={3}>
8496
<IdpField
8597
name={"Sync Field"}
86-
fieldText={user_role_field}
98+
fieldText={roleSyncSettings?.field}
8799
showStatusIndicator
88100
/>
89101
</Stack>
90102
</fieldset>
91103
</Stack>
92104
<Stackspacing={6}>
93105
<IdpMappingTable
94-
type="Role"
106+
type="Group"
95107
isEmpty={Boolean(
96-
!oidcConfig?.user_role_mapping||
97-
Object.entries(oidcConfig?.user_role_mapping).length===0,
108+
!groupSyncSettings?.mapping||
109+
Object.entries(groupSyncSettings?.mapping).length===0,
98110
)}
99111
>
100-
{oidcConfig?.user_role_mapping&&
101-
Object.entries(oidcConfig.user_role_mapping)
112+
{groupSyncSettings?.mapping&&
113+
Object.entries(groupSyncSettings.mapping)
102114
.sort()
103-
.map(([idpRole,roles])=>(
104-
<RoleRow
105-
key={idpRole}
106-
idpRole={idpRole}
107-
coderRoles={roles}
115+
.map(([idpGroup,groups])=>(
116+
<GroupRow
117+
key={idpGroup}
118+
idpGroup={idpGroup}
119+
coderGroup={getGroupNames(groups)}
108120
/>
109121
))}
110122
</IdpMappingTable>
111123
<IdpMappingTable
112-
type="Group"
124+
type="Role"
113125
isEmpty={Boolean(
114-
!oidcConfig?.group_mapping||
115-
Object.entries(oidcConfig?.group_mapping).length===0,
126+
!roleSyncSettings?.mapping||
127+
Object.entries(roleSyncSettings?.mapping).length===0,
116128
)}
117129
>
118-
{oidcConfig?.user_role_mapping&&
119-
Object.entries(oidcConfig.group_mapping)
130+
{roleSyncSettings?.mapping&&
131+
Object.entries(roleSyncSettings.mapping)
120132
.sort()
121-
.map(([idpGroup,group])=>(
122-
<GroupRow
123-
key={idpGroup}
124-
idpGroup={idpGroup}
125-
coderGroup={group}
133+
.map(([idpRole,roles])=>(
134+
<RoleRow
135+
key={idpRole}
136+
idpRole={idpRole}
137+
coderRoles={roles}
126138
/>
127139
))}
128140
</IdpMappingTable>
@@ -226,28 +238,32 @@ const IdpMappingTable: FC<IdpMappingTableProps> = ({
226238

227239
interfaceGroupRowProps{
228240
idpGroup:string;
229-
coderGroup:string;
241+
coderGroup:readonlystring[];
230242
}
231243

232244
constGroupRow:FC<GroupRowProps>=({ idpGroup, coderGroup})=>{
233245
return(
234246
<TableRowdata-testid={`group-${idpGroup}`}>
235247
<TableCell>{idpGroup}</TableCell>
236-
<TableCell>{coderGroup}</TableCell>
248+
<TableCell>
249+
<PillListroles={coderGroup}/>
250+
</TableCell>
237251
</TableRow>
238252
);
239253
};
240254

241255
interfaceRoleRowProps{
242256
idpRole:string;
243-
coderRoles:ReadonlyArray<string>;
257+
coderRoles:readonlystring[];
244258
}
245259

246260
constRoleRow:FC<RoleRowProps>=({ idpRole, coderRoles})=>{
247261
return(
248262
<TableRowdata-testid={`role-${idpRole}`}>
249263
<TableCell>{idpRole}</TableCell>
250-
<TableCell>coderRoles Placeholder</TableCell>
264+
<TableCell>
265+
<PillListroles={coderRoles}/>
266+
</TableCell>
251267
</TableRow>
252268
);
253269
};
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import{typeInterpolation,typeTheme,useTheme}from"@emotion/react";
2+
importStackfrom"@mui/material/Stack";
3+
import{Pill}from"components/Pill/Pill";
4+
import{
5+
Popover,
6+
PopoverContent,
7+
PopoverTrigger,
8+
}from"components/Popover/Popover";
9+
importtype{FC}from"react";
10+
11+
interfacePillListProps{
12+
roles:readonlystring[];
13+
}
14+
15+
exportconstPillList:FC<PillListProps>=({ roles})=>{
16+
return(
17+
<Stackdirection="row"spacing={1}>
18+
{roles.length>0 ?(
19+
<Pillcss={styles.pill}>{roles[0]}</Pill>
20+
) :(
21+
<p>None</p>
22+
)}
23+
24+
{roles.length>1&&<OverflowPillroles={roles.slice(1)}/>}
25+
</Stack>
26+
);
27+
};
28+
29+
typeOverflowPillProps={
30+
roles:string[];
31+
};
32+
33+
constOverflowPill:FC<OverflowPillProps>=({ roles})=>{
34+
consttheme=useTheme();
35+
36+
return(
37+
<Popovermode="hover">
38+
<PopoverTrigger>
39+
<Pill
40+
css={{
41+
backgroundColor:theme.palette.background.paper,
42+
borderColor:theme.palette.divider,
43+
}}
44+
data-testid="overflow-pill"
45+
>
46+
+{roles.length} more
47+
</Pill>
48+
</PopoverTrigger>
49+
50+
<PopoverContent
51+
disableRestoreFocus
52+
disableScrollLock
53+
css={{
54+
".MuiPaper-root":{
55+
display:"flex",
56+
flexFlow:"column wrap",
57+
columnGap:8,
58+
rowGap:12,
59+
padding:"12px 16px",
60+
alignContent:"space-around",
61+
minWidth:"auto",
62+
backgroundColor:theme.palette.background.default,
63+
},
64+
}}
65+
anchorOrigin={{
66+
vertical:-4,
67+
horizontal:"center",
68+
}}
69+
transformOrigin={{
70+
vertical:"bottom",
71+
horizontal:"center",
72+
}}
73+
>
74+
{roles.map((role)=>(
75+
<Pillkey={role}css={styles.pill}>
76+
{role}
77+
</Pill>
78+
))}
79+
</PopoverContent>
80+
</Popover>
81+
);
82+
};
83+
84+
conststyles={
85+
pill:(theme)=>({
86+
backgroundColor:theme.experimental.pillDefault.background,
87+
borderColor:theme.experimental.pillDefault.outline,
88+
color:theme.experimental.pillDefault.text,
89+
width:"fit-content",
90+
}),
91+
}satisfiesRecord<string,Interpolation<Theme>>;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp