[WEB-1459] chore: save users all / favorite project list collapse state into localstorage. (#4701)

This commit is contained in:
Prateek Shourya 2024-06-05 12:47:16 +05:30 committed by GitHub
parent 8c5f693214
commit 453459d271
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,22 +5,30 @@ import { observer } from "mobx-react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { ChevronDown, ChevronRight, Plus } from "lucide-react"; import { ChevronDown, ChevronRight, Plus } from "lucide-react";
import { Disclosure, Transition } from "@headlessui/react"; import { Disclosure, Transition } from "@headlessui/react";
// types
import { IProject } from "@plane/types"; import { IProject } from "@plane/types";
// hooks // ui
import { TOAST_TYPE, setToast } from "@plane/ui"; import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { CreateProjectModal, ProjectSidebarListItem } from "@/components/project"; import { CreateProjectModal, ProjectSidebarListItem } from "@/components/project";
// constants
import { EUserWorkspaceRoles } from "@/constants/workspace"; import { EUserWorkspaceRoles } from "@/constants/workspace";
// helpers
import { cn } from "@/helpers/common.helper"; import { cn } from "@/helpers/common.helper";
import { orderJoinedProjects } from "@/helpers/project.helper"; import { orderJoinedProjects } from "@/helpers/project.helper";
import { copyUrlToClipboard } from "@/helpers/string.helper"; import { copyUrlToClipboard } from "@/helpers/string.helper";
// hooks
import { useAppTheme, useCommandPalette, useEventTracker, useProject, useUser } from "@/hooks/store"; import { useAppTheme, useCommandPalette, useEventTracker, useProject, useUser } from "@/hooks/store";
// ui
// components
// helpers
// constants
export const ProjectSidebarList: FC = observer(() => { export const ProjectSidebarList: FC = observer(() => {
// get local storage data for isFavoriteProjectsListOpen and isAllProjectsListOpen
const isFavProjectsListOpenInLocalStorage = localStorage.getItem("isFavoriteProjectsListOpen");
const isAllProjectsListOpenInLocalStorage = localStorage.getItem("isAllProjectsListOpen");
// states // states
const [isFavoriteProjectsListOpen, setIsFavoriteProjectsListOpen] = useState(
isFavProjectsListOpenInLocalStorage === "true"
);
const [isAllProjectsListOpen, setIsAllProjectsListOpen] = useState(isAllProjectsListOpenInLocalStorage === "true");
const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false); const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false);
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false); const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false); // scroll animation state const [isScrolled, setIsScrolled] = useState(false); // scroll animation state
@ -122,6 +130,16 @@ export const ProjectSidebarList: FC = observer(() => {
); );
}, [containerRef]); }, [containerRef]);
const toggleListDisclosure = (isOpen: boolean, type: "all" | "favorite") => {
if (type === "all") {
setIsAllProjectsListOpen(isOpen);
localStorage.setItem("isAllProjectsListOpen", isOpen.toString());
} else {
setIsFavoriteProjectsListOpen(isOpen);
localStorage.setItem("isFavoriteProjectsListOpen", isOpen.toString());
}
};
return ( return (
<> <>
{workspaceSlug && ( {workspaceSlug && (
@ -147,8 +165,7 @@ export const ProjectSidebarList: FC = observer(() => {
> >
<div> <div>
{favoriteProjects && favoriteProjects.length > 0 && ( {favoriteProjects && favoriteProjects.length > 0 && (
<Disclosure as="div" className="flex flex-col" defaultOpen> <Disclosure as="div" className="flex flex-col" defaultOpen={isFavoriteProjectCreate}>
{({ open }) => (
<> <>
{!isCollapsed && ( {!isCollapsed && (
<div className="group flex w-full items-center justify-between rounded p-1.5 text-xs text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80"> <div className="group flex w-full items-center justify-between rounded p-1.5 text-xs text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80">
@ -156,9 +173,14 @@ export const ProjectSidebarList: FC = observer(() => {
as="button" as="button"
type="button" type="button"
className="group flex w-full items-center gap-1 whitespace-nowrap rounded px-1.5 text-left text-sm font-semibold text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80" className="group flex w-full items-center gap-1 whitespace-nowrap rounded px-1.5 text-left text-sm font-semibold text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80"
onClick={() => toggleListDisclosure(!isFavoriteProjectsListOpen, "favorite")}
> >
Favorites Favorites
{open ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />} {isFavoriteProjectsListOpen ? (
<ChevronDown className="h-3.5 w-3.5" />
) : (
<ChevronRight className="h-3.5 w-3.5" />
)}
</Disclosure.Button> </Disclosure.Button>
{isAuthorizedUser && ( {isAuthorizedUser && (
<button <button
@ -175,6 +197,7 @@ export const ProjectSidebarList: FC = observer(() => {
</div> </div>
)} )}
<Transition <Transition
show={isFavoriteProjectsListOpen}
enter="transition duration-100 ease-out" enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0" enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100" enterTo="transform scale-100 opacity-100"
@ -182,7 +205,8 @@ export const ProjectSidebarList: FC = observer(() => {
leaveFrom="transform scale-100 opacity-100" leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0" leaveTo="transform scale-95 opacity-0"
> >
<Disclosure.Panel as="div" className="space-y-2"> {isFavoriteProjectsListOpen && (
<Disclosure.Panel as="div" className={`space-y-2`} static>
{favoriteProjects.map((projectId, index) => ( {favoriteProjects.map((projectId, index) => (
<ProjectSidebarListItem <ProjectSidebarListItem
key={projectId} key={projectId}
@ -195,16 +219,15 @@ export const ProjectSidebarList: FC = observer(() => {
/> />
))} ))}
</Disclosure.Panel> </Disclosure.Panel>
)}
</Transition> </Transition>
</> </>
)}
</Disclosure> </Disclosure>
)} )}
</div> </div>
<div> <div>
{joinedProjects && joinedProjects.length > 0 && ( {joinedProjects && joinedProjects.length > 0 && (
<Disclosure as="div" className="flex flex-col" defaultOpen> <Disclosure as="div" className="flex flex-col" defaultOpen={isAllProjectsListOpen}>
{({ open }) => (
<> <>
{!isCollapsed && ( {!isCollapsed && (
<div className="group flex w-full items-center justify-between rounded p-1.5 text-xs text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80"> <div className="group flex w-full items-center justify-between rounded p-1.5 text-xs text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80">
@ -212,9 +235,14 @@ export const ProjectSidebarList: FC = observer(() => {
as="button" as="button"
type="button" type="button"
className="group flex w-full items-center gap-1 whitespace-nowrap rounded px-1.5 text-left text-sm font-semibold text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80" className="group flex w-full items-center gap-1 whitespace-nowrap rounded px-1.5 text-left text-sm font-semibold text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80"
onClick={() => toggleListDisclosure(!isAllProjectsListOpen, "all")}
> >
Your projects Your projects
{open ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />} {isAllProjectsListOpen ? (
<ChevronDown className="h-3.5 w-3.5" />
) : (
<ChevronRight className="h-3.5 w-3.5" />
)}
</Disclosure.Button> </Disclosure.Button>
{isAuthorizedUser && ( {isAuthorizedUser && (
<button <button
@ -231,6 +259,7 @@ export const ProjectSidebarList: FC = observer(() => {
</div> </div>
)} )}
<Transition <Transition
show={isAllProjectsListOpen}
enter="transition duration-100 ease-out" enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0" enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100" enterTo="transform scale-100 opacity-100"
@ -238,7 +267,8 @@ export const ProjectSidebarList: FC = observer(() => {
leaveFrom="transform scale-100 opacity-100" leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0" leaveTo="transform scale-95 opacity-0"
> >
<Disclosure.Panel as="div"> {isAllProjectsListOpen && (
<Disclosure.Panel as="div" static>
{joinedProjects.map((projectId, index) => ( {joinedProjects.map((projectId, index) => (
<ProjectSidebarListItem <ProjectSidebarListItem
key={projectId} key={projectId}
@ -250,9 +280,9 @@ export const ProjectSidebarList: FC = observer(() => {
/> />
))} ))}
</Disclosure.Panel> </Disclosure.Panel>
)}
</Transition> </Transition>
</> </>
)}
</Disclosure> </Disclosure>
)} )}
</div> </div>