forked from github/plane
feat : sidebar progress improvement (#272)
* feat: progress chart render validation * fix: sidebar stats tab * feat: sidebar active tab context
This commit is contained in:
parent
ebf294af55
commit
8fb34fe1e3
@ -20,6 +20,7 @@ import User from "public/user.png";
|
|||||||
import { IIssue, IIssueLabels } from "types";
|
import { IIssue, IIssueLabels } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys";
|
||||||
|
import useLocalStorage from "hooks/use-local-storage";
|
||||||
// types
|
// types
|
||||||
type Props = {
|
type Props = {
|
||||||
groupedIssues: any;
|
groupedIssues: any;
|
||||||
@ -38,6 +39,7 @@ const stateGroupColours: {
|
|||||||
|
|
||||||
export const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues }) => {
|
export const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [tab, setTab] = useLocalStorage("tab", "Assignees");
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
const { data: issueLabels } = useSWR<IIssueLabels[]>(
|
const { data: issueLabels } = useSWR<IIssueLabels[]>(
|
||||||
workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null,
|
||||||
@ -52,8 +54,34 @@ export const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues })
|
|||||||
? () => projectService.projectMembers(workspaceSlug as string, projectId as string)
|
? () => projectService.projectMembers(workspaceSlug as string, projectId as string)
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentValue = (tab: string) => {
|
||||||
|
switch (tab) {
|
||||||
|
case "Assignees":
|
||||||
|
return 0;
|
||||||
|
case "Labels":
|
||||||
|
return 1;
|
||||||
|
case "States":
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Tab.Group>
|
<Tab.Group
|
||||||
|
defaultIndex={currentValue(tab)}
|
||||||
|
onChange={(i) => {
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
return setTab("Assignees");
|
||||||
|
case 1:
|
||||||
|
return setTab("Labels");
|
||||||
|
case 2:
|
||||||
|
return setTab("States");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return setTab("Assignees");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Tab.List
|
<Tab.List
|
||||||
as="div"
|
as="div"
|
||||||
className="flex items-center justify-between w-full rounded bg-gray-100 text-xs"
|
className="flex items-center justify-between w-full rounded bg-gray-100 text-xs"
|
||||||
|
@ -118,6 +118,8 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
|||||||
});
|
});
|
||||||
}, [module, reset]);
|
}, [module, reset]);
|
||||||
|
|
||||||
|
const isStartValid = new Date(`${module?.start_date}`) <= new Date();
|
||||||
|
const isEndValid = new Date(`${module?.target_date}`) >= new Date(`${module?.start_date}`);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ModuleLinkModal
|
<ModuleLinkModal
|
||||||
@ -297,13 +299,20 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center w-full gap-2 ">
|
<div className="flex flex-col items-center justify-center w-full gap-2 ">
|
||||||
|
{isStartValid && isEndValid ? (
|
||||||
<ProgressChart
|
<ProgressChart
|
||||||
issues={issues}
|
issues={issues}
|
||||||
start={module?.start_date ?? ""}
|
start={module?.start_date ?? ""}
|
||||||
end={module?.target_date ?? ""}
|
end={module?.target_date ?? ""}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
{issues.length > 0 ? (
|
||||||
<SidebarProgressStats issues={issues} groupedIssues={groupedIssues} />
|
<SidebarProgressStats issues={issues} groupedIssues={groupedIssues} />
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
@ -101,6 +101,8 @@ const CycleDetailSidebar: React.FC<Props> = ({ issues, cycle, isOpen, cycleIssue
|
|||||||
});
|
});
|
||||||
}, [cycle, reset]);
|
}, [cycle, reset]);
|
||||||
|
|
||||||
|
const isStartValid = new Date(`${cycle?.start_date}`) <= new Date();
|
||||||
|
const isEndValid = new Date(`${cycle?.end_date}`) >= new Date(`${cycle?.start_date}`);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed top-0 ${
|
className={`fixed top-0 ${
|
||||||
@ -275,6 +277,7 @@ const CycleDetailSidebar: React.FC<Props> = ({ issues, cycle, isOpen, cycleIssue
|
|||||||
<div className="py-1" />
|
<div className="py-1" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center w-full gap-2 ">
|
<div className="flex flex-col items-center justify-center w-full gap-2 ">
|
||||||
|
{isStartValid && isEndValid ? (
|
||||||
<div className="relative h-[200px] w-full ">
|
<div className="relative h-[200px] w-full ">
|
||||||
<ProgressChart
|
<ProgressChart
|
||||||
issues={issues}
|
issues={issues}
|
||||||
@ -282,7 +285,14 @@ const CycleDetailSidebar: React.FC<Props> = ({ issues, cycle, isOpen, cycleIssue
|
|||||||
end={cycle?.end_date ?? ""}
|
end={cycle?.end_date ?? ""}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
{issues.length > 0 ? (
|
||||||
<SidebarProgressStats issues={issues} groupedIssues={groupedIssues} />
|
<SidebarProgressStats issues={issues} groupedIssues={groupedIssues} />
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
22
apps/app/hooks/use-local-storage.tsx
Normal file
22
apps/app/hooks/use-local-storage.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const getSavedValue = (key: any, value: any) => {
|
||||||
|
const savedValue = localStorage.getItem(key);
|
||||||
|
if (savedValue) {
|
||||||
|
return savedValue;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useLocalStorage = (key: any, value: any) => {
|
||||||
|
const [updatedvalue, seUpdatedvalue] = useState(() => getSavedValue(key, value));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem(key, updatedvalue);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [updatedvalue]);
|
||||||
|
|
||||||
|
return [updatedvalue, seUpdatedvalue];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useLocalStorage;
|
Loading…
Reference in New Issue
Block a user