Skip to main content
Glama

Convex MCP server

Official
by get-convex
DeleteProjectModal.tsx6.4 kB
import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { Callout } from "@ui/Callout"; import { ConfirmationDialog } from "@ui/ConfirmationDialog"; import { Checkbox } from "@ui/Checkbox"; import { LoadingTransition } from "@ui/Loading"; import { WaitForDeploymentApi } from "@common/lib/deploymentContext"; import { useDeployments } from "api/deployments"; import { useTeamMembers } from "api/teams"; import { useDeleteProject } from "api/projects"; import { useQuery } from "convex/react"; import { ProjectDetails, Team } from "generatedApi"; import udfs from "@common/udfs"; import { useState } from "react"; import { DeploymentInfoProvider } from "providers/DeploymentInfoProvider"; import { MaybeDeploymentApiProvider } from "providers/MaybeDeploymentApiProvider"; export function DeleteProjectModal({ onClose, onDelete, team, project, }: { onClose: () => void; onDelete?: () => void; team: Team; project: ProjectDetails; }) { const deleteProject = useDeleteProject( team.id, project.id, project.name || "Untitled Project", ); const handleDelete = async () => { onDelete && onDelete(); await deleteProject(); onClose(); }; const { deployments } = useDeployments(project.id); const prodDeployment = deployments?.find((d) => d.deploymentType === "prod"); return deployments && prodDeployment ? ( <DeploymentInfoProvider deploymentOverride={prodDeployment.name}> <MaybeDeploymentApiProvider deploymentOverride={prodDeployment.name}> <WaitForDeploymentApi sizeClass="hidden"> <DeleteProjectModalContentWithProd team={team} project={project} onClose={onClose} handleDelete={handleDelete} /> </WaitForDeploymentApi> </MaybeDeploymentApiProvider> </DeploymentInfoProvider> ) : ( <DeleteProjectDialog onClose={onClose} onConfirm={handleDelete} validationText={project.isDemo ? undefined : project.name} > <DeleteProjectModalContent team={team} /> </DeleteProjectDialog> ); } function DeleteProjectModalContentWithProd({ team, project, onClose, handleDelete, }: { team: Team; project: ProjectDetails; onClose: () => void; handleDelete: () => Promise<void>; }) { const numFiles = useQuery(udfs.fileStorageV2.numFiles, { componentId: null, }); const numDocuments = useQuery(udfs.tableSize.sizeOfAllTables, { componentId: null, }); const doneLoading = numFiles !== undefined && numDocuments !== undefined; const showAdditionalConfirmation = !doneLoading || numFiles > 0 || numDocuments > 0; const [acceptedConsequences, setAcceptedConsequences] = useState(false); const shouldDisable = !acceptedConsequences && showAdditionalConfirmation; return ( <DeleteProjectDialog onClose={onClose} onConfirm={handleDelete} validationText={shouldDisable ? undefined : project.name} disableConfirm={shouldDisable} > <LoadingTransition loadingProps={{ fullHeight: false, className: "h-64" }} > {doneLoading && ( <DeleteProjectModalContent team={team} additionalBody={ showAdditionalConfirmation && ( <Callout className="flex flex-col gap-2"> <div className="flex items-start gap-2"> <ExclamationTriangleIcon className="mt-1" /> <div className="flex flex-col gap-1"> <div className="flex flex-col gap-1"> <span> This project contains data in{" "} <span className="font-semibold">Production</span>: </span> <ul className="ml-4 flex list-disc flex-col gap-1"> <li> <span className="font-semibold"> {numDocuments.toLocaleString()} Documents </span>{" "} stored across all tables. </li> <li> <span className="font-semibold"> {numFiles.toLocaleString()} Files </span>{" "} stored. </li> </ul> </div> </div> </div> <label className="flex gap-2 text-sm"> <Checkbox className="mt-0.5" checked={acceptedConsequences} onChange={(e) => setAcceptedConsequences(e.currentTarget.checked) } />{" "} By checking this box, I acknowledge the consequences of deleting this project. </label> </Callout> ) } /> )} </LoadingTransition> </DeleteProjectDialog> ); } function DeleteProjectModalContent({ team, additionalBody, }: { team: Team; additionalBody?: React.ReactNode; }) { const members = useTeamMembers(team?.id); const numOtherTeamMembers = members ? members.length - 1 : 0; let warningMessage: React.ReactNode | string = "Delete this project and all associated data."; if (members && numOtherTeamMembers >= 1) { warningMessage = ( <span> Delete this project for you and{" "} <span className="font-semibold"> {numOtherTeamMembers} other team member {numOtherTeamMembers > 1 ? "s" : ""} </span> . </span> ); } return ( <div className="flex w-full flex-col gap-2"> {warningMessage} <span className="font-semibold"> Deleted projects cannot be recovered. </span> {additionalBody} </div> ); } function DeleteProjectDialog({ children, ...props }: { onClose: () => void; onConfirm: () => Promise<void>; validationText?: string; disableConfirm?: boolean; children: React.ReactNode; }) { return ( <ConfirmationDialog {...props} confirmText="Delete Project" variant="danger" dialogTitle="Delete Project" dialogBody={children} /> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server