[WEB-4951] [WEB-4884] feat: work item filters revamp (#7810)

This commit is contained in:
Prateek Shourya 2025-09-19 18:27:36 +05:30 committed by GitHub
parent e6a7ca4c72
commit 9aef5d4aa9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
160 changed files with 5879 additions and 4881 deletions

View file

@ -1,6 +1,4 @@
import { differenceInCalendarDays } from "date-fns/differenceInCalendarDays";
// plane imports
import { IIssueFilters } from "@plane/types";
// local imports
import { getDate } from "./datetime";
@ -63,17 +61,3 @@ export const satisfiesDateFilter = (date: Date, filter: string): boolean => {
return false;
};
/**
* @description checks if the issue filter is active
* @param {IIssueFilters} issueFilters
* @returns {boolean}
*/
export const isIssueFilterActive = (issueFilters: IIssueFilters | undefined): boolean => {
if (!issueFilters) return false;
const issueType = issueFilters?.displayFilters?.type;
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0 || !!issueType;
return isFiltersApplied;
};

View file

@ -28,5 +28,6 @@ export * from "./subscription";
export * from "./tab-indices";
export * from "./theme";
export * from "./url";
export * from "./work-item-filters";
export * from "./work-item";
export * from "./workspace";

View file

@ -1,30 +1,7 @@
// plane imports
import {
FILTER_FIELD_TYPE,
TFilterValue,
TFilterProperty,
TFilterConfig,
TSupportedOperators,
TBaseFilterFieldConfig,
} from "@plane/types";
import { FILTER_FIELD_TYPE, TFilterValue, TSupportedOperators, TBaseFilterFieldConfig } from "@plane/types";
// local imports
import {
createFilterFieldConfig,
DEFAULT_DATE_FILTER_TYPE_CONFIG,
DEFAULT_DATE_RANGE_FILTER_TYPE_CONFIG,
DEFAULT_MULTI_SELECT_FILTER_TYPE_CONFIG,
DEFAULT_SINGLE_SELECT_FILTER_TYPE_CONFIG,
IFilterIconConfig,
} from "./shared";
/**
* Helper to create a type-safe filter config
* @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;
import { createFilterFieldConfig, IFilterIconConfig } from "./shared";
// ------------ Selection filters ------------
@ -59,12 +36,11 @@ export const getSingleSelectConfig = <
TIconData extends string | number | boolean | object | undefined = undefined,
>(
transforms: TOptionTransforms<TItem, TValue, TIconData>,
config?: TSingleSelectConfig<TValue>,
config: TSingleSelectConfig<TValue>,
iconConfig?: IFilterIconConfig<TIconData>
) =>
createFilterFieldConfig<typeof FILTER_FIELD_TYPE.SINGLE_SELECT, TValue>({
type: FILTER_FIELD_TYPE.SINGLE_SELECT,
...DEFAULT_SINGLE_SELECT_FILTER_TYPE_CONFIG,
...config,
getOptions: () =>
transforms.items.map((item) => ({
@ -101,7 +77,6 @@ export const getMultiSelectConfig = <
) =>
createFilterFieldConfig<typeof FILTER_FIELD_TYPE.MULTI_SELECT, TValue>({
type: FILTER_FIELD_TYPE.MULTI_SELECT,
...DEFAULT_MULTI_SELECT_FILTER_TYPE_CONFIG,
...config,
operatorLabel: config?.operatorLabel,
getOptions: () =>
@ -136,10 +111,9 @@ export type TDateRangeConfig = TBaseFilterFieldConfig & {
* @param config - Date-specific configuration
* @returns The date picker config
*/
export const getDatePickerConfig = (config?: TDateConfig) =>
export const getDatePickerConfig = (config: TDateConfig) =>
createFilterFieldConfig<typeof FILTER_FIELD_TYPE.DATE, Date>({
type: FILTER_FIELD_TYPE.DATE,
...DEFAULT_DATE_FILTER_TYPE_CONFIG,
...config,
});
@ -148,9 +122,8 @@ export const getDatePickerConfig = (config?: TDateConfig) =>
* @param config - Date range-specific configuration
* @returns The date range picker config
*/
export const getDateRangePickerConfig = (config?: TDateRangeConfig) =>
export const getDateRangePickerConfig = (config: TDateRangeConfig) =>
createFilterFieldConfig<typeof FILTER_FIELD_TYPE.DATE_RANGE, Date>({
type: FILTER_FIELD_TYPE.DATE_RANGE,
...DEFAULT_DATE_RANGE_FILTER_TYPE_CONFIG,
...config,
});

View file

@ -10,8 +10,59 @@ import {
TMultiSelectFilterFieldConfig,
TSingleSelectFilterFieldConfig,
TSupportedFilterFieldConfigs,
TSupportedOperators,
} from "@plane/types";
/**
* Helper to create a type-safe filter config
* @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;
/**
* Base parameters for filter type config factory functions.
* - operator: The operator to use for the filter.
*/
export type TCreateFilterConfigParams = Omit<TBaseFilterFieldConfig, "isOperatorEnabled"> & {
isEnabled: boolean;
allowedOperators: Set<TSupportedOperators>;
};
/**
* Icon configuration for filters and their options.
* - filterIcon: Optional icon for the filter
* - getOptionIcon: Function to get icon for specific option values
*/
export interface IFilterIconConfig<T extends string | number | boolean | object | undefined = undefined> {
filterIcon?: React.FC<React.SVGAttributes<SVGElement>>;
getOptionIcon?: (value: T) => React.ReactNode;
}
/**
* Date filter config params
*/
export type TCreateDateFilterParams = TCreateFilterConfigParams & IFilterIconConfig<Date>;
/**
* 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.
* @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
*/
export const createOperatorConfigEntry = <T, P extends TCreateFilterConfigParams>(
operator: TSupportedOperators,
createParams: P,
configFn: (updatedParams: P) => T
): [TSupportedOperators, T] => [
operator,
configFn({ isOperatorEnabled: createParams.allowedOperators.has(operator), ...createParams }),
];
/**
* Factory function signature for creating filter configurations.
*/
@ -33,44 +84,3 @@ export const createFilterFieldConfig = <T extends TFilterFieldType, V extends TF
? TDateRangeFilterFieldConfig<V>
: never
): TSupportedFilterFieldConfigs<V> => config as TSupportedFilterFieldConfigs<V>;
/**
* Base parameters for filter type config factory functions.
* - operator: The operator to use for the filter.
*/
export type TCreateFilterConfigParams = TBaseFilterFieldConfig & {
isEnabled: boolean;
};
/**
* Icon configuration for filters and their options.
* - filterIcon: Optional icon for the filter
* - getOptionIcon: Function to get icon for specific option values
*/
export interface IFilterIconConfig<T extends string | number | boolean | object | undefined = undefined> {
filterIcon?: React.FC<React.SVGAttributes<SVGElement>>;
getOptionIcon?: (value: T) => React.ReactNode;
}
/**
* Date filter config params
*/
export type TCreateDateFilterParams = TCreateFilterConfigParams & IFilterIconConfig<Date>;
// ------------ Default filter type configs ------------
export const DEFAULT_SINGLE_SELECT_FILTER_TYPE_CONFIG = {
allowNegative: false,
};
export const DEFAULT_MULTI_SELECT_FILTER_TYPE_CONFIG = {
allowNegative: false,
};
export const DEFAULT_DATE_FILTER_TYPE_CONFIG = {
allowNegative: false,
};
export const DEFAULT_DATE_RANGE_FILTER_TYPE_CONFIG = {
allowNegative: false,
};

View file

@ -0,0 +1,70 @@
// plane imports
import {
EQUALITY_OPERATOR,
ICycle,
TCycleGroups,
TFilterProperty,
COLLECTION_OPERATOR,
TSupportedOperators,
} from "@plane/types";
// local imports
import {
createFilterConfig,
TCreateFilterConfigParams,
IFilterIconConfig,
TCreateFilterConfig,
getMultiSelectConfig,
createOperatorConfigEntry,
} from "../../../rich-filters";
/**
* Cycle filter specific params
*/
export type TCreateCycleFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<TCycleGroups> & {
cycles: ICycle[];
};
/**
* Helper to get the cycle multi select config
* @param params - The filter params
* @returns The cycle multi select config
*/
export const getCycleMultiSelectConfig = (params: TCreateCycleFilterParams, singleValueOperator: TSupportedOperators) =>
getMultiSelectConfig<ICycle, string, TCycleGroups>(
{
items: params.cycles,
getId: (cycle) => cycle.id,
getLabel: (cycle) => cycle.name,
getValue: (cycle) => cycle.id,
getIconData: (cycle) => cycle.status || "draft",
},
{
singleValueOperator,
...params,
},
{
...params,
}
);
/**
* Get the cycle filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the cycle filter config
*/
export const getCycleFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateCycleFilterParams> =>
(params: TCreateCycleFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Cycle",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getCycleMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});

View file

@ -0,0 +1,43 @@
// plane imports
import { TFilterProperty } from "@plane/types";
// local imports
import { createFilterConfig, TCreateFilterConfig, TCreateDateFilterParams } from "../../../rich-filters";
import { getSupportedDateOperators } from "./shared";
// ------------ Date filters ------------
/**
* Get the start date filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the start date filter config
*/
export const getStartDateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
id: key,
label: "Start date",
icon: params.filterIcon,
isEnabled: params.isEnabled,
allowMultipleFilters: true,
supportedOperatorConfigsMap: getSupportedDateOperators(params),
});
/**
* Get the target date filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the target date filter config
*/
export const getTargetDateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateDateFilterParams> =>
(params: TCreateDateFilterParams) =>
createFilterConfig<P, Date>({
id: key,
label: "Target date",
icon: params.filterIcon,
isEnabled: params.isEnabled,
allowMultipleFilters: true,
supportedOperatorConfigsMap: getSupportedDateOperators(params),
});

View file

@ -0,0 +1,8 @@
export * from "./cycle";
export * from "./date";
export * from "./label";
export * from "./module";
export * from "./priority";
export * from "./project";
export * from "./state";
export * from "./user";

View file

@ -0,0 +1,69 @@
// plane imports
import {
EQUALITY_OPERATOR,
IIssueLabel,
TFilterProperty,
COLLECTION_OPERATOR,
TSupportedOperators,
} from "@plane/types";
// local imports
import {
createFilterConfig,
TCreateFilterConfigParams,
IFilterIconConfig,
TCreateFilterConfig,
getMultiSelectConfig,
createOperatorConfigEntry,
} from "../../../rich-filters";
/**
* Label filter specific params
*/
export type TCreateLabelFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<string> & {
labels: IIssueLabel[];
};
/**
* Helper to get the label multi select config
* @param params - The filter params
* @returns The label multi select config
*/
export const getLabelMultiSelectConfig = (params: TCreateLabelFilterParams, singleValueOperator: TSupportedOperators) =>
getMultiSelectConfig<IIssueLabel, string, string>(
{
items: params.labels,
getId: (label) => label.id,
getLabel: (label) => label.name,
getValue: (label) => label.id,
getIconData: (label) => label.color,
},
{
singleValueOperator,
...params,
},
{
getOptionIcon: params.getOptionIcon,
}
);
/**
* Get the label filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the label filter config
*/
export const getLabelFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateLabelFilterParams> =>
(params: TCreateLabelFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Label",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getLabelMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});

View file

@ -0,0 +1,63 @@
// plane imports
import { EQUALITY_OPERATOR, IModule, TFilterProperty, COLLECTION_OPERATOR } from "@plane/types";
// local imports
import {
createFilterConfig,
TCreateFilterConfigParams,
IFilterIconConfig,
TCreateFilterConfig,
getMultiSelectConfig,
createOperatorConfigEntry,
} from "../../../rich-filters";
/**
* Module filter specific params
*/
export type TCreateModuleFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<undefined> & {
modules: IModule[];
};
/**
* Helper to get the module multi select config
* @param params - The filter params
* @returns The module multi select config
*/
export const getModuleMultiSelectConfig = (params: TCreateModuleFilterParams) =>
getMultiSelectConfig<IModule, string, undefined>(
{
items: params.modules,
getId: (module) => module.id,
getLabel: (module) => module.name,
getValue: (module) => module.id,
getIconData: () => undefined,
},
{
singleValueOperator: EQUALITY_OPERATOR.EXACT,
...params,
},
{
...params,
}
);
/**
* Get the module filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the module filter config
*/
export const getModuleFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateModuleFilterParams> =>
(params: TCreateModuleFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Module",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getModuleMultiSelectConfig(updatedParams)
),
]),
});

View file

@ -0,0 +1,66 @@
// plane imports
import { ISSUE_PRIORITIES, TIssuePriorities } from "@plane/constants";
import { EQUALITY_OPERATOR, TFilterProperty, COLLECTION_OPERATOR, TSupportedOperators } from "@plane/types";
// local imports
import {
createFilterConfig,
TCreateFilterConfigParams,
IFilterIconConfig,
TCreateFilterConfig,
getMultiSelectConfig,
createOperatorConfigEntry,
} from "../../../rich-filters";
// ------------ Priority filter ------------
/**
* Priority filter specific params
*/
export type TCreatePriorityFilterParams = TCreateFilterConfigParams & IFilterIconConfig<TIssuePriorities>;
/**
* Helper to get the priority multi select config
* @param params - The filter params
* @returns The priority multi select config
*/
export const getPriorityMultiSelectConfig = (
params: TCreatePriorityFilterParams,
singleValueOperator: TSupportedOperators
) =>
getMultiSelectConfig<{ key: TIssuePriorities; title: string }, TIssuePriorities, TIssuePriorities>(
{
items: ISSUE_PRIORITIES,
getId: (priority) => priority.key,
getLabel: (priority) => priority.title,
getValue: (priority) => priority.key,
getIconData: (priority) => priority.key,
},
{
singleValueOperator,
...params,
},
{
getOptionIcon: params.getOptionIcon,
}
);
/**
* Get the priority filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the priority filter config
*/
export const getPriorityFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreatePriorityFilterParams> =>
(params: TCreatePriorityFilterParams) =>
createFilterConfig<P, TIssuePriorities>({
id: key,
label: "Priority",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getPriorityMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});

View file

@ -0,0 +1,28 @@
// 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";
// ------------ Project filter ------------
/**
* Get the project filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the project filter config
*/
export const getProjectFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateProjectFilterParams> =>
(params: TCreateProjectFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Projects",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getProjectMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});

View file

@ -0,0 +1,64 @@
// plane imports
import {
COMPARISON_OPERATOR,
EQUALITY_OPERATOR,
IProject,
TOperatorConfigMap,
TSupportedOperators,
} from "@plane/types";
// local imports
import {
createOperatorConfigEntry,
getDatePickerConfig,
getDateRangePickerConfig,
getMultiSelectConfig,
IFilterIconConfig,
TCreateDateFilterParams,
TCreateFilterConfigParams,
} from "../../../rich-filters";
// ------------ Date filter ------------
export const getSupportedDateOperators = (params: TCreateDateFilterParams): TOperatorConfigMap<Date> =>
new Map([
createOperatorConfigEntry(EQUALITY_OPERATOR.EXACT, params, (updatedParams) => getDatePickerConfig(updatedParams)),
createOperatorConfigEntry(COMPARISON_OPERATOR.RANGE, params, (updatedParams) =>
getDateRangePickerConfig(updatedParams)
),
]);
// ------------ Project filter ------------
/**
* Project filter specific params
*/
export type TCreateProjectFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<IProject> & {
projects: IProject[];
};
/**
* Helper to get the project multi select config
* @param params - The filter params
* @returns The member multi select config
*/
export const getProjectMultiSelectConfig = (
params: TCreateProjectFilterParams,
singleValueOperator: TSupportedOperators
) =>
getMultiSelectConfig<IProject, string, IProject>(
{
items: params.projects,
getId: (project) => project.id,
getLabel: (project) => project.name,
getValue: (project) => project.id,
getIconData: (project) => project,
},
{
singleValueOperator,
...params,
},
{
...params,
}
);

View file

@ -0,0 +1,127 @@
// plane imports
import { STATE_GROUPS } from "@plane/constants";
import {
COLLECTION_OPERATOR,
EQUALITY_OPERATOR,
IState,
TFilterProperty,
TStateGroups,
TSupportedOperators,
} from "@plane/types";
// local imports
import {
createFilterConfig,
getMultiSelectConfig,
IFilterIconConfig,
TCreateFilterConfig,
TCreateFilterConfigParams,
createOperatorConfigEntry,
} from "../../../rich-filters";
// ------------ State group filter ------------
/**
* State group filter specific params
*/
export type TCreateStateGroupFilterParams = TCreateFilterConfigParams & IFilterIconConfig<TStateGroups>;
/**
* Helper to get the state group multi select config
* @param params - The filter params
* @returns The state group multi select config
*/
export const getStateGroupMultiSelectConfig = (
params: TCreateStateGroupFilterParams,
singleValueOperator: TSupportedOperators
) =>
getMultiSelectConfig<{ key: TStateGroups; label: string }, TStateGroups, TStateGroups>(
{
items: Object.values(STATE_GROUPS),
getId: (state) => state.key,
getLabel: (state) => state.label,
getValue: (state) => state.key,
getIconData: (state) => state.key,
},
{
singleValueOperator,
...params,
},
{
...params,
}
);
/**
* Get the state group filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the state group filter config
*/
export const getStateGroupFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateStateGroupFilterParams> =>
(params: TCreateStateGroupFilterParams) =>
createFilterConfig<P, TStateGroups>({
id: key,
label: "State Group",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getStateGroupMultiSelectConfig(updatedParams, EQUALITY_OPERATOR.EXACT)
),
]),
});
// ------------ State filter ------------
/**
* State filter specific params
*/
export type TCreateStateFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<IState> & {
states: IState[];
};
/**
* Helper to get the state multi select config
* @param params - The filter params
* @returns The state multi select config
*/
export const getStateMultiSelectConfig = (params: TCreateStateFilterParams) =>
getMultiSelectConfig<IState, string, IState>(
{
items: params.states,
getId: (state) => state.id,
getLabel: (state) => state.name,
getValue: (state) => state.id,
getIconData: (state) => state,
},
{
singleValueOperator: EQUALITY_OPERATOR.EXACT,
...params,
},
{
...params,
}
);
/**
* Get the state filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the state filter config
*/
export const getStateFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateStateFilterParams> =>
(params: TCreateStateFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "State",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getStateMultiSelectConfig(updatedParams)
),
]),
});

View file

@ -0,0 +1,156 @@
// plane imports
import { EQUALITY_OPERATOR, IUserLite, TFilterProperty, COLLECTION_OPERATOR } from "@plane/types";
// local imports
import {
createFilterConfig,
TCreateFilterConfigParams,
IFilterIconConfig,
TCreateFilterConfig,
getMultiSelectConfig,
createOperatorConfigEntry,
} from "../../../rich-filters";
// ------------ Base User Filter Types ------------
/**
* User filter specific params
*/
export type TCreateUserFilterParams = TCreateFilterConfigParams &
IFilterIconConfig<IUserLite> & {
members: IUserLite[];
};
/**
* Helper to get the member multi select config
* @param params - The filter params
* @returns The member multi select config
*/
export const getMemberMultiSelectConfig = (params: TCreateUserFilterParams) =>
getMultiSelectConfig<IUserLite, string, IUserLite>(
{
items: params.members,
getId: (member) => member.id,
getLabel: (member) => member.display_name,
getValue: (member) => member.id,
getIconData: (member) => member,
},
{
singleValueOperator: EQUALITY_OPERATOR.EXACT,
...params,
},
{
...params,
}
);
// ------------ Assignee filter ------------
/**
* Assignee filter specific params
*/
export type TCreateAssigneeFilterParams = TCreateUserFilterParams;
/**
* Get the assignee filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the assignee filter config
*/
export const getAssigneeFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateAssigneeFilterParams> =>
(params: TCreateAssigneeFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Assignees",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getMemberMultiSelectConfig(updatedParams)
),
]),
});
// ------------ Mention filter ------------
/**
* Mention filter specific params
*/
export type TCreateMentionFilterParams = TCreateUserFilterParams;
/**
* Get the mention filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the mention filter config
*/
export const getMentionFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateMentionFilterParams> =>
(params: TCreateMentionFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Mentions",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getMemberMultiSelectConfig(updatedParams)
),
]),
});
// ------------ Created by filter ------------
/**
* Created by filter specific params
*/
export type TCreateCreatedByFilterParams = TCreateUserFilterParams;
/**
* Get the created by filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the created by filter config
*/
export const getCreatedByFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateCreatedByFilterParams> =>
(params: TCreateCreatedByFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Created by",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getMemberMultiSelectConfig(updatedParams)
),
]),
});
// ------------ Subscriber filter ------------
/**
* Subscriber filter specific params
*/
export type TCreateSubscriberFilterParams = TCreateUserFilterParams;
/**
* Get the subscriber filter config
* @template K - The filter key
* @param key - The filter key to use
* @returns A function that takes parameters and returns the subscriber filter config
*/
export const getSubscriberFilterConfig =
<P extends TFilterProperty>(key: P): TCreateFilterConfig<P, TCreateSubscriberFilterParams> =>
(params: TCreateSubscriberFilterParams) =>
createFilterConfig<P, string>({
id: key,
label: "Subscriber",
icon: params.filterIcon,
isEnabled: params.isEnabled,
supportedOperatorConfigsMap: new Map([
createOperatorConfigEntry(COLLECTION_OPERATOR.IN, params, (updatedParams) =>
getMemberMultiSelectConfig(updatedParams)
),
]),
});

View file

@ -0,0 +1 @@
export * from "./filters";

View file

@ -0,0 +1 @@
export * from "./configs";

View file

@ -4,15 +4,16 @@ import { v4 as uuidv4 } from "uuid";
// plane imports
import {
ISSUE_DISPLAY_FILTERS_BY_PAGE,
STATE_GROUPS,
TIssuePriorities,
ISSUE_PRIORITY_FILTERS,
STATE_GROUPS,
TIssueFilterPriorityObject,
TIssuePriorities,
} from "@plane/constants";
import {
EIssueLayoutTypes,
IGanttBlock,
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
IGanttBlock,
TGroupedIssues,
TIssue,
TIssueGroupByOptions,
@ -21,7 +22,6 @@ import {
TStateGroups,
TSubGroupedIssues,
TUnGroupedIssues,
EIssueLayoutTypes,
} from "@plane/types";
// local imports
import { orderArrayBy } from "../array";
@ -111,25 +111,20 @@ export const handleIssueQueryParamsByLayout = (
| "team_issues"
| "team_project_work_items"
): TIssueParams[] | null => {
const queryParams: TIssueParams[] = [];
const queryParams: TIssueParams[] = ["filters"];
if (!layout) return null;
const layoutOptions = ISSUE_DISPLAY_FILTERS_BY_PAGE[viewType][layout];
// add filters query params
layoutOptions.filters.forEach((option) => {
queryParams.push(option);
});
const currentViewLayoutOptions = ISSUE_DISPLAY_FILTERS_BY_PAGE[viewType].layoutOptions[layout];
// add display filters query params
Object.keys(layoutOptions.display_filters).forEach((option) => {
Object.keys(currentViewLayoutOptions.display_filters).forEach((option) => {
queryParams.push(option as TIssueParams);
});
// add extra options query params
if (layoutOptions.extra_options.access) {
layoutOptions.extra_options.values.forEach((option) => {
if (currentViewLayoutOptions.extra_options.access) {
currentViewLayoutOptions.extra_options.values.forEach((option) => {
queryParams.push(option);
});
}
@ -286,7 +281,6 @@ export const getComputedDisplayFilters = (
order_by: filters?.order_by || "sort_order",
group_by: filters?.group_by || null,
sub_group_by: filters?.sub_group_by || null,
type: filters?.type || null,
sub_issue: filters?.sub_issue || false,
show_empty_groups: filters?.show_empty_groups || false,
};