2
0

🌐 Translate workspace (#528)

This commit is contained in:
Baptiste Arnaud
2023-05-31 07:53:30 +02:00
committed by GitHub
parent 6651c85f02
commit b2ea8fc059
18 changed files with 3029 additions and 3494 deletions

View File

@ -13,7 +13,7 @@ const nextConfig = {
], ],
i18n: { i18n: {
defaultLocale: 'en', defaultLocale: 'en',
locales: ['en', 'fr', 'pt'], locales: ['en', 'fr', 'pt', 'de'],
}, },
experimental: { experimental: {
outputFileTracingRoot: path.join(__dirname, '../../'), outputFileTracingRoot: path.join(__dirname, '../../'),

View File

@ -37,7 +37,6 @@
"@trpc/server": "10.27.3", "@trpc/server": "10.27.3",
"@typebot.io/emails": "workspace:*", "@typebot.io/emails": "workspace:*",
"@typebot.io/js": "workspace:*", "@typebot.io/js": "workspace:*",
"@typebot.io/next-international": "0.3.8",
"@typebot.io/react": "workspace:*", "@typebot.io/react": "workspace:*",
"@udecode/plate-basic-marks": "21.1.5", "@udecode/plate-basic-marks": "21.1.5",
"@udecode/plate-common": "^21.1.5", "@udecode/plate-common": "^21.1.5",
@ -71,6 +70,7 @@
"minio": "7.1.1", "minio": "7.1.1",
"next": "13.4.3", "next": "13.4.3",
"next-auth": "4.22.1", "next-auth": "4.22.1",
"next-international": "^0.4.1",
"nextjs-cors": "^2.1.2", "nextjs-cors": "^2.1.2",
"nodemailer": "6.9.2", "nodemailer": "6.9.2",
"nprogress": "0.2.0", "nprogress": "0.2.0",

View File

@ -1,15 +1,36 @@
import { Stack, Heading, useColorMode } from '@chakra-ui/react' import {
Stack,
Heading,
useColorMode,
Menu,
MenuButton,
MenuList,
MenuItem,
Button,
HStack,
} from '@chakra-ui/react'
import { GraphNavigation } from '@typebot.io/prisma' import { GraphNavigation } from '@typebot.io/prisma'
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { GraphNavigationRadioGroup } from './GraphNavigationRadioGroup' import { GraphNavigationRadioGroup } from './GraphNavigationRadioGroup'
import { AppearanceRadioGroup } from './AppearanceRadioGroup' import { AppearanceRadioGroup } from './AppearanceRadioGroup'
import { useUser } from '../hooks/useUser' import { useUser } from '../hooks/useUser'
import { useScopedI18n } from '@/locales' import { useChangeLocale, useCurrentLocale, useScopedI18n } from '@/locales'
import { ChevronDownIcon } from '@/components/icons'
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
const localeHumanReadable = {
en: 'English',
fr: 'Français',
de: 'Deutsch',
pt: 'Português',
} as const
export const UserPreferencesForm = () => { export const UserPreferencesForm = () => {
const scopedT = useScopedI18n('account.preferences') const scopedT = useScopedI18n('account.preferences')
const { colorMode, setColorMode } = useColorMode() const { colorMode, setColorMode } = useColorMode()
const { user, updateUser } = useUser() const { user, updateUser } = useUser()
const changeLocale = useChangeLocale()
const currentLocale = useCurrentLocale()
useEffect(() => { useEffect(() => {
if (!user?.graphNavigation) if (!user?.graphNavigation)
@ -25,8 +46,40 @@ export const UserPreferencesForm = () => {
updateUser({ preferredAppAppearance: value }) updateUser({ preferredAppAppearance: value })
} }
const updateLocale = (locale: keyof typeof localeHumanReadable) => () => {
changeLocale(locale)
document.cookie = `NEXT_LOCALE=${locale}; path=/; max-age=31536000`
}
return ( return (
<Stack spacing={12}> <Stack spacing={12}>
<HStack spacing={4}>
<Heading size="md">{scopedT('language.heading')}</Heading>
<Menu>
<MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
{localeHumanReadable[currentLocale]}
</MenuButton>
<MenuList>
{Object.keys(localeHumanReadable).map((locale) => (
<MenuItem
key={locale}
onClick={updateLocale(
locale as keyof typeof localeHumanReadable
)}
>
{
localeHumanReadable[
locale as keyof typeof localeHumanReadable
]
}
</MenuItem>
))}
</MenuList>
</Menu>
{currentLocale !== 'en' && (
<MoreInfoTooltip>{scopedT('language.tooltip')}</MoreInfoTooltip>
)}
</HStack>
<Stack spacing={6}> <Stack spacing={6}>
<Heading size="md">{scopedT('graphNavigation.heading')}</Heading> <Heading size="md">{scopedT('graphNavigation.heading')}</Heading>
<GraphNavigationRadioGroup <GraphNavigationRadioGroup

View File

@ -13,6 +13,7 @@ import { WorkspaceInvitation, WorkspaceRole } from '@typebot.io/prisma'
import { FormEvent, useState } from 'react' import { FormEvent, useState } from 'react'
import { Member } from '../types' import { Member } from '../types'
import { sendInvitationQuery } from '../queries/sendInvitationQuery' import { sendInvitationQuery } from '../queries/sendInvitationQuery'
import { useScopedI18n } from '@/locales'
type Props = { type Props = {
workspaceId: string workspaceId: string
@ -28,6 +29,7 @@ export const AddMemberForm = ({
isLoading, isLoading,
isLocked, isLocked,
}: Props) => { }: Props) => {
const scopedT = useScopedI18n('workspace.membersList')
const [invitationEmail, setInvitationEmail] = useState('') const [invitationEmail, setInvitationEmail] = useState('')
const [invitationRole, setInvitationRole] = useState<WorkspaceRole>( const [invitationRole, setInvitationRole] = useState<WorkspaceRole>(
WorkspaceRole.MEMBER WorkspaceRole.MEMBER
@ -52,7 +54,7 @@ export const AddMemberForm = ({
return ( return (
<HStack as="form" onSubmit={handleInvitationSubmit}> <HStack as="form" onSubmit={handleInvitationSubmit}>
<Input <Input
placeholder="colleague@company.com" placeholder={scopedT('inviteInput.placeholder')}
name="inviteEmail" name="inviteEmail"
value={invitationEmail} value={invitationEmail}
onChange={(e) => setInvitationEmail(e.target.value)} onChange={(e) => setInvitationEmail(e.target.value)}
@ -73,7 +75,7 @@ export const AddMemberForm = ({
type="submit" type="submit"
isDisabled={isLoading || isLocked || invitationEmail === ''} isDisabled={isLoading || isLocked || invitationEmail === ''}
> >
Invite {scopedT('inviteButton.label')}
</Button> </Button>
</HStack> </HStack>
) )

View File

@ -13,6 +13,7 @@ import {
import { WorkspaceRole } from '@typebot.io/prisma' import { WorkspaceRole } from '@typebot.io/prisma'
import React from 'react' import React from 'react'
import { convertWorkspaceRoleToReadable } from './AddMemberForm' import { convertWorkspaceRoleToReadable } from './AddMemberForm'
import { useI18n } from '@/locales'
type Props = { type Props = {
image?: string image?: string
@ -37,6 +38,7 @@ export const MemberItem = ({
onDeleteClick, onDeleteClick,
onSelectNewRole, onSelectNewRole,
}: Props) => { }: Props) => {
const t = useI18n()
const handleAdminClick = () => onSelectNewRole(WorkspaceRole.ADMIN) const handleAdminClick = () => onSelectNewRole(WorkspaceRole.ADMIN)
const handleMemberClick = () => onSelectNewRole(WorkspaceRole.MEMBER) const handleMemberClick = () => onSelectNewRole(WorkspaceRole.MEMBER)
@ -65,7 +67,7 @@ export const MemberItem = ({
{convertWorkspaceRoleToReadable(WorkspaceRole.MEMBER)} {convertWorkspaceRoleToReadable(WorkspaceRole.MEMBER)}
</MenuItem> </MenuItem>
<MenuItem color="red.500" onClick={onDeleteClick}> <MenuItem color="red.500" onClick={onDeleteClick}>
Remove {t('remove')}
</MenuItem> </MenuItem>
</MenuList> </MenuList>
)} )}
@ -85,32 +87,36 @@ export const MemberIdentityContent = ({
image?: string image?: string
isGuest?: boolean isGuest?: boolean
email: string email: string
}) => ( }) => {
<HStack justifyContent="space-between" maxW="full" p="2"> const t = useI18n()
<HStack minW={0} spacing="4">
<Avatar name={name} src={image} size="sm" /> return (
<Stack spacing={0} minW="0"> <HStack justifyContent="space-between" maxW="full" p="2">
{name && ( <HStack minW={0} spacing="4">
<Text textAlign="left" fontSize="15px"> <Avatar name={name} src={image} size="sm" />
{name} <Stack spacing={0} minW="0">
{name && (
<Text textAlign="left" fontSize="15px">
{name}
</Text>
)}
<Text
color="gray.500"
fontSize={name ? '14px' : 'inherit'}
noOfLines={1}
>
{email}
</Text> </Text>
</Stack>
</HStack>
<HStack flexShrink={0}>
{isGuest && (
<Tag color="gray.400" data-testid="tag">
{t('pending')}
</Tag>
)} )}
<Text <Tag data-testid="tag">{tag}</Tag>
color="gray.500" </HStack>
fontSize={name ? '14px' : 'inherit'}
noOfLines={1}
>
{email}
</Text>
</Stack>
</HStack> </HStack>
<HStack flexShrink={0}> )
{isGuest && ( }
<Tag color="gray.400" data-testid="tag">
Pending
</Tag>
)}
<Tag data-testid="tag">{tag}</Tag>
</HStack>
</HStack>
)

View File

@ -20,8 +20,10 @@ import { updateInvitationQuery } from '../queries/updateInvitationQuery'
import { updateMemberQuery } from '../queries/updateMemberQuery' import { updateMemberQuery } from '../queries/updateMemberQuery'
import { Member } from '../types' import { Member } from '../types'
import { useWorkspace } from '../WorkspaceProvider' import { useWorkspace } from '../WorkspaceProvider'
import { useScopedI18n } from '@/locales'
export const MembersList = () => { export const MembersList = () => {
const scopedT = useScopedI18n('workspace.membersList')
const { user } = useUser() const { user } = useUser()
const { workspace, currentRole } = useWorkspace() const { workspace, currentRole } = useWorkspace()
const { members, invitations, isLoading, mutate } = useMembers({ const { members, invitations, isLoading, mutate } = useMembers({
@ -102,16 +104,11 @@ export const MembersList = () => {
return ( return (
<Stack w="full" spacing={3}> <Stack w="full" spacing={3}>
{!canInviteNewMember && ( {!canInviteNewMember && (
<UnlockPlanAlertInfo <UnlockPlanAlertInfo contentLabel={scopedT('unlockBanner.label')} />
contentLabel={`
Upgrade your plan to work with more team members, and unlock awesome
power features 🚀
`}
/>
)} )}
{isDefined(seatsLimit) && ( {isDefined(seatsLimit) && (
<Heading fontSize="2xl"> <Heading fontSize="2xl">
Members{' '} {scopedT('title')}{' '}
{seatsLimit === -1 ? '' : `(${currentMembersCount}/${seatsLimit})`} {seatsLimit === -1 ? '' : `(${currentMembersCount}/${seatsLimit})`}
</Heading> </Heading>
)} )}

View File

@ -7,6 +7,7 @@ import {
} from '@/components/icons' } from '@/components/icons'
import { PlanTag } from '@/features/billing/components/PlanTag' import { PlanTag } from '@/features/billing/components/PlanTag'
import { trpc } from '@/lib/trpc' import { trpc } from '@/lib/trpc'
import { useScopedI18n } from '@/locales'
import { import {
Menu, Menu,
MenuButton, MenuButton,
@ -31,6 +32,7 @@ export const WorkspaceDropdown = ({
onLogoutClick, onLogoutClick,
onCreateNewWorkspaceClick, onCreateNewWorkspaceClick,
}: Props) => { }: Props) => {
const scopedT = useScopedI18n('workspace.dropdown')
const { data } = trpc.workspace.listWorkspaces.useQuery() const { data } = trpc.workspace.listWorkspaces.useQuery()
const workspaces = data?.workspaces ?? [] const workspaces = data?.workspaces ?? []
@ -70,14 +72,14 @@ export const WorkspaceDropdown = ({
</MenuItem> </MenuItem>
))} ))}
<MenuItem onClick={onCreateNewWorkspaceClick} icon={<PlusIcon />}> <MenuItem onClick={onCreateNewWorkspaceClick} icon={<PlusIcon />}>
New workspace {scopedT('newButton.label')}
</MenuItem> </MenuItem>
<MenuItem <MenuItem
onClick={onLogoutClick} onClick={onLogoutClick}
icon={<LogOutIcon />} icon={<LogOutIcon />}
color="orange.500" color="orange.500"
> >
Log out {scopedT('logoutButton.label')}
</MenuItem> </MenuItem>
</MenuList> </MenuList>
</Menu> </Menu>

View File

@ -12,8 +12,10 @@ import React from 'react'
import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon' import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon'
import { useWorkspace } from '../WorkspaceProvider' import { useWorkspace } from '../WorkspaceProvider'
import { TextInput } from '@/components/inputs' import { TextInput } from '@/components/inputs'
import { useScopedI18n } from '@/locales'
export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => { export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
const scopedT = useScopedI18n('workspace.settings')
const { workspace, workspaces, updateWorkspace, deleteCurrentWorkspace } = const { workspace, workspaces, updateWorkspace, deleteCurrentWorkspace } =
useWorkspace() useWorkspace()
@ -34,7 +36,7 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
return ( return (
<Stack spacing="6" w="full"> <Stack spacing="6" w="full">
<FormControl> <FormControl>
<FormLabel>Icon</FormLabel> <FormLabel>{scopedT('icon.title')}</FormLabel>
<Flex> <Flex>
{workspace && ( {workspace && (
<EditableEmojiOrImageIcon <EditableEmojiOrImageIcon
@ -48,7 +50,7 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
</FormControl> </FormControl>
{workspace && ( {workspace && (
<TextInput <TextInput
label="Name:" label={scopedT('name.label')}
withVariableButton={false} withVariableButton={false}
defaultValue={workspace?.name} defaultValue={workspace?.name}
onChange={handleNameChange} onChange={handleNameChange}
@ -71,11 +73,12 @@ const DeleteWorkspaceButton = ({
workspaceName: string workspaceName: string
onConfirm: () => Promise<void> onConfirm: () => Promise<void>
}) => { }) => {
const scopedT = useScopedI18n('workspace.settings')
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
return ( return (
<> <>
<Button colorScheme="red" variant="outline" onClick={onOpen}> <Button colorScheme="red" variant="outline" onClick={onOpen}>
Delete workspace {scopedT('deleteButton.label')}
</Button> </Button>
<ConfirmModal <ConfirmModal
isOpen={isOpen} isOpen={isOpen}
@ -83,8 +86,9 @@ const DeleteWorkspaceButton = ({
onClose={onClose} onClose={onClose}
message={ message={
<Text> <Text>
Are you sure you want to delete {workspaceName} workspace? All its {scopedT('deleteButton.confirmMessage', {
folders, typebots and results will be deleted forever. workspaceName,
})}
</Text> </Text>
} }
confirmButtonLabel="Delete" confirmButtonLabel="Delete"

View File

@ -24,6 +24,7 @@ import packageJson from '../../../../../../package.json'
import { UserPreferencesForm } from '@/features/account/components/UserPreferencesForm' import { UserPreferencesForm } from '@/features/account/components/UserPreferencesForm'
import { MyAccountForm } from '@/features/account/components/MyAccountForm' import { MyAccountForm } from '@/features/account/components/MyAccountForm'
import { BillingSettingsLayout } from '@/features/billing/components/BillingSettingsLayout' import { BillingSettingsLayout } from '@/features/billing/components/BillingSettingsLayout'
import { useScopedI18n } from '@/locales'
type Props = { type Props = {
isOpen: boolean isOpen: boolean
@ -45,6 +46,7 @@ export const WorkspaceSettingsModal = ({
workspace, workspace,
onClose, onClose,
}: Props) => { }: Props) => {
const scopedT = useScopedI18n('workspace.settings.modal')
const { currentRole } = useWorkspace() const { currentRole } = useWorkspace()
const [selectedTab, setSelectedTab] = useState<SettingsTab>('my-account') const [selectedTab, setSelectedTab] = useState<SettingsTab>('my-account')
@ -56,7 +58,7 @@ export const WorkspaceSettingsModal = ({
<ModalContent minH="600px" flexDir="row"> <ModalContent minH="600px" flexDir="row">
<Stack <Stack
spacing={8} spacing={8}
w="200px" w="180px"
py="6" py="6"
borderRightWidth={1} borderRightWidth={1}
justifyContent="space-between" justifyContent="space-between"
@ -80,7 +82,7 @@ export const WorkspaceSettingsModal = ({
justifyContent="flex-start" justifyContent="flex-start"
pl="4" pl="4"
> >
My account {scopedT('menu.myAccount.label')}
</Button> </Button>
<Button <Button
variant={selectedTab === 'user-settings' ? 'solid' : 'ghost'} variant={selectedTab === 'user-settings' ? 'solid' : 'ghost'}
@ -90,12 +92,12 @@ export const WorkspaceSettingsModal = ({
justifyContent="flex-start" justifyContent="flex-start"
pl="4" pl="4"
> >
Preferences {scopedT('menu.preferences.label')}
</Button> </Button>
</Stack> </Stack>
<Stack> <Stack>
<Text pl="4" color="gray.500"> <Text pl="4" color="gray.500">
Workspace {scopedT('menu.workspace.label')}
</Text> </Text>
{canEditWorkspace && ( {canEditWorkspace && (
<Button <Button
@ -114,7 +116,7 @@ export const WorkspaceSettingsModal = ({
justifyContent="flex-start" justifyContent="flex-start"
pl="4" pl="4"
> >
Settings {scopedT('menu.settings.label')}
</Button> </Button>
)} )}
<Button <Button
@ -125,7 +127,7 @@ export const WorkspaceSettingsModal = ({
justifyContent="flex-start" justifyContent="flex-start"
pl="4" pl="4"
> >
Members {scopedT('menu.members.label')}
</Button> </Button>
{canEditWorkspace && ( {canEditWorkspace && (
<Button <Button
@ -135,8 +137,10 @@ export const WorkspaceSettingsModal = ({
size="sm" size="sm"
justifyContent="flex-start" justifyContent="flex-start"
pl="4" pl="4"
overflow="scroll"
className="hide-scrollbar"
> >
Billing & Usage {scopedT('menu.billingAndUsage.label')}
</Button> </Button>
)} )}
</Stack> </Stack>
@ -144,7 +148,7 @@ export const WorkspaceSettingsModal = ({
<Flex justify="center" pt="10"> <Flex justify="center" pt="10">
<Text color="gray.500" fontSize="xs"> <Text color="gray.500" fontSize="xs">
Version: {packageJson.version} {scopedT('menu.version.label', { version: packageJson.version })}
</Text> </Text>
</Flex> </Flex>
</Stack> </Stack>

View File

@ -1,6 +1,4 @@
import { defineLocale } from './index' export default {
export default defineLocale({
back: 'Zurück', back: 'Zurück',
'confirmModal.defaultTitle': 'Bist du sicher?', 'confirmModal.defaultTitle': 'Bist du sicher?',
'dashboard.header.settingsButton.label': 'Einstellungen & Mitglieder', 'dashboard.header.settingsButton.label': 'Einstellungen & Mitglieder',
@ -12,55 +10,61 @@ export default defineLocale({
update: 'Aktualisieren', update: 'Aktualisieren',
upgrade: 'Upgrade', upgrade: 'Upgrade',
downgrade: 'Downgrade', downgrade: 'Downgrade',
remove: 'Entfernen',
pending: 'Ausstehend',
'folders.createFolderButton.label': 'Ordner erstellen', 'folders.createFolderButton.label': 'Ordner erstellen',
'folders.createTypebotButton.label': 'Typebot erstellen', 'folders.createTypebotButton.label': 'Typebot erstellen',
'folders.folderButton.deleteConfirmationMessage': 'folders.folderButton.deleteConfirmationMessage':
'Möchtest du den Ordner {folderName} wirklich löschen? (Alles im Inneren wird in dein Dashboard verschoben)', 'Möchtest du den Ordner {folderName} wirklich löschen? (Alles im Inneren wird in dein Dashboard verschoben)',
'folders.typebotButton.live': 'Live', 'folders.typebotButton.live': 'Live',
'folders.typebotButton.showMoreOptions': 'Mehr Optionen anzeigen', 'folders.typebotButton.showMoreOptions': 'Mehr Optionen anzeigen',
'folders.typebotButton.unpublish': 'Unveröffentlichen', 'folders.typebotButton.unpublish': 'Unveröffentlichen',
'folders.typebotButton.duplicate': 'Duplizieren', 'folders.typebotButton.duplicate': 'Duplizieren',
'folders.typebotButton.delete': 'Löschen', 'folders.typebotButton.delete': 'Löschen',
'folders.typebotButton.deleteConfirmationMessage': 'folders.typebotButton.deleteConfirmationMessage':
'Möchtest du deinen Typebot {typebotName} wirklich löschen?', 'Möchtest du deinen Typebot {typebotName} wirklich löschen?',
'folders.typebotButton.deleteConfirmationMessageWarning': 'folders.typebotButton.deleteConfirmationMessageWarning':
'Alle zugehörigen Daten werden gelöscht und können nicht wiederhergestellt werden.', 'Alle zugehörigen Daten werden gelöscht und können nicht wiederhergestellt werden.',
'account.apiTokens.heading': 'API-Token', 'account.apiTokens.heading': 'API-Token',
'account.apiTokens.description': 'account.apiTokens.description':
'Diese Token ermöglichen es anderen Apps, dein gesamtes Konto und Typebots zu steuern. Sei vorsichtig!', 'Diese Token ermöglichen es anderen Apps, dein gesamtes Konto und Typebots zu steuern. Sei vorsichtig!',
'account.apiTokens.createButton.label': 'Erstellen', 'account.apiTokens.createButton.label': 'Erstellen',
'account.apiTokens.deleteButton.label': 'Löschen', 'account.apiTokens.deleteButton.label': 'Löschen',
'account.apiTokens.table.nameHeader': 'Name', 'account.apiTokens.table.nameHeader': 'Name',
'account.apiTokens.table.createdHeader': 'Erstellt', 'account.apiTokens.table.createdHeader': 'Erstellt',
'account.apiTokens.deleteConfirmationMessage': 'account.apiTokens.deleteConfirmationMessage':
'Der Token {tokenName} wird dauerhaft widerrufen, bist du sicher, dass du fortfahren möchtest?', 'Der Token {tokenName} wird dauerhaft widerrufen, bist du sicher, dass du fortfahren möchtest?',
'account.apiTokens.createModal.createHeading': 'Token erstellen', 'account.apiTokens.createModal.createHeading': 'Token erstellen',
'account.apiTokens.createModal.createdHeading': 'Token erstellt', 'account.apiTokens.createModal.createdHeading': 'Token erstellt',
'account.apiTokens.createModal.nameInput.label': 'account.apiTokens.createModal.nameInput.label':
'Gib einen eindeutigen Namen für deinen Token ein, um ihn von anderen Token zu unterscheiden.', 'Gib einen eindeutigen Namen für deinen Token ein, um ihn von anderen Token zu unterscheiden.',
'account.apiTokens.createModal.nameInput.placeholder': 'account.apiTokens.createModal.nameInput.placeholder':
'Z.B. Zapier, Github, Make.com', 'Z.B. Zapier, Github, Make.com',
'account.apiTokens.createModal.createButton.label': 'Token erstellen', 'account.apiTokens.createModal.createButton.label': 'Token erstellen',
'account.apiTokens.createModal.doneButton.label': 'Fertig', 'account.apiTokens.createModal.doneButton.label': 'Fertig',
'account.apiTokens.createModal.copyInstruction': 'account.apiTokens.createModal.copyInstruction':
'Bitte kopiere deinen Token und bewahre ihn an einem sicheren Ort auf.', 'Bitte kopiere deinen Token und bewahre ihn an einem sicheren Ort auf.',
'account.apiTokens.createModal.securityWarning': 'account.apiTokens.createModal.securityWarning':
'Aus Sicherheitsgründen können wir ihn nicht erneut anzeigen.', 'Aus Sicherheitsgründen können wir ihn nicht erneut anzeigen.',
'account.preferences.language.heading': 'Sprache',
'account.preferences.language.tooltip':
'Die Übersetzungen sind noch nicht vollständig. Es ist eine laufende Arbeit. 🤓',
'account.preferences.graphNavigation.heading': 'Editor-Navigation', 'account.preferences.graphNavigation.heading': 'Editor-Navigation',
'account.preferences.graphNavigation.mouse.label': 'Maus', 'account.preferences.graphNavigation.mouse.label': 'Maus',
'account.preferences.graphNavigation.mouse.description': 'account.preferences.graphNavigation.mouse.description':
'Bewege dich, indem du das Board ziehst und zoome rein/raus mit dem Mausrad', 'Bewege dich, indem du das Board ziehst und zoome rein/raus mit dem Mausrad',
'account.preferences.graphNavigation.trackpad.label': 'Trackpad', 'account.preferences.graphNavigation.trackpad.label': 'Trackpad',
'account.preferences.graphNavigation.trackpad.description': 'account.preferences.graphNavigation.trackpad.description':
'Bewege das Board mit 2 Fingern und zoome rein/raus, indem du kneifst', 'Bewege das Board mit 2 Fingern und zoome rein/raus, indem du kneifst',
'account.preferences.appearance.heading': 'Erscheinungsbild', 'account.preferences.appearance.heading': 'Erscheinungsbild',
'account.preferences.appearance.systemLabel': 'System', 'account.preferences.appearance.systemLabel': 'System',
'account.preferences.appearance.lightLabel': 'Hell', 'account.preferences.appearance.lightLabel': 'Hell',
'account.preferences.appearance.darkLabel': 'Dunkel', 'account.preferences.appearance.darkLabel': 'Dunkel',
'account.myAccount.changePhotoButton.label': 'Foto ändern', 'account.myAccount.changePhotoButton.label': 'Foto ändern',
'account.myAccount.changePhotoButton.specification': '.jpg oder .png, max 1MB', 'account.myAccount.changePhotoButton.specification':
'.jpg oder .png, max 1MB',
'account.myAccount.emailInput.disabledTooltip': 'account.myAccount.emailInput.disabledTooltip':
'Das Aktualisieren der E-Mail-Adresse ist nicht verfügbar. Kontaktiere den Support, wenn du sie ändern möchtest.', 'Das Aktualisieren der E-Mail-Adresse ist nicht verfügbar. Kontaktiere den Support, wenn du sie ändern möchtest.',
'account.myAccount.emailInput.label': 'E-Mail-Adresse:', 'account.myAccount.emailInput.label': 'E-Mail-Adresse:',
'account.myAccount.nameInput.label': 'Name:', 'account.myAccount.nameInput.label': 'Name:',
'analytics.viewsLabel': 'Ansichten', 'analytics.viewsLabel': 'Ansichten',
@ -70,22 +74,25 @@ export default defineLocale({
'auth.signin.noAccountLabel.preLink': 'Noch kein Konto?', 'auth.signin.noAccountLabel.preLink': 'Noch kein Konto?',
'auth.signin.noAccountLabel.link': 'Kostenlos anmelden', 'auth.signin.noAccountLabel.link': 'Kostenlos anmelden',
'auth.register.heading': 'Konto erstellen', 'auth.register.heading': 'Konto erstellen',
'auth.register.alreadyHaveAccountLabel.preLink': 'Bereits ein Konto vorhanden?', 'auth.register.alreadyHaveAccountLabel.preLink':
'Bereits ein Konto vorhanden?',
'auth.register.alreadyHaveAccountLabel.link': 'Anmelden', 'auth.register.alreadyHaveAccountLabel.link': 'Anmelden',
'auth.error.default': 'Versuche, dich mit einem anderen Konto anzumelden.', 'auth.error.default': 'Versuche, dich mit einem anderen Konto anzumelden.',
'auth.error.email': 'E-Mail nicht gefunden. Versuche, dich mit einem anderen Anbieter anzumelden.', 'auth.error.email':
'E-Mail nicht gefunden. Versuche, dich mit einem anderen Anbieter anzumelden.',
'auth.error.oauthNotLinked': 'auth.error.oauthNotLinked':
'Um deine Identität zu bestätigen, melde dich mit demselben Konto an, das du ursprünglich verwendet hast.', 'Um deine Identität zu bestätigen, melde dich mit demselben Konto an, das du ursprünglich verwendet hast.',
'auth.error.unknown': 'Ein Fehler ist aufgetreten. Bitte versuche es erneut.', 'auth.error.unknown': 'Ein Fehler ist aufgetreten. Bitte versuche es erneut.',
'auth.signinErrorToast.title': 'Nicht autorisiert', 'auth.signinErrorToast.title': 'Nicht autorisiert',
'auth.signinErrorToast.description': 'Anmeldungen sind deaktiviert.', 'auth.signinErrorToast.description': 'Anmeldungen sind deaktiviert.',
'auth.noProvider.preLink': 'Du musst', 'auth.noProvider.preLink': 'Du musst',
'auth.noProvider.link': 'auth.noProvider.link':
'mindestens einen Authentifizierungsanbieter konfigurieren (E-Mail, Google, GitHub, Facebook oder Azure AD).', 'mindestens einen Authentifizierungsanbieter konfigurieren (E-Mail, Google, GitHub, Facebook oder Azure AD).',
'auth.orEmailLabel': 'Oder mit deiner E-Mail', 'auth.orEmailLabel': 'Oder mit deiner E-Mail',
'auth.emailSubmitButton.label': 'Absenden', 'auth.emailSubmitButton.label': 'Absenden',
'auth.magicLink.title': 'Eine E-Mail mit magischem Link wurde gesendet. 🪄', 'auth.magicLink.title': 'Eine E-Mail mit magischem Link wurde gesendet. 🪄',
'auth.magicLink.description': 'Vergiss nicht, deinen Spam-Ordner zu überprüfen.', 'auth.magicLink.description':
'Vergiss nicht, deinen Spam-Ordner zu überprüfen.',
'auth.socialLogin.githubButton.label': 'Mit GitHub fortfahren', 'auth.socialLogin.githubButton.label': 'Mit GitHub fortfahren',
'auth.socialLogin.googleButton.label': 'Mit Google fortfahren', 'auth.socialLogin.googleButton.label': 'Mit Google fortfahren',
'auth.socialLogin.facebookButton.label': 'Mit Facebook fortfahren', 'auth.socialLogin.facebookButton.label': 'Mit Facebook fortfahren',
@ -94,64 +101,86 @@ export default defineLocale({
'auth.socialLogin.customButton.label': 'Mit {customProviderName} fortfahren', 'auth.socialLogin.customButton.label': 'Mit {customProviderName} fortfahren',
'billing.billingPortalButton.label': 'Abrechnungsportal', 'billing.billingPortalButton.label': 'Abrechnungsportal',
'billing.contribution.preLink': 'billing.contribution.preLink':
'Typebot trägt 1% deines Abonnements dazu bei, CO₂ aus der Atmosphäre zu entfernen.', 'Typebot trägt 1% deines Abonnements dazu bei, CO₂ aus der Atmosphäre zu entfernen.',
'billing.contribution.link': 'Erfahre mehr.', 'billing.contribution.link': 'Erfahre mehr.',
'billing.updateSuccessToast.description': 'billing.updateSuccessToast.description':
'Arbeitsbereich {plan} Plan erfolgreich aktualisiert 🎉', 'Arbeitsbereich {plan} Plan erfolgreich aktualisiert 🎉',
'billing.customLimit.preLink': 'Brauchst du individuelle Limits? Spezielle Funktionen?', 'billing.customLimit.preLink':
'billing.customLimit.link': "Lass uns darüber sprechen!", 'Brauchst du individuelle Limits? Spezielle Funktionen?',
'billing.upgradeLimitLabel': 'billing.customLimit.link': 'Lass uns darüber sprechen!',
'Um {type} hinzuzufügen, musst du deinen Tarif aktualisieren', 'billing.upgradeLimitLabel':
'billing.currentSubscription.heading': 'Abonnement', 'Um {type} hinzuzufügen, musst du deinen Tarif aktualisieren',
'billing.currentSubscription.subheading': 'Aktuelles Arbeitsbereich-Abonnement:', 'billing.currentSubscription.heading': 'Abonnement',
'billing.currentSubscription.cancelLink': 'Mein Abonnement kündigen', 'billing.currentSubscription.subheading':
'billing.invoices.heading': 'Rechnungen', 'Aktuelles Arbeitsbereich-Abonnement:',
'billing.invoices.empty': 'Keine Rechnungen für diesen Arbeitsbereich gefunden.', 'billing.currentSubscription.cancelLink': 'Mein Abonnement kündigen',
'billing.invoices.paidAt': 'Bezahlt am', 'billing.invoices.heading': 'Rechnungen',
'billing.invoices.subtotal': 'Zwischensumme', 'billing.invoices.empty':
'billing.preCheckoutModal.companyInput.label': 'Firmenname:', 'Keine Rechnungen für diesen Arbeitsbereich gefunden.',
'billing.preCheckoutModal.emailInput.label': 'E-Mail:', 'billing.invoices.paidAt': 'Bezahlt am',
'billing.preCheckoutModal.taxId.label': 'Steuernummer:', 'billing.invoices.subtotal': 'Zwischensumme',
'billing.preCheckoutModal.taxId.placeholder': 'ID-Typ', 'billing.preCheckoutModal.companyInput.label': 'Firmenname:',
'billing.preCheckoutModal.submitButton.label': 'Zur Kasse gehen', 'billing.preCheckoutModal.emailInput.label': 'E-Mail:',
'billing.pricingCard.heading': 'Upgrade auf {plan}', 'billing.preCheckoutModal.taxId.label': 'Steuernummer:',
'billing.pricingCard.perMonth': '/ Monat', 'billing.preCheckoutModal.taxId.placeholder': 'ID-Typ',
'billing.pricingCard.plus': ', plus:', 'billing.preCheckoutModal.submitButton.label': 'Zur Kasse gehen',
'billing.pricingCard.upgradeButton.current': 'Dein aktueller Tarif', 'billing.pricingCard.heading': 'Upgrade auf {plan}',
'billing.pricingCard.chatsPerMonth': 'Chats/Monat', 'billing.pricingCard.perMonth': '/ Monat',
'billing.pricingCard.chatsTooltip': 'billing.pricingCard.plus': ', plus:',
'Ein Chat wird gezählt, wenn ein Benutzer eine Diskussion startet. Es ist unabhängig von der Anzahl der gesendeten und empfangenen Nachrichten.', 'billing.pricingCard.upgradeButton.current': 'Dein aktueller Tarif',
'billing.pricingCard.storageLimit': 'GB Speicherplatz', 'billing.pricingCard.chatsPerMonth': 'Chats/Monat',
'billing.pricingCard.storageLimitTooltip': 'billing.pricingCard.chatsTooltip':
'Du sammelst Speicherplatz für jede Datei, die dein Benutzer in deinem Bot hochlädt. Wenn du das Ergebnis löschst, wird der Platz freigegeben.', 'Ein Chat wird gezählt, wenn ein Benutzer eine Diskussion startet. Es ist unabhängig von der Anzahl der gesendeten und empfangenen Nachrichten.',
'billing.pricingCard.starter.description': 'billing.pricingCard.storageLimit': 'GB Speicherplatz',
'Für Einzelpersonen & kleine Unternehmen.', 'billing.pricingCard.storageLimitTooltip':
'billing.pricingCard.starter.includedSeats': '2 Plätze inklusive', 'Du sammelst Speicherplatz für jede Datei, die dein Benutzer in deinem Bot hochlädt. Wenn du das Ergebnis löschst, wird der Platz freigegeben.',
'billing.pricingCard.starter.brandingRemoved': 'Branding entfernt', 'billing.pricingCard.starter.description':
'billing.pricingCard.starter.fileUploadBlock': 'Datei-Upload Eingabefeld', 'Für Einzelpersonen & kleine Unternehmen.',
'billing.pricingCard.starter.createFolders': 'Ordner erstellen', 'billing.pricingCard.starter.includedSeats': '2 Plätze inklusive',
'billing.pricingCard.pro.mostPopularLabel': 'Am beliebtesten', 'billing.pricingCard.starter.brandingRemoved': 'Branding entfernt',
'billing.pricingCard.pro.description': 'Für Agenturen & wachsende Start-ups.', 'billing.pricingCard.starter.fileUploadBlock': 'Datei-Upload Eingabefeld',
'billing.pricingCard.pro.everythingFromStarter': 'Alles in Starter', 'billing.pricingCard.starter.createFolders': 'Ordner erstellen',
'billing.pricingCard.pro.includedSeats': '5 Plätze inklusive', 'billing.pricingCard.pro.mostPopularLabel': 'Am beliebtesten',
'billing.pricingCard.pro.customDomains': 'Eigene Domains', 'billing.pricingCard.pro.description': 'Für Agenturen & wachsende Start-ups.',
'billing.pricingCard.pro.analytics': 'Detaillierte Analysen', 'billing.pricingCard.pro.everythingFromStarter': 'Alles in Starter',
'billing.usage.heading': 'Nutzung', 'billing.pricingCard.pro.includedSeats': '5 Plätze inklusive',
'billing.usage.chats.heading': 'Chats', 'billing.pricingCard.pro.customDomains': 'Eigene Domains',
'billing.usage.chats.alert.soonReach': 'billing.pricingCard.pro.analytics': 'Detaillierte Analysen',
"Deine Typebots sind beliebt! Du wirst bald das Chat-Limit deines Tarifs erreichen. 🚀", 'billing.usage.heading': 'Nutzung',
'billing.usage.chats.alert.updatePlan': 'billing.usage.chats.heading': 'Chats',
'Vergewissere dich, dass du deinen Tarif aktualisierst, um dieses Limit zu erhöhen und weiterhin mit deinen Benutzern zu chatten.', 'billing.usage.chats.alert.soonReach':
'billing.usage.chats.resetInfo': '(setzt sich am 1. jeden Monats zurück)', 'Deine Typebots sind beliebt! Du wirst bald das Chat-Limit deines Tarifs erreichen. 🚀',
'billing.usage.storage.heading': 'Speicher', 'billing.usage.chats.alert.updatePlan':
'billing.usage.storage.alert.soonReach': 'Vergewissere dich, dass du deinen Tarif aktualisierst, um dieses Limit zu erhöhen und weiterhin mit deinen Benutzern zu chatten.',
"Deine Typebots sind beliebt! Du wirst bald das Speicherlimit deines Tarifs erreichen. 🚀", 'billing.usage.chats.resetInfo': '(setzt sich am 1. jeden Monats zurück)',
'billing.usage.storage.alert.updatePlan': 'billing.usage.storage.heading': 'Speicher',
'Stelle sicher, dass du deinen Tarif aktualisierst, um weiterhin hochgeladene Dateien zu sammeln. Du kannst auch Dateien löschen, um Speicherplatz freizugeben.', 'billing.usage.storage.alert.soonReach':
'billing.limitMessage.brand': 'Branding entfernen', 'Deine Typebots sind beliebt! Du wirst bald das Speicherlimit deines Tarifs erreichen. 🚀',
'billing.limitMessage.customDomain': 'Eigene Domains hinzufügen', 'billing.usage.storage.alert.updatePlan':
'billing.limitMessage.analytics': 'Detaillierte Analysen freischalten', 'Stelle sicher, dass du deinen Tarif aktualisierst, um weiterhin hochgeladene Dateien zu sammeln. Du kannst auch Dateien löschen, um Speicherplatz freizugeben.',
'billing.limitMessage.fileInput': 'Datei-Eingabefelder verwenden', 'billing.limitMessage.brand': 'Branding entfernen',
'billing.limitMessage.folder': 'Ordner erstellen', 'billing.limitMessage.customDomain': 'Eigene Domains hinzufügen',
'billing.upgradeAlert.buttonDefaultLabel': 'Mehr Informationen', 'billing.limitMessage.analytics': 'Detaillierte Analysen freischalten',
}) 'billing.limitMessage.fileInput': 'Datei-Eingabefelder verwenden',
'billing.limitMessage.folder': 'Ordner erstellen',
'billing.upgradeAlert.buttonDefaultLabel': 'Mehr Informationen',
'workspace.membersList.inviteInput.placeholder': 'kollege@unternehmen.com',
'workspace.membersList.inviteButton.label': 'Einladen',
'workspace.membersList.unlockBanner.label':
'Aktualisieren Sie Ihren Plan, um mit mehr Teammitgliedern zu arbeiten und erstaunliche Leistungsmerkmale freizuschalten 🚀',
'workspace.membersList.title': 'Mitglieder',
'workspace.settings.icon.title': 'Symbol',
'workspace.settings.name.label': 'Name:',
'workspace.settings.deleteButton.label': 'Arbeitsbereich löschen',
'workspace.settings.deleteButton.confirmMessage':
'Sind Sie sicher, dass Sie den Arbeitsbereich {workspaceName} löschen möchten? Alle seine Ordner, Typebots und Ergebnisse werden dauerhaft gelöscht.',
'workspace.settings.modal.menu.myAccount.label': 'Mein Konto',
'workspace.settings.modal.menu.preferences.label': 'Einstellungen',
'workspace.settings.modal.menu.workspace.label': 'Arbeitsbereich',
'workspace.settings.modal.menu.settings.label': 'Einstellungen',
'workspace.settings.modal.menu.members.label': 'Mitglieder',
'workspace.settings.modal.menu.billingAndUsage.label': 'Abrechnung & Nutzung',
'workspace.settings.modal.menu.version.label': 'Version: {version}',
'workspace.dropdown.newButton.label': 'Neuer Arbeitsbereich',
'workspace.dropdown.logoutButton.label': 'Abmelden',
} as const

View File

@ -10,6 +10,8 @@ export default {
update: 'Update', update: 'Update',
upgrade: 'Upgrade', upgrade: 'Upgrade',
downgrade: 'Downgrade', downgrade: 'Downgrade',
remove: 'Remove',
pending: 'Pending',
'folders.createFolderButton.label': 'Create a folder', 'folders.createFolderButton.label': 'Create a folder',
'folders.createTypebotButton.label': 'Create a typebot', 'folders.createTypebotButton.label': 'Create a typebot',
'folders.folderButton.deleteConfirmationMessage': 'folders.folderButton.deleteConfirmationMessage':
@ -44,6 +46,9 @@ export default {
'Please copy your token and store it in a safe place.', 'Please copy your token and store it in a safe place.',
'account.apiTokens.createModal.securityWarning': 'account.apiTokens.createModal.securityWarning':
'For security reasons we cannot show it again.', 'For security reasons we cannot show it again.',
'account.preferences.language.heading': 'Language',
'account.preferences.language.tooltip':
'The translations are not complete yet. It is a work in progress. 🤓',
'account.preferences.graphNavigation.heading': 'Editor Navigation', 'account.preferences.graphNavigation.heading': 'Editor Navigation',
'account.preferences.graphNavigation.mouse.label': 'Mouse', 'account.preferences.graphNavigation.mouse.label': 'Mouse',
'account.preferences.graphNavigation.mouse.description': 'account.preferences.graphNavigation.mouse.description':
@ -152,4 +157,23 @@ export default {
'billing.limitMessage.fileInput': 'use file input blocks', 'billing.limitMessage.fileInput': 'use file input blocks',
'billing.limitMessage.folder': 'create folders', 'billing.limitMessage.folder': 'create folders',
'billing.upgradeAlert.buttonDefaultLabel': 'More info', 'billing.upgradeAlert.buttonDefaultLabel': 'More info',
'workspace.membersList.inviteInput.placeholder': 'colleague@company.com',
'workspace.membersList.inviteButton.label': 'Invite',
'workspace.membersList.unlockBanner.label':
'Upgrade your plan to work with more team members, and unlock awesome power features 🚀',
'workspace.membersList.title': 'Members',
'workspace.settings.icon.title': 'Icon',
'workspace.settings.name.label': 'Name:',
'workspace.settings.deleteButton.label': 'Delete workspace',
'workspace.settings.deleteButton.confirmMessage':
'Are you sure you want to delete {workspaceName} workspace? All its folders, typebots and results will be deleted forever.',
'workspace.settings.modal.menu.myAccount.label': 'My account',
'workspace.settings.modal.menu.preferences.label': 'Preferences',
'workspace.settings.modal.menu.workspace.label': 'Workspace',
'workspace.settings.modal.menu.settings.label': 'Settings',
'workspace.settings.modal.menu.members.label': 'Members',
'workspace.settings.modal.menu.billingAndUsage.label': 'Billing & Usage',
'workspace.settings.modal.menu.version.label': 'Version: {version}',
'workspace.dropdown.newButton.label': 'New workspace',
'workspace.dropdown.logoutButton.label': 'Log out',
} as const } as const

View File

@ -1,10 +1,8 @@
import { defineLocale } from './index' export default {
export default defineLocale({
back: 'Retour', back: 'Retour',
'confirmModal.defaultTitle': 'Êtes-vous sûr ?', 'confirmModal.defaultTitle': 'Es-tu sûr ?',
'dashboard.header.settingsButton.label': 'Paramètres & Membres', 'dashboard.header.settingsButton.label': 'Paramètres & Membres',
'dashboard.redirectionMessage': "Vous êtes en train d'être redirigé...", 'dashboard.redirectionMessage': 'Redirection en cours...',
'dashboard.title': 'Mes typebots', 'dashboard.title': 'Mes typebots',
delete: 'Supprimer', delete: 'Supprimer',
errorMessage: "Une erreur s'est produite", errorMessage: "Une erreur s'est produite",
@ -12,47 +10,52 @@ export default defineLocale({
update: 'Mettre à jour', update: 'Mettre à jour',
upgrade: 'Upgrade', upgrade: 'Upgrade',
downgrade: 'Downgrade', downgrade: 'Downgrade',
remove: 'Retirer',
pending: 'En attente',
'folders.createFolderButton.label': 'Créer un dossier', 'folders.createFolderButton.label': 'Créer un dossier',
'folders.createTypebotButton.label': 'Créer un typebot', 'folders.createTypebotButton.label': 'Créer un typebot',
'folders.folderButton.deleteConfirmationMessage': 'folders.folderButton.deleteConfirmationMessage':
"Êtes-vous sûr de vouloir supprimer le dossier {folderName} ? (Tout ce qui est à l'intérieur sera déplacé dans le dossier parent ou sur votre tableau de bord)", "Es-tu sûr de vouloir supprimer le dossier {folderName} ? (Tout ce qui est à l'intérieur sera déplacé dans le dossier parent ou sur votre tableau de bord)",
'folders.typebotButton.live': 'Live', 'folders.typebotButton.live': 'Live',
'folders.typebotButton.showMoreOptions': "Afficher plus d'options", 'folders.typebotButton.showMoreOptions': "Afficher plus d'options",
'folders.typebotButton.unpublish': 'Dépublier', 'folders.typebotButton.unpublish': 'Dépublier',
'folders.typebotButton.duplicate': 'Dupliquer', 'folders.typebotButton.duplicate': 'Dupliquer',
'folders.typebotButton.delete': 'Supprimer', 'folders.typebotButton.delete': 'Supprimer',
'folders.typebotButton.deleteConfirmationMessage': 'folders.typebotButton.deleteConfirmationMessage':
'Êtes-vous sûr de vouloir supprimer votre typebot {typebotName} ?', 'Es-tu sûr de vouloir supprimer votre typebot {typebotName} ?',
'folders.typebotButton.deleteConfirmationMessageWarning': 'folders.typebotButton.deleteConfirmationMessageWarning':
'Toutes les données associées seront supprimées et ne pourront pas être récupérées.', 'Toutes les données associées seront supprimées et ne pourront pas être récupérées.',
'account.apiTokens.heading': 'Tokens API', 'account.apiTokens.heading': 'Tokens API',
'account.apiTokens.description': 'account.apiTokens.description':
"Ces tokens permettent à d'autres applications de contrôler votre compte et vos typebots. Soyez prudent !", "Ces tokens permettent à d'autres applications de contrôler ton compte et tes typebots. Prudence !",
'account.apiTokens.createButton.label': 'Créer', 'account.apiTokens.createButton.label': 'Créer',
'account.apiTokens.deleteButton.label': 'Supprimer', 'account.apiTokens.deleteButton.label': 'Supprimer',
'account.apiTokens.table.nameHeader': 'Nom', 'account.apiTokens.table.nameHeader': 'Nom',
'account.apiTokens.table.createdHeader': 'Créé', 'account.apiTokens.table.createdHeader': 'Créé',
'account.apiTokens.deleteConfirmationMessage': 'account.apiTokens.deleteConfirmationMessage':
'Le token {tokenName} sera définitivement révoqué, êtes-vous sûr de vouloir continuer ?', 'Le token {tokenName} sera définitivement révoqué, es-tu sûr de vouloir continuer ?',
'account.apiTokens.createModal.createHeading': 'Créer un token', 'account.apiTokens.createModal.createHeading': 'Créer un token',
'account.apiTokens.createModal.createdHeading': 'Token créé', 'account.apiTokens.createModal.createdHeading': 'Token créé',
'account.apiTokens.createModal.nameInput.label': 'account.apiTokens.createModal.nameInput.label':
'Entrez un nom unique pour votre token afin de le différencier des autres tokens.', 'Tape un nom unique pour votre token afin de le différencier des autres tokens.',
'account.apiTokens.createModal.nameInput.placeholder': 'account.apiTokens.createModal.nameInput.placeholder':
'Ex. Zapier, Github, Make.com', 'Ex. Zapier, Github, Make.com',
'account.apiTokens.createModal.createButton.label': 'Créer un token', 'account.apiTokens.createModal.createButton.label': 'Créer un token',
'account.apiTokens.createModal.doneButton.label': 'Terminé', 'account.apiTokens.createModal.doneButton.label': 'Terminé',
'account.apiTokens.createModal.copyInstruction': 'account.apiTokens.createModal.copyInstruction':
'Veuillez copier votre token et le stocker dans un endroit sûr.', 'Copie ton token et enregistre le dans un endroit sûr.',
'account.apiTokens.createModal.securityWarning': 'account.apiTokens.createModal.securityWarning':
'Pour des raisons de sécurité, nous ne pouvons pas le montrer à nouveau.', 'Pour des raisons de sécurité, nous ne pourrons pas le montrer à nouveau.',
'account.preferences.language.heading': 'Langue',
'account.preferences.language.tooltip':
"Les traductions ne sont pas encore complètes. C'est un travail en cours. 🤓",
'account.preferences.graphNavigation.heading': "Navigation de l'éditeur", 'account.preferences.graphNavigation.heading': "Navigation de l'éditeur",
'account.preferences.graphNavigation.mouse.label': 'Souris', 'account.preferences.graphNavigation.mouse.label': 'Souris',
'account.preferences.graphNavigation.mouse.description': 'account.preferences.graphNavigation.mouse.description':
'Déplacez en glissant et zoom en avant/arrière en utilisant la molette', 'Déplace le board en cliquant avec la souris et zoom utilisant la molette',
'account.preferences.graphNavigation.trackpad.label': 'Trackpad', 'account.preferences.graphNavigation.trackpad.label': 'Trackpad',
'account.preferences.graphNavigation.trackpad.description': 'account.preferences.graphNavigation.trackpad.description':
'Déplacez le board en utilisant 2 doigts et zoomer en avant/arrière en pincant', 'Déplace le board en déplaçant les 2 doigts et zoom pincant',
'account.preferences.appearance.heading': 'Apparence', 'account.preferences.appearance.heading': 'Apparence',
'account.preferences.appearance.systemLabel': 'Système', 'account.preferences.appearance.systemLabel': 'Système',
'account.preferences.appearance.lightLabel': 'Clair', 'account.preferences.appearance.lightLabel': 'Clair',
@ -60,35 +63,34 @@ export default defineLocale({
'account.myAccount.changePhotoButton.label': 'Changer de photo', 'account.myAccount.changePhotoButton.label': 'Changer de photo',
'account.myAccount.changePhotoButton.specification': '.jpg ou.png, max 1MB', 'account.myAccount.changePhotoButton.specification': '.jpg ou.png, max 1MB',
'account.myAccount.emailInput.disabledTooltip': 'account.myAccount.emailInput.disabledTooltip':
"La mise à jour de l'adresse e-mail n'est pas disponible. Contactez le service d'assistance si vous souhaitez la modifier.", "La mise à jour de l'adresse e-mail n'est pas disponible. Contacte le service d'assistance si tu souhaites la modifier.",
'account.myAccount.emailInput.label': 'Adresse e-mail:', 'account.myAccount.emailInput.label': 'Adresse e-mail:',
'account.myAccount.nameInput.label': 'Nom:', 'account.myAccount.nameInput.label': 'Nom:',
'analytics.viewsLabel': 'Vues', 'analytics.viewsLabel': 'Vues',
'analytics.startsLabel': 'Démarrés', 'analytics.startsLabel': 'Démarrés',
'analytics.completionRateLabel': 'Taux de complétion', 'analytics.completionRateLabel': 'Taux de complétion',
'auth.signin.heading': 'Se connecter', 'auth.signin.heading': 'Se connecter',
'auth.signin.noAccountLabel.preLink': "Vous n'avez pas de compte?", 'auth.signin.noAccountLabel.preLink': "Tu n'as pas de compte?",
'auth.signin.noAccountLabel.link': 'Inscrivez-vous gratuitement', 'auth.signin.noAccountLabel.link': 'Inscris-toi gratuitement',
'auth.register.heading': 'Créer un compte', 'auth.register.heading': 'Créer un compte',
'auth.register.alreadyHaveAccountLabel.preLink': 'Vous avez déjà un compte?', 'auth.register.alreadyHaveAccountLabel.preLink': 'Tu as déjà un compte?',
'auth.register.alreadyHaveAccountLabel.link': 'Se connecter', 'auth.register.alreadyHaveAccountLabel.link': 'Se connecter',
'auth.error.default': 'Essayez de vous connecter avec un compte différent.', 'auth.error.default': 'Essaye de te connecter avec un compte différent.',
'auth.error.email': 'auth.error.email':
'Email non trouvé. Essayez de vous connecter avec un fournisseur différent.', 'Email non trouvé. Essaye de te connecter avec un fournisseur différent.',
'auth.error.oauthNotLinked': 'auth.error.oauthNotLinked':
'Pour confirmer votre identité, connectez-vous avec le même compte que vous avez utilisé à lorigine.', 'Pour confirmer ton identité, connecte-toi avec le même compte que tu as utilisé à lorigine.',
'auth.error.unknown': 'Une erreur est survenue. Veuillez réessayer.', 'auth.error.unknown': 'Une erreur est survenue. Essaye à nouveau.',
'auth.signinErrorToast.title': 'Non autorisé', 'auth.signinErrorToast.title': 'Non autorisé',
'auth.signinErrorToast.description': 'Les inscriptions sont désactivées.', 'auth.signinErrorToast.description': 'Les inscriptions sont désactivées.',
'auth.noProvider.preLink': 'Vous avez besoin de', 'auth.noProvider.preLink': 'Tu as besoin de',
'auth.noProvider.link': 'auth.noProvider.link':
"configurer au moins un fournisseur d'authentification (E-mail, Google, GitHub, Facebook ou Azure AD).", "configurer au moins un fournisseur d'authentification (E-mail, Google, GitHub, Facebook ou Azure AD).",
'auth.orEmailLabel': 'Ou avec votre email', 'auth.orEmailLabel': 'Ou avec votre email',
'auth.emailSubmitButton.label': 'Se connecter', 'auth.emailSubmitButton.label': 'Se connecter',
'auth.magicLink.title': 'auth.magicLink.title':
"Un email avec un lien d'authentification a été envoyé. 🪄", "Un email avec un lien d'authentification a été envoyé. 🪄",
'auth.magicLink.description': 'auth.magicLink.description': "N'oublie pas de vérifier ton dossier spam.",
'Assurez-vous de vérifier votre dossier de spam.',
'auth.socialLogin.githubButton.label': 'Continuer avec GitHub', 'auth.socialLogin.githubButton.label': 'Continuer avec GitHub',
'auth.socialLogin.googleButton.label': 'Continuer avec Google', 'auth.socialLogin.googleButton.label': 'Continuer avec Google',
'auth.socialLogin.facebookButton.label': 'Continuer avec Facebook', 'auth.socialLogin.facebookButton.label': 'Continuer avec Facebook',
@ -100,12 +102,12 @@ export default defineLocale({
"Typebot contribue à hauteur de 1% de votre abonnement pour éliminer le CO₂ de l'atmosphère.", "Typebot contribue à hauteur de 1% de votre abonnement pour éliminer le CO₂ de l'atmosphère.",
'billing.contribution.link': 'En savoir plus.', 'billing.contribution.link': 'En savoir plus.',
'billing.updateSuccessToast.description': 'billing.updateSuccessToast.description':
'Votre abonnement {plan} a été mis à jour avec succès 🎉', 'Ton abonnement {plan} a été mis à jour avec succès 🎉',
'billing.customLimit.preLink': 'billing.customLimit.preLink':
'Vous avez besoin de limites personnalisées ? De fonctionnalités spécifiques ?', 'Tu as besoin de limites personnalisées ? De fonctionnalités spécifiques ?',
'billing.customLimit.link': 'Discutons-en!', 'billing.customLimit.link': 'Discutons-en!',
'billing.upgradeLimitLabel': 'billing.upgradeLimitLabel':
'Vous devez mettre à niveau votre abonnement pour {type}', 'Tu dois mettre à niveau ton abonnement pour {type}',
'billing.currentSubscription.heading': 'Abonnement', 'billing.currentSubscription.heading': 'Abonnement',
'billing.currentSubscription.subheading': 'Abonnement actuel du workspace :', 'billing.currentSubscription.subheading': 'Abonnement actuel du workspace :',
'billing.currentSubscription.cancelLink': "Annuler l'abonnement", 'billing.currentSubscription.cancelLink': "Annuler l'abonnement",
@ -127,7 +129,7 @@ export default defineLocale({
"Un chat est comptabilisé chaque fois qu'un utilisateur démarre une discussion. Il est indépendant du nombre de messages qu'il envoie et reçoit.", "Un chat est comptabilisé chaque fois qu'un utilisateur démarre une discussion. Il est indépendant du nombre de messages qu'il envoie et reçoit.",
'billing.pricingCard.storageLimit': 'Go de stockage', 'billing.pricingCard.storageLimit': 'Go de stockage',
'billing.pricingCard.storageLimitTooltip': 'billing.pricingCard.storageLimitTooltip':
"Vous accumulez du stockage pour chaque fichier que votre utilisateur télécharge dans votre bot. Si vous supprimez le résultat, cela libérera de l'espace.", "Tu accumules du stockage pour chaque fichier que ton utilisateur télécharge dans ton bot. Si tu supprimes le résultat, ça libérera de l'espace.",
'billing.pricingCard.starter.description': 'billing.pricingCard.starter.description':
'Pour les particuliers et les petites entreprises.', 'Pour les particuliers et les petites entreprises.',
'billing.pricingCard.starter.includedSeats': '2 collègues inclus', 'billing.pricingCard.starter.includedSeats': '2 collègues inclus',
@ -145,19 +147,39 @@ export default defineLocale({
'billing.usage.heading': 'Utilisation', 'billing.usage.heading': 'Utilisation',
'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.heading': 'Chats',
'billing.usage.chats.alert.soonReach': 'billing.usage.chats.alert.soonReach':
'Vos typebots sont populaires ! Vous atteindrez bientôt la limite de chats de votre abonnement. 🚀', 'Tes typebots sont populaires ! Tu atteindras bientôt la limite de chats de votre abonnement. 🚀',
'billing.usage.chats.alert.updatePlan': 'billing.usage.chats.alert.updatePlan':
'Assurez-vous de mettre à jour votre abonnement pour augmenter cette limite et continuer à discuter avec vos utilisateurs.', 'Assure-toi de mettre à jour votre abonnement pour augmenter cette limite et continuer à discuter avec vos utilisateurs.',
'billing.usage.chats.resetInfo': '(réinitialisé le 1er de chaque mois)', 'billing.usage.chats.resetInfo': '(réinitialisé le 1er de chaque mois)',
'billing.usage.storage.heading': 'Stockage', 'billing.usage.storage.heading': 'Stockage',
'billing.usage.storage.alert.soonReach': 'billing.usage.storage.alert.soonReach':
'Vos typebots sont populaires ! Vous atteindrez bientôt la limite de stockage de votre abonnement. 🚀', 'Tes typebots sont populaires ! Tu atteindras bientôt la limite de stockage de ton abonnement. 🚀',
'billing.usage.storage.alert.updatePlan': 'billing.usage.storage.alert.updatePlan':
"Assurez-vous de mettre à jour votre abonnement pour continuer à collecter des fichiers téléchargés. Vous pouvez également supprimer des fichiers pour libérer de l'espace.", "Assure-toi de mettre à jour votre abonnement pour continuer à collecter des fichiers téléchargés. Tu peux également supprimer des fichiers pour libérer de l'espace.",
'billing.limitMessage.brand': 'supprimer la marque', 'billing.limitMessage.brand': 'supprimer la marque',
'billing.limitMessage.customDomain': 'ajouter des domaines personnalisés', 'billing.limitMessage.customDomain': 'ajouter des domaines personnalisés',
'billing.limitMessage.analytics': 'débloquer des analyses approfondies', 'billing.limitMessage.analytics': 'débloquer des analyses approfondies',
'billing.limitMessage.fileInput': 'utiliser des blocs de saisie de fichiers', 'billing.limitMessage.fileInput': 'utiliser des blocs de saisie de fichiers',
'billing.limitMessage.folder': 'créer des dossiers', 'billing.limitMessage.folder': 'créer des dossiers',
'billing.upgradeAlert.buttonDefaultLabel': "Plus d'informations", 'billing.upgradeAlert.buttonDefaultLabel': "Plus d'informations",
}) 'workspace.membersList.inviteInput.placeholder': 'collegue@entreprise.fr',
'workspace.membersList.inviteButton.label': 'Inviter',
'workspace.membersList.unlockBanner.label':
"Upgrade ton plan pour travailler les membres de ton équipe et débloquer d'autres fonctionnalités puissantes 🚀",
'workspace.membersList.title': 'Membres',
'workspace.settings.icon.title': 'Icône',
'workspace.settings.name.label': 'Nom:',
'workspace.settings.deleteButton.label': 'Supprimer le workspace',
'workspace.settings.deleteButton.confirmMessage':
'Es-tu sûr(e) de vouloir supprimer le workspace {workspaceName} ? Tous ses dossiers, typebots et résultats seront supprimés pour toujours.',
'workspace.settings.modal.menu.myAccount.label': 'Mon compte',
'workspace.settings.modal.menu.preferences.label': 'Préférences',
'workspace.settings.modal.menu.workspace.label': 'Workspace',
'workspace.settings.modal.menu.settings.label': 'Paramètres',
'workspace.settings.modal.menu.members.label': 'Membres',
'workspace.settings.modal.menu.billingAndUsage.label':
'Facturation et utilisation',
'workspace.settings.modal.menu.version.label': 'Version : {version}',
'workspace.dropdown.newButton.label': 'Nouveau workspace',
'workspace.dropdown.logoutButton.label': 'Déconnexion',
} as const

View File

@ -1,13 +1,13 @@
import { createI18n } from '@typebot.io/next-international' import { createI18n } from 'next-international'
import type Locale from './en'
export const { export const {
defineLocale,
useI18n, useI18n,
useScopedI18n, useScopedI18n,
I18nProvider, I18nProvider,
getLocaleProps, getLocaleProps,
} = createI18n<typeof Locale>({ useCurrentLocale,
useChangeLocale,
} = createI18n({
en: () => import('./en'), en: () => import('./en'),
fr: () => import('./fr'), fr: () => import('./fr'),
pt: () => import('./pt'), pt: () => import('./pt'),

View File

@ -1,6 +1,4 @@
import { defineLocale } from './index' export default {
export default defineLocale({
back: 'Voltar', back: 'Voltar',
'confirmModal.defaultTitle': 'Tem certeza?', 'confirmModal.defaultTitle': 'Tem certeza?',
'dashboard.header.settingsButton.label': 'Configurações & Membros', 'dashboard.header.settingsButton.label': 'Configurações & Membros',
@ -12,6 +10,8 @@ export default defineLocale({
update: 'Atualizar', update: 'Atualizar',
upgrade: 'Upgrade', upgrade: 'Upgrade',
downgrade: 'Downgrade', downgrade: 'Downgrade',
remove: 'Remover',
pending: 'Pendente',
'folders.createFolderButton.label': 'Criar uma pasta', 'folders.createFolderButton.label': 'Criar uma pasta',
'folders.createTypebotButton.label': 'Criar um typebot', 'folders.createTypebotButton.label': 'Criar um typebot',
'folders.folderButton.deleteConfirmationMessage': 'folders.folderButton.deleteConfirmationMessage':
@ -46,6 +46,9 @@ export default defineLocale({
'Por favor, copie seu token e guarde-o em um lugar seguro.', 'Por favor, copie seu token e guarde-o em um lugar seguro.',
'account.apiTokens.createModal.securityWarning': 'account.apiTokens.createModal.securityWarning':
'Por motivos de segurança, não podemos mostrá-lo novamente.', 'Por motivos de segurança, não podemos mostrá-lo novamente.',
'account.preferences.language.heading': 'Idioma',
'account.preferences.language.tooltip':
'As traduções ainda não estão completas. É um trabalho em andamento. 🤓',
'account.preferences.graphNavigation.heading': 'Navegação do Editor', 'account.preferences.graphNavigation.heading': 'Navegação do Editor',
'account.preferences.graphNavigation.mouse.label': 'Mouse', 'account.preferences.graphNavigation.mouse.label': 'Mouse',
'account.preferences.graphNavigation.mouse.description': 'account.preferences.graphNavigation.mouse.description':
@ -161,4 +164,23 @@ export default defineLocale({
'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo', 'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo',
'billing.limitMessage.folder': 'criar pastas', 'billing.limitMessage.folder': 'criar pastas',
'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações', 'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações',
}) 'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com',
'workspace.membersList.inviteButton.label': 'Convidar',
'workspace.membersList.unlockBanner.label':
'Atualize seu plano para trabalhar com mais membros da equipe e desbloqueie recursos incríveis 🚀',
'workspace.membersList.title': 'Membros',
'workspace.settings.icon.title': 'Ícone',
'workspace.settings.name.label': 'Nome:',
'workspace.settings.deleteButton.label': 'Excluir espaço de trabalho',
'workspace.settings.deleteButton.confirmMessage':
'Você tem certeza de que deseja excluir o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.',
'workspace.settings.modal.menu.myAccount.label': 'Minha conta',
'workspace.settings.modal.menu.preferences.label': 'Preferências',
'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho',
'workspace.settings.modal.menu.settings.label': 'Configurações',
'workspace.settings.modal.menu.members.label': 'Membros',
'workspace.settings.modal.menu.billingAndUsage.label': 'Faturamento e uso',
'workspace.settings.modal.menu.version.label': 'Versão: {version}',
'workspace.dropdown.newButton.label': 'Novo espaço de trabalho',
'workspace.dropdown.logoutButton.label': 'Sair',
} as const

View File

@ -19,6 +19,7 @@ import { I18nProvider } from '@/locales'
import { TypebotProvider } from '@/features/editor/providers/TypebotProvider' import { TypebotProvider } from '@/features/editor/providers/TypebotProvider'
import { WorkspaceProvider } from '@/features/workspace/WorkspaceProvider' import { WorkspaceProvider } from '@/features/workspace/WorkspaceProvider'
import { isCloudProdInstance } from '@/helpers/isCloudProdInstance' import { isCloudProdInstance } from '@/helpers/isCloudProdInstance'
import en from '@/locales/en'
const { ToastContainer, toast } = createStandaloneToast(customTheme) const { ToastContainer, toast } = createStandaloneToast(customTheme)

View File

@ -2601,6 +2601,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -2928,6 +2931,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -3093,6 +3099,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -3182,6 +3191,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [

View File

@ -2214,6 +2214,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -2541,6 +2544,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -2706,6 +2712,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -2795,6 +2804,9 @@
}, },
"isCustomBody": { "isCustomBody": {
"type": "boolean" "type": "boolean"
},
"isExecutedOnClient": {
"type": "boolean"
} }
}, },
"required": [ "required": [
@ -4322,92 +4334,171 @@
{ {
"anyOf": [ "anyOf": [
{ {
"type": "object", "anyOf": [
"properties": { {
"scriptToExecute": {
"type": "object", "type": "object",
"properties": { "properties": {
"content": { "scriptToExecute": {
"type": "string" "type": "object",
}, "properties": {
"args": { "content": {
"type": "array", "type": "string"
"items": { },
"type": "object", "args": {
"properties": { "type": "array",
"id": { "items": {
"type": "string" "type": "object",
}, "properties": {
"value": { "id": {
"anyOf": [ "type": "string"
{ },
"value": {
"anyOf": [ "anyOf": [
{ {
"anyOf": [ "anyOf": [
{ {
"type": "string" "anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
}, },
{ {
"type": "number" "type": "boolean"
} }
] ]
}, },
{ {
"type": "boolean" "type": "array",
"items": {
"type": "string",
"nullable": true
}
} }
] ],
}, "nullable": true
{
"type": "array",
"items": {
"type": "string",
"nullable": true
}
} }
},
"required": [
"id"
], ],
"nullable": true "additionalProperties": false
} }
}, }
"required": [ },
"id" "required": [
], "content",
"additionalProperties": false "args"
} ],
"additionalProperties": false
} }
}, },
"required": [ "required": [
"content", "scriptToExecute"
"args" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"redirect": {
"type": "object",
"properties": {
"url": {
"type": "string"
},
"isNewTab": {
"type": "boolean"
}
},
"required": [
"isNewTab"
],
"additionalProperties": false
}
},
"required": [
"redirect"
], ],
"additionalProperties": false "additionalProperties": false
} }
}, ]
"required": [
"scriptToExecute"
],
"additionalProperties": false
}, },
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"redirect": { "chatwoot": {
"type": "object", "type": "object",
"properties": { "properties": {
"url": { "scriptToExecute": {
"type": "string" "type": "object",
}, "properties": {
"isNewTab": { "content": {
"type": "boolean" "type": "string"
},
"args": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"value": {
"anyOf": [
{
"anyOf": [
{
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
},
{
"type": "boolean"
}
]
},
{
"type": "array",
"items": {
"type": "string",
"nullable": true
}
}
],
"nullable": true
}
},
"required": [
"id"
],
"additionalProperties": false
}
}
},
"required": [
"content",
"args"
],
"additionalProperties": false
} }
}, },
"required": [ "required": [
"isNewTab" "scriptToExecute"
], ],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"redirect" "chatwoot"
], ],
"additionalProperties": false "additionalProperties": false
} }
@ -4416,75 +4507,38 @@
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"chatwoot": { "googleAnalytics": {
"type": "object", "type": "object",
"properties": { "properties": {
"scriptToExecute": { "trackingId": {
"type": "object", "type": "string"
"properties": { },
"content": { "category": {
"type": "string" "type": "string"
},
"action": {
"type": "string"
},
"label": {
"type": "string"
},
"value": {
"anyOf": [
{
"type": "number"
}, },
"args": { {}
"type": "array", ]
"items": { },
"type": "object", "sendTo": {
"properties": { "type": "string"
"id": {
"type": "string"
},
"value": {
"anyOf": [
{
"anyOf": [
{
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
},
{
"type": "boolean"
}
]
},
{
"type": "array",
"items": {
"type": "string",
"nullable": true
}
}
],
"nullable": true
}
},
"required": [
"id"
],
"additionalProperties": false
}
}
},
"required": [
"content",
"args"
],
"additionalProperties": false
} }
}, },
"required": [
"scriptToExecute"
],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"chatwoot" "googleAnalytics"
], ],
"additionalProperties": false "additionalProperties": false
} }
@ -4493,38 +4547,21 @@
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"googleAnalytics": { "wait": {
"type": "object", "type": "object",
"properties": { "properties": {
"trackingId": { "secondsToWaitFor": {
"type": "string" "type": "number"
},
"category": {
"type": "string"
},
"action": {
"type": "string"
},
"label": {
"type": "string"
},
"value": {
"anyOf": [
{
"type": "number"
},
{}
]
},
"sendTo": {
"type": "string"
} }
}, },
"required": [
"secondsToWaitFor"
],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"googleAnalytics" "wait"
], ],
"additionalProperties": false "additionalProperties": false
} }
@ -4533,21 +4570,75 @@
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"wait": { "setVariable": {
"type": "object", "type": "object",
"properties": { "properties": {
"secondsToWaitFor": { "scriptToExecute": {
"type": "number" "type": "object",
"properties": {
"content": {
"type": "string"
},
"args": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"value": {
"anyOf": [
{
"anyOf": [
{
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
},
{
"type": "boolean"
}
]
},
{
"type": "array",
"items": {
"type": "string",
"nullable": true
}
}
],
"nullable": true
}
},
"required": [
"id"
],
"additionalProperties": false
}
}
},
"required": [
"content",
"args"
],
"additionalProperties": false
} }
}, },
"required": [ "required": [
"secondsToWaitFor" "scriptToExecute"
], ],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"wait" "setVariable"
], ],
"additionalProperties": false "additionalProperties": false
} }
@ -4556,75 +4647,38 @@
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"setVariable": { "streamOpenAiChatCompletion": {
"type": "object", "type": "object",
"properties": { "properties": {
"scriptToExecute": { "messages": {
"type": "object", "type": "array",
"properties": { "items": {
"content": { "type": "object",
"type": "string" "properties": {
}, "content": {
"args": { "type": "string"
"type": "array", },
"items": { "role": {
"type": "object", "type": "string",
"properties": { "enum": [
"id": { "system",
"type": "string" "user",
}, "assistant"
"value": { ]
"anyOf": [
{
"anyOf": [
{
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
},
{
"type": "boolean"
}
]
},
{
"type": "array",
"items": {
"type": "string",
"nullable": true
}
}
],
"nullable": true
}
},
"required": [
"id"
],
"additionalProperties": false
} }
} },
}, "additionalProperties": false
"required": [ }
"content",
"args"
],
"additionalProperties": false
} }
}, },
"required": [ "required": [
"scriptToExecute" "messages"
], ],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"setVariable" "streamOpenAiChatCompletion"
], ],
"additionalProperties": false "additionalProperties": false
} }
@ -4633,38 +4687,42 @@
{ {
"type": "object", "type": "object",
"properties": { "properties": {
"streamOpenAiChatCompletion": { "webhookToExecute": {
"type": "object", "type": "object",
"properties": { "properties": {
"messages": { "url": {
"type": "array", "type": "string"
"items": { },
"type": "object", "headers": {
"properties": { "type": "object",
"content": { "additionalProperties": {
"type": "string" "type": "string"
},
"role": {
"type": "string",
"enum": [
"system",
"user",
"assistant"
]
}
},
"additionalProperties": false
} }
},
"body": {},
"method": {
"type": "string",
"enum": [
"POST",
"GET",
"PUT",
"DELETE",
"PATCH",
"HEAD",
"CONNECT",
"OPTIONS",
"TRACE"
]
} }
}, },
"required": [ "required": [
"messages" "url"
], ],
"additionalProperties": false "additionalProperties": false
} }
}, },
"required": [ "required": [
"streamOpenAiChatCompletion" "webhookToExecute"
], ],
"additionalProperties": false "additionalProperties": false
} }

5497
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff