[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,42 +165,48 @@ 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"> <Disclosure.Button
<Disclosure.Button 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 ? (
</Disclosure.Button> <ChevronDown className="h-3.5 w-3.5" />
{isAuthorizedUser && ( ) : (
<button <ChevronRight className="h-3.5 w-3.5" />
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setTrackElement("APP_SIDEBAR_FAVORITES_BLOCK");
setIsFavoriteProjectCreate(true);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
)} )}
</div> </Disclosure.Button>
)} {isAuthorizedUser && (
<Transition <button
enter="transition duration-100 ease-out" className="opacity-0 group-hover:opacity-100"
enterFrom="transform scale-95 opacity-0" onClick={() => {
enterTo="transform scale-100 opacity-100" setTrackElement("APP_SIDEBAR_FAVORITES_BLOCK");
leave="transition duration-75 ease-out" setIsFavoriteProjectCreate(true);
leaveFrom="transform scale-100 opacity-100" setIsProjectModalOpen(true);
leaveTo="transform scale-95 opacity-0" }}
> >
<Disclosure.Panel as="div" className="space-y-2"> <Plus className="h-3 w-3" />
</button>
)}
</div>
)}
<Transition
show={isFavoriteProjectsListOpen}
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
{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,50 +219,56 @@ 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"> <Disclosure.Button
<Disclosure.Button 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 ? (
</Disclosure.Button> <ChevronDown className="h-3.5 w-3.5" />
{isAuthorizedUser && ( ) : (
<button <ChevronRight className="h-3.5 w-3.5" />
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setTrackElement("Sidebar");
setIsFavoriteProjectCreate(false);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
)} )}
</div> </Disclosure.Button>
)} {isAuthorizedUser && (
<Transition <button
enter="transition duration-100 ease-out" className="opacity-0 group-hover:opacity-100"
enterFrom="transform scale-95 opacity-0" onClick={() => {
enterTo="transform scale-100 opacity-100" setTrackElement("Sidebar");
leave="transition duration-75 ease-out" setIsFavoriteProjectCreate(false);
leaveFrom="transform scale-100 opacity-100" setIsProjectModalOpen(true);
leaveTo="transform scale-95 opacity-0" }}
> >
<Disclosure.Panel as="div"> <Plus className="h-3 w-3" />
</button>
)}
</div>
)}
<Transition
show={isAllProjectsListOpen}
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
{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>