Skip to content

Commit

Permalink
🚸 (dashboard) Add unpublish menu item in dashboard
Browse files Browse the repository at this point in the history
Also remove the useless publishedTypebotId field in Typebot

Closes baptisteArno#232
  • Loading branch information
baptisteArno authored and jmgoncalves97 committed Jan 17, 2025
1 parent 7069f3d commit be00e74
Show file tree
Hide file tree
Showing 59 changed files with 212 additions and 90 deletions.
1 change: 0 additions & 1 deletion apps/builder/public/bots/onboarding-dark.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"createdAt": "2022-03-22T14:33:05.037Z",
"updatedAt": "2022-03-22T16:33:37.928Z",
"name": "Onboarding",
"publishedTypebotId": "cl128n64i00092e69wenv1dlx",
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/bots/onboarding.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"createdAt": "2022-03-22T14:33:05.037Z",
"updatedAt": "2022-03-22T16:33:37.928Z",
"name": "Onboarding",
"publishedTypebotId": "cl128n64i00092e69wenv1dlx",
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/customer-support.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-03-25T15:42:12.544Z",
"name": "Customer Support",
"icon": "😍",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/digital-product-payment.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-05-31T12:31:12.867Z",
"icon": "🖼️",
"name": "Digital Product Payment",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/faq.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-10-13T06:27:31.951Z",
"icon": "💬",
"name": "FAQ",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/lead-gen.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-02-05T06:21:16.522Z",
"name": "Lead Generation",
"icon": "🤝",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/lead-scoring.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-04-09T22:35:22.449Z",
"icon": "🏆",
"name": "Lead Scoring",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/public/templates/quiz.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-04-08T23:03:34.726Z",
"icon": "🕹️",
"name": "Digital Marketing Quiz",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
1 change: 0 additions & 1 deletion apps/builder/src/features/dashboard/api/parseNewTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export type NewTypebotProps = Omit<
| 'createdAt'
| 'updatedAt'
| 'id'
| 'publishedTypebotId'
| 'publicId'
| 'customDomain'
| 'icon'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const duplicateTypebot = (
...typebot,
id,
name: `${typebot.name} copy`,
publishedTypebotId: null,
publicId: null,
customDomain: null,
groups: typebot.groups.map((b) => ({
Expand Down
7 changes: 3 additions & 4 deletions apps/builder/src/features/dashboard/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Typebot } from 'models'

export type TypebotInDashboard = Pick<
Typebot,
'id' | 'name' | 'publishedTypebotId' | 'icon'
>
export type TypebotInDashboard = Pick<Typebot, 'id' | 'name' | 'icon'> & {
publishedTypebotId?: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { RightPanel, useEditor } from '../../providers/EditorProvider'
import { useTypebot } from '../../providers/TypebotProvider'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { isNotDefined } from 'utils'
import { isDefined, isNotDefined } from 'utils'
import { EditableTypebotName } from './EditableTypebotName'
import { getBubbleActions } from 'typebot-js'
import Link from 'next/link'
Expand All @@ -34,6 +34,7 @@ export const TypebotHeader = () => {
const router = useRouter()
const {
typebot,
publishedTypebot,
updateTypebot,
save,
undo,
Expand Down Expand Up @@ -126,7 +127,7 @@ export const TypebotHeader = () => {
>
Share
</Button>
{typebot?.publishedTypebotId && (
{isDefined(publishedTypebot) && (
<Button
as={Link}
href={`/typebots/${typebot?.id}/results`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import {
useMemo,
useState,
} from 'react'
import { isDefined, isNotDefined, omit } from 'utils'
import { isDefined, omit } from 'utils'
import { edgesAction, EdgesActions } from './actions/edges'
import { itemsAction, ItemsActions } from './actions/items'
import { GroupsActions, groupsActions } from './actions/groups'
import { blocksAction, BlocksActions } from './actions/blocks'
import { variablesAction, VariablesActions } from './actions/variables'
import { dequal } from 'dequal'
import cuid from 'cuid'
import { useToast } from '@/hooks/useToast'
import { useTypebotQuery } from '@/hooks/useTypebotQuery'
import useUndo from '../../hooks/useUndo'
Expand Down Expand Up @@ -52,7 +51,6 @@ type UpdateTypebotPayload = Partial<{
settings: Settings
publicId: string
name: string
publishedTypebotId: string
icon: string
customDomain: string
resultsTablePreferences: ResultsTablePreferences
Expand Down Expand Up @@ -254,17 +252,12 @@ export const TypebotProvider = ({

const publishTypebot = async () => {
if (!localTypebot) return
const publishedTypebotId = cuid()
const newLocalTypebot = { ...localTypebot }
if (publishedTypebot && isNotDefined(localTypebot.publishedTypebotId)) {
updateLocalTypebot({ publishedTypebotId: publishedTypebot.id })
await saveTypebot()
}
if (!publishedTypebot) {
const newPublicId =
localTypebot.publicId ??
parseDefaultPublicId(localTypebot.name, localTypebot.id)
updateLocalTypebot({ publicId: newPublicId, publishedTypebotId })
updateLocalTypebot({ publicId: newPublicId })
newLocalTypebot.publicId = newPublicId
await saveTypebot()
}
Expand All @@ -277,8 +270,7 @@ export const TypebotProvider = ({
setIsPublishing(true)
const { data, error } = await createPublishedTypebotQuery(
{
...parseTypebotToPublicTypebot(newLocalTypebot),
id: publishedTypebotId,
...omit(parseTypebotToPublicTypebot(newLocalTypebot), 'id'),
},
localTypebot.workspaceId
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const FolderContent = ({ folder }: Props) => {
if (newFolder) mutateFolders({ folders: [...folders, newFolder] })
}

const handleTypebotDeleted = () => {
const handleTypebotUpdated = () => {
if (!typebots) return
refetchTypebots()
}
Expand Down Expand Up @@ -208,7 +208,7 @@ export const FolderContent = ({ folder }: Props) => {
<TypebotButton
key={typebot.id.toString()}
typebot={typebot}
onTypebotDeleted={handleTypebotDeleted}
onTypebotUpdated={handleTypebotUpdated}
onMouseDown={handleMouseDown(typebot)}
/>
))}
Expand Down
29 changes: 22 additions & 7 deletions apps/builder/src/features/folders/components/TypebotButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
import { useRouter } from 'next/router'
import { ConfirmModal } from '@/components/ConfirmModal'
import { GripIcon } from '@/components/icons'
import { Typebot } from 'models'
import { useTypebotDnd } from '../TypebotDndProvider'
import { useDebounce } from 'use-debounce'
import { Plan } from 'db'
Expand All @@ -24,23 +23,25 @@ import {
getTypebotQuery,
deleteTypebotQuery,
importTypebotQuery,
TypebotInDashboard,
} from '@/features/dashboard'
import { MoreButton } from './MoreButton'
import { EmojiOrImageIcon } from '@/components/EmojiOrImageIcon'
import { deletePublishedTypebotQuery } from '@/features/publish/queries/deletePublishedTypebotQuery'

type ChatbotCardProps = {
typebot: Pick<Typebot, 'id' | 'publishedTypebotId' | 'name' | 'icon'>
type Props = {
typebot: TypebotInDashboard
isReadOnly?: boolean
onTypebotDeleted?: () => void
onTypebotUpdated: () => void
onMouseDown?: (e: React.MouseEvent<HTMLButtonElement>) => void
}

export const TypebotButton = ({
typebot,
onTypebotDeleted,
isReadOnly = false,
onTypebotUpdated,
onMouseDown,
}: ChatbotCardProps) => {
}: Props) => {
const router = useRouter()
const { workspace } = useWorkspace()
const { draggedTypebot } = useTypebotDnd()
Expand Down Expand Up @@ -70,7 +71,7 @@ export const TypebotButton = ({
title: "Couldn't delete typebot",
description: error.message,
})
if (onTypebotDeleted) onTypebotDeleted()
onTypebotUpdated()
}

const handleDuplicateClick = async (e: React.MouseEvent) => {
Expand All @@ -95,6 +96,17 @@ export const TypebotButton = ({
onDeleteOpen()
}

const handleUnpublishClick = async (e: React.MouseEvent) => {
e.stopPropagation()
if (!typebot.publishedTypebotId) return
const { error } = await deletePublishedTypebotQuery({
publishedTypebotId: typebot.publishedTypebotId,
typebotId: typebot.id,
})
if (error) showToast({ description: error.message })
else onTypebotUpdated()
}

return (
<Button
as={WrapItem}
Expand Down Expand Up @@ -143,6 +155,9 @@ export const TypebotButton = ({
right="20px"
aria-label={`Show ${typebot.name} menu`}
>
{typebot.publishedTypebotId && (
<MenuItem onClick={handleUnpublishClick}>Unpublish</MenuItem>
)}
<MenuItem onClick={handleDuplicateClick}>Duplicate</MenuItem>
<MenuItem color="red" onClick={handleDeleteClick}>
Delete
Expand Down
4 changes: 2 additions & 2 deletions apps/builder/src/features/publish/components/SharePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { integrationsList } from './embeds/EmbedButton'

export const SharePage = () => {
const { workspace } = useWorkspace()
const { typebot, updateTypebot } = useTypebot()
const { typebot, updateTypebot, publishedTypebot } = useTypebot()
const { showToast } = useToast()

const handlePublicIdChange = async (publicId: string) => {
Expand All @@ -39,7 +39,7 @@ export const SharePage = () => {
const publicId = typebot
? typebot?.publicId ?? parseDefaultPublicId(typebot.name, typebot.id)
: ''
const isPublished = isDefined(typebot?.publishedTypebotId)
const isPublished = isDefined(publishedTypebot)

const handlePathnameChange = (pathname: string) => {
if (!typebot?.customDomain) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PublicTypebot } from 'models'
import { sendRequest } from 'utils'

export const createPublishedTypebotQuery = async (
typebot: PublicTypebot,
typebot: Omit<PublicTypebot, 'id'>,
workspaceId: string
) =>
sendRequest<PublicTypebot>({
Expand Down
1 change: 0 additions & 1 deletion apps/builder/src/features/publish/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const parsePublicTypebotToTypebot = (
customDomain: existingTypebot.customDomain,
createdAt: existingTypebot.createdAt,
updatedAt: existingTypebot.updatedAt,
publishedTypebotId: typebot.id,
folderId: existingTypebot.folderId,
icon: existingTypebot.icon,
workspaceId: existingTypebot.workspaceId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { WorkspaceRole } from 'db'
import { Typebot, typebotSchema } from 'models'
import { PublicTypebot, Typebot, typebotSchema } from 'models'
import { omit } from 'utils'
import { z } from 'zod'

export const listTypebotsProcedure = authenticatedProcedure
Expand All @@ -19,12 +20,13 @@ export const listTypebotsProcedure = authenticatedProcedure
.output(
z.object({
typebots: z.array(
typebotSchema.pick({
name: true,
icon: true,
id: true,
publishedTypebotId: true,
})
typebotSchema
.pick({
name: true,
icon: true,
id: true,
})
.and(z.object({ publishedTypebotId: z.string().optional() }))
),
})
)
Expand Down Expand Up @@ -58,11 +60,23 @@ export const listTypebotsProcedure = authenticatedProcedure
],
},
orderBy: { createdAt: 'desc' },
select: { name: true, publishedTypebotId: true, id: true, icon: true },
})) as Pick<Typebot, 'name' | 'id' | 'icon' | 'publishedTypebotId'>[]
select: {
name: true,
publishedTypebot: { select: { id: true } },
id: true,
icon: true,
},
})) as (Pick<Typebot, 'name' | 'id' | 'icon'> & {
publishedTypebot: Pick<PublicTypebot, 'id'>
})[]

if (!typebots)
throw new TRPCError({ code: 'NOT_FOUND', message: 'No typebots found' })

return { typebots }
return {
typebots: typebots.map((typebot) => ({
publishedTypebotId: typebot.publishedTypebot?.id,
...omit(typebot, 'publishedTypebot'),
})),
}
})
2 changes: 1 addition & 1 deletion apps/builder/src/features/workspace/workspaces.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ test('can update workspace info', async ({ page }) => {
await page.fill('input[value="Pro workspace"]', 'My awesome workspace')
await page.getByTestId('typebot-logo').click({ force: true })
await expect(
page.getByRole('button', { name: '🏦 My awesome workspace Pro' })
page.getByRole('button', { name: 'My awesome workspace Pro' })
).toBeVisible()
})

Expand Down
2 changes: 1 addition & 1 deletion apps/builder/src/pages/api/publicTypebots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (!workspaceId) return badRequest(res, 'workspaceId is required')
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as PublicTypebot
) as Omit<PublicTypebot, 'id'>
const typebotContainsFileInput = data.groups
.flatMap((g) => g.blocks)
.some((b) => b.type === InputBlockType.FILE)
Expand Down
2 changes: 1 addition & 1 deletion apps/builder/src/pages/api/typebots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
],
},
orderBy: { createdAt: 'desc' },
select: { name: true, publishedTypebotId: true, id: true, icon: true },
select: { name: true, id: true, icon: true },
})
return res.send({ typebots })
}
Expand Down
1 change: 0 additions & 1 deletion apps/builder/src/test/assets/typebots/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"createdAt": "2022-02-05T06:21:16.522Z",
"updatedAt": "2022-02-05T06:21:16.522Z",
"name": "My typebot",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"updatedAt": "2022-12-23T09:04:36.750Z",
"icon": null,
"name": "My typebot copy",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
Expand Down
Loading

0 comments on commit be00e74

Please sign in to comment.