Skip to content

Conversation

prateekshourya29
Copy link
Member

@prateekshourya29 prateekshourya29 commented Oct 7, 2025

Description

  • Introduced FilterItem and related components for better filter item management.
  • Updated filter configurations to include new properties and support for multiple values.
  • Improved loading states and error handling in filter components.
  • Refactored existing filter logic to streamline operations and enhance performance.
  • Moved AddFilterButton and AddFilterDropdown to a new directory structure for better organization.
  • Updated FilterItemProperty to handle filter selection and condition updates more effectively.
  • Enhanced the FilterInstance class with methods to update condition properties and operators, improving filter management.
  • Added new functionality to handle invalid filter states and improve user feedback.

Type of Change

  • Improvement (change that would cause existing functionality to not work as expected)

Summary by CodeRabbit

  • New Features

    • Added “Created at” and “Updated at” filters.
    • New Add Filter button/dropdown and filter item components, including invalid-state display and close button.
    • Fallback input for unsupported filter types.
  • Improvements

    • Shows loader while filters initialize; smoother row/item transitions.
    • Enhanced dropdown layout, option content, and constrained height.
    • Standardized empty-value placeholder to “--”.
    • Tooltips and right-side content supported in filter options.
    • Better handling of multi-value operators and custom property keys.
    • Exposes members in filter configs.
  • Backend

    • API supports filtering by updated_at.

- Added `AdditionalFilterValueInput` for unsupported filter types.
- Introduced `FilterItem` and related components for better filter item management.
- Updated filter configurations to include new properties and support for multiple values.
- Improved loading states and error handling in filter components.
- Refactored existing filter logic to streamline operations and enhance performance.
Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

Walkthrough

Adds new rich-filters UI components and refactors filter item rendering, introduces an AddFilter button/dropdown split, centralizes placeholder and value-input props, and adds invalid/loader states. Extends config readiness via a new flag and loader utility, broadens operator/type support (multi-value, non-string values), adds created_at/updated_at filters, adjusts dropdown sizing, and updates API filter fields.

Changes

Cohort / File(s) Summary
CE: Filter inputs & config hooks
apps/web/ce/components/rich-filters/filter-value-input/root.tsx, apps/web/ce/helpers/work-item-filters/project-level.ts, apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
Adds AdditionalFilterValueInput fallback; extends HOC params with entityType; hook now exposes areAllConfigsInitialized and members, wires created_at/updated_at configs and loader readiness.
Core Rich Filters: Add filters UI
apps/web/core/components/rich-filters/add-filters/button.tsx, apps/web/core/components/rich-filters/add-filters/dropdown.tsx
Introduces AddFilterButton wrapper and refactors dropdown component/props; selection now calls handleFilterSelect; trims button props and adjusts option layout and max height.
Core Rich Filters: Filter item components
apps/web/core/components/rich-filters/filter-item/... (close-button.tsx, container.tsx, invalid.tsx, loader.tsx, property.tsx, root.tsx)
Componentizes filter item UI with container, property selector, close button, invalid state, and loader; integrates config readiness/validity guards and delegates property updates.
Core Rich Filters: Value input & shared
apps/web/core/components/rich-filters/filter-value-input/... (date/range.tsx, date/single.tsx, select/selected-options-display.tsx, root.tsx), apps/web/core/components/rich-filters/shared.ts
Centralizes EMPTY_FILTER_PLACEHOLDER_TEXT and TFilterValueInputProps; updates placeholders; routes unknown value-input types to AdditionalFilterValueInput.
Core Rich Filters: Filters row/toggle
apps/web/core/components/rich-filters/filters-row.tsx, apps/web/core/components/rich-filters/filters-toggle.tsx
Adds RowTransition and Loader for not-ready state; updates AddFilterButton imports and disables operations when configs aren’t ready.
Work item filters HOC
apps/web/core/components/work-item-filters/filters-hoc/base.tsx, apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx
Propagates areAllConfigsInitialized to configManager.setAreConfigsReady; passes entityType into project-level HOC props builder.
Shared state: Filter store
packages/shared-state/src/store/rich-filters/config-manager.ts, packages/shared-state/src/store/rich-filters/filter-helpers.ts, packages/shared-state/src/store/rich-filters/filter.ts
Adds areConfigsReady flag/action; introduces centralized condition property updater; adds updateConditionProperty API; improves value update guards and equality checks.
Work item adapter
packages/shared-state/src/store/work-item-filters/adapter.ts
Allows customproperty_* keys; types operator as TSupportedOperators; parses multi-value operators via MULTI_VALUE_OPERATORS; relaxes value parsing.
Types: Operators, configs, view props
packages/types/src/rich-filters/operators/... (core.ts, extended.ts, index.ts), packages/types/src/rich-filters/config/filter-config.ts, packages/types/src/view-props.ts
Exposes multi-value operator lists and aggregate; adds rightContent and tooltipContent to filter config; adds created_at/updated_at and widens filter condition data value types.
Utils: Loader and factories
packages/utils/src/index.ts, packages/utils/src/loader.ts, packages/utils/src/rich-filters/factories/... (configs/index.ts, configs/properties/*, configs/shared.ts, index.ts)
Adds isLoaderReady and re-exports; introduces property-based filter config helpers (date, member-picker, shared); extends base config params with UI content fields and icon type.
Utils: Work-item filter configs
packages/utils/src/work-item-filters/configs/filters/... (cycle.ts, date.ts, label.ts, module.ts, priority.ts, project.ts, state.ts, user.ts)
Spreads params instead of explicit isEnabled; adds created_at/updated_at date filter builders; adjusts state/user helpers to accept/operator param; updates imports to shared helpers.
UI: Dropdown
packages/ui/src/dropdowns/custom-search-select.tsx, packages/ui/src/dropdowns/helper.tsx
Tweaks panel spacing; replaces maxHeight "full" with "xl"/"2xl" options and scrollbar classes.
API: Django filterset
apps/api/plane/utils/filters/filterset.py
Adds updated_at to IssueFilterSet Meta.fields to enable exact/range filters.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant B as AddFilterButton
  participant D as AddFilterDropdown
  participant F as FilterInstance
  participant H as FilterInstanceHelper

  U->>B: Click custom button
  B->>D: Open dropdown
  U->>D: Select property/operator
  D->>B: handleFilterSelect(property, operator, isNegation)
  B->>F: addCondition(AND, {property, operator, value: undefined}, isNegation)
  Note right of F: Condition created with empty value
Loading
sequenceDiagram
  autonumber
  participant Hook as useWorkItemFiltersConfig
  participant Utils as isLoaderReady
  participant CM as FilterConfigManager
  participant HOC as WorkItemFilterRoot
  participant UI as FiltersRow

  Hook->>Utils: isLoaderReady(projectLoader)
  Utils-->>Hook: areAllConfigsInitialized (bool)
  HOC->>CM: setAreConfigsReady(areAllConfigsInitialized)
  HOC->>CM: registerAll(configs)
  UI->>CM: read areConfigsReady
  alt not ready and no conditions
    UI-->>U: Show Loader
  else ready or has conditions
    UI-->>U: Render filters
  end
Loading
sequenceDiagram
  autonumber
  participant UI as FilterItemProperty
  participant DD as AddFilterDropdown
  participant F as FilterInstance
  participant H as FilterInstanceHelper

  UI->>DD: Open property menu
  U->>DD: Pick property/operator/negation
  DD->>UI: handleFilterSelect(property, operator, isNegation)
  UI->>F: updateConditionProperty(conditionId, property, operator, isNegation)
  F->>H: handleConditionPropertyUpdate(expression, ...)
  H-->>F: Updated expression
  F-->>UI: Notify change
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Poem

A rabbit taps filters with tidy delight,
New buttons pop open, options take flight.
Dates hop in pairs, created and updated,
Placeholders—“--”—now neatly curated.
When loaders aren’t ready, I nibble and wait—
Then leap through the dropdowns, configuring fate. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description provides a detailed list of changes and correctly identifies the type of change, but it omits the required Test Scenarios section specified in the repository template, leaving out how the changes were verified. Please add a "Test Scenarios" section describing the tests executed to verify the new components and configurations, for example unit tests or manual verification steps.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly summarizes the primary purpose of the changes by stating that rich filters are being enhanced with new components and configurations, and it remains concise and focused on the main change.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ 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 improvement-rich-fitlers-ui

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.

…ctionality

- Moved AddFilterButton and AddFilterDropdown to a new directory structure for better organization.
- Updated FilterItemProperty to handle filter selection and condition updates more effectively.
- Enhanced the FilterInstance class with methods to update condition properties and operators, improving filter management.
- Added new functionality to handle invalid filter states and improve user feedback.
@prateekshourya29 prateekshourya29 marked this pull request as ready for review October 9, 2025 07:59
@prateekshourya29 prateekshourya29 changed the title improvement: enhance rich filters with new components and configurations [WEB-5099] improvement: enhance rich filters with new components and configurations Oct 9, 2025
Copy link

makeplane bot commented Oct 9, 2025

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

Copy link
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

Caution

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

⚠️ Outside diff range comments (1)
packages/shared-state/src/store/rich-filters/filter-helpers.ts (1)

173-275: Negation handling removed from condition updates

The new _updateCondition helper just mutates the targeted node and returns, ignoring the isNegation flag. Both handleConditionPropertyUpdate and restructureExpressionForOperatorChange now funnel through this helper, so any scenario that previously required wrapping/unwrapping the condition in a NOT-group (e.g., switching between negative and positive operators) stops working—the tree never restructures. This regresses negated filter updates. Please restore the negation-aware restructuring the old path provided_before landing this refactor.

♻️ Duplicate comments (2)
packages/utils/src/work-item-filters/configs/filters/priority.ts (1)

59-59: LGTM! Consistent with param spreading pattern.

The change aligns with the refactor to support additional filter properties through parameter spreading, matching the pattern in other filter configs.

packages/utils/src/work-item-filters/configs/filters/date.ts (1)

25-25: LGTM! Consistent parameter spreading.

Both filter configs now spread all params, consistent with the refactor pattern across other filter configuration files.

Also applies to: 43-43

🧹 Nitpick comments (5)
packages/shared-state/src/store/work-item-filters/adapter.ts (2)

212-213: Document the expected behavior for non-string values.

The parameter type changed from string to TFilterValue, but the function name and logic still imply string parsing. The early return on line 213 handles falsy values, but the behavior for numbers, booleans, and Date objects is implicit (they're returned as-is).

Consider adding documentation or renaming to clarify intent:

  /**
   * Parses filter value from string format
+  * Non-string values and falsy values are returned as-is
   * @param value - The string value to parse
   * @returns Parsed value as string or array of strings
   */
- private _parseFilterValue = (value: TFilterValue): SingleOrArray<TFilterValue> => {
+ private _parseFilterValue = (value: TFilterValue): SingleOrArray<TFilterValue> => {
    if (!value) return value;
-
+   // Non-string values are returned as-is
    if (typeof value !== "string") return value;

    // Handle empty string
    if (value === "") return value;

    // Split by comma if contains comma, otherwise return as single value
    if (value.includes(",")) {
      // Split and trim each value, filter out empty strings
      const splitValues = value
        .split(",")
        .map((v) => v.trim())
        .filter((v) => v.length > 0);

      // Return single value if only one non-empty value after split
      return splitValues.length === 1 ? splitValues[0] : splitValues;
    }

    return value;
  };

202-202: Ensure _parseFilterValue covers all edge cases and add tests

  • Handle invalid operator casts, null/undefined, numbers, booleans, Date objects, and when rawValue is already an array.
  • Add unit tests in packages/shared-state/src/store/work-item-filters/adapter.ts to validate each scenario.
apps/web/core/components/rich-filters/filter-item/loader.tsx (1)

3-7: LGTM! Simple and effective loader component.

The component provides a clean loading state for filter items. The fixed dimensions (28px × 180px) work well for the current use case.

If you anticipate needing different loader sizes across the application, consider making dimensions configurable via props:

-export const FilterItemLoader = () => (
+export const FilterItemLoader = ({ height = "28px", width = "180px" }: { height?: string; width?: string } = {}) => (
   <Loader>
-    <Loader.Item height="28px" width="180px" />
+    <Loader.Item height={height} width={width} />
   </Loader>
 );
packages/utils/src/rich-filters/factories/configs/shared.ts (1)

36-39: Consider constraining the object type in TFilterIconType.

The object type is too permissive and allows any object. Consider making it more specific to prevent unintended usage.

If icon data has known shapes, consider:

-export type TFilterIconType = string | number | boolean | object | undefined;
+export type TFilterIconType = string | number | boolean | Record<string, unknown> | undefined;

Or better yet, if you know the specific icon data structures, define them explicitly:

export type TFilterIconType = string | number | boolean | TKnownIconData | undefined;
packages/shared-state/src/store/rich-filters/filter.ts (1)

369-388: Document the extra parameters

The docblock still lists only the property argument, but the method now accepts operator and negation as well—could you expand the comment so future readers don’t miss those inputs?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cbb604 and a17cf68.

📒 Files selected for processing (49)
  • apps/web/ce/components/rich-filters/filter-value-input/root.tsx (1 hunks)
  • apps/web/ce/helpers/work-item-filters/project-level.ts (1 hunks)
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (5 hunks)
  • apps/web/core/components/rich-filters/add-filters-button.tsx (0 hunks)
  • apps/web/core/components/rich-filters/add-filters/button.tsx (1 hunks)
  • apps/web/core/components/rich-filters/add-filters/dropdown.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/close-button.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/container.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/invalid.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/loader.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/property.tsx (1 hunks)
  • apps/web/core/components/rich-filters/filter-item/root.tsx (5 hunks)
  • apps/web/core/components/rich-filters/filter-value-input/date/range.tsx (2 hunks)
  • apps/web/core/components/rich-filters/filter-value-input/date/single.tsx (2 hunks)
  • apps/web/core/components/rich-filters/filter-value-input/root.tsx (3 hunks)
  • apps/web/core/components/rich-filters/filter-value-input/select/selected-options-display.tsx (2 hunks)
  • apps/web/core/components/rich-filters/filters-row.tsx (4 hunks)
  • apps/web/core/components/rich-filters/filters-toggle.tsx (1 hunks)
  • apps/web/core/components/rich-filters/shared.ts (1 hunks)
  • apps/web/core/components/work-item-filters/filters-hoc/base.tsx (1 hunks)
  • apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx (1 hunks)
  • packages/shared-state/src/store/rich-filters/config-manager.ts (5 hunks)
  • packages/shared-state/src/store/rich-filters/filter-helpers.ts (5 hunks)
  • packages/shared-state/src/store/rich-filters/filter.ts (4 hunks)
  • packages/shared-state/src/store/work-item-filters/adapter.ts (4 hunks)
  • packages/types/src/rich-filters/config/filter-config.ts (1 hunks)
  • packages/types/src/rich-filters/operators/core.ts (1 hunks)
  • packages/types/src/rich-filters/operators/extended.ts (1 hunks)
  • packages/types/src/rich-filters/operators/index.ts (2 hunks)
  • packages/types/src/view-props.ts (1 hunks)
  • packages/ui/src/dropdowns/custom-search-select.tsx (2 hunks)
  • packages/ui/src/dropdowns/helper.tsx (1 hunks)
  • packages/utils/src/index.ts (1 hunks)
  • packages/utils/src/loader.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/index.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/properties/date.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/properties/index.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/configs/shared.ts (1 hunks)
  • packages/utils/src/rich-filters/factories/index.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/date.ts (3 hunks)
  • packages/utils/src/work-item-filters/configs/filters/label.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/module.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/priority.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/project.ts (2 hunks)
  • packages/utils/src/work-item-filters/configs/filters/state.ts (4 hunks)
  • packages/utils/src/work-item-filters/configs/filters/user.ts (5 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/core/components/rich-filters/add-filters-button.tsx
🧰 Additional context used
🧬 Code graph analysis (26)
apps/web/core/components/rich-filters/filter-value-input/date/range.tsx (1)
apps/web/core/components/rich-filters/shared.ts (1)
  • EMPTY_FILTER_PLACEHOLDER_TEXT (11-11)
apps/web/core/components/rich-filters/filter-item/loader.tsx (1)
packages/ui/src/loader.tsx (1)
  • Loader (30-30)
packages/utils/src/loader.ts (1)
packages/types/src/issues/base.ts (1)
  • TLoader (10-10)
packages/utils/src/rich-filters/factories/configs/properties/date.ts (3)
packages/utils/src/rich-filters/factories/configs/shared.ts (3)
  • TCreateDateFilterParams (54-54)
  • TCreateFilterConfig (76-76)
  • createFilterConfig (21-23)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)
  • getSupportedDateOperators (54-60)
apps/web/core/components/rich-filters/filter-value-input/date/single.tsx (1)
apps/web/core/components/rich-filters/shared.ts (1)
  • EMPTY_FILTER_PLACEHOLDER_TEXT (11-11)
apps/web/core/components/rich-filters/filter-item/container.tsx (3)
packages/types/src/utils.ts (1)
  • SingleOrArray (9-9)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterValue (24-24)
packages/utils/src/rich-filters/validators/core.ts (1)
  • hasValidValue (12-26)
apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (5)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/view-props.ts (1)
  • TWorkItemFilterProperty (104-104)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterValue (24-24)
packages/types/src/users.ts (1)
  • IUserLite (20-29)
packages/utils/src/loader.ts (1)
  • isLoaderReady (4-4)
apps/web/core/components/rich-filters/shared.ts (3)
packages/types/src/rich-filters/expression.ts (3)
  • TFilterProperty (19-19)
  • TFilterValue (24-24)
  • TFilterConditionNodeForDisplay (55-60)
packages/types/src/rich-filters/field-types/index.ts (1)
  • TSupportedFilterFieldConfigs (19-21)
packages/types/src/utils.ts (1)
  • SingleOrArray (9-9)
packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts (5)
packages/types/src/users.ts (1)
  • IUserLite (20-29)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (2)
  • TCreateUserFilterParams (24-27)
  • getMemberMultiSelectConfig (34-50)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/utils/src/rich-filters/factories/configs/shared.ts (3)
  • TCreateFilterConfig (76-76)
  • createFilterConfig (21-23)
  • createOperatorConfigEntry (64-71)
packages/types/src/rich-filters/operators/index.ts (1)
  • EQUALITY_OPERATOR (25-28)
apps/web/core/components/rich-filters/filter-item/property.tsx (6)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (1)
  • AddFilterDropdown (20-86)
apps/web/core/components/rich-filters/shared.ts (1)
  • COMMON_FILTER_ITEM_BORDER_CLASSNAME (9-9)
packages/ui/src/dropdowns/custom-search-select.tsx (1)
packages/ui/src/utils/classname.tsx (1)
  • cn (4-4)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (6)
packages/utils/src/rich-filters/factories/configs/shared.ts (4)
  • TCreateFilterConfigParams (29-34)
  • IFilterIconConfig (46-49)
  • TCreateDateFilterParams (54-54)
  • createOperatorConfigEntry (64-71)
packages/types/src/users.ts (1)
  • IUserLite (20-29)
packages/types/src/rich-filters/operators/index.ts (3)
  • TSupportedOperators (56-56)
  • EQUALITY_OPERATOR (25-28)
  • COMPARISON_OPERATOR (35-38)
packages/utils/src/rich-filters/factories/configs/core.ts (3)
  • getMultiSelectConfig (69-89)
  • getDatePickerConfig (114-118)
  • getDateRangePickerConfig (125-129)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (48-51)
packages/types/src/project/projects.ts (1)
  • IProject (38-54)
apps/web/core/components/rich-filters/add-filters/button.tsx (6)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/propel/src/button/helper.tsx (2)
  • TButtonVariant (1-12)
  • getButtonStyling (109-120)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
packages/types/src/rich-filters/operators/index.ts (2)
  • TSupportedOperators (56-56)
  • LOGICAL_OPERATOR (20-23)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (1)
  • AddFilterDropdown (20-86)
apps/web/core/components/rich-filters/filter-value-input/select/selected-options-display.tsx (1)
apps/web/core/components/rich-filters/shared.ts (1)
  • EMPTY_FILTER_PLACEHOLDER_TEXT (11-11)
apps/web/core/components/rich-filters/filter-item/invalid.tsx (6)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
apps/web/core/components/rich-filters/filter-item/root.tsx (1)
  • IFilterItemProps (24-29)
apps/web/core/components/rich-filters/filter-item/container.tsx (1)
  • FilterItemContainer (16-64)
apps/web/core/components/rich-filters/filter-item/property.tsx (1)
  • FilterItemProperty (20-40)
apps/web/core/components/rich-filters/filter-item/close-button.tsx (1)
  • FilterItemCloseButton (13-32)
apps/web/core/components/rich-filters/filter-value-input/root.tsx (1)
apps/web/ce/components/rich-filters/filter-value-input/root.tsx (1)
  • AdditionalFilterValueInput (8-15)
packages/types/src/rich-filters/operators/index.ts (2)
packages/types/src/rich-filters/operators/core.ts (1)
  • CORE_MULTI_VALUE_OPERATORS (32-32)
packages/types/src/rich-filters/operators/extended.ts (1)
  • EXTENDED_MULTI_VALUE_OPERATORS (24-24)
apps/web/ce/components/rich-filters/filter-value-input/root.tsx (2)
packages/types/src/rich-filters/expression.ts (2)
  • TFilterProperty (19-19)
  • TFilterValue (24-24)
apps/web/core/components/rich-filters/shared.ts (1)
  • TFilterValueInputProps (13-18)
packages/shared-state/src/store/rich-filters/filter.ts (4)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
packages/utils/src/rich-filters/operations/traversal/core.ts (1)
  • findNodeById (91-103)
packages/types/src/rich-filters/expression.ts (1)
  • FILTER_NODE_TYPE (10-13)
packages/utils/src/rich-filters/validators/core.ts (1)
  • hasValidValue (12-26)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (5)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
packages/utils/src/rich-filters/operators/shared.ts (1)
  • getOperatorForPayload (16-24)
packages/ui/src/dropdowns/custom-search-select.tsx (1)
  • CustomSearchSelect (14-225)
packages/shared-state/src/store/rich-filters/filter-helpers.ts (3)
packages/types/src/rich-filters/expression.ts (3)
  • TFilterExpression (86-88)
  • TFilterConditionNode (45-50)
  • TFilterValue (24-24)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
packages/utils/src/rich-filters/operations/manipulation/core.ts (1)
  • updateNodeInExpression (84-107)
packages/shared-state/src/store/work-item-filters/adapter.ts (4)
packages/types/src/view-props.ts (2)
  • WORK_ITEM_FILTER_PROPERTY_KEYS (89-103)
  • TWorkItemFilterConditionKey (106-106)
packages/types/src/rich-filters/operators/index.ts (2)
  • TSupportedOperators (56-56)
  • MULTI_VALUE_OPERATORS (40-43)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterValue (24-24)
packages/types/src/utils.ts (1)
  • SingleOrArray (9-9)
packages/utils/src/work-item-filters/configs/filters/user.ts (2)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createOperatorConfigEntry (64-71)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)
  • getMemberMultiSelectConfig (34-50)
packages/utils/src/work-item-filters/configs/filters/state.ts (2)
packages/types/src/rich-filters/operators/index.ts (3)
  • TSupportedOperators (56-56)
  • COLLECTION_OPERATOR (30-33)
  • EQUALITY_OPERATOR (25-28)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createOperatorConfigEntry (64-71)
apps/web/core/components/rich-filters/filter-item/close-button.tsx (3)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
apps/web/core/components/rich-filters/filter-item/root.tsx (8)
packages/types/src/rich-filters/expression.ts (3)
  • TFilterProperty (19-19)
  • TFilterConditionNodeForDisplay (55-60)
  • TFilterValue (24-24)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
apps/web/core/components/rich-filters/filter-item/loader.tsx (1)
  • FilterItemLoader (3-7)
apps/web/core/components/rich-filters/filter-item/invalid.tsx (1)
  • InvalidFilterItem (12-36)
apps/web/core/components/rich-filters/filter-item/container.tsx (1)
  • FilterItemContainer (16-64)
apps/web/core/components/rich-filters/filter-item/property.tsx (1)
  • FilterItemProperty (20-40)
apps/web/core/components/rich-filters/filter-item/close-button.tsx (1)
  • FilterItemCloseButton (13-32)
⏰ 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: Build and lint web apps
🔇 Additional comments (35)
packages/types/src/view-props.ts (1)

108-110: No downstream changes required. The type widening only affects typings; the filter adapter always serializes values to strings, so existing string operations and serialization logic remain safe.

apps/web/ce/helpers/work-item-filters/project-level.ts (1)

1-20: LGTM! Type extension for future use.

The addition of entityType: EIssuesStoreType extends the type definition without changing the current implementation behavior. The field is intentionally unused in getAdditionalProjectLevelFiltersHOCProps, likely reserved for future filtering enhancements or to maintain consistency with other HOC parameter patterns.

packages/utils/src/loader.ts (1)

1-4: LGTM! Clean utility function.

The isLoaderReady utility provides a clear abstraction for checking initialization state. The logic correctly identifies when loading has progressed beyond the initial state.

packages/ui/src/dropdowns/custom-search-select.tsx (1)

142-167: LGTM! UI refinements align with type updates.

The spacing adjustments and expanded maxHeight handling correctly implement support for the new "xl" and "2xl" options while removing "full". The changes improve layout consistency:

  • Tighter alignment with margin-based spacing (mx-2 on line 149)
  • Explicit scrollbar styling for better UX
  • Preserved mappings for existing breakpoints
packages/types/src/rich-filters/config/filter-config.ts (1)

18-19: LGTM! Well-documented type extension.

The addition of optional rightContent and tooltipContent fields extends the filter configuration API with clear UI hooks. The documentation comments clearly explain their purpose and usage context.

packages/ui/src/dropdowns/helper.tsx (1)

27-27: Breaking change: removed “full” maxHeight option.
No internal usages of maxHeight="full" detected. Ensure external consumers (docs, published API) are updated and bump the major version accordingly.

packages/utils/src/work-item-filters/configs/filters/label.ts (1)

59-69: Spreading params is safeTCreateLabelFilterParams only includes isEnabled, allowedOperators, optional rightContent/tooltipContent, filterIcon and labels, all of which createFilterConfig’s TFilterConfig<'label', string> expects.

apps/web/core/components/rich-filters/filter-value-input/date/single.tsx (1)

7-7: LGTM! Good use of shared constants.

Replacing the hard-coded placeholder with EMPTY_FILTER_PLACEHOLDER_TEXT improves maintainability and ensures consistency across the application.

Also applies to: 37-37

apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx (1)

169-173: LGTM! Proper prop forwarding.

The addition of entityType: props.entityType correctly forwards the new property to getAdditionalProjectLevelFiltersHOCProps, aligning with the updated type signature.

apps/web/core/components/rich-filters/filters-toggle.tsx (1)

8-8: LGTM! Import path correctly updated.

The import path change reflects the reorganization of AddFilterButton into a new directory structure.

apps/web/core/components/rich-filters/filter-value-input/select/selected-options-display.tsx (1)

6-6: LGTM! Consistent use of shared constants.

Replacing the hard-coded "--" with EMPTY_FILTER_PLACEHOLDER_TEXT ensures consistency with other filter components.

Also applies to: 17-17

apps/web/core/components/rich-filters/filter-value-input/date/range.tsx (1)

9-9: LGTM! Good use of shared constants.

Replacing the hard-coded placeholder with EMPTY_FILTER_PLACEHOLDER_TEXT maintains consistency across date input components.

Also applies to: 45-45

packages/utils/src/rich-filters/factories/configs/index.ts (1)

3-3: LGTM! Proper public API extension.

The new export for "./properties" appropriately extends the public API to include the properties module.

packages/utils/src/work-item-filters/configs/filters/project.ts (1)

23-32: Spread ...params includes isEnabled
TCreateProjectFilterParams extends TCreateFilterConfigParams, which declares isEnabled: boolean, so ...params already brings in isEnabled.

packages/utils/src/rich-filters/factories/index.ts (1)

3-3: LGTM! API surface expansion for property configurations.

The new re-export exposes property-based filter configurations, aligning with the PR's goal to enhance rich filters with new components and configurations.

packages/utils/src/rich-filters/factories/configs/shared.ts (1)

32-33: LGTM! Good extensibility for UI content.

Adding rightContent and tooltipContent as optional ReactNode properties provides flexible extension points for filter UI customization.

packages/utils/src/work-item-filters/configs/filters/date.ts (1)

4-9: LGTM! Cleaner import organization.

Consolidating imports from the same module improves readability.

apps/web/ce/components/rich-filters/filter-value-input/root.tsx (1)

8-15: LGTM! Clean fallback implementation.

The component provides a clear fallback UI for unsupported filter types. Using observer from mobx-react and ignoring props (prefixed with _) is appropriate for a static fallback component.

packages/types/src/rich-filters/operators/core.ts (1)

29-32: LGTM! Well-defined multi-value operator constant.

The new constant clearly identifies which core operators support multiple values. Using as const ensures type safety and immutability.

packages/utils/src/work-item-filters/configs/filters/module.ts (1)

56-56: Parameter spreading is consistent across all filter configs.

packages/utils/src/work-item-filters/configs/filters/cycle.ts (1)

63-63: LGTM: Cleaner parameter propagation.

Spreading all params instead of explicit assignment is more maintainable and aligns with the broader refactor pattern across other filter configs.

apps/web/core/components/work-item-filters/filters-hoc/base.tsx (1)

97-97: LGTM: Proper readiness propagation.

Setting the configs ready state before registration ensures the config manager has accurate initialization status during the registration phase.

packages/types/src/rich-filters/operators/extended.ts (1)

21-24: LGTM: Consistent multi-value operator infrastructure.

The empty array is appropriate for extended operators and maintains consistency with the core multi-value operator pattern.

apps/web/core/components/rich-filters/filter-item/close-button.tsx (1)

1-32: LGTM: Clean close button implementation.

The component correctly handles filter removal with proper accessibility attributes and MobX reactivity.

apps/web/core/components/rich-filters/shared.ts (1)

1-18: LGTM: Good centralization of shared types and constants.

Consolidating EMPTY_FILTER_PLACEHOLDER_TEXT and TFilterValueInputProps improves maintainability and consistency across filter components.

packages/utils/src/rich-filters/factories/configs/properties/index.ts (1)

1-3: LGTM: Standard barrel export pattern.

The index file correctly consolidates and re-exports from the properties config modules.

packages/types/src/rich-filters/operators/index.ts (1)

40-43: LGTM: Proper multi-value operator aggregation.

The constant correctly combines core and extended multi-value operators with appropriate typing for a readonly array.

apps/web/core/components/rich-filters/filter-item/property.tsx (1)

1-67: LGTM: Well-structured property filter component.

The component correctly handles both disabled and enabled states, properly delegates filter selection, and uses good composition patterns with the internal PropertyButton and AddFilterDropdown integration.

packages/utils/src/rich-filters/factories/configs/properties/date.ts (1)

17-27: Date property factory reads clean

Nice job parameterizing the factory and reusing the shared date operator map—this keeps the property configs consistent and extensible.

packages/shared-state/src/store/rich-filters/filter.ts (1)

446-461: Value no-op guard is appreciated

Using isEqual to bail when the value doesn’t change should trim a lot of redundant notifications—thanks for tightening this up.

apps/web/core/components/rich-filters/filter-item/container.tsx (1)

21-48: Entrance animation is well-contained

Wrapping the transition behind showTransition and skipping it once the value is valid keeps the effect predictable—looks good.

apps/web/core/components/rich-filters/add-filters/dropdown.tsx (1)

55-82: Dropdown wiring looks solid

The option mapping plus the fallback toast make the selection flow resilient—nicely handled.

packages/utils/src/work-item-filters/configs/filters/state.ts (1)

90-125: State configs align with multi-value support

Passing the single-value operator through keeps the multi-select helper flexible—looks great.

packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts (1)

17-29: Member picker factory is consistent

This mirrors the shared multi-select helper neatly and keeps the property config API uniform—nice work.

packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)

34-99: Shared helpers nicely abstracted

Centralizing the member/project multi-select builders and date operator map keeps the property factories lightweight—great abstraction.

…em configuration

- Introduced new filter configurations for 'created_at' and 'updated_at' in the work item filters.
- Updated relevant components to utilize these new filters, enhancing filtering capabilities.
- Added corresponding filter configuration functions in the utils for better date handling.
Copy link
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

🧹 Nitpick comments (1)
packages/utils/src/work-item-filters/configs/filters/date.ts (1)

19-83: Consider extracting common logic to reduce duplication.

All four date filter config functions follow an identical pattern, differing only in the label. Consider creating a helper function to reduce duplication and improve maintainability:

/**
 * Create a date filter config with the given label
 */
const createDateFilterConfig = <P extends TFilterProperty>(
  key: P,
  label: string
): TCreateFilterConfig<P, TCreateDateFilterParams> =>
  (params: TCreateDateFilterParams) =>
    createFilterConfig<P, Date>({
      id: key,
      label,
      ...params,
      icon: params.filterIcon,
      allowMultipleFilters: true,
      supportedOperatorConfigsMap: getSupportedDateOperators(params),
    });

export const getStartDateFilterConfig = <P extends TFilterProperty>(key: P) =>
  createDateFilterConfig(key, "Start date");

export const getTargetDateFilterConfig = <P extends TFilterProperty>(key: P) =>
  createDateFilterConfig(key, "Target date");

export const getCreatedAtFilterConfig = <P extends TFilterProperty>(key: P) =>
  createDateFilterConfig(key, "Created at");

export const getUpdatedAtFilterConfig = <P extends TFilterProperty>(key: P) =>
  createDateFilterConfig(key, "Updated at");

This maintains the same public API while eliminating duplication.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a17cf68 and b0d81a3.

📒 Files selected for processing (4)
  • apps/api/plane/utils/filters/filterset.py (1 hunks)
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (9 hunks)
  • packages/types/src/view-props.ts (1 hunks)
  • packages/utils/src/work-item-filters/configs/filters/date.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
packages/types/src/view-props.ts (1)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
packages/utils/src/work-item-filters/configs/filters/date.ts (3)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)
  • getSupportedDateOperators (54-60)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/utils/src/rich-filters/factories/configs/shared.ts (3)
  • TCreateFilterConfig (76-76)
  • TCreateDateFilterParams (54-54)
  • createFilterConfig (21-23)
⏰ 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). (2)
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/utils/src/work-item-filters/configs/filters/date.ts (3)

4-9: LGTM! Improved import organization.

The multi-line import format improves readability and the addition of getSupportedDateOperators properly supports the date filter configurations.


49-83: LGTM! New filter configurations follow established patterns.

The getCreatedAtFilterConfig and getUpdatedAtFilterConfig functions are correctly implemented and consistent with the existing date filter configurations.


22-29: Spread order is safe; TCreateFilterConfigParams doesn’t define id or label, so ...params can’t override them.

Likely an incorrect or invalid review comment.

packages/types/src/view-props.ts (2)

103-104: Approve date filter property additions

created_at and updated_at are now supported in WORK_ITEM_FILTER_PROPERTY_KEYS and have matching configs (getCreatedAtFilterConfig, getUpdatedAtFilterConfig) implemented in packages/utils/src/work-item-filters/configs/filters/date.ts and wired in the hooks.


111-111: Verify handling of non-string filter values.
Ensure downstream code guards against boolean/number values in string-specific operations, persisted filters remain compatible or include migration logic, and any API serialization/deserialization supports boolean and number types.

@arpadgabor
Copy link

To be honest I can't really tell from the code, does this PR by any chance also add support for an "is empty" filter?

aaryan610
aaryan610 previously approved these changes Oct 13, 2025
Merge branch 'preview' of github.com:makeplane/plane into improvement-rich-fitlers-ui
Copy link
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

🧹 Nitpick comments (1)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (1)

27-54: Consider extracting option content rendering for improved readability.

The filter options mapping logic is correct and includes good UI enhancements (justify-between layout, rightContent support). However, extracting the option content rendering to a separate component or function would improve maintainability.

Example refactor:

const renderOptionContent = (config: typeof filter.configManager.allAvailableConfigs[0]) => (
  <div className="flex items-center justify-between gap-2 text-custom-text-200 transition-all duration-200 ease-in-out">
    <div className="flex items-center gap-2">
      {config.icon && (
        <config.icon className="size-4 text-custom-text-300 transition-transform duration-200 ease-in-out" />
      )}
      <span>{config.label}</span>
    </div>
    {config.rightContent}
  </div>
);

const filterOptions = filter.configManager.allAvailableConfigs.map((config) => ({
  value: config.id,
  content: renderOptionContent(config),
  query: config.label.toLowerCase(),
}));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d49d994 and 00af965.

📒 Files selected for processing (1)
  • apps/web/core/components/rich-filters/add-filters/dropdown.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (4)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/adapter.ts (1)
  • TExternalFilter (7-7)
packages/shared-state/src/store/rich-filters/filter.ts (1)
  • IFilterInstance (64-119)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
⏰ 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). (2)
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
apps/web/core/components/rich-filters/add-filters/dropdown.tsx (5)

1-8: LGTM! Clean import organization.

The imports are well-organized and all necessary dependencies are included for the refactored component.


23-24: LGTM! Props destructuring is clean.

The destructuring properly extracts the required props with sensible defaults for optional values.


56-68: LGTM! Clean implementation with proper error handling.

The function correctly:

  • Uses optional chaining to safely access config properties
  • Delegates to the parent's handleFilterSelect callback with the extracted operator and negation values
  • Provides user feedback via toast notification when configuration is invalid

70-85: Verify that the maxHeight reduction doesn't negatively impact UX.

The component correctly uses the new customButton prop and simplified configuration. However, the maxHeight was changed from "full" to "2xl", which could limit visibility when there are many available filters.

Please verify in the UI that:

  1. The dropdown is usable when there are many filter options (e.g., 20+ filters)
  2. The scroll behavior is smooth and intuitive
  3. Users can still easily find and select filters from the list

If the reduced height causes usability issues with many filters, consider making maxHeight configurable via props or reverting to a larger value.


10-19: All AddFilterDropdown calls include customButton. Verified that both callers explicitly provide this prop.

@sriramveeraghanta sriramveeraghanta merged commit cfb4a82 into preview Oct 13, 2025
6 of 7 checks passed
@sriramveeraghanta sriramveeraghanta deleted the improvement-rich-fitlers-ui branch October 13, 2025 20:09
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.

5 participants