From 7b3e116bf8f14bd2996b9881977a47025723c68f Mon Sep 17 00:00:00 2001 From: Alfonso Hernandez Date: Wed, 17 Jul 2024 20:26:27 +0200 Subject: [PATCH] feat(frontend): remove AccessApprovalPolicyList --- .../SecretApprovalPage/SecretApprovalPage.tsx | 6 - .../AccessApprovalPolicyList.tsx | 174 ------------ .../components/AccessApprovalPolicyRow.tsx | 146 ---------- .../components/AccessPolicyModal.tsx | 266 ------------------ .../AccessApprovalPolicyList/index.tsx | 1 - 5 files changed, 593 deletions(-) delete mode 100644 frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/AccessApprovalPolicyList.tsx delete mode 100644 frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessApprovalPolicyRow.tsx delete mode 100644 frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessPolicyModal.tsx delete mode 100644 frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/index.tsx diff --git a/frontend/src/views/SecretApprovalPage/SecretApprovalPage.tsx b/frontend/src/views/SecretApprovalPage/SecretApprovalPage.tsx index f8d056cce..df0ba55f9 100644 --- a/frontend/src/views/SecretApprovalPage/SecretApprovalPage.tsx +++ b/frontend/src/views/SecretApprovalPage/SecretApprovalPage.tsx @@ -8,7 +8,6 @@ import { Divider } from "@app/components/v2/Divider"; import { useWorkspace } from "@app/context"; import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount } from "@app/hooks/api"; -import { AccessApprovalPolicyList } from "./components/AccessApprovalPolicyList"; import { AccessApprovalRequest } from "./components/AccessApprovalRequest"; import { ApprovalPolicyList } from "./components/ApprovalPolicyList"; import { SecretApprovalPolicyList } from "./components/SecretApprovalPolicyList"; @@ -66,8 +65,6 @@ export const SecretApprovalPage = () => { Access Requests {Boolean(accessApprovalRequestCount?.pendingCount) && {accessApprovalRequestCount?.pendingCount}} - Access Request Policies - Policies @@ -79,9 +76,6 @@ export const SecretApprovalPage = () => { - - - diff --git a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/AccessApprovalPolicyList.tsx b/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/AccessApprovalPolicyList.tsx deleted file mode 100644 index aa47cce80..000000000 --- a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/AccessApprovalPolicyList.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { faFileShield, faPlus } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -import { createNotification } from "@app/components/notifications"; -import { ProjectPermissionCan } from "@app/components/permissions"; -import { - Button, - DeleteActionModal, - EmptyState, - Table, - TableContainer, - TableSkeleton, - TBody, - Td, - Th, - THead, - Tr, - UpgradePlanModal -} from "@app/components/v2"; -import { - ProjectPermissionActions, - ProjectPermissionSub, - useProjectPermission, - useSubscription, - useWorkspace -} from "@app/context"; -import { usePopUp } from "@app/hooks"; -import { useDeleteAccessApprovalPolicy, useGetWorkspaceUsers } from "@app/hooks/api"; -import { useGetAccessApprovalPolicies } from "@app/hooks/api/accessApproval/queries"; -import { TAccessApprovalPolicy } from "@app/hooks/api/types"; - -import { AccessApprovalPolicyRow } from "./components/AccessApprovalPolicyRow"; -import { AccessPolicyForm } from "./components/AccessPolicyModal"; - -interface IProps { - workspaceId: string; -} - -export const AccessApprovalPolicyList = ({ workspaceId }: IProps) => { - const { handlePopUpToggle, handlePopUpOpen, handlePopUpClose, popUp } = usePopUp([ - "secretPolicyForm", - "deletePolicy", - "upgradePlan" - ] as const); - const { permission } = useProjectPermission(); - const { subscription } = useSubscription(); - const { currentWorkspace } = useWorkspace(); - - const { data: members } = useGetWorkspaceUsers(workspaceId); - const { data: policies, isLoading: isPoliciesLoading } = useGetAccessApprovalPolicies({ - projectSlug: currentWorkspace?.slug as string, - options: { - enabled: - permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval) && - !!currentWorkspace?.slug - } - }); - - const { mutateAsync: deleteSecretApprovalPolicy } = useDeleteAccessApprovalPolicy(); - - const handleDeletePolicy = async () => { - const { id } = popUp.deletePolicy.data as TAccessApprovalPolicy; - if (!currentWorkspace?.slug) return; - - try { - await deleteSecretApprovalPolicy({ - projectSlug: currentWorkspace?.slug, - id - }); - createNotification({ - type: "success", - text: "Successfully deleted policy" - }); - handlePopUpClose("deletePolicy"); - } catch (err) { - console.log(err); - createNotification({ - type: "error", - text: "Failed to delete policy" - }); - } - }; - - return ( -
-
-
- Access Request Policies -
- Implement secret request policies for specific secrets and environments. -
-
-
- - {(isAllowed) => ( - - )} - -
-
- - - - - - - - - - - - - {isPoliciesLoading && ( - - )} - {!isPoliciesLoading && !policies?.length && ( - - - - )} - {!!currentWorkspace && - policies?.map((policy) => ( - handlePopUpOpen("secretPolicyForm", policy)} - onDelete={() => handlePopUpOpen("deletePolicy", policy)} - /> - ))} - -
NameEnvironmentSecret PathEligible ApproversApproval Required -
- -
-
- handlePopUpToggle("secretPolicyForm", isOpen)} - members={members} - editValues={popUp.secretPolicyForm.data as TAccessApprovalPolicy} - /> - handlePopUpToggle("deletePolicy", isOpen)} - onDeleteApproved={handleDeletePolicy} - /> - handlePopUpToggle("upgradePlan", isOpen)} - text="You can add secret approval policy if you switch to Infisical's Enterprise plan." - /> -
- ); -}; diff --git a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessApprovalPolicyRow.tsx b/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessApprovalPolicyRow.tsx deleted file mode 100644 index 8476bac8d..000000000 --- a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessApprovalPolicyRow.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { useState } from "react"; -import { faCheckCircle, faPencil, faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -import { ProjectPermissionCan } from "@app/components/permissions"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuTrigger, - IconButton, - Input, - Td, - Tr -} from "@app/components/v2"; -import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context"; -import { useUpdateAccessApprovalPolicy } from "@app/hooks/api"; -import { TAccessApprovalPolicy } from "@app/hooks/api/types"; -import { TWorkspaceUser } from "@app/hooks/api/users/types"; - -type Props = { - policy: TAccessApprovalPolicy; - members?: TWorkspaceUser[]; - projectSlug: string; - onEdit: () => void; - onDelete: () => void; -}; - -export const AccessApprovalPolicyRow = ({ - policy, - members = [], - projectSlug, - onEdit, - onDelete -}: Props) => { - const [selectedApprovers, setSelectedApprovers] = useState([]); - const { mutate: updateAccessApprovalPolicy, isLoading } = useUpdateAccessApprovalPolicy(); - const { permission } = useProjectPermission(); - - return ( - - {policy.name} - {policy.environment.slug} - {policy.secretPath || "*"} - - { - if (!isOpen) { - updateAccessApprovalPolicy( - { - projectSlug, - id: policy.id, - approvers: selectedApprovers - }, - { - onSettled: () => { - setSelectedApprovers([]); - } - } - ); - } else { - setSelectedApprovers(policy.approvers); - } - }} - > - - - - - - Select members that are allowed to approve changes - - {members?.map(({ id, user }) => { - const isChecked = selectedApprovers.includes(id); - return ( - { - evt.preventDefault(); - setSelectedApprovers((state) => - isChecked ? state.filter((el) => el !== id) : [...state, id] - ); - }} - key={`create-policy-members-${id}`} - iconPos="right" - icon={isChecked && } - > - {user.username} - - ); - })} - - - - {policy.approvals} - -
- - {(isAllowed) => ( - - - - )} - - - {(isAllowed) => ( - - - - )} - -
- - - ); -}; diff --git a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessPolicyModal.tsx b/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessPolicyModal.tsx deleted file mode 100644 index 6c0ee3fb6..000000000 --- a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/components/AccessPolicyModal.tsx +++ /dev/null @@ -1,266 +0,0 @@ -import { useEffect } from "react"; -import { Controller, useForm } from "react-hook-form"; -import { faCheckCircle } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { z } from "zod"; - -import { createNotification } from "@app/components/notifications"; -import { - Button, - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuTrigger, - FormControl, - Input, - Modal, - ModalContent, - Select, - SelectItem -} from "@app/components/v2"; -import { useWorkspace } from "@app/context"; -import { - useCreateAccessApprovalPolicy, - useUpdateAccessApprovalPolicy -} from "@app/hooks/api/accessApproval"; -import { TAccessApprovalPolicy } from "@app/hooks/api/accessApproval/types"; -import { TWorkspaceUser } from "@app/hooks/api/users/types"; - -type Props = { - isOpen?: boolean; - onToggle: (isOpen: boolean) => void; - members?: TWorkspaceUser[]; - projectSlug: string; - editValues?: TAccessApprovalPolicy; -}; - -const formSchema = z - .object({ - environment: z.string(), - name: z.string().optional(), - secretPath: z.string().optional(), - approvals: z.number().min(1), - approvers: z.string().array().min(1) - }) - .refine((data) => data.approvals <= data.approvers.length, { - path: ["approvals"], - message: "The number of approvals should be lower than the number of approvers." - }); - -type TFormSchema = z.infer; - -export const AccessPolicyForm = ({ - isOpen, - onToggle, - members = [], - projectSlug, - editValues -}: Props) => { - const { - control, - handleSubmit, - reset, - formState: { isSubmitting } - } = useForm({ - resolver: zodResolver(formSchema), - values: editValues ? { ...editValues, environment: editValues.environment.slug } : undefined - }); - const { currentWorkspace } = useWorkspace(); - - const environments = currentWorkspace?.environments || []; - useEffect(() => { - if (!isOpen) reset({}); - }, [isOpen]); - - const isEditMode = Boolean(editValues); - - const { mutateAsync: createAccessApprovalPolicy } = useCreateAccessApprovalPolicy(); - const { mutateAsync: updateAccessApprovalPolicy } = useUpdateAccessApprovalPolicy(); - - const handleCreatePolicy = async (data: TFormSchema) => { - if (!projectSlug) return; - - try { - await createAccessApprovalPolicy({ - ...data, - projectSlug - }); - createNotification({ - type: "success", - text: "Successfully created policy" - }); - onToggle(false); - } catch (err) { - console.log(err); - createNotification({ - type: "error", - text: "Failed to create policy" - }); - } - }; - - const handleUpdatePolicy = async (data: TFormSchema) => { - if (!projectSlug) return; - if (!editValues?.id) return; - - try { - await updateAccessApprovalPolicy({ - id: editValues?.id, - ...data, - projectSlug - }); - createNotification({ - type: "success", - text: "Successfully updated policy" - }); - onToggle(false); - } catch (err) { - console.log(err); - createNotification({ - type: "error", - text: "failed to update policy" - }); - } - }; - - const handleFormSubmit = async (data: TFormSchema) => { - if (isEditMode) { - await handleUpdatePolicy(data); - } else { - await handleCreatePolicy(data); - } - }; - - return ( - - -
- ( - - - - )} - /> - ( - - - - )} - /> - - ( - - - - )} - /> - - ( - - - - - - - - Select members that are allowed to approve changes - - {members.map(({ id, user }) => { - const isChecked = value?.includes(id); - return ( - { - evt.preventDefault(); - onChange( - isChecked ? value?.filter((el) => el !== id) : [...(value || []), id] - ); - }} - key={`create-policy-members-${id}`} - iconPos="right" - icon={isChecked && } - > - {user.username} - - ); - })} - - - - )} - /> - ( - - field.onChange(parseInt(el.target.value, 10))} - /> - - )} - /> -
- - -
- -
-
- ); -}; diff --git a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/index.tsx b/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/index.tsx deleted file mode 100644 index f6db07c94..000000000 --- a/frontend/src/views/SecretApprovalPage/components/AccessApprovalPolicyList/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { AccessApprovalPolicyList } from "./AccessApprovalPolicyList";