2
0

(editor) Allow empty group titles

This commit is contained in:
Baptiste Arnaud
2023-03-13 09:29:56 +01:00
parent 186328132f
commit f9aef907e3
11 changed files with 42 additions and 21 deletions

View File

@ -3,7 +3,7 @@ import { canReadTypebots } from '@/utils/api/dbRules'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { Group, Typebot, Webhook, WebhookBlock } from 'models'
import { byId, isWebhookBlock } from 'utils'
import { byId, isWebhookBlock, parseGroupTitle } from 'utils'
import { z } from 'zod'
export const listWebhookBlocksProcedure = authenticatedProcedure
@ -55,7 +55,7 @@ export const listWebhookBlocksProcedure = authenticatedProcedure
...webhookBlocks,
...blocks.map((b) => ({
id: b.id,
label: `${group.title} > ${b.id}`,
label: `${parseGroupTitle(group.title)} > ${b.id}`,
url: typebot?.webhooks.find(byId(b.webhookId))?.url ?? undefined,
})),
]

View File

@ -1,7 +1,7 @@
import React from 'react'
import { Tag, Text } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor'
import { byId, isDefined } from 'utils'
import { byId, isDefined, parseGroupTitle } from 'utils'
import { JumpBlock } from 'models/features/blocks/logic/jump'
type Props = {
@ -15,7 +15,8 @@ export const JumpNodeBody = ({ options }: Props) => {
if (!selectedGroup) return <Text color="gray.500">Configure...</Text>
return (
<Text>
Jump to <Tag colorScheme="blue">{selectedGroup.title}</Tag>{' '}
Jump to{' '}
<Tag colorScheme="blue">{parseGroupTitle(selectedGroup.title)}</Tag>{' '}
{isDefined(blockIndex) && blockIndex >= 0 ? (
<>
at block <Tag colorScheme="blue">{blockIndex + 1}</Tag>

View File

@ -3,7 +3,7 @@ import { useTypebot } from '@/features/editor'
import { Stack } from '@chakra-ui/react'
import { JumpBlock } from 'models/features/blocks/logic/jump'
import React from 'react'
import { byId } from 'utils'
import { byId, parseGroupTitle } from 'utils'
type Props = {
groupId: string
@ -32,7 +32,7 @@ export const JumpSettings = ({ groupId, options, onOptionsChange }: Props) => {
items={typebot.groups
.filter((group) => group.id !== currentGroupId)
.map((group) => ({
label: group.title,
label: parseGroupTitle(group.title),
value: group.id,
}))}
selectedItem={selectedGroup?.id}

View File

@ -1,6 +1,7 @@
import { Select } from '@/components/inputs/Select'
import { Input } from '@chakra-ui/react'
import { Group } from 'models'
import { parseGroupTitle } from 'utils'
type Props = {
groups: Group[]
@ -22,7 +23,7 @@ export const GroupsDropdown = ({
<Select
selectedItem={groupId}
items={(groups ?? []).map((group) => ({
label: group.title,
label: parseGroupTitle(group.title),
value: group.id,
}))}
onSelect={onGroupIdSelected}

View File

@ -9,6 +9,7 @@ import {
WebhookCallBacks,
} from './blocks'
import { Coordinates } from '@/features/graph'
import { parseGroupTitle } from 'utils'
export type GroupsActions = {
createGroup: (
@ -69,7 +70,7 @@ const groupsActions = (
const id = createId()
const newGroup: Group = {
...group,
title: `${group.title} copy`,
title: `${parseGroupTitle(group.title)} copy`,
id,
blocks: group.blocks.map((block) =>
duplicateBlockDraft(id)(block, onWebhookBlockDuplicated)

View File

@ -15,7 +15,7 @@ import {
useBlockDnd,
} from '../../../providers'
import { BlockNodesList } from '../BlockNode/BlockNodesList'
import { isDefined, isNotDefined } from 'utils'
import { isDefined, isEmpty, isNotDefined } from 'utils'
import { useTypebot, RightPanel, useEditor } from '@/features/editor'
import { GroupNodeContextMenu } from './GroupNodeContextMenu'
import { useDebounce } from 'use-debounce'
@ -108,6 +108,7 @@ const NonMemoizedDraggableGroupNode = ({
useEffect(() => {
setGroupTitle(group.title)
}, [group.title])
useEffect(() => {
if (!currentCoordinates || isReadOnly) return
if (
@ -127,7 +128,7 @@ const NonMemoizedDraggableGroupNode = ({
}, [connectingIds, group.id])
const handleTitleSubmit = (title: string) =>
title.length > 0 ? updateGroup(groupIndex, { title }) : undefined
updateGroup(groupIndex, { title })
const handleMouseEnter = () => {
if (isReadOnly) return
@ -226,6 +227,16 @@ const NonMemoizedDraggableGroupNode = ({
}}
px="1"
userSelect={'none'}
style={
isEmpty(groupTitle)
? {
display: 'block',
position: 'absolute',
top: '10px',
width: '100px',
}
: undefined
}
/>
<EditableInput minW="0" px="1" className="prevent-group-drag" />
</Editable>

View File

@ -43,10 +43,7 @@ export const AvatarForm = ({
useOutsideClick({
ref: popoverContainerRef,
handler: () => {
console.log('close')
onClose()
},
handler: onClose,
})
const isDefaultAvatar = !avatarProps?.url || avatarProps.url.includes('{{')

View File

@ -2,7 +2,7 @@ import { authenticateUser } from '@/features/auth/api'
import prisma from '@/lib/prisma'
import { Group, WebhookBlock } from 'models'
import { NextApiRequest, NextApiResponse } from 'next'
import { byId, isWebhookBlock } from 'utils'
import { byId, isWebhookBlock, parseGroupTitle } from 'utils'
import { methodNotAllowed } from 'utils/api'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
@ -27,7 +27,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
...emptyWebhookBlocks,
...blocks.map((b) => ({
blockId: b.id,
name: `${group.title} > ${b.id}`,
name: `${parseGroupTitle(group.title)} > ${b.id}`,
url: typebot?.webhooks.find(byId(b.webhookId))?.url ?? undefined,
})),
]

View File

@ -2,7 +2,7 @@ import { authenticateUser } from '@/features/auth/api'
import prisma from '@/lib/prisma'
import { Group, WebhookBlock } from 'models'
import { NextApiRequest, NextApiResponse } from 'next'
import { byId, isNotDefined, isWebhookBlock } from 'utils'
import { byId, isNotDefined, isWebhookBlock, parseGroupTitle } from 'utils'
import { methodNotAllowed } from 'utils/api'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
@ -32,7 +32,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
...blocks.map((s) => ({
id: s.id,
groupId: s.groupId,
name: `${group.title} > ${s.id}`,
name: `${parseGroupTitle(group.title)} > ${s.id}`,
})),
]
}, [])

View File

@ -10,7 +10,13 @@ import {
InputBlockType,
ResultInSession,
} from 'models'
import { isInputBlock, isDefined, byId, isNotEmpty } from './utils'
import {
isInputBlock,
isDefined,
byId,
isNotEmpty,
parseGroupTitle,
} from './utils'
export const parseResultHeader = (
typebot: Pick<Typebot, 'groups' | 'variables'>,
@ -55,7 +61,7 @@ const parseInputsResultHeader = ({
.flatMap((group) =>
group.blocks.map((block) => ({
...block,
groupTitle: group.title,
groupTitle: parseGroupTitle(group.title),
}))
)
.filter((block) => isInputBlock(block)) as (InputBlock & {
@ -80,7 +86,8 @@ const parseInputsResultHeader = ({
if (
existingHeader.blocks?.some(
(block) => block.groupId === inputBlock.groupId
)
) ||
existingHeader.label.includes('Untitled')
) {
const totalPrevious = existingHeaders.filter((h) =>
h.label.includes(label)

View File

@ -305,3 +305,6 @@ export const getAtPath = <T>(obj: T, path: string): unknown => {
}
return current
}
export const parseGroupTitle = (title: string) =>
isEmpty(title) ? 'Untitled' : title