Conversation
WalkthroughThis PR addresses multiple frontend improvements: implements user-friendly 2FA error messaging, adds asynchronous copy functionality with debouncing and error handling, expands message role support, swaps UI icon components for semantic consistency, adds visual feedback for selected options via conditional borders, and updates translations across five locales. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
echo/frontend/src/locales/de-DE.po (2)
769-776: Refine / Go deeper / Make it concrete: semantics solid, one micro-phrase nitThe whole “Go deeper / Konkret machen / Verfeinern” cluster is consistent and reads naturally. Placeholders (
{0},{remainingTime}) are preserved, and the participant-facing tone is on point.One tiny polish you might consider:
"Abkühlung läuft. Verfügbar in {0}"→ something like"Abkühlphase. In {0} wieder verfügbar."reads a bit more idiomatic.If you like the current, it’s totally shippable as is.
Also applies to: 1475-1482, 1497-1504, 2527-2529, 3279-3284, 3423-3425, 3880-3883, 4006-4014
1487-1490: Leftover English strings: worth cleaning up while you’re in hereA few visible UI strings are still English in the German locale:
- Line 1489:
"Go back"→ currently"Go back"- Line 2987:
"Settings | Dembrane"→ currently"Settings | Dembrane"- Line 3905–3906:
"Welcome back"→ currently"Welcome back"These weren’t necessarily introduced in this PR, but since you’re already touching adjacent translations, it’s a cheap win to localize them (e.g.
"Zurück","Einstellungen | Dembrane","Willkommen zurück").Also applies to: 2985-2987, 3904-3907
echo/frontend/src/locales/es-ES.po (2)
3648-3658: Normalize Spanish wording for “two‑factor authentication” across all 2FA strings2FA UX is much better now, but the Spanish phrasing oscillates between “autenticación de dos factores” and “autenticación en dos pasos”:
- Line 3650:
Two-factor authentication→Autenticación de dos factores✅- Line 3654:
Two-factor authentication disabled→Autenticación en dos pasos desactivada- Line 3658:
Two-factor authentication enabled→Autenticación en dos pasos activada- Elsewhere you consistently use “autenticación de dos factores” (enable/disable tooltips, error toasts, description text, etc.).
For a polished UX, pick one term and use it everywhere. Given most of the new copy uses “autenticación de dos factores”, I’d standardize on that:
msgid "Two-factor authentication disabled" -msgstr "Autenticación en dos pasos desactivada" +msgstr "Autenticación de dos factores desactivada" msgid "Two-factor authentication enabled" -msgstr "Autenticación en dos pasos activada" +msgstr "Autenticación de dos factores activada"Rest of the 2FA messaging (“Ese código no funcionó…”, “Mantén el acceso seguro…”, etc.) reads solid and user‑friendly.
Also applies to: 308-312, 1081-1084, 1131-1134, 1160-1162, 1679-1682, 3315-3325, 2863-2869
3799-3813: Finish localizing verified‑artefact labels in filtersVerify UX strings are mostly in good shape, but a couple of surface labels stay English:
- Line 3801:
conversation.filters.verified.text→"Verified"(still English)- Line 3812:
verified artifacts→"verified artifacts"(still English)- Nearby, you already have
msgid "Has verified artifacts"→"Tiene artefactos verificados"✅To keep the dashboard coherent in ES:
msgid "conversation.filters.verified.text" -msgstr "Verified" +msgstr "Verificado" msgid "verified artifacts" -msgstr "verified artifacts" +msgstr "artefactos verificados"That keeps filters consistent with “Tiene artefactos verificados”.
Also applies to: 1519-1522
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
echo/frontend/src/components/chat/chatUtils.ts(1 hunks)echo/frontend/src/components/common/CopyRichTextIconButton.tsx(1 hunks)echo/frontend/src/components/conversation/ConversationAccordion.tsx(6 hunks)echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx(2 hunks)echo/frontend/src/components/project/ProjectPortalEditor.tsx(4 hunks)echo/frontend/src/components/settings/TwoFactorSettingsCard.tsx(2 hunks)echo/frontend/src/components/settings/hooks/index.ts(1 hunks)echo/frontend/src/locales/de-DE.po(79 hunks)echo/frontend/src/locales/en-US.po(15 hunks)echo/frontend/src/locales/es-ES.po(87 hunks)echo/frontend/src/locales/fr-FR.po(84 hunks)echo/frontend/src/locales/nl-NL.po(21 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
echo/frontend/**/src/{routes,components}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
echo/frontend/**/src/{routes,components}/**/*.tsx: Compose Mantine primitives (Stack,Group,ActionIcon, etc.) while layering Tailwind utility classes viaclassName, alongside toast feedback via@/components/common/Toaster
For Tailwind classes that need dynamic values, replace with inlinestyleprops using CSS variables instead of hardcoded hex values
Files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsxecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
echo/frontend/**/src/**/*.{css,tsx,ts}
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
Use CSS variables
var(--app-background)andvar(--app-text)instead of hardcoded colors like#F6F4F1or#2D2D2Cto ensure theme changes propagate
Files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/chat/chatUtils.tsecho/frontend/src/components/project/ProjectPortalEditor.tsxecho/frontend/src/components/settings/hooks/index.tsecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
echo/frontend/**/src/{theme.tsx,components,routes}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
When adding new Mantine components, reference the global Mantine theme in
src/theme.tsxwith customprimarycolor palette and component defaults, preferring CSS variables in styles over hardcoded hex values
Files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsxecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
echo/frontend/**/src/{components,routes}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
UI mutations should surface inline feedback: pair toasts with contextual Mantine
Alertcomponents inside modals/forms for errors or warnings
Files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsxecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
echo/frontend/**/src/{components,routes}/**/+(LoginRoute|TwoFactorSettingsCard|*OTP*).tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
OTP entry should use Mantine
PinInputand auto-submit on completion; keep hidden inputs registered when swapping forms
Files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsx
echo/frontend/**/src/components/**/hooks/index.ts
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
In TypeScript/React files, use React Query hook hubs with a
hooks/index.tsexposinguseQuery/useMutationwrappers with shareduseQueryClientinvalidation logic
Files:
echo/frontend/src/components/settings/hooks/index.ts
echo/frontend/**/src/{components,routes}/**/hooks/index.ts
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
Reuse
postDirectusfromsrc/components/settings/hooks/index.tsto stay consistent when making custom Directus POSTs like 2FA
Files:
echo/frontend/src/components/settings/hooks/index.ts
echo/frontend/**/src/{routes/auth,components/settings}/**/hooks/index.ts
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
Auth session state depends on the shared
['auth','session']React Query key; invalidate it on login/logout before fetching['users','me']
Files:
echo/frontend/src/components/settings/hooks/index.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/lib/{directus,api}.ts : Standardize Directus error handling and add localization polish in `src/lib/directus.ts`; custom Directus POSTs should call `directus.request` with a function signature rather than `restRequest`
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{components,routes}/**/*.tsx : UI mutations should surface inline feedback: pair toasts with contextual Mantine `Alert` components inside modals/forms for errors or warnings
Learnt from: ussaama
Repo: Dembrane/echo PR: 205
File: echo/frontend/src/lib/query.ts:1444-1506
Timestamp: 2025-07-10T12:48:20.683Z
Learning: ussaama prefers string concatenation over template literals for simple cases where readability is clearer, even when linting tools suggest template literals. Human readability takes precedence over strict linting rules in straightforward concatenation scenarios.
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/auth/**/*.tsx : Directus login surfaces 2FA by responding with `INVALID_OTP`; toggle an OTP field in the login form and retry using `useLoginMutation`. Reuse this pattern when touching other auth entry points
Applied to files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/fr-FR.poecho/frontend/src/components/settings/hooks/index.tsecho/frontend/src/locales/nl-NL.poecho/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{components,routes}/**/+(LoginRoute|TwoFactorSettingsCard|*OTP*).tsx : OTP entry should use Mantine `PinInput` and auto-submit on completion; keep hidden inputs registered when swapping forms
Applied to files:
echo/frontend/src/components/settings/TwoFactorSettingsCard.tsxecho/frontend/src/components/settings/hooks/index.tsecho/frontend/src/locales/nl-NL.poecho/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{routes,components}/**/*.tsx : Compose Mantine primitives (`Stack`, `Group`, `ActionIcon`, etc.) while layering Tailwind utility classes via `className`, alongside toast feedback via `@/components/common/Toaster`
Applied to files:
echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/**/*.tsx : Use Lingui macros `t` from `lingui/core/macro` and `Trans` from `lingui/react/macro` for localizing UI strings in routed screens
Applied to files:
echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/fr-FR.poecho/frontend/src/components/common/CopyRichTextIconButton.tsxecho/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{theme.tsx,components,routes}/**/*.tsx : When adding new Mantine components, reference the global Mantine theme in `src/theme.tsx` with custom `primary` color palette and component defaults, preferring CSS variables in styles over hardcoded hex values
Applied to files:
echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/conversation/ConversationAccordion.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{components,routes}/**/*.tsx : UI mutations should surface inline feedback: pair toasts with contextual Mantine `Alert` components inside modals/forms for errors or warnings
Applied to files:
echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/settings/hooks/index.tsecho/frontend/src/components/common/CopyRichTextIconButton.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/settings/**/*.tsx : Provide ergonomic navigation in settings-like routes: breadcrumb + back action (ActionIcon + navigate(-1)) with relevant iconography is the default
Applied to files:
echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/locales/fr-FR.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/components/chat/**/*.tsx : Chat modes have dedicated accent colors (Overview: Spring Green `#1EFFA1`, Deep Dive: Cyan `#00FFFF`) defined in `src/components/chat/ChatModeSelector.tsx` (`MODE_COLORS`); keep these hardcoded for consistent mode identification
Applied to files:
echo/frontend/src/components/chat/chatUtils.tsecho/frontend/src/components/conversation/ConversationAccordion.tsx
📚 Learning: 2025-05-30T15:38:44.413Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/components/project/ProjectPortalEditor.tsx:409-464
Timestamp: 2025-05-30T15:38:44.413Z
Learning: Badge-based selectors in ProjectPortalEditor.tsx: Keyboard navigation enhancements for accessibility are considered optional improvements rather than critical issues. The user acknowledges these suggestions but doesn't prioritize them as blockers.
Applied to files:
echo/frontend/src/components/project/ProjectPortalEditor.tsx
📚 Learning: 2025-10-28T13:47:02.926Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 350
File: echo/frontend/src/components/participant/ParticipantConversationText.tsx:82-85
Timestamp: 2025-10-28T13:47:02.926Z
Learning: In text mode (echo/frontend/src/components/participant/ParticipantConversationText.tsx), participants only submit PORTAL_TEXT chunks (no audio). The “Finish” button is shown only after at least one text message is saved to Directus.
Applied to files:
echo/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/fr-FR.po
📚 Learning: 2025-08-19T10:14:31.647Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 266
File: echo/frontend/src/components/chat/ChatAccordion.tsx:214-221
Timestamp: 2025-08-19T10:14:31.647Z
Learning: In the Echo frontend codebase using Lingui, i18n IDs in Trans components (e.g., `<Trans id="any.string.here">`) can be arbitrary strings and don't need to follow specific naming conventions. They are just references used in .po files, and the actual translations need to be manually defined in the locale files.
Applied to files:
echo/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/fr-FR.poecho/frontend/src/locales/en-US.po
📚 Learning: 2025-09-16T08:34:38.109Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 293
File: echo/frontend/src/components/chat/ChatTemplatesMenu.tsx:15-16
Timestamp: 2025-09-16T08:34:38.109Z
Learning: In ChatTemplatesMenu.tsx, titles are preferred over IDs for template selection logic since titles are unique one-liners and work effectively as identifiers. IDs were added primarily for better list rendering rather than selection purposes.
Applied to files:
echo/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/fr-FR.po
📚 Learning: 2025-05-30T15:36:40.131Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/locales/fr-FR.po:521-523
Timestamp: 2025-05-30T15:36:40.131Z
Learning: In the French localization file (fr-FR.po), "Dembrane Echo" is intentionally translated as "Echo Dembrane" for better French language flow and natural sound. This is not an error but a deliberate localization choice.
Applied to files:
echo/frontend/src/locales/fr-FR.po
📚 Learning: 2025-05-30T15:37:46.279Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/locales/fr-FR.po:1298-1301
Timestamp: 2025-05-30T15:37:46.279Z
Learning: In French localization files, UI terms like "Portail" should maintain their proper capitalization according to French language conventions, even if it appears inconsistent with lowercase usage in other translations. French capitalization rules for UI terms should be respected over assumed consistency patterns.
Applied to files:
echo/frontend/src/locales/fr-FR.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{components,routes}/**/hooks/index.ts : Reuse `postDirectus` from `src/components/settings/hooks/index.ts` to stay consistent when making custom Directus POSTs like 2FA
Applied to files:
echo/frontend/src/components/settings/hooks/index.ts
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/lib/{directus,api}.ts : Standardize Directus error handling and add localization polish in `src/lib/directus.ts`; custom Directus POSTs should call `directus.request` with a function signature rather than `restRequest`
Applied to files:
echo/frontend/src/components/settings/hooks/index.ts
📚 Learning: 2025-07-10T12:47:06.269Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 205
File: echo/frontend/src/locales/nl-NL.po:1246-1247
Timestamp: 2025-07-10T12:47:06.269Z
Learning: .po files (gettext internationalization files) are auto-generated by i18n tools like lingui/cli and should not be manually edited. The format of component paths and line numbers in these files is determined by the tool configuration, not manually written. Do not suggest manual edits to .po files.
Applied to files:
echo/frontend/src/locales/en-US.po
📚 Learning: 2025-06-06T05:43:44.935Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 180
File: echo/frontend/src/locales/es-ES.ts:1-1
Timestamp: 2025-06-06T05:43:44.935Z
Learning: When users indicate they have already addressed translation issues in locale files, verify the current state before assuming the issue persists. Translation files are often updated in bulk and previously flagged English text may have been properly localized.
Applied to files:
echo/frontend/src/locales/en-US.po
🧬 Code graph analysis (2)
echo/frontend/src/components/settings/hooks/index.ts (1)
echo/frontend/src/components/common/Toaster.tsx (1)
toast(38-38)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (3)
echo/frontend/src/config.ts (1)
ENABLE_CHAT_AUTO_SELECT(45-45)echo/frontend/src/components/conversation/AutoSelectConversations.tsx (1)
AutoSelectConversations(23-175)echo/frontend/src/components/chat/ChatModeSelector.tsx (1)
MODE_COLORS(23-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ci-check-server
🔇 Additional comments (22)
echo/frontend/src/locales/de-DE.po (3)
777-789: Copy‑chat UX strings: LGTM and match the new behaviorThe copy states cluster looks tight:
"Copied"→"Kopiert""Copy"/"Copy secret"→"Kopieren"/"Geheimnis kopieren""Copying..."→"Kopieren..."(fine for an in‑progress label)"Failed to copy chat. Please try again."→"Fehler beim Kopieren des Chats. Bitte versuchen Sie es erneut."Semantics and tone are correct and should support the “Copy full chat” behavior cleanly.
Also applies to: 798-802, 807-810, 814-817, 1263-1266
1516-1519: Verified artefact filters: terminology is coherentFor the verified‑artefact UX:
"Has verified artifacts"→"Hat verifizierte Artefakte""verified artifacts"filter label →"verifizierte Artefakte""conversation.filters.verified.text"→"Verifiziert"This is internally consistent (noun vs. adjective label) and matches the rest of the “Artefakt/Artefakte” terminology in this locale. No placeholder or meaning issues here.
Also applies to: 3795-3798, 3805-3808
421-424: Concrete topics / Make it concrete UX: copy is aligned and clearThe “Make it concrete / Concrete Topics” UX strings look well wired:
- Constraint message:
"At least one topic must be selected to enable Make it concrete"→"Wähle mindestens ein Thema, um Konkret machen zu aktivieren"is concise and matches the feature behavior.- Titles and labels (
"Concrete Topics","Konkrete Themen","dashboard.dembrane.concrete.topic.select","Wähl ein konkretes Thema aus.","No concrete topics available.") are consistent and understandable.- Library / “Library” / “Bibliothek” references in this block are coherent.
From a product UX standpoint, this copy should make the selected/deselected states around concrete topics much easier to parse.
Also applies to: 653-656, 1695-1717, 1785-1788, 1990-1993, 2935-2938
echo/frontend/src/locales/en-US.po (1)
725-1471: 2FA & copy UX strings are wired up correctly in en-US localeNew/updated entries for 2FA enable/disable flows and chat copy status (
Authenticator code, “The code didn't work…”, “Two-factor authentication…”, “Copying…”, “Failed to copy chat. Please try again.”) line up with the component changes and keep wording consistent across flows. No manual tweaks needed here; this file should stay tool-generated. Based on learnings, .po stays auto-managed.Also applies to: 1590-1593, 4030-4261
echo/frontend/src/components/chat/chatUtils.ts (1)
18-22: Includingassistantrole informatMessageis the right moveAllowing
"assistant"through the role guard ensures assistant messages hit the formatter and get labeled viaassistantName, while still dropping unknown roles. No regressions in the existing user/dembrane path.echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx (1)
9-11: ThemeIcon swap makes the artefact badge clearly non-interactiveGood call replacing the ActionIcon with a
ThemeIconin the header: keeps the verified mark visually prominent, removes misleading click affordance, and still exposes anaria-labelfor accessibility. Matches the pattern you’re using elsewhere for verified indicators.Also applies to: 89-97
echo/frontend/src/components/project/ProjectPortalEditor.tsx (1)
641-645: Selected badges now have a clean, theme-aware affordanceThe conditional
border: "1px solid var(--mantine-color-primary-5)"on the reply-mode and concrete-topic badges is a nice, minimal way to signal selection state. You keep opacity/cursor semantics as before, use Mantine’s CSS var instead of hardcoded colors, and hit the UX goal of making selected vs deselected options immediately obvious.Also applies to: 672-675, 701-705, 856-863
echo/frontend/src/components/conversation/ConversationAccordion.tsx (4)
414-418: Duration pill rendering is correctly guardedRendering the duration badge only when
conversation.duration > 0andshowDurationis true is the right balance: no noise for empty/zero durations, and you reuse the existingfDurationformatter, so no extra surface area.
552-561: Verified artefact indicator is now clearly status-onlySwapping the verified marker to a
ThemeIconwithcursor: "default"removes the old “clickable icon” vibe while keeping the tooltip and aria-label. That nails the requirement to avoid misleading click affordance on the verify badge in the conversation list.
910-921: Auto-select card is scoped correctly to deep-dive chats + feature flagThe auto-select block only shows in chat mode, not in overview, respects the
ENABLE_CHAT_AUTO_SELECTfeature flag, and hides when there are no conversations. TheLoadingOverlaytied toconversationsQuery.isLoadingkeeps the UX clean while initial data is streaming.
1255-1259: Paging loader uses the deep-dive accent color nicelyShowing a centered
LoaderwhileisFetchingNextPageis true, and tinting it withMODE_COLORS.deep_dive.primary, gives clear feedback that more conversations are loading and keeps the visual language consistent with chat mode colors.echo/frontend/src/components/settings/TwoFactorSettingsCard.tsx (1)
284-294: Disable-2FA inline error messaging is now user-friendly and consistent
getDisableTwoFactorErrorMessagemirrors the enable helper: defaulting to a clear “We couldn’t disable…” message and remapping the"Invalid payload. \"otp\" is invalid"case toThe code didn't work, please try again.Wiring the Alert to this helper in the disable modal keeps the UX consistent with the toasts from the hooks layer.Also applies to: 396-401
echo/frontend/src/components/common/CopyRichTextIconButton.tsx (1)
1-47: Async copy flow + loading state is tightWrapping
copy(markdown)in anisLoading-guarded async handler, disabling the button while in-flight, and driving the tooltip/icon offisLoading/copiedhits the UX brief: no accidental double-copies, clear “Copying…” feedback, and a localized toast on failure. The implementation is small, composable, and fits cleanly on top ofuseCopyToRichText.echo/frontend/src/locales/fr-FR.po (6)
454-457: Ship it—2FA translations are clean and user-friendly.All 2FA-related strings use natural, accessible French without technical jargon. Error messages like "Ce code n'a pas fonctionné. Réessayez avec un nouveau code" are clear and actionable, aligning with ECHO-591's objective to replace technical errors with user-facing messages.
Also applies to: 680-682, 804-805, 956-967, 1083-1084, 1131-1138, 1159-1182, 2164-2165, 2846-2847, 3317-3324, 3648-3659
783-791: LGTM—copy flow translations are solid.New async copy functionality strings (
"Copying...","Copied","Failed to copy chat") support the expanded CopyRichTextIconButton behavior described in the PR summary. French translations are natural and consistent with existing patterns.Also applies to: 817-819, 1266-1268
177-184: All systems go on audit translations, boss.Audit log strings use consistent, professional French terminology. "Journaux d'audit" is the correct standard term, and all related UI elements (filters, export, loading states, errors) follow proper conventions.
Also applies to: 241-248, 441-451, 1392-1407, 1642-1644, 1771-1787, 1979-1980, 2057-2059, 2804-2806, 3107-3109, 3677-3680
328-395: Verification strings are locked in.All artefact/verification translations use correct French spelling ("artefact" not "artifact") and provide clear, natural instructions. Success messages, error states, and user guidance are properly localized and consistent with the "Make it concrete" feature.
Also applies to: 1262-1268, 1293-1330, 1521-1522, 1534-1535, 1661-1662, 1765-1766, 1778-1779, 2092-2094, 2112-2118, 2335-2336, 2565-2567, 2638-2640, 2669-2670, 2818-2819, 3132-3134, 3499-3506, 3638-3640, 3661-3676, 3683-3684, 4015-4022
426-427: Rest of the translations check out.General UI strings are well-localized with proper French conventions. The intentional mix of formal ("vous") and informal ("tu") address aligns with context—participant-facing features use "tu" for approachability while settings use "vous" for professionalism. Feature names like "Va plus profond" and "Rends-le concret" are consistent throughout.
Also applies to: 778-779, 1129-1130, 1358-1359, 1411-1412, 1492-1493, 1501-1507, 1573-1574, 1840-1846, 2230-2234, 2335-2336, 2595-2596, 2774-2775, 2899-2900, 2943-2944, 2993-2994, 3124-3125, 3264-3265, 3430-3431, 3914-3915, 3953-3954
101-101: LGTM but verify quote rendering, chief.The translation
"\"Refine\" Bientôt disponible"includes escaped quotes around "Refine". Confirm these render as intended in the UI—most similar feature-unavailable strings don't include quotes (see lines 1358, 2230-2233 for comparison).[scratchpad_end] -->
⛔ Skipped due to learnings
Learnt from: ussaama Repo: Dembrane/echo PR: 169 File: echo/frontend/src/locales/fr-FR.po:521-523 Timestamp: 2025-05-30T15:36:40.131Z Learning: In the French localization file (fr-FR.po), "Dembrane Echo" is intentionally translated as "Echo Dembrane" for better French language flow and natural sound. This is not an error but a deliberate localization choice.Learnt from: ussaama Repo: Dembrane/echo PR: 180 File: echo/frontend/src/locales/es-ES.ts:1-1 Timestamp: 2025-06-06T05:43:44.935Z Learning: When users indicate they have already addressed translation issues in locale files, verify the current state before assuming the issue persists. Translation files are often updated in bulk and previously flagged English text may have been properly localized.Learnt from: ussaama Repo: Dembrane/echo PR: 205 File: echo/frontend/src/locales/nl-NL.po:1246-1247 Timestamp: 2025-07-10T12:47:06.269Z Learning: .po files (gettext internationalization files) are auto-generated by i18n tools like lingui/cli and should not be manually edited. The format of component paths and line numbers in these files is determined by the tool configuration, not manually written. Do not suggest manual edits to .po files.Learnt from: ussaama Repo: Dembrane/echo PR: 169 File: echo/frontend/src/locales/fr-FR.po:1298-1301 Timestamp: 2025-05-30T15:37:46.279Z Learning: In French localization files, UI terms like "Portail" should maintain their proper capitalization according to French language conventions, even if it appears inconsistent with lowercase usage in other translations. French capitalization rules for UI terms should be respected over assumed consistency patterns.Learnt from: ussaama Repo: Dembrane/echo PR: 169 File: echo/frontend/src/locales/fr-FR.po:1778-1780 Timestamp: 2025-05-30T15:37:29.029Z Learning: Translation and localization suggestions should be treated as preferences rather than errors. Different phrasings in target languages can be equally valid, and users may have specific reasons for choosing particular translations.echo/frontend/src/locales/nl-NL.po (3)
834-873: LGTM – Copy flow translations ship ready.New entries for
Copying...andFailed to copy chatnail the async feedback pattern. These map to ECHO-553 (full chat copy) and provide clean UX states. Dutch phrasing (Kopieren...progressive,Gekopieerdpast) matches established conventions in the file.
2828-2838: LGTM – 2FA strings level up the user experience.Translations for
Two-factor authentication disabled/enableduse natural Dutch (uitgezet/aangezetinstead of technical terms). Error messageCode werkt niet, probeer het nog een keerhits the ECHO-591 objective—way friendlier thanInvalid Payload, 'otp' is invalid. Clean alignment with the Directus INVALID_OTP flow pattern.Also applies to: 3482-3487
1-4247: Ship it – Translation updates are production-ready.This PR delivers clean Dutch localization for new features:
- ✅ Async copy states with user feedback (ECHO-553)
- ✅ User-friendly 2FA messaging (ECHO-591)
- ✅ Consistent terminology (
Ga dieper,Transcriptie, etc.)- ✅ Valid PO syntax, no missing translations
Reference line updates are maintenance overhead from code moves—totally normal. If you haven't already, run the updated strings by a native Dutch speaker for final polish, but structure and consistency are solid.
| if (error.message.includes('Invalid payload. "otp" is invalid')) { | ||
| toast.error(t`The code didn't work, please try again.`); | ||
| } else { | ||
| toast.error(error.message); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Disable-2FA error handling now matches the enable path
Mirroring the "Invalid payload. \"otp\" is invalid" check here keeps the disable flow on the same friendly, localized toast (The code didn't work, please try again.) instead of leaking the raw Directus error. If you ever want to DRY this up, a tiny shared helper for the OTP mapping used by both enable/disable hooks would do it, but not a blocker.
🤖 Prompt for AI Agents
In echo/frontend/src/components/settings/hooks/index.ts around lines 76 to 80,
the disable-2FA error branch currently shows the raw Directus error message
instead of the friendly localized toast used by the enable flow; update the
error handling to check for the same Invalid payload. "otp" is invalid condition
and call toast.error(t`The code didn't work, please try again.`) in that case,
otherwise fall back to toast.error(error.message). Optionally extract that
OTP-mapping check into a small shared helper used by both enable/disable
handlers to avoid duplication.
| #. js-lingui-explicit-id | ||
| #: src/components/layout/TransitionCurtainProvider.tsx:143 | ||
| msgid "We're preparing your workspace." | ||
| msgstr "We're preparing your workspace." | ||
| msgstr "Wir bereiten deinen Arbeitsbereich vor." | ||
|
|
There was a problem hiding this comment.
Workspace preload copy: align register with the rest of auth UI
"Wir bereiten deinen Arbeitsbereich vor." is friendly but switches to informal du while most auth/onboarding copy in this locale uses formal Sie. Consider "Wir bereiten Ihren Arbeitsbereich vor." for consistency, unless you’re intentionally moving the whole auth flow to du.
🤖 Prompt for AI Agents
In echo/frontend/src/locales/de-DE.po around lines 42 to 46, the German
translation uses informal "deinen" (Wir bereiten deinen Arbeitsbereich vor.)
which is inconsistent with the rest of the auth/onboarding UI that uses formal
"Sie"; change the msgstr to the formal form "Wir bereiten Ihren Arbeitsbereich
vor." to match the existing tone across the auth flow.
| #: src/components/settings/TwoFactorSettingsCard.tsx:176 | ||
| msgid "Account password" | ||
| msgstr "Account password" | ||
| msgstr "Konto-Passwort" | ||
|
|
||
| #: src/components/settings/AuditLogsCard.tsx:274 | ||
| msgid "Action By" | ||
| msgstr "Action By" | ||
| msgstr "Aktion von" | ||
|
|
||
| #: src/components/settings/AuditLogsCard.tsx:255 | ||
| msgid "Action On" | ||
| msgstr "Action On" | ||
| msgstr "Aktion am" | ||
|
|
There was a problem hiding this comment.
Audit log table + filters: copy is accurate; a couple of style nits
Overall, the audit‑logs translations are solid and preserve meaning and placeholders:
- Columns:
"Account password","Collection","IP Address","Timestamp","Type"→ all mapped correctly. - Filters and loading/empty states (
"Filter audit logs by action","Loading actions...","No audit logs match the current filters.","Rows per page","Showing {displayFrom}–{displayTo} ...) look good.
Minor stylistic tweaks you might consider for more idiomatic German:
"Action By"→"Aktion von"is understandable;"Ausgeführt von"or"Durchgeführt von"would read more naturally for an audit column."Action On"→"Aktion am"is okay but"Zeitpunkt"or"Ausgeführt am"might communicate intent more clearly.
None of these are blockers; the current strings are perfectly shippable.
Also applies to: 241-248, 638-641, 1389-1404, 1768-1784, 1966-1977, 2818-2821, 3651-3659, 3713-3716
| #. js-lingui-explicit-id | ||
| #: src/components/participant/ParticipantConversationAudio.tsx:266 | ||
| msgid "participant.modal.refine.info.title.generic" | ||
| msgstr "\"Refine\" available soon" | ||
| msgstr "\"Refinar\" Disponible pronto" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Tighten and align the “Refine / Make it concrete / Go deeper” “coming soon” and cooldown copy
The refine/verify cluster is almost there but a bit inconsistent stylistically:
- Line 101:
msgstr "\"Refinar\" Disponible pronto"– mixed casing and bare quotes read a bit rough. - Line 1358:
msgstr "Función disponible pronto"– generic, no mention of which feature. - Line 3430:
msgstr "Esta función estará disponible en {remainingTime} segundos."– clearer and more user‑friendly. - Elsewhere (
participant.refine.make.concrete.*,participant.refine.go.deeper.*) you’ve got nice, conversational Spanish.
I’d align all the “coming soon / cooldown” messages to the clearer pattern you’re already using (line 3430) and keep names consistent:
Example tweak:
msgid "participant.modal.refine.info.title.generic"
-msgstr "\"Refinar\" Disponible pronto"
+msgstr "La función \"Refinar\" estará disponible pronto"
msgid "participant.modal.refine.info.title"
-msgstr "Función disponible pronto"
+msgstr "Esta función estará disponible pronto"You can keep:
msgid "participant.modal.refine.info.available.in"
msgstr "Esta función estará disponible en {remainingTime} segundos."as the canonical cooldown phrasing. That way all refine‑related gating text feels like one coherent system.
Also applies to: 1356-1358, 3428-3431, 772-779, 1477-1485, 2528-3290
| #: src/components/settings/TwoFactorSettingsCard.tsx:431 | ||
| #: src/components/settings/TwoFactorSettingsCard.tsx:436 | ||
| msgid "Copy secret" | ||
| msgstr "Copy secret" | ||
|
|
There was a problem hiding this comment.
Localize “Copy secret” to match rest of 2FA copy flow
You’ve got a clean 2FA flow, but this one string is still English in the ES bundle while the success state is localized.
msgid "Copy secret"→msgstr "Copy secret"(English)msgid "Secret copied"→msgstr "Secreto copiado"(correct)
Recommend aligning:
msgid "Copy secret"
-msgstr "Copy secret"
+msgstr "Copiar secreto"Everything else in the copy/secret cluster looks tight.
Also applies to: 2890-2893
🤖 Prompt for AI Agents
In echo/frontend/src/locales/es-ES.po around lines 801-805 (and also at lines
~2890-2893), the msgid "Copy secret" remains untranslated; change the msgstr
from "Copy secret" to the Spanish equivalent (e.g., "Copiar secreto") so it
matches the rest of the 2FA copy flow; update both occurrences and keep
quotation/PO formatting intact.
Summary by CodeRabbit
Release Notes
New Features
Improvements
Localization
✏️ Tip: You can customize this high-level summary in your review settings.