From 06f60049931701b0a219075a3c03c45c74bb5128 Mon Sep 17 00:00:00 2001 From: Scott Wilson <scottraywilson@gmail.com> Date: Wed, 27 Nov 2024 15:37:17 -0800 Subject: [PATCH 1/5] improvement: refactor sidebar project select to support filtering with UI adjustments --- .../v2/FilterableSelect/FilterableSelect.tsx | 8 +- frontend/src/layouts/AppLayout/AppLayout.tsx | 182 +-------------- .../ProjectSelect/ProjectSelect.tsx | 214 ++++++++++++++++++ .../components/ProjectSelect/index.ts | 1 + 4 files changed, 228 insertions(+), 177 deletions(-) create mode 100644 frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx create mode 100644 frontend/src/layouts/AppLayout/components/ProjectSelect/index.ts diff --git a/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx b/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx index 450b58aef..0f1fd61e5 100644 --- a/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx +++ b/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx @@ -32,7 +32,13 @@ export const FilterableSelect = <T,>({ }) }} tabSelectsValue={tabSelectsValue} - components={{ DropdownIndicator, ClearIndicator, MultiValueRemove, Option }} + components={{ + DropdownIndicator, + ClearIndicator, + MultiValueRemove, + Option, + ...props.components + }} classNames={{ container: () => "w-full font-inter", control: ({ isFocused }) => diff --git a/frontend/src/layouts/AppLayout/AppLayout.tsx b/frontend/src/layouts/AppLayout/AppLayout.tsx index 2d12b3eda..8c4f8e1c8 100644 --- a/frontend/src/layouts/AppLayout/AppLayout.tsx +++ b/frontend/src/layouts/AppLayout/AppLayout.tsx @@ -10,7 +10,6 @@ import { useTranslation } from "react-i18next"; import Link from "next/link"; import { useRouter } from "next/router"; import { faGithub, faSlack } from "@fortawesome/free-brands-svg-icons"; -import { faStar } from "@fortawesome/free-regular-svg-icons"; import { faAngleDown, faArrowLeft, @@ -22,15 +21,11 @@ import { faInfo, faMobile, faPlus, - faQuestion, - faStar as faSolidStar + faQuestion } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; -import { twMerge } from "tailwind-merge"; -import { createNotification } from "@app/components/notifications"; -import { OrgPermissionCan } from "@app/components/permissions"; import { tempLocalStorage } from "@app/components/utilities/checks/tempLocalStorage"; import SecurityClient from "@app/components/utilities/SecurityClient"; import { @@ -39,20 +34,9 @@ import { DropdownMenuContent, DropdownMenuItem, Menu, - MenuItem, - Select, - SelectItem, - UpgradePlanModal + MenuItem } from "@app/components/v2"; -import { NewProjectModal } from "@app/components/v2/projects/NewProjectModal"; -import { - OrgPermissionActions, - OrgPermissionSubjects, - useOrganization, - useSubscription, - useUser, - useWorkspace -} from "@app/context"; +import { useOrganization, useSubscription, useUser, useWorkspace } from "@app/context"; import { usePopUp, useToggle } from "@app/hooks"; import { useGetAccessRequestsCount, @@ -62,11 +46,9 @@ import { useSelectOrganization } from "@app/hooks/api"; import { MfaMethod } from "@app/hooks/api/auth/types"; -import { Workspace } from "@app/hooks/api/types"; -import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation"; -import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries"; import { AuthMethod } from "@app/hooks/api/users/types"; import { InsecureConnectionBanner } from "@app/layouts/AppLayout/components/InsecureConnectionBanner"; +import { ProjectSelect } from "@app/layouts/AppLayout/components/ProjectSelect"; import { navigateUserToOrg } from "@app/views/Login/Login.utils"; import { Mfa } from "@app/views/Login/Mfa"; import { CreateOrgModal } from "@app/views/Org/components"; @@ -108,23 +90,10 @@ export const AppLayout = ({ children }: LayoutProps) => { const { workspaces, currentWorkspace } = useWorkspace(); const { orgs, currentOrg } = useOrganization(); - const { data: projectFavorites } = useGetUserProjectFavorites(currentOrg?.id!); - const { mutateAsync: updateUserProjectFavorites } = useUpdateUserProjectFavorites(); const [shouldShowMfa, toggleShowMfa] = useToggle(false); const [requiredMfaMethod, setRequiredMfaMethod] = useState(MfaMethod.EMAIL); const [mfaSuccessCallback, setMfaSuccessCallback] = useState<() => void>(() => {}); - const workspacesWithFaveProp = useMemo( - () => - workspaces - .map((w): Workspace & { isFavorite: boolean } => ({ - ...w, - isFavorite: Boolean(projectFavorites?.includes(w.id)) - })) - .sort((a, b) => Number(b.isFavorite) - Number(a.isFavorite)), - [workspaces, projectFavorites] - ); - const { user } = useUser(); const { subscription } = useSubscription(); const workspaceId = currentWorkspace?.id || ""; @@ -137,17 +106,9 @@ export const AppLayout = ({ children }: LayoutProps) => { return (secretApprovalReqCount?.open || 0) + (accessApprovalRequestCount?.pendingCount || 0); }, [secretApprovalReqCount, accessApprovalRequestCount]); - const isAddingProjectsAllowed = subscription?.workspaceLimit - ? subscription.workspacesUsed < subscription.workspaceLimit - : true; - const infisicalPlatformVersion = process.env.NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION; - const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ - "addNewWs", - "upgradePlan", - "createOrg" - ] as const); + const { popUp, handlePopUpToggle } = usePopUp(["createOrg"] as const); const { t } = useTranslation(); @@ -230,38 +191,6 @@ export const AppLayout = ({ children }: LayoutProps) => { putUserInOrg(); }, [router.query.id]); - const addProjectToFavorites = async (projectId: string) => { - try { - if (currentOrg?.id) { - await updateUserProjectFavorites({ - orgId: currentOrg?.id, - projectFavorites: [...(projectFavorites || []), projectId] - }); - } - } catch (err) { - createNotification({ - text: "Failed to add project to favorites.", - type: "error" - }); - } - }; - - const removeProjectFromFavorites = async (projectId: string) => { - try { - if (currentOrg?.id) { - await updateUserProjectFavorites({ - orgId: currentOrg?.id, - projectFavorites: [...(projectFavorites || []).filter((entry) => entry !== projectId)] - }); - } - } catch (err) { - createNotification({ - text: "Failed to remove project from favorites.", - type: "error" - }); - } - }; - if (shouldShowMfa) { return ( <div className="flex max-h-screen min-h-screen flex-col items-center justify-center gap-2 overflow-y-auto bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700"> @@ -448,97 +377,7 @@ export const AppLayout = ({ children }: LayoutProps) => { )} {!router.asPath.includes("org") && (!router.asPath.includes("personal") && currentWorkspace ? ( - <div className="mt-5 mb-4 w-full p-3"> - <p className="ml-1.5 mb-1 text-xs font-semibold uppercase text-gray-400"> - Project - </p> - <Select - defaultValue={currentWorkspace?.id} - value={currentWorkspace?.id} - className="w-full bg-mineshaft-600 py-2.5 font-medium [&>*:first-child]:truncate" - onValueChange={(value) => { - localStorage.setItem("projectData.id", value); - // this is not using react query because react query in overview is throwing error when envs are not exact same count - // to reproduce change this back to router.push and switch between two projects with different env count - // look into this on dashboard revamp - window.location.assign(`/project/${value}/secrets/overview`); - }} - position="popper" - dropdownContainerClassName="text-bunker-200 bg-mineshaft-800 border border-mineshaft-600 z-50 max-h-96 border-gray-700" - > - <div className="no-scrollbar::-webkit-scrollbar h-full no-scrollbar"> - {workspacesWithFaveProp - .filter((ws) => ws.orgId === currentOrg?.id) - .map(({ id, name, isFavorite }) => ( - <div - className={twMerge( - "mb-1 grid grid-cols-7 rounded-md hover:bg-mineshaft-500", - id === currentWorkspace?.id && "bg-mineshaft-500" - )} - key={id} - > - <div className="col-span-6"> - <SelectItem - key={`ws-layout-list-${id}`} - value={id} - className="transition-none data-[highlighted]:bg-mineshaft-500" - > - {name} - </SelectItem> - </div> - <div className="col-span-1 flex items-center"> - {isFavorite ? ( - <FontAwesomeIcon - icon={faSolidStar} - className="text-sm text-mineshaft-300 hover:text-mineshaft-400" - onClick={(e) => { - e.stopPropagation(); - removeProjectFromFavorites(id); - }} - /> - ) : ( - <FontAwesomeIcon - icon={faStar} - className="text-sm text-mineshaft-400 hover:text-mineshaft-300" - onClick={(e) => { - e.stopPropagation(); - addProjectToFavorites(id); - }} - /> - )} - </div> - </div> - ))} - </div> - <hr className="mt-1 mb-1 h-px border-0 bg-gray-700" /> - <div className="w-full"> - <OrgPermissionCan - I={OrgPermissionActions.Create} - a={OrgPermissionSubjects.Workspace} - > - {(isAllowed) => ( - <Button - className="w-full bg-mineshaft-700 py-2 text-bunker-200" - colorSchema="primary" - variant="outline_bg" - size="sm" - isDisabled={!isAllowed} - onClick={() => { - if (isAddingProjectsAllowed) { - handlePopUpOpen("addNewWs"); - } else { - handlePopUpOpen("upgradePlan"); - } - }} - leftIcon={<FontAwesomeIcon icon={faPlus} />} - > - Add Project - </Button> - )} - </OrgPermissionCan> - </div> - </Select> - </div> + <ProjectSelect /> ) : ( <Link href={`/org/${currentOrg?.id}/overview`}> <div className="my-6 flex cursor-default items-center justify-center pr-2 text-sm text-mineshaft-300 hover:text-mineshaft-100"> @@ -816,15 +655,6 @@ export const AppLayout = ({ children }: LayoutProps) => { </div> </nav> </aside> - <NewProjectModal - isOpen={popUp.addNewWs.isOpen} - onOpenChange={(isOpen) => handlePopUpToggle("addNewWs", isOpen)} - /> - <UpgradePlanModal - isOpen={popUp.upgradePlan.isOpen} - onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)} - text="You have exceeded the number of projects allowed on the free plan." - /> <CreateOrgModal isOpen={popUp?.createOrg?.isOpen} onClose={() => handlePopUpToggle("createOrg", false)} diff --git a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx new file mode 100644 index 000000000..9300a3e93 --- /dev/null +++ b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx @@ -0,0 +1,214 @@ +import { useMemo } from "react"; +import { components, MenuProps, OptionProps } from "react-select"; +import { faStar } from "@fortawesome/free-regular-svg-icons"; +import { faEye, faPlus, faStar as faSolidStar } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; + +import { createNotification } from "@app/components/notifications"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { Button, FilterableSelect, UpgradePlanModal } from "@app/components/v2"; +import { NewProjectModal } from "@app/components/v2/projects"; +import { + OrgPermissionActions, + OrgPermissionSubjects, + useOrganization, + useSubscription, + useWorkspace +} from "@app/context"; +import { usePopUp } from "@app/hooks"; +import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation"; +import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries"; +import { Workspace } from "@app/hooks/api/workspace/types"; + +type TWorkspaceWithFaveProp = Workspace & { isFavorite: boolean }; + +const ProjectsMenu = ({ children, ...props }: MenuProps<TWorkspaceWithFaveProp>) => { + return ( + <components.Menu {...props}> + {children} + <div className=" m-2 mt-0 "> + <hr className="mb-2 h-px border-0 bg-mineshaft-500" /> + <OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Workspace}> + {(isAllowed) => ( + <Button + className="w-full bg-mineshaft-700 py-2 text-bunker-200" + colorSchema="primary" + variant="outline_bg" + size="xs" + isDisabled={!isAllowed} + onClick={() => props.clearValue()} + leftIcon={<FontAwesomeIcon icon={faPlus} />} + > + Add Project + </Button> + )} + </OrgPermissionCan> + </div> + </components.Menu> + ); +}; + +const ProjectOption = ({ + isSelected, + children, + data, + ...props +}: OptionProps<TWorkspaceWithFaveProp>) => { + const { currentOrg } = useOrganization(); + const { mutateAsync: updateUserProjectFavorites } = useUpdateUserProjectFavorites(); + const { data: projectFavorites } = useGetUserProjectFavorites(currentOrg?.id!); + + const removeProjectFromFavorites = async (projectId: string) => { + try { + await updateUserProjectFavorites({ + orgId: currentOrg!.id, + projectFavorites: [...(projectFavorites || []).filter((entry) => entry !== projectId)] + }); + } catch (err) { + createNotification({ + text: "Failed to remove project from favorites.", + type: "error" + }); + } + }; + + const addProjectToFavorites = async (projectId: string) => { + try { + await updateUserProjectFavorites({ + orgId: currentOrg!.id, + projectFavorites: [...(projectFavorites || []), projectId] + }); + } catch (err) { + createNotification({ + text: "Failed to add project to favorites.", + type: "error" + }); + } + }; + return ( + <components.Option + isSelected={isSelected} + data={data} + {...props} + className={twMerge(props.className, isSelected && "bg-mineshaft-600")} + > + <div className="flex w-full items-center"> + {isSelected && ( + <FontAwesomeIcon className="mr-2 text-mineshaft-300" icon={faEye} size="sm" /> + )} + <p className="truncate">{children}</p> + {data.isFavorite ? ( + <FontAwesomeIcon + icon={faSolidStar} + className="ml-auto text-sm text-yellow-600 hover:text-mineshaft-400" + onClick={async (e) => { + e.stopPropagation(); + await removeProjectFromFavorites(data.id); + }} + /> + ) : ( + <FontAwesomeIcon + icon={faStar} + className="ml-auto text-sm text-mineshaft-400 hover:text-mineshaft-300" + onClick={async (e) => { + e.stopPropagation(); + await addProjectToFavorites(data.id); + }} + /> + )} + </div> + </components.Option> + ); +}; + +export const ProjectSelect = () => { + const { workspaces, currentWorkspace } = useWorkspace(); + const { currentOrg } = useOrganization(); + const { data: projectFavorites } = useGetUserProjectFavorites(currentOrg?.id!); + + const { subscription } = useSubscription(); + + const isAddingProjectsAllowed = subscription?.workspaceLimit + ? subscription.workspacesUsed < subscription.workspaceLimit + : true; + + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ + "addNewWs", + "upgradePlan" + ] as const); + + const { options, value } = useMemo(() => { + const projectOptions = workspaces + .map((w): Workspace & { isFavorite: boolean } => ({ + ...w, + isFavorite: Boolean(projectFavorites?.includes(w.id)) + })) + .sort((a, b) => Number(b.isFavorite) - Number(a.isFavorite)); + + const currentOption = projectOptions.find((option) => option.id === currentWorkspace?.id); + + if (!currentOption) { + return { + options: projectOptions, + value: null + }; + } + + return { + options: [ + currentOption, + ...projectOptions.filter((option) => option.id !== currentOption.id) + ], + value: currentOption + }; + }, [workspaces, projectFavorites, currentWorkspace]); + + return ( + <div className="mt-5 mb-4 w-full p-3"> + <p className="ml-1.5 mb-1 text-xs font-semibold uppercase text-gray-400">Project</p> + <FilterableSelect + className="text-sm" + value={value} + filterOption={(option, inputValue) => + option.data.name.toLowerCase().includes(inputValue.toLowerCase()) + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + onChange={(newValue) => { + // hacky use of null as indication to create project + if (!newValue) { + if (isAddingProjectsAllowed) { + handlePopUpOpen("addNewWs"); + } else { + handlePopUpOpen("upgradePlan"); + } + return; + } + + const project = newValue as TWorkspaceWithFaveProp; + localStorage.setItem("projectData.id", project.id); + // this is not using react query because react query in overview is throwing error when envs are not exact same count + // to reproduce change this back to router.push and switch between two projects with different env count + // look into this on dashboard revamp + window.location.assign(`/project/${project.id}/secrets/overview`); + }} + options={options} + components={{ + Option: ProjectOption, + Menu: ProjectsMenu + }} + /> + <UpgradePlanModal + isOpen={popUp.upgradePlan.isOpen} + onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)} + text="You have exceeded the number of projects allowed on the free plan." + /> + + <NewProjectModal + isOpen={popUp.addNewWs.isOpen} + onOpenChange={(isOpen) => handlePopUpToggle("addNewWs", isOpen)} + /> + </div> + ); +}; diff --git a/frontend/src/layouts/AppLayout/components/ProjectSelect/index.ts b/frontend/src/layouts/AppLayout/components/ProjectSelect/index.ts new file mode 100644 index 000000000..d0be7c203 --- /dev/null +++ b/frontend/src/layouts/AppLayout/components/ProjectSelect/index.ts @@ -0,0 +1 @@ +export * from "./ProjectSelect"; From 57261cf0c89087af49df8d286c66b55cb05ee1b5 Mon Sep 17 00:00:00 2001 From: Scott Wilson <scottraywilson@gmail.com> Date: Wed, 27 Nov 2024 15:42:07 -0800 Subject: [PATCH 2/5] improvement: adjust contrast for selected project --- .../AppLayout/components/ProjectSelect/ProjectSelect.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx index 9300a3e93..07add98bb 100644 --- a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx +++ b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx @@ -91,7 +91,7 @@ const ProjectOption = ({ isSelected={isSelected} data={data} {...props} - className={twMerge(props.className, isSelected && "bg-mineshaft-600")} + className={twMerge(props.className, isSelected && "bg-mineshaft-500")} > <div className="flex w-full items-center"> {isSelected && ( From afdc70442326c58e2e788ba6d223a39394cd3dc8 Mon Sep 17 00:00:00 2001 From: Scott Wilson <scottraywilson@gmail.com> Date: Wed, 27 Nov 2024 17:50:42 -0800 Subject: [PATCH 3/5] improvement: improve select styling --- .../src/components/v2/FilterableSelect/FilterableSelect.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx b/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx index 0f1fd61e5..ad51f565d 100644 --- a/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx +++ b/frontend/src/components/v2/FilterableSelect/FilterableSelect.tsx @@ -59,13 +59,13 @@ export const FilterableSelect = <T,>({ indicatorSeparator: () => "bg-bunker-400", dropdownIndicator: () => "text-bunker-200 p-1", menu: () => - "mt-2 border text-sm text-mineshaft-200 thin-scrollbar bg-mineshaft-900 border-mineshaft-600 rounded-md", + "mt-2 p-2 border text-sm text-mineshaft-200 thin-scrollbar bg-mineshaft-900 border-mineshaft-600 rounded-md", groupHeading: () => "ml-3 mt-2 mb-1 text-mineshaft-400 text-sm", option: ({ isFocused, isSelected }) => twMerge( isFocused && "bg-mineshaft-700 active:bg-mineshaft-600", isSelected && "text-mineshaft-200", - "hover:cursor-pointer text-xs px-3 py-2" + "hover:cursor-pointer mb-1 rounded text-xs px-3 py-2" ), noOptionsMessage: () => "text-mineshaft-400 p-2 rounded-md" }} From 9df9f4a5da580b4bc6f55f3bdc06cb057e84b1fd Mon Sep 17 00:00:00 2001 From: Scott Wilson <scottraywilson@gmail.com> Date: Wed, 27 Nov 2024 17:54:00 -0800 Subject: [PATCH 4/5] improvement: adjust add project button margins --- .../ProjectSelect/ProjectSelect.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx index 07add98bb..fb5dec26a 100644 --- a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx +++ b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx @@ -27,24 +27,22 @@ const ProjectsMenu = ({ children, ...props }: MenuProps<TWorkspaceWithFaveProp>) return ( <components.Menu {...props}> {children} - <div className=" m-2 mt-0 "> - <hr className="mb-2 h-px border-0 bg-mineshaft-500" /> - <OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Workspace}> - {(isAllowed) => ( - <Button - className="w-full bg-mineshaft-700 py-2 text-bunker-200" - colorSchema="primary" - variant="outline_bg" - size="xs" - isDisabled={!isAllowed} - onClick={() => props.clearValue()} - leftIcon={<FontAwesomeIcon icon={faPlus} />} - > - Add Project - </Button> - )} - </OrgPermissionCan> - </div> + <hr className="mb-2 h-px border-0 bg-mineshaft-500" /> + <OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Workspace}> + {(isAllowed) => ( + <Button + className="w-full bg-mineshaft-700 pt-2 text-bunker-200" + colorSchema="primary" + variant="outline_bg" + size="xs" + isDisabled={!isAllowed} + onClick={() => props.clearValue()} + leftIcon={<FontAwesomeIcon icon={faPlus} />} + > + Add Project + </Button> + )} + </OrgPermissionCan> </components.Menu> ); }; From 16d215b58811433e33f52802df218663d6442997 Mon Sep 17 00:00:00 2001 From: Scott Wilson <78768277+scott-ray-wilson@users.noreply.github.com> Date: Fri, 29 Nov 2024 08:17:34 -0800 Subject: [PATCH 5/5] add todo(author) to previous existing comment --- .../AppLayout/components/ProjectSelect/ProjectSelect.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx index fb5dec26a..2768abfed 100644 --- a/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx +++ b/frontend/src/layouts/AppLayout/components/ProjectSelect/ProjectSelect.tsx @@ -186,7 +186,7 @@ export const ProjectSelect = () => { const project = newValue as TWorkspaceWithFaveProp; localStorage.setItem("projectData.id", project.id); - // this is not using react query because react query in overview is throwing error when envs are not exact same count + // todo(akhi): this is not using react query because react query in overview is throwing error when envs are not exact same count // to reproduce change this back to router.push and switch between two projects with different env count // look into this on dashboard revamp window.location.assign(`/project/${project.id}/secrets/overview`);