Skip to content

ECHO-473 ECHO-448 Make tags searchable#304

Merged
spashii merged 3 commits intomainfrom
filters-update
Sep 22, 2025
Merged

ECHO-473 ECHO-448 Make tags searchable#304
spashii merged 3 commits intomainfrom
filters-update

Conversation

@ussaama
Copy link
Copy Markdown
Contributor

@ussaama ussaama commented Sep 19, 2025

Summary by CodeRabbit

  • New Features

    • Tag-based filtering in Conversations: search tags, multi-select tags, removable selected-tag pills, and tag-filtered conversation list.
    • Options toggle showing Sort and Tags menus, filter count badge, loading/empty states, and “Reset All Options.”
  • UI Changes

    • Removed “Show duration” toggle from sort options.
    • Minor spacing/layout adjustments; conversation emptiness check improved.
  • Chores

    • Updated translations (en, de, es, fr, nl): added “Search tags”/“Tags”, deprecated “Show duration”, German auth message tweak, and small Dutch preview-label adjustments.

@linear
Copy link
Copy Markdown

linear bot commented Sep 19, 2025

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 19, 2025

Walkthrough

Adds tag-based filtering to ConversationAccordion: fetches project tags, provides searchable multi-select tag UI, applies tag filters to the infinite conversations query, updates filter UI/menus and emptiness checks, and adjusts localization entries for new strings and location shifts. LGTM.

Changes

Cohort / File(s) Summary
Conversation UI / Data
echo/frontend/src/components/conversation/ConversationAccordion.tsx
Adds project tag fetch (useProjectById), tagSearch and selectedTagIds state, derives filteredProjectTags, applies tags._some filter to conversations/count queries, replaces options menu with toggle + Sort and Tags menus, adds filter badge/count, resetEverything, new UI controls (search, tag pills, checkboxes, loader, No tags found), layout spacing tweaks, imports Divider, IconTags, IconChevronDown, IconChevronUp.
Locales (.po) updates
echo/frontend/src/locales/en-US.po, echo/frontend/src/locales/de-DE.po, echo/frontend/src/locales/es-ES.po, echo/frontend/src/locales/fr-FR.po, echo/frontend/src/locales/nl-NL.po
Add new msgids (e.g., "Tags", "Search tags"), move/relocate many source-location references to reflect TSX changes, add/move "No tags found", and mark "Show duration" obsolete in some locales; translations themselves largely unchanged.
Locales (.ts) minimal changes
echo/frontend/src/locales/en-US.ts, echo/frontend/src/locales/de-DE.ts, echo/frontend/src/locales/es-ES.ts, echo/frontend/src/locales/nl-NL.ts
Minor/no-op edits and one small text adjustment in de-DE.ts ("You are not authenticated"); exports and runtime behavior unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The PR satisfies the core "make tags searchable" objective from [ECHO-448] — the raw summary documents tagSearch state, filteredProjectTags, selectedTagIds, and query filtering via tags._some — but I find no evidence in the provided diff summary that it implements "select conversations for a tag in Chat Mode" or the required error flow when selections exceed the context limit; [ECHO-473] has no actionable details in the summary. Add or point to the changes that implement conversation selection in Chat Mode and the context-limit error flow (or update the PR description to show where those behaviors live), include tests or a short manual-test note, then request re-check for full compliance.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "ECHO-473 ECHO-448 Make tags searchable" succinctly names the primary change (making tags searchable) and references the relevant issue keys, so it is clear and informative for a teammate scanning PR history.
Out of Scope Changes Check ✅ Passed The changes appear scoped to ConversationAccordion UI and related localization files to support searchable tags, plus minor UI/layout tweaks; I do not see unrelated backend/API edits or features outside the linked issues' scope.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch filters-update

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
echo/frontend/src/locales/de-DE.po (1)

1416-1420: Minor style nit (optional): “Loading...”

“Laden...” is acceptable; “Wird geladen...” feels a bit more native for progressive status. Non-blocking.

 msgid "Loading..."
-msgstr "Laden..."
+msgstr "Wird geladen..."
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 7480c38 and aee79e5.

📒 Files selected for processing (10)
  • echo/frontend/src/components/conversation/ConversationAccordion.tsx (10 hunks)
  • echo/frontend/src/locales/de-DE.po (30 hunks)
  • echo/frontend/src/locales/de-DE.ts (1 hunks)
  • echo/frontend/src/locales/en-US.po (30 hunks)
  • echo/frontend/src/locales/en-US.ts (1 hunks)
  • echo/frontend/src/locales/es-ES.po (30 hunks)
  • echo/frontend/src/locales/es-ES.ts (1 hunks)
  • echo/frontend/src/locales/fr-FR.po (30 hunks)
  • echo/frontend/src/locales/nl-NL.po (30 hunks)
  • echo/frontend/src/locales/nl-NL.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T10:22:55.323Z
Learnt from: ussaama
PR: Dembrane/echo#266
File: echo/frontend/src/components/conversation/ConversationAccordion.tsx:675-678
Timestamp: 2025-08-19T10:22:55.323Z
Learning: In echo/frontend/src/components/conversation/hooks/index.ts, the useConversationsCountByProjectId hook uses useSuspenseQuery with Directus aggregate, which always returns string numbers like "0", "1", "2" and suspends during loading instead of returning undefined. Therefore, Number(conversationsCountQuery.data) ?? 0 is safe and the Number() conversion is necessary for type conversion from string to number.

Applied to files:

  • echo/frontend/src/components/conversation/ConversationAccordion.tsx
🧬 Code graph analysis (3)
echo/frontend/src/locales/es-ES.ts (1)
echo/frontend/src/locales/en-US.ts (1)
  • messages (1-1)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (1)
echo/frontend/src/components/project/hooks/index.ts (1)
  • useProjectById (213-238)
echo/frontend/src/locales/de-DE.ts (1)
echo/frontend/src/locales/en-US.ts (1)
  • messages (1-1)
⏰ 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 (16)
echo/frontend/src/locales/de-DE.ts (1)

1-1: Formatting-only changes, LGTM

The German locale file shows no semantic changes - just a formatting update to the translated messages JSON. The export signature remains unchanged and the functionality is identical. Clean diff for tag search UI localization support.

echo/frontend/src/locales/en-US.ts (1)

1-1: No functional changes detected, ship it

Pure formatting change on the en-US locale - the minified JSON structure and export remain identical. Zero impact on runtime behavior or translation logic.

echo/frontend/src/locales/nl-NL.ts (1)

1-1: EOF newline addition only, good to merge

Just adding a trailing newline to the Dutch locale file. No changes to the actual translations or export structure. Consistent with standard formatting practices.

echo/frontend/src/locales/es-ES.ts (1)

1-1: Spanish locale unchanged semantically, looks solid

The ES translation file remains functionally identical - same export pattern and message structure. Zero behavioral impact, just part of the broader tag filtering UI internationalization work.

echo/frontend/src/locales/en-US.po (1)

1678-1682: “No tags found” — LGTM

String and references look consistent with the new tag picker.

echo/frontend/src/locales/de-DE.po (3)

2235-2238: New key “Search tags” — passt

“Tags suchen” reads well and matches other search labels. LGTM.


617-620: Sort option labels — consistent and natural

“Längste zuerst,” “Neueste zuerst,” “Älteste zuerst,” “Kürzeste zuerst,” and “Name A‑Z/Z‑A” are idiomatic. Good to ship.

Also applies to: 1437-1440, 1533-1536, 1670-1672, 2353-2355, 1498-1505, 1502-1505


2235-2238: LGTM — locale coverage verified

Both "Search tags" and "No tags found" are present in nl-NL, en-US, es-ES, fr-FR and de-DE .po files; no action required.

echo/frontend/src/locales/es-ES.po (1)

2239-2241: LGTM! Clean translation addition.

The new Spanish translations for tag search functionality are properly formatted and consistent with the existing translation patterns.

echo/frontend/src/components/conversation/ConversationAccordion.tsx (4)

658-686: Solid tag fetching implementation.

The minimal query approach fetching only necessary tag fields is efficient. The memoized filtering logic handles the search case well.


701-713: Clean tag filter integration into the conversation query.

The conditional filter construction using _some with project_tag_id.id._in is the right approach for filtering conversations by multiple tags while preserving the project scope.


1035-1058: Nice tag pill management UX.

The selected tags display with remove buttons provides clear visual feedback. Good defensive check for missing tags before rendering.


862-863: Good fix for the zero-state check.

Using totalConversations instead of checking the filtered query results prevents the search bar from disappearing when users have conversations but none match current filters.

echo/frontend/src/locales/fr-FR.po (2)

2453-2456: “Sort” — good.

“Trier” matches UX convention. LGTM.


1636-1640: Replace inconsistent FR translation: use "étiquettes" instead of "tags"

echo/frontend/src/locales/fr-FR.po:2241 — msgstr "Rechercher des tags" should be "Rechercher des étiquettes" to match "Aucune étiquette trouvée". LGTM after fix.

Likely an incorrect or invalid review comment.

echo/frontend/src/locales/nl-NL.po (1)

1803-1806: “No tags found” — good.

Matches “trefwoorden” choice. LGTM.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (15)
echo/frontend/src/locales/de-DE.po (1)

603-610: Fix compound noun: Gesprächsstatus

German genitive “s” is missing in two places.

Apply this diff:

 msgid "Conversation Status"
-msgstr "Gesprächstatus"
+msgstr "Gesprächsstatus"

 msgid "Conversation Status Details"
-msgstr "Gesprächstatusdetails"
+msgstr "Gesprächsstatusdetails"
echo/frontend/src/locales/nl-NL.po (1)

93-101: Externalize toggle labels “Hide Preview” / “Show Preview”

Inline English is used at echo/frontend/src/components/project/ProjectPortalEditor.tsx:262: {showPreview ? "Hide Preview" : "Show Preview"}. Extraction produced a placeholder "{0}" in echo/frontend/src/locales/nl-NL.po, so the labels stay untranslated.

  • Change to conditional translations: showPreview ? tHide Preview : tShow Preview (or explicit i18n keys).
  • Add PO entries for both literals in echo/frontend/src/locales/nl-NL.po (example):
+# Toggle labels
+msgid "Hide Preview"
+msgstr "Voorbeeld verbergen"
+
+msgid "Show Preview"
+msgstr "Voorbeeld tonen"
echo/frontend/src/locales/en-US.po (1)

1-15: PO header hygiene

Plural-Forms is empty. Set it to avoid plural edge cases.

 "Plural-Forms: \n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"

Optionally populate Last-Translator/PO-Revision-Date.

echo/frontend/src/locales/es-ES.po (5)

211-214: Fix gender agreement ("archivos" is masculine).

Apply:

-msgstr "Todas las archivos se han subido correctamente."
+msgstr "Todos los archivos se han subido correctamente."

946-949: Spanish phrasing: use “conversación” (feminine).

-msgstr "Ingresa un nombre para el nuevo conversation"
+msgstr "Ingresa un nombre para la nueva conversación"

2713-2715: Natural Spanish for “prompt”.

-msgstr "Esta prompt guía cómo la IA responde a los participantes. Personaliza la prompt para formar el tipo de retroalimentación o participación que quieres fomentar."
+msgstr "Este prompt guía cómo la IA responde a los participantes. Personaliza el prompt para definir el tipo de retroalimentación o participación que quieres fomentar."

2985-2987: Add inverted question mark.

-msgstr "Quieres añadir una plantilla a ECHO?"
+msgstr "¿Quieres añadir una plantilla a ECHO?"

3087-3089: Correct reflexive verb (“desuscribir” → “desuscribir(se)”).

-msgstr "Has desuscribido con éxito."
+msgstr "Te has desuscrito con éxito."
echo/frontend/src/locales/fr-FR.po (6)

271-282: Typo: “superficieles” → “superficielles”.

-"Aller au-delà des comparaisons superficieles\n"
+"Aller au-delà des comparaisons superficielles\n"

946-949: Agreement: “la nouvelle conversation”.

-msgstr "Entrez un nom pour le nouveau conversation"
+msgstr "Entrez un nom pour la nouvelle conversation"

1515-1517: Agreement in label.

-msgstr "Nom du nouveau conversation"
+msgstr "Nom de la nouvelle conversation"

2186-2188: Correct noun form.

-msgstr "La rétranscrire a commencé. La nouvelle conversation sera disponible bientôt."
+msgstr "La retranscription a commencé. La nouvelle conversation sera disponible bientôt."

2669-2674: Article for “e-mail”.

-msgstr "Cette e-mail est déjà dans la liste."
+msgstr "Cet e-mail est déjà dans la liste."

And:

-#~ msgstr "Cette e-mail est déjà abonnée aux notifications."
+#~ msgstr "Cet e-mail est déjà abonné aux notifications."

3009-3012: Conjugation (“nous vous enverrons”).

-msgstr "Nous vous envoyerons un message uniquement si votre hôte génère un rapport, nous ne partageons jamais vos informations avec personne. Vous pouvez vous désinscrire à tout moment."
+msgstr "Nous vous enverrons un message uniquement si votre hôte génère un rapport, nous ne partageons jamais vos informations avec personne. Vous pouvez vous désinscrire à tout moment."
echo/frontend/src/components/conversation/ConversationAccordion.tsx (1)

602-616: Remove unused “totalConversationsQuery”.

Dead fetch wastes a network call; count now comes from useConversationsCountByProjectId.

-  const totalConversationsQuery = useConversationsByProjectId(
-    projectId,
-    false,
-    false,
-    {
-      limit: 1,
-      deep: {
-        // @ts-expect-error chunks is not typed
-        chunks: {
-          _limit: 25,
-        },
-      },
-    },
-  );
+  // Removed redundant list fetch; count handled by useConversationsCountByProjectId
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 7480c38 and aee79e5.

📒 Files selected for processing (10)
  • echo/frontend/src/components/conversation/ConversationAccordion.tsx (10 hunks)
  • echo/frontend/src/locales/de-DE.po (30 hunks)
  • echo/frontend/src/locales/de-DE.ts (1 hunks)
  • echo/frontend/src/locales/en-US.po (30 hunks)
  • echo/frontend/src/locales/en-US.ts (1 hunks)
  • echo/frontend/src/locales/es-ES.po (30 hunks)
  • echo/frontend/src/locales/es-ES.ts (1 hunks)
  • echo/frontend/src/locales/fr-FR.po (30 hunks)
  • echo/frontend/src/locales/nl-NL.po (30 hunks)
  • echo/frontend/src/locales/nl-NL.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T10:22:55.323Z
Learnt from: ussaama
PR: Dembrane/echo#266
File: echo/frontend/src/components/conversation/ConversationAccordion.tsx:675-678
Timestamp: 2025-08-19T10:22:55.323Z
Learning: In echo/frontend/src/components/conversation/hooks/index.ts, the useConversationsCountByProjectId hook uses useSuspenseQuery with Directus aggregate, which always returns string numbers like "0", "1", "2" and suspends during loading instead of returning undefined. Therefore, Number(conversationsCountQuery.data) ?? 0 is safe and the Number() conversion is necessary for type conversion from string to number.

Applied to files:

  • echo/frontend/src/components/conversation/ConversationAccordion.tsx
🧬 Code graph analysis (3)
echo/frontend/src/locales/es-ES.ts (1)
echo/frontend/src/locales/en-US.ts (1)
  • messages (1-1)
echo/frontend/src/locales/de-DE.ts (1)
echo/frontend/src/locales/en-US.ts (1)
  • messages (1-1)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (1)
echo/frontend/src/components/project/hooks/index.ts (1)
  • useProjectById (213-238)
🔇 Additional comments (31)
echo/frontend/src/locales/en-US.ts (1)

1-1: LGTM — compiled Lingui catalog; verification blocked by ripgrep

rg reported "No files were searched", so I couldn't confirm the new message IDs or UI references across locales. Re-run these checks locally/CI and ensure catalogs are generated (don't hand-edit compiled files):

keys=(lnWve4 ekUnNJ OYHzN1 WRRjA9)
for k in "${keys[@]}"; do rg -nS "$k" frontend/src/locales || echo "MISSING $k"; done

rg -nP -C2 --type=tsx 'Search tags|Select tags|No tags found' frontend/src/components || echo "UI refs missing"

rg -n --max-count 1 '/\*eslint-disable\*/import type\{Messages\}from"@lingui/core";export const messages=JSON\.parse' frontend/src/locales/en-US.ts || echo "Catalog format unexpected"

Do not hand-edit compiled locales; update via lingui extract/compile.

echo/frontend/src/locales/de-DE.po (7)

2235-2238: Add: “Search tags” — LGTM

Translation is clear and consistent with existing “Search …” patterns.


2218-2221: Search UX copy — LGTM

Conversations/Projects search strings read well and match tone elsewhere.

Also applies to: 2226-2229, 2231-2234


1437-1440: Sort labels — LGTM

Comparatives are correct: Längste/Kürzeste/Neueste/Älteste zuerst.

Also applies to: 1533-1536, 1669-1672, 2352-2355


187-190: Chat add/remove labels — LGTM

Wording is natural and consistent.

Also applies to: 227-230, 2072-2075


2449-2452: “Sort” — LGTM

Verb form “Sortieren” aligns with other menu actions.


617-620: Bulk locale shifts — LGTM

These relocations/translations look solid and consistent.

Also applies to: 889-893, 1721-1725, 431-434, 559-562, 847-850, 1493-1497, 1498-1505, 1476-1479, 1481-1484, 2267-2270, 2548-2552, 2557-2560, 1416-1420, 1674-1677, 1591-1594, 1942-1945, 2915-2918


2235-2238: Search tags present in all locales — fix duplicate msgids in de-DE.po and verify build

Found msgid "Search tags" in de-DE, en-US, es-ES, fr-FR, nl-NL. Sanity check shows duplicate msgid entries in echo/frontend/src/locales/de-DE.po — remove/merge those duplicates and run the locale compilation to confirm a clean build.

echo/frontend/src/locales/nl-NL.po (7)

2764-2768: “Tags” → “Trefwoorden” consistency LGTM

Matches existing Dutch across the product. No action needed.


1599-1602: Sort option labels read cleanly

“Langste/Kortste/Nieuwste/Oudste eerst” and “Naam A‑Z/Z‑A” are idiomatic.

Also applies to: 1695-1698, 1839-1842, 2569-2571, 1661-1667


2425-2428: Search/Options/Sort UI labels — solid

Clear and consistent with the rest of the UI.

Also applies to: 939-946, 1895-1899


203-206: Chat selection controls — good coverage

“Toevoegen/Al toegevoegd/Verwijderen” are concise and consistent.

Also applies to: 255-258, 2279-2282


2100-2103: Status/empty/upload labels — LGTM

Terminology aligns with other screens.

Also applies to: 1006-1010, 3170-3172


2351-2353: “Reset All Options” — LGTM

Clear action phrasing.


2883-2886: Trim trailing space & improve phrasing in nl-NL.po — verify source msgid

Trailing space in msgstr and awkward word order. Suggested change (echo/frontend/src/locales/nl-NL.po:2883-2886):

 msgid "This conversation is still being processed. It will be available for analysis and chat shortly. "
-msgstr "Dit gesprek wordt nog verwerkt. Het zal beschikbaar zijn voor analyse en chat binnenkort. "
+msgstr "Dit gesprek wordt nog verwerkt. Het zal binnenkort beschikbaar zijn voor analyse en chat."

src/components/conversation/ConversationAccordion.tsx was not found in the repo; confirm whether the English msgid contains the trailing space and remove it in the source if present.

echo/frontend/src/locales/nl-NL.ts (2)

1-1: LGTM: new tag-search strings are present and export shape is intact.

"Zoek tags" (lnWve4) and "Selecteer tags" (ekUnNJ) exist; import/type assertion pattern is standard for Lingui bundles. Ship it.


1-1: Verify 'lnWve4' and 'ekUnNJ' exist across all locale bundles.

Automated check couldn't find src/locales (locales are under echo/frontend/src/locales). Run: rg -nF -e 'lnWve4' -e 'ekUnNJ' echo/frontend/src/locales -S and confirm both keys appear in every locale .ts to avoid fallback-to-English.

echo/frontend/src/locales/en-US.po (2)

2297-2300: Good: new tag-searching strings are present

“Search tags”, “Tags”, and “Text” entries exist and map to ConversationAccordion. This unblocks the feature UI.

If you want, I can generate a quick grep to confirm these ids match current callsites in ConversationAccordion.tsx.

Also applies to: 2608-2614, 2620-2622


638-641: Confirm key relocations — verified.
Both msgids exist in en-US.po and are correctly referenced by ConversationAccordion.tsx: "Conversations" → en-US.po (msgid at ~line 639) → ConversationAccordion.tsx:843; "No tags found" → en-US.po (msgid at ~line 1678) → ConversationAccordion.tsx:1096. LGTM.

echo/frontend/src/locales/de-DE.ts (1)

1-1: Blocker: placeholder mismatch in library.generate.duration.message

File: echo/frontend/src/locales/de-DE.ts

- "library.generate.duration.message":[ "Die Bibliothek wird ",["duration"]," dauern." ],
+ "library.generate.duration.message":[ "Die Generierung der Bibliothek kann bis zu einer Stunde dauern." ],
echo/frontend/src/locales/es-ES.ts (1)

1-1: Verify es-ES locale keys — automated extraction failed

Automated extraction returned empty JSON; cannot confirm keys in echo/frontend/src/locales/es-ES.ts. If those keys are present, apply these fixes:

- "library.generate.duration.message":["La biblioteca tardará ",["duration"]],
+ "library.generate.duration.message":["Generar la biblioteca puede tardar hasta una hora."],

- "participant.button.stop.no":["Detener"],
+ "participant.button.stop.no":["No"],

- "participant.button.stop.yes":["Detener"],
+ "participant.button.stop.yes":["Sí"],

- "participant.ready.to_begin.button.text":["¿Listo para comenzar?"],
+ "participant.ready.to.begin.button.text":["Siguiente"]

Run the extraction locally or open echo/frontend/src/locales/es-ES.ts to confirm and commit.

echo/frontend/src/components/conversation/ConversationAccordion.tsx (10)

39-40: Import looks good.

Divider is used later in the Tags menu.


66-69: New icons LGTM.

Used for Options/Tags toggles.


657-687: Tags fetch: tight and efficient.

Minimal payload + sorted tags. Casting is acceptable given Directus types.

If tags volume can exceed ~1k, consider server‑side search or client‑side virtualization to keep the menu snappy. Want a quick PR to add virtualization when tags.length > 500?


749-759: filterApplied logic LGTM.

It properly reflects search/sort/tag changes.


767-770: State for filter menus: clean and explicit.

No concerns.


777-779: Reset handler covers new tags state.

Nice touch to clear tagSearch alongside selections.


852-913: Options toggle UX is solid; prevents accordion collapse.

Good use of stopPropagation and a compact badge indicator.


915-975: Sort menu implementation LGTM.

Simple, accessible, and wired to session‑persisted state.


1133-1160: Infinite list rendering LGTM.

Load‑more sentinel is correctly attached to last item.


701-714: Verify Directus M2M filter shape for tags.

File: echo/frontend/src/components/conversation/ConversationAccordion.tsx (lines 701–714)

Directus accepts both forms — explicit _some with project_tag_id._in or _some with project_tag_id.id._in (and _some is often implicit). Keep the current nested .id form if the junction row stores an object; simplify to project_tag_id: { _in: [...] } (or "tags.project_tag_id": { _in: [...] }) if it stores scalar IDs.

Suggested diffs (pick the one matching your junction shape):

-        ...(selectedTagIds.length > 0 && {
-          tags: {
-            _some: {
-              project_tag_id: {
-                id: { _in: selectedTagIds },
-              },
-            },
-          },
-        }),
+        ...(selectedTagIds.length > 0 && {
+          tags: {
+            _some: {
+              project_tag_id: { _in: selectedTagIds },
+            },
+          },
+        }),

Or:

+        ...(selectedTagIds.length > 0 && {
+          "tags.project_tag_id": { _in: selectedTagIds },
+        }),

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (2)

761-764: Remove unused dependency from appliedFiltersCount.

sortBy isn’t used in the computation; drop it (or drop useMemo entirely).

-const appliedFiltersCount = useMemo(() => {
-  return selectedTagIds.length;
-}, [sortBy, selectedTagIds.length]);
+const appliedFiltersCount = useMemo(() => selectedTagIds.length, [selectedTagIds.length]);

1067-1082: Simplify checkbox updater; redundant includes check.

Since checked controls state, just add/remove. Guard via Set to avoid duplicates.

 onChange={(e) => {
   const isChecked = e.currentTarget.checked;
   setSelectedTagIds((prev) => {
-    if (isChecked) {
-      if (prev.includes(tag.id)) return prev;
-      return [...prev, tag.id];
-    }
-    return prev.filter((id) => id !== tag.id);
+    if (isChecked) return Array.from(new Set([...prev, tag.id]));
+    return prev.filter((id) => id !== tag.id);
   });
 }}
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between aee79e5 and de9a7ca.

📒 Files selected for processing (1)
  • echo/frontend/src/components/conversation/ConversationAccordion.tsx (10 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T10:22:55.323Z
Learnt from: ussaama
PR: Dembrane/echo#266
File: echo/frontend/src/components/conversation/ConversationAccordion.tsx:675-678
Timestamp: 2025-08-19T10:22:55.323Z
Learning: In echo/frontend/src/components/conversation/hooks/index.ts, the useConversationsCountByProjectId hook uses useSuspenseQuery with Directus aggregate, which always returns string numbers like "0", "1", "2" and suspends during loading instead of returning undefined. Therefore, Number(conversationsCountQuery.data) ?? 0 is safe and the Number() conversion is necessary for type conversion from string to number.

Applied to files:

  • echo/frontend/src/components/conversation/ConversationAccordion.tsx
🧬 Code graph analysis (1)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (1)
echo/frontend/src/components/project/hooks/index.ts (1)
  • useProjectById (213-238)
🔇 Additional comments (8)
echo/frontend/src/components/conversation/ConversationAccordion.tsx (8)

657-673: Tags fetch: solid, minimal payload, sorted. LGTM.

Fetching only id/text/sort and applying deep sort is the right call. Keeps payload lean and order deterministic.


680-687: Tag search filter reads well. LGTM.

Trim+lowercase and safe null handling are on point.


749-759: Filter badge highlight condition is accurate. LGTM.

Boolean correctly reflects search, non-default sort, or tag selection.


883-910: Mantine color token: verify primary usage.

ActionIcon color/c often expects a theme color (e.g., "blue") or CSS var. If your theme doesn’t alias primary, this renders wrong.

Safer:

-<ActionIcon
-  variant="outline"
-  color={filterApplied ? "primary" : "gray"}
-  c={filterApplied ? "primary" : "gray"}
+<ActionIcon
+  variant="outline"
+  color={filterApplied ? "blue" : "gray"}

If you do have a primary alias in theme, ignore and keep as-is.


913-972: Sort menu UX is clean. Reset action is a nice touch. LGTM.


974-1011: Tags button label UX: crisp. LGTM.

Showing the selected-count badge next to “Tags” communicates state well.


1060-1100: Loading/empty states: tidy. LGTM.

Loader height and “No tags found” fallback are well handled inside the scroll area.

Also applies to: 1092-1096


701-714: Double-check Directus M2M filter shape for tags.

Search output didn’t surface the hook forwarding the filter or the conversation.tags relation shape — Directus M2M filters can be either nested (object) or direct FK. If selecting tags returns no results, switch to the FK _in form:

-          tags: {
-            _some: {
-              project_tag_id: {
-                id: { _in: selectedTagIds },
-              },
-            },
-          },
+          tags: {
+            _some: {
+              project_tag_id: { _in: selectedTagIds },
+            },
+          },

@spashii spashii added this pull request to the merge queue Sep 22, 2025
Merged via the queue into main with commit 67a5e0f Sep 22, 2025
11 checks passed
@spashii spashii deleted the filters-update branch September 22, 2025 11:05
spashii pushed a commit that referenced this pull request Nov 18, 2025
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- New Features
- Tag-based filtering in Conversations: search tags, multi-select tags,
removable selected-tag pills, and tag-filtered conversation list.
- Options toggle showing Sort and Tags menus, filter count badge,
loading/empty states, and “Reset All Options.”

- UI Changes
  - Removed “Show duration” toggle from sort options.
- Minor spacing/layout adjustments; conversation emptiness check
improved.

- Chores
- Updated translations (en, de, es, fr, nl): added “Search tags”/“Tags”,
deprecated “Show duration”, German auth message tweak, and small Dutch
preview-label adjustments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants