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

Commit093d243

Browse files
authored
feat: add resource-action pills to custom roles table (#14354)
* feat: add resource-action pills to custom roles table* fix: remove permission from theme and change name to colorRoles* fix: revert name from colorRoles to roles* fix: format* fix: custom role with no permissions* feat: extract permissions pull list component and add tests* chore: undo color roles name change* feat: add experimental pill colors* fix: format* chore: update experiment name* chore: cleanup
1 parent4421063 commit093d243

File tree

9 files changed

+254
-8
lines changed

9 files changed

+254
-8
lines changed

‎site/src/pages/ManagementSettingsPage/CustomRolesPage/CustomRolesPageView.stories.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
2-
import{MockRoleWithOrgPermissions}from"testHelpers/entities";
2+
import{
3+
MockOrganizationAuditorRole,
4+
MockRoleWithOrgPermissions,
5+
}from"testHelpers/entities";
36
import{CustomRolesPageView}from"./CustomRolesPageView";
47

58
constmeta:Meta<typeofCustomRolesPageView>={
@@ -26,6 +29,14 @@ export const Enabled: Story = {
2629
},
2730
};
2831

32+
exportconstRoleWithoutPermissions:Story={
33+
args:{
34+
roles:[MockOrganizationAuditorRole],
35+
canAssignOrgRole:true,
36+
isCustomRolesEnabled:true,
37+
},
38+
};
39+
2940
exportconstEmptyDisplayName:Story={
3041
args:{
3142
roles:[
@@ -40,15 +51,15 @@ export const EmptyDisplayName: Story = {
4051
},
4152
};
4253

43-
exportconstEmptyRoleWithoutPermission:Story={
54+
exportconstEmptyTableUserWithoutPermission:Story={
4455
args:{
4556
roles:[],
4657
canAssignOrgRole:false,
4758
isCustomRolesEnabled:true,
4859
},
4960
};
5061

51-
exportconstEmptyRoleWithPermission:Story={
62+
exportconstEmptyTableUserWithPermission:Story={
5263
args:{
5364
roles:[],
5465
canAssignOrgRole:true,

‎site/src/pages/ManagementSettingsPage/CustomRolesPage/CustomRolesPageView.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
importtype{FC}from"react";
2727
import{LinkasRouterLink,useNavigate}from"react-router-dom";
2828
import{docs}from"utils/docs";
29+
import{PermissionPillsList}from"./PermissionPillsList";
2930

3031
exporttypeCustomRolesPageViewProps={
3132
roles:Role[]|undefined;
@@ -42,7 +43,6 @@ export const CustomRolesPageView: FC<CustomRolesPageViewProps> = ({
4243
})=>{
4344
constisLoading=roles===undefined;
4445
constisEmpty=Boolean(roles&&roles.length===0);
45-
4646
return(
4747
<>
4848
<ChooseOne>
@@ -58,8 +58,8 @@ export const CustomRolesPageView: FC<CustomRolesPageViewProps> = ({
5858
<Table>
5959
<TableHead>
6060
<TableRow>
61-
<TableCellwidth="50%">Name</TableCell>
62-
<TableCellwidth="49%">Permissions</TableCell>
61+
<TableCellwidth="40%">Name</TableCell>
62+
<TableCellwidth="59%">Permissions</TableCell>
6363
<TableCellwidth="1%"/>
6464
</TableRow>
6565
</TableHead>
@@ -129,8 +129,8 @@ const RoleRow: FC<RoleRowProps> = ({ role, onDelete, canAssignOrgRole }) => {
129129
<TableRowdata-testid={`role-${role.name}`}>
130130
<TableCell>{role.display_name||role.name}</TableCell>
131131

132-
<TableCellcss={styles.secondary}>
133-
{role.organization_permissions.length}
132+
<TableCell>
133+
<PermissionPillsListpermissions={role.organization_permissions}/>
134134
</TableCell>
135135

136136
<TableCell>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{userEvent,within}from"@storybook/test";
3+
import{MockRoleWithOrgPermissions}from"testHelpers/entities";
4+
import{PermissionPillsList}from"./PermissionPillsList";
5+
6+
constmeta:Meta<typeofPermissionPillsList>={
7+
title:"pages/OrganizationCustomRolesPage/PermissionPillsList",
8+
component:PermissionPillsList,
9+
};
10+
11+
exportdefaultmeta;
12+
typeStory=StoryObj<typeofPermissionPillsList>;
13+
14+
exportconstDefault:Story={
15+
args:{
16+
permissions:MockRoleWithOrgPermissions.organization_permissions,
17+
},
18+
};
19+
20+
exportconstSinglePermission:Story={
21+
args:{
22+
permissions:[
23+
{
24+
negate:false,
25+
resource_type:"organization_member",
26+
action:"create",
27+
},
28+
],
29+
},
30+
};
31+
32+
exportconstNoPermissions:Story={
33+
args:{
34+
permissions:[],
35+
},
36+
};
37+
38+
exportconstHoverOverflowPill:Story={
39+
args:{
40+
permissions:MockRoleWithOrgPermissions.organization_permissions,
41+
},
42+
play:async({ canvasElement})=>{
43+
constcanvas=within(canvasElement);
44+
awaituserEvent.hover(canvas.getByTestId("overflow-permissions-pill"));
45+
},
46+
};
47+
48+
exportconstShowAllResources:Story={
49+
args:{
50+
permissions:MockRoleWithOrgPermissions.organization_permissions,
51+
},
52+
};
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import{typeInterpolation,typeTheme,useTheme}from"@emotion/react";
2+
importStackfrom"@mui/material/Stack";
3+
importtype{Permission}from"api/typesGenerated";
4+
import{Pill}from"components/Pill/Pill";
5+
import{
6+
Popover,
7+
PopoverContent,
8+
PopoverTrigger,
9+
}from"components/Popover/Popover";
10+
importtype{FC}from"react";
11+
12+
functiongetUniqueResourceTypes(jsonObject:readonlyPermission[]){
13+
constresourceTypes=jsonObject.map((item)=>item.resource_type);
14+
return[...newSet(resourceTypes)];
15+
}
16+
17+
interfacePermissionPillsListProps{
18+
permissions:readonlyPermission[];
19+
}
20+
21+
exportconstPermissionPillsList:FC<PermissionPillsListProps>=({
22+
permissions,
23+
})=>{
24+
constresourceTypes=getUniqueResourceTypes(permissions);
25+
26+
return(
27+
<Stackdirection="row"spacing={1}>
28+
{permissions.length>0 ?(
29+
<PermissionsPill
30+
resource={resourceTypes[0]}
31+
permissions={permissions}
32+
/>
33+
) :(
34+
<p>None</p>
35+
)}
36+
37+
{resourceTypes.length>1&&(
38+
<OverflowPermissionPill
39+
resources={resourceTypes.slice(1)}
40+
permissions={permissions.slice(1)}
41+
/>
42+
)}
43+
</Stack>
44+
);
45+
};
46+
47+
interfacePermissionPillProps{
48+
resource:string;
49+
permissions:readonlyPermission[];
50+
}
51+
52+
constPermissionsPill:FC<PermissionPillProps>=({
53+
resource,
54+
permissions,
55+
})=>{
56+
constactions=permissions.filter(
57+
(p)=>resource===p.resource_type&&p.action,
58+
);
59+
60+
return(
61+
<Pillcss={styles.permissionPill}>
62+
<b>{resource}</b>:{actions.map((p)=>p.action).join(", ")}
63+
</Pill>
64+
);
65+
};
66+
67+
typeOverflowPermissionPillProps={
68+
resources:string[];
69+
permissions:readonlyPermission[];
70+
};
71+
72+
constOverflowPermissionPill:FC<OverflowPermissionPillProps>=({
73+
resources,
74+
permissions,
75+
})=>{
76+
consttheme=useTheme();
77+
78+
return(
79+
<Popovermode="hover">
80+
<PopoverTrigger>
81+
<Pill
82+
css={{
83+
backgroundColor:theme.palette.background.paper,
84+
borderColor:theme.palette.divider,
85+
}}
86+
data-testid="overflow-permissions-pill"
87+
>
88+
+{resources.length} more
89+
</Pill>
90+
</PopoverTrigger>
91+
92+
<PopoverContent
93+
disableRestoreFocus
94+
disableScrollLock
95+
css={{
96+
".MuiPaper-root":{
97+
display:"flex",
98+
flexFlow:"column wrap",
99+
columnGap:8,
100+
rowGap:12,
101+
padding:"12px 16px",
102+
alignContent:"space-around",
103+
minWidth:"auto",
104+
backgroundColor:theme.palette.background.default,
105+
},
106+
}}
107+
anchorOrigin={{
108+
vertical:-4,
109+
horizontal:"center",
110+
}}
111+
transformOrigin={{
112+
vertical:"bottom",
113+
horizontal:"center",
114+
}}
115+
>
116+
{resources.map((resource)=>(
117+
<PermissionsPill
118+
key={resource}
119+
resource={resource}
120+
permissions={permissions}
121+
/>
122+
))}
123+
</PopoverContent>
124+
</Popover>
125+
);
126+
};
127+
128+
conststyles={
129+
permissionPill:(theme)=>({
130+
backgroundColor:theme.experimental.pillDefault.background,
131+
borderColor:theme.experimental.pillDefault.outline,
132+
color:theme.experimental.pillDefault.text,
133+
width:"fit-content",
134+
}),
135+
}satisfiesRecord<string,Interpolation<Theme>>;

‎site/src/testHelpers/entities.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,31 @@ export const MockRoleWithOrgPermissions: TypesGen.Role = {
388388
resource_type:"audit_log",
389389
action:"read",
390390
},
391+
{
392+
negate:false,
393+
resource_type:"group",
394+
action:"create",
395+
},
396+
{
397+
negate:false,
398+
resource_type:"group",
399+
action:"delete",
400+
},
401+
{
402+
negate:false,
403+
resource_type:"group",
404+
action:"read",
405+
},
406+
{
407+
negate:false,
408+
resource_type:"group",
409+
action:"update",
410+
},
411+
{
412+
negate:false,
413+
resource_type:"provisioner_daemon",
414+
action:"create",
415+
},
391416
],
392417
user_permissions:[],
393418
};

‎site/src/theme/dark/experimental.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@ export default {
4343
},
4444
},
4545
},
46+
47+
pillDefault:{
48+
background:colors.zinc[800],
49+
outline:colors.zinc[700],
50+
text:colors.zinc[200],
51+
},
4652
}satisfiesNewTheme;

‎site/src/theme/darkBlue/experimental.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@ export default {
4343
},
4444
},
4545
},
46+
47+
pillDefault:{
48+
background:colors.gray[800],
49+
outline:colors.gray[700],
50+
text:colors.gray[200],
51+
},
4652
}satisfiesNewTheme;

‎site/src/theme/experimental.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ import type { InteractiveRole, Role } from "./roles";
33
exportinterfaceNewTheme{
44
l1:Role;// page background, things which sit at the "root level"
55
l2:InteractiveRole;// sidebars, table headers, navigation
6+
pillDefault:{
7+
background:string;
8+
outline:string;
9+
text:string;
10+
};
611
}

‎site/src/theme/light/experimental.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@ export default {
4343
},
4444
},
4545
},
46+
47+
pillDefault:{
48+
background:colors.zinc[200],
49+
outline:colors.zinc[300],
50+
text:colors.zinc[700],
51+
},
4652
}satisfiesNewTheme;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp