diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx deleted file mode 100644 index 9c8bb4da2..000000000 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx +++ /dev/null @@ -1,249 +0,0 @@ -import { useForm } from "react-hook-form"; -import { - faArrowLeft, - faCog, - faContactCard, - faMagnifyingGlass, - faMoneyBill, - faServer, - faSignIn, - faUser, - faUserCog, - faUsers -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { zodResolver } from "@hookform/resolvers/zod"; - -import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, Input } from "@app/components/v2"; -import { useOrganization } from "@app/context"; -import { useCreateOrgRole, useUpdateOrgRole } from "@app/hooks/api"; -import { TOrgRole } from "@app/hooks/api/roles/types"; - -import { - formRolePermission2API, - formSchema, - rolePermission2Form, - TFormSchema -} from "./OrgRoleModifySection.utils"; -import { SimpleLevelPermissionOption } from "./SimpleLevelPermissionOptions"; -import { WorkspacePermission } from "./WorkspacePermission"; - -type Props = { - role?: TOrgRole; - onGoBack: VoidFunction; -}; - -const SIMPLE_PERMISSION_OPTIONS = [ - { - title: "User management", - subtitle: "Invite, view and remove users from the organization", - icon: faUser, - formName: "member" - }, - { - title: "Group management", - subtitle: "Invite, view and remove user groups from the organization", - icon: faUsers, - formName: "groups" - }, - { - title: "Machine identity management", - subtitle: "Create, view, update and remove (machine) identities from the organization", - icon: faServer, - formName: "identity" - }, - { - title: "Billing & usage", - subtitle: "Modify organization subscription plan", - icon: faMoneyBill, - formName: "billing" - }, - { - title: "Role management", - subtitle: "Create, modify and remove organization roles", - icon: faUserCog, - formName: "role" - }, - { - title: "Incident Contacts", - subtitle: "Incident contacts management control", - icon: faContactCard, - formName: "incident-contact" - }, - { - title: "Organization profile", - subtitle: "View & update organization metadata such as name", - icon: faCog, - formName: "settings" - }, - { - title: "Secret Scanning", - subtitle: "Secret scanning management control", - icon: faMagnifyingGlass, - formName: "secret-scanning" - }, - { - title: "SSO", - subtitle: "Define organization level SSO requirements", - icon: faSignIn, - formName: "sso" - }, - { - title: "LDAP", - subtitle: "Define organization level LDAP requirements", - icon: faSignIn, - formName: "ldap" - }, - { - title: "SCIM", - subtitle: "Define organization level SCIM requirements", - icon: faUsers, - formName: "scim" - } -] as const; - -export const OrgRoleModifySection = ({ role, onGoBack }: Props) => { - const isNonEditable = ["owner", "admin", "member", "no-access"].includes(role?.slug || ""); - const isNewRole = !role?.slug; - const { currentOrg } = useOrganization(); - const orgId = currentOrg?.id || ""; - const { - handleSubmit, - register, - formState: { isSubmitting, isDirty, errors }, - setValue, - control - } = useForm({ - defaultValues: role ? { ...role, permissions: rolePermission2Form(role.permissions) } : {}, - resolver: zodResolver(formSchema) - }); - - const { mutateAsync: createRole } = useCreateOrgRole(); - const { mutateAsync: updateRole } = useUpdateOrgRole(); - - const handleRoleUpdate = async (el: TFormSchema) => { - if (!role?.id) return; - - try { - await updateRole({ - orgId, - id: role?.id, - ...el, - permissions: formRolePermission2API(el.permissions) - }); - createNotification({ type: "success", text: "Successfully updated role" }); - onGoBack(); - } catch (err) { - console.log(err); - createNotification({ type: "error", text: "Failed to update role" }); - } - }; - - const handleFormSubmit = async (el: TFormSchema) => { - if (!isNewRole) { - await handleRoleUpdate(el); - return; - } - - try { - await createRole({ - orgId, - ...el, - permissions: formRolePermission2API(el.permissions) - }); - createNotification({ type: "success", text: "Created new role" }); - onGoBack(); - } catch (err) { - console.log(err); - createNotification({ type: "error", text: "Failed to create role" }); - } - }; - - return ( -
-
-
-

- {isNewRole ? "New" : "Edit"} Role -

- -
-

- Organization-level roles allow you to define permissions for resources at a high level - across the organization -

-
- - - - - - - - - -
-
-

Add Permission

-
-
-
- -
- {SIMPLE_PERMISSION_OPTIONS.map(({ title, subtitle, icon, formName }) => ( -
- -
- ))} -
-
- - -
-
-
- ); -}; diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/SimpleLevelPermissionOptions.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/SimpleLevelPermissionOptions.tsx deleted file mode 100644 index 8fe6a1953..000000000 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/SimpleLevelPermissionOptions.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { useEffect, useMemo } from "react"; -import { Control, Controller, UseFormSetValue, useWatch } from "react-hook-form"; -import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { motion } from "framer-motion"; -import { twMerge } from "tailwind-merge"; - -import { Checkbox, Select, SelectItem } from "@app/components/v2"; -import { useToggle } from "@app/hooks"; - -import { TFormSchema } from "./OrgRoleModifySection.utils"; - -type Props = { - formName: keyof Omit, "workspace">; - isNonEditable?: boolean; - setValue: UseFormSetValue; - control: Control; - title: string; - subtitle: string; - icon: IconProp; -}; - -enum Permission { - NoAccess = "no-access", - ReadOnly = "read-only", - FullAccess = "full-acess", - Custom = "custom" -} - -const PERMISSIONS = [ - { action: "read", label: "View" }, - { action: "create", label: "Create" }, - { action: "edit", label: "Modify" }, - { action: "delete", label: "Remove" } -] as const; - -const SECRET_SCANNING_PERMISSIONS = [ - { action: "read", label: "View risks" }, - { action: "create", label: "Add integrations" }, - { action: "edit", label: "Edit risk status" }, - { action: "delete", label: "Remove integrations" } -] as const; - -const INCIDENT_CONTACTS_PERMISSIONS = [ - { action: "read", label: "View contacts" }, - { action: "create", label: "Add new contacts" }, - { action: "edit", label: "Edit contacts" }, - { action: "delete", label: "Remove contacts" } -] as const; - -const MEMBERS_PERMISSIONS = [ - { action: "read", label: "View all members" }, - { action: "create", label: "Invite members" }, - { action: "edit", label: "Edit members" }, - { action: "delete", label: "Remove members" } -] as const; - -const BILLING_PERMISSIONS = [ - { action: "read", label: "View bills" }, - { action: "create", label: "Add payment methods" }, - { action: "edit", label: "Edit payments" }, - { action: "delete", label: "Remove payments" } -] as const; - -const getPermissionList = (option: Props["formName"]) => { - switch (option) { - case "secret-scanning": - return SECRET_SCANNING_PERMISSIONS; - case "billing": - return BILLING_PERMISSIONS; - case "incident-contact": - return INCIDENT_CONTACTS_PERMISSIONS; - case "member": - return MEMBERS_PERMISSIONS; - default: - return PERMISSIONS; - } -}; - -export const SimpleLevelPermissionOption = ({ - isNonEditable, - setValue, - control, - formName, - subtitle, - title, - icon -}: Props) => { - const rule = useWatch({ - control, - name: `permissions.${formName}` - }); - const [isCustom, setIsCustom] = useToggle(); - - const selectedPermissionCategory = useMemo(() => { - const actions = Object.keys(rule || {}) as Array; - const totalActions = PERMISSIONS.length; - const score = actions.map((key) => (rule?.[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number); - - if (isCustom) return Permission.Custom; - if (score === 0) return Permission.NoAccess; - if (score === totalActions) return Permission.FullAccess; - if (score === 1 && rule?.read) return Permission.ReadOnly; - - return Permission.Custom; - }, [rule, isCustom]); - - useEffect(() => { - if (selectedPermissionCategory === Permission.Custom) setIsCustom.on(); - else setIsCustom.off(); - }, [selectedPermissionCategory]); - - const handlePermissionChange = (val: Permission) => { - if (val === Permission.Custom) setIsCustom.on(); - else setIsCustom.off(); - - switch (val) { - case Permission.NoAccess: - setValue( - `permissions.${formName}`, - { read: false, edit: false, create: false, delete: false }, - { shouldDirty: true } - ); - break; - case Permission.FullAccess: - setValue( - `permissions.${formName}`, - { read: true, edit: true, create: true, delete: true }, - { shouldDirty: true } - ); - break; - case Permission.ReadOnly: - setValue( - `permissions.${formName}`, - { read: true, edit: false, create: false, delete: false }, - { shouldDirty: true } - ); - break; - default: - setValue( - `permissions.${formName}`, - { read: false, edit: false, create: false, delete: false }, - { shouldDirty: true } - ); - break; - } - }; - - return ( -
-
-
- -
-
-
{title}
-
{subtitle}
-
-
- -
-
- - {isCustom && - getPermissionList(formName).map(({ action, label }) => ( - ( - - {label} - - )} - /> - ))} - -
- ); -}; diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/WorkspacePermission.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/WorkspacePermission.tsx index 7c98f1759..465029f8b 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/WorkspacePermission.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/WorkspacePermission.tsx @@ -8,7 +8,7 @@ import { twMerge } from "tailwind-merge"; import { Checkbox, Select, SelectItem } from "@app/components/v2"; import { useToggle } from "@app/hooks"; -import { TFormSchema } from "./OrgRoleModifySection.utils"; +import { TFormSchema } from "../../../../RolePage/components/OrgRoleModifySection.utils"; type Props = { isNonEditable?: boolean; diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/index.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/index.tsx deleted file mode 100644 index 86de1647a..000000000 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { OrgRoleModifySection } from "./OrgRoleModifySection"; diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx index ef83bca9c..8e6c5d591 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx @@ -1,27 +1,9 @@ import { motion } from "framer-motion"; -import { usePopUp } from "@app/hooks"; -import { TOrgRole } from "@app/hooks/api/roles/types"; - -import { OrgRoleModifySection } from "./OrgRoleModifySection"; import { OrgRoleTable } from "./OrgRoleTable"; export const OrgRoleTabSection = () => { - const { popUp, handlePopUpClose } = usePopUp(["editRole"] as const); - return popUp.editRole.isOpen ? ( - - handlePopUpClose("editRole")} - /> - - ) : ( + return (