Skip to content

feat: add search functionality to filters#349

Merged
michnowak merged 18 commits intomainfrom
feature/search-filter-item
Nov 19, 2025
Merged

feat: add search functionality to filters#349
michnowak merged 18 commits intomainfrom
feature/search-filter-item

Conversation

@michnowak
Copy link
Copy Markdown
Contributor

@michnowak michnowak commented Nov 12, 2025

What does this PR do?

  • My bugfix

Related Ticket(s)

  • Notion Ticket

Key Changes

  • How does the code change address the issue? Describe, at a high level, what was done to affect change.
  • What side effects does this change have? This is the most important question to answer, as it can point out problems where you are making too many changes in one commit or branch. One or two bullet points for related changes may be okay, but five or six are likely indicators of a commit that is doing too many things.

How to test

  • Create a detailed description of what you need to do to set this PR up. ie: Does it need migrations? Do you need to install something?
  • Create a step by step list of what the engineer needs to do to test.

Media (Loom or gif)

  • Insert media here (if applicable)

Summary by CodeRabbit

  • New Features

    • Text search added to invoice list filters (localized) and applied to invoice filtering.
  • Chores

    • Search input now debounces submissions for smoother filtering; stories updated to showcase search and leading-item variants.
    • Input component can hide labels while preserving accessibility (aria support).

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
o2s-docs Skipped Skipped Nov 19, 2025 0:09am

@vercel vercel bot temporarily deployed to Preview – o2s-docs November 12, 2025 14:28 Inactive
@michnowak michnowak marked this pull request as ready for review November 12, 2025 14:39
@michnowak
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 13, 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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 13, 2025

Walkthrough

Adds optional search fields to invoice list request types, introduces a FilterText model and UI input with debounced submit, updates mock mappers to expose and apply search filtering, extends filters typings, updates Storybook, and adds throttle-debounce dependency to UI package.

Changes

Cohort / File(s) Summary
Changeset Documentation
\.changeset/wise-crews-smoke.md
Adds a changeset noting minor version bumps and "Added search functionality to invoice list filters."
Invoice List Block
packages/blocks/invoice-list/src/api-harmonization/invoice-list.request.ts, packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx
Adds optional search?: string to block query types; initializes search in initial filter payload; adds displayField/labelField hints to some DataList column configs.
Framework: Requests & Models
packages/framework/src/modules/invoices/invoices.request.ts, packages/framework/src/utils/models/filters.ts
Adds search?: string to GetInvoiceListQuery; introduces exported FilterText<T> class; extends FilterItem<T> union to include FilterText<T>; updates Filters<T>.items typing to include search.
Mocked Integrations / Mappers
packages/integrations/mocked/src/modules/cms/mappers/blocks/cms.invoice-list.mapper.ts, packages/integrations/mocked/src/modules/invoices/invoices.mapper.ts
Inserts a FilterText search item into CMS mapper for locales (id: search, placeholder, isLeading, isLabelHidden); updates invoices mapper to filter invoices by case-insensitive substring match on invoice.id when query.search is present (applied before other filters).
UI: Components, Stories & Dependencies
packages/ui/package.json, packages/ui/src/components/Filters/FilterItem.tsx, packages/ui/src/components/Filters/Filters.stories.tsx, packages/ui/src/elements/input.tsx
Adds throttle-debounce and its types; renders FilterText using InputWithLabel with a leading Search icon; implements 500ms debounced submit when isLeading; simplifies toggle-group handling; adds isLabelHidden?: boolean to InputWithLabelProps; updates stories and types to include search and new search story variants.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant F as FiltersUI
    participant D as Debouncer (500ms)
    participant API as Invoice Block API
    participant M as Mock Mapper
    participant R as Results

    U->>F: type into search input
    F->>D: onChange -> schedule debounced submit
    D--)API: submit query { search }
    API->>M: mapInvoices(query)
    M->>M: filter invoices where invoice.id contains search (case-insensitive)
    M-->>API: return filtered list
    API-->>R: render filtered invoices
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect debounce implementation, effect cleanup, and ref usage in packages/ui/src/components/Filters/FilterItem.tsx.
  • Verify FilterText<T> export, typings, and Filters<T>.items changes in packages/framework/src/utils/models/filters.ts.
  • Confirm mapper filtering order and case-insensitive substring logic in packages/integrations/mocked/src/modules/invoices/invoices.mapper.ts.
  • Ensure search propagates consistently across block, framework request types, and Storybook updates.
  • Check dependency additions in packages/ui/package.json.

Poem

🐇
I nibble letters, soft and sly,
A tiny search to help rows fly.
Debounced hops send queries light,
IDs shimmer, found by night. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely filled with template placeholders and contains no actual content describing the changes, testing steps, or related tickets. Replace placeholder text with concrete details: describe what the search functionality does, list side effects (new dependencies, API changes to GetInvoiceListBlockQuery, FilterItem types), and provide specific testing instructions.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add search functionality to filters' clearly and concisely summarizes the main change across the PR: introducing search capability to the filters system.
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
  • Commit unit tests in branch feature/search-filter-item

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 385f91d and 34a1794.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • packages/ui/src/components/Filters/FilterItem.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ui/src/components/Filters/FilterItem.tsx
⏰ 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: deploy-preview

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

🧹 Nitpick comments (1)
packages/ui/src/components/Filters/Filters.stories.tsx (1)

243-281: New stories effectively demonstrate search functionality.

The WithSearch and WithSearchLeading stories provide good coverage of the search feature, including the leading item behavior which triggers automatic submission on value change.

Consider adding a story variant with a pre-populated search value to demonstrate how the component handles non-empty initial search state:

+export const WithSearchPreselected: Story = {
+    args: {
+        filters: {
+            ...basicFilters,
+            items: [
+                { ...searchFilterItem, isLeading: true },
+                categoryFilterItem,
+                priceFilterItem,
+                ratingFilterItem,
+                sortFilterItem,
+            ],
+        },
+        initialValues: {
+            category: 'electronics',
+            price: '',
+            rating: [],
+            sort: 'relevance',
+            search: 'laptop',
+        },
+        hasLeadingItem: true,
+    },
+};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 485731c and e2c0b5e.

📒 Files selected for processing (10)
  • .changeset/wise-crews-smoke.md (1 hunks)
  • packages/blocks/invoice-list/src/api-harmonization/invoice-list.request.ts (1 hunks)
  • packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1 hunks)
  • packages/framework/src/modules/invoices/invoices.request.ts (1 hunks)
  • packages/framework/src/utils/models/filters.ts (2 hunks)
  • packages/integrations/mocked/src/modules/cms/mappers/blocks/cms.invoice-list.mapper.ts (3 hunks)
  • packages/integrations/mocked/src/modules/invoices/invoices.mapper.ts (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/Filters/FilterItem.tsx (3 hunks)
  • packages/ui/src/components/Filters/Filters.stories.tsx (7 hunks)
🔇 Additional comments (14)
packages/framework/src/modules/invoices/invoices.request.ts (1)

14-14: LGTM!

The addition of the optional search parameter follows the existing pattern and is consistent with other filter fields.

packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1)

35-35: LGTM!

The search field initialization is consistent with the pattern used for other filters and correctly initializes to an empty string.

packages/integrations/mocked/src/modules/cms/mappers/blocks/cms.invoice-list.mapper.ts (3)

51-57: LGTM!

The FilterText item for search is correctly configured with appropriate localization and isLeading: true for prominent placement.


174-180: LGTM!

The German localization for the search filter is properly configured.


297-303: LGTM!

The Polish localization for the search filter is properly configured.

.changeset/wise-crews-smoke.md (1)

1-8: LGTM!

The changeset correctly documents the feature addition with appropriate minor version bumps for all affected packages.

packages/integrations/mocked/src/modules/invoices/invoices.mapper.ts (1)

222-228: LGTM!

The search implementation is correct and user-friendly:

  • Case-insensitive matching for better UX
  • Searches the invoice ID field as indicated by the placeholder text
  • Properly placed before other filters in the filter chain
packages/blocks/invoice-list/src/api-harmonization/invoice-list.request.ts (1)

9-9: LGTM!

The addition of the optional search parameter is consistent with the framework's request type and follows the existing pattern.

packages/ui/src/components/Filters/FilterItem.tsx (2)

2-9: LGTM!

The new imports are correctly added to support the FilterText functionality.


183-208: FilterText implementation looks good overall.

The FilterText case correctly renders a search input with:

  • Proper field binding
  • Search icon adornment
  • Placeholder text
  • Debounced submission for leading filters

The core logic is sound, pending the debounce timing and cleanup issues noted separately.

packages/ui/src/components/Filters/Filters.stories.tsx (3)

55-56: Type definitions updated consistently.

The FilterType and FilterValues types are correctly extended with the search field, maintaining consistency with the framework changes.


130-135: searchFilterItem definition looks good.

The new filter item is properly typed and includes appropriate labels and placeholder text for a search input.


161-161: All initialValues consistently updated.

The search field is properly initialized to an empty string across all story variants, ensuring consistent behavior.

Also applies to: 175-175, 189-189, 203-203

packages/framework/src/utils/models/filters.ts (1)

50-53: FilterText integration is complete and properly handled in UI rendering.

The verification confirms that packages/ui/src/components/Filters/FilterItem.tsx at line 183 contains a case statement handling 'FilterText', which means the UI component is already set up to render FilterText filter items. The new FilterText class follows the established pattern of other filter types and integrates seamlessly into the existing rendering logic.

@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 09:25 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 09:38 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 09:52 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 13:01 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 14:26 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 15:53 Inactive
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: 1

♻️ Duplicate comments (1)
packages/framework/src/utils/models/filters.ts (1)

9-9: Verify all Filters usages have been updated to include the required search field.

This line introduces a breaking change by requiring search: string on all Filters<T> instances. A previous review identified 12 incompatible usages across the codebase where types are missing the required search field.

Run the following script to verify all affected usages have been updated:

#!/bin/bash
# Description: Verify that all Filters<T> usages now include the required search field

echo "=== Checking model files that define filter types ==="
rg -n "Filters<" --type=ts --type=tsx -A2 -B2 | rg -C3 "(Order|Ticket|Contract|Product|OrderItem|Invoice|Notification)" 

echo -e "\n=== Verifying type definitions include search field ==="
rg -n "type.*=.*\{.*sort.*\}" --type=ts --type=tsx -C3 | rg -C2 "search"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42b37e7 and 915389f.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • packages/framework/src/utils/models/filters.ts (2 hunks)
  • packages/ui/package.json (2 hunks)
  • packages/ui/src/components/Filters/FilterItem.tsx (4 hunks)
  • packages/ui/src/components/Filters/Filters.stories.tsx (7 hunks)
  • packages/ui/src/elements/input.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/ui/package.json
  • packages/ui/src/components/Filters/FilterItem.tsx
🧰 Additional context used
🧬 Code graph analysis (3)
packages/framework/src/utils/models/filters.ts (1)
packages/ui/src/components/Filters/FilterItem.tsx (1)
  • FilterItem (16-217)
packages/ui/src/components/Filters/Filters.stories.tsx (1)
packages/framework/src/utils/models/filters.ts (1)
  • FilterText (50-54)
packages/ui/src/elements/input.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ 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: deploy-preview
🔇 Additional comments (5)
packages/ui/src/elements/input.tsx (1)

129-138: LGTM with dependency on fixing the aria-label computation.

The conditional rendering of the label wrapper and the propagation of aria-label to the Input component are correctly implemented. This approach properly hides the visual label while attempting to maintain accessibility.

Note: This implementation depends on fixing the ariaLabel computation at line 125 to ensure accessibility is maintained in all cases.

packages/ui/src/components/Filters/Filters.stories.tsx (3)

130-135: LGTM!

The searchFilterItem definition is correctly typed as FilterText and includes appropriate label and placeholder properties.


161-161: LGTM!

The search: '' field has been consistently added to initialValues across all story variants, properly satisfying the new type constraint.

Also applies to: 175-175, 189-189, 203-203


243-281: LGTM!

The new stories effectively demonstrate the search filter functionality. WithSearch shows basic usage, while WithSearchLeading showcases advanced features like isLeading and isLabelHidden, providing comprehensive coverage of the new functionality.

packages/framework/src/utils/models/filters.ts (1)

50-54: LGTM!

The FilterText class definition is well-structured and follows the established pattern of other filter classes. The optional isLabelHidden and placeholder properties align with the UI implementation.

@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 16:38 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 13, 2025 16:44 Inactive
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: 0

♻️ Duplicate comments (1)
packages/ui/src/components/Filters/FilterItem.tsx (1)

36-38: Add cleanup for the debounced function to prevent memory leaks.

The debounced function needs to be cancelled on component unmount to prevent calling submitForm after the component has unmounted, which could cause memory leaks or errors.

Apply this diff to add cleanup:

+    useEffect(() => {
+        return () => {
+            onTextFilterChange.cancel?.();
+        };
+    }, [onTextFilterChange]);
+
     const onTextFilterChange = debounce(500, async () => {
         await submitForm();
     });

Note: You may need to wrap onTextFilterChange in useMemo or useCallback to ensure the cleanup effect has a stable reference.

🧹 Nitpick comments (1)
packages/ui/src/components/Filters/FilterItem.tsx (1)

25-34: Consider simplifying by removing refs and useEffects.

As noted in previous review feedback, this ref synchronization pattern adds unnecessary complexity. The debounced function can directly reference isLeading and submitForm without needing refs and useEffect hooks, improving both code clarity and performance.

Based on learnings.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 915389f and d8c070f.

📒 Files selected for processing (2)
  • packages/integrations/mocked/src/modules/cms/mappers/blocks/cms.invoice-list.mapper.ts (3 hunks)
  • packages/ui/src/components/Filters/FilterItem.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/integrations/mocked/src/modules/cms/mappers/blocks/cms.invoice-list.mapper.ts
⏰ 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: Determine which apps changed / dry-run
🔇 Additional comments (4)
packages/ui/src/components/Filters/FilterItem.tsx (4)

2-9: Imports look good.

The new imports (Search icon, useEffect, debounce, InputWithLabel) are all necessary for the text filter functionality.


89-89: Nice simplification of the ALL handling logic.

The direct boolean assignment makes the code clearer and more concise.


151-183: Layout wrapper improves consistency.

The grid container with gap spacing provides better vertical alignment between the label and select elements.


184-213: Text filter implementation looks good, but verify edge case behavior.

The new FilterText case properly implements the search functionality with the isLabelHidden prop addressing previous feedback. The debounced submission is only triggered when isLeading is true at the time of input change.

However, there's a potential edge case: if isLeading changes from true to false during the 500ms debounce delay, the form will still submit when the debounced function executes. Consider whether this edge case needs handling or if it's acceptable in your use case.

Based on learnings.

@marcinkrasowski marcinkrasowski changed the title feat(ui): add search functionality to filters feat: add search functionality to filters Nov 14, 2025
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 14, 2025 13:02 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 19, 2025 11:18 Inactive
@vercel vercel bot temporarily deployed to Preview – o2s-docs November 19, 2025 12:09 Inactive
@michnowak michnowak merged commit 3da2e69 into main Nov 19, 2025
9 checks passed
@michnowak michnowak deleted the feature/search-filter-item branch November 19, 2025 13:16
@coderabbitai coderabbitai bot mentioned this pull request Dec 5, 2025
1 task
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.

2 participants