feat(editor): ✨ Add a Help button
This commit is contained in:
@@ -463,3 +463,14 @@ export const StarIcon = (props: IconProps) => (
|
|||||||
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
|
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
|
||||||
</Icon>
|
</Icon>
|
||||||
)
|
)
|
||||||
|
export const BuoyIcon = (props: IconProps) => (
|
||||||
|
<Icon viewBox="0 0 24 24" {...featherIconsBaseProps} {...props}>
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<circle cx="12" cy="12" r="4"></circle>
|
||||||
|
<line x1="4.93" y1="4.93" x2="9.17" y2="9.17"></line>
|
||||||
|
<line x1="14.83" y1="14.83" x2="19.07" y2="19.07"></line>
|
||||||
|
<line x1="14.83" y1="9.17" x2="19.07" y2="4.93"></line>
|
||||||
|
<line x1="14.83" y1="9.17" x2="18.36" y2="5.64"></line>
|
||||||
|
<line x1="4.93" y1="19.07" x2="9.17" y2="14.83"></line>
|
||||||
|
</Icon>
|
||||||
|
)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import React, { useEffect, useState } from 'react'
|
|||||||
import { isCloudProdInstance } from 'services/utils'
|
import { isCloudProdInstance } from 'services/utils'
|
||||||
import { planToReadable } from 'services/workspace'
|
import { planToReadable } from 'services/workspace'
|
||||||
import { initBubble } from 'typebot-js'
|
import { initBubble } from 'typebot-js'
|
||||||
import { isEmpty } from 'utils'
|
|
||||||
|
|
||||||
export const SupportBubble = () => {
|
export const SupportBubble = () => {
|
||||||
const { typebot } = useTypebot()
|
const { typebot } = useTypebot()
|
||||||
@@ -22,11 +21,7 @@ export const SupportBubble = () => {
|
|||||||
setLocalTypebotId(typebot?.id)
|
setLocalTypebotId(typebot?.id)
|
||||||
setLocalUserId(user?.id)
|
setLocalUserId(user?.id)
|
||||||
initBubble({
|
initBubble({
|
||||||
url: `${
|
url: `https://viewer.typebot.io/typebot-support`,
|
||||||
isEmpty(process.env.NEXT_PUBLIC_VIEWER_INTERNAL_URL)
|
|
||||||
? process.env.NEXT_PUBLIC_VIEWER_URL
|
|
||||||
: process.env.NEXT_PUBLIC_VIEWER_INTERNAL_URL
|
|
||||||
}/typebot-support`,
|
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#ffffff',
|
||||||
button: {
|
button: {
|
||||||
color: '#0042DA',
|
color: '#0042DA',
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export const CollaborationMenuButton = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
icon={<UsersIcon />}
|
icon={<UsersIcon />}
|
||||||
aria-label="Show collaboration menu"
|
aria-label="Show collaboration menu"
|
||||||
|
size="sm"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -18,14 +18,15 @@ export const EditableTypebotName = ({ name, onNewName }: EditableProps) => {
|
|||||||
<Tooltip label="Rename">
|
<Tooltip label="Rename">
|
||||||
<Editable value={localName} onChange={setLocalName} onSubmit={onNewName}>
|
<Editable value={localName} onChange={setLocalName} onSubmit={onNewName}>
|
||||||
<EditablePreview
|
<EditablePreview
|
||||||
noOfLines={1}
|
noOfLines={2}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
maxW="200px"
|
maxW="150px"
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
display="flex"
|
display="flex"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
|
fontSize="14px"
|
||||||
/>
|
/>
|
||||||
<EditableInput />
|
<EditableInput fontSize="14px" />
|
||||||
</Editable>
|
</Editable>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
Spinner,
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { ChevronLeftIcon, RedoIcon, UndoIcon } from 'assets/icons'
|
import { BuoyIcon, ChevronLeftIcon, RedoIcon, UndoIcon } from 'assets/icons'
|
||||||
import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
||||||
import { RightPanel, useEditor } from 'contexts/EditorContext'
|
import { RightPanel, useEditor } from 'contexts/EditorContext'
|
||||||
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
||||||
@@ -18,6 +18,8 @@ import { PublishButton } from '../buttons/PublishButton'
|
|||||||
import { EditableEmojiOrImageIcon } from '../EditableEmojiOrImageIcon'
|
import { EditableEmojiOrImageIcon } from '../EditableEmojiOrImageIcon'
|
||||||
import { CollaborationMenuButton } from './CollaborationMenuButton'
|
import { CollaborationMenuButton } from './CollaborationMenuButton'
|
||||||
import { EditableTypebotName } from './EditableTypebotName'
|
import { EditableTypebotName } from './EditableTypebotName'
|
||||||
|
import { getBubbleActions } from 'typebot-js'
|
||||||
|
import { isCloudProdInstance } from 'services/utils'
|
||||||
|
|
||||||
export const headerHeight = 56
|
export const headerHeight = 56
|
||||||
|
|
||||||
@@ -45,24 +47,34 @@ export const TypebotHeader = () => {
|
|||||||
setRightPanel(RightPanel.PREVIEW)
|
setRightPanel(RightPanel.PREVIEW)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleHelpClick = () => {
|
||||||
|
isCloudProdInstance()
|
||||||
|
? getBubbleActions().open()
|
||||||
|
: window.open('https://docs.typebot.io', '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
w="full"
|
w="full"
|
||||||
borderBottomWidth="1px"
|
borderBottomWidth="1px"
|
||||||
justify="center"
|
justify="center"
|
||||||
align="center"
|
align="center"
|
||||||
pos="relative"
|
|
||||||
h={`${headerHeight}px`}
|
h={`${headerHeight}px`}
|
||||||
zIndex={100}
|
zIndex={100}
|
||||||
bgColor="white"
|
bgColor="white"
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
>
|
>
|
||||||
<HStack display={['none', 'flex']}>
|
<HStack
|
||||||
|
display={['none', 'flex']}
|
||||||
|
pos={{ base: 'absolute', xl: 'relative' }}
|
||||||
|
right={{ base: 280, xl: 0 }}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
as={NextChakraLink}
|
as={NextChakraLink}
|
||||||
href={`/typebots/${typebot?.id}/edit`}
|
href={`/typebots/${typebot?.id}/edit`}
|
||||||
colorScheme={router.pathname.includes('/edit') ? 'blue' : 'gray'}
|
colorScheme={router.pathname.includes('/edit') ? 'blue' : 'gray'}
|
||||||
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
|
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Flow
|
Flow
|
||||||
</Button>
|
</Button>
|
||||||
@@ -71,6 +83,7 @@ export const TypebotHeader = () => {
|
|||||||
href={`/typebots/${typebot?.id}/theme`}
|
href={`/typebots/${typebot?.id}/theme`}
|
||||||
colorScheme={router.pathname.endsWith('theme') ? 'blue' : 'gray'}
|
colorScheme={router.pathname.endsWith('theme') ? 'blue' : 'gray'}
|
||||||
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Theme
|
Theme
|
||||||
</Button>
|
</Button>
|
||||||
@@ -79,6 +92,7 @@ export const TypebotHeader = () => {
|
|||||||
href={`/typebots/${typebot?.id}/settings`}
|
href={`/typebots/${typebot?.id}/settings`}
|
||||||
colorScheme={router.pathname.endsWith('settings') ? 'blue' : 'gray'}
|
colorScheme={router.pathname.endsWith('settings') ? 'blue' : 'gray'}
|
||||||
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
</Button>
|
</Button>
|
||||||
@@ -87,6 +101,7 @@ export const TypebotHeader = () => {
|
|||||||
href={`/typebots/${typebot?.id}/share`}
|
href={`/typebots/${typebot?.id}/share`}
|
||||||
colorScheme={router.pathname.endsWith('share') ? 'blue' : 'gray'}
|
colorScheme={router.pathname.endsWith('share') ? 'blue' : 'gray'}
|
||||||
variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Share
|
Share
|
||||||
</Button>
|
</Button>
|
||||||
@@ -96,6 +111,7 @@ export const TypebotHeader = () => {
|
|||||||
href={`/typebots/${typebot?.id}/results`}
|
href={`/typebots/${typebot?.id}/results`}
|
||||||
colorScheme={router.pathname.includes('results') ? 'blue' : 'gray'}
|
colorScheme={router.pathname.includes('results') ? 'blue' : 'gray'}
|
||||||
variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
|
variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Results
|
Results
|
||||||
</Button>
|
</Button>
|
||||||
@@ -108,11 +124,11 @@ export const TypebotHeader = () => {
|
|||||||
align="center"
|
align="center"
|
||||||
spacing="6"
|
spacing="6"
|
||||||
>
|
>
|
||||||
<HStack alignItems="center" spacing={4}>
|
<HStack alignItems="center" spacing={3}>
|
||||||
<IconButton
|
<IconButton
|
||||||
as={NextChakraLink}
|
as={NextChakraLink}
|
||||||
aria-label="Navigate back"
|
aria-label="Navigate back"
|
||||||
icon={<ChevronLeftIcon fontSize={30} />}
|
icon={<ChevronLeftIcon fontSize={25} />}
|
||||||
href={
|
href={
|
||||||
router.query.parentId
|
router.query.parentId
|
||||||
? `/typebots/${router.query.parentId}/edit`
|
? `/typebots/${router.query.parentId}/edit`
|
||||||
@@ -120,6 +136,7 @@ export const TypebotHeader = () => {
|
|||||||
? `/typebots/folders/${typebot.folderId}`
|
? `/typebots/folders/${typebot.folderId}`
|
||||||
: '/typebots'
|
: '/typebots'
|
||||||
}
|
}
|
||||||
|
size="sm"
|
||||||
/>
|
/>
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<EditableEmojiOrImageIcon
|
<EditableEmojiOrImageIcon
|
||||||
@@ -157,6 +174,9 @@ export const TypebotHeader = () => {
|
|||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
<Button leftIcon={<BuoyIcon />} onClick={handleHelpClick} size="sm">
|
||||||
|
Help
|
||||||
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
{isSavingLoading && (
|
{isSavingLoading && (
|
||||||
<HStack>
|
<HStack>
|
||||||
@@ -174,11 +194,12 @@ export const TypebotHeader = () => {
|
|||||||
<Button
|
<Button
|
||||||
onClick={handlePreviewClick}
|
onClick={handlePreviewClick}
|
||||||
isLoading={isNotDefined(typebot)}
|
isLoading={isNotDefined(typebot)}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Preview
|
Preview
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<PublishButton />
|
<PublishButton size="sm" />
|
||||||
</HStack>
|
</HStack>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
MenuList,
|
MenuList,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
|
ButtonProps,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { ChevronLeftIcon } from 'assets/icons'
|
import { ChevronLeftIcon } from 'assets/icons'
|
||||||
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
||||||
@@ -23,7 +24,7 @@ import { isNotDefined } from 'utils'
|
|||||||
import { UpgradeModal } from '../modals/UpgradeModal'
|
import { UpgradeModal } from '../modals/UpgradeModal'
|
||||||
import { LimitReached } from '../modals/UpgradeModal/UpgradeModal'
|
import { LimitReached } from '../modals/UpgradeModal/UpgradeModal'
|
||||||
|
|
||||||
export const PublishButton = () => {
|
export const PublishButton = (props: ButtonProps) => {
|
||||||
const { workspace } = useWorkspace()
|
const { workspace } = useWorkspace()
|
||||||
const { push, query } = useRouter()
|
const { push, query } = useRouter()
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||||
@@ -78,6 +79,7 @@ export const PublishButton = () => {
|
|||||||
isDisabled={isPublished}
|
isDisabled={isPublished}
|
||||||
onClick={handlePublishClick}
|
onClick={handlePublishClick}
|
||||||
borderRightRadius={publishedTypebot && !isPublished ? 0 : undefined}
|
borderRightRadius={publishedTypebot && !isPublished ? 0 : undefined}
|
||||||
|
{...props}
|
||||||
>
|
>
|
||||||
{isPublished ? 'Published' : 'Publish'}
|
{isPublished ? 'Published' : 'Publish'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -116,4 +116,4 @@ export const timeSince = (date: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const isCloudProdInstance = () =>
|
export const isCloudProdInstance = () =>
|
||||||
window.location.hostname === 'app.typebot.io'
|
typeof window !== 'undefined' && window.location.hostname === 'app.typebot.io'
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ export const getBubbleActions = (
|
|||||||
): BubbleActions => {
|
): BubbleActions => {
|
||||||
const existingBubbleElement =
|
const existingBubbleElement =
|
||||||
bubbleElement ??
|
bubbleElement ??
|
||||||
(document.querySelector('#typebot-bubble') as HTMLDivElement)
|
(document.querySelector('#typebot-bubble') as HTMLDivElement | undefined)
|
||||||
|
if (!existingBubbleElement) return { close: () => {}, open: () => {} }
|
||||||
const existingIframeElement =
|
const existingIframeElement =
|
||||||
iframeElement ??
|
iframeElement ??
|
||||||
(existingBubbleElement.querySelector(
|
(existingBubbleElement.querySelector(
|
||||||
|
|||||||
Reference in New Issue
Block a user