diff --git a/backend/src/ee/routes/v1/org-role-router.ts b/backend/src/ee/routes/v1/org-role-router.ts index 559bd1611..ae7304907 100644 --- a/backend/src/ee/routes/v1/org-role-router.ts +++ b/backend/src/ee/routes/v1/org-role-router.ts @@ -53,7 +53,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => { }); server.route({ - // new: note that doesn't work for default roles method: "GET", url: "/:organizationId/roles/:roleId", config: { diff --git a/backend/src/services/org/org-role-service.ts b/backend/src/services/org/org-role-service.ts index 262f98bc6..26cfd67eb 100644 --- a/backend/src/services/org/org-role-service.ts +++ b/backend/src/services/org/org-role-service.ts @@ -51,9 +51,50 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol ) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role); - const role = await orgRoleDAL.findOne({ id: roleId, orgId }); - if (!role) throw new BadRequestError({ message: "Role not found", name: "Get role" }); - return role; + + switch (roleId) { + case "b11b49a9-09a9-4443-916a-4246f9ff2c69": { + return { + id: roleId, + orgId, + name: "Admin", + slug: "admin", + description: "Complete administration access over the organization", + permissions: packRules(orgAdminPermissions.rules), + createdAt: new Date(), + updatedAt: new Date() + }; + } + case "b11b49a9-09a9-4443-916a-4246f9ff2c70": { + return { + id: roleId, + orgId, + name: "Member", + slug: "member", + description: "Non-administrative role in an organization", + permissions: packRules(orgMemberPermissions.rules), + createdAt: new Date(), + updatedAt: new Date() + }; + } + case "b10d49a9-09a9-4443-916a-4246f9ff2c72": { + return { + id: "b10d49a9-09a9-4443-916a-4246f9ff2c72", // dummy user for zod validation in response + orgId, + name: "No Access", + slug: "no-access", + description: "No access to any resources in the organization", + permissions: packRules(orgNoAccessPermissions.rules), + createdAt: new Date(), + updatedAt: new Date() + }; + } + default: { + const role = await orgRoleDAL.findOne({ id: roleId, orgId }); + if (!role) throw new BadRequestError({ message: "Role not found", name: "Get role" }); + return role; + } + } }; const updateRole = async ( diff --git a/frontend/src/views/Org/RolePage/components/RoleDetailsSection.tsx b/frontend/src/views/Org/RolePage/components/RoleDetailsSection.tsx index 4142569fd..6497f5ba6 100644 --- a/frontend/src/views/Org/RolePage/components/RoleDetailsSection.tsx +++ b/frontend/src/views/Org/RolePage/components/RoleDetailsSection.tsx @@ -21,32 +21,35 @@ export const RoleDetailsSection = ({ roleId, handlePopUpOpen }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; const { data } = useGetOrgRole(orgId, roleId); + const isCustomRole = !["admin", "member", "no-access"].includes(data?.slug ?? ""); return data ? (

Details

- - {(isAllowed) => { - return ( - - - handlePopUpOpen("role", { - roleId - }) - } - > - - - - ); - }} - + {isCustomRole && ( + + {(isAllowed) => { + return ( + + + handlePopUpOpen("role", { + roleId + }) + } + > + + + + ); + }} + + )}
diff --git a/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionRow.tsx b/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionRow.tsx index 60c181d17..b27a95a22 100644 --- a/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionRow.tsx +++ b/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionRow.tsx @@ -3,7 +3,8 @@ import { Control, Controller, UseFormSetValue, useWatch } from "react-hook-form" import { faChevronDown, faChevronRight } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Checkbox, IconButton, Select, SelectItem, Td, Tr } from "@app/components/v2"; +import { createNotification } from "@app/components/notifications"; +import { Checkbox, Select, SelectItem, Td, Tr } from "@app/components/v2"; import { useToggle } from "@app/hooks"; import { TFormSchema } from "@app/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.utils"; @@ -58,6 +59,7 @@ const getPermissionList = (option: string) => { }; type Props = { + isEditable: boolean; title: string; formName: keyof Omit, "workspace">; setValue: UseFormSetValue; @@ -76,7 +78,14 @@ enum Permission { // TODO: support for default roles -export const RolePermissionRow = ({ title, formName, handleSubmit, control, setValue }: Props) => { +export const RolePermissionRow = ({ + isEditable, + title, + formName, + handleSubmit, + control, + setValue +}: Props) => { const [isRowExpanded, setIsRowExpanded] = useToggle(); const [isCustom, setIsCustom] = useToggle(); @@ -159,14 +168,7 @@ export const RolePermissionRow = ({ title, formName, handleSubmit, control, setV onClick={() => setIsRowExpanded.toggle()} > - setIsRowExpanded.toggle()} - > - - + {title} @@ -175,6 +177,7 @@ export const RolePermissionRow = ({ title, formName, handleSubmit, control, setV className="w-40 bg-mineshaft-600" dropdownContainerClassName="border border-mineshaft-600 bg-mineshaft-800" onValueChange={handlePermissionChange} + isDisabled={!isEditable} > No Access Read Only @@ -200,6 +203,13 @@ export const RolePermissionRow = ({ title, formName, handleSubmit, control, setV { + if (!isEditable) { + createNotification({ + type: "error", + text: "Failed to update default role" + }); + return; + } field.onChange(e); handleSubmit(); }} diff --git a/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionsTable.tsx b/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionsTable.tsx index ac485b47b..0140d8eff 100644 --- a/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionsTable.tsx +++ b/frontend/src/views/Org/RolePage/components/RolePermissionsSection/RolePermissionsTable.tsx @@ -93,6 +93,8 @@ export const RolePermissionsTable = ({ roleId }: Props) => { } }; + const isCustomRole = !["admin", "member", "no-access"].includes(role?.slug ?? ""); + return (
@@ -114,6 +116,7 @@ export const RolePermissionsTable = ({ roleId }: Props) => { setValue={setValue} handleSubmit={handleSubmit(onSubmit)} key={`org-role-${roleId}-permission-${permission.formName}`} + isEditable={isCustomRole} /> ); })}