diff --git a/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsForm.tsx b/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsForm.tsx
index 480407580..801bc05b1 100644
--- a/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsForm.tsx
+++ b/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsForm.tsx
@@ -1,11 +1,21 @@
-import { Stack, FormControl, FormLabel, Flex } from '@chakra-ui/react'
+import {
+ Stack,
+ FormControl,
+ FormLabel,
+ Flex,
+ Button,
+ useDisclosure,
+ Text,
+} from '@chakra-ui/react'
+import { ConfirmModal } from 'components/modals/ConfirmModal'
import { EditableEmojiOrImageIcon } from 'components/shared/EditableEmojiOrImageIcon'
import { Input } from 'components/shared/Textbox'
import { useWorkspace } from 'contexts/WorkspaceContext'
import React from 'react'
-export const WorkspaceSettingsForm = () => {
- const { workspace, updateWorkspace } = useWorkspace()
+export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
+ const { workspace, workspaces, updateWorkspace, deleteCurrentWorkspace } =
+ useWorkspace()
const handleNameChange = (name: string) => {
if (!workspace?.id) return
@@ -17,6 +27,11 @@ export const WorkspaceSettingsForm = () => {
updateWorkspace(workspace?.id, { icon })
}
+ const handleDeleteClick = async () => {
+ await deleteCurrentWorkspace()
+ onClose()
+ }
+
return (
@@ -40,6 +55,41 @@ export const WorkspaceSettingsForm = () => {
/>
)}
+ {workspace && workspaces && workspaces.length > 1 && (
+
+ )}
)
}
+
+const DeleteWorkspaceButton = ({
+ workspaceName,
+ onConfirm,
+}: {
+ workspaceName: string
+ onConfirm: () => Promise
+}) => {
+ const { isOpen, onOpen, onClose } = useDisclosure()
+ return (
+ <>
+
+
+ Are you sure you want to delete {workspaceName} workspace? All its
+ folders, typebots and results will be deleted forever.'
+
+ }
+ confirmButtonLabel="Delete"
+ />
+ >
+ )
+}
diff --git a/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsModal.tsx b/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsModal.tsx
index 54158680e..fa784d479 100644
--- a/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsModal.tsx
+++ b/apps/builder/components/dashboard/WorkspaceSettingsModal/WorkspaceSettingsModal.tsx
@@ -132,21 +132,27 @@ export const WorkspaceSettingsModal = ({
-
+
)
}
-const SettingsContent = ({ tab }: { tab: SettingsTab }) => {
+const SettingsContent = ({
+ tab,
+ onClose,
+}: {
+ tab: SettingsTab
+ onClose: () => void
+}) => {
switch (tab) {
case 'my-account':
return
case 'user-settings':
return
case 'workspace-settings':
- return
+ return
case 'members':
return
case 'billing':
diff --git a/apps/builder/contexts/WorkspaceContext.tsx b/apps/builder/contexts/WorkspaceContext.tsx
index 9ffa349be..4dabd2de5 100644
--- a/apps/builder/contexts/WorkspaceContext.tsx
+++ b/apps/builder/contexts/WorkspaceContext.tsx
@@ -11,6 +11,7 @@ import {
createNewWorkspace,
useWorkspaces,
updateWorkspace as patchWorkspace,
+ deleteWorkspace,
} from 'services/workspace/workspace'
import { useUser } from './UserContext'
import { useTypebot } from './TypebotContext'
@@ -29,6 +30,7 @@ const workspaceContext = createContext<{
workspaceId: string,
updates: Partial
) => Promise
+ deleteCurrentWorkspace: () => Promise
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
@@ -122,6 +124,20 @@ export const WorkspaceContext = ({ children }: { children: ReactNode }) => {
})
}
+ const deleteCurrentWorkspace = async () => {
+ if (!currentWorkspace || !workspaces || workspaces.length < 2) return
+ const { data } = await deleteWorkspace(currentWorkspace.id)
+ if (!data || !currentWorkspace) return
+ setCurrentWorkspace(workspaces[0])
+ mutate({
+ workspaces: (workspaces ?? []).filter((w) =>
+ w.id === currentWorkspace.id
+ ? { ...data.workspace, members: w.members }
+ : w
+ ),
+ })
+ }
+
return (
{
switchWorkspace,
createWorkspace,
updateWorkspace,
+ deleteCurrentWorkspace,
}}
>
{children}
diff --git a/apps/builder/pages/api/workspaces/[workspaceId].ts b/apps/builder/pages/api/workspaces/[workspaceId].ts
index 6b828ce0c..2848ad172 100644
--- a/apps/builder/pages/api/workspaces/[workspaceId].ts
+++ b/apps/builder/pages/api/workspaces/[workspaceId].ts
@@ -22,6 +22,18 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
workspace: updatedWorkspace,
})
}
+ if (req.method === 'DELETE') {
+ const id = req.query.workspaceId as string
+ await prisma.workspace.deleteMany({
+ where: {
+ id,
+ members: { some: { userId: user.id, role: WorkspaceRole.ADMIN } },
+ },
+ })
+ return res.status(200).json({
+ message: 'success',
+ })
+ }
methodNotAllowed(res)
}
diff --git a/apps/builder/playwright/tests/workspaces.spec.ts b/apps/builder/playwright/tests/workspaces.spec.ts
index 7299c49a3..3df72294d 100644
--- a/apps/builder/playwright/tests/workspaces.spec.ts
+++ b/apps/builder/playwright/tests/workspaces.spec.ts
@@ -41,7 +41,7 @@ test('can switch between workspaces and access typebot', async ({ page }) => {
await expect(page.locator('text="Hey there"')).toBeVisible()
})
-test('can create a new workspace', async ({ page }) => {
+test('can create and delete a new workspace', async ({ page }) => {
await page.goto('/typebots')
await page.click("text=Pro user's workspace")
await expect(
@@ -53,6 +53,20 @@ test('can create a new workspace', async ({ page }) => {
await expect(
page.locator('text="Pro user\'s workspace" >> nth=1')
).toBeVisible()
+ await page.click('text=Settings & Members')
+ await page.click('text="Settings"')
+ await page.click('text="Delete workspace"')
+ await expect(
+ page.locator(
+ "text=Are you sure you want to delete Pro user's workspace workspace?"
+ )
+ ).toBeVisible()
+ await page.click('text="Delete"')
+ await expect(page.locator('text=Pro typebot')).toBeVisible()
+ await page.click("text=Pro user's workspace")
+ await expect(
+ page.locator('text="Pro user\'s workspace" >> nth=1')
+ ).toBeHidden()
})
test('can update workspace info', async ({ page }) => {
diff --git a/apps/builder/services/workspace/workspace.ts b/apps/builder/services/workspace/workspace.ts
index e78ee664d..6d8964227 100644
--- a/apps/builder/services/workspace/workspace.ts
+++ b/apps/builder/services/workspace/workspace.ts
@@ -38,6 +38,14 @@ export const updateWorkspace = async (updates: Partial) =>
body: updates,
})
+export const deleteWorkspace = (workspaceId: string) =>
+ sendRequest<{
+ workspace: Workspace
+ }>({
+ url: `/api/workspaces/${workspaceId}`,
+ method: 'DELETE',
+ })
+
export const planToReadable = (plan?: Plan) => {
if (!plan) return
switch (plan) {