From 43c75f4457d3dd8fe7756aeeccd493f091cbf228 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Thu, 14 Mar 2024 12:43:29 +0530 Subject: [PATCH 1/6] fix: rendering Issue in kanban swimlanes view for unassigned cycle or Modules (#3965) --- web/store/issue/helpers/issue-helper.store.ts | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/web/store/issue/helpers/issue-helper.store.ts b/web/store/issue/helpers/issue-helper.store.ts index a267ac9c8..563fe9bb5 100644 --- a/web/store/issue/helpers/issue-helper.store.ts +++ b/web/store/issue/helpers/issue-helper.store.ts @@ -1,16 +1,17 @@ -import orderBy from "lodash/orderBy"; import get from "lodash/get"; import indexOf from "lodash/indexOf"; import isEmpty from "lodash/isEmpty"; +import orderBy from "lodash/orderBy"; import values from "lodash/values"; -// types -import { TIssue, TIssueMap, TIssueGroupByOptions, TIssueOrderByOptions } from "@plane/types"; -import { IIssueRootStore } from "../root.store"; // constants import { ISSUE_PRIORITIES } from "constants/issue"; import { STATE_GROUPS } from "constants/state"; // helpers import { renderFormattedPayloadDate } from "helpers/date-time.helper"; +// types +import { TIssue, TIssueMap, TIssueGroupByOptions, TIssueOrderByOptions } from "@plane/types"; +// store +import { IIssueRootStore } from "../root.store"; export type TIssueDisplayFilterOptions = Exclude | "target_date"; @@ -62,35 +63,35 @@ export class IssueHelperStore implements TIssueHelperStore { issues: TIssueMap, isCalendarIssues: boolean = false ) => { - const _issues: { [group_id: string]: string[] } = {}; - if (!groupBy) return _issues; + const currentIssues: { [group_id: string]: string[] } = {}; + if (!groupBy) return currentIssues; this.issueDisplayFiltersDefaultData(groupBy).forEach((group) => { - _issues[group] = []; + currentIssues[group] = []; }); const projectIssues = this.issuesSortWithOrderBy(issues, orderBy); for (const issue in projectIssues) { - const _issue = projectIssues[issue]; + const currentIssue = projectIssues[issue]; let groupArray = []; if (groupBy === "state_detail.group") { - const state_group = - this.rootStore?.stateDetails?.find((_state) => _state.id === _issue?.state_id)?.group || "None"; + // if groupBy state_detail.group is coming from the project level the we are using stateDetails from root store else we are looping through the stateMap + const state_group = (this.rootStore?.stateMap || {})?.[currentIssue?.state_id]?.group || "None"; groupArray = [state_group]; } else { - const groupValue = get(_issue, ISSUE_FILTER_DEFAULT_DATA[groupBy]); - groupArray = groupValue !== undefined ? this.getGroupArray(groupValue, isCalendarIssues) : []; + const groupValue = get(currentIssue, ISSUE_FILTER_DEFAULT_DATA[groupBy]); + groupArray = groupValue !== undefined ? this.getGroupArray(groupValue, isCalendarIssues) : ["None"]; } for (const group of groupArray) { - if (group && _issues[group]) _issues[group].push(_issue.id); - else if (group) _issues[group] = [_issue.id]; + if (group && currentIssues[group]) currentIssues[group].push(currentIssue.id); + else if (group) currentIssues[group] = [currentIssue.id]; } } - return _issues; + return currentIssues; }; subGroupedIssues = ( @@ -99,45 +100,47 @@ export class IssueHelperStore implements TIssueHelperStore { orderBy: TIssueOrderByOptions, issues: TIssueMap ) => { - const _issues: { [sub_group_id: string]: { [group_id: string]: string[] } } = {}; - if (!subGroupBy || !groupBy) return _issues; + const currentIssues: { [sub_group_id: string]: { [group_id: string]: string[] } } = {}; + if (!subGroupBy || !groupBy) return currentIssues; - this.issueDisplayFiltersDefaultData(subGroupBy).forEach((sub_group: any) => { + this.issueDisplayFiltersDefaultData(subGroupBy).forEach((sub_group) => { const groupByIssues: { [group_id: string]: string[] } = {}; this.issueDisplayFiltersDefaultData(groupBy).forEach((group) => { groupByIssues[group] = []; }); - _issues[sub_group] = groupByIssues; + currentIssues[sub_group] = groupByIssues; }); const projectIssues = this.issuesSortWithOrderBy(issues, orderBy); for (const issue in projectIssues) { - const _issue = projectIssues[issue]; + const currentIssue = projectIssues[issue]; let subGroupArray = []; let groupArray = []; if (subGroupBy === "state_detail.group" || groupBy === "state_detail.group") { - const state_group = - this.rootStore?.stateDetails?.find((_state) => _state.id === _issue?.state_id)?.group || "None"; + const state_group = (this.rootStore?.stateMap || {})?.[currentIssue?.state_id]?.group || "None"; + subGroupArray = [state_group]; groupArray = [state_group]; } else { - const subGroupValue = get(_issue, ISSUE_FILTER_DEFAULT_DATA[subGroupBy]); - const groupValue = get(_issue, ISSUE_FILTER_DEFAULT_DATA[groupBy]); - subGroupArray = subGroupValue != undefined ? this.getGroupArray(subGroupValue) : []; - groupArray = groupValue != undefined ? this.getGroupArray(groupValue) : []; + const subGroupValue = get(currentIssue, ISSUE_FILTER_DEFAULT_DATA[subGroupBy]); + const groupValue = get(currentIssue, ISSUE_FILTER_DEFAULT_DATA[groupBy]); + + subGroupArray = subGroupValue != undefined ? this.getGroupArray(subGroupValue) : ["None"]; + groupArray = groupValue != undefined ? this.getGroupArray(groupValue) : ["None"]; } for (const subGroup of subGroupArray) { for (const group of groupArray) { - if (subGroup && group && _issues?.[subGroup]?.[group]) _issues[subGroup][group].push(_issue.id); - else if (subGroup && group && _issues[subGroup]) _issues[subGroup][group] = [_issue.id]; - else if (subGroup && group) _issues[subGroup] = { [group]: [_issue.id] }; + if (subGroup && group && currentIssues?.[subGroup]?.[group]) + currentIssues[subGroup][group].push(currentIssue.id); + else if (subGroup && group && currentIssues[subGroup]) currentIssues[subGroup][group] = [currentIssue.id]; + else if (subGroup && group) currentIssues[subGroup] = { [group]: [currentIssue.id] }; } } } - return _issues; + return currentIssues; }; unGroupedIssues = (orderBy: TIssueOrderByOptions, issues: TIssueMap) => @@ -215,8 +218,8 @@ export class IssueHelperStore implements TIssueHelperStore { const moduleMap = this.rootStore?.moduleMap; if (!moduleMap) break; for (const dataId of dataIdsArray) { - const _module = moduleMap[dataId]; - if (_module && _module.name) dataValues.push(_module.name.toLocaleLowerCase()); + const currentModule = moduleMap[dataId]; + if (currentModule && currentModule.name) dataValues.push(currentModule.name.toLocaleLowerCase()); } break; case "cycle_id": @@ -233,10 +236,10 @@ export class IssueHelperStore implements TIssueHelperStore { } /** - * This Method is mainly used to filter out empty values in the begining + * This Method is mainly used to filter out empty values in the beginning * @param key key of the value that is to be checked if empty * @param object any object in which the key's value is to be checked - * @returns 1 if emoty, 0 if not empty + * @returns 1 if empty, 0 if not empty */ getSortOrderToFilterEmptyValues(key: string, object: any) { const value = object?.[key]; @@ -388,7 +391,7 @@ export class IssueHelperStore implements TIssueHelperStore { getGroupArray(value: boolean | number | string | string[] | null, isDate: boolean = false): string[] { if (!value || value === null || value === undefined) return ["None"]; if (Array.isArray(value)) - if (value.length) return value; + if (value && value.length) return value; else return ["None"]; else if (typeof value === "boolean") return [value ? "True" : "False"]; else if (typeof value === "number") return [value.toString()]; From 0bc4b6cece3c66d6376ea0951ab17b46caffe81e Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:16:07 +0530 Subject: [PATCH 2/6] chore: ai modal disclamier added (#3970) --- .../core/modals/gpt-assistant-popover.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/web/components/core/modals/gpt-assistant-popover.tsx b/web/components/core/modals/gpt-assistant-popover.tsx index 590015e12..deffd883a 100644 --- a/web/components/core/modals/gpt-assistant-popover.tsx +++ b/web/components/core/modals/gpt-assistant-popover.tsx @@ -7,6 +7,8 @@ import useToast from "hooks/use-toast"; import { usePopper } from "react-popper"; // ui import { Button, Input } from "@plane/ui"; +// icons +import { AlertCircle } from "lucide-react"; // components import { RichReadOnlyEditorWithRef } from "@plane/rich-text-editor"; import { Popover, Transition } from "@headlessui/react"; @@ -250,8 +252,17 @@ export const GptAssistantPopover: React.FC = (props) => { /> )} /> -
- {responseActionButton} +
+ {responseActionButton ? ( + <>{responseActionButton} + ) : ( + <> +
+ +

By using this feature, you consent to sharing the message with a 3rd party service.

+
+ + )}