Skip to content

Conversation

@prateekshourya29
Copy link
Member

@prateekshourya29 prateekshourya29 commented Dec 23, 2025

Description

Problem

Filter configurations were constrained to a single value type (e.g., TFilterConfig<'priority', TIssuePriorities>), but different operators for the same filter can accept different value types.

Solution

  • Remove value type parameter from filter configs: TFilterConfig<P, V>TFilterConfig<P>
  • Make value types operator-specific rather than filter-specific
  • Simplify all filter config creators across the codebase
  • Add forceUpdate parameter to updateConditionValue() for explicit updates

Impact

  • More accurate type representation
  • Better flexibility for diverse operator types
  • Simplified filter configuration APIs
  • No breaking runtime changes

Files Changed

  • Types: filter-config.ts, operator-configs/*
  • Filters: priority, state, user, date, cycle, label, module, project
  • State: enhanced updateConditionValue in filter.ts

Type of Change

  • Code refactoring

Note

Refactor rich filter typing

  • Convert TFilterConfig<P, V> to TFilterConfig<P> and remove TFilterValue generics across config, manager, and factories; move value typing to operator-specific configs (TOperatorSpecificConfigs, TOperatorConfigMap).
  • Update FilterConfig, FilterConfigManager, and all work-item filter creators (state, priority, user, date, cycle, label, module, project) to new signatures.
  • Add forceUpdate?: boolean to updateConditionValue() in FilterInstance to allow explicit updates even when values are equal.
  • Minor UI: replace Calendar with CalendarLayoutIcon for created/updated date filters.

Written by Cursor Bugbot for commit ccce43b. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features
    • Added an optional parameter to force filter condition reassessment, allowing manual re-evaluation of a filter even when its value hasn't changed.
  • Updated UI
    • Switched the date filter icon used for created/updated date filters to an updated calendar icon.

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

…ations

Remove value type constraints from filter configurations to support
operator-specific value types. Different operators can accept different
value types for the same filter property, so value types should be
determined at the operator level rather than the filter level.

- Remove generic value type parameter from TFilterConfig
- Update TOperatorConfigMap to accept union of all value types
- Simplify filter config factory signatures across all filter types
- Add forceUpdate parameter to updateConditionValue method
@makeplane
Copy link

makeplane bot commented Dec 23, 2025

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

This PR removes the generic type parameter V from rich-filter operator and filter config types across the codebase so types use TFilterValue directly. It also adds an optional forceUpdate parameter to FilterInstance.updateConditionValue to allow forcing reassessment even when values are equal.

Changes

Cohort / File(s) Summary
Filter instance
packages/shared-state/src/store/rich-filters/filter.ts
Added optional forceUpdate?: boolean to IFilterInstance.updateConditionValue and implementation updateConditionValue(..., forceUpdate: boolean = false). Equality early-return now guarded by if (!forceUpdate && isEqual(...)) { return; }. JSDoc added.
Filter config runtime
packages/shared-state/src/store/rich-filters/config.ts, packages/shared-state/src/store/rich-filters/config-manager.ts
Dropped V generic from IFilterConfig, FilterConfig, IFilterConfigManager, and FilterConfigManager. Updated constructors, methods, public fields, maps, and internal collections to use TFilterValue / non‑generic TFilterConfig<P> types.
Type definitions (core & index)
packages/types/src/rich-filters/config/filter-config.ts, packages/types/src/rich-filters/operator-configs/core.ts, packages/types/src/rich-filters/operator-configs/index.ts, packages/types/src/rich-filters/operator-configs/extended.ts, packages/types/src/rich-filters/derived/core.ts
Removed the generic V extends TFilterValue from many operator and config type aliases; replaced V-parameterized unions/maps with non-generic equivalents that reference TFilterValue directly. Removed unused TFilterValue imports where applicable.
Utils — factories & helpers
packages/utils/src/rich-filters/factories/configs/shared.ts, packages/utils/src/rich-filters/factories/configs/properties/shared.ts, packages/utils/src/rich-filters/factories/configs/properties/shared.ts
Simplified createFilterConfig signature from <P, V> to <P>. Adjusted createOperatorConfigEntry and getSupportedDateOperators return types to use non-generic TOperatorConfigMap / TOperatorSpecificConfigs.
Work-item filters — call sites
packages/utils/src/work-item-filters/configs/filters/*
packages/utils/src/work-item-filters/configs/filters/cycle.ts, .../date.ts, .../label.ts, .../module.ts, .../priority.ts, .../project.ts, .../state.ts, .../user.ts, .../shared.ts
Removed second generic argument on createFilterConfig calls (e.g., createFilterConfig<P, string>createFilterConfig<P>) across multiple filter builders. Adjusted return types where they referenced operator map generics.
App hook — icons & config typing
apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
Replaced Calendar with CalendarLayoutIcon for some filter icons. Updated exported TWorkItemFiltersConfig shape to use TFilterConfig<TWorkItemFilterProperty>[] and configMap entries to TFilterConfig<TWorkItemFilterProperty> (dropped TFilterValue generic).

Sequence Diagram(s)

(omitted — changes are type-level and a small update to a single-method behavior; conditions for sequence diagrams not met)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: decoupling filter value types from configurations, directly aligned with the PR's core objective.
Description check ✅ Passed The description includes the template's required sections: a detailed problem statement, solution approach, impact analysis, and explicitly marks this as a code refactoring, meeting all template requirements.
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 refactor-filter-types

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28ebe65 and ccce43b.

📒 Files selected for processing (7)
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/types/src/rich-filters/derived/core.ts
  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,mts,cts}

📄 CodeRabbit inference engine (.github/instructions/typescript.instructions.md)

**/*.{ts,tsx,mts,cts}: Use const type parameters for more precise literal inference in TypeScript 5.0+
Use the satisfies operator to validate types without widening them
Leverage inferred type predicates to reduce the need for explicit is return types in filter/check functions
Use NoInfer<T> utility to block inference for specific type arguments when they should be determined by other arguments
Utilize narrowing in switch(true) blocks for control flow analysis (TypeScript 5.3+)
Rely on narrowing from direct boolean comparisons for type guards
Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+)
Use constant indices to narrow object/array properties (TypeScript 5.5+)
Use standard ECMAScript decorators (Stage 3) instead of legacy experimentalDecorators
Use using declarations for explicit resource management with Disposable pattern instead of manual cleanup (TypeScript 5.2+)
Use with { type: "json" } for import attributes; avoid deprecated assert syntax (TypeScript 5.3/5.8+)
Use import type explicitly when importing types to ensure they are erased during compilation, respecting verbatimModuleSyntax flag
Use .ts, .mts, .cts extensions in import type statements (TypeScript 5.2+)
Use import type { Type } from "mod" with { "resolution-mode": "import" } for specific module resolution contexts (TypeScript 5.3+)
Use new iterator methods (map, filter, etc.) if targeting modern environments (TypeScript 5.6+)
Utilize new Set methods like union, intersection, etc., when available (TypeScript 5.5+)
Use Object.groupBy / Map.groupBy standard methods for grouping instead of external libraries (TypeScript 5.4+)
Use Promise.withResolvers() for creating promises with exposed resolve/reject functions (TypeScript 5.7+)
Use copying array methods (toSorted, toSpliced, with) for immutable array operations (TypeScript 5.2+)
Avoid accessing instance fields via super in classes (TypeScript 5....

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Enable TypeScript strict mode and ensure all files are fully typed

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{js,jsx,ts,tsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with Tailwind plugin for code formatting, run pnpm fix:format

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Use ESLint with shared config across packages, adhering to max warnings limits per package
Use camelCase for variable and function names, PascalCase for components and types
Use try-catch with proper error types and log errors appropriately

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
packages/shared-state/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain MobX stores in packages/shared-state using reactive patterns

Files:

  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/shared-state/src/store/rich-filters/config-manager.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • packages/shared-state/src/store/rich-filters/config-manager.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use `const` type parameters for more precise literal inference in TypeScript 5.0+

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/types/src/rich-filters/derived/core.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use the `satisfies` operator to validate types without widening them

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Rely on narrowing from direct boolean comparisons for type guards

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use constant indices to narrow object/array properties (TypeScript 5.5+)

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/types/src/rich-filters/derived/core.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+)

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use `NoInfer<T>` utility to block inference for specific type arguments when they should be determined by other arguments

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
📚 Learning: 2025-12-12T15:20:36.542Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to packages/shared-state/**/*.{ts,tsx} : Maintain MobX stores in `packages/shared-state` using reactive patterns

Applied to files:

  • packages/shared-state/src/store/rich-filters/config.ts
📚 Learning: 2025-10-09T20:42:31.843Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T20:42:31.843Z
Learning: In the makeplane/plane repository, React types are globally available through TypeScript configuration. Type annotations like React.FC, React.ReactNode, etc. can be used without explicitly importing the React namespace. The codebase uses the modern JSX transform, so React imports are not required for JSX or type references.

Applied to files:

  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
📚 Learning: 2025-10-01T15:30:17.605Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7888
File: packages/propel/src/avatar/avatar.stories.tsx:2-3
Timestamp: 2025-10-01T15:30:17.605Z
Learning: In the makeplane/plane repository, avoid suggesting inline type imports (e.g., `import { Avatar, type TAvatarSize }`) due to bundler compatibility issues. Keep type imports and value imports as separate statements.

Applied to files:

  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
🧬 Code graph analysis (5)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (3)
packages/utils/src/work-item-filters/configs/filters/shared.ts (1)
  • getSupportedDateOperators (15-21)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • TCreateDateFilterParams (53-53)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (43-46)
packages/shared-state/src/store/rich-filters/config.ts (4)
packages/types/src/rich-filters/expression.ts (2)
  • TFilterProperty (19-19)
  • TFilterValue (24-24)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorSpecificConfigs (33-37)
packages/utils/src/work-item-filters/configs/filters/shared.ts (3)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)
  • getSupportedDateOperators (44-50)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • TCreateDateFilterParams (53-53)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (43-46)
apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (3)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/view-props.ts (1)
  • TWorkItemFilterProperty (106-106)
packages/propel/src/icons/layouts/calendar-icon.tsx (1)
  • CalendarLayoutIcon (6-15)
packages/shared-state/src/store/rich-filters/config-manager.ts (3)
packages/shared-state/src/store/rich-filters/config.ts (1)
  • IFilterConfig (28-41)
packages/constants/src/rich-filters/option.ts (1)
  • TConfigOptions (6-6)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
⏰ 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). (3)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Build packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (14)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)

44-50: LGTM! Type signature correctly updated to non-generic operator config map.

The return type change from TOperatorConfigMap<Date> to TOperatorConfigMap aligns with the PR's goal of decoupling value types from filter configurations. The function body remains unchanged, preserving runtime behavior while gaining flexibility for operator-specific value types.

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

15-21: LGTM!

The return type change from TOperatorConfigMap<Date> to TOperatorConfigMap correctly aligns with the refactored non-generic TOperatorConfigMap type definition. This is consistent with the similar function in packages/utils/src/rich-filters/factories/configs/properties/shared.ts.

apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (3)

2-19: LGTM!

Import changes are clean - Calendar removed and replaced with CalendarLayoutIcon from the propel icons package. The import structure follows project conventions with separate value and type imports.


75-83: LGTM!

The simplified TFilterConfig<TWorkItemFilterProperty> type (without the value-type generic) correctly aligns with the updated type definition in packages/types/src/rich-filters/config/filter-config.ts. This makes the public API surface cleaner while maintaining type safety through operator-specific typing.


324-344: LGTM!

The icon change from Calendar to CalendarLayoutIcon for both created_at and updated_at filters is applied consistently. This provides visual alignment between the timestamp filters.

packages/shared-state/src/store/rich-filters/config-manager.ts (3)

25-39: LGTM!

The IFilterConfigManager interface correctly removes the value-type generic while maintaining the property type generic P. The type signatures for filterConfigs, allAvailableConfigs, getConfigByProperty, register, registerAll, and updateConfigByProperty are all consistent with the simplified IFilterConfig<P> and TFilterConfig<P> types.


117-119: LGTM!

The getConfigByProperty implementation correctly uses computedFn for MobX reactivity and the cast to IFilterConfig<P> aligns with the updated type definition. The implementation maintains proper MobX reactive patterns as per the coding guidelines.


168-178: LGTM!

Private computed properties _allConfigs and _allEnabledConfigs correctly updated to return IFilterConfig<P>[]. The filter operation on line 177 properly leverages TypeScript's type inference.

packages/shared-state/src/store/rich-filters/config.ts (4)

28-41: LGTM!

The IFilterConfig interface correctly removes the value-type generic V while maintaining proper typing:

  • getDisplayOperatorByValue and getAllDisplayOperatorOptionsByValue now use TFilterValue directly, which represents the union of all possible filter value types
  • mutate accepts Partial<TFilterConfig<P>> aligned with the simplified type
  • The method signatures are consistent with the PR's objective of making value types operator-specific rather than filter-specific

43-77: LGTM!

The FilterConfig class implementation correctly:

  • Simplifies the generic signature to FilterConfig<P extends TFilterProperty>
  • References IFilterConfig<P> for observable property types
  • Uses TFilterConfig<P> for constructor parameter
  • Maintains proper MobX observable/computed/action decorations

152-171: LGTM!

The getAllDisplayOperatorOptionsByValue method has been refactored with:

  • Clean for...of loop instead of more verbose alternatives
  • Consistent use of TFilterValue for the value parameter
  • Proper building of operator options array with both primary and additional options

The implementation correctly handles operator-specific value types through TFilterValue.


179-195: LGTM!

The mutate action correctly:

  • Accepts Partial<TFilterConfig<P>> aligned with simplified types
  • Uses runInAction for proper MobX batching
  • Casts to keyof TFilterConfig<P> for type safety

The private _getAdditionalOperatorOptions helper correctly uses TFilterValue for the _value parameter, maintaining consistency with the refactored type surface.

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

2-11: LGTM! Placeholder types simplified.

The removal of the generic V parameter from these extended operator config placeholders is consistent with the PR's goal to decouple value types from filter configurations. Since these are placeholder types (never and unknown) with no active logic, the generic parameter was unused and its removal simplifies the type signatures without any impact.

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

16-22: LGTM! Consistent refactoring across all operator helper types.

The systematic removal of the generic V parameter from TCoreOperatorSpecificConfigs across all four mapped types is correct and aligns with the PR's objective to make value types operator-specific rather than filter-specific. The parent types appropriately retain the V parameter for field config specialization (e.g., TDateFilterFieldConfig<V>), maintaining the correct semantics: "which operators from the (now non-generic) operator config map support field configs with value type V?"

The refactoring is applied consistently across date and select filter operator types, preserving type correctness while simplifying the operator config API.

Also applies to: 27-33, 50-56, 61-67


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.

@prateekshourya29 prateekshourya29 changed the title [WEB-5804] refactor: decouple filter value types from filter configur… [WEB-5804] refactor: decouple filter value types from filter configurations Dec 23, 2025
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

Caution

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

⚠️ Outside diff range comments (1)
packages/types/src/rich-filters/config/filter-config.ts (1)

4-10: Update JSDoc comment to reflect removed generic parameter.

The comment still documents the @template V - Value type for the filter parameter, but line 11 shows that V has been removed from the type signature.

🔎 Suggested fix
 /**
  * Main filter configuration type for different properties.
  * This is the primary configuration type used throughout the application.
  *
  * @template P - Property key type (e.g., 'state_id', 'priority', 'assignee')
- * @template V - Value type for the filter
  */
🧹 Nitpick comments (1)
packages/shared-state/src/store/rich-filters/filter.ts (1)

446-468: Well-implemented force update mechanism.

The forceUpdate parameter with default false preserves backward compatibility while enabling explicit updates when needed. The condition !forceUpdate && isEqual(...) correctly short-circuits the equality check when forcing. The JSDoc is clear about the parameter's purpose.

One minor observation: consider documenting a use case for forceUpdate in the JSDoc (e.g., "useful when the same value needs to trigger re-notification to observers").

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 777200d and 28ebe65.

📒 Files selected for processing (13)
  • packages/shared-state/src/store/rich-filters/filter.ts
  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/work-item-filters/configs/filters/priority.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,mts,cts}

📄 CodeRabbit inference engine (.github/instructions/typescript.instructions.md)

**/*.{ts,tsx,mts,cts}: Use const type parameters for more precise literal inference in TypeScript 5.0+
Use the satisfies operator to validate types without widening them
Leverage inferred type predicates to reduce the need for explicit is return types in filter/check functions
Use NoInfer<T> utility to block inference for specific type arguments when they should be determined by other arguments
Utilize narrowing in switch(true) blocks for control flow analysis (TypeScript 5.3+)
Rely on narrowing from direct boolean comparisons for type guards
Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+)
Use constant indices to narrow object/array properties (TypeScript 5.5+)
Use standard ECMAScript decorators (Stage 3) instead of legacy experimentalDecorators
Use using declarations for explicit resource management with Disposable pattern instead of manual cleanup (TypeScript 5.2+)
Use with { type: "json" } for import attributes; avoid deprecated assert syntax (TypeScript 5.3/5.8+)
Use import type explicitly when importing types to ensure they are erased during compilation, respecting verbatimModuleSyntax flag
Use .ts, .mts, .cts extensions in import type statements (TypeScript 5.2+)
Use import type { Type } from "mod" with { "resolution-mode": "import" } for specific module resolution contexts (TypeScript 5.3+)
Use new iterator methods (map, filter, etc.) if targeting modern environments (TypeScript 5.6+)
Utilize new Set methods like union, intersection, etc., when available (TypeScript 5.5+)
Use Object.groupBy / Map.groupBy standard methods for grouping instead of external libraries (TypeScript 5.4+)
Use Promise.withResolvers() for creating promises with exposed resolve/reject functions (TypeScript 5.7+)
Use copying array methods (toSorted, toSpliced, with) for immutable array operations (TypeScript 5.2+)
Avoid accessing instance fields via super in classes (TypeScript 5....

Files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/shared-state/src/store/rich-filters/filter.ts
  • packages/utils/src/work-item-filters/configs/filters/priority.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Enable TypeScript strict mode and ensure all files are fully typed

Files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/shared-state/src/store/rich-filters/filter.ts
  • packages/utils/src/work-item-filters/configs/filters/priority.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
**/*.{js,jsx,ts,tsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with Tailwind plugin for code formatting, run pnpm fix:format

Files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/shared-state/src/store/rich-filters/filter.ts
  • packages/utils/src/work-item-filters/configs/filters/priority.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Use ESLint with shared config across packages, adhering to max warnings limits per package
Use camelCase for variable and function names, PascalCase for components and types
Use try-catch with proper error types and log errors appropriately

Files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/shared-state/src/store/rich-filters/filter.ts
  • packages/utils/src/work-item-filters/configs/filters/priority.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
packages/shared-state/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain MobX stores in packages/shared-state using reactive patterns

Files:

  • packages/shared-state/src/store/rich-filters/filter.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions

Applied to files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/state.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use the `satisfies` operator to validate types without widening them

Applied to files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use `const` type parameters for more precise literal inference in TypeScript 5.0+

Applied to files:

  • packages/types/src/rich-filters/config/filter-config.ts
  • packages/utils/src/work-item-filters/configs/filters/date.ts
  • packages/utils/src/work-item-filters/configs/filters/cycle.ts
  • packages/utils/src/work-item-filters/configs/filters/user.ts
  • packages/utils/src/work-item-filters/configs/filters/label.ts
  • packages/utils/src/work-item-filters/configs/filters/project.ts
  • packages/types/src/rich-filters/operator-configs/index.ts
  • packages/types/src/rich-filters/operator-configs/core.ts
  • packages/utils/src/work-item-filters/configs/filters/module.ts
  • packages/utils/src/rich-filters/factories/configs/shared.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Rely on narrowing from direct boolean comparisons for type guards

Applied to files:

  • packages/types/src/rich-filters/operator-configs/index.ts
📚 Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use constant indices to narrow object/array properties (TypeScript 5.5+)

Applied to files:

  • packages/types/src/rich-filters/operator-configs/index.ts
📚 Learning: 2025-12-12T15:20:36.542Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to packages/shared-state/**/*.{ts,tsx} : Maintain MobX stores in `packages/shared-state` using reactive patterns

Applied to files:

  • packages/utils/src/work-item-filters/configs/filters/state.ts
🧬 Code graph analysis (13)
packages/types/src/rich-filters/config/filter-config.ts (2)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterProperty (19-19)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (43-46)
packages/utils/src/work-item-filters/configs/filters/date.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/work-item-filters/configs/filters/cycle.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/work-item-filters/configs/filters/user.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/shared-state/src/store/rich-filters/filter.ts (2)
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/priority.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/work-item-filters/configs/filters/label.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/work-item-filters/configs/filters/project.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/types/src/rich-filters/operator-configs/index.ts (3)
packages/types/src/rich-filters/operator-configs/core.ts (3)
  • TCoreExactOperatorConfigs (11-13)
  • TCoreInOperatorConfigs (16-16)
  • TCoreRangeOperatorConfigs (19-19)
packages/types/src/rich-filters/operator-configs/extended.ts (4)
  • TExtendedExactOperatorConfigs (4-4)
  • TExtendedInOperatorConfigs (7-7)
  • TExtendedRangeOperatorConfigs (10-10)
  • TExtendedOperatorSpecificConfigs (13-13)
packages/types/src/rich-filters/operators/index.ts (3)
  • EQUALITY_OPERATOR (25-28)
  • COLLECTION_OPERATOR (30-33)
  • COMPARISON_OPERATOR (35-38)
packages/types/src/rich-filters/operator-configs/core.ts (3)
packages/types/src/rich-filters/field-types/core.ts (4)
  • TSingleSelectFilterFieldConfig (51-55)
  • TDateFilterFieldConfig (28-31)
  • TMultiSelectFilterFieldConfig (63-68)
  • TDateRangeFilterFieldConfig (39-42)
packages/types/src/rich-filters/expression.ts (1)
  • TFilterValue (24-24)
packages/types/src/rich-filters/operators/core.ts (3)
  • CORE_EQUALITY_OPERATOR (11-13)
  • CORE_COLLECTION_OPERATOR (18-20)
  • CORE_COMPARISON_OPERATOR (25-27)
packages/utils/src/work-item-filters/configs/filters/state.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/work-item-filters/configs/filters/module.ts (1)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • createFilterConfig (22-22)
packages/utils/src/rich-filters/factories/configs/shared.ts (3)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorSpecificConfigs (33-37)
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). (3)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Build packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (16)
packages/utils/src/work-item-filters/configs/filters/cycle.ts (1)

48-48: LGTM! Mechanical type parameter simplification.

The change from createFilterConfig<P, string> to createFilterConfig<P> correctly aligns with the PR's objective to decouple filter value types from filter configurations. This allows operators to specify their own value types instead of being constrained to a single type per filter.

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

52-52: LGTM! Consistent with the refactoring pattern.

The removal of the second generic parameter aligns with the broader refactor to simplify filter configuration type parameters.

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

48-48: LGTM! Type parameter simplification applied consistently.

The change correctly removes the value type parameter, aligning with the refactor objectives.

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

19-19: LGTM! Mechanical refactor applied consistently.

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

48-48: LGTM! Refactor applied consistently.

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

18-18: LGTM! All date filter configs updated consistently.

All four date filter config builders (getStartDateFilterConfig, getTargetDateFilterConfig, getCreatedAtFilterConfig, getUpdatedAtFilterConfig) have been updated to remove the Date type parameter, maintaining consistency with the refactor across all filter types.

Also applies to: 36-36, 54-54, 72-72

packages/types/src/rich-filters/config/filter-config.ts (2)

1-1: LGTM! Import updated to match new type signature.

Correctly removes TFilterValue import as the type is no longer parameterized by value type.


11-17: LGTM! Core type refactor successfully decouples value types from filter config.

The removal of the V generic parameter from TFilterConfig and the change to use non-generic TOperatorConfigMap enables operators to have different value types instead of being constrained to a single type per filter. This is the foundational change that enables all the mechanical updates across filter config builders.

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

51-51: LGTM! Both state filter configs updated consistently.

Both getStateGroupFilterConfig and getStateFilterConfig have been updated to remove their respective type parameters (TStateGroups and string), maintaining consistency with the broader refactor.

Also applies to: 105-105

packages/utils/src/work-item-filters/configs/filters/user.ts (2)

21-34: LGTM!

The removal of the second generic parameter from createFilterConfig<P> aligns correctly with the updated signature in shared.ts. The filter configuration structure remains intact while simplifying the type parameterization.


49-62: Consistent refactoring across all user filter builders.

The same pattern is correctly applied to getMentionFilterConfig, getCreatedByFilterConfig, and getSubscriberFilterConfig. All now use createFilterConfig<P> without the value type parameter, maintaining consistency with the PR's goal of decoupling value types from filter configurations.

Also applies to: 77-90, 105-118

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

113-117: Interface update looks good.

The new optional forceUpdate?: boolean parameter is correctly added to the interface, maintaining backward compatibility since it's optional.

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

10-26: Type simplification aligns with PR goals.

Removing the generic V parameter from operator config types and using TFilterValue directly is consistent with the PR's objective to make value types operator-specific. The underlying field types (TSingleSelectFilterFieldConfig<TFilterValue>, etc.) still provide the structure, while the config level no longer constrains to specific value subtypes.

This trade-off of slightly less precise config-level typing for increased flexibility in handling diverse value types per operator is reasonable given the stated problem.

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

33-46: Type mapping and Map definition look correct.

The TOperatorSpecificConfigs mapped type correctly associates each operator with its composed config type, and the intersection with TExtendedOperatorSpecificConfigs allows for extensibility. The TOperatorConfigMap type using Map<keyof TOperatorSpecificConfigs, TOperatorSpecificConfigs[keyof TOperatorSpecificConfigs]> provides proper key-value typing for the operator config storage.

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

22-22: Simplified createFilterConfig signature.

Removing the value type generic V from createFilterConfig aligns with the PR's goal of decoupling value types from filter configurations. The function remains a simple identity helper for type inference with just the property type P.


64-74: Good approach for Map compatibility, but note the type widening trade-off.

The return type [TSupportedOperators, TOperatorSpecificConfigs[keyof TOperatorSpecificConfigs]] is necessary for the Map constructor to accept entries with different config types. While the input configFn returns the specific type T, the tuple return type is widened to the union of all possible configs.

This is a reasonable trade-off: you lose the ability to infer the specific config type from the return value, but gain the flexibility to construct heterogeneous operator config maps. The type safety is preserved because T extends TOperatorSpecificConfigs[keyof TOperatorSpecificConfigs] ensures only valid configs can be passed in.

…ions

Eliminate the generic value type parameter from filter configurations to allow for operator-specific value types. This change enhances flexibility by enabling different operators to accept various value types for the same filter property.

- Updated TFilterConfig and related interfaces to remove value type constraints
- Adjusted filter configuration methods and types accordingly
- Refactored date operator support to align with the new structure
@sriramveeraghanta sriramveeraghanta merged commit f04be48 into preview Dec 24, 2025
10 checks passed
@sriramveeraghanta sriramveeraghanta deleted the refactor-filter-types branch December 24, 2025 15:33
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.

3 participants