forked from github/plane
chore: cycle and module sidebar state filter implementation (#4522)
This commit is contained in:
parent
8730049c00
commit
44f743d52c
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
// headless ui
|
// headless ui
|
||||||
import { Tab } from "@headlessui/react";
|
import { Tab } from "@headlessui/react";
|
||||||
@ -15,6 +15,7 @@ import {
|
|||||||
// hooks
|
// hooks
|
||||||
import { Avatar, StateGroupIcon } from "@plane/ui";
|
import { Avatar, StateGroupIcon } from "@plane/ui";
|
||||||
import { SingleProgressStats } from "@/components/core";
|
import { SingleProgressStats } from "@/components/core";
|
||||||
|
import { useProjectState } from "@/hooks/store";
|
||||||
import useLocalStorage from "@/hooks/use-local-storage";
|
import useLocalStorage from "@/hooks/use-local-storage";
|
||||||
// images
|
// images
|
||||||
import emptyLabel from "public/empty-state/empty_label.svg";
|
import emptyLabel from "public/empty-state/empty_label.svg";
|
||||||
@ -44,7 +45,8 @@ type Props = {
|
|||||||
handleFiltersUpdate: (key: keyof IIssueFilterOptions, value: string | string[]) => void;
|
handleFiltersUpdate: (key: keyof IIssueFilterOptions, value: string | string[]) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SidebarProgressStats: React.FC<Props> = ({
|
export const SidebarProgressStats: React.FC<Props> = observer((props) => {
|
||||||
|
const {
|
||||||
distribution,
|
distribution,
|
||||||
groupedIssues,
|
groupedIssues,
|
||||||
totalIssues,
|
totalIssues,
|
||||||
@ -55,9 +57,11 @@ export const SidebarProgressStats: React.FC<Props> = ({
|
|||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
filters,
|
filters,
|
||||||
handleFiltersUpdate,
|
handleFiltersUpdate,
|
||||||
}) => {
|
} = props;
|
||||||
const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees");
|
const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees");
|
||||||
|
|
||||||
|
const { groupedProjectStates } = useProjectState();
|
||||||
|
|
||||||
const currentValue = (tab: string | null) => {
|
const currentValue = (tab: string | null) => {
|
||||||
switch (tab) {
|
switch (tab) {
|
||||||
case "Assignees":
|
case "Assignees":
|
||||||
@ -71,6 +75,12 @@ export const SidebarProgressStats: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStateGroupState = (stateGroup: string) => {
|
||||||
|
const stateGroupStates = groupedProjectStates?.[stateGroup];
|
||||||
|
const stateGroupStatesId = stateGroupStates?.map((state) => state.id);
|
||||||
|
return stateGroupStatesId;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tab.Group
|
<Tab.Group
|
||||||
defaultIndex={currentValue(tab)}
|
defaultIndex={currentValue(tab)}
|
||||||
@ -261,10 +271,14 @@ export const SidebarProgressStats: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
completed={groupedIssues[group]}
|
completed={groupedIssues[group]}
|
||||||
total={totalIssues}
|
total={totalIssues}
|
||||||
|
{...(!isPeekView &&
|
||||||
|
!isCompleted && {
|
||||||
|
onClick: () => handleFiltersUpdate("state", getStateGroupState(group) ?? []),
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tab.Panel>
|
</Tab.Panel>
|
||||||
</Tab.Panels>
|
</Tab.Panels>
|
||||||
</Tab.Group>
|
</Tab.Group>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import isEmpty from "lodash/isEmpty";
|
import isEmpty from "lodash/isEmpty";
|
||||||
|
import isEqual from "lodash/isEqual";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
@ -199,14 +200,18 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
let newValues = issueFilters?.filters?.[key] ?? [];
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
if (key === "state") {
|
||||||
|
if (isEqual(newValues, value)) newValues = [];
|
||||||
|
else newValues = value;
|
||||||
|
} else {
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
if (!newValues.includes(val)) newValues.push(val);
|
if (!newValues.includes(val)) newValues.push(val);
|
||||||
else newValues.splice(newValues.indexOf(val), 1);
|
else newValues.splice(newValues.indexOf(val), 1);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
import isEqual from "lodash/isEqual";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
@ -252,14 +253,18 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
let newValues = issueFilters?.filters?.[key] ?? [];
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
if (key === "state") {
|
||||||
|
if (isEqual(newValues, value)) newValues = [];
|
||||||
|
else newValues = value;
|
||||||
|
} else {
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
if (!newValues.includes(val)) newValues.push(val);
|
if (!newValues.includes(val)) newValues.push(val);
|
||||||
else newValues.splice(newValues.indexOf(val), 1);
|
else newValues.splice(newValues.indexOf(val), 1);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
|
Loading…
Reference in New Issue
Block a user