-
Notifications
You must be signed in to change notification settings - Fork 2.8k
[WEB-5099] improvement: enhance rich filters with new components and configurations #7916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- 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.
WalkthroughAdds 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
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
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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60–90 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
…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.
Linked to Plane Work Item(s) This comment was auto-generated by Plane |
There was a problem hiding this 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 updatesThe new
_updateCondition
helper just mutates the targeted node and returns, ignoring theisNegation
flag. BothhandleConditionPropertyUpdate
andrestructureExpressionForOperatorChange
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
toTFilterValue
, 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 whenrawValue
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 theobject
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 parametersThe 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
📒 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 ingetAdditionalProjectLevelFiltersHOCProps
, 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
andtooltipContent
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 ofmaxHeight="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
: Spreadingparams
is safe –TCreateLabelFilterParams
only includesisEnabled
,allowedOperators
, optionalrightContent
/tooltipContent
,filterIcon
andlabels
, all of whichcreateFilterConfig
’sTFilterConfig<'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 togetAdditionalProjectLevelFiltersHOCProps
, 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
"--"
withEMPTY_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
includesisEnabled
TCreateProjectFilterParams
extendsTCreateFilterConfigParams
, which declaresisEnabled: boolean
, so...params
already brings inisEnabled
.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
andtooltipContent
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 cleanNice 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 appreciatedUsing
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-containedWrapping 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 solidThe 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 supportPassing 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 consistentThis 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 abstractedCentralizing 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.
There was a problem hiding this 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
📒 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
andgetUpdatedAtFilterConfig
functions are correctly implemented and consistent with the existing date filter configurations.
22-29
: Spread order is safe;TCreateFilterConfigParams
doesn’t defineid
orlabel
, 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
andupdated_at
are now supported inWORK_ITEM_FILTER_PROPERTY_KEYS
and have matching configs (getCreatedAtFilterConfig
,getUpdatedAtFilterConfig
) implemented inpackages/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.
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? |
Merge branch 'preview' of github.com:makeplane/plane into improvement-rich-fitlers-ui
d49d994
There was a problem hiding this 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
📒 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 themaxHeight
reduction doesn't negatively impact UX.The component correctly uses the new
customButton
prop and simplified configuration. However, themaxHeight
was changed from"full"
to"2xl"
, which could limit visibility when there are many available filters.Please verify in the UI that:
- The dropdown is usable when there are many filter options (e.g., 20+ filters)
- The scroll behavior is smooth and intuitive
- 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
: AllAddFilterDropdown
calls includecustomButton
. Verified that both callers explicitly provide this prop.
Description
FilterItem
and related components for better filter item management.Type of Change
Summary by CodeRabbit
New Features
Improvements
Backend