2
0

Add editor header translation keys (#1110)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Implemented internationalization support across various components
using the `useTranslate` function for dynamic content translation.

- **Enhancements**
- Updated UI elements such as buttons, tooltips, placeholders, and
labels to display translated text, improving accessibility and user
experience for non-English speakers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Baptiste Arnaud <contact@baptiste-arnaud.fr>
Co-authored-by: Baptiste Arnaud <baptiste.arnaud95@gmail.com>
This commit is contained in:
Gabriel Pavão
2023-12-28 06:50:33 -03:00
committed by GitHub
parent 74f5a17de0
commit d42e4a9ce1
38 changed files with 520 additions and 199 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh" . "$(dirname -- "$0")/_/husky.sh"
pnpm lint pnpm lint && pnpm format:fix

View File

@ -0,0 +1,2 @@
emojiList.json
iconNames.ts

View File

@ -8,7 +8,8 @@
"start": "dotenv -e ./.env -e ../../.env -- next start", "start": "dotenv -e ./.env -e ../../.env -- next start",
"lint": "dotenv -e ./.env -e ../../.env -- next lint", "lint": "dotenv -e ./.env -e ../../.env -- next lint",
"test": "dotenv -e ./.env -e ../../.env -- pnpm playwright test", "test": "dotenv -e ./.env -e ../../.env -- pnpm playwright test",
"test:show-report": "pnpm playwright show-report src/test/reporters" "test:show-report": "pnpm playwright show-report src/test/reporters",
"format:fix": "prettier --write ./src"
}, },
"dependencies": { "dependencies": {
"@chakra-ui/anatomy": "2.1.1", "@chakra-ui/anatomy": "2.1.1",

View File

@ -150,14 +150,14 @@
"editor.gettingStartedModal.seeAction.item.label": "Weitere Videos", "editor.gettingStartedModal.seeAction.item.label": "Weitere Videos",
"editor.gettingStartedModal.seeAction.label": "In Aktion sehen", "editor.gettingStartedModal.seeAction.label": "In Aktion sehen",
"editor.gettingStartedModal.seeAction.time": "5 Minuten", "editor.gettingStartedModal.seeAction.time": "5 Minuten",
"editor.headers.flowButton.label": "Ablauf", "editor.header.flowButton.label": "Ablauf",
"editor.headers.helpButton.label": "Hilfe", "editor.header.helpButton.label": "Hilfe",
"editor.headers.previewButton.label": "Vorschau", "editor.header.previewButton.label": "Vorschau",
"editor.headers.resultsButton.label": "Ergebnisse", "editor.header.resultsButton.label": "Ergebnisse",
"editor.headers.savingSpinner.label": "Speichern...", "editor.header.savingSpinner.label": "Speichern...",
"editor.headers.settingsButton.label": "Einstellungen", "editor.header.settingsButton.label": "Einstellungen",
"editor.headers.shareButton.label": "Teilen", "share.button.label": "Teilen",
"editor.headers.themeButton.label": "Design", "editor.header.themeButton.label": "Design",
"editor.sidebarBlock.abTest.label": "AB-Test", "editor.sidebarBlock.abTest.label": "AB-Test",
"editor.sidebarBlock.analytics.label": "Analytics", "editor.sidebarBlock.analytics.label": "Analytics",
"editor.sidebarBlock.audio.label": "Audio", "editor.sidebarBlock.audio.label": "Audio",

View File

@ -117,7 +117,24 @@
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets", "blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Cancel", "cancel": "Cancel",
"clickToEdit": "Click to edit...", "clickToEdit": "Click to edit...",
"collaboration.roles.edit.label": "Can edit",
"collaboration.roles.full.label": "Full access",
"collaboration.roles.view.label": "Can view",
"confirmModal.defaultTitle": "Are you sure?", "confirmModal.defaultTitle": "Are you sure?",
"emojiList.categories.activities.label": "ACTIVITIES",
"emojiList.categories.animalsAndNature.label": "ANIMALS & NATURE",
"emojiList.categories.flags.label": "FLAGS",
"emojiList.categories.foodAndDrink.label": "FOOD & DRINK",
"emojiList.categories.objects.label": "OBJECTS",
"emojiList.categories.people.label": "PEOPLE",
"emojiList.categories.recent.label": "RECENT",
"emojiList.categories.symbols.label": "SYMBOLS",
"emojiList.categories.travelAndPlaces.label": "TRAVEL & PLACES",
"emojiList.searchInput.placeholder": "Search...",
"variables.button.tooltip": "Insert a variable",
"variables.button.searchInput.placeholder": "Search for a variable",
"copy": "Copy",
"copied": "Copied",
"dashboard.header.settingsButton.label": "Settings & Members", "dashboard.header.settingsButton.label": "Settings & Members",
"dashboard.redirectionMessage": "You are being redirected...", "dashboard.redirectionMessage": "You are being redirected...",
"dashboard.title": "My typebots", "dashboard.title": "My typebots",
@ -140,7 +157,13 @@
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Link alt text (description)", "editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Link alt text (description)",
"editor.blocks.bubbles.textEditor.plate.label": "Text editor", "editor.blocks.bubbles.textEditor.plate.label": "Text editor",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Search for a variable", "editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Search for a variable",
"editor.graph.menu.documentationItem.label": "Documentation",
"editor.graph.menu.editorSettingsItem.label": "Editor settings",
"editor.graph.menu.exportFlowItem.label": "Export flow",
"editor.blocks.start.text": "Start", "editor.blocks.start.text": "Start",
"editor.header.linkTab.searchInputPlaceholder.label": "Paste the image link...",
"editor.header.tooltip.changeIcon.label": "Change icon",
"editor.header.uploadTab.uploadButton.label": "Choose an image",
"editor.editableTypebotName.tooltip.rename.label": "Rename", "editor.editableTypebotName.tooltip.rename.label": "Rename",
"editor.gettingStartedModal.editorBasics.heading": "Editor Basics", "editor.gettingStartedModal.editorBasics.heading": "Editor Basics",
"editor.gettingStartedModal.editorBasics.list.four.label": "Preview your bot by clicking the test button on the top right", "editor.gettingStartedModal.editorBasics.list.four.label": "Preview your bot by clicking the test button on the top right",
@ -151,14 +174,42 @@
"editor.gettingStartedModal.seeAction.item.label": "Other videos", "editor.gettingStartedModal.seeAction.item.label": "Other videos",
"editor.gettingStartedModal.seeAction.label": "See it in action", "editor.gettingStartedModal.seeAction.label": "See it in action",
"editor.gettingStartedModal.seeAction.time": "5 minutes", "editor.gettingStartedModal.seeAction.time": "5 minutes",
"editor.headers.flowButton.label": "Flow", "editor.header.flowButton.label": "Flow",
"editor.headers.helpButton.label": "Help", "editor.header.helpButton.label": "Help",
"editor.headers.previewButton.label": "Test", "editor.header.previewButton.label": "Test",
"editor.headers.resultsButton.label": "Results", "publishButton.closed.label": "Closed",
"editor.headers.savingSpinner.label": "Saving...", "publishButton.label": "Publish",
"editor.headers.settingsButton.label": "Settings", "publishButton.tooltip.nonPublishedChanges.label": "There are non published changes.",
"editor.headers.shareButton.label": "Share", "publishButton.tooltip.publishedVersion.from.label": "Published version from",
"editor.headers.themeButton.label": "Theme", "publishButton.tooltip.publishedVersion.ago.label": "ago",
"publishButton.published.label": "Published",
"publishButton.dropdown.close.label": "Close typebot to new responses",
"publishButton.dropdown.reopen.label": "Reopen typebot to new responses",
"publishButton.dropdown.showMenu.label": "Show published typebot menu",
"publishButton.dropdown.unpublish.label": "Unpublish typebot",
"publish.versionWarning.title.label": "⚠️ New engine version",
"publish.versionWarning.message.aboutToDeploy.label": "You are about to a deploy a version of your bot with an updated engine. (Typebot V6).",
"publish.versionWarning.message.check.label": "Make sure to check out all the",
"publish.versionWarning.message.breakingChanges.label": "associated breaking changes",
"publish.versionWarning.message.testInPreviewMode.label": "Then test, the bot thoroughly in preview mode before publishing.",
"publish.error.label": "Error while publishing typebot",
"publishButton.dropdown.restoreVersion.label": "Restore published version",
"editor.header.redoButton.label": "Redo",
"editor.header.resultsButton.label": "Results",
"editor.header.savingSpinner.label": "Saving...",
"editor.header.settingsButton.label": "Settings",
"share.button.label": "Share",
"share.button.popover.ariaLabel": "Open share popover",
"share.button.popover.collaboratorsFetch.error.label": "Couldn't fetch collaborators",
"share.button.popover.invitationsFetch.error.label": "Couldn't fetch invitations",
"share.button.popover.invitationSent.successToast.label": "Invitation sent! 📧",
"share.button.popover.inviteButton.label": "Invite",
"share.button.popover.inviteInput.placeholder": "colleague@company.com",
"share.button.popover.publicFlow.label": "Make the flow publicly available",
"editor.header.themeButton.label": "Theme",
"editor.header.undo.tooltip.label": "Changes reverted!",
"editor.header.undoButton.label": "Undo",
"editor.header.unpublishTypebot.error.label": "Error while unpublishing typebot",
"editor.sidebarBlock.abTest.label": "AB Test", "editor.sidebarBlock.abTest.label": "AB Test",
"editor.sidebarBlock.analytics.label": "Analytics", "editor.sidebarBlock.analytics.label": "Analytics",
"editor.sidebarBlock.audio.label": "Audio", "editor.sidebarBlock.audio.label": "Audio",
@ -213,6 +264,7 @@
"folders.typebotButton.showMoreOptions": "Show more options", "folders.typebotButton.showMoreOptions": "Show more options",
"folders.typebotButton.unpublish": "Unpublish", "folders.typebotButton.unpublish": "Unpublish",
"pending": "Pending", "pending": "Pending",
"preview.restartButton.label": "Restart",
"remove": "Remove", "remove": "Remove",
"skip": "Skip", "skip": "Skip",
"templates.buttons.fromScratchButton.label": "Start from scratch", "templates.buttons.fromScratchButton.label": "Start from scratch",

View File

@ -151,14 +151,14 @@
"editor.gettingStartedModal.seeAction.item.label": "Otros videos", "editor.gettingStartedModal.seeAction.item.label": "Otros videos",
"editor.gettingStartedModal.seeAction.label": "Verlo en acción", "editor.gettingStartedModal.seeAction.label": "Verlo en acción",
"editor.gettingStartedModal.seeAction.time": "5 minutos", "editor.gettingStartedModal.seeAction.time": "5 minutos",
"editor.headers.flowButton.label": "Flujo", "editor.header.flowButton.label": "Flujo",
"editor.headers.helpButton.label": "Ayuda", "editor.header.helpButton.label": "Ayuda",
"editor.headers.previewButton.label": "Previsualización", "editor.header.previewButton.label": "Previsualización",
"editor.headers.resultsButton.label": "Resultados", "editor.header.resultsButton.label": "Resultados",
"editor.headers.savingSpinner.label": "Guardando...", "editor.header.savingSpinner.label": "Guardando...",
"editor.headers.settingsButton.label": "Configuración", "editor.header.settingsButton.label": "Configuración",
"editor.headers.shareButton.label": "Compartir", "share.button.label": "Compartir",
"editor.headers.themeButton.label": "Tema", "editor.header.themeButton.label": "Tema",
"editor.sidebarBlock.abTest.label": "Prueba A/B", "editor.sidebarBlock.abTest.label": "Prueba A/B",
"editor.sidebarBlock.analytics.label": "Análisis", "editor.sidebarBlock.analytics.label": "Análisis",
"editor.sidebarBlock.audio.label": "Audio", "editor.sidebarBlock.audio.label": "Audio",

View File

@ -151,14 +151,14 @@
"editor.gettingStartedModal.seeAction.item.label": "Autres vidéos", "editor.gettingStartedModal.seeAction.item.label": "Autres vidéos",
"editor.gettingStartedModal.seeAction.label": "Voir en action", "editor.gettingStartedModal.seeAction.label": "Voir en action",
"editor.gettingStartedModal.seeAction.time": "5 minutes", "editor.gettingStartedModal.seeAction.time": "5 minutes",
"editor.headers.flowButton.label": "Flow", "editor.header.flowButton.label": "Flow",
"editor.headers.helpButton.label": "Aide", "editor.header.helpButton.label": "Aide",
"editor.headers.previewButton.label": "Tester", "editor.header.previewButton.label": "Tester",
"editor.headers.resultsButton.label": "Résultats", "editor.header.resultsButton.label": "Résultats",
"editor.headers.savingSpinner.label": "Enregistrement...", "editor.header.savingSpinner.label": "Enregistrement...",
"editor.headers.settingsButton.label": "Paramètres", "editor.header.settingsButton.label": "Paramètres",
"editor.headers.shareButton.label": "Partage", "share.button.label": "Partage",
"editor.headers.themeButton.label": "Thème", "editor.header.themeButton.label": "Thème",
"editor.sidebarBlock.abTest.label": "AB Test", "editor.sidebarBlock.abTest.label": "AB Test",
"editor.sidebarBlock.analytics.label": "Analytics", "editor.sidebarBlock.analytics.label": "Analytics",
"editor.sidebarBlock.audio.label": "Audio", "editor.sidebarBlock.audio.label": "Audio",

View File

@ -117,7 +117,24 @@
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets", "blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Cancelar", "cancel": "Cancelar",
"clickToEdit": "Clique para editar...", "clickToEdit": "Clique para editar...",
"collaboration.roles.edit.label": "Pode editar",
"collaboration.roles.full.label": "Acesso Total",
"collaboration.roles.view.label": "Pode ver",
"confirmModal.defaultTitle": "Tem certeza?", "confirmModal.defaultTitle": "Tem certeza?",
"emojiList.categories.activities.label": "ATIVIDADES",
"emojiList.categories.animalsAndNature.label": "ANIMAIS & NATUREZA",
"emojiList.categories.flags.label": "BANDEIRAS",
"emojiList.categories.foodAndDrink.label": "COMIDA & BEBIDA",
"emojiList.categories.objects.label": "OBJETOS",
"emojiList.categories.people.label": "PESSOAS",
"emojiList.categories.recent.label": "RECENTE",
"emojiList.categories.symbols.label": "SÍMBOLOS",
"emojiList.categories.travelAndPlaces.label": "VIAJEM E LUGARES",
"emojiList.searchInput.placeholder": "Buscar...",
"variables.button.tooltip": "Insira uma variável",
"variables.button.searchInput.placeholder": "Procure por uma variável",
"copy": "Copiar",
"copied": "Copiado",
"dashboard.header.settingsButton.label": "Configurações & Membros", "dashboard.header.settingsButton.label": "Configurações & Membros",
"dashboard.redirectionMessage": "Você está sendo redirecionado...", "dashboard.redirectionMessage": "Você está sendo redirecionado...",
"dashboard.title": "Meus typebots", "dashboard.title": "Meus typebots",
@ -140,7 +157,13 @@
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Texto alternativo do link (descrição)", "editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Texto alternativo do link (descrição)",
"editor.blocks.bubbles.textEditor.plate.label": "Editor de texto", "editor.blocks.bubbles.textEditor.plate.label": "Editor de texto",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Pesquisar uma variável", "editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Pesquisar uma variável",
"editor.graph.menu.documentationItem.label": "Documentação",
"editor.graph.menu.editorSettingsItem.label": "Configurações do editor",
"editor.graph.menu.exportFlowItem.label": "Exportar fluxo",
"editor.blocks.start.text": "Início", "editor.blocks.start.text": "Início",
"editor.header.linkTab.searchInputPlaceholder.label": "Cole o link da imagem...",
"editor.header.tooltip.changeIcon.label": "Alterar Ícone",
"editor.header.uploadTab.uploadButton.label": "Escolha uma imagem",
"editor.editableTypebotName.tooltip.rename.label": "Renomear", "editor.editableTypebotName.tooltip.rename.label": "Renomear",
"editor.gettingStartedModal.editorBasics.heading": "Fundamentos do Editor", "editor.gettingStartedModal.editorBasics.heading": "Fundamentos do Editor",
"editor.gettingStartedModal.editorBasics.list.four.label": "Pré-visualize o seu bot ao clicar no botão de visualizar no canto superior direito", "editor.gettingStartedModal.editorBasics.list.four.label": "Pré-visualize o seu bot ao clicar no botão de visualizar no canto superior direito",
@ -151,14 +174,42 @@
"editor.gettingStartedModal.seeAction.item.label": "Outros vídeos", "editor.gettingStartedModal.seeAction.item.label": "Outros vídeos",
"editor.gettingStartedModal.seeAction.label": "Veja como funciona em", "editor.gettingStartedModal.seeAction.label": "Veja como funciona em",
"editor.gettingStartedModal.seeAction.time": "5 minutos", "editor.gettingStartedModal.seeAction.time": "5 minutos",
"editor.headers.flowButton.label": "Fluxo", "editor.header.flowButton.label": "Fluxo",
"editor.headers.helpButton.label": "Ajuda", "editor.header.helpButton.label": "Ajuda",
"editor.headers.previewButton.label": "Visualizar", "editor.header.previewButton.label": "Visualizar",
"editor.headers.resultsButton.label": "Resultados", "publishButton.label": "Publicar",
"editor.headers.savingSpinner.label": "Salvando...", "publishButton.closed.label": "Fechado",
"editor.headers.settingsButton.label": "Configurações", "publishButton.tooltip.nonPublishedChanges.label": "Existem alterações não publicadas.",
"editor.headers.shareButton.label": "Compartilhar", "publishButton.tooltip.publishedVersion.from.label": "Versão publicada de",
"editor.headers.themeButton.label": "Tema", "publishButton.tooltip.publishedVersion.ago.label": "atrás",
"publishButton.published.label": "Publicado",
"publishButton.dropdown.close.label": "Fechar typebot para novas respostas",
"publishButton.dropdown.reopen.label": "Reabrir typebot para novas respostas",
"publishButton.dropdown.showMenu.label": "Mostrar menu de typebot publicado",
"publishButton.dropdown.unpublish.label": "Despublicar typebot",
"publish.versionWarning.title.label": "⚠️ Nova versão da engine",
"publish.versionWarning.message.aboutToDeploy.label": "Você está prestes a fazer o deploy de uma versão do seu bot com uma engine atualizada. (Typebot V6).",
"publish.versionWarning.message.check.label": "Assegure-se de verificar todos as",
"publish.versionWarning.message.breakingChanges.label": "significativas alterações associadas",
"publish.versionWarning.message.testInPreviewMode.label": "Em seguida, teste o bot completamente no modo de visualização antes de publicar.",
"publish.error.label": "Erro durante a publicação do typebot",
"publishButton.dropdown.restoreVersion.label": "Restaurar versão publicada",
"editor.header.redoButton.label": "Refazer",
"editor.header.resultsButton.label": "Resultados",
"editor.header.savingSpinner.label": "Salvando...",
"editor.header.settingsButton.label": "Configurações",
"share.button.label": "Compartilhar",
"share.button.popover.ariaLabel": "Abrir popover de compartilhamento",
"share.button.popover.collaboratorsFetch.error.label": "Falha ao buscar os colaboradores",
"share.button.popover.invitationsFetch.error.label": "Falha ao buscar os convites",
"share.button.popover.invitationSent.successToast.label": "Convite enviado! 📧",
"share.button.popover.inviteButton.label": "Convidar",
"share.button.popover.inviteInput.placeholder": "colega@empresa.com",
"share.button.popover.publicFlow.label": "Disponibilizar o fluxo publicamente",
"editor.header.themeButton.label": "Tema",
"editor.header.undo.tooltip.label": "Alterações revertidas Changes reverted!",
"editor.header.undoButton.label": "Desfazer",
"editor.header.unpublishTypebot.error.label": "Erro durante a despublicação do typebot",
"editor.sidebarBlock.abTest.label": "Teste AB", "editor.sidebarBlock.abTest.label": "Teste AB",
"editor.sidebarBlock.analytics.label": "Analytics", "editor.sidebarBlock.analytics.label": "Analytics",
"editor.sidebarBlock.audio.label": "Áudio", "editor.sidebarBlock.audio.label": "Áudio",
@ -213,6 +264,7 @@
"folders.typebotButton.showMoreOptions": "Mostrar mais opções", "folders.typebotButton.showMoreOptions": "Mostrar mais opções",
"folders.typebotButton.unpublish": "Despublicar", "folders.typebotButton.unpublish": "Despublicar",
"pending": "Pendente", "pending": "Pendente",
"preview.restartButton.label": "Reiniciar",
"remove": "Remover", "remove": "Remover",
"skip": "Pular", "skip": "Pular",
"templates.buttons.fromScratchButton.label": "Comece do zero", "templates.buttons.fromScratchButton.label": "Comece do zero",

View File

@ -151,14 +151,14 @@
"editor.gettingStartedModal.seeAction.item.label": "Outros vídeos", "editor.gettingStartedModal.seeAction.item.label": "Outros vídeos",
"editor.gettingStartedModal.seeAction.label": "Veja o funcionamento em", "editor.gettingStartedModal.seeAction.label": "Veja o funcionamento em",
"editor.gettingStartedModal.seeAction.time": "5 minutos", "editor.gettingStartedModal.seeAction.time": "5 minutos",
"editor.headers.flowButton.label": "Fluxo", "editor.header.flowButton.label": "Fluxo",
"editor.headers.helpButton.label": "Ajuda", "editor.header.helpButton.label": "Ajuda",
"editor.headers.previewButton.label": "Visualizar", "editor.header.previewButton.label": "Visualizar",
"editor.headers.resultsButton.label": "Resultados", "editor.header.resultsButton.label": "Resultados",
"editor.headers.savingSpinner.label": "Salvando...", "editor.header.savingSpinner.label": "Salvando...",
"editor.headers.settingsButton.label": "Configurações", "editor.header.settingsButton.label": "Configurações",
"editor.headers.shareButton.label": "Compartilhar", "share.button.label": "Compartilhar",
"editor.headers.themeButton.label": "Tema", "editor.header.themeButton.label": "Tema",
"editor.sidebarBlock.abTest.label": "Teste AB", "editor.sidebarBlock.abTest.label": "Teste AB",
"editor.sidebarBlock.analytics.label": "Analytics", "editor.sidebarBlock.analytics.label": "Analytics",
"editor.sidebarBlock.audio.label": "Áudio", "editor.sidebarBlock.audio.label": "Áudio",

View File

@ -151,14 +151,14 @@
"editor.gettingStartedModal.seeAction.item.label": "Alte videoclipuri", "editor.gettingStartedModal.seeAction.item.label": "Alte videoclipuri",
"editor.gettingStartedModal.seeAction.label": "Vedeți-l în acțiune", "editor.gettingStartedModal.seeAction.label": "Vedeți-l în acțiune",
"editor.gettingStartedModal.seeAction.time": "5 minute", "editor.gettingStartedModal.seeAction.time": "5 minute",
"editor.headers.flowButton.label": "curgere", "editor.header.flowButton.label": "curgere",
"editor.headers.helpButton.label": "Ajutor", "editor.header.helpButton.label": "Ajutor",
"editor.headers.previewButton.label": "previzualizare", "editor.header.previewButton.label": "previzualizare",
"editor.headers.resultsButton.label": "Rezultate", "editor.header.resultsButton.label": "Rezultate",
"editor.headers.savingSpinner.label": "Salvare...", "editor.header.savingSpinner.label": "Salvare...",
"editor.headers.settingsButton.label": "Setări", "editor.header.settingsButton.label": "Setări",
"editor.headers.shareButton.label": "Acțiune", "share.button.label": "Acțiune",
"editor.headers.themeButton.label": "Temă", "editor.header.themeButton.label": "Temă",
"editor.sidebarBlock.abTest.label": "Testul AB", "editor.sidebarBlock.abTest.label": "Testul AB",
"editor.sidebarBlock.analytics.label": "Analitica", "editor.sidebarBlock.analytics.label": "Analitica",
"editor.sidebarBlock.audio.label": "Audio", "editor.sidebarBlock.audio.label": "Audio",

View File

@ -24,9 +24,9 @@
} */ } */
/*Hide track timeline in audio tag in Windows*/ /*Hide track timeline in audio tag in Windows*/
audio::-webkit-media-controls-timeline{ audio::-webkit-media-controls-timeline {
display:none; display: none;
} }
audio::-webkit-media-controls-panel{ audio::-webkit-media-controls-panel {
justify-content:space-between; justify-content: space-between;
} }

View File

@ -1,5 +1,6 @@
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { ButtonProps, Button, useClipboard } from '@chakra-ui/react' import { ButtonProps, Button, useClipboard } from '@chakra-ui/react'
import { useTranslate } from '@tolgee/react'
interface CopyButtonProps extends ButtonProps { interface CopyButtonProps extends ButtonProps {
textToCopy: string textToCopy: string
@ -13,6 +14,7 @@ interface CopyButtonProps extends ButtonProps {
export const CopyButton = (props: CopyButtonProps) => { export const CopyButton = (props: CopyButtonProps) => {
const { textToCopy, onCopied, ...buttonProps } = props const { textToCopy, onCopied, ...buttonProps } = props
const { hasCopied, onCopy, setValue } = useClipboard(textToCopy) const { hasCopied, onCopy, setValue } = useClipboard(textToCopy)
const { t } = useTranslate()
useEffect(() => { useEffect(() => {
setValue(textToCopy) setValue(textToCopy)
@ -27,7 +29,9 @@ export const CopyButton = (props: CopyButtonProps) => {
}} }}
{...buttonProps} {...buttonProps}
> >
{!hasCopied ? props.text?.copy ?? 'Copy' : props.text?.copied ?? 'Copied'} {!hasCopied
? props.text?.copy ?? t('copy')
: props.text?.copied ?? t('copied')}
</Button> </Button>
) )
} }

View File

@ -11,6 +11,7 @@ import React from 'react'
import { EmojiOrImageIcon } from './EmojiOrImageIcon' import { EmojiOrImageIcon } from './EmojiOrImageIcon'
import { ImageUploadContent } from './ImageUploadContent' import { ImageUploadContent } from './ImageUploadContent'
import { FilePathUploadProps } from '@/features/upload/api/generateUploadUrl' import { FilePathUploadProps } from '@/features/upload/api/generateUploadUrl'
import { useTranslate } from '@tolgee/react'
type Props = { type Props = {
uploadFileProps: FilePathUploadProps uploadFileProps: FilePathUploadProps
@ -25,13 +26,14 @@ export const EditableEmojiOrImageIcon = ({
onChangeIcon, onChangeIcon,
boxSize, boxSize,
}: Props) => { }: Props) => {
const { t } = useTranslate()
const bg = useColorModeValue('gray.100', 'gray.700') const bg = useColorModeValue('gray.100', 'gray.700')
return ( return (
<Popover isLazy> <Popover isLazy>
{({ onClose }: { onClose: () => void }) => ( {({ onClose }: { onClose: () => void }) => (
<> <>
<Tooltip label="Change icon"> <Tooltip label={t('editor.header.tooltip.changeIcon.label')}>
<Flex <Flex
cursor="pointer" cursor="pointer"
p="2" p="2"

View File

@ -11,6 +11,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
import { iconNames } from './iconNames' import { iconNames } from './iconNames'
import { TextInput } from '../inputs' import { TextInput } from '../inputs'
import { ColorPicker } from '../ColorPicker' import { ColorPicker } from '../ColorPicker'
import { useTranslate } from '@tolgee/react'
const batchSize = 200 const batchSize = 200
@ -39,6 +40,7 @@ export const IconPicker = ({ onIconSelected }: Props) => {
[initialIconColor, selectedColor] [initialIconColor, selectedColor]
) )
const [recentIconNames, setRecentIconNames] = useState([]) const [recentIconNames, setRecentIconNames] = useState([])
const { t } = useTranslate()
useEffect(() => { useEffect(() => {
const recentIconNames = localStorage.getItem(localStorageRecentIconNamesKey) const recentIconNames = localStorage.getItem(localStorageRecentIconNamesKey)
@ -105,7 +107,7 @@ export const IconPicker = ({ onIconSelected }: Props) => {
<Stack> <Stack>
<HStack> <HStack>
<TextInput <TextInput
placeholder="Search..." placeholder={t('emojiList.searchInput.placeholder')}
onChange={searchIcon} onChange={searchIcon}
withVariableButton={false} withVariableButton={false}
debounceTimeout={300} debounceTimeout={300}

View File

@ -7,6 +7,7 @@ import { EmojiSearchableList } from './emoji/EmojiSearchableList'
import { UnsplashPicker } from './UnsplashPicker' import { UnsplashPicker } from './UnsplashPicker'
import { IconPicker } from './IconPicker' import { IconPicker } from './IconPicker'
import { FilePathUploadProps } from '@/features/upload/api/generateUploadUrl' import { FilePathUploadProps } from '@/features/upload/api/generateUploadUrl'
import { useTranslate } from '@tolgee/react'
type Tabs = 'link' | 'upload' | 'giphy' | 'emoji' | 'unsplash' | 'icon' type Tabs = 'link' | 'upload' | 'giphy' | 'emoji' | 'unsplash' | 'icon'
@ -173,31 +174,39 @@ type ContentProps = { onNewUrl: (url: string) => void }
const UploadFileContent = ({ const UploadFileContent = ({
uploadFileProps, uploadFileProps,
onNewUrl, onNewUrl,
}: ContentProps & { uploadFileProps: FilePathUploadProps }) => ( }: ContentProps & { uploadFileProps: FilePathUploadProps }) => {
<Flex justify="center" py="2"> const { t } = useTranslate()
<UploadButton
fileType="image" return (
filePathProps={uploadFileProps} <Flex justify="center" py="2">
onFileUploaded={onNewUrl} <UploadButton
colorScheme="blue" fileType="image"
> filePathProps={uploadFileProps}
Choose an image onFileUploaded={onNewUrl}
</UploadButton> colorScheme="blue"
</Flex> >
) {t('editor.header.uploadTab.uploadButton.label')}
</UploadButton>
</Flex>
)
}
const EmbedLinkContent = ({ const EmbedLinkContent = ({
defaultUrl, defaultUrl,
onNewUrl, onNewUrl,
}: ContentProps & { defaultUrl?: string }) => ( }: ContentProps & { defaultUrl?: string }) => {
<Stack py="2"> const { t } = useTranslate()
<TextInput
placeholder={'Paste the image link...'} return (
onChange={onNewUrl} <Stack py="2">
defaultValue={defaultUrl ?? ''} <TextInput
/> placeholder={t('editor.header.linkTab.searchInputPlaceholder.label')}
</Stack> onChange={onNewUrl}
) defaultValue={defaultUrl ?? ''}
/>
</Stack>
)
}
const GiphyContent = ({ onNewUrl }: ContentProps) => ( const GiphyContent = ({ onNewUrl }: ContentProps) => (
<GiphyPicker onSubmit={onNewUrl} /> <GiphyPicker onSubmit={onNewUrl} />

View File

@ -9,6 +9,7 @@ import {
Text, Text,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { useState, ChangeEvent, useEffect, useRef } from 'react' import { useState, ChangeEvent, useEffect, useRef } from 'react'
import { useTranslate } from '@tolgee/react'
const emojiTags = emojiTagsData as Record<string, string[]> const emojiTags = emojiTagsData as Record<string, string[]>
@ -41,6 +42,7 @@ export const EmojiSearchableList = ({
const [filteredFlags, setFilteredFlags] = useState(flags) const [filteredFlags, setFilteredFlags] = useState(flags)
const [totalDisplayedCategories, setTotalDisplayedCategories] = useState(1) const [totalDisplayedCategories, setTotalDisplayedCategories] = useState(1)
const [recentEmojis, setRecentEmojis] = useState([]) const [recentEmojis, setRecentEmojis] = useState([])
const { t } = useTranslate()
useEffect(() => { useEffect(() => {
const recentIconNames = localStorage.getItem(localStorageRecentEmojisKey) const recentIconNames = localStorage.getItem(localStorageRecentEmojisKey)
@ -104,12 +106,15 @@ export const EmojiSearchableList = ({
return ( return (
<Stack> <Stack>
<ClassicInput placeholder="Search..." onChange={handleSearchChange} /> <ClassicInput
placeholder={t('emojiList.searchInput.placeholder')}
onChange={handleSearchChange}
/>
<Stack ref={scrollContainer} overflow="scroll" maxH="350px" spacing={4}> <Stack ref={scrollContainer} overflow="scroll" maxH="350px" spacing={4}>
{recentEmojis.length > 0 && ( {recentEmojis.length > 0 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
RECENT {t('emojiList.categories.recent.label')}
</Text> </Text>
<EmojiGrid emojis={recentEmojis} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={recentEmojis} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -117,7 +122,7 @@ export const EmojiSearchableList = ({
{filteredPeople.length > 0 && ( {filteredPeople.length > 0 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
PEOPLE {t('emojiList.categories.people.label')}
</Text> </Text>
<EmojiGrid emojis={filteredPeople} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredPeople} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -125,7 +130,7 @@ export const EmojiSearchableList = ({
{filteredAnimals.length > 0 && totalDisplayedCategories >= 2 && ( {filteredAnimals.length > 0 && totalDisplayedCategories >= 2 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
ANIMALS & NATURE {t('emojiList.categories.animalsAndNature.label')}
</Text> </Text>
<EmojiGrid emojis={filteredAnimals} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredAnimals} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -133,7 +138,7 @@ export const EmojiSearchableList = ({
{filteredFood.length > 0 && totalDisplayedCategories >= 3 && ( {filteredFood.length > 0 && totalDisplayedCategories >= 3 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
FOOD & DRINK {t('emojiList.categories.foodAndDrink.label')}
</Text> </Text>
<EmojiGrid emojis={filteredFood} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredFood} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -141,7 +146,7 @@ export const EmojiSearchableList = ({
{filteredTravel.length > 0 && totalDisplayedCategories >= 4 && ( {filteredTravel.length > 0 && totalDisplayedCategories >= 4 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
TRAVEL & PLACES {t('emojiList.categories.travelAndPlaces.label')}
</Text> </Text>
<EmojiGrid emojis={filteredTravel} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredTravel} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -149,7 +154,7 @@ export const EmojiSearchableList = ({
{filteredActivities.length > 0 && totalDisplayedCategories >= 5 && ( {filteredActivities.length > 0 && totalDisplayedCategories >= 5 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
ACTIVITIES {t('emojiList.categories.activities.label')}
</Text> </Text>
<EmojiGrid emojis={filteredActivities} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredActivities} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -157,7 +162,7 @@ export const EmojiSearchableList = ({
{filteredObjects.length > 0 && totalDisplayedCategories >= 6 && ( {filteredObjects.length > 0 && totalDisplayedCategories >= 6 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
OBJECTS {t('emojiList.categories.objects.label')}
</Text> </Text>
<EmojiGrid emojis={filteredObjects} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredObjects} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -165,7 +170,7 @@ export const EmojiSearchableList = ({
{filteredSymbols.length > 0 && totalDisplayedCategories >= 7 && ( {filteredSymbols.length > 0 && totalDisplayedCategories >= 7 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
SYMBOLS {t('emojiList.categories.symbols.label')}
</Text> </Text>
<EmojiGrid emojis={filteredSymbols} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredSymbols} onEmojiClick={selectEmoji} />
</Stack> </Stack>
@ -173,7 +178,7 @@ export const EmojiSearchableList = ({
{filteredFlags.length > 0 && totalDisplayedCategories >= 8 && ( {filteredFlags.length > 0 && totalDisplayedCategories >= 8 && (
<Stack> <Stack>
<Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2"> <Text fontSize="xs" color="gray.400" fontWeight="semibold" pl="2">
FLAGS {t('emojiList.categories.flags.label')}
</Text> </Text>
<EmojiGrid emojis={filteredFlags} onEmojiClick={selectEmoji} /> <EmojiGrid emojis={filteredFlags} onEmojiClick={selectEmoji} />
</Stack> </Stack>

View File

@ -12,7 +12,7 @@ export const AzureAdLogo = (props: IconProps) => {
<g id="g1016" transform="translate(-63.947 -88.179)"> <g id="g1016" transform="translate(-63.947 -88.179)">
<path <path
id="path1008" id="path1008"
fill='#00bef2' fill="#00bef2"
d="M290 166.3c.4 0 .8.5 1.4 1.4.5.8 42.6 51.3 93.6 112.2 51 60.9 92.6 111 92.4 111.3-.1.3-40.7 33.6-90.2 73.9s-91.6 74.6-93.5 76.2c-3.3 2.7-3.5 2.8-4.7 1.6-.7-.7-42.9-35.2-93.8-76.7S102.8 390.5 103 390c.2-.5 42-50.4 93.1-111s92.9-110.7 93.1-111.5c.2-.8.5-1.2.8-1.2z" d="M290 166.3c.4 0 .8.5 1.4 1.4.5.8 42.6 51.3 93.6 112.2 51 60.9 92.6 111 92.4 111.3-.1.3-40.7 33.6-90.2 73.9s-91.6 74.6-93.5 76.2c-3.3 2.7-3.5 2.8-4.7 1.6-.7-.7-42.9-35.2-93.8-76.7S102.8 390.5 103 390c.2-.5 42-50.4 93.1-111s92.9-110.7 93.1-111.5c.2-.8.5-1.2.8-1.2z"
/> />
<path <path

View File

@ -2,12 +2,33 @@ import { IconProps, Icon } from '@chakra-ui/react'
export const GitlabLogo = (props: IconProps) => ( export const GitlabLogo = (props: IconProps) => (
<Icon viewBox="0 0 256 236" {...props}> <Icon viewBox="0 0 256 236" {...props}>
<path d="M128.075 236.075l47.104-144.97H80.97l47.104 144.97z" fill="#E24329" /> <path
<path d="M128.075 236.074L80.97 91.104H14.956l113.119 144.97z" fill="#FC6D26" /> d="M128.075 236.075l47.104-144.97H80.97l47.104 144.97z"
<path d="M14.956 91.104L.642 135.16a9.752 9.752 0 0 0 3.542 10.903l123.891 90.012-113.12-144.97z" fill="#FCA326" /> fill="#E24329"
<path d="M14.956 91.105H80.97L52.601 3.79c-1.46-4.493-7.816-4.492-9.275 0l-28.37 87.315z" fill="#E24329" /> />
<path d="M128.075 236.074l47.104-144.97h66.015l-113.12 144.97z" fill="#FC6D26" /> <path
<path d="M241.194 91.104l14.314 44.056a9.752 9.752 0 0 1-3.543 10.903l-123.89 90.012 113.119-144.97z" fill="#FCA326" /> d="M128.075 236.074L80.97 91.104H14.956l113.119 144.97z"
<path d="M241.194 91.105h-66.015l28.37-87.315c1.46-4.493 7.816-4.492 9.275 0l28.37 87.315z" fill="#E24329" /> fill="#FC6D26"
/>
<path
d="M14.956 91.104L.642 135.16a9.752 9.752 0 0 0 3.542 10.903l123.891 90.012-113.12-144.97z"
fill="#FCA326"
/>
<path
d="M14.956 91.105H80.97L52.601 3.79c-1.46-4.493-7.816-4.492-9.275 0l-28.37 87.315z"
fill="#E24329"
/>
<path
d="M128.075 236.074l47.104-144.97h66.015l-113.12 144.97z"
fill="#FC6D26"
/>
<path
d="M241.194 91.104l14.314 44.056a9.752 9.752 0 0 1-3.543 10.903l-123.89 90.012 113.119-144.97z"
fill="#FCA326"
/>
<path
d="M241.194 91.105h-66.015l28.37-87.315c1.46-4.493 7.816-4.492 9.275 0l28.37 87.315z"
fill="#E24329"
/>
</Icon> </Icon>
) )

View File

@ -28,9 +28,11 @@ import { deleteInvitationQuery } from '../queries/deleteInvitationQuery'
import { updateCollaboratorQuery } from '../queries/updateCollaboratorQuery' import { updateCollaboratorQuery } from '../queries/updateCollaboratorQuery'
import { deleteCollaboratorQuery } from '../queries/deleteCollaboratorQuery' import { deleteCollaboratorQuery } from '../queries/deleteCollaboratorQuery'
import { sendInvitationQuery } from '../queries/sendInvitationQuery' import { sendInvitationQuery } from '../queries/sendInvitationQuery'
import { TFnType, useTranslate } from '@tolgee/react'
export const CollaborationList = () => { export const CollaborationList = () => {
const { currentRole, workspace } = useWorkspace() const { currentRole, workspace } = useWorkspace()
const { t } = useTranslate()
const { typebot } = useTypebot() const { typebot } = useTypebot()
const [invitationType, setInvitationType] = useState<CollaborationType>( const [invitationType, setInvitationType] = useState<CollaborationType>(
CollaborationType.READ CollaborationType.READ
@ -50,7 +52,7 @@ export const CollaborationList = () => {
typebotId: typebot?.id, typebotId: typebot?.id,
onError: (e) => onError: (e) =>
showToast({ showToast({
title: "Couldn't fetch collaborators", title: t('share.button.popover.collaboratorsFetch.error.label'),
description: e.message, description: e.message,
}), }),
}) })
@ -62,7 +64,7 @@ export const CollaborationList = () => {
typebotId: typebot?.id, typebotId: typebot?.id,
onError: (e) => onError: (e) =>
showToast({ showToast({
title: "Couldn't fetch invitations", title: t('share.button.popover.invitationsFetch.error.label'),
description: e.message, description: e.message,
}), }),
}) })
@ -132,7 +134,10 @@ export const CollaborationList = () => {
mutateCollaborators({ collaborators: collaborators ?? [] }) mutateCollaborators({ collaborators: collaborators ?? [] })
if (error) if (error)
return showToast({ title: error.name, description: error.message }) return showToast({ title: error.name, description: error.message })
showToast({ status: 'success', title: 'Invitation sent! 📧' }) showToast({
status: 'success',
title: t('share.button.popover.invitationSent.successToast.label'),
})
setInvitationEmail('') setInvitationEmail('')
} }
@ -141,7 +146,7 @@ export const CollaborationList = () => {
<HStack as="form" onSubmit={handleInvitationSubmit} px="4" pb="2"> <HStack as="form" onSubmit={handleInvitationSubmit} px="4" pb="2">
<Input <Input
size="sm" size="sm"
placeholder="colleague@company.com" placeholder={t('share.button.popover.inviteInput.placeholder')}
name="inviteEmail" name="inviteEmail"
value={invitationEmail} value={invitationEmail}
onChange={(e) => setInvitationEmail(e.target.value)} onChange={(e) => setInvitationEmail(e.target.value)}
@ -163,7 +168,7 @@ export const CollaborationList = () => {
type="submit" type="submit"
isDisabled={!hasFullAccess} isDisabled={!hasFullAccess}
> >
Invite {t('share.button.popover.inviteButton.label')}
</Button> </Button>
</HStack> </HStack>
{workspace && ( {workspace && (
@ -176,6 +181,7 @@ export const CollaborationList = () => {
</HStack> </HStack>
<Tag flexShrink={0}> <Tag flexShrink={0}>
{convertCollaborationTypeEnumToReadable( {convertCollaborationTypeEnumToReadable(
t,
CollaborationType.FULL_ACCESS CollaborationType.FULL_ACCESS
)} )}
</Tag> </Tag>
@ -227,6 +233,8 @@ const CollaborationTypeMenuButton = ({
type: CollaborationType type: CollaborationType
onChange: (type: CollaborationType) => void onChange: (type: CollaborationType) => void
}) => { }) => {
const { t } = useTranslate()
return ( return (
<Menu placement="bottom-end"> <Menu placement="bottom-end">
<MenuButton <MenuButton
@ -235,15 +243,15 @@ const CollaborationTypeMenuButton = ({
as={Button} as={Button}
rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />} rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />}
> >
{convertCollaborationTypeEnumToReadable(type)} {convertCollaborationTypeEnumToReadable(t, type)}
</MenuButton> </MenuButton>
<MenuList minW={0}> <MenuList minW={0}>
<Stack maxH={'35vh'} overflowY="scroll" spacing="0"> <Stack maxH={'35vh'} overflowY="scroll" spacing="0">
<MenuItem onClick={() => onChange(CollaborationType.READ)}> <MenuItem onClick={() => onChange(CollaborationType.READ)}>
{convertCollaborationTypeEnumToReadable(CollaborationType.READ)} {convertCollaborationTypeEnumToReadable(t, CollaborationType.READ)}
</MenuItem> </MenuItem>
<MenuItem onClick={() => onChange(CollaborationType.WRITE)}> <MenuItem onClick={() => onChange(CollaborationType.WRITE)}>
{convertCollaborationTypeEnumToReadable(CollaborationType.WRITE)} {convertCollaborationTypeEnumToReadable(t, CollaborationType.WRITE)}
</MenuItem> </MenuItem>
</Stack> </Stack>
</MenuList> </MenuList>
@ -252,14 +260,15 @@ const CollaborationTypeMenuButton = ({
} }
export const convertCollaborationTypeEnumToReadable = ( export const convertCollaborationTypeEnumToReadable = (
t: TFnType,
type: CollaborationType type: CollaborationType
) => { ) => {
switch (type) { switch (type) {
case CollaborationType.READ: case CollaborationType.READ:
return 'Can view' return t('collaboration.roles.view.label')
case CollaborationType.WRITE: case CollaborationType.WRITE:
return 'Can edit' return t('collaboration.roles.edit.label')
case CollaborationType.FULL_ACCESS: case CollaborationType.FULL_ACCESS:
return 'Full access' return t('collaboration.roles.full.label')
} }
} }

View File

@ -13,6 +13,7 @@ import {
import { CollaborationType } from '@typebot.io/prisma' import { CollaborationType } from '@typebot.io/prisma'
import React from 'react' import React from 'react'
import { convertCollaborationTypeEnumToReadable } from './CollaborationList' import { convertCollaborationTypeEnumToReadable } from './CollaborationList'
import { useTranslate } from '@tolgee/react'
type Props = { type Props = {
image?: string image?: string
@ -35,6 +36,7 @@ export const CollaboratorItem = ({
onDeleteClick, onDeleteClick,
onChangeCollaborationType, onChangeCollaborationType,
}: Props) => { }: Props) => {
const { t } = useTranslate()
const hoverBgColor = useColorModeValue('gray.100', 'gray.700') const hoverBgColor = useColorModeValue('gray.100', 'gray.700')
const handleEditClick = () => const handleEditClick = () =>
onChangeCollaborationType(CollaborationType.WRITE) onChangeCollaborationType(CollaborationType.WRITE)
@ -48,19 +50,19 @@ export const CollaboratorItem = ({
name={name} name={name}
image={image} image={image}
isGuest={isGuest} isGuest={isGuest}
tag={convertCollaborationTypeEnumToReadable(type)} tag={convertCollaborationTypeEnumToReadable(t, type)}
/> />
</MenuButton> </MenuButton>
{isOwner && ( {isOwner && (
<MenuList shadow="lg"> <MenuList shadow="lg">
<MenuItem onClick={handleEditClick}> <MenuItem onClick={handleEditClick}>
{convertCollaborationTypeEnumToReadable(CollaborationType.WRITE)} {convertCollaborationTypeEnumToReadable(t, CollaborationType.WRITE)}
</MenuItem> </MenuItem>
<MenuItem onClick={handleViewClick}> <MenuItem onClick={handleViewClick}>
{convertCollaborationTypeEnumToReadable(CollaborationType.READ)} {convertCollaborationTypeEnumToReadable(t, CollaborationType.READ)}
</MenuItem> </MenuItem>
<MenuItem color="red.500" onClick={onDeleteClick}> <MenuItem color="red.500" onClick={onDeleteClick}>
Remove {t('remove')}
</MenuItem> </MenuItem>
</MenuList> </MenuList>
)} )}
@ -80,28 +82,32 @@ export const CollaboratorIdentityContent = ({
image?: string image?: string
isGuest?: boolean isGuest?: boolean
email: string email: string
}) => ( }) => {
<HStack justifyContent="space-between" maxW="full" py="2" px="4"> const { t } = useTranslate()
<HStack minW={0} spacing={3}>
<Avatar name={name} src={image} size="sm" /> return (
<Stack spacing={0} minW="0"> <HStack justifyContent="space-between" maxW="full" py="2" px="4">
{name && ( <HStack minW={0} spacing={3}>
<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>
<Text </HStack>
color="gray.500" <HStack flexShrink={0}>
fontSize={name ? '14px' : 'inherit'} {isGuest && <Tag color="gray.400">{t('pending')}</Tag>}
noOfLines={1} <Tag>{tag}</Tag>
> </HStack>
{email}
</Text>
</Stack>
</HStack> </HStack>
<HStack flexShrink={0}> )
{isGuest && <Tag color="gray.400">Pending</Tag>} }
<Tag>{tag}</Tag>
</HStack>
</HStack>
)

View File

@ -22,6 +22,7 @@ import { useRouter } from 'next/router'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { EditorSettingsModal } from './EditorSettingsModal' import { EditorSettingsModal } from './EditorSettingsModal'
import { parseDefaultPublicId } from '@/features/publish/helpers/parseDefaultPublicId' import { parseDefaultPublicId } from '@/features/publish/helpers/parseDefaultPublicId'
import { useTranslate } from '@tolgee/react'
export const BoardMenuButton = (props: FlexProps) => { export const BoardMenuButton = (props: FlexProps) => {
const { query } = useRouter() const { query } = useRouter()
@ -29,6 +30,7 @@ export const BoardMenuButton = (props: FlexProps) => {
const { user } = useUser() const { user } = useUser()
const [isDownloading, setIsDownloading] = useState(false) const [isDownloading, setIsDownloading] = useState(false)
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
const { t } = useTranslate()
useEffect(() => { useEffect(() => {
if (user && !user.graphNavigation && !query.isFirstBot) onOpen() if (user && !user.graphNavigation && !query.isFirstBot) onOpen()
@ -71,13 +73,13 @@ export const BoardMenuButton = (props: FlexProps) => {
/> />
<MenuList> <MenuList>
<MenuItem icon={<BookIcon />} onClick={redirectToDocumentation}> <MenuItem icon={<BookIcon />} onClick={redirectToDocumentation}>
Documentation {t('editor.graph.menu.documentationItem.label')}
</MenuItem> </MenuItem>
<MenuItem icon={<SettingsIcon />} onClick={onOpen}> <MenuItem icon={<SettingsIcon />} onClick={onOpen}>
Editor settings {t('editor.graph.menu.editorSettingsItem.label')}
</MenuItem> </MenuItem>
<MenuItem icon={<DownloadIcon />} onClick={downloadFlow}> <MenuItem icon={<DownloadIcon />} onClick={downloadFlow}>
Export flow {t('editor.graph.menu.exportFlowItem.label')}
</MenuItem> </MenuItem>
</MenuList> </MenuList>
<EditorSettingsModal isOpen={isOpen} onClose={onClose} /> <EditorSettingsModal isOpen={isOpen} onClose={onClose} />

View File

@ -116,7 +116,7 @@ export const TypebotHeader = () => {
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'} variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.flowButton.label')} {t('editor.header.flowButton.label')}
</Button> </Button>
<Button <Button
as={Link} as={Link}
@ -125,7 +125,7 @@ export const TypebotHeader = () => {
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'} variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.themeButton.label')} {t('editor.header.themeButton.label')}
</Button> </Button>
<Button <Button
as={Link} as={Link}
@ -134,7 +134,7 @@ export const TypebotHeader = () => {
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'} variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.settingsButton.label')} {t('editor.header.settingsButton.label')}
</Button> </Button>
<Button <Button
as={Link} as={Link}
@ -143,7 +143,7 @@ export const TypebotHeader = () => {
variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'} variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.shareButton.label')} {t('share.button.label')}
</Button> </Button>
{isDefined(publishedTypebot) && ( {isDefined(publishedTypebot) && (
<Button <Button
@ -153,7 +153,7 @@ export const TypebotHeader = () => {
variant={router.pathname.includes('results') ? 'outline' : 'ghost'} variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.resultsButton.label')} {t('editor.header.resultsButton.label')}
</Button> </Button>
)} )}
</HStack> </HStack>
@ -211,7 +211,11 @@ export const TypebotHeader = () => {
{currentUserMode === 'write' && ( {currentUserMode === 'write' && (
<HStack> <HStack>
<Tooltip <Tooltip
label={isUndoShortcutTooltipOpen ? 'Changes reverted!' : 'Undo'} label={
isUndoShortcutTooltipOpen
? t('editor.header.undo.tooltip.label')
: t('editor.header.undoButton.label')
}
isOpen={isUndoShortcutTooltipOpen ? true : undefined} isOpen={isUndoShortcutTooltipOpen ? true : undefined}
hasArrow={isUndoShortcutTooltipOpen} hasArrow={isUndoShortcutTooltipOpen}
> >
@ -219,18 +223,18 @@ export const TypebotHeader = () => {
display={['none', 'flex']} display={['none', 'flex']}
icon={<UndoIcon />} icon={<UndoIcon />}
size="sm" size="sm"
aria-label="Undo" aria-label={t('editor.header.undoButton.label')}
onClick={undo} onClick={undo}
isDisabled={!canUndo} isDisabled={!canUndo}
/> />
</Tooltip> </Tooltip>
<Tooltip label="Redo"> <Tooltip label={t('editor.header.redoButton.label')}>
<IconButton <IconButton
display={['none', 'flex']} display={['none', 'flex']}
icon={<RedoIcon />} icon={<RedoIcon />}
size="sm" size="sm"
aria-label="Redo" aria-label={t('editor.header.redoButton.label')}
onClick={redo} onClick={redo}
isDisabled={!canRedo} isDisabled={!canRedo}
/> />
@ -238,14 +242,14 @@ export const TypebotHeader = () => {
</HStack> </HStack>
)} )}
<Button leftIcon={<BuoyIcon />} onClick={handleHelpClick} size="sm"> <Button leftIcon={<BuoyIcon />} onClick={handleHelpClick} size="sm">
{t('editor.headers.helpButton.label')} {t('editor.header.helpButton.label')}
</Button> </Button>
</HStack> </HStack>
{isSavingLoading && ( {isSavingLoading && (
<HStack> <HStack>
<Spinner speed="0.7s" size="sm" color="gray.400" /> <Spinner speed="0.7s" size="sm" color="gray.400" />
<Text fontSize="sm" color="gray.400"> <Text fontSize="sm" color="gray.400">
{t('editor.headers.savingSpinner.label')} {t('editor.header.savingSpinner.label')}
</Text> </Text>
</HStack> </HStack>
)} )}
@ -263,7 +267,7 @@ export const TypebotHeader = () => {
leftIcon={<PlayIcon />} leftIcon={<PlayIcon />}
size="sm" size="sm"
> >
{t('editor.headers.previewButton.label')} {t('editor.header.previewButton.label')}
</Button> </Button>
)} )}
{currentUserMode === 'write' && <PublishButton size="sm" />} {currentUserMode === 'write' && <PublishButton size="sm" />}

View File

@ -62,7 +62,7 @@ export const GuestTypebotHeader = () => {
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'} variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.flowButton.label')} {t('editor.header.flowButton.label')}
</Button> </Button>
<Button <Button
as={Link} as={Link}
@ -71,7 +71,7 @@ export const GuestTypebotHeader = () => {
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'} variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.themeButton.label')} {t('editor.header.themeButton.label')}
</Button> </Button>
<Button <Button
as={Link} as={Link}
@ -80,7 +80,7 @@ export const GuestTypebotHeader = () => {
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'} variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
size="sm" size="sm"
> >
{t('editor.headers.settingsButton.label')} {t('editor.header.settingsButton.label')}
</Button> </Button>
</HStack> </HStack>
<HStack <HStack

View File

@ -1,11 +1,14 @@
import { FlagIcon } from '@/components/icons' import { FlagIcon } from '@/components/icons'
import { HStack, Text } from '@chakra-ui/react' import { HStack, Text } from '@chakra-ui/react'
import { useTranslate } from '@tolgee/react'
export const StartEventNode = () => { export const StartEventNode = () => {
const { t } = useTranslate()
return ( return (
<HStack spacing={3}> <HStack spacing={3}>
<FlagIcon /> <FlagIcon />
<Text>Start</Text> <Text>{t('editor.blocks.start.text')}</Text>
</HStack> </HStack>
) )
} }

View File

@ -17,6 +17,7 @@ import { runtimes } from '../data'
import { PreviewDrawerBody } from './PreviewDrawerBody' import { PreviewDrawerBody } from './PreviewDrawerBody'
import { useDrag } from '@use-gesture/react' import { useDrag } from '@use-gesture/react'
import { ResizeHandle } from './ResizeHandle' import { ResizeHandle } from './ResizeHandle'
import { useTranslate } from '@tolgee/react'
const preferredRuntimeKey = 'preferredRuntime' const preferredRuntimeKey = 'preferredRuntime'
@ -30,6 +31,7 @@ const getDefaultRuntime = (typebotId?: string) => {
export const PreviewDrawer = () => { export const PreviewDrawer = () => {
const { typebot, save, isSavingLoading } = useTypebot() const { typebot, save, isSavingLoading } = useTypebot()
const { t } = useTranslate()
const { setRightPanel } = useEditor() const { setRightPanel } = useEditor()
const { setPreviewingBlock } = useGraph() const { setPreviewingBlock } = useGraph()
const [width, setWidth] = useState(500) const [width, setWidth] = useState(500)
@ -103,7 +105,7 @@ export const PreviewDrawer = () => {
isLoading={isSavingLoading} isLoading={isSavingLoading}
variant="ghost" variant="ghost"
> >
Restart {t('preview.restartButton.label')}
</Button> </Button>
) : null} ) : null}
</HStack> </HStack>

View File

@ -73,7 +73,7 @@ export const PublishButton = ({
trpc.typebot.publishTypebot.useMutation({ trpc.typebot.publishTypebot.useMutation({
onError: (error) => { onError: (error) => {
showToast({ showToast({
title: 'Error while publishing typebot', title: t('publish.error.label'),
description: error.message, description: error.message,
}) })
if (error.data?.httpStatus === 403) logOut() if (error.data?.httpStatus === 403) logOut()
@ -91,7 +91,7 @@ export const PublishButton = ({
trpc.typebot.unpublishTypebot.useMutation({ trpc.typebot.unpublishTypebot.useMutation({
onError: (error) => onError: (error) =>
showToast({ showToast({
title: 'Error while unpublishing typebot', title: t('editor.header.unpublishTypebot.error.label'),
description: error.message, description: error.message,
}), }),
onSuccess: () => { onSuccess: () => {
@ -149,41 +149,40 @@ export const PublishButton = ({
onConfirm={handlePublishClick} onConfirm={handlePublishClick}
onClose={onNewEngineWarningClose} onClose={onNewEngineWarningClose}
confirmButtonColor="blue" confirmButtonColor="blue"
title="⚠️ New engine version" title={t('publish.versionWarning.title.label')}
message={ message={
<Stack spacing="3"> <Stack spacing="3">
<Text> <Text>
You are about to a deploy a version of your bot with an updated {t('publish.versionWarning.message.aboutToDeploy.label')}
engine (Typebot V6).
</Text> </Text>
<Text fontWeight="bold"> <Text fontWeight="bold">
Make sure to check out all the{' '} {t('publish.versionWarning.message.check.label')}{' '}
<TextLink <TextLink
href="https://docs.typebot.io/breaking-changes#typebot-v6" href="https://docs.typebot.io/breaking-changes#typebot-v6"
isExternal isExternal
> >
associated breaking changes {t('publish.versionWarning.message.breakingChanges.label')}
</TextLink> </TextLink>
</Text> </Text>
<Text> <Text>
{' '} {' '}
Then test, the bot thoroughly in preview mode before publishing. {t('publish.versionWarning.message.testInPreviewMode.label')}
</Text> </Text>
</Stack> </Stack>
} }
confirmButtonLabel={'Publish'} confirmButtonLabel={t('publishButton.label')}
/> />
)} )}
<Tooltip <Tooltip
placement="bottom-end" placement="bottom-end"
label={ label={
<Stack> <Stack>
<Text>There are non published changes.</Text> <Text>{t('publishButton.tooltip.nonPublishedChanges.label')}</Text>
<Text fontStyle="italic"> <Text fontStyle="italic">
Published version from{' '} {t('publishButton.tooltip.publishedVersion.from.label')}{' '}
{publishedTypebot && {publishedTypebot &&
parseTimeSince(publishedTypebot.updatedAt.toString())}{' '} parseTimeSince(publishedTypebot.updatedAt.toString())}{' '}
ago {t('publishButton.tooltip.publishedVersion.ago.label')}
</Text> </Text>
</Stack> </Stack>
} }
@ -205,9 +204,9 @@ export const PublishButton = ({
> >
{isPublished {isPublished
? typebot?.isClosed ? typebot?.isClosed
? 'Closed' ? t('publishButton.closed.label')
: 'Published' : t('publishButton.published.label')
: 'Publish'} : t('publishButton.label')}
</Button> </Button>
</Tooltip> </Tooltip>
@ -218,27 +217,27 @@ export const PublishButton = ({
colorScheme={'blue'} colorScheme={'blue'}
borderLeftRadius={0} borderLeftRadius={0}
icon={<ChevronLeftIcon transform="rotate(-90deg)" />} icon={<ChevronLeftIcon transform="rotate(-90deg)" />}
aria-label="Show published typebot menu" aria-label={t('publishButton.dropdown.showMenu.label')}
size="sm" size="sm"
isDisabled={isPublishing || isSavingLoading} isDisabled={isPublishing || isSavingLoading}
/> />
<MenuList> <MenuList>
{!isPublished && ( {!isPublished && (
<MenuItem onClick={restorePublishedTypebot}> <MenuItem onClick={restorePublishedTypebot}>
Restore published version {t('publishButton.dropdown.restoreVersion.label')}
</MenuItem> </MenuItem>
)} )}
{!typebot?.isClosed ? ( {!typebot?.isClosed ? (
<MenuItem onClick={closeTypebot} icon={<LockedIcon />}> <MenuItem onClick={closeTypebot} icon={<LockedIcon />}>
Close typebot to new responses {t('publishButton.dropdown.close.label')}
</MenuItem> </MenuItem>
) : ( ) : (
<MenuItem onClick={openTypebot} icon={<UnlockedIcon />}> <MenuItem onClick={openTypebot} icon={<UnlockedIcon />}>
Reopen typebot to new responses {t('publishButton.dropdown.reopen.label')}
</MenuItem> </MenuItem>
)} )}
<MenuItem onClick={unpublishTypebot} icon={<CloudOffIcon />}> <MenuItem onClick={unpublishTypebot} icon={<CloudOffIcon />}>
Unpublish typebot {t('publishButton.dropdown.unpublish.label')}
</MenuItem> </MenuItem>
</MenuList> </MenuList>
</Menu> </Menu>

View File

@ -6,10 +6,7 @@ import { parseReactBotProps } from '../../snippetParsers'
type Props = { widthLabel?: string; heightLabel: string } type Props = { widthLabel?: string; heightLabel: string }
export const NextjsStandardSnippet = ({ export const NextjsStandardSnippet = ({ widthLabel, heightLabel }: Props) => {
widthLabel,
heightLabel,
}: Props) => {
const { typebot } = useTypebot() const { typebot } = useTypebot()
const snippet = prettier.format( const snippet = prettier.format(
`import { Standard } from "@typebot.io/nextjs"; `import { Standard } from "@typebot.io/nextjs";

View File

@ -4,8 +4,10 @@ import { SwitchWithRelatedSettings } from '@/components/SwitchWithRelatedSetting
import { CopyButton } from '@/components/CopyButton' import { CopyButton } from '@/components/CopyButton'
import { CollaborationList } from '@/features/collaboration/components/CollaborationList' import { CollaborationList } from '@/features/collaboration/components/CollaborationList'
import { useTypebot } from '@/features/editor/providers/TypebotProvider' import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { useTranslate } from '@tolgee/react'
export const SharePopoverContent = () => { export const SharePopoverContent = () => {
const { t } = useTranslate()
const { typebot, updateTypebot } = useTypebot() const { typebot, updateTypebot } = useTypebot()
const currentUrl = `${window.location.origin}/typebots/${typebot?.id}/edit` const currentUrl = `${window.location.origin}/typebots/${typebot?.id}/edit`
@ -30,7 +32,7 @@ export const SharePopoverContent = () => {
<CollaborationList /> <CollaborationList />
<Stack p="4" borderTopWidth={1}> <Stack p="4" borderTopWidth={1}>
<SwitchWithRelatedSettings <SwitchWithRelatedSettings
label={'Make the flow publicly available'} label={t('share.button.popover.publicFlow.label')}
initialValue={typebot?.settings.publicShare?.isEnabled ?? false} initialValue={typebot?.settings.publicShare?.isEnabled ?? false}
onCheckChange={updateIsPublicShareEnabled} onCheckChange={updateIsPublicShareEnabled}
> >

View File

@ -7,18 +7,21 @@ import {
import { UsersIcon } from '@/components/icons' import { UsersIcon } from '@/components/icons'
import React from 'react' import React from 'react'
import { SharePopoverContent } from './SharePopoverContent' import { SharePopoverContent } from './SharePopoverContent'
import { useTranslate } from '@tolgee/react'
export const ShareTypebotButton = ({ isLoading }: { isLoading: boolean }) => { export const ShareTypebotButton = ({ isLoading }: { isLoading: boolean }) => {
const { t } = useTranslate()
return ( return (
<Popover isLazy placement="bottom-end"> <Popover isLazy placement="bottom-end">
<PopoverTrigger> <PopoverTrigger>
<Button <Button
isLoading={isLoading} isLoading={isLoading}
leftIcon={<UsersIcon />} leftIcon={<UsersIcon />}
aria-label="Open share popover" aria-label={t('share.button.popover.ariaLabel')}
size="sm" size="sm"
> >
Share {t('share.button.label')}
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent

View File

@ -15,12 +15,14 @@ import React, { useRef } from 'react'
import { VariableSearchInput } from '@/components/inputs/VariableSearchInput' import { VariableSearchInput } from '@/components/inputs/VariableSearchInput'
import { useOutsideClick } from '@/hooks/useOutsideClick' import { useOutsideClick } from '@/hooks/useOutsideClick'
import { useParentModal } from '@/features/graph/providers/ParentModalProvider' import { useParentModal } from '@/features/graph/providers/ParentModalProvider'
import { useTranslate } from '@tolgee/react'
type Props = { type Props = {
onSelectVariable: (variable: Pick<Variable, 'name' | 'id'>) => void onSelectVariable: (variable: Pick<Variable, 'name' | 'id'>) => void
} & Omit<IconButtonProps, 'aria-label'> } & Omit<IconButtonProps, 'aria-label'>
export const VariablesButton = ({ onSelectVariable, ...props }: Props) => { export const VariablesButton = ({ onSelectVariable, ...props }: Props) => {
const { t } = useTranslate()
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
const popoverRef = useRef<HTMLDivElement>(null) const popoverRef = useRef<HTMLDivElement>(null)
const { ref: parentModalRef } = useParentModal() const { ref: parentModalRef } = useParentModal()
@ -35,9 +37,9 @@ export const VariablesButton = ({ onSelectVariable, ...props }: Props) => {
<Popover isLazy isOpen={isOpen}> <Popover isLazy isOpen={isOpen}>
<PopoverAnchor> <PopoverAnchor>
<Flex> <Flex>
<Tooltip label="Insert a variable"> <Tooltip label={t('variables.button.tooltip')}>
<IconButton <IconButton
aria-label={'Insert a variable'} aria-label={t('variables.button.tooltip')}
icon={<UserIcon />} icon={<UserIcon />}
pos="relative" pos="relative"
onClick={onOpen} onClick={onOpen}
@ -54,7 +56,7 @@ export const VariablesButton = ({ onSelectVariable, ...props }: Props) => {
onClose() onClose()
if (variable) onSelectVariable(variable) if (variable) onSelectVariable(variable)
}} }}
placeholder="Search for a variable" placeholder={t('variables.button.searchInput.placeholder')}
shadow="lg" shadow="lg"
autoFocus autoFocus
/> />

View File

@ -1 +1,137 @@
{"id":"clemrhnsp00001auiaoun42wf","version":"3","createdAt":"2023-02-27T11:53:48.217Z","updatedAt":"2023-02-27T11:53:48.217Z","icon":null,"name":"My typebot","folderId":null,"groups":[{"id":"et7lna5mxbmn9blchekkejdf","title":"Start","blocks":[{"id":"ivcklgamqz8e3uwmtshm32n9","type":"start","label":"Start","groupId":"et7lna5mxbmn9blchekkejdf","outgoingEdgeId":"ogi8zj19v4krzm9xe4c9orv2"}],"graphCoordinates":{"x":0,"y":0}},{"id":"wrd4694r5fo8czflp4t79259","graphCoordinates":{"x":41.28125,"y":169.53125},"title":"Group #1","blocks":[{"id":"pjnrvjh6un6el1tjsbu7d6w1","groupId":"wrd4694r5fo8czflp4t79259","type":"text","content":{"html":"<div>Hello this is a test!</div>","richText":[{"type":"p","children":[{"text":"Hello this is a test!"}]}],"plainText":"Hello this is a test!"}},{"id":"wvt13rpcvuy5s7mj83bm946s","groupId":"wrd4694r5fo8czflp4t79259","type":"text","content":{"html":"<div>How are you?</div>","richText":[{"type":"p","children":[{"text":"How are you?"}]}],"plainText":"How are you?"}},{"id":"he864w99l8y6c6epfd9girvv","groupId":"wrd4694r5fo8czflp4t79259","type":"text input","options":{"isLong":false,"labels":{"button":"Send","placeholder":"Type your answer..."}},"outgoingEdgeId":"a42zatxkw0q8w2kq886m9ek8"}]},{"id":"eao5ufv4wtl0yos09w6wag3j","graphCoordinates":{"x":411.078125,"y":169.94140625},"title":"Group #2","blocks":[{"id":"t33v5ijddw2e2786jiurep3p","groupId":"eao5ufv4wtl0yos09w6wag3j","type":"Jump","options":{}}]}],"variables":[],"edges":[{"from":{"groupId":"et7lna5mxbmn9blchekkejdf","blockId":"ivcklgamqz8e3uwmtshm32n9"},"to":{"groupId":"wrd4694r5fo8czflp4t79259"},"id":"ogi8zj19v4krzm9xe4c9orv2"},{"from":{"groupId":"wrd4694r5fo8czflp4t79259","blockId":"he864w99l8y6c6epfd9girvv"},"to":{"groupId":"eao5ufv4wtl0yos09w6wag3j"},"id":"a42zatxkw0q8w2kq886m9ek8"}],"theme":{"chat":{"inputs":{"color":"#303235","backgroundColor":"#FFFFFF","placeholderColor":"#9095A0"},"buttons":{"color":"#FFFFFF","backgroundColor":"#0042DA"},"hostAvatar":{"url":"https://avatars.githubusercontent.com/u/16015833?v=4","isEnabled":true},"hostBubbles":{"color":"#303235","backgroundColor":"#F7F8FF"},"guestBubbles":{"color":"#FFFFFF","backgroundColor":"#FF8E21"}},"general":{"font":"Open Sans","background":{"type":"Color","content":"#ffffff"}}},"settings":{"general":{"isBrandingEnabled":true,"isInputPrefillEnabled":true,"isResultSavingEnabled":true,"isHideQueryParamsEnabled":true,"isNewResultOnRefreshEnabled":true},"metadata":{"description":"Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."},"typingEmulation":{"speed":300,"enabled":true,"maxDelay":1.5}},"publicId":null,"customDomain":null,"workspaceId":"freeWorkspace","resultsTablePreferences":null,"isArchived":false,"isClosed":false} {
"id": "clemrhnsp00001auiaoun42wf",
"version": "3",
"createdAt": "2023-02-27T11:53:48.217Z",
"updatedAt": "2023-02-27T11:53:48.217Z",
"icon": null,
"name": "My typebot",
"folderId": null,
"groups": [
{
"id": "et7lna5mxbmn9blchekkejdf",
"title": "Start",
"blocks": [
{
"id": "ivcklgamqz8e3uwmtshm32n9",
"type": "start",
"label": "Start",
"groupId": "et7lna5mxbmn9blchekkejdf",
"outgoingEdgeId": "ogi8zj19v4krzm9xe4c9orv2"
}
],
"graphCoordinates": { "x": 0, "y": 0 }
},
{
"id": "wrd4694r5fo8czflp4t79259",
"graphCoordinates": { "x": 41.28125, "y": 169.53125 },
"title": "Group #1",
"blocks": [
{
"id": "pjnrvjh6un6el1tjsbu7d6w1",
"groupId": "wrd4694r5fo8czflp4t79259",
"type": "text",
"content": {
"html": "<div>Hello this is a test!</div>",
"richText": [
{ "type": "p", "children": [{ "text": "Hello this is a test!" }] }
],
"plainText": "Hello this is a test!"
}
},
{
"id": "wvt13rpcvuy5s7mj83bm946s",
"groupId": "wrd4694r5fo8czflp4t79259",
"type": "text",
"content": {
"html": "<div>How are you?</div>",
"richText": [
{ "type": "p", "children": [{ "text": "How are you?" }] }
],
"plainText": "How are you?"
}
},
{
"id": "he864w99l8y6c6epfd9girvv",
"groupId": "wrd4694r5fo8czflp4t79259",
"type": "text input",
"options": {
"isLong": false,
"labels": { "button": "Send", "placeholder": "Type your answer..." }
},
"outgoingEdgeId": "a42zatxkw0q8w2kq886m9ek8"
}
]
},
{
"id": "eao5ufv4wtl0yos09w6wag3j",
"graphCoordinates": { "x": 411.078125, "y": 169.94140625 },
"title": "Group #2",
"blocks": [
{
"id": "t33v5ijddw2e2786jiurep3p",
"groupId": "eao5ufv4wtl0yos09w6wag3j",
"type": "Jump",
"options": {}
}
]
}
],
"variables": [],
"edges": [
{
"from": {
"groupId": "et7lna5mxbmn9blchekkejdf",
"blockId": "ivcklgamqz8e3uwmtshm32n9"
},
"to": { "groupId": "wrd4694r5fo8czflp4t79259" },
"id": "ogi8zj19v4krzm9xe4c9orv2"
},
{
"from": {
"groupId": "wrd4694r5fo8czflp4t79259",
"blockId": "he864w99l8y6c6epfd9girvv"
},
"to": { "groupId": "eao5ufv4wtl0yos09w6wag3j" },
"id": "a42zatxkw0q8w2kq886m9ek8"
}
],
"theme": {
"chat": {
"inputs": {
"color": "#303235",
"backgroundColor": "#FFFFFF",
"placeholderColor": "#9095A0"
},
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
"hostAvatar": {
"url": "https://avatars.githubusercontent.com/u/16015833?v=4",
"isEnabled": true
},
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
},
"general": {
"font": "Open Sans",
"background": { "type": "Color", "content": "#ffffff" }
}
},
"settings": {
"general": {
"isBrandingEnabled": true,
"isInputPrefillEnabled": true,
"isResultSavingEnabled": true,
"isHideQueryParamsEnabled": true,
"isNewResultOnRefreshEnabled": true
},
"metadata": {
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
},
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
},
"publicId": null,
"customDomain": null,
"workspaceId": "freeWorkspace",
"resultsTablePreferences": null,
"isArchived": false,
"isClosed": false
}

View File

@ -7,6 +7,7 @@
"build": "dotenv -e ./.env -e ../../.env -- next build", "build": "dotenv -e ./.env -e ../../.env -- next build",
"start": "dotenv -e ./.env -e ../../.env -- next start", "start": "dotenv -e ./.env -e ../../.env -- next start",
"lint": "dotenv -e ./.env -e ../../.env -- next lint", "lint": "dotenv -e ./.env -e ../../.env -- next lint",
"format:fix": "prettier --write ./src",
"test": "dotenv -e ./.env -e ../../.env -- pnpm playwright test", "test": "dotenv -e ./.env -e ../../.env -- pnpm playwright test",
"test:report": "pnpm playwright show-report" "test:report": "pnpm playwright show-report"
}, },

View File

@ -14,9 +14,9 @@
"db:migrate": "cd packages/prisma && pnpm run db:migrate", "db:migrate": "cd packages/prisma && pnpm run db:migrate",
"generate-change-log": "git fetch --all && pnpx gitmoji-changelog", "generate-change-log": "git fetch --all && pnpx gitmoji-changelog",
"locales:sync": "tolgee sync './apps/builder/src/**/*.ts?(x)' --continue-on-warning --remove-unused", "locales:sync": "tolgee sync './apps/builder/src/**/*.ts?(x)' --continue-on-warning --remove-unused",
"locales:push": "tolgee push ./apps/builder/public/locales",
"locales:pull": "tolgee pull ./apps/builder/public/locales", "locales:pull": "tolgee pull ./apps/builder/public/locales",
"create-new-block": "cd packages/forge/cli && pnpm start" "create-new-block": "cd packages/forge/cli && pnpm start",
"format:fix": "turbo run format:fix"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "7.0.3", "cross-env": "7.0.3",

View File

@ -8,7 +8,8 @@
"scripts": { "scripts": {
"dev": "rollup --watch --config rollup.config.js", "dev": "rollup --watch --config rollup.config.js",
"build": "rollup --config rollup.config.js", "build": "rollup --config rollup.config.js",
"lint": "eslint --fix \"src/**/*.ts*\"" "lint": "eslint --fix \"src/**/*.ts*\"",
"format:fix": "prettier --write ./src"
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@ -8,7 +8,8 @@
"scripts": { "scripts": {
"dev": "rollup --watch --config rollup.config.js", "dev": "rollup --watch --config rollup.config.js",
"build": "rollup --config rollup.config.js", "build": "rollup --config rollup.config.js",
"lint": "eslint --fix \"src/**/*.ts*\"" "lint": "eslint --fix \"src/**/*.ts*\"",
"format:fix": "prettier --write ./src"
}, },
"keywords": [], "keywords": [],
"author": "Baptiste Arnaud", "author": "Baptiste Arnaud",

View File

@ -10,7 +10,8 @@
"stories:build": "ladle build", "stories:build": "ladle build",
"dev": "rollup --watch --config rollup.config.js", "dev": "rollup --watch --config rollup.config.js",
"build": "rollup --config rollup.config.js", "build": "rollup --config rollup.config.js",
"lint": "eslint --fix \"src/**/*.ts*\"" "lint": "eslint --fix \"src/**/*.ts*\"",
"format:fix": "prettier --write ./src"
}, },
"keywords": [], "keywords": [],
"author": "Baptiste Arnaud", "author": "Baptiste Arnaud",

View File

@ -5,6 +5,9 @@
"lint": { "lint": {
"outputs": [] "outputs": []
}, },
"format:fix": {
"outputs": []
},
"dev": { "dev": {
"dependsOn": [ "dependsOn": [
"^dev", "^dev",