[WEB-4951] [WEB-4884] feat: work item filters revamp (#7810)
This commit is contained in:
parent
e6a7ca4c72
commit
9aef5d4aa9
160 changed files with 5879 additions and 4881 deletions
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
43
packages/utils/src/work-item-filters/configs/filters/date.ts
Normal file
43
packages/utils/src/work-item-filters/configs/filters/date.ts
Normal 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),
|
||||
});
|
||||
|
|
@ -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";
|
||||
|
|
@ -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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
|
|
@ -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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
|
|
@ -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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
|
|
@ -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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
|
|
@ -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,
|
||||
}
|
||||
);
|
||||
127
packages/utils/src/work-item-filters/configs/filters/state.ts
Normal file
127
packages/utils/src/work-item-filters/configs/filters/state.ts
Normal 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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
156
packages/utils/src/work-item-filters/configs/filters/user.ts
Normal file
156
packages/utils/src/work-item-filters/configs/filters/user.ts
Normal 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)
|
||||
),
|
||||
]),
|
||||
});
|
||||
1
packages/utils/src/work-item-filters/configs/index.ts
Normal file
1
packages/utils/src/work-item-filters/configs/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./filters";
|
||||
1
packages/utils/src/work-item-filters/index.ts
Normal file
1
packages/utils/src/work-item-filters/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./configs";
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue