[WEB-5804] refactor: decouple filter value types from filter configurations (#8441)

* [WEB-5804] refactor: decouple filter value types from filter configurations

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

* refactor: remove filter value type constraints from filter configurations

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
This commit is contained in:
Prateek Shourya 2025-12-24 21:03:22 +05:30 committed by GitHub
parent 5499e49b72
commit f04be48f61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 126 additions and 133 deletions

View file

@ -41,7 +41,7 @@ export const getMemberMultiSelectConfig = (params: TCreateUserFilterParams, sing
// ------------ Date Operators ------------
export const getSupportedDateOperators = (params: TCreateDateFilterParams): TOperatorConfigMap<Date> =>
export const getSupportedDateOperators = (params: TCreateDateFilterParams): TOperatorConfigMap =>
new Map([
createOperatorConfigEntry(EQUALITY_OPERATOR.EXACT, params, (updatedParams) => getDatePickerConfig(updatedParams)),
createOperatorConfigEntry(COMPARISON_OPERATOR.RANGE, params, (updatedParams) =>

View file

@ -11,6 +11,7 @@ import type {
TSingleSelectFilterFieldConfig,
TSupportedFilterFieldConfigs,
TSupportedOperators,
TOperatorSpecificConfigs,
} from "@plane/types";
/**
@ -18,9 +19,7 @@ import type {
* @param config - The filter config to create
* @returns The created filter config
*/
export const createFilterConfig = <P extends TFilterProperty, V extends TFilterValue>(
config: TFilterConfig<P, V>
): TFilterConfig<P, V> => config;
export const createFilterConfig = <P extends TFilterProperty>(config: TFilterConfig<P>): TFilterConfig<P> => config;
/**
* Base parameters for filter type config factory functions.
@ -56,16 +55,20 @@ export type TCreateDateFilterParams = TCreateFilterConfigParams & IFilterIconCon
/**
* Helper to create an operator entry for the supported operators map.
* This ensures consistency between the operator key and the operator passed to the config function.
* Returns a type compatible with TOperatorSpecificConfigs so Map constructor accepts union types.
* @param operator - The operator to use as both key and parameter
* @param createParams - The base filter configuration parameters
* @param configFn - Function that creates the operator config using base configuration
* @returns A tuple of operator and its config
* @returns A tuple of operator and its config, typed to be compatible with operator configs map
*/
export const createOperatorConfigEntry = <T, P extends TCreateFilterConfigParams>(
export const createOperatorConfigEntry = <
T extends TOperatorSpecificConfigs[keyof TOperatorSpecificConfigs],
P extends TCreateFilterConfigParams,
>(
operator: TSupportedOperators,
createParams: P,
configFn: (updatedParams: P) => T
): [TSupportedOperators, T] => [
): [TSupportedOperators, TOperatorSpecificConfigs[keyof TOperatorSpecificConfigs]] => [
operator,
configFn({ isOperatorEnabled: createParams.allowedOperators.has(operator), ...createParams }),
];

View file

@ -45,7 +45,7 @@ export const getCycleMultiSelectConfig = (params: TCreateCycleFilterParams, sing
export const getCycleFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateCycleFilterParams> =>
(params: TCreateCycleFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Cycle",
...params,

View file

@ -15,7 +15,7 @@ import { createFilterConfig, getSupportedDateOperators } from "../../../rich-fil
export const getStartDateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
createFilterConfig<P>({
id: key,
label: "Start date",
...params,
@ -33,7 +33,7 @@ export const getStartDateFilterConfig =
export const getTargetDateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
createFilterConfig<P>({
id: key,
label: "Target date",
...params,
@ -51,7 +51,7 @@ export const getTargetDateFilterConfig =
export const getCreatedAtFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
createFilterConfig<P>({
id: key,
label: "Created at",
...params,
@ -69,7 +69,7 @@ export const getCreatedAtFilterConfig =
export const getUpdatedAtFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
createFilterConfig<P>({
id: key,
label: "Updated at",
...params,

View file

@ -45,7 +45,7 @@ export const getLabelMultiSelectConfig = (params: TCreateLabelFilterParams, sing
export const getLabelFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateLabelFilterParams> =>
(params: TCreateLabelFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Label",
...params,

View file

@ -45,7 +45,7 @@ export const getModuleMultiSelectConfig = (params: TCreateModuleFilterParams) =>
export const getModuleFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateModuleFilterParams> =>
(params: TCreateModuleFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Module",
...params,

View file

@ -49,7 +49,7 @@ export const getPriorityMultiSelectConfig = (
export const getPriorityFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreatePriorityFilterParams> =>
(params: TCreatePriorityFilterParams) =>
createFilterConfig<P, TIssuePriorities>({
createFilterConfig<P>({
id: key,
label: "Priority",
...params,

View file

@ -16,7 +16,7 @@ import { createFilterConfig, createOperatorConfigEntry, getProjectMultiSelectCon
export const getProjectFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateProjectFilterParams> =>
(params: TCreateProjectFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Projects",
...params,

View file

@ -12,7 +12,7 @@ import {
// ------------ Date filter ------------
export const getSupportedDateOperators = (params: TCreateDateFilterParams): TOperatorConfigMap<Date> =>
export const getSupportedDateOperators = (params: TCreateDateFilterParams): TOperatorConfigMap =>
new Map([
createOperatorConfigEntry(EQUALITY_OPERATOR.EXACT, params, (updatedParams) => getDatePickerConfig(updatedParams)),
createOperatorConfigEntry(COMPARISON_OPERATOR.RANGE, params, (updatedParams) =>

View file

@ -48,7 +48,7 @@ export const getStateGroupMultiSelectConfig = (
export const getStateGroupFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateStateGroupFilterParams> =>
(params: TCreateStateGroupFilterParams) =>
createFilterConfig<P, TStateGroups>({
createFilterConfig<P>({
id: key,
label: "State Group",
...params,
@ -102,7 +102,7 @@ export const getStateMultiSelectConfig = (params: TCreateStateFilterParams, sing
export const getStateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateStateFilterParams> =>
(params: TCreateStateFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "State",
...params,

View file

@ -21,7 +21,7 @@ export type TCreateAssigneeFilterParams = TCreateUserFilterParams;
export const getAssigneeFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateAssigneeFilterParams> =>
(params: TCreateAssigneeFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Assignees",
...params,
@ -49,7 +49,7 @@ export type TCreateMentionFilterParams = TCreateUserFilterParams;
export const getMentionFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateMentionFilterParams> =>
(params: TCreateMentionFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Mentions",
...params,
@ -77,7 +77,7 @@ export type TCreateCreatedByFilterParams = TCreateUserFilterParams;
export const getCreatedByFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateCreatedByFilterParams> =>
(params: TCreateCreatedByFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Created by",
...params,
@ -105,7 +105,7 @@ export type TCreateSubscriberFilterParams = TCreateUserFilterParams;
export const getSubscriberFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateSubscriberFilterParams> =>
(params: TCreateSubscriberFilterParams) =>
createFilterConfig<P, string>({
createFilterConfig<P>({
id: key,
label: "Subscriber",
...params,