From d8e85a064b072153901c618bb0b2f8b131b0eb42 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Mon, 21 Apr 2025 15:58:29 +0700 Subject: [PATCH] Clear last visited organization when deleteing or leaving org (#35088) * Clear last visited organization when deleteing or leaving org * Fix DEFAULT_HOME to be dynamic based on if the new layout preview is enabled or not --- .../interfaces/App/RouteValidationWrapper.tsx | 10 +++++++- .../DeleteOrganizationButton.tsx | 14 ++++++++++- .../TeamSettings/TeamSettings.tsx | 24 ++++++++++++++++--- .../ProjectLayout/LayoutHeader/HomeIcon.tsx | 2 -- apps/studio/lib/constants/index.ts | 1 - 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/apps/studio/components/interfaces/App/RouteValidationWrapper.tsx b/apps/studio/components/interfaces/App/RouteValidationWrapper.tsx index 1447e364f4d..ef14cacedce 100644 --- a/apps/studio/components/interfaces/App/RouteValidationWrapper.tsx +++ b/apps/studio/components/interfaces/App/RouteValidationWrapper.tsx @@ -8,13 +8,15 @@ import { useProjectsQuery } from 'data/projects/projects-query' import useLatest from 'hooks/misc/useLatest' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' -import { DEFAULT_HOME, IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants' +import { IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants' import { useAppStateSnapshot } from 'state/app-state' +import { useIsNewLayoutEnabled } from './FeaturePreview/FeaturePreviewContext' // Ideally these could all be within a _middleware when we use Next 12 const RouteValidationWrapper = ({ children }: PropsWithChildren<{}>) => { const router = useRouter() const { ref, slug, id } = useParams() + const newLayoutPreview = useIsNewLayoutEnabled() const isLoggedIn = useIsLoggedIn() const snap = useAppStateSnapshot() @@ -31,6 +33,12 @@ const RouteValidationWrapper = ({ children }: PropsWithChildren<{}>) => { '' ) + const DEFAULT_HOME = IS_PLATFORM + ? newLayoutPreview + ? '/organizations' + : '/projects' + : '/project/default' + /** * Array of urls/routes that should be ignored */ diff --git a/apps/studio/components/interfaces/Organization/GeneralSettings/DeleteOrganizationButton.tsx b/apps/studio/components/interfaces/Organization/GeneralSettings/DeleteOrganizationButton.tsx index da2876a39dc..923e57e8a0e 100644 --- a/apps/studio/components/interfaces/Organization/GeneralSettings/DeleteOrganizationButton.tsx +++ b/apps/studio/components/interfaces/Organization/GeneralSettings/DeleteOrganizationButton.tsx @@ -6,7 +6,9 @@ import { toast } from 'sonner' import { useIsNewLayoutEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useOrganizationDeleteMutation } from 'data/organizations/organization-delete-mutation' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' +import { LOCAL_STORAGE_KEYS } from 'lib/constants' import { Button, Form, Input, Modal } from 'ui' const DeleteOrganizationButton = () => { @@ -18,11 +20,21 @@ const DeleteOrganizationButton = () => { const [isOpen, setIsOpen] = useState(false) const [value, setValue] = useState('') + const [_, setLastVisitedOrganization] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION, + '' + ) + const canDeleteOrganization = useCheckPermissions(PermissionAction.UPDATE, 'organizations') const { mutate: deleteOrganization, isLoading: isDeleting } = useOrganizationDeleteMutation({ onSuccess: () => { toast.success(`Successfully deleted ${orgName}`) - router.push(newLayoutPreview ? '/organizations' : '/projects') + if (newLayoutPreview) { + setLastVisitedOrganization('') + router.push('/organizations') + } else { + router.push('/projects') + } }, }) diff --git a/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx b/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx index 27ad91f1448..4426b4af278 100644 --- a/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx +++ b/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx @@ -1,4 +1,5 @@ import { Search } from 'lucide-react' +import { useRouter } from 'next/router' import { useState } from 'react' import { toast } from 'sonner' @@ -16,10 +17,12 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useOrganizationRolesV2Query } from 'data/organization-members/organization-roles-query' import { useOrganizationMemberDeleteMutation } from 'data/organizations/organization-member-delete-mutation' import { useOrganizationMembersQuery } from 'data/organizations/organization-members-query' +import { useOrganizationsQuery } from 'data/organizations/organizations-query' import { usePermissionsQuery } from 'data/permissions/permissions-query' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' +import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' -import { BASE_PATH } from 'lib/constants' +import { LOCAL_STORAGE_KEYS } from 'lib/constants' import { useProfile } from 'lib/profile' import { Input } from 'ui-patterns/DataInputs/Input' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' @@ -29,6 +32,10 @@ import { hasMultipleOwners, useGetRolesManagementPermissions } from './TeamSetti const TeamSettings = () => { const newLayoutPreview = useIsNewLayoutEnabled() + const [_, setLastVisitedOrganization] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION, + '' + ) const { organizationMembersCreate: organizationMembersCreationEnabled, @@ -36,11 +43,13 @@ const TeamSettings = () => { } = useIsFeatureEnabled(['organization_members:create', 'organization_members:delete']) const { slug } = useParams() + const router = useRouter() const { profile } = useProfile() const selectedOrganization = useSelectedOrganization() const isOwner = selectedOrganization?.is_owner const { data: permissions } = usePermissionsQuery() + const { refetch: refetchOrganizations } = useOrganizationsQuery() const { data: rolesData } = useOrganizationRolesV2Query({ slug }) const { data: members } = useOrganizationMembersQuery({ slug }) @@ -59,10 +68,19 @@ const TeamSettings = () => { const canLeave = !isOwner || (isOwner && hasMultipleOwners(members, roles)) const { mutate: deleteMember } = useOrganizationMemberDeleteMutation({ - onSuccess: () => { + onSuccess: async () => { setIsLeaving(false) setIsLeaveTeamModalOpen(false) - window?.location.replace(BASE_PATH) // Force reload to clear Store + + await refetchOrganizations() + toast.success(`Successfully left ${selectedOrganization?.name}`) + + if (newLayoutPreview) { + setLastVisitedOrganization('') + router.push('/organizations') + } else { + router.push('/projects') + } }, onError: (error) => { setIsLeaving(false) diff --git a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/HomeIcon.tsx b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/HomeIcon.tsx index 23938d63705..84e82a0990b 100644 --- a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/HomeIcon.tsx +++ b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/HomeIcon.tsx @@ -3,7 +3,6 @@ import Link from 'next/link' import { useRouter } from 'next/router' import { useIsNewLayoutEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' import { useOrganizationsQuery } from 'data/organizations/organizations-query' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' @@ -15,7 +14,6 @@ export const HomeIcon = () => { const showLayoutHeader = useShowLayoutHeader() const selectedOrganization = useSelectedOrganization() const { data: organizations } = useOrganizationsQuery() - const { project } = useProjectContext() const router = useRouter() const [lastVisitedOrganization] = useLocalStorageQuery( diff --git a/apps/studio/lib/constants/index.ts b/apps/studio/lib/constants/index.ts index e8a5d13f0f8..ac4f7e22636 100644 --- a/apps/studio/lib/constants/index.ts +++ b/apps/studio/lib/constants/index.ts @@ -3,7 +3,6 @@ export * from './infrastructure' export const IS_PLATFORM = process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' -export const DEFAULT_HOME = IS_PLATFORM ? '/organizations' : '/project/default' export const API_URL = (() => { // If running in platform, use API_URL from the env var