Skip to content

Conversation

hahn-kev
Copy link
Collaborator

This lets users be more specific about their filters.

Here's the UI:
image

on narrow lists:
image

clicking the filter by icon shows labels:
image

you can even filter for multiple or all writing systems
image

Copy link

coderabbitai bot commented Jul 24, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This update introduces advanced filtering capabilities to the search filter UI, including field-based, operation-based, and writing system–based filtering. It adds new Svelte components for operation and writing system selection, extends existing select components for improved styling and icon customization, and enhances the writing system service with "no-audio" filtering options.

Changes

Files/Group Change Summary
frontend/viewer/src/project/browse/SearchFilter.svelte Adds advanced filter UI and logic: field, writing system, and operation selection; integrates new filter state into gridifyFilter.
frontend/viewer/src/project/browse/filter/OpFilter.svelte
frontend/viewer/src/project/browse/filter/WsSelect.svelte
Introduces new components: OpFilter (operation dropdown) and WsSelect (multi-select writing system picker).
frontend/viewer/src/lib/components/field-editors/select.svelte
frontend/viewer/src/lib/components/ui/select/select-trigger.svelte
Extends select components to accept custom class and icon props for improved styling and flexibility.
frontend/viewer/src/lib/writing-system-service.svelte.ts Adds "no-audio" writing system options and exposes corresponding getters and selection logic.
frontend/viewer/src/project/browse/BrowseView.svelte Adds a CSS class to the ResizablePane for layout/styling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • Hide audio writing systems from UI #1659: Both PRs address filtering and display of audio writing systems, with this PR extending UI filtering and the related PR adding backend support for hiding audio writing systems.

Suggested labels

💻 FW Lite

Poem

In the meadow of code, new filters bloom bright,
With WsSelect and OpFilter, the search takes flight.
No-audio writing systems, now easy to find,
While dropdowns and triggers are more refined.
The bunny hops through fields, with joy in its heart—
Advanced filters and UI, a beautiful start!
🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch show-filters

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@hahn-kev hahn-kev requested a review from rmunn July 24, 2025 03:16
@github-actions github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Jul 24, 2025
@hahn-kev hahn-kev requested a review from imnasnainaec July 24, 2025 03:16
Copy link

github-actions bot commented Jul 24, 2025

UI unit Tests

  1 files  ±0   38 suites  ±0   20s ⏱️ ±0s
 80 tests ±0   80 ✅ ±0  0 💤 ±0  0 ❌ ±0 
111 runs  ±0  111 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit a2f549e. ± Comparison against base commit 70c3d7b.

♻️ This comment has been updated with latest results.

Copy link

argos-ci bot commented Jul 24, 2025

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

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jul 24, 2025, 6:38 AM

Copy link

github-actions bot commented Jul 24, 2025

C# Unit Tests

126 tests   126 ✅  12s ⏱️
 20 suites    0 💤
  1 files      0 ❌

Results for commit a2f549e.

♻️ This comment has been updated with latest results.

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: 3

🧹 Nitpick comments (2)
frontend/viewer/src/project/browse/filter/OpFilter.svelte (1)

22-22: Consider a more neutral fallback icon.

The i-mdi-close icon as a fallback might confuse users into thinking it's a clear/cancel button. Consider using a more neutral icon like i-mdi-help or i-mdi-dots-horizontal for unmatched operations.

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

44-45: Consider removing the svelte-ignore directive if not needed.

The // svelte-ignore state_referenced_locally comment on line 44 appears unnecessary since selectedField is properly used in the component. If there's no actual warning from Svelte, this directive can be removed to keep the code clean.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70c3d7b and b675778.

📒 Files selected for processing (7)
  • frontend/viewer/src/lib/components/field-editors/select.svelte (3 hunks)
  • frontend/viewer/src/lib/components/ui/select/select-trigger.svelte (2 hunks)
  • frontend/viewer/src/lib/writing-system-service.svelte.ts (2 hunks)
  • frontend/viewer/src/project/browse/BrowseView.svelte (1 hunks)
  • frontend/viewer/src/project/browse/SearchFilter.svelte (4 hunks)
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte (1 hunks)
  • frontend/viewer/src/project/browse/filter/WsSelect.svelte (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: hahn-kev
PR: sillsdev/languageforge-lexbox#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.
Learnt from: hahn-kev
PR: sillsdev/languageforge-lexbox#1698
File: backend/FwLite/LcmCrdt/Data/Filtering.cs:25-35
Timestamp: 2025-06-13T09:25:37.958Z
Learning: In backend/FwLite/LcmCrdt/Data/Filtering.cs `FtsFilter`, the `&&` combination between the FTS `MATCH` result and the `SearchValue` fallback is intentional to maintain existing search behavior; any future change to use `||` (or another approach) will be considered later.
frontend/viewer/src/lib/components/field-editors/select.svelte (5)

Learnt from: hahn-kev
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.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., onclick={handler}) instead of the Svelte-specific directive syntax (e.g., on:click={handler}) used in previous versions.

Learnt from: hahn-kev
PR: #1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., onclick={handler}) instead of the Svelte-specific directive syntax (e.g., on:click={handler}) used in previous versions.

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

frontend/viewer/src/lib/components/ui/select/select-trigger.svelte (2)

Learnt from: hahn-kev
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.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

frontend/viewer/src/lib/writing-system-service.svelte.ts (1)

Learnt from: rmunn
PR: #1836
File: frontend/viewer/src/lib/components/audio/AudioDialog.svelte:25-25
Timestamp: 2025-07-22T09:19:37.367Z
Learning: In the sillsdev/languageforge-lexbox project, when file size limits or other constants need to be shared between C# backend and TypeScript frontend code, prefer exposing them through Reinforced.Typings type generation rather than hardcoding the values separately. This ensures consistency and prevents discrepancies when values change.

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

Learnt from: hahn-kev
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.

frontend/viewer/src/project/browse/filter/WsSelect.svelte (2)

Learnt from: hahn-kev
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.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

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

Learnt from: hahn-kev
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.

Learnt from: hahn-kev
PR: #1698
File: backend/FwLite/LcmCrdt/Data/Filtering.cs:25-35
Timestamp: 2025-06-13T09:25:37.958Z
Learning: In backend/FwLite/LcmCrdt/Data/Filtering.cs FtsFilter, the && combination between the FTS MATCH result and the SearchValue fallback is intentional to maintain existing search behavior; any future change to use || (or another approach) will be considered later.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

⏰ 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). (7)
  • GitHub Check: Build UI / publish-ui
  • GitHub Check: Build API / publish-api
  • GitHub Check: check-and-lint
  • GitHub Check: Analyze (csharp)
  • GitHub Check: frontend
  • GitHub Check: frontend-component-unit-tests
  • GitHub Check: Build FW Lite and run tests
🔇 Additional comments (16)
frontend/viewer/src/lib/writing-system-service.svelte.ts (4)

18-19: LGTM! Type extension follows existing patterns.

The new audio-filtered writing system selection types are well-named and consistent with the existing type structure.


60-66: Well-implemented filtering logic.

The new getter methods correctly filter out audio writing systems using a clean and readable implementation that builds on existing getters.


93-96: Switch case implementation is correct.

The new cases properly handle the audio-filtered writing system selections by delegating to the appropriate getter methods, maintaining consistency with the existing switch structure.


111-111: Good application of the new filtering capability.

Using vernacularNoAudio for headword extraction makes logical sense, ensuring headwords don't come from audio-only writing systems.

frontend/viewer/src/project/browse/BrowseView.svelte (1)

55-55: Container query class correctly applied.

The @container/list class addition enables responsive styling for the enhanced filter UI within the left pane, which is appropriate for the new advanced filtering functionality.

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

32-32: Standard styling prop addition.

The optional class prop follows common UI component patterns and enables external styling customization.


45-45: Proper implementation of dynamic class handling.

The className extraction and application using the cn() utility correctly enables external styling while preserving existing button classes.

Also applies to: 94-94

frontend/viewer/src/lib/components/ui/select/select-trigger.svelte (3)

5-5: Appropriate typing for customizable icon prop.

The IconClass | null type for downIcon properly enables icon customization or complete removal, with correct TypeScript typing.

Also applies to: 14-14


10-10: Backward-compatible default value.

The default downIcon value maintains existing behavior while enabling customization, ensuring no breaking changes.


27-29: Clean conditional icon rendering.

The truthy check for downIcon properly enables icon customization or removal while maintaining consistent styling when rendered.

frontend/viewer/src/project/browse/filter/OpFilter.svelte (2)

1-3: Well-designed operation type definition.

The Op type provides a comprehensive set of string filtering operations with clear, descriptive names. The module-level export enables proper reuse across components.


20-35: Clean Select component implementation.

The dropdown implementation effectively uses the enhanced Select components with proper value binding, custom trigger styling, and appropriate fallback handling for unmatched operations.

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

1-33: Well-structured writing system selector component

The component is well-implemented with proper Svelte 5 syntax, good internationalization, and clear UI states. The multi-select functionality and display logic for different selection states are well thought out.

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

16-21: LGTM! Appropriate imports for the new filtering functionality.

The new imports align well with the PR objectives to add advanced field filtering capabilities.


120-143: Well-structured responsive layout for the advanced filter UI.

The implementation provides a good user experience with:

  • Logical flow from field selection to filter value input
  • Responsive design that adapts to different screen sizes
  • Proper use of flex layouts and container queries

39-46: Confirmed writing system categories

The literals 'vernacular-no-audio' and 'analysis-no-audio' are defined in WritingSystemService and map correctly to the vernacularNoAudio and analysisNoAudio getters:

  • In frontend/viewer/src/lib/writing-system-service.svelte.ts
    • case 'vernacular-no-audio': returns this.vernacularNoAudio (line 93)
    • case 'analysis-no-audio': returns this.analysisNoAudio (line 96)

No further changes are required.

@rmunn
Copy link
Contributor

rmunn commented Jul 24, 2025

Looks really good! Found one bug. Repro:

  • Load the sena-3 project
  • Filter for gloss, choose Por and Eng writing systems so that the writing system field says "Any ws". Search for "ab". You'll find, among others, the word "sa" with gloss "Habitual".
  • Without closing filter dialog, switch to searching for lexeme form and search for "sa". The writing system field still says "Any ws", but the two vernacular writing systems, seh and Sen, are not checked. The ones that are still checked, Por and Eng, are invisible. And no search results come up for "sa" because that text does not appear in the lexeme form in Por and Eng; it appears in Sen.

Copy link
Contributor

@rmunn rmunn left a comment

Choose a reason for hiding this comment

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

Apart from the one bug I found related to the WS selection not being cleared when switching from analysis (Gloss) to vernacular (Lexeme/Citation), and presumably vice-versa though I didn't test that, this LGTM. There's also a minor UX issue detailed below.

Approving so you don't need to request a re-review once that bug is fixed. The UX issue is really minor, and if it would be difficult to fix can easily wait until a later date, but if it's easy then the fix might as well go in now.

@hahn-kev hahn-kev merged commit e1859b4 into develop Jul 24, 2025
27 checks passed
@hahn-kev hahn-kev deleted the show-filters branch July 24, 2025 07:37
@imnasnainaec
Copy link
Collaborator

This looks like a cool improvement! One little nit... I personally find the "Contains" icon confusing. Since "Starts with" has a [ bracket at the start and "Ends with" has a ] bracket on the end, I would expect the "Contains" icon to be just ... ellipsis without [ ] brackets.

@hahn-kev
Copy link
Collaborator Author

Yeah that's fair, this is the contains icon in the Google icon set, so I'm hoping they did a lot of research about what the right icon should be.

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.

3 participants