import { subject } from "@casl/ability"; import { faClose, faFingerprint, faPencilSquare, faWarning } 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, IconButton, Modal, ModalContent, Tag, Tooltip } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useDeleteDynamicSecret } from "@app/hooks/api"; import { DynamicSecretProviders, DynamicSecretStatus, TDynamicSecret } from "@app/hooks/api/dynamicSecret/types"; import { SortDir } from "../../SecretMainPage.types"; import { CreateDynamicSecretLease } from "./CreateDynamicSecretLease"; import { DynamicSecretLease } from "./DynamicSecretLease"; import { EditDynamicSecretForm } from "./EditDynamicSecretForm"; const formatProviderName = (type: DynamicSecretProviders) => { if (type === DynamicSecretProviders.SqlDatabase) return "SQL Database"; return ""; }; type Props = { dynamicSecrets: TDynamicSecret[]; environment: string; projectSlug: string; secretPath?: string; sortDir: SortDir; }; export const DynamicSecretListView = ({ dynamicSecrets = [], environment, projectSlug, secretPath = "/", sortDir = SortDir.ASC }: Props) => { const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([ "dynamicSecretLeases", "createDynamicSecretLease", "updateDynamicSecret", "deleteDynamicSecret" ] as const); const deleteDynamicSecret = useDeleteDynamicSecret(); const handleDynamicSecretDelete = async () => { try { const { name, isForced } = popUp.deleteDynamicSecret.data as TDynamicSecret & { isForced?: boolean; }; await deleteDynamicSecret.mutateAsync({ environmentSlug: environment, projectSlug, path: secretPath, name, isForced }); handlePopUpClose("deleteDynamicSecret"); createNotification({ type: "success", text: "Successfully deleted dynamic secret" }); } catch (error) { console.log(error); createNotification({ type: "error", text: "Failed to delete dynamic secret" }); } }; return ( <> {dynamicSecrets .sort((a, b) => sortDir === SortDir.ASC ? a.name.toLowerCase().localeCompare(b.name.toLowerCase()) : b.name.toLowerCase().localeCompare(a.name.toLowerCase()) ) .map((secret) => { const isRevocking = secret.status === DynamicSecretStatus.Deleting; return ( handlePopUpToggle("dynamicSecretLeases", state)} >
{ if (evt.key === "Enter" && !isRevocking) handlePopUpOpen("dynamicSecretLeases", secret.id); }} onClick={() => { if (!isRevocking) { handlePopUpOpen("dynamicSecretLeases", secret.id); } }} >
{secret.name} {formatProviderName(secret.type)} {Boolean(secret.status) && ( )}
{secret.status === DynamicSecretStatus.FailedDeletion && ( )}
{(isAllowed) => ( { evt.stopPropagation(); handlePopUpOpen("updateDynamicSecret", secret); }} isDisabled={!isAllowed || isRevocking} > )} {(isAllowed) => ( { evt.stopPropagation(); handlePopUpOpen("deleteDynamicSecret", secret); }} isDisabled={!isAllowed || isRevocking} > )}
handlePopUpOpen("createDynamicSecretLease", secret)} onClose={() => handlePopUpClose("dynamicSecretLeases")} projectSlug={projectSlug} key={secret.id} dynamicSecretName={secret.name} secretPath={secretPath} environment={environment} />
); })} handlePopUpToggle("createDynamicSecretLease", state)} > handlePopUpClose("createDynamicSecretLease")} projectSlug={projectSlug} dynamicSecretName={(popUp.createDynamicSecretLease?.data as { name: string })?.name} secretPath={secretPath} environment={environment} /> handlePopUpToggle("updateDynamicSecret", state)} > handlePopUpClose("updateDynamicSecret")} projectSlug={projectSlug} dynamicSecretName={(popUp.updateDynamicSecret?.data as TDynamicSecret)?.name} secretPath={secretPath} environment={environment} /> handlePopUpToggle("deleteDynamicSecret", isOpen)} onDeleteApproved={handleDynamicSecretDelete} /> ); };