From 14e8c19c965e62e1c351164d9d3261ecb49eaeca Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Mon, 17 Jul 2023 22:31:00 +0800 Subject: [PATCH] Add AppLayout and simplify height logic in layout component --- .../{HeaderBar.tsx => AppHeader.tsx} | 14 +- .../layouts/AppLayout/AppLayout.tsx | 9 +- .../AppLayout/OrganizationDropdown.tsx | 17 +- .../LayoutHeader/ProjectDropdown.tsx | 21 ++- .../NavigationBar/NavigationBar.tsx | 30 ++-- .../layouts/ProjectLayout/ProductMenuBar.tsx | 16 +- .../layouts/ProjectLayout/ProjectLayout.tsx | 165 ++++++++++-------- studio/pages/org/[slug]/index.tsx | 53 +++--- 8 files changed, 181 insertions(+), 144 deletions(-) rename studio/components/layouts/AppLayout/{HeaderBar.tsx => AppHeader.tsx} (69%) diff --git a/studio/components/layouts/AppLayout/HeaderBar.tsx b/studio/components/layouts/AppLayout/AppHeader.tsx similarity index 69% rename from studio/components/layouts/AppLayout/HeaderBar.tsx rename to studio/components/layouts/AppLayout/AppHeader.tsx index 061df2adebe..f27e9d5a24c 100644 --- a/studio/components/layouts/AppLayout/HeaderBar.tsx +++ b/studio/components/layouts/AppLayout/AppHeader.tsx @@ -1,18 +1,23 @@ import Link from 'next/link' import { useRouter } from 'next/router' + import FeedbackDropdown from '../ProjectLayout/LayoutHeader/FeedbackDropdown' import HelpPopover from '../ProjectLayout/LayoutHeader/HelpPopover' import NotificationsPopover from '../ProjectLayout/LayoutHeader/NotificationsPopover' import OrganizationDropdown from './OrganizationDropdown' import UserSettingsDropdown from './UserSettingsDropdown' +import { useSelectedOrganization, useSelectedProject } from 'hooks' +import ProjectDropdown from '../ProjectLayout/LayoutHeader/ProjectDropdown' -const HeaderBar = () => { +const AppHeader = () => { const router = useRouter() + const project = useSelectedProject() + const organization = useSelectedOrganization() return ( -
+
- + { +
@@ -34,4 +40,4 @@ const HeaderBar = () => { ) } -export default HeaderBar +export default AppHeader diff --git a/studio/components/layouts/AppLayout/AppLayout.tsx b/studio/components/layouts/AppLayout/AppLayout.tsx index a14f74d752c..275113dbde8 100644 --- a/studio/components/layouts/AppLayout/AppLayout.tsx +++ b/studio/components/layouts/AppLayout/AppLayout.tsx @@ -1,13 +1,14 @@ -import Image from 'next/image' -import Link from 'next/link' import { PropsWithChildren } from 'react' -import HeaderBar from './HeaderBar' +import AppHeader from './AppHeader' +import { useFlag } from 'hooks' const AppLayout = ({ children }: PropsWithChildren<{}>) => { + const navLayoutV2 = useFlag('navigationLayoutV2') + return (
- + {navLayoutV2 && } {children}
) diff --git a/studio/components/layouts/AppLayout/OrganizationDropdown.tsx b/studio/components/layouts/AppLayout/OrganizationDropdown.tsx index 3149b62b941..52fe6f28602 100644 --- a/studio/components/layouts/AppLayout/OrganizationDropdown.tsx +++ b/studio/components/layouts/AppLayout/OrganizationDropdown.tsx @@ -1,18 +1,18 @@ -import { useRouter } from 'next/router' -import { Button, Dropdown, IconChevronDown, IconChevronsDown, IconCode, IconPlus } from 'ui' +import Link from 'next/link' +import { Badge, Button, Dropdown, IconCode, IconPlus } from 'ui' import { useOrganizationsQuery } from 'data/organizations/organizations-query' -import { useFlag, useSelectedOrganization, useStore } from 'hooks' +import { useFlag, useSelectedOrganization } from 'hooks' import { IS_PLATFORM } from 'lib/constants' -import Link from 'next/link' +import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query' const OrganizationDropdown = () => { - const router = useRouter() - const { ui } = useStore() const { data: organizations } = useOrganizationsQuery() const selectedOrganization = useSelectedOrganization() const orgCreationV2 = useFlag('orgcreationv2') + const { data, isSuccess } = useOrgSubscriptionQuery({ orgSlug: selectedOrganization?.slug }) + return IS_PLATFORM ? ( { iconRight={} > {selectedOrganization?.name} + {isSuccess && ( + + {data?.plan.name} + + )} ) : ( diff --git a/studio/components/layouts/ProjectLayout/LayoutHeader/ProjectDropdown.tsx b/studio/components/layouts/ProjectLayout/LayoutHeader/ProjectDropdown.tsx index b56940ded52..784bf0589a7 100644 --- a/studio/components/layouts/ProjectLayout/LayoutHeader/ProjectDropdown.tsx +++ b/studio/components/layouts/ProjectLayout/LayoutHeader/ProjectDropdown.tsx @@ -1,7 +1,7 @@ import Link from 'next/link' import { useRouter } from 'next/router' import { ParsedUrlQuery } from 'querystring' -import { Button, Dropdown, IconPlus, Popover } from 'ui' +import { Button, Dropdown, IconCode, IconPlus, Popover } from 'ui' import { useProjectsQuery } from 'data/projects/projects-query' import { useSelectedOrganization, useSelectedProject } from 'hooks' @@ -30,7 +30,11 @@ export const sanitizeRoute = (route: string, routerQueries: ParsedUrlQuery) => { } } -const ProjectDropdown = () => { +interface ProjectDropdownProps { + alt?: boolean +} + +const ProjectDropdown = ({ alt }: ProjectDropdownProps) => { const selectedOrganization = useSelectedOrganization() const selectedProject = useSelectedProject() const { data: allProjects } = useProjectsQuery() @@ -75,13 +79,18 @@ const ProjectDropdown = () => { } > - ) : ( - ) } diff --git a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx index 50bdff1621b..2ef126699c0 100644 --- a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx +++ b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx @@ -2,7 +2,6 @@ import * as Tooltip from '@radix-ui/react-tooltip' import { isUndefined } from 'lodash' import Link from 'next/link' import { useRouter } from 'next/router' -import { FC } from 'react' import { useTheme } from 'common' import { useParams } from 'common/hooks' @@ -27,15 +26,13 @@ import { } from './NavigationBar.utils' import NavigationIconButton from './NavigationIconButton' -interface Props {} - -const NavigationBar: FC = ({}) => { +const NavigationBar = ({}) => { const router = useRouter() const { isDarkMode, toggleTheme } = useTheme() const { ref: projectRef } = useParams() const { project } = useProjectContext() - const ongoingIncident = useFlag('ongoingIncident') + const navLayoutV2 = useFlag('navigationLayoutV2') const activeRoute = router.pathname.split('/')[3] const toolRoutes = generateToolRoutes(projectRef, project) @@ -46,22 +43,23 @@ const NavigationBar: FC = ({}) => { const { setIsOpen } = useCommandMenu() return (
    - - - Supabase - - + {!navLayoutV2 && ( + + + Supabase + + + )} = ({}) => { link: `/project/${projectRef}`, }} /> -
    +
    {toolRoutes.map((route) => ( = ({ title, children }) => { - const ongoingIncident = useFlag('ongoingIncident') - const maxHeight = ongoingIncident ? 'calc(100vh - 44px)' : '100vh' - +const ProductMenuBar = ({ title, children }: PropsWithChildren) => { return (
    = ({ title, children }) => { >

    {title}

    -
    {children}
    +
    + {children} +
    ) } diff --git a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx index e2dae22e23c..7e72ae8ca00 100644 --- a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx +++ b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx @@ -16,6 +16,7 @@ import { ProjectContextProvider } from './ProjectContext' import ProjectPausedState from './ProjectPausedState' import RestoringState from './RestoringState' import UpgradingState from './UpgradingState' +import AppLayout from '../AppLayout/AppLayout' export interface ProjectLayoutProps { title?: string @@ -39,61 +40,70 @@ const ProjectLayout = ({ }: PropsWithChildren) => { const router = useRouter() const { ref: projectRef } = useParams() - const ongoingIncident = useFlag('ongoingIncident') const selectedOrganization = useSelectedOrganization() const selectedProject = useSelectedProject() const projectName = selectedProject?.name const organizationName = selectedOrganization?.name + const ongoingIncident = useFlag('ongoingIncident') + const navLayoutV2 = useFlag('navigationLayoutV2') + const appHeaderHeight = navLayoutV2 ? 48 : 0 + const isPaused = selectedProject?.status === PROJECT_STATUS.INACTIVE const ignorePausedState = router.pathname === '/project/[ref]' || router.pathname.includes('/project/[ref]/settings') const showPausedState = isPaused && !ignorePausedState return ( - - - - {title - ? `${title} | Supabase` - : selectedTable - ? `${selectedTable} | ${projectName} | ${organizationName} | Supabase` - : projectName - ? `${projectName} | ${organizationName} | Supabase` - : organizationName - ? `${organizationName} | Supabase` - : 'Supabase'} - - - -
    - {/* Left-most navigation side bar to access products */} - {!hideIconBar && } - - {/* Product menu bar */} - {!showPausedState && ( - - {productMenu} - - )} - -
    + + + + {title + ? `${title} | Supabase` + : selectedTable + ? `${selectedTable} | ${projectName} | ${organizationName} | Supabase` + : projectName + ? `${projectName} | ${organizationName} | Supabase` + : organizationName + ? `${organizationName} | Supabase` + : 'Supabase'} + + + +
    - {!hideHeader && } - {showPausedState ? ( -
    -
    - -
    -
    - ) : ( - {children} + {/* Left-most navigation side bar to access products */} + {!hideIconBar && } + + {/* Product menu bar */} + {!showPausedState && ( + + {productMenu} + )} -
    -
    -
    + +
    + {!navLayoutV2 && !hideHeader && } + {showPausedState ? ( +
    +
    + +
    +
    + ) : ( + {children} + )} +
    +
+ + ) } @@ -190,44 +200,53 @@ export const ProjectLayoutNonBlocking = ({ const selectedProject = useSelectedProject() const router = useRouter() const { ref: projectRef } = useParams() - const ongoingIncident = useFlag('ongoingIncident') const isPaused = selectedProject?.status === PROJECT_STATUS.INACTIVE const ignorePausedState = router.pathname === '/project/[ref]' || router.pathname.includes('/project/[ref]/settings') const showPausedState = isPaused && !ignorePausedState + const ongoingIncident = useFlag('ongoingIncident') + const navLayoutV2 = useFlag('navigationLayoutV2') + const appHeaderHeight = navLayoutV2 ? 48 : 0 + return ( - - - {title ? `${title} | Supabase` : 'Supabase'} - - - -
- {/* Left-most navigation side bar to access products */} - {!hideIconBar && } - - {/* Product menu bar */} - {productMenu && !showPausedState && ( - {productMenu} - )} - -
+ + + {title ? `${title} | Supabase` : 'Supabase'} + + + +
- {!hideHeader && } - {showPausedState ? ( -
-
- -
-
- ) : ( - children + {/* Left-most navigation side bar to access products */} + {!hideIconBar && } + + {/* Product menu bar */} + {productMenu && !showPausedState && ( + {productMenu} )} -
-
-
+ +
+ {!hideHeader && } + {showPausedState ? ( +
+
+ +
+
+ ) : ( + children + )} +
+
+ + ) } diff --git a/studio/pages/org/[slug]/index.tsx b/studio/pages/org/[slug]/index.tsx index 0daf06e04b4..263a42d7732 100644 --- a/studio/pages/org/[slug]/index.tsx +++ b/studio/pages/org/[slug]/index.tsx @@ -1,3 +1,6 @@ +import Link from 'next/link' +import { Button, IconPlus } from 'ui' + import ProjectCard from 'components/interfaces/Home/ProjectList/ProjectCard' import ShimmeringCard from 'components/interfaces/Home/ProjectList/ShimmeringCard' import AppLayout from 'components/layouts/AppLayout/AppLayout' @@ -5,9 +8,7 @@ import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import AlertError from 'components/ui/AlertError' import { useProjectsQuery } from 'data/projects/projects-query' import { useSelectedOrganization } from 'hooks' -import Link from 'next/link' import { NextPageWithLayout } from 'types' -import { Button, IconPlus } from 'ui' const ProjectsPage: NextPageWithLayout = () => { const { @@ -27,31 +28,33 @@ const ProjectsPage: NextPageWithLayout = () => { return ( -
-
+
+ + + + + +

Projects

- - - - - + {isLoadingProjects && ( +
    + + +
+ )} + {isErrorProjects && ( + + )} + {isSuccessProjects && ( +
    + {projects?.map((project) => ( + + ))} +
+ )}
- {isLoadingProjects && ( -
    - - -
- )} - {isErrorProjects && ( - - )} - {isSuccessProjects && ( -
    - {projects?.map((project) => ( - - ))} -
- )}