Skip to content

Commit

Permalink
feat(dashboard): ⚡️ Delete workspace button
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed May 17, 2022
1 parent d0119ee commit b7b0344
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,6 +27,11 @@ export const WorkspaceSettingsForm = () => {
updateWorkspace(workspace?.id, { icon })
}

const handleDeleteClick = async () => {
await deleteCurrentWorkspace()
onClose()
}

return (
<Stack spacing="6" w="full">
<FormControl>
Expand All @@ -40,6 +55,41 @@ export const WorkspaceSettingsForm = () => {
/>
)}
</FormControl>
{workspace && workspaces && workspaces.length > 1 && (
<DeleteWorkspaceButton
onConfirm={handleDeleteClick}
workspaceName={workspace?.name}
/>
)}
</Stack>
)
}

const DeleteWorkspaceButton = ({
workspaceName,
onConfirm,
}: {
workspaceName: string
onConfirm: () => Promise<void>
}) => {
const { isOpen, onOpen, onClose } = useDisclosure()
return (
<>
<Button colorScheme="red" variant="outline" onClick={onOpen}>
Delete workspace
</Button>
<ConfirmModal
isOpen={isOpen}
onConfirm={onConfirm}
onClose={onClose}
message={
<Text>
Are you sure you want to delete {workspaceName} workspace? All its
folders, typebots and results will be deleted forever.'
</Text>
}
confirmButtonLabel="Delete"
/>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,27 @@ export const WorkspaceSettingsModal = ({
</Stack>
</Stack>
<Flex flex="1" p="10">
<SettingsContent tab={selectedTab} />
<SettingsContent tab={selectedTab} onClose={onClose} />
</Flex>
</ModalContent>
</Modal>
)
}

const SettingsContent = ({ tab }: { tab: SettingsTab }) => {
const SettingsContent = ({
tab,
onClose,
}: {
tab: SettingsTab
onClose: () => void
}) => {
switch (tab) {
case 'my-account':
return <MyAccountForm />
case 'user-settings':
return <EditorSettings />
case 'workspace-settings':
return <WorkspaceSettingsForm />
return <WorkspaceSettingsForm onClose={onClose} />
case 'members':
return <MembersList />
case 'billing':
Expand Down
17 changes: 17 additions & 0 deletions apps/builder/contexts/WorkspaceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
createNewWorkspace,
useWorkspaces,
updateWorkspace as patchWorkspace,
deleteWorkspace,
} from 'services/workspace/workspace'
import { useUser } from './UserContext'
import { useTypebot } from './TypebotContext'
Expand All @@ -29,6 +30,7 @@ const workspaceContext = createContext<{
workspaceId: string,
updates: Partial<Workspace>
) => Promise<void>
deleteCurrentWorkspace: () => Promise<void>
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
Expand Down Expand Up @@ -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 (
<workspaceContext.Provider
value={{
Expand All @@ -133,6 +149,7 @@ export const WorkspaceContext = ({ children }: { children: ReactNode }) => {
switchWorkspace,
createWorkspace,
updateWorkspace,
deleteCurrentWorkspace,
}}
>
{children}
Expand Down
12 changes: 12 additions & 0 deletions apps/builder/pages/api/workspaces/[workspaceId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
16 changes: 15 additions & 1 deletion apps/builder/playwright/tests/workspaces.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 }) => {
Expand Down
8 changes: 8 additions & 0 deletions apps/builder/services/workspace/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ export const updateWorkspace = async (updates: Partial<Workspace>) =>
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) {
Expand Down

4 comments on commit b7b0344

@vercel
Copy link

@vercel vercel bot commented on b7b0344 May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on b7b0344 May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on b7b0344 May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

app.typebot.io
builder-v2-git-main-typebot-io.vercel.app
builder-v2-typebot-io.vercel.app

Please sign in to comment.