@@ -11,7 +11,6 @@ import {
|
||||
MenuItem,
|
||||
useDisclosure,
|
||||
ButtonProps,
|
||||
useColorModeValue,
|
||||
} from '@chakra-ui/react'
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
@@ -21,7 +20,6 @@ import {
|
||||
} from '@/components/icons'
|
||||
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import { InputBlockType } from '@typebot.io/schemas'
|
||||
import { useRouter } from 'next/router'
|
||||
import { isNotDefined } from '@typebot.io/lib'
|
||||
import { ChangePlanModal } from '@/features/billing/components/ChangePlanModal'
|
||||
@@ -31,6 +29,8 @@ import { useTranslate } from '@tolgee/react'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { useToast } from '@/hooks/useToast'
|
||||
import { parseDefaultPublicId } from '../helpers/parseDefaultPublicId'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { ConfirmModal } from '@/components/ConfirmModal'
|
||||
|
||||
type Props = ButtonProps & {
|
||||
isMoreMenuDisabled?: boolean
|
||||
@@ -40,10 +40,14 @@ export const PublishButton = ({
|
||||
...props
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
const warningTextColor = useColorModeValue('red.300', 'red.600')
|
||||
const { workspace } = useWorkspace()
|
||||
const { push, query, pathname } = useRouter()
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
const {
|
||||
isOpen: isNewEngineWarningOpen,
|
||||
onOpen: onNewEngineWarningOpen,
|
||||
onClose: onNewEngineWarningClose,
|
||||
} = useDisclosure()
|
||||
const {
|
||||
isPublished,
|
||||
publishedTypebot,
|
||||
@@ -52,6 +56,7 @@ export const PublishButton = ({
|
||||
isSavingLoading,
|
||||
updateTypebot,
|
||||
save,
|
||||
publishedTypebotVersion,
|
||||
} = useTypebot()
|
||||
const { showToast } = useToast()
|
||||
|
||||
@@ -133,18 +138,33 @@ export const PublishButton = ({
|
||||
onClose={onClose}
|
||||
type={t('billing.limitMessage.fileInput')}
|
||||
/>
|
||||
{publishedTypebotVersion !== typebot?.version && (
|
||||
<ConfirmModal
|
||||
isOpen={isNewEngineWarningOpen}
|
||||
onConfirm={handlePublishClick}
|
||||
onClose={onNewEngineWarningClose}
|
||||
confirmButtonColor="blue"
|
||||
title="⚠️ New engine version"
|
||||
message={
|
||||
<Stack>
|
||||
<Text>
|
||||
You are about to a deploy a version of your bot with an updated
|
||||
engine.
|
||||
</Text>
|
||||
<Text fontWeight="bold">
|
||||
Make sure to test it thoroughly in preview mode before
|
||||
publishing.
|
||||
</Text>
|
||||
</Stack>
|
||||
}
|
||||
confirmButtonLabel={'Publish'}
|
||||
/>
|
||||
)}
|
||||
<Tooltip
|
||||
placement="bottom-end"
|
||||
label={
|
||||
<Stack>
|
||||
{!publishedTypebot?.version ? (
|
||||
<Text color={warningTextColor} fontWeight="semibold">
|
||||
This will deploy your bot with an updated engine. Make sure to
|
||||
test it properly in preview mode before publishing.
|
||||
</Text>
|
||||
) : (
|
||||
<Text>There are non published changes.</Text>
|
||||
)}
|
||||
<Text>There are non published changes.</Text>
|
||||
<Text fontStyle="italic">
|
||||
Published version from{' '}
|
||||
{publishedTypebot &&
|
||||
@@ -159,7 +179,11 @@ export const PublishButton = ({
|
||||
colorScheme="blue"
|
||||
isLoading={isPublishing || isUnpublishing}
|
||||
isDisabled={isPublished || isSavingLoading}
|
||||
onClick={handlePublishClick}
|
||||
onClick={() => {
|
||||
publishedTypebot && publishedTypebotVersion !== typebot?.version
|
||||
? onNewEngineWarningOpen()
|
||||
: handlePublishClick()
|
||||
}}
|
||||
borderRightRadius={
|
||||
publishedTypebot && !isMoreMenuDisabled ? 0 : undefined
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const GtmBubbleInstructions = () => {
|
||||
theme={theme}
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
onThemeChange={setTheme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -23,7 +23,7 @@ ${parseInitBubbleCode({
|
||||
theme: {
|
||||
...theme,
|
||||
chatWindow: {
|
||||
backgroundColor: typebot?.theme.general.background.content ?? '#fff',
|
||||
backgroundColor: typebot?.theme.general?.background?.content ?? '#fff',
|
||||
},
|
||||
},
|
||||
previewMessage,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { JavascriptBubbleSnippet } from '../JavascriptBubbleSnippet'
|
||||
|
||||
export const parseDefaultBubbleTheme = (typebot?: Typebot) => ({
|
||||
button: {
|
||||
backgroundColor: typebot?.theme.chat.buttons.backgroundColor,
|
||||
backgroundColor: typebot?.theme.chat?.buttons?.backgroundColor,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -25,7 +25,7 @@ export const JavascriptBubbleInstructions = () => {
|
||||
<BubbleSettings
|
||||
theme={theme}
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={typebot?.theme.chat.hostAvatar?.url ?? ''}
|
||||
defaultPreviewMessageAvatar={typebot?.theme.chat?.hostAvatar?.url ?? ''}
|
||||
onThemeChange={setTheme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
/>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CodeEditor } from '@/components/inputs/CodeEditor'
|
||||
export const InstallNextjsPackageSnippet = () => {
|
||||
return (
|
||||
<CodeEditor
|
||||
value={`npm install @typebot.io/nextjs`}
|
||||
value={`npm install @typebot.io/js @typebot.io/nextjs`}
|
||||
isReadOnly
|
||||
lang="shell"
|
||||
/>
|
||||
|
||||
@@ -29,7 +29,7 @@ export const NextjsBubbleInstructions = () => {
|
||||
theme={theme}
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
onThemeChange={setTheme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CodeEditor } from '@/components/inputs/CodeEditor'
|
||||
export const InstallReactPackageSnippet = () => {
|
||||
return (
|
||||
<CodeEditor
|
||||
value={`npm install @typebot.io/react`}
|
||||
value={`npm install @typebot.io/js @typebot.io/react`}
|
||||
isReadOnly
|
||||
lang="shell"
|
||||
/>
|
||||
|
||||
@@ -29,7 +29,7 @@ export const ReactBubbleInstructions = () => {
|
||||
theme={theme}
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
onThemeChange={setTheme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -14,12 +14,11 @@ import {
|
||||
|
||||
export const parseDefaultBubbleTheme = (typebot?: Typebot) => ({
|
||||
button: {
|
||||
backgroundColor: typebot?.theme.chat.buttons.backgroundColor,
|
||||
iconColor: typebot?.theme.chat.buttons.color,
|
||||
backgroundColor: typebot?.theme.chat?.buttons?.backgroundColor,
|
||||
iconColor: typebot?.theme.chat?.buttons?.color,
|
||||
},
|
||||
previewMessage: {
|
||||
backgroundColor: typebot?.theme.general.background.content ?? 'white',
|
||||
textColor: 'black',
|
||||
backgroundColor: typebot?.theme.general?.background?.content,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -47,7 +46,7 @@ ${parseInitBubbleCode({
|
||||
<BubbleSettings
|
||||
theme={theme}
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={typebot?.theme.chat.hostAvatar?.url ?? ''}
|
||||
defaultPreviewMessageAvatar={typebot?.theme.chat?.hostAvatar?.url ?? ''}
|
||||
onThemeChange={setTheme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
/>
|
||||
|
||||
@@ -26,7 +26,7 @@ export const ShopifyBubbleInstructions = () => {
|
||||
<BubbleSettings
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
theme={theme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const WebflowBubbleInstructions = () => {
|
||||
<BubbleSettings
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
theme={theme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { HStack, Text } from '@chakra-ui/react'
|
||||
import { DropdownList } from '@/components/DropdownList'
|
||||
import { ComparisonOperators } from '@typebot.io/schemas'
|
||||
import { TableListItemProps } from '@/components/TableList'
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { WhatsAppComparison } from '@typebot.io/schemas/features/whatsapp'
|
||||
import { ComparisonOperators } from '@typebot.io/schemas/features/blocks/logic/condition/constants'
|
||||
|
||||
export const WhatsAppComparisonItem = ({
|
||||
item,
|
||||
|
||||
@@ -31,7 +31,7 @@ import { useParentModal } from '@/features/graph/providers/ParentModalProvider'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||
import { TableList } from '@/components/TableList'
|
||||
import { Comparison, LogicalOperator } from '@typebot.io/schemas'
|
||||
import { Comparison } from '@typebot.io/schemas'
|
||||
import { DropdownList } from '@/components/DropdownList'
|
||||
import { WhatsAppComparisonItem } from './WhatsAppComparisonItem'
|
||||
import { AlertInfo } from '@/components/AlertInfo'
|
||||
@@ -42,6 +42,7 @@ import { isDefined } from '@typebot.io/lib/utils'
|
||||
import { hasProPerks } from '@/features/billing/helpers/hasProPerks'
|
||||
import { UnlockPlanAlertInfo } from '@/components/UnlockPlanAlertInfo'
|
||||
import { PlanTag } from '@/features/billing/components/PlanTag'
|
||||
import { LogicalOperator } from '@typebot.io/schemas/features/blocks/logic/condition/constants'
|
||||
|
||||
export const WhatsAppModal = ({ isOpen, onClose }: ModalProps): JSX.Element => {
|
||||
const { typebot, updateTypebot, isPublished } = useTypebot()
|
||||
|
||||
@@ -31,7 +31,7 @@ export const WixBubbleInstructions = () => {
|
||||
<BubbleSettings
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
theme={theme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -33,7 +33,7 @@ export const WordpressBubbleInstructions = ({ publicId }: Props) => {
|
||||
theme: {
|
||||
...theme,
|
||||
chatWindow: {
|
||||
backgroundColor: typebot?.theme.general.background.content ?? '#fff',
|
||||
backgroundColor: typebot?.theme.general?.background?.content ?? '#fff',
|
||||
},
|
||||
},
|
||||
previewMessage,
|
||||
@@ -57,7 +57,7 @@ export const WordpressBubbleInstructions = ({ publicId }: Props) => {
|
||||
<BubbleSettings
|
||||
previewMessage={previewMessage}
|
||||
defaultPreviewMessageAvatar={
|
||||
typebot?.theme.chat.hostAvatar?.url ?? ''
|
||||
typebot?.theme.chat?.hostAvatar?.url ?? ''
|
||||
}
|
||||
theme={theme}
|
||||
onPreviewMessageChange={setPreviewMessage}
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
import { PublicTypebot, Typebot } from '@typebot.io/schemas'
|
||||
import { PublicTypebot, TypebotV6 } from '@typebot.io/schemas'
|
||||
|
||||
export const convertPublicTypebotToTypebot = (
|
||||
typebot: PublicTypebot,
|
||||
existingTypebot: Typebot
|
||||
): Typebot => ({
|
||||
id: typebot.typebotId,
|
||||
version: typebot.version,
|
||||
groups: typebot.groups,
|
||||
edges: typebot.edges,
|
||||
name: existingTypebot.name,
|
||||
publicId: existingTypebot.publicId,
|
||||
settings: typebot.settings,
|
||||
theme: typebot.theme,
|
||||
variables: typebot.variables,
|
||||
customDomain: existingTypebot.customDomain,
|
||||
createdAt: existingTypebot.createdAt,
|
||||
updatedAt: existingTypebot.updatedAt,
|
||||
folderId: existingTypebot.folderId,
|
||||
icon: existingTypebot.icon,
|
||||
workspaceId: existingTypebot.workspaceId,
|
||||
isArchived: existingTypebot.isArchived,
|
||||
isClosed: existingTypebot.isClosed,
|
||||
resultsTablePreferences: existingTypebot.resultsTablePreferences,
|
||||
selectedThemeTemplateId: existingTypebot.selectedThemeTemplateId,
|
||||
whatsAppCredentialsId: existingTypebot.whatsAppCredentialsId,
|
||||
})
|
||||
existingTypebot: TypebotV6
|
||||
): TypebotV6 => {
|
||||
if (typebot.version !== '6') return existingTypebot
|
||||
return {
|
||||
id: typebot.typebotId,
|
||||
version: typebot.version,
|
||||
groups: typebot.groups,
|
||||
edges: typebot.edges,
|
||||
name: existingTypebot.name,
|
||||
publicId: existingTypebot.publicId,
|
||||
settings: typebot.settings,
|
||||
theme: typebot.theme,
|
||||
variables: typebot.variables,
|
||||
customDomain: existingTypebot.customDomain,
|
||||
createdAt: existingTypebot.createdAt,
|
||||
updatedAt: existingTypebot.updatedAt,
|
||||
folderId: existingTypebot.folderId,
|
||||
icon: existingTypebot.icon,
|
||||
workspaceId: existingTypebot.workspaceId,
|
||||
isArchived: existingTypebot.isArchived,
|
||||
isClosed: existingTypebot.isClosed,
|
||||
resultsTablePreferences: existingTypebot.resultsTablePreferences,
|
||||
selectedThemeTemplateId: existingTypebot.selectedThemeTemplateId,
|
||||
whatsAppCredentialsId: existingTypebot.whatsAppCredentialsId,
|
||||
events: existingTypebot.events,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { PublicTypebot, Typebot } from '@typebot.io/schemas'
|
||||
import { PublicTypebot, TypebotV6 } from '@typebot.io/schemas'
|
||||
|
||||
export const convertTypebotToPublicTypebot = (
|
||||
typebot: Typebot
|
||||
typebot: TypebotV6
|
||||
): PublicTypebot => ({
|
||||
id: createId(),
|
||||
version: typebot.version,
|
||||
typebotId: typebot.id,
|
||||
groups: typebot.groups,
|
||||
events: typebot.events,
|
||||
edges: typebot.edges,
|
||||
settings: typebot.settings,
|
||||
theme: typebot.theme,
|
||||
|
||||
@@ -9,6 +9,7 @@ export const isPublished = (
|
||||
) => {
|
||||
if (debug)
|
||||
console.log(
|
||||
'diff:',
|
||||
diff(
|
||||
JSON.parse(JSON.stringify(typebot.groups)),
|
||||
JSON.parse(JSON.stringify(publicTypebot.groups))
|
||||
@@ -30,6 +31,10 @@ export const isPublished = (
|
||||
dequal(
|
||||
JSON.parse(JSON.stringify(typebot.variables)),
|
||||
JSON.parse(JSON.stringify(publicTypebot.variables))
|
||||
) &&
|
||||
dequal(
|
||||
JSON.parse(JSON.stringify(typebot.events)),
|
||||
JSON.parse(JSON.stringify(publicTypebot.events))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { defaultTextInputOptions, InputBlockType } from '@typebot.io/schemas'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
|
||||
test('should not be able to submit taken url ID', async ({ page }) => {
|
||||
const takenTypebotId = createId()
|
||||
@@ -12,7 +12,6 @@ test('should not be able to submit taken url ID', async ({ page }) => {
|
||||
id: takenTypebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: InputBlockType.TEXT,
|
||||
options: defaultTextInputOptions,
|
||||
}),
|
||||
publicId: 'taken-url-id',
|
||||
},
|
||||
@@ -22,7 +21,6 @@ test('should not be able to submit taken url ID', async ({ page }) => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: InputBlockType.TEXT,
|
||||
options: defaultTextInputOptions,
|
||||
}),
|
||||
publicId: typebotId + '-public',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user