mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Add incident banner
This commit is contained in:
1 parent
4f3b225f75
commit
aa5b4269b2
8 files changed
+77
-34
No files matched your search
@@ -0,0 +1,29 @@
|
||||
import { FC } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useFlag } from 'hooks'
|
||||
import { IconExternalLink } from '@supabase/ui'
|
||||
|
||||
const AppBannerWrapper: FC = ({ children }) => {
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
{ongoingIncident && (
|
||||
<Link href="https://status.supabase.com">
|
||||
<a target="_blank">
|
||||
<div className="hover:bg-green-1000 flex cursor-pointer items-center justify-center space-x-2 bg-green-900 py-3 transition">
|
||||
<p className="text-scale-1200 text-sm font-medium">
|
||||
We are currently investigating a technical issue, follow status.supabase.com for
|
||||
updates
|
||||
</p>
|
||||
<IconExternalLink size={16} strokeWidth={2} />
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppBannerWrapper
|
||||
@@ -1,5 +1,6 @@
|
||||
import PortalToast from './PortalToast'
|
||||
import GoTrueWrapper from './GoTrueWrapper/GoTrueWrapper'
|
||||
import RouteValidationWrapper from './RouteValidationWrapper'
|
||||
import AppBannerWrapper from './AppBannerWrapper'
|
||||
|
||||
export { PortalToast, GoTrueWrapper, RouteValidationWrapper }
|
||||
export { PortalToast, GoTrueWrapper, RouteValidationWrapper, AppBannerWrapper }
|
||||
@@ -3,7 +3,7 @@ import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { API_URL, IS_PLATFORM } from 'lib/constants'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore, withAuth, useFlag } from 'hooks'
|
||||
import WithSidebar from './WithSidebar'
|
||||
import { auth } from 'lib/gotrue'
|
||||
|
||||
@@ -17,9 +17,11 @@ import { auth } from 'lib/gotrue'
|
||||
|
||||
const AccountLayout = ({ children, title, breadcrumbs }: any) => {
|
||||
const router = useRouter()
|
||||
|
||||
const { app, ui } = useStore()
|
||||
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
const maxHeight = ongoingIncident ? 'calc(100vh - 44px)' : '100vh'
|
||||
|
||||
const onClickLogout = async () => {
|
||||
await auth.signOut()
|
||||
router.reload()
|
||||
@@ -117,7 +119,7 @@ const AccountLayout = ({ children, title, breadcrumbs }: any) => {
|
||||
</Head>
|
||||
<div className="flex h-full">
|
||||
<main
|
||||
style={{ maxHeight: '100vh' }}
|
||||
style={{ height: maxHeight, maxHeight }}
|
||||
className="flex w-full flex-1 flex-col overflow-y-auto"
|
||||
>
|
||||
<WithSidebar title={title} breadcrumbs={breadcrumbs} links={linksWithHeaders}>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import { CSSProperties, FC, ReactNode } from 'react'
|
||||
import { Menu, Typography, IconArrowUpRight, Badge } from '@supabase/ui'
|
||||
import { FC, ReactNode } from 'react'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { Menu, Typography, IconArrowUpRight, Badge } from '@supabase/ui'
|
||||
import { useFlag } from 'hooks'
|
||||
import LayoutHeader from '../ProjectLayout/LayoutHeader'
|
||||
|
||||
interface Props {
|
||||
@@ -11,7 +12,6 @@ interface Props {
|
||||
header?: ReactNode
|
||||
subitems?: any[]
|
||||
subitemsParentKey?: number
|
||||
sidebarStyle?: CSSProperties
|
||||
hideSidebar?: boolean
|
||||
customSidebarContent?: ReactNode
|
||||
children: ReactNode
|
||||
@@ -22,7 +22,6 @@ const WithSidebar: FC<Props> = ({
|
||||
header,
|
||||
breadcrumbs = [],
|
||||
children,
|
||||
sidebarStyle,
|
||||
links,
|
||||
subitems,
|
||||
subitemsParentKey,
|
||||
@@ -32,16 +31,19 @@ const WithSidebar: FC<Props> = ({
|
||||
const noContent = !links && !customSidebarContent
|
||||
const linksHaveHeaders = links && links[0].heading
|
||||
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
const maxHeight = ongoingIncident ? 'calc(100vh - 44px)' : '100vh'
|
||||
|
||||
return (
|
||||
<div className={`flex `}>
|
||||
<div className="flex max-h-full">
|
||||
{!hideSidebar && !noContent && (
|
||||
<div
|
||||
id="with-sidebar"
|
||||
style={{ height: maxHeight, maxHeight }}
|
||||
className={[
|
||||
'bg-sidebar-linkbar-light dark:bg-sidebar-linkbar-dark',
|
||||
'hide-scrollbar dark:border-dark h-screen w-64 overflow-auto border-r',
|
||||
'bg-sidebar-linkbar-light dark:bg-sidebar-linkbar-dark h-full',
|
||||
'hide-scrollbar dark:border-dark w-64 overflow-auto border-r',
|
||||
].join(' ')}
|
||||
style={sidebarStyle}
|
||||
>
|
||||
{title && (
|
||||
<div className="mb-2">
|
||||
@@ -74,7 +76,7 @@ const WithSidebar: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex h-screen flex-1 flex-col">
|
||||
<div className="flex flex-1 flex-col">
|
||||
<LayoutHeader breadcrumbs={breadcrumbs} />
|
||||
<div className="flex-1 flex-grow overflow-auto">{children}</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isUndefined } from 'lodash'
|
||||
import { Button, IconHome, Dropdown, IconUser, IconSettings } from '@supabase/ui'
|
||||
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { useStore } from 'hooks'
|
||||
import { useStore, useFlag } from 'hooks'
|
||||
import { generateProductRoutes, generateOtherRoutes } from './NavigationBar.utils'
|
||||
import NavigationIconButton from './NavigationIconButton'
|
||||
|
||||
@@ -18,22 +18,19 @@ const NavigationBar: FC<Props> = ({}) => {
|
||||
const projectRef = ui.selectedProjectRef as string
|
||||
const projectBaseInfo = ui.selectedProjectBaseInfo
|
||||
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
|
||||
const activeRoute = router.pathname.split('/')[3]
|
||||
const productRoutes = generateProductRoutes(projectRef, projectBaseInfo)
|
||||
const otherRoutes = generateOtherRoutes(projectRef, projectBaseInfo)
|
||||
|
||||
return (
|
||||
<div
|
||||
className="
|
||||
h-screen w-14
|
||||
flex flex-col
|
||||
justify-between
|
||||
p-2
|
||||
overflow-y-hidden
|
||||
bg-sidebar-light
|
||||
dark:bg-sidebar-dark
|
||||
border-r
|
||||
dark:border-dark"
|
||||
style={{ height: ongoingIncident ? 'calc(100vh - 44px)' : '100vh' }}
|
||||
className={[
|
||||
'flex w-14 flex-col justify-between overflow-y-hidden p-2',
|
||||
'bg-sidebar-light dark:bg-sidebar-dark dark:border-dark border-r',
|
||||
].join(' ')}
|
||||
>
|
||||
<ul className="flex flex-col space-y-2">
|
||||
<Link href={'/'}>
|
||||
@@ -41,7 +38,7 @@ const NavigationBar: FC<Props> = ({}) => {
|
||||
<img
|
||||
src="/img/supabase-logo.svg"
|
||||
alt="Supabase"
|
||||
className="rounded h-[40px] w-6 mx-auto cursor-pointer"
|
||||
className="mx-auto h-[40px] w-6 cursor-pointer rounded"
|
||||
/>
|
||||
</a>
|
||||
</Link>
|
||||
@@ -54,7 +51,7 @@ const NavigationBar: FC<Props> = ({}) => {
|
||||
link: `/project/${projectRef}`,
|
||||
}}
|
||||
/>
|
||||
<div className="h-px w-full bg-scale-500"></div>
|
||||
<div className="bg-scale-500 h-px w-full"></div>
|
||||
{productRoutes.map((route) => (
|
||||
<NavigationIconButton
|
||||
key={route.key}
|
||||
@@ -62,7 +59,7 @@ const NavigationBar: FC<Props> = ({}) => {
|
||||
isActive={activeRoute === route.key}
|
||||
/>
|
||||
))}
|
||||
<div className="h-px w-full bg-scale-500"></div>
|
||||
<div className="bg-scale-500 h-px w-full"></div>
|
||||
{otherRoutes.map((route) => (
|
||||
<NavigationIconButton
|
||||
key={route.key}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FC, ReactNode } from 'react'
|
||||
import { Typography } from '@supabase/ui'
|
||||
import { useFlag } from 'hooks'
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
@@ -7,21 +8,25 @@ interface Props {
|
||||
}
|
||||
|
||||
const ProductMenuBar: FC<Props> = ({ title, children }) => {
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
const maxHeight = ongoingIncident ? 'calc(100vh - 44px)' : '100vh'
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ height: maxHeight, maxHeight }}
|
||||
className={[
|
||||
'w-64 h-screen flex flex-col hide-scrollbar border-r', // Layout
|
||||
'hide-scrollbar flex w-64 flex-col border-r', // Layout
|
||||
'bg-sidebar-linkbar-light', // Light mode
|
||||
'dark:bg-sidebar-linkbar-dark dark:border-dark ', // Dark mode
|
||||
].join(' ')}
|
||||
>
|
||||
<div
|
||||
className="px-6 max-h-12 border-b dark:border-dark flex items-center"
|
||||
className="dark:border-dark flex max-h-12 items-center border-b px-6"
|
||||
style={{ minHeight: '3rem' }}
|
||||
>
|
||||
<Typography.Title level={4}>{title}</Typography.Title>
|
||||
</div>
|
||||
<div className="overflow-y-auto flex-grow">{children}</div>
|
||||
<div className="flex-grow overflow-y-auto">{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Head from 'next/head'
|
||||
import { FC, ReactNode, PropsWithChildren } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore, withAuth, useFlag } from 'hooks'
|
||||
import { PROJECT_STATUS } from 'lib/constants'
|
||||
|
||||
import Connecting from 'components/ui/Loading'
|
||||
@@ -30,6 +30,8 @@ const ProjectLayout = ({
|
||||
hideHeader = false,
|
||||
hideIconBar = false,
|
||||
}: PropsWithChildren<Props>) => {
|
||||
const ongoingIncident = useFlag('ongoingIncident')
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -47,8 +49,8 @@ const ProjectLayout = ({
|
||||
</MenuBarWrapper>
|
||||
|
||||
<main
|
||||
style={{ maxHeight: '100vh' }}
|
||||
className="flex w-full flex-1 flex-col overflow-x-hidden"
|
||||
style={{ height: ongoingIncident ? 'calc(100vh - 44px)' : '100vh' }}
|
||||
>
|
||||
{!hideHeader && <LayoutHeader />}
|
||||
<ContentWrapper isLoading={isLoading}>{children}</ContentWrapper>
|
||||
|
||||
@@ -26,7 +26,12 @@ import { StoreProvider } from 'hooks'
|
||||
import { getParameterByName } from 'lib/common/fetch'
|
||||
import { GOTRUE_ERRORS } from 'lib/constants'
|
||||
|
||||
import { PortalToast, GoTrueWrapper, RouteValidationWrapper } from 'components/interfaces/App'
|
||||
import {
|
||||
PortalToast,
|
||||
GoTrueWrapper,
|
||||
RouteValidationWrapper,
|
||||
AppBannerWrapper,
|
||||
} from 'components/interfaces/App'
|
||||
import PageTelemetry from 'components/ui/PageTelemetry'
|
||||
import FlagProvider from 'components/ui/Flag/FlagProvider'
|
||||
|
||||
@@ -62,7 +67,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||
<GoTrueWrapper>
|
||||
<PageTelemetry>
|
||||
<RouteValidationWrapper>
|
||||
{getLayout(<Component {...pageProps} />)}
|
||||
<AppBannerWrapper>{getLayout(<Component {...pageProps} />)}</AppBannerWrapper>
|
||||
</RouteValidationWrapper>
|
||||
</PageTelemetry>
|
||||
</GoTrueWrapper>
|
||||
|
||||
Reference in new issue
Block a user