"use client"; import { useEffect, useState, FC } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { ChevronDown, ChevronUp, Pencil } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; import { IWorkspace } from "@plane/types"; // ui import { Button, CustomSelect, Input, TOAST_TYPE, setToast } from "@plane/ui"; // components import { LogoSpinner } from "@/components/common"; import { WorkspaceImageUploadModal } from "@/components/core"; import { DeleteWorkspaceModal } from "@/components/workspace"; // constants import { WORKSPACE_UPDATED } from "@/constants/event-tracker"; import { EUserWorkspaceRoles, ORGANIZATION_SIZE } from "@/constants/workspace"; // helpers import { copyUrlToClipboard } from "@/helpers/string.helper"; // hooks import { useEventTracker, useUser, useWorkspace } from "@/hooks/store"; // services import { FileService } from "@/services/file.service"; // types const defaultValues: Partial = { name: "", url: "", organization_size: "2-10", logo: null, }; // services const fileService = new FileService(); export const WorkspaceDetails: FC = observer(() => { // states const [isLoading, setIsLoading] = useState(false); const [deleteWorkspaceModal, setDeleteWorkspaceModal] = useState(false); const [isImageRemoving, setIsImageRemoving] = useState(false); const [isImageUploadModalOpen, setIsImageUploadModalOpen] = useState(false); // store hooks const { captureWorkspaceEvent } = useEventTracker(); const { membership: { currentWorkspaceRole }, } = useUser(); const { currentWorkspace, updateWorkspace } = useWorkspace(); // form info const { handleSubmit, control, reset, watch, formState: { errors }, } = useForm({ defaultValues: { ...defaultValues, ...currentWorkspace }, }); const onSubmit = async (formData: IWorkspace) => { if (!currentWorkspace) return; setIsLoading(true); const payload: Partial = { logo: formData.logo, name: formData.name, organization_size: formData.organization_size, }; await updateWorkspace(currentWorkspace.slug, payload) .then((res) => { captureWorkspaceEvent({ eventName: WORKSPACE_UPDATED, payload: { ...res, state: "SUCCESS", element: "Workspace general settings page", }, }); setToast({ title: "Success!", type: TOAST_TYPE.SUCCESS, message: "Workspace updated successfully", }); }) .catch((err) => { captureWorkspaceEvent({ eventName: WORKSPACE_UPDATED, payload: { state: "FAILED", element: "Workspace general settings page", }, }); console.error(err); }); setTimeout(() => { setIsLoading(false); }, 300); }; const handleRemoveLogo = () => { if (!currentWorkspace) return; const url = currentWorkspace.logo; if (!url) return; setIsImageRemoving(true); fileService.deleteFile(currentWorkspace.id, url).then(() => { updateWorkspace(currentWorkspace.slug, { logo: "" }) .then(() => { setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", message: "Workspace picture removed successfully.", }); setIsImageUploadModalOpen(false); }) .catch(() => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "There was some error in deleting your profile picture. Please try again.", }); }) .finally(() => setIsImageRemoving(false)); }); }; const handleCopyUrl = () => { if (!currentWorkspace) return; copyUrlToClipboard(`${currentWorkspace.slug}`).then(() => { setToast({ type: TOAST_TYPE.SUCCESS, title: "Workspace URL copied to the clipboard.", }); }); }; useEffect(() => { if (currentWorkspace) reset({ ...currentWorkspace }); }, [currentWorkspace, reset]); const isAdmin = currentWorkspaceRole === EUserWorkspaceRoles.ADMIN; if (!currentWorkspace) return (
); return ( <> setDeleteWorkspaceModal(false)} /> ( setIsImageUploadModalOpen(false)} isRemoving={isImageRemoving} handleRemove={handleRemoveLogo} onSuccess={(imageUrl) => { onChange(imageUrl); setIsImageUploadModalOpen(false); handleSubmit(onSubmit)(); }} value={value} /> )} />

{watch("name")}

{isAdmin && ( )}

Workspace name

( )} />

Company size

( c === value) ?? "Select organization size"} optionsClassName="w-full" buttonClassName="!border-[0.5px] !border-custom-border-200 !shadow-none" input disabled={!isAdmin} > {ORGANIZATION_SIZE.map((item) => ( {item} ))} )} />

Workspace URL

( )} />
{isAdmin && (
)}
{isAdmin && ( {({ open }) => (
Delete Workspace {/* */} {open ? : }
The danger zone of the workspace delete page is a critical area that requires careful consideration and attention. When deleting a workspace, all of the data and resources within that workspace will be permanently removed and cannot be recovered.
)}
)}
); });