Skip to content

Conversation

@aditya-mitra
Copy link
Contributor

@aditya-mitra aditya-mitra commented Dec 10, 2025

Allow to select all and deselect all when in the translations multi-selector.

feat.mp4

closes #3336

Summary by CodeRabbit

Release Notes

New Features

  • Users can now select an empty language option in the language selector.
  • Batch operation controls ("All" and "None") are now available in translation contexts.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

This PR enables users to deselect all languages in the translation view by expanding batch-operation controls ("All" and "None" buttons) to the translations context, adding an enableEmpty prop to allow empty selections, and adjusting the service logic to preserve empty arrays instead of defaulting to all available languages.

Changes

Cohort / File(s) Summary
Batch Controls & UI Rendering
webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx, webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx
Expanded the condition for displaying "All" and "None" batch-operation buttons to include the 'translations' context; added enableEmpty prop to LanguagesSelect component to allow empty language selection.
Service State Management
webapp/src/views/projects/translations/context/services/useTranslationsService.tsx
Modified selectedLanguages calculation to preserve empty arrays: returns [] when languages is empty (instead of defaulting to all); changed setLanguages to directly preserve the value instead of coercing empty arrays to undefined.

Sequence Diagram

sequenceDiagram
    actor User
    participant LanguagesSelect as LanguagesSelect<br/>(UI Component)
    participant Service as useTranslationsService<br/>(State)
    
    User->>LanguagesSelect: Clicks "None" button
    Note over LanguagesSelect: Batch deselection triggered<br/>(enabled by getLanguagesContent<br/>condition expansion)
    LanguagesSelect->>LanguagesSelect: Set selectedLanguages = []<br/>(enableEmpty allows empty selection)
    LanguagesSelect->>Service: Pass empty array []
    Service->>Service: languages.length === 0<br/>→ Return []<br/>(preserve empty, don't default)
    Service->>Service: setLanguages([])
    Note over Service: Empty array persisted<br/>(not coerced to undefined)
    Service-->>User: Updated state reflects<br/>no selected languages
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Focus areas:
    • Verify that empty array handling in useTranslationsService.tsx does not cause unintended side effects when no languages are selected (e.g., API calls, UI rendering)
    • Confirm the batch "All/None" button visibility logic correctly targets the 'translations' context without affecting other uses
    • Test the enableEmpty prop integration with existing LanguagesSelect consumers to ensure backward compatibility

Possibly related PRs

Suggested reviewers

  • Anty0

Poem

🐰 Click "None" and they all disappear,
No more clicking one by one, my dear,
Empty selections now hold their place,
Switching languages at a faster pace!

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: adding select/deselect all functionality to the translations language selector.
Linked Issues check ✅ Passed The changes implement the requested deselect all functionality for languages in the translation view, directly addressing issue #3336.
Out of Scope Changes check ✅ Passed All changes are focused on the language selector's batch operations and empty state handling, directly supporting the select/deselect all feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df527ba and 6a7914d.

📒 Files selected for processing (3)
  • webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx (1 hunks)
  • webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx (1 hunks)
  • webapp/src/views/projects/translations/context/services/useTranslationsService.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

webapp/**/*.{ts,tsx}: Use TypeScript path aliases (tg.component/, tg.service/, tg.hooks/, tg.views/, tg.globalContext/*) instead of relative imports
After backend API changes, regenerate TypeScript types by running npm run schema (and npm run billing-schema if applicable) in the webapp directory
Use typed React Query hooks from useQueryApi.ts for API communication, not raw React Query
Use Tolgee-specific hooks useReportEvent and useReportOnce from 'tg.hooks/useReportEvent' for business event tracking and analytics

Files:

  • webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx
  • webapp/src/views/projects/translations/context/services/useTranslationsService.tsx
  • webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx
webapp/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Always use data-cy attributes for E2E test selectors, never rely on text content

Files:

  • webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx
  • webapp/src/views/projects/translations/context/services/useTranslationsService.tsx
  • webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx
**/*.{ts,tsx,js,jsx,kt,kts}

⚙️ CodeRabbit configuration file

As part of review, please check if the file follows 'The Stepdown Rule': The most important, high-level concepts should be at the top (like a newspaper headline and opening paragraph). Details should increase as you read downward. Functions should be ordered so that a caller appears before the functions it calls. When working with JavaScript components, we allow the main component to live at the bottom of the file as an exception to the rule.

Files:

  • webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx
  • webapp/src/views/projects/translations/context/services/useTranslationsService.tsx
  • webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx
🔇 Additional comments (4)
webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx (1)

67-68: LGTM!

The expansion of batch operation controls to the translations context aligns perfectly with the PR objective. The logic correctly enables "All" and "None" buttons in the translations language selector.

webapp/src/views/projects/translations/TranslationHeader/TranslationControls.tsx (1)

124-124: LGTM!

The enableEmpty prop correctly enables the "deselect all" functionality in the translations view, fulfilling the PR objective.

webapp/src/views/projects/translations/context/services/useTranslationsService.tsx (2)

180-188: Verify the UX when all languages are deselected.

The logic correctly preserves an empty array as an explicit "no languages selected" state. However, note that when languages = [], the API request (line 138) still includes the base language via addBaseIfMissing. This means the UI shows no languages selected, but the backend queries and returns translations for the base language.

This might be intentional to prevent a completely unusable state, but verify that the UX is clear to users—they might expect to see nothing when they deselect all languages.

Run the following manual test:

  1. Navigate to the translations view
  2. Click "None" to deselect all languages
  3. Verify that the UI clearly indicates what languages are being displayed (if any)
  4. Check if this behavior aligns with user expectations

307-307: LGTM!

The change correctly preserves an empty array as a valid state instead of coercing it to undefined. This is essential for the "deselect all" functionality to work properly.


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.

@JanCizmar
Copy link
Contributor

Thanks! Looks cool.

@ZuzanaOdstrcilova, can you check it?

@JanCizmar
Copy link
Contributor

One thing comes into my mind and that's we have limit that only 10 languages can be selected in the same time. Doesn't it break when I select all?

@aditya-mitra
Copy link
Contributor Author

One thing comes into my mind and that's we have limit that only 10 languages can be selected in the same time. Doesn't it break when I select all?

Let me give it a try today and find out

@ZuzanaOdstrcilova
Copy link
Collaborator

Hey Aditya, I like your ideas, but unfortunately, there's a limit of 10 languages. Someone already asked us about this. We will discuss it internally and let you know. Thank you:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow deselecting all selected languages in translation view

3 participants