diff --git a/apps/api/plane/utils/filters/filterset.py b/apps/api/plane/utils/filters/filterset.py index 8fff8de37..0099b83d0 100644 --- a/apps/api/plane/utils/filters/filterset.py +++ b/apps/api/plane/utils/filters/filterset.py @@ -159,6 +159,7 @@ class IssueFilterSet(BaseFilterSet): "start_date": ["exact", "range"], "target_date": ["exact", "range"], "created_at": ["exact", "range"], + "updated_at": ["exact", "range"], "is_draft": ["exact"], "priority": ["exact", "in"], } diff --git a/apps/web/ce/components/rich-filters/filter-value-input/root.tsx b/apps/web/ce/components/rich-filters/filter-value-input/root.tsx new file mode 100644 index 000000000..5a3842164 --- /dev/null +++ b/apps/web/ce/components/rich-filters/filter-value-input/root.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import { observer } from "mobx-react"; +// plane imports +import { TFilterValue, TFilterProperty } from "@plane/types"; +// local imports +import { TFilterValueInputProps } from "@/components/rich-filters/shared"; + +export const AdditionalFilterValueInput = observer( +
(_props: TFilterValueInputProps
) => ( + // Fallback +
= { + buttonConfig?: { + label: string | null; + variant?: TButtonVariant; + className?: string; + defaultOpen?: boolean; + iconConfig?: { + shouldShowIcon: boolean; + iconComponent?: React.ElementType; + }; + isDisabled?: boolean; + }; + filter: IFilterInstance
; + onFilterSelect?: (id: string) => void; +}; + +export const AddFilterButton = observer( +
(props: TAddFilterButtonProps
) => {
+ const { filter, buttonConfig, onFilterSelect } = props;
+ const {
+ variant = "link-neutral",
+ className,
+ label,
+ iconConfig = { shouldShowIcon: true },
+ isDisabled = false,
+ } = buttonConfig || {};
+ // derived values
+ const FilterIcon = iconConfig.iconComponent || ListFilter;
+
+ const handleFilterSelect = (property: P, operator: TSupportedOperators, isNegation: boolean) => {
+ filter.addCondition(
+ LOGICAL_OPERATOR.AND,
+ {
+ property,
+ operator,
+ value: undefined,
+ },
+ isNegation
+ );
+ onFilterSelect?.(property);
+ };
+
+ if (isDisabled) return null;
+ return (
+ = {
+export type TAddFilterDropdownProps = {
+ customButton: React.ReactNode;
buttonConfig?: {
- label: string | null;
- variant?: TButtonVariant;
className?: string;
defaultOpen?: boolean;
- iconConfig?: {
- shouldShowIcon: boolean;
- iconComponent?: React.ElementType;
- };
isDisabled?: boolean;
};
filter: IFilterInstance ;
- onFilterSelect?: (id: string) => void;
+ handleFilterSelect: (property: P, operator: TSupportedOperators, isNegation: boolean) => void;
};
-export const AddFilterButton = observer(
- (props: TAddFilterButtonProps ) => {
- const { filter, buttonConfig, onFilterSelect } = props;
- const {
- label,
- variant = "link-neutral",
- className,
- defaultOpen = false,
- iconConfig = { shouldShowIcon: true },
- isDisabled = false,
- } = buttonConfig || {};
- // derived values
- const FilterIcon = iconConfig.iconComponent || ListFilter;
+export const AddFilterDropdown = observer(
+ (props: TAddFilterDropdownProps ) => {
+ const { filter, customButton, buttonConfig } = props;
+ const { className, defaultOpen = false, isDisabled = false } = buttonConfig || {};
// Transform available filter configs to CustomSearchSelect options format
const filterOptions = filter.configManager.allAvailableConfigs.map((config) => ({
value: config.id,
content: (
- {
+ conditionId: string;
+ filter: IFilterInstance ;
+}
+
+export const FilterItemCloseButton = observer(
+ (props: FilterItemCloseButtonProps ) => {
+ const { conditionId, filter } = props;
+
+ const handleRemoveFilter = () => {
+ filter.removeCondition(conditionId);
+ };
+
+ return (
+
+ );
+ }
+);
diff --git a/apps/web/core/components/rich-filters/filter-item/container.tsx b/apps/web/core/components/rich-filters/filter-item/container.tsx
new file mode 100644
index 000000000..f044c1b32
--- /dev/null
+++ b/apps/web/core/components/rich-filters/filter-item/container.tsx
@@ -0,0 +1,64 @@
+import { useEffect, useRef } from "react";
+// plane imports
+import { Tooltip } from "@plane/propel/tooltip";
+import { cn } from "@plane/propel/utils";
+import { SingleOrArray, TFilterValue } from "@plane/types";
+import { hasValidValue } from "@plane/utils";
+
+interface FilterItemContainerProps {
+ children: React.ReactNode;
+ conditionValue: SingleOrArray (props: IFilterItemProps ) => {
+ const { condition, filter, isDisabled = false, showTransition = true } = props;
+
+ return (
+ {
+ conditionId: string;
+ icon: React.FC ;
+ label: string;
+ tooltipContent?: React.ReactNode | undefined;
+}
+
+export const FilterItemProperty = observer(
+ (props: IFilterItemPropertyProps ) => {
+ const { conditionId, filter, isDisabled } = props;
+
+ if (isDisabled) {
+ return = IFilterItemPropertyProps & {
+ className?: string;
+};
+
+const PropertyButton = (props: TPropertyButtonProps ) => {
+ const { icon: Icon, label, tooltipContent, className } = props;
+
+ return (
+ {
+export interface IFilterItemProps {
condition: TFilterConditionNodeForDisplay ;
filter: IFilterInstance ;
isDisabled?: boolean;
@@ -25,10 +29,8 @@ interface FilterItemProps
}
export const FilterItem = observer(
- (props: FilterItemProps ) => {
+ (props: IFilterItemProps ) => {
const { condition, filter, isDisabled = false, showTransition = true } = props;
- // refs
- const itemRef = useRef = {
config: TDateRangeFilterFieldConfig = {
config: TDateFilterFieldConfig = {
- condition: TFilterConditionNodeForDisplay ;
- filterFieldConfig: TSupportedFilterFieldConfigs (props: TFilterValueInputProps ) => {
const { condition, filterFieldConfig, isDisabled = false, onChange } = props;
@@ -80,11 +74,6 @@ export const FilterValueInput = observer(
);
}
- // Fallback
- return (
- = {
filter: IFilterInstance | undefined;
diff --git a/apps/web/core/components/rich-filters/shared.ts b/apps/web/core/components/rich-filters/shared.ts
index 7361c81f2..9caf23643 100644
--- a/apps/web/core/components/rich-filters/shared.ts
+++ b/apps/web/core/components/rich-filters/shared.ts
@@ -1 +1,18 @@
+import {
+ SingleOrArray,
+ TFilterConditionNodeForDisplay,
+ TFilterProperty,
+ TFilterValue,
+ TSupportedFilterFieldConfigs,
+} from "@plane/types";
+
export const COMMON_FILTER_ITEM_BORDER_CLASSNAME = "border-r border-custom-border-200";
+
+export const EMPTY_FILTER_PLACEHOLDER_TEXT = "--";
+
+export type TFilterValueInputProps = {
+ condition: TFilterConditionNodeForDisplay ;
+ filterFieldConfig: TSupportedFilterFieldConfigs >; // filter property -> config
configOptions: TConfigOptions;
+ areConfigsReady: boolean;
// computed
allAvailableConfigs: IFilterConfig [];
// computed functions
@@ -32,6 +33,7 @@ export interface IFilterConfigManager {
register: []) => void;
updateConfigByProperty: (property: P, configUpdates: Partial ["filterConfigs"];
configOptions: IFilterConfigManager ["configOptions"];
+ areConfigsReady: IFilterConfigManager ["areConfigsReady"];
// parent filter instance
private _filterInstance: IFilterInstance ;
@@ -69,18 +72,21 @@ export class FilterConfigManager , params: TConfigManagerParams) {
this.filterConfigs = new Map >();
this.configOptions = this._initializeConfigOptions(params.options);
+ this.areConfigsReady = true;
// parent filter instance
this._filterInstance = filterInstance;
makeObservable(this, {
filterConfigs: observable,
configOptions: observable,
+ areConfigsReady: observable,
// computed
allAvailableConfigs: computed,
// helpers
register: action,
registerAll: action,
updateConfigByProperty: action,
+ setAreConfigsReady: action,
});
}
@@ -146,6 +152,14 @@ export class FilterConfigManager ["setAreConfigsReady"] = action((value) => {
+ this.areConfigsReady = value;
+ });
+
// ------------ private computed ------------
private get _allConfigs(): IFilterConfig [] {
diff --git a/packages/shared-state/src/store/rich-filters/filter-helpers.ts b/packages/shared-state/src/store/rich-filters/filter-helpers.ts
index c9483408b..9c57c3d71 100644
--- a/packages/shared-state/src/store/rich-filters/filter-helpers.ts
+++ b/packages/shared-state/src/store/rich-filters/filter-helpers.ts
@@ -6,6 +6,7 @@ import {
IFilterAdapter,
LOGICAL_OPERATOR,
TSupportedOperators,
+ TFilterConditionNode,
TFilterExpression,
TFilterValue,
TFilterProperty,
@@ -43,9 +44,16 @@ export interface IFilterInstanceHelper ,
isNegation: boolean
) => TFilterExpression | null;
+ handleConditionPropertyUpdate: (
+ expression: TFilterExpression ,
+ conditionId: string,
+ property: P,
+ operator: TSupportedOperators,
+ isNegation: boolean
+ ) => TFilterExpression | null;
// group operations
restructureExpressionForOperatorChange: (
- expression: TFilterExpression | null,
+ expression: TFilterExpression ,
conditionId: string,
newOperator: TSupportedOperators,
isNegation: boolean,
@@ -162,6 +170,28 @@ export class FilterInstanceHelper this._addConditionByOperator(expression, groupOperator, this._getConditionPayloadToAdd(condition, isNegation));
+ /**
+ * Updates the property and operator of a condition in the filter expression.
+ * This method updates the property, operator, resets the value, and handles negation properly.
+ * @param expression - The filter expression to operate on
+ * @param conditionId - The ID of the condition being updated
+ * @param property - The new property for the condition
+ * @param operator - The new operator for the condition
+ * @param isNegation - Whether the condition should be negated
+ * @returns The updated expression
+ */
+ handleConditionPropertyUpdate: IFilterInstanceHelper ["handleConditionPropertyUpdate"] = (
+ expression,
+ conditionId,
+ property,
+ operator,
+ isNegation
+ ) => {
+ const payload = { property, operator, value: undefined };
+
+ return this._updateCondition(expression, conditionId, payload, isNegation);
+ };
+
// ------------ group operations ------------
/**
@@ -177,17 +207,12 @@ export class FilterInstanceHelper {
- if (!expression) return null;
-
const payload = shouldResetValue ? { operator: newOperator, value: undefined } : { operator: newOperator };
- // Update the condition with the new operator
- updateNodeInExpression(expression, conditionId, payload);
-
- return expression;
+ return this._updateCondition(expression, conditionId, payload, isNegation);
};
// ------------ private helpers ------------
@@ -227,4 +252,24 @@ export class FilterInstanceHelper ,
+ conditionId: string,
+ payload: Partial | null => {
+ // Update the condition with the payload
+ updateNodeInExpression(expression, conditionId, payload);
+
+ return expression;
+ };
}
diff --git a/packages/shared-state/src/store/rich-filters/filter.ts b/packages/shared-state/src/store/rich-filters/filter.ts
index be13c7f88..94236036b 100644
--- a/packages/shared-state/src/store/rich-filters/filter.ts
+++ b/packages/shared-state/src/store/rich-filters/filter.ts
@@ -1,4 +1,4 @@
-import { cloneDeep } from "lodash-es";
+import { cloneDeep, isEqual } from "lodash-es";
import { action, computed, makeObservable, observable, toJS } from "mobx";
import { computedFn } from "mobx-utils";
import { v4 as uuidv4 } from "uuid";
@@ -101,6 +101,12 @@ export interface IFilterInstance ,
isNegation: boolean
) => void;
+ updateConditionProperty: (
+ conditionId: string,
+ property: P,
+ operator: TSupportedOperators,
+ isNegation: boolean
+ ) => void;
updateConditionOperator: (conditionId: string, operator: TSupportedOperators, isNegation: boolean) => void;
updateConditionValue: ["updateConditionProperty"] = action(
+ (conditionId: string, property: P, operator: TSupportedOperators, isNegation: boolean) => {
+ if (!this.expression) return;
+ const conditionBeforeUpdate = cloneDeep(findNodeById(this.expression, conditionId));
+ if (!conditionBeforeUpdate || conditionBeforeUpdate.type !== FILTER_NODE_TYPE.CONDITION) return;
+
+ // Update the condition property
+ const updatedExpression = this.helper.handleConditionPropertyUpdate(
+ this.expression,
+ conditionId,
+ property,
+ operator,
+ isNegation
+ );
+
+ if (updatedExpression) {
+ this.expression = updatedExpression;
+ this._notifyExpressionChange();
+ }
+ }
+ );
+
/**
* Updates the operator of a condition in the filter expression.
* @param conditionId - The id of the condition to update.
@@ -410,12 +443,23 @@ export class FilterInstance => {
+ private _parseFilterValue = (value: TFilterValue): SingleOrArray ;
+ rightContent?: React.ReactNode; // content to display on the right side of the filter option in the dropdown
+ tooltipContent?: React.ReactNode; // content to display when hovering over the applied filter item in the filter list
};
diff --git a/packages/types/src/rich-filters/operators/core.ts b/packages/types/src/rich-filters/operators/core.ts
index 573b1a0a3..602fdab94 100644
--- a/packages/types/src/rich-filters/operators/core.ts
+++ b/packages/types/src/rich-filters/operators/core.ts
@@ -26,6 +26,11 @@ export const CORE_COMPARISON_OPERATOR = {
RANGE: "range",
} as const;
+/**
+ * Core operators that support multiple values
+ */
+export const CORE_MULTI_VALUE_OPERATORS = [CORE_COLLECTION_OPERATOR.IN, CORE_COMPARISON_OPERATOR.RANGE] as const;
+
/**
* All core operators
*/
diff --git a/packages/types/src/rich-filters/operators/extended.ts b/packages/types/src/rich-filters/operators/extended.ts
index db54ec91e..4616e40b6 100644
--- a/packages/types/src/rich-filters/operators/extended.ts
+++ b/packages/types/src/rich-filters/operators/extended.ts
@@ -18,6 +18,11 @@ export const EXTENDED_COLLECTION_OPERATOR = {} as const;
*/
export const EXTENDED_COMPARISON_OPERATOR = {} as const;
+/**
+ * Extended operators that support multiple values
+ */
+export const EXTENDED_MULTI_VALUE_OPERATORS = [] as const;
+
/**
* All extended operators
*/
diff --git a/packages/types/src/rich-filters/operators/index.ts b/packages/types/src/rich-filters/operators/index.ts
index 458eff497..bcfd3cbba 100644
--- a/packages/types/src/rich-filters/operators/index.ts
+++ b/packages/types/src/rich-filters/operators/index.ts
@@ -4,6 +4,7 @@ import {
CORE_COLLECTION_OPERATOR,
CORE_COMPARISON_OPERATOR,
TCoreSupportedOperators,
+ CORE_MULTI_VALUE_OPERATORS,
} from "./core";
import {
EXTENDED_LOGICAL_OPERATOR,
@@ -11,6 +12,7 @@ import {
EXTENDED_COLLECTION_OPERATOR,
EXTENDED_COMPARISON_OPERATOR,
TExtendedSupportedOperators,
+ EXTENDED_MULTI_VALUE_OPERATORS,
} from "./extended";
// -------- COMPOSED OPERATORS --------
@@ -35,6 +37,11 @@ export const COMPARISON_OPERATOR = {
...EXTENDED_COMPARISON_OPERATOR,
} as const;
+export const MULTI_VALUE_OPERATORS: ReadonlyArray (key: P): TCreateFilterConfig =>
+ (params: TCreateDatePropertyFilterParams) =>
+ createFilterConfig({
+ id: key,
+ ...params,
+ label: params.propertyDisplayName,
+ icon: params.filterIcon,
+ allowMultipleFilters: true,
+ supportedOperatorConfigsMap: getSupportedDateOperators(params),
+ });
diff --git a/packages/utils/src/rich-filters/factories/configs/properties/index.ts b/packages/utils/src/rich-filters/factories/configs/properties/index.ts
new file mode 100644
index 000000000..96edf472a
--- /dev/null
+++ b/packages/utils/src/rich-filters/factories/configs/properties/index.ts
@@ -0,0 +1,3 @@
+export * from "./date";
+export * from "./member-picker";
+export * from "./shared";
diff --git a/packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts b/packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts
new file mode 100644
index 000000000..d94ad4aba
--- /dev/null
+++ b/packages/utils/src/rich-filters/factories/configs/properties/member-picker.ts
@@ -0,0 +1,30 @@
+// plane imports
+import { EQUALITY_OPERATOR, IUserLite, TFilterProperty } from "@plane/types";
+// local imports
+import { createFilterConfig, createOperatorConfigEntry, TCreateFilterConfig } from "../shared";
+import { getMemberMultiSelectConfig, TCreateUserFilterParams, TCustomPropertyFilterParams } from "./shared";
+
+/**
+ * Member picker property filter specific params
+ */
+type TCreateMemberPickerPropertyFilterParams = TCustomPropertyFilterParams (key: P): TCreateFilterConfig =>
+ (params: TCreateMemberPickerPropertyFilterParams) =>
+ createFilterConfig({
+ id: key,
+ ...params,
+ label: params.propertyDisplayName,
+ icon: params.filterIcon,
+ supportedOperatorConfigsMap: new Map([
+ createOperatorConfigEntry(EQUALITY_OPERATOR.EXACT, params, (updatedParams) =>
+ getMemberMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
+ ),
+ ]),
+ });
diff --git a/packages/utils/src/rich-filters/factories/configs/properties/shared.ts b/packages/utils/src/rich-filters/factories/configs/properties/shared.ts
new file mode 100644
index 000000000..1fa1267b2
--- /dev/null
+++ b/packages/utils/src/rich-filters/factories/configs/properties/shared.ts
@@ -0,0 +1,96 @@
+// plane imports
+import {
+ COMPARISON_OPERATOR,
+ EQUALITY_OPERATOR,
+ IProject,
+ IUserLite,
+ TOperatorConfigMap,
+ TSupportedOperators,
+} from "@plane/types";
+// local imports
+import { getDatePickerConfig, getDateRangePickerConfig, getMultiSelectConfig } from "../core";
+import {
+ createOperatorConfigEntry,
+ IFilterIconConfig,
+ TCreateDateFilterParams,
+ TCreateFilterConfigParams,
+} from "../shared";
+
+// ------------ Base User Filter Types ------------
+
+/**
+ * User filter specific params
+ */
+export type TCreateUserFilterParams = TCreateFilterConfigParams &
+ IFilterIconConfig & {
isEnabled: boolean;
allowedOperators: Set ({
id: key,
label: "Cycle",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getCycleMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
diff --git a/packages/utils/src/work-item-filters/configs/filters/date.ts b/packages/utils/src/work-item-filters/configs/filters/date.ts
index 1de8f9728..1492c4518 100644
--- a/packages/utils/src/work-item-filters/configs/filters/date.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/date.ts
@@ -1,8 +1,12 @@
// plane imports
import { TFilterProperty } from "@plane/types";
// local imports
-import { createFilterConfig, TCreateFilterConfig, TCreateDateFilterParams } from "../../../rich-filters";
-import { getSupportedDateOperators } from "./shared";
+import {
+ createFilterConfig,
+ TCreateFilterConfig,
+ TCreateDateFilterParams,
+ getSupportedDateOperators,
+} from "../../../rich-filters";
// ------------ Date filters ------------
@@ -18,8 +22,8 @@ export const getStartDateFilterConfig =
createFilterConfig ({
id: key,
label: "Start date",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
allowMultipleFilters: true,
supportedOperatorConfigsMap: getSupportedDateOperators(params),
});
@@ -36,8 +40,44 @@ export const getTargetDateFilterConfig =
createFilterConfig ({
id: key,
label: "Target date",
+ ...params,
+ icon: params.filterIcon,
+ allowMultipleFilters: true,
+ supportedOperatorConfigsMap: getSupportedDateOperators(params),
+ });
+
+/**
+ * Get the created at filter config
+ * @template K - The filter key
+ * @param key - The filter key to use
+ * @returns A function that takes parameters and returns the created at filter config
+ */
+export const getCreatedAtFilterConfig =
+ (key: P): TCreateFilterConfig =>
+ (params: TCreateDateFilterParams) =>
+ createFilterConfig ({
+ id: key,
+ label: "Created at",
+ ...params,
+ icon: params.filterIcon,
+ allowMultipleFilters: true,
+ supportedOperatorConfigsMap: getSupportedDateOperators(params),
+ });
+
+/**
+ * Get the updated at filter config
+ * @template K - The filter key
+ * @param key - The filter key to use
+ * @returns A function that takes parameters and returns the updated at filter config
+ */
+export const getUpdatedAtFilterConfig =
+ (key: P): TCreateFilterConfig =>
+ (params: TCreateDateFilterParams) =>
+ createFilterConfig ({
+ id: key,
+ label: "Updated at",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
allowMultipleFilters: true,
supportedOperatorConfigsMap: getSupportedDateOperators(params),
});
diff --git a/packages/utils/src/work-item-filters/configs/filters/label.ts b/packages/utils/src/work-item-filters/configs/filters/label.ts
index 41fa84bf3..dcabd9db3 100644
--- a/packages/utils/src/work-item-filters/configs/filters/label.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/label.ts
@@ -59,8 +59,8 @@ export const getLabelFilterConfig =
createFilterConfig ({
id: key,
label: "Label",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getLabelMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
diff --git a/packages/utils/src/work-item-filters/configs/filters/module.ts b/packages/utils/src/work-item-filters/configs/filters/module.ts
index 0c595eb25..8c36409c1 100644
--- a/packages/utils/src/work-item-filters/configs/filters/module.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/module.ts
@@ -53,8 +53,8 @@ export const getModuleFilterConfig =
createFilterConfig ({
id: key,
label: "Module",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getModuleMultiSelectConfig(updatedParams)
diff --git a/packages/utils/src/work-item-filters/configs/filters/priority.ts b/packages/utils/src/work-item-filters/configs/filters/priority.ts
index b04a3b786..0d5834c5e 100644
--- a/packages/utils/src/work-item-filters/configs/filters/priority.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/priority.ts
@@ -56,8 +56,8 @@ export const getPriorityFilterConfig =
createFilterConfig ({
id: key,
label: "Priority",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getPriorityMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
diff --git a/packages/utils/src/work-item-filters/configs/filters/project.ts b/packages/utils/src/work-item-filters/configs/filters/project.ts
index b5c123ed4..fcefa309c 100644
--- a/packages/utils/src/work-item-filters/configs/filters/project.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/project.ts
@@ -1,8 +1,13 @@
// plane imports
import { EQUALITY_OPERATOR, TFilterProperty, COLLECTION_OPERATOR } from "@plane/types";
// local imports
-import { createFilterConfig, createOperatorConfigEntry, TCreateFilterConfig } from "../../../rich-filters";
-import { getProjectMultiSelectConfig, TCreateProjectFilterParams } from "./shared";
+import {
+ createFilterConfig,
+ createOperatorConfigEntry,
+ getProjectMultiSelectConfig,
+ TCreateFilterConfig,
+ TCreateProjectFilterParams,
+} from "../../../rich-filters";
// ------------ Project filter ------------
@@ -18,8 +23,8 @@ export const getProjectFilterConfig =
createFilterConfig ({
id: key,
label: "Projects",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getProjectMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
diff --git a/packages/utils/src/work-item-filters/configs/filters/state.ts b/packages/utils/src/work-item-filters/configs/filters/state.ts
index 2281171e1..b3a3d6daf 100644
--- a/packages/utils/src/work-item-filters/configs/filters/state.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/state.ts
@@ -63,8 +63,8 @@ export const getStateGroupFilterConfig =
createFilterConfig ({
id: key,
label: "State Group",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getStateGroupMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
@@ -87,7 +87,7 @@ export type TCreateStateFilterParams = TCreateFilterConfigParams &
* @param params - The filter params
* @returns The state multi select config
*/
-export const getStateMultiSelectConfig = (params: TCreateStateFilterParams) =>
+export const getStateMultiSelectConfig = (params: TCreateStateFilterParams, singleValueOperator: TSupportedOperators) =>
getMultiSelectConfig ({
id: key,
label: "State",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
- getStateMultiSelectConfig(updatedParams)
+ getStateMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});
diff --git a/packages/utils/src/work-item-filters/configs/filters/user.ts b/packages/utils/src/work-item-filters/configs/filters/user.ts
index cae90b871..f5c1cb7e2 100644
--- a/packages/utils/src/work-item-filters/configs/filters/user.ts
+++ b/packages/utils/src/work-item-filters/configs/filters/user.ts
@@ -1,48 +1,14 @@
// plane imports
-import { EQUALITY_OPERATOR, IUserLite, TFilterProperty, COLLECTION_OPERATOR } from "@plane/types";
+import { EQUALITY_OPERATOR, TFilterProperty, COLLECTION_OPERATOR } from "@plane/types";
// local imports
import {
createFilterConfig,
- TCreateFilterConfigParams,
- IFilterIconConfig,
TCreateFilterConfig,
- getMultiSelectConfig,
createOperatorConfigEntry,
+ getMemberMultiSelectConfig,
+ TCreateUserFilterParams,
} from "../../../rich-filters";
-// ------------ Base User Filter Types ------------
-
-/**
- * User filter specific params
- */
-export type TCreateUserFilterParams = TCreateFilterConfigParams &
- IFilterIconConfig ({
id: key,
label: "Assignees",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
- getMemberMultiSelectConfig(updatedParams)
+ getMemberMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});
@@ -90,11 +56,11 @@ export const getMentionFilterConfig =
createFilterConfig ({
id: key,
label: "Mentions",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
- getMemberMultiSelectConfig(updatedParams)
+ getMemberMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});
@@ -118,11 +84,11 @@ export const getCreatedByFilterConfig =
createFilterConfig ({
id: key,
label: "Created by",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
- getMemberMultiSelectConfig(updatedParams)
+ getMemberMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});
@@ -146,11 +112,11 @@ export const getSubscriberFilterConfig =
createFilterConfig ({
id: key,
label: "Subscriber",
+ ...params,
icon: params.filterIcon,
- isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
- getMemberMultiSelectConfig(updatedParams)
+ getMemberMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});