🧑💻 Migrate to Tolgee (#976)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ### Summary by CodeRabbit - Refactor: Transitioned to a new translation library (`@tolgee/react`) across the application, enhancing the localization capabilities and consistency. - New Feature: Introduced a JSON configuration file for application settings, improving customization and flexibility. - Refactor: Updated SVG attribute naming convention in the `WhatsAppLogo` component to align with React standards. - Chore: Adjusted the `.gitignore` file and added a new line at the end. - Documentation: Added instructions for setting up environment variables for the Tolgee i18n contribution dev tool, improving the self-hosting configuration guide. - Style: Updated the `CollaborationMenuButton` to hide the `PopoverContent` component by scaling it down to zero. - Refactor: Simplified error handling logic for fetching and updating typebots in `TypebotProvider.tsx`, improving code readability and maintenance. - Refactor: Removed the dependency on the `parseGroupTitle` function, simplifying the code in several components. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -13,7 +13,7 @@ import { WorkspaceInvitation, WorkspaceRole } from '@typebot.io/prisma'
|
||||
import { FormEvent, useState } from 'react'
|
||||
import { Member } from '../types'
|
||||
import { sendInvitationQuery } from '../queries/sendInvitationQuery'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
workspaceId: string
|
||||
@@ -29,7 +29,7 @@ export const AddMemberForm = ({
|
||||
isLoading,
|
||||
isLocked,
|
||||
}: Props) => {
|
||||
const scopedT = useScopedI18n('workspace.membersList')
|
||||
const { t } = useTranslate()
|
||||
const [invitationEmail, setInvitationEmail] = useState('')
|
||||
const [invitationRole, setInvitationRole] = useState<WorkspaceRole>(
|
||||
WorkspaceRole.MEMBER
|
||||
@@ -54,7 +54,7 @@ export const AddMemberForm = ({
|
||||
return (
|
||||
<HStack as="form" onSubmit={handleInvitationSubmit}>
|
||||
<Input
|
||||
placeholder={scopedT('inviteInput.placeholder')}
|
||||
placeholder={t('workspace.membersList.inviteInput.placeholder')}
|
||||
name="inviteEmail"
|
||||
value={invitationEmail}
|
||||
onChange={(e) => setInvitationEmail(e.target.value)}
|
||||
@@ -75,7 +75,7 @@ export const AddMemberForm = ({
|
||||
type="submit"
|
||||
isDisabled={isLoading || isLocked || invitationEmail === ''}
|
||||
>
|
||||
{scopedT('inviteButton.label')}
|
||||
{t('workspace.membersList.inviteButton.label')}
|
||||
</Button>
|
||||
</HStack>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { WorkspaceRole } from '@typebot.io/prisma'
|
||||
import React from 'react'
|
||||
import { convertWorkspaceRoleToReadable } from './AddMemberForm'
|
||||
import { useI18n } from '@/locales'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
image?: string
|
||||
@@ -38,7 +38,7 @@ export const MemberItem = ({
|
||||
onDeleteClick,
|
||||
onSelectNewRole,
|
||||
}: Props) => {
|
||||
const t = useI18n()
|
||||
const { t } = useTranslate()
|
||||
const handleAdminClick = () => onSelectNewRole(WorkspaceRole.ADMIN)
|
||||
const handleMemberClick = () => onSelectNewRole(WorkspaceRole.MEMBER)
|
||||
|
||||
@@ -88,7 +88,7 @@ export const MemberIdentityContent = ({
|
||||
isGuest?: boolean
|
||||
email: string
|
||||
}) => {
|
||||
const t = useI18n()
|
||||
const { t } = useTranslate()
|
||||
|
||||
return (
|
||||
<HStack justifyContent="space-between" maxW="full" p="2">
|
||||
|
||||
@@ -19,11 +19,11 @@ import { updateInvitationQuery } from '../queries/updateInvitationQuery'
|
||||
import { updateMemberQuery } from '../queries/updateMemberQuery'
|
||||
import { Member } from '../types'
|
||||
import { useWorkspace } from '../WorkspaceProvider'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { getSeatsLimit } from '@typebot.io/lib/billing/getSeatsLimit'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
export const MembersList = () => {
|
||||
const scopedT = useScopedI18n('workspace.membersList')
|
||||
const { t } = useTranslate()
|
||||
const { user } = useUser()
|
||||
const { workspace, currentRole } = useWorkspace()
|
||||
const { members, invitations, isLoading, mutate } = useMembers({
|
||||
@@ -103,12 +103,12 @@ export const MembersList = () => {
|
||||
<Stack w="full" spacing={3}>
|
||||
{!canInviteNewMember && (
|
||||
<UnlockPlanAlertInfo>
|
||||
{scopedT('unlockBanner.label')}
|
||||
{t('workspace.membersList.unlockBanner.label')}
|
||||
</UnlockPlanAlertInfo>
|
||||
)}
|
||||
{isDefined(seatsLimit) && (
|
||||
<Heading fontSize="2xl">
|
||||
{scopedT('title')}{' '}
|
||||
{t('workspace.membersList.title')}{' '}
|
||||
{seatsLimit === -1 ? '' : `(${currentMembersCount}/${seatsLimit})`}
|
||||
</Heading>
|
||||
)}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from '@/components/icons'
|
||||
import { PlanTag } from '@/features/billing/components/PlanTag'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
@@ -32,7 +32,7 @@ export const WorkspaceDropdown = ({
|
||||
onLogoutClick,
|
||||
onCreateNewWorkspaceClick,
|
||||
}: Props) => {
|
||||
const scopedT = useScopedI18n('workspace.dropdown')
|
||||
const { t } = useTranslate()
|
||||
const { data } = trpc.workspace.listWorkspaces.useQuery()
|
||||
|
||||
const workspaces = data?.workspaces ?? []
|
||||
@@ -72,14 +72,14 @@ export const WorkspaceDropdown = ({
|
||||
</MenuItem>
|
||||
))}
|
||||
<MenuItem onClick={onCreateNewWorkspaceClick} icon={<PlusIcon />}>
|
||||
{scopedT('newButton.label')}
|
||||
{t('workspace.dropdown.newButton.label')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={onLogoutClick}
|
||||
icon={<LogOutIcon />}
|
||||
color="orange.500"
|
||||
>
|
||||
{scopedT('logoutButton.label')}
|
||||
{t('workspace.dropdown.logoutButton.label')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
|
||||
@@ -12,10 +12,10 @@ import React from 'react'
|
||||
import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon'
|
||||
import { useWorkspace } from '../WorkspaceProvider'
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
|
||||
const scopedT = useScopedI18n('workspace.settings')
|
||||
const { t } = useTranslate()
|
||||
const { workspace, workspaces, updateWorkspace, deleteCurrentWorkspace } =
|
||||
useWorkspace()
|
||||
|
||||
@@ -34,7 +34,7 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
|
||||
return (
|
||||
<Stack spacing="6" w="full">
|
||||
<FormControl>
|
||||
<FormLabel>{scopedT('icon.title')}</FormLabel>
|
||||
<FormLabel>{t('workspace.settings.icon.title')}</FormLabel>
|
||||
<Flex>
|
||||
{workspace && (
|
||||
<EditableEmojiOrImageIcon
|
||||
@@ -51,7 +51,7 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
|
||||
</FormControl>
|
||||
{workspace && (
|
||||
<TextInput
|
||||
label={scopedT('name.label')}
|
||||
label={t('workspace.settings.name.label')}
|
||||
withVariableButton={false}
|
||||
defaultValue={workspace?.name}
|
||||
onChange={handleNameChange}
|
||||
@@ -74,12 +74,12 @@ const DeleteWorkspaceButton = ({
|
||||
workspaceName: string
|
||||
onConfirm: () => Promise<void>
|
||||
}) => {
|
||||
const scopedT = useScopedI18n('workspace.settings')
|
||||
const { t } = useTranslate()
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
return (
|
||||
<>
|
||||
<Button colorScheme="red" variant="outline" onClick={onOpen}>
|
||||
{scopedT('deleteButton.label')}
|
||||
{t('workspace.settings.deleteButton.label')}
|
||||
</Button>
|
||||
<ConfirmModal
|
||||
isOpen={isOpen}
|
||||
@@ -87,7 +87,7 @@ const DeleteWorkspaceButton = ({
|
||||
onClose={onClose}
|
||||
message={
|
||||
<Text>
|
||||
{scopedT('deleteButton.confirmMessage', {
|
||||
{t('workspace.settings.deleteButton.confirmMessage', {
|
||||
workspaceName,
|
||||
})}
|
||||
</Text>
|
||||
|
||||
@@ -24,7 +24,7 @@ import packageJson from '../../../../../../package.json'
|
||||
import { UserPreferencesForm } from '@/features/account/components/UserPreferencesForm'
|
||||
import { MyAccountForm } from '@/features/account/components/MyAccountForm'
|
||||
import { BillingSettingsLayout } from '@/features/billing/components/BillingSettingsLayout'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean
|
||||
@@ -46,7 +46,7 @@ export const WorkspaceSettingsModal = ({
|
||||
workspace,
|
||||
onClose,
|
||||
}: Props) => {
|
||||
const scopedT = useScopedI18n('workspace.settings.modal')
|
||||
const { t } = useTranslate()
|
||||
const { currentRole } = useWorkspace()
|
||||
const [selectedTab, setSelectedTab] = useState<SettingsTab>('my-account')
|
||||
|
||||
@@ -82,7 +82,7 @@ export const WorkspaceSettingsModal = ({
|
||||
justifyContent="flex-start"
|
||||
pl="4"
|
||||
>
|
||||
{scopedT('menu.myAccount.label')}
|
||||
{t('workspace.settings.modal.menu.myAccount.label')}
|
||||
</Button>
|
||||
<Button
|
||||
variant={selectedTab === 'user-settings' ? 'solid' : 'ghost'}
|
||||
@@ -92,12 +92,12 @@ export const WorkspaceSettingsModal = ({
|
||||
justifyContent="flex-start"
|
||||
pl="4"
|
||||
>
|
||||
{scopedT('menu.preferences.label')}
|
||||
{t('workspace.settings.modal.menu.preferences.label')}
|
||||
</Button>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Text pl="4" color="gray.500">
|
||||
{scopedT('menu.workspace.label')}
|
||||
{t('workspace.settings.modal.menu.workspace.label')}
|
||||
</Text>
|
||||
{canEditWorkspace && (
|
||||
<Button
|
||||
@@ -116,7 +116,7 @@ export const WorkspaceSettingsModal = ({
|
||||
justifyContent="flex-start"
|
||||
pl="4"
|
||||
>
|
||||
{scopedT('menu.settings.label')}
|
||||
{t('workspace.settings.modal.menu.settings.label')}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
@@ -127,7 +127,7 @@ export const WorkspaceSettingsModal = ({
|
||||
justifyContent="flex-start"
|
||||
pl="4"
|
||||
>
|
||||
{scopedT('menu.members.label')}
|
||||
{t('workspace.settings.modal.menu.members.label')}
|
||||
</Button>
|
||||
{canEditWorkspace && (
|
||||
<Button
|
||||
@@ -140,7 +140,7 @@ export const WorkspaceSettingsModal = ({
|
||||
overflow="scroll"
|
||||
className="hide-scrollbar"
|
||||
>
|
||||
{scopedT('menu.billingAndUsage.label')}
|
||||
{t('workspace.settings.modal.menu.billingAndUsage.label')}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
@@ -148,7 +148,9 @@ export const WorkspaceSettingsModal = ({
|
||||
|
||||
<Flex justify="center" pt="10">
|
||||
<Text color="gray.500" fontSize="xs">
|
||||
{scopedT('menu.version.label', { version: packageJson.version })}
|
||||
{t('workspace.settings.modal.menu.version.label', {
|
||||
version: packageJson.version,
|
||||
})}
|
||||
</Text>
|
||||
</Flex>
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user