Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 28, 2025

Adds a part of speech filter to the browse view, matching the visual design of the existing semantic domain filter.

image

The collapsible filter section also now has a max-height and scrolls, so it doesn't hog the whole screen:
image

@coderabbitai
Copy link

coderabbitai bot commented Oct 28, 2025

📝 Walkthrough

Walkthrough

This PR enhances field editors (select and multi-select) with improved handling of missing labels using "Untitled" fallbacks, ellipsis overflow styling, and adjusted command list heights. A new PartOfSpeechSelect component is introduced for grammatical filtering in the browse interface, integrated into SearchFilter. Translations are added across multiple locales for the new UI strings.

Changes

Cohort / File(s) Summary
Field Editor UI Enhancements
frontend/viewer/src/lib/components/field-editors/select.svelte, multi-select.svelte
Adds "Untitled" fallback labels for missing values, applies ellipsis and margin styling for text truncation, reduces command list max-height from 50vh to 40vh, changes option value composition to concatenate label with item id, updates conditional class logic to handle label presence.
Button Component Styling
frontend/viewer/src/lib/components/ui/button/x-button.svelte
Adds bg-background class to Button component for background color styling.
Part of Speech Filter Component
frontend/viewer/src/project/browse/filter/PartOfSpeechSelect.svelte
New Svelte component for filtering entries by part of speech; wires to current view and writing system service, provides options via partsOfSpeech data source, uses localized placeholder and best-alternative label selection.
Browse Filter Integration
frontend/viewer/src/project/browse/SearchFilter.svelte
Imports and integrates PartOfSpeechSelect component, adds IPartOfSpeech type support, declares partOfSpeech state variable, extends filter construction to include Senses.PartOfSpeechId when set, expands UI with new labeled section for part of speech selection.
Localization Updates
frontend/viewer/src/locales/en.po, es.po, fr.po, id.po, ko.po, ms.po, sw.po
Adds translation entries for new UI strings: "Any grammatical info.", "Any part of speech", "Grammatical info.", "Part of speech" (tied to PartOfSpeechSelect and SearchFilter); expands "Untitled" reference mappings for select and multi-select field editors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • PartOfSpeechSelect component: Verify correct integration with view context, writing system service, and parts of speech data source
  • Value composition changes in select/multi-select: Confirm id concatenation doesn't break existing bindings or option identification logic
  • Locale file consistency: Cross-check that all language files have corresponding translations for new keys and proper reference mappings
  • SearchFilter integration: Ensure filter construction correctly handles undefined partOfSpeech and Senses.PartOfSpeechId filtering logic

Possibly related PRs

Suggested reviewers

  • hahn-kev

Poem

🐰 A filter for speech, a part of the parts,
With ellipsis and "Untitled" to mend broken hearts,
Locale files bloom in seven sweet tongues,
The select component now hums its new songs! ✨

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'Add part of speech filter' directly and clearly summarizes the main change in the changeset. The PR introduces a new PartOfSpeechSelect component, integrates it into SearchFilter.svelte, adds related translations across multiple locales, and makes supporting UI adjustments to select and multi-select components. The title accurately captures the primary objective of adding a part of speech filter to the browse view.
Description check ✅ Passed The pull request description is directly related to the changeset. It explains that the PR adds a part of speech filter to the browse view, matching the visual design of the existing semantic domain filter, and includes screenshots demonstrating the new filter UI and scrollable filter section. This matches the actual changes shown in the file summaries, which include the new PartOfSpeechSelect component and modifications to SearchFilter.svelte.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/add-part-of-speech-filter

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.

Copilot AI changed the title [WIP] Add part of speech filter to interface Add part of speech filter Oct 28, 2025
Copilot AI requested a review from myieye October 28, 2025 16:36
Copy link
Collaborator

@myieye myieye left a comment

Choose a reason for hiding this comment

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

The "Part of speech" field is called "Grammatical info." in the "FieldWorks (Classic)" view.
You used the correct terminology for the FieldWorks Lite view, but need to adapt the FieldWorks (Classic) view.

Please find a good way to use that terminology where you're currently referring to "Parts of speech".

@myieye
Copy link
Collaborator

myieye commented Oct 28, 2025

@copilot see my review

Copy link
Contributor Author

Copilot AI commented Oct 28, 2025

The "Part of speech" field is called "Grammatical info." in the "FieldWorks (Classic)" view.
You used the correct terminology for the FieldWorks Lite view, but need to adapt the FieldWorks (Classic) v...

Updated to use view-based terminology in commit 8dccced:

  • Filter label: "Grammatical info." (Classic) / "Part of speech" (Lite)
  • Placeholder: "Any grammatical info." (Classic) / "Any part of speech" (Lite)

This matches the terminology used in SenseEditorPrimitive.svelte.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fonts.googleapis.com
    • Triggering command: node /home/REDACTED/work/languageforge-lexbox/languageforge-lexbox/frontend/viewer/node_modules/.bin/../vite/bin/vite.js build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from myieye October 28, 2025 19:13
@github-actions github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Oct 29, 2025
@github-actions
Copy link

github-actions bot commented Oct 29, 2025

UI unit Tests

  1 files  ±0   45 suites  ±0   28s ⏱️ -1s
111 tests ±0  111 ✅ ±0  0 💤 ±0  0 ❌ ±0 
160 runs  ±0  160 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 5a86f84. ± Comparison against base commit fa40eb4.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Oct 29, 2025

C# Unit Tests

130 tests  ±0   130 ✅ ±0   20s ⏱️ ±0s
 20 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 5a86f84. ± Comparison against base commit fa40eb4.

♻️ This comment has been updated with latest results.

Copilot AI and others added 10 commits October 29, 2025 17:07
Co-authored-by: myieye <12587509+myieye@users.noreply.github.com>
Co-authored-by: myieye <12587509+myieye@users.noreply.github.com>
Use "Grammatical info." for FieldWorks Classic view and "Part of speech" for FieldWorks Lite view in both the filter label and placeholder text.

Co-authored-by: myieye <12587509+myieye@users.noreply.github.com>
@myieye myieye force-pushed the copilot/add-part-of-speech-filter branch from 41084f2 to 5a86f84 Compare October 29, 2025 16:07
@myieye myieye marked this pull request as ready for review October 29, 2025 16:08
Copy link
Collaborator

@myieye myieye left a comment

Choose a reason for hiding this comment

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

Ran into a little bit of scope creep as I found various nuisances, imperfections in our select components.

@argos-ci
Copy link

argos-ci bot commented Oct 29, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Oct 29, 2025, 4:23 PM

@myieye
Copy link
Collaborator

myieye commented Nov 3, 2025

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa40eb4 and 5a86f84.

📒 Files selected for processing (12)
  • frontend/viewer/src/lib/components/field-editors/multi-select.svelte (4 hunks)
  • frontend/viewer/src/lib/components/field-editors/select.svelte (3 hunks)
  • frontend/viewer/src/lib/components/ui/button/x-button.svelte (1 hunks)
  • frontend/viewer/src/locales/en.po (4 hunks)
  • frontend/viewer/src/locales/es.po (4 hunks)
  • frontend/viewer/src/locales/fr.po (4 hunks)
  • frontend/viewer/src/locales/id.po (4 hunks)
  • frontend/viewer/src/locales/ko.po (4 hunks)
  • frontend/viewer/src/locales/ms.po (4 hunks)
  • frontend/viewer/src/locales/sw.po (4 hunks)
  • frontend/viewer/src/project/browse/SearchFilter.svelte (5 hunks)
  • frontend/viewer/src/project/browse/filter/PartOfSpeechSelect.svelte (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.
📚 Learning: 2025-06-18T05:13:00.591Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Applied to files:

  • frontend/viewer/src/lib/components/field-editors/multi-select.svelte
  • frontend/viewer/src/project/browse/SearchFilter.svelte
  • frontend/viewer/src/project/browse/filter/PartOfSpeechSelect.svelte
  • frontend/viewer/src/lib/components/field-editors/select.svelte
📚 Learning: 2025-07-30T04:53:41.702Z
Learnt from: rmunn
Repo: sillsdev/languageforge-lexbox PR: 1844
File: frontend/viewer/src/lib/entry-editor/ItemListItem.svelte:26-37
Timestamp: 2025-07-30T04:53:41.702Z
Learning: In frontend/viewer/src/lib/entry-editor/ItemListItem.svelte, the TODO comments for unused props `index` and `actions` are intentional reminders for future work to be completed in a separate PR, not issues to be resolved immediately. These represent planned functionality that will be implemented later.

Applied to files:

  • frontend/viewer/src/lib/components/field-editors/multi-select.svelte
  • frontend/viewer/src/locales/en.po
  • frontend/viewer/src/lib/components/field-editors/select.svelte
  • frontend/viewer/src/locales/sw.po
📚 Learning: 2025-06-02T14:27:02.745Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 1720
File: frontend/viewer/src/locales/es.json:1786-1790
Timestamp: 2025-06-02T14:27:02.745Z
Learning: Spanish locale file (frontend/viewer/src/locales/es.json) contains generated code that may have null line numbers in origin entries due to limitations in the code generation process.

Applied to files:

  • frontend/viewer/src/locales/es.po
📚 Learning: 2025-10-06T12:48:36.601Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 2025
File: frontend/viewer/src/locales/sw.po:146-149
Timestamp: 2025-10-06T12:48:36.601Z
Learning: Do not review or comment on `.po` translation files (e.g., files in `frontend/viewer/src/locales/`) in the languageforge-lexbox repository, as translations are managed by Crowdin.

Applied to files:

  • frontend/viewer/src/locales/es.po
  • frontend/viewer/src/locales/en.po
📚 Learning: 2025-08-15T07:32:23.641Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1923
File: frontend/viewer/src/locales/en.po:845-848
Timestamp: 2025-08-15T07:32:23.641Z
Learning: Do not suggest specific translations for missing msgstr entries in locale files. Only identify that translations are missing without proposing the actual translated text.

Applied to files:

  • frontend/viewer/src/locales/es.po
🔇 Additional comments (14)
frontend/viewer/src/lib/components/ui/button/x-button.svelte (1)

15-15: LGTM! Background styling improvement.

The addition of bg-background ensures consistent background styling for the close button across different contexts.

frontend/viewer/src/lib/components/field-editors/multi-select.svelte (4)

166-183: LGTM! Good UX improvements for missing labels.

The addition of overflow-hidden, ellipsis styling, and the "Untitled" fallback text for missing labels improves the component's robustness and visual presentation.


216-216: LGTM! Improved list height constraints.

The responsive height constraints (max-md:h-[300px] md:max-h-[40vh]) ensure the command list remains usable on different screen sizes without occupying too much vertical space.


227-248: LGTM! Consistent fallback styling.

The conditional class for missing labels and the "Untitled" fallback text provide consistent visual feedback when option labels are empty.


225-225: No breaking changes detected—original concern is not valid.

The getHighlightedValue() function retrieves values via the data-value-index attribute (line 160) and returns the corresponding entry from filteredOptions (line 161), not the CommandItem value prop itself. This means the change from label to label.toLocaleLowerCase() + String(id) only affects bits-ui's internal command filtering behavior and does not impact how the multi-select component or external code accesses selected values. No external dependencies on the CommandItem value format were found.

frontend/viewer/src/project/browse/SearchFilter.svelte (5)

22-24: LGTM! Proper imports for the new filter.

The imports for PartOfSpeechSelect and IPartOfSpeech type are correctly added.


46-46: LGTM! State variable follows existing patterns.

The partOfSpeech state variable declaration is consistent with the semanticDomain state variable above it.


79-81: LGTM! Filter logic is correct.

The part of speech filter construction (Senses.PartOfSpeechId=${partOfSpeech.id}) correctly filters entries by the selected part of speech ID, following the same pattern as the semantic domain filter.


124-124: LGTM! Improved scrollability for filter section.

Increasing the max-height to max-h-[calc(65vh-3rem)] with overflow-y-auto ensures the expanded filter section remains scrollable and doesn't dominate the viewport, especially important now with the additional part of speech filter.


150-153: LGTM! Well-integrated part of speech filter UI.

The part of speech filter section follows the same pattern as the semantic domain filter above it, with appropriate labeling using view-specific terminology ("Grammatical info." for classic view, "Part of speech" for lite view).

frontend/viewer/src/project/browse/filter/PartOfSpeechSelect.svelte (1)

1-23: LGTM! Clean implementation of the part of speech filter.

The component follows established patterns and integrates well with existing services (writing system, parts of speech, current view). The use of pickBestAlternative for label selection and pt() for localized placeholders is appropriate.

frontend/viewer/src/lib/components/field-editors/select.svelte (3)

97-106: Good UX improvements for label handling.

The addition of ellipsis truncation and the "Untitled" fallback ensures consistent display when labels are missing or too long. The mr-4 margin provides proper spacing for the chevron/clear buttons.


132-132: Height constraint adjustment improves UX.

Reducing the max height from 50vh to 40vh prevents the dropdown from dominating the screen, which aligns with the PR's goal of making filters more manageable.


136-149: The value composition change is safe and consistent across the codebase.

The value prop in CommandItem is used internally by the Command component for filtering and selection, not parsed by external code. Both select.svelte and multi-select.svelte consistently use the same pattern (label.toLocaleLowerCase() + String(id)), and the onSelect handlers work with the original option object via callback, not the value string. No breaking changes detected.

Copy link
Collaborator

@imnasnainaec imnasnainaec left a comment

Choose a reason for hiding this comment

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

😃 The code looks good.

❓ Could we get some screenshots to show key visual changes?

@myieye
Copy link
Collaborator

myieye commented Nov 4, 2025

😃 The code looks good.

❓ Could we get some screenshots to show key visual changes?

@imnasnainaec there are actually screenshots already at the top.

@imnasnainaec
Copy link
Collaborator

😃 The code looks good.
❓ Could we get some screenshots to show key visual changes?

@imnasnainaec there are actually screenshots already at the top.

@myieye Indeed there are! I saw them at one point, but I think I mentally dismissed them, assuming they hadn't been updated for any of the various subsequent ui tweaks.

@myieye myieye merged commit 6cf4b2a into develop Nov 6, 2025
27 of 28 checks passed
@myieye myieye deleted the copilot/add-part-of-speech-filter branch November 6, 2025 13:13
@myieye myieye linked an issue Nov 13, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Part of speech filter

3 participants