fix: issue with cycle and module sidebar filter implementation. (#3142)

This commit is contained in:
Prateek Shourya 2023-12-17 00:34:42 +05:30 committed by GitHub
parent d473ba9d0d
commit 3d83101f69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 29 deletions

View File

@ -14,6 +14,7 @@ import { SingleProgressStats } from "components/core";
import { Avatar, StateGroupIcon } from "@plane/ui"; import { Avatar, StateGroupIcon } from "@plane/ui";
// types // types
import { import {
IIssueFilterOptions,
IModule, IModule,
TAssigneesDistribution, TAssigneesDistribution,
TCompletionChartDistribution, TCompletionChartDistribution,
@ -35,6 +36,9 @@ type Props = {
roundedTab?: boolean; roundedTab?: boolean;
noBackground?: boolean; noBackground?: boolean;
isPeekView?: boolean; isPeekView?: boolean;
isCompleted?: boolean;
filters?: IIssueFilterOptions;
handleFiltersUpdate: (key: keyof IIssueFilterOptions, value: string | string[]) => void;
}; };
export const SidebarProgressStats: React.FC<Props> = ({ export const SidebarProgressStats: React.FC<Props> = ({
@ -44,7 +48,10 @@ export const SidebarProgressStats: React.FC<Props> = ({
module, module,
roundedTab, roundedTab,
noBackground, noBackground,
isCompleted = false,
isPeekView = false, isPeekView = false,
filters,
handleFiltersUpdate,
}) => { }) => {
const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees"); const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees");
@ -140,20 +147,11 @@ export const SidebarProgressStats: React.FC<Props> = ({
} }
completed={assignee.completed_issues} completed={assignee.completed_issues}
total={assignee.total_issues} total={assignee.total_issues}
{...(!isPeekView && { {...(!isPeekView &&
onClick: () => { !isCompleted && {
// TODO: set filters here onClick: () => handleFiltersUpdate("assignees", assignee.assignee_id ?? ""),
// if (filters?.assignees?.includes(assignee.assignee_id ?? "")) selected: filters?.assignees?.includes(assignee.assignee_id ?? ""),
// setFilters({ })}
// assignees: filters?.assignees?.filter((a) => a !== assignee.assignee_id),
// });
// else
// setFilters({
// assignees: [...(filters?.assignees ?? []), assignee.assignee_id ?? ""],
// });
},
// selected: filters?.assignees?.includes(assignee.assignee_id ?? ""),
})}
/> />
); );
else else
@ -200,17 +198,11 @@ export const SidebarProgressStats: React.FC<Props> = ({
} }
completed={label.completed_issues} completed={label.completed_issues}
total={label.total_issues} total={label.total_issues}
{...(!isPeekView && { {...(!isPeekView &&
// TODO: set filters here !isCompleted && {
onClick: () => { onClick: () => handleFiltersUpdate("labels", label.label_id ?? ""),
// if (filters.labels?.includes(label.label_id ?? "")) selected: filters?.labels?.includes(label.label_id ?? `no-label-${index}`),
// setFilters({ })}
// labels: filters?.labels?.filter((l) => l !== label.label_id),
// });
// else setFilters({ labels: [...(filters?.labels ?? []), label.label_id ?? ""] });
},
// selected: filters?.labels?.includes(label.label_id ?? ""),
})}
/> />
)) ))
) : ( ) : (

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@ -29,7 +29,8 @@ import {
renderShortMonthDate, renderShortMonthDate,
} from "helpers/date-time.helper"; } from "helpers/date-time.helper";
// types // types
import { ICycle } from "types"; import { ICycle, IIssueFilterOptions } from "types";
import { EFilterType } from "store/issues/types";
// constants // constants
import { EUserWorkspaceRoles } from "constants/workspace"; import { EUserWorkspaceRoles } from "constants/workspace";
// fetch-keys // fetch-keys
@ -54,6 +55,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
const { const {
cycle: cycleDetailsStore, cycle: cycleDetailsStore,
cycleIssuesFilter: { issueFilters, updateFilters },
trackEvent: { setTrackElement }, trackEvent: { setTrackElement },
user: { currentProjectRole }, user: { currentProjectRole },
} = useMobxStore(); } = useMobxStore();
@ -245,6 +247,25 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
} }
}; };
const handleFiltersUpdate = useCallback(
(key: keyof IIssueFilterOptions, value: string | string[]) => {
if (!workspaceSlug || !projectId) return;
const newValues = issueFilters?.filters?.[key] ?? [];
if (Array.isArray(value)) {
value.forEach((val) => {
if (!newValues.includes(val)) newValues.push(val);
});
} else {
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
else newValues.push(value);
}
updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.FILTERS, { [key]: newValues }, cycleId);
},
[workspaceSlug, projectId, cycleId, issueFilters, updateFilters]
);
const cycleStatus = const cycleStatus =
cycleDetails?.start_date && cycleDetails?.end_date cycleDetails?.start_date && cycleDetails?.end_date
? getDateRangeStatus(cycleDetails?.start_date, cycleDetails?.end_date) ? getDateRangeStatus(cycleDetails?.start_date, cycleDetails?.end_date)
@ -538,6 +559,9 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
}} }}
totalIssues={cycleDetails.total_issues} totalIssues={cycleDetails.total_issues}
isPeekView={Boolean(peekCycle)} isPeekView={Boolean(peekCycle)}
isCompleted={isCompleted}
filters={issueFilters?.filters}
handleFiltersUpdate={handleFiltersUpdate}
/> />
</div> </div>
)} )}

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
@ -25,7 +25,8 @@ import {
} from "helpers/date-time.helper"; } from "helpers/date-time.helper";
import { copyUrlToClipboard } from "helpers/string.helper"; import { copyUrlToClipboard } from "helpers/string.helper";
// types // types
import { ILinkDetails, IModule, ModuleLink } from "types"; import { IIssueFilterOptions, ILinkDetails, IModule, ModuleLink } from "types";
import { EFilterType } from "store/issues/types";
// constant // constant
import { MODULE_STATUS } from "constants/module"; import { MODULE_STATUS } from "constants/module";
import { EUserWorkspaceRoles } from "constants/workspace"; import { EUserWorkspaceRoles } from "constants/workspace";
@ -62,6 +63,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
updateModuleLink, updateModuleLink,
deleteModuleLink, deleteModuleLink,
}, },
moduleIssuesFilter: { issueFilters, updateFilters },
user: userStore, user: userStore,
} = useMobxStore(); } = useMobxStore();
@ -211,6 +213,25 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
} }
}; };
const handleFiltersUpdate = useCallback(
(key: keyof IIssueFilterOptions, value: string | string[]) => {
if (!workspaceSlug || !projectId) return;
const newValues = issueFilters?.filters?.[key] ?? [];
if (Array.isArray(value)) {
value.forEach((val) => {
if (!newValues.includes(val)) newValues.push(val);
});
} else {
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
else newValues.push(value);
}
updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.FILTERS, { [key]: newValues }, moduleId);
},
[workspaceSlug, projectId, moduleId, issueFilters, updateFilters]
);
useEffect(() => { useEffect(() => {
if (moduleDetails) if (moduleDetails)
reset({ reset({
@ -544,6 +565,8 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
totalIssues={moduleDetails.total_issues} totalIssues={moduleDetails.total_issues}
module={moduleDetails} module={moduleDetails}
isPeekView={Boolean(peekModule)} isPeekView={Boolean(peekModule)}
filters={issueFilters?.filters}
handleFiltersUpdate={handleFiltersUpdate}
/> />
</div> </div>
)} )}