[WEB-4283] fix: update group key handling in issue store utilities for state groups (#7191)

* fix: update group key handling in issue store utilities for state groups

- Introduced a new function to determine the default group key based on the provided groupByKey.
- Updated references to use the new function for improved clarity and maintainability.
- Adjusted the mapping for "state_detail.group" in the ISSUE_GROUP_BY_KEY to ensure consistency.
- Enhanced the getArrayStringArray method to handle group values more effectively.

* refactor: clean up filters constants
This commit is contained in:
Prateek Shourya 2025-06-10 13:56:42 +05:30 committed by GitHub
parent 531748dcc3
commit 6adc721b34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 43 additions and 55 deletions

View file

@ -136,45 +136,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_PAGE: TIssueFiltersToDisplayByPageType = {
], ],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS, display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: { display_filters: {
group_by: [ group_by: ["state", "cycle", "module", "priority", "labels", "assignees", "created_by", null],
"state",
"cycle",
"module",
"state_detail.group",
"priority",
"labels",
"assignees",
"created_by",
null,
],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"],
},
extra_options: {
access: true,
values: ["show_empty_groups"],
},
},
},
draft_issues: {
list: {
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: {
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels", null],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"],
},
extra_options: {
access: true,
values: ["show_empty_groups"],
},
},
kanban: {
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: {
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels"],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"], order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"], type: [null, "active", "backlog"],
}, },

View file

@ -5,7 +5,6 @@ import isEmpty from "lodash/isEmpty";
import orderBy from "lodash/orderBy"; import orderBy from "lodash/orderBy";
import set from "lodash/set"; import set from "lodash/set";
import uniq from "lodash/uniq"; import uniq from "lodash/uniq";
import { runInAction } from "mobx";
import { ALL_ISSUES, EIssueFilterType, FILTER_TO_ISSUE_MAP, ISSUE_PRIORITIES } from "@plane/constants"; import { ALL_ISSUES, EIssueFilterType, FILTER_TO_ISSUE_MAP, ISSUE_PRIORITIES } from "@plane/constants";
import { import {
IIssueDisplayFilterOptions, IIssueDisplayFilterOptions,
@ -318,10 +317,22 @@ export const getGroupedWorkItemIds = (
}; };
} }
// Get the default key for the group by key
const getDefaultGroupKey = (groupByKey: TIssueGroupByOptions) => {
switch (groupByKey) {
case "state_detail.group":
return "state__group";
case null:
return null;
default:
return ISSUE_GROUP_BY_KEY[groupByKey];
}
};
// Group work items // Group work items
const groupKey = ISSUE_GROUP_BY_KEY[groupByKey]; const groupKey = getDefaultGroupKey(groupByKey);
const groupedWorkItems = groupBy(workItems, (item) => { const groupedWorkItems = groupBy(workItems, (item) => {
const value = item[groupKey]; const value = groupKey ? item[groupKey] : null;
if (Array.isArray(value)) { if (Array.isArray(value)) {
if (value.length === 0) return "None"; if (value.length === 0) return "None";
// Sort & join to build deterministic set-like key // Sort & join to build deterministic set-like key

View file

@ -121,7 +121,7 @@ export interface IBaseIssuesStore {
export const ISSUE_GROUP_BY_KEY: Record<TIssueDisplayFilterOptions, keyof TIssue> = { export const ISSUE_GROUP_BY_KEY: Record<TIssueDisplayFilterOptions, keyof TIssue> = {
project: "project_id", project: "project_id",
state: "state_id", state: "state_id",
"state_detail.group": "state__group" as keyof TIssue, // state_detail.group is only being used for state_group display, "state_detail.group": "state_id", // state_detail.group is only being used for state_group display,
priority: "priority", priority: "priority",
labels: "label_ids", labels: "label_ids",
created_by: "created_by", created_by: "created_by",
@ -137,7 +137,7 @@ export const ISSUE_FILTER_DEFAULT_DATA: Record<TIssueDisplayFilterOptions, keyof
cycle: "cycle_id", cycle: "cycle_id",
module: "module_ids", module: "module_ids",
state: "state_id", state: "state_id",
"state_detail.group": "state_group" as keyof TIssue, // state_detail.group is only being used for state_group display, "state_detail.group": "state__group", // state_detail.group is only being used for state_group display,
priority: "priority", priority: "priority",
labels: "label_ids", labels: "label_ids",
created_by: "created_by", created_by: "created_by",
@ -1594,11 +1594,11 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
// if unGrouped, then return the path as ALL_ISSUES along with orderByUpdates // if unGrouped, then return the path as ALL_ISSUES along with orderByUpdates
if (!this.issueGroupKey) return action ? [{ path: [ALL_ISSUES], action }, ...orderByUpdates] : orderByUpdates; if (!this.issueGroupKey) return action ? [{ path: [ALL_ISSUES], action }, ...orderByUpdates] : orderByUpdates;
const issueGroupKey = issue?.[this.issueGroupKey] as string | string[] | null | undefined; const issueGroupKeyValue = issue?.[this.issueGroupKey] as string | string[] | null | undefined;
const issueBeforeUpdateGroupKey = issueBeforeUpdate?.[this.issueGroupKey] as string | string[] | null | undefined; const issueBeforeUpdateGroupKey = issueBeforeUpdate?.[this.issueGroupKey] as string | string[] | null | undefined;
// if grouped, the get the Difference between the two issue properties (this.issueGroupKey) on which groupBy is performed // if grouped, the get the Difference between the two issue properties (this.issueGroupKey) on which groupBy is performed
const groupActionsArray = getDifference( const groupActionsArray = getDifference(
this.getArrayStringArray(issue, issueGroupKey, this.groupBy), this.getArrayStringArray(issue, issueGroupKeyValue, this.groupBy),
this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateGroupKey, this.groupBy), this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateGroupKey, this.groupBy),
action action
); );
@ -1632,7 +1632,7 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
groupActionsArray, groupActionsArray,
subGroupActionsArray, subGroupActionsArray,
this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateGroupKey, this.groupBy), this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateGroupKey, this.groupBy),
this.getArrayStringArray(issue, issueGroupKey, this.groupBy), this.getArrayStringArray(issue, issueGroupKeyValue, this.groupBy),
this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateSubGroupKey, this.subGroupBy), this.getArrayStringArray(issueBeforeUpdate, issueBeforeUpdateSubGroupKey, this.subGroupBy),
this.getArrayStringArray(issue, issueSubGroupKey, this.subGroupBy) this.getArrayStringArray(issue, issueSubGroupKey, this.subGroupBy)
), ),
@ -1690,12 +1690,13 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
return issueKeyActions; return issueKeyActions;
} }
/** // /**
* get the groupByKey issue property on which actions are to be decided in the form of array // * Normalizes group values into a consistent string array format
* @param value // * @param issueObject - The issue object to extract values from
* @param groupByKey // * @param value - The raw value (string, array, or null/undefined)
* @returns an array of issue property values // * @param groupByKey - The group by key to handle special cases
*/ // * @returns Normalized array of string values
// */
getArrayStringArray = ( getArrayStringArray = (
issueObject: Partial<TIssue> | undefined, issueObject: Partial<TIssue> | undefined,
value: string | string[] | undefined | null, value: string | string[] | undefined | null,
@ -1708,9 +1709,23 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
// if array return the array // if array return the array
if (Array.isArray(value)) return value; if (Array.isArray(value)) return value;
// if the groupKey is state group then return the group based on state_id return this.getDefaultGroupValue(issueObject, value, groupByKey);
};
// /**
// * Gets the default value for a group when the primary value is empty
// * @param issueObject - The issue object to extract fallback values from
// * @param groupByKey - The group by key to determine fallback logic
// * @returns Default group value as string array
// */
private getDefaultGroupValue = (
issueObject: Partial<TIssue>,
value: string,
groupByKey?: TIssueGroupByOptions
): string[] => {
// Handle special case for state group
if (groupByKey === "state_detail.group") { if (groupByKey === "state_detail.group") {
return [this.rootIssueStore.rootStore.state.stateMap?.[value]?.group]; return [this.rootIssueStore.rootStore.state.stateMap?.[value]?.group ?? issueObject.state__group];
} }
return [value]; return [value];