Merge pull request #11170 from supabase/master

Prod deploy dashboard
This commit is contained in:
Joshen Lim authored and GitHub committed 2022-12-21 22:14:21 +07:00
commit d31caddc39
20 files changed
+109 -131

No files matched your search

+2 -2
View File
@@ -14,7 +14,7 @@ const Footer = () => {
<span className="text-xs text-scale-900">Supabase 2022</span>
<span className="text-xs text-scale-900">—</span>
{footerData.map((item) => (
<Link href={item.url}>
<Link href={item.url} key={item.url}>
<a className="text-xs text-scale-800 hover:underline">{item.title}</a>
</Link>
))}
@@ -41,7 +41,7 @@ const Footer = () => {
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="16">
<path
fill="none"
fill-rule="nonzero"
fillRule="nonzero"
stroke={`${isDarkMode ? '#fff' : '#333'}`}
d="M16.238 2.16a14.628 14.628 0 0 0-3.664-1.159.055.055 0 0 0-.059.028c-.158.288-.333.662-.456.957a13.432 13.432 0 0 0-4.115 0 9.76 9.76 0 0 0-.464-.957.057.057 0 0 0-.058-.028 14.587 14.587 0 0 0-3.664 1.16.053.053 0 0 0-.024.02C1.4 5.74.76 9.21 1.074 12.637c.002.017.011.033.024.043a14.813 14.813 0 0 0 4.494 2.318.058.058 0 0 0 .064-.02c.346-.483.654-.992.92-1.527a.059.059 0 0 0-.032-.08c-.49-.19-.956-.421-1.404-.684a.06.06 0 0 1-.006-.097c.094-.072.189-.148.279-.223a.055.055 0 0 1 .058-.008c2.946 1.372 6.135 1.372 9.046 0a.055.055 0 0 1 .06.007 7.2 7.2 0 0 0 .279.224.06.06 0 0 1-.005.097 9.143 9.143 0 0 1-1.405.683.06.06 0 0 0-.03.081c.27.534.578 1.043.918 1.526.014.02.04.029.063.021A14.763 14.763 0 0 0 18.9 12.68a.06.06 0 0 0 .023-.042c.376-3.962-.628-7.404-2.66-10.455a.046.046 0 0 0-.024-.021Zm-9.223 8.39c-.887 0-1.618-.831-1.618-1.852 0-1.02.717-1.851 1.618-1.851.908 0 1.632.838 1.618 1.851 0 1.02-.717 1.851-1.618 1.851Zm5.981 0c-.887 0-1.618-.831-1.618-1.852 0-1.02.717-1.851 1.618-1.851.908 0 1.632.838 1.618 1.851 0 1.02-.71 1.851-1.618 1.851Z"
/>
@@ -129,7 +129,7 @@ const NavigationMenuHome = () => {
<ul className="relative w-full flex flex-col gap-4">
{home.map((section, sectionIndex) => {
return (
<>
<div key={`section-container-${sectionIndex}-border`}>
{sectionIndex !== 0 && (
<div
className="h-px w-full bg-blackA-300 dark:bg-whiteA-300"
@@ -176,7 +176,7 @@ const NavigationMenuHome = () => {
})}
</div>
</div>
</>
</div>
)
})}
</ul>
@@ -173,7 +173,7 @@ const SideNav = () => {
<NavigationMenuGuideList id={'reference'} />
{/* // Client Libs */}
<NavigationMenuRefList
key={'reference-js-menu'}
key={'reference-js-menu-v1'}
id={'reference_javascript_v1'}
commonSections={libCommonSections}
lib="javascript"
@@ -194,7 +194,7 @@ const SideNav = () => {
allowedClientKeys={generateAllowedClientLibKeys(libCommonSections, spec_dart_v0)}
/>
<NavigationMenuRefList
key={'reference-dart-menu'}
key={'reference-dart-menu-v1'}
id={'reference_dart_v1'}
commonSections={libCommonSections}
lib="dart"
+18 -12
View File
@@ -31,10 +31,11 @@ const Layout: FC<Props> = (props) => {
const [tocList, setTocList] = useState([])
const { asPath } = useRouter()
const page = getPageType(asPath)
const router = useRouter()
const EDIT_BUTTON_EXCLUDE_LIST = ['/404']
useEffect(() => {
if (hash && tocList.length > 0) {
highlightSelectedTocItem(hash as string)
@@ -100,18 +101,23 @@ const Layout: FC<Props> = (props) => {
)}
<div className="max-w-xs w-32 h-[1px] bg-gradient-to-r from-brand-800 to-brand-900 my-8"></div>
<MDXProvider components={components}>{props.children}</MDXProvider>
<div className="mt-16 not-prose">
<div>
<Link
href={`https://github.com/supabase/supabase/edit/master/apps/docs/pages${router.asPath}.mdx`}
passHref
>
<a className="text-sm transition flex items-center gap-1 text-scale-1000 hover:text-scale-1200">
Edit this page on GitHub <IconExternalLink size={14} strokeWidth={1.5} />
</a>
</Link>
{EDIT_BUTTON_EXCLUDE_LIST.includes(router.route) ? (
<></>
) : (
<div className="mt-16 not-prose">
<div>
<Link
href={`https://github.com/supabase/supabase/edit/master/apps/docs/pages${router.asPath}.mdx`}
passHref
>
<a className="text-sm transition flex items-center gap-1 text-scale-1000 hover:text-scale-1200">
Edit this page on GitHub <IconExternalLink size={14} strokeWidth={1.5} />
</a>
</Link>
</div>
</div>
</div>
)}
</article>
</div>
{!props.hideToc && hasTableOfContents && !props.meta?.hide_table_of_contents && (
-52
View File
@@ -1,52 +0,0 @@
import { useEffect, useState } from 'react'
import Link from 'next/link'
import { Button } from 'ui'
import Head from 'next/head'
export default function Custom404() {
const [show404, setShow404] = useState<boolean>(false)
useEffect(() => {
setTimeout(() => {
setShow404(true)
}, 500)
}, [])
return (
<>
<Head>
<title>404 | Supabase</title>
</Head>
<div className="relative mx-auto flex h-screen w-full flex-col items-center justify-center">
<div className="absolute">
<h1
className={`text-scale-1200 select-none text-[14rem] opacity-[5%] filter transition duration-200 sm:text-[18rem] lg:text-[28rem] ${
show404 ? 'blur-sm' : 'blur-none'
}`}
>
404
</h1>
</div>
<div
className={`flex flex-col items-center justify-center space-y-6 transition ${
show404 ? 'opacity-100' : 'opacity-0'
}`}
>
<div className="text-scale-1200 flex w-[320px] flex-col items-center justify-center space-y-3">
<h1 className="m-2 text-2xl">Looking for something?</h1>
<p className="text-center text-sm">
We could not find the page that you are looking for!
</p>
</div>
<div className="flex items-center space-x-4">
<Link href="/">
<Button as="a" size="small" className="text-white">
Head back
</Button>
</Link>
</div>
</div>
</div>
</>
)
}
+1 -1
View File
@@ -30,7 +30,7 @@ export const meta = {
">
<div className="col-span-12 lg:col-span-7 flex flex-col gap-6">
<img className="hidden lg:visible absolute right-0 top-0 w-[500px]" src="/docs/img/cards/dark.png" />
<div classNam="">
<div className="">
<h3 className="text-2xl m-0 mb-3">Getting Started</h3>
Discover how to set up a database to an app making queries in just a few minutes.
+2 -1
View File
@@ -34,6 +34,7 @@ Kevin Grüneberg
Lakshmipathi G
Laura C
Leo T
Long Hoang
Margarita Sandomirskaia
Marijana Šimag
Mark Burggraf
@@ -60,7 +61,7 @@ ____________
JOBS
If you are interested in working with us check out the open roles here: https://about.supabase.com/careers
If you are interested in working with us check out the open roles here: https://supabase.com/careers
___________
+5 -11
View File
@@ -1,26 +1,20 @@
[
{
"text": "Documentation",
"description": "Everything you need that makes it simple to get started.",
"description": "Everything you need to start building with Supabase.",
"url": "/docs",
"icon": "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
},
{
"text": "API reference",
"description": "Examples and references for using API libraries.",
"url": "/docs/client/supabase-client",
"icon": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
},
{
"text": "Guides",
"description": "Examples and references for using Supabase.",
"url": "/docs/",
"text": "Changelog",
"description": "See the latest updates and product improvements.",
"url": "/changelog",
"icon": "M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
},
{
"text": "Careers",
"description": "Join the Supabase team and get involved.",
"url": "https://supabase.com/careers",
"url": "/careers",
"icon": "M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
}
]
-10
View File
@@ -1787,16 +1787,6 @@ module.exports = [
source: '/docs/guides/with-ionic-angular',
destination: '/docs/guides/getting-started/tutorials/with-ionic-angular',
},
{
permanent: true,
source: '/docs/guides/examples',
destination: '/docs/guides/resources/examples',
},
{
permanent: true,
source: '/docs/guides/examples',
destination: '/docs/guides/resources/examples',
},
{
permanent: true,
source: '/docs/guides/hosting/overview',
@@ -135,13 +135,6 @@
"summary": "Retrieve object info",
"type": "operation"
},
{
"id": "retrieve-object-info",
"title": "Retrieve object info",
"slug": "retrieve-object-info",
"summary": "Retrieve object info",
"type": "operation"
},
{
"id": "copies-an-object",
"title": "Copies an object",
@@ -137,6 +137,25 @@ const EnterpriseUpdate: FC<Props> = ({
captchaRef.current?.resetCaptcha()
}
const beforeConfirmPayment = async (): Promise<boolean> => {
setIsSubmitting(true)
let token = captchaToken
try {
if (!token) {
const captchaResponse = await captchaRef.current?.execute({ async: true })
token = captchaResponse?.response ?? null
setCaptchaToken(token)
}
} catch (error) {
setIsSubmitting(false)
return false
}
setIsSubmitting(false)
return true
}
// Last todo to support enterprise billing on dashboard + E2E test
const onConfirmPayment = async () => {
setIsSubmitting(true)
@@ -296,6 +315,7 @@ const EnterpriseUpdate: FC<Props> = ({
onSelectAddNewPaymentMethod={() => {
setShowAddPaymentMethodModal(true)
}}
beforeConfirmPayment={beforeConfirmPayment}
onConfirmPayment={onConfirmPayment}
captcha={
<HCaptcha
@@ -42,6 +42,7 @@ interface Props {
isLoadingPaymentMethods: boolean
onSelectPaymentMethod: (method: any) => void
onSelectAddNewPaymentMethod: () => void
beforeConfirmPayment: () => Promise<boolean>
onConfirmPayment: () => void
isSubmitting: boolean
@@ -72,6 +73,7 @@ const PaymentSummaryPanel: FC<Props> = ({
isLoadingPaymentMethods,
onSelectPaymentMethod,
onSelectAddNewPaymentMethod,
beforeConfirmPayment,
onConfirmPayment,
isSubmitting,
captcha,
@@ -132,16 +134,23 @@ const PaymentSummaryPanel: FC<Props> = ({
message: error,
})
} else {
isChangingComputeSize || (isChangingPITRDuration && selectedPITRDays === 0)
? setShowConfirmModal(true)
: onConfirmPayment()
// [Joshen] We're validating captcha before subsequent actions as there's an issue
// with the hcaptcha overlay and the modal component, such that clicking on the hcaptcha closes
// both the hcaptcha overlay and the modal. Need to figure that out first, then we can validate
// the hcaptcha within onConfirmPayment()
const hasValidCaptcha = await beforeConfirmPayment()
if (hasValidCaptcha) {
isChangingComputeSize || (isChangingPITRDuration && selectedPITRDays === 0)
? setShowConfirmModal(true)
: onConfirmPayment()
}
}
}
return (
<>
<div
className="w-full space-y-8 border-l bg-panel-body-light px-6 py-10 dark:bg-panel-body-dark lg:px-12 overflow-y-auto"
className="w-full px-6 py-10 space-y-8 overflow-y-auto border-l bg-panel-body-light dark:bg-panel-body-dark lg:px-12"
style={{ height: 'calc(100vh - 57px)' }}
>
<p>Payment Summary</p>
@@ -296,7 +305,7 @@ const PaymentSummaryPanel: FC<Props> = ({
</div>
)}
<div className="h-px w-full bg-scale-600" />
<div className="w-full h-px bg-scale-600" />
<PaymentTotal
subscriptionPreview={subscriptionPreview}
@@ -308,12 +317,12 @@ const PaymentSummaryPanel: FC<Props> = ({
<div className="space-y-2">
<p className="text-sm">Select payment method</p>
{isLoadingPaymentMethods ? (
<div className="flex items-center space-x-4 rounded-md border border-scale-700 bg-scale-400 px-4 py-2">
<div className="flex items-center px-4 py-2 space-x-4 border rounded-md border-scale-700 bg-scale-400">
<IconLoader className="animate-spin" size={14} />
<p className="text-sm text-scale-1100">Retrieving payment methods</p>
</div>
) : paymentMethods.length === 0 ? (
<div className="flex items-center justify-between rounded-md border border-dashed bg-scale-100 px-4 py-2">
<div className="flex items-center justify-between px-4 py-2 border border-dashed rounded-md bg-scale-100">
<div className="flex items-center space-x-4 text-scale-1100">
<IconAlertCircle size={16} strokeWidth={1.5} />
<p className="text-sm">No saved payment methods</p>
@@ -373,11 +382,11 @@ const PaymentSummaryPanel: FC<Props> = ({
)
})}
<div
className="group flex cursor-pointer items-center space-x-2 py-2 px-3 transition hover:bg-scale-500"
className="flex items-center px-3 py-2 space-x-2 transition cursor-pointer group hover:bg-scale-500"
onClick={onSelectAddNewPaymentMethod}
>
<IconPlus size={16} />
<p className="text-scale-1000 transition group-hover:text-scale-1200">
<p className="transition text-scale-1000 group-hover:text-scale-1200">
Add new payment method
</p>
</div>
@@ -158,7 +158,7 @@ const ProUpgrade: FC<Props> = ({
captchaRef.current?.resetCaptcha()
}
const onConfirmPayment = async () => {
const beforeConfirmPayment = async (): Promise<boolean> => {
setIsSubmitting(true)
let token = captchaToken
@@ -166,12 +166,18 @@ const ProUpgrade: FC<Props> = ({
if (!token) {
const captchaResponse = await captchaRef.current?.execute({ async: true })
token = captchaResponse?.response ?? null
setCaptchaToken(token)
}
} catch (error) {
setIsSubmitting(false)
return
return false
}
setIsSubmitting(false)
return true
}
const onConfirmPayment = async () => {
const payload = formSubscriptionUpdatePayload(
currentSubscription,
selectedTier,
@@ -179,7 +185,7 @@ const ProUpgrade: FC<Props> = ({
nonChangeableAddons,
selectedPaymentMethodId,
projectRegion,
token ?? undefined
captchaToken ?? undefined
)
const res = await patch(`${API_URL}/projects/${projectRef}/subscription`, payload)
resetCaptcha()
@@ -223,17 +229,17 @@ const ProUpgrade: FC<Props> = ({
enter="transition ease-out duration-300"
enterFrom="transform opacity-0 translate-x-10"
enterTo="transform opacity-100 translate-x-0"
className="flex w-full items-start justify-between"
className="flex items-start justify-between w-full"
>
<div className="flex-grow mt-10">
<div className="relative space-y-4">
<div className="space-y-4 2xl:min-w-5xl mx-auto px-32">
<div className="px-32 mx-auto space-y-4 2xl:min-w-5xl">
<BackButton onClick={() => onSelectBack()} />
<h4 className="text-lg text-scale-900 !mb-8">Change your project's subscription</h4>
</div>
<div
className="space-y-8 overflow-y-auto pb-8 2xl:min-w-5xl mx-auto px-32"
className="px-32 pb-8 mx-auto space-y-8 overflow-y-auto 2xl:min-w-5xl"
style={{ height: 'calc(100vh - 9rem - 57px)' }}
>
<div className="space-y-2">
@@ -257,14 +263,14 @@ const ProUpgrade: FC<Props> = ({
</>
)}
</div>
<div className="flex items-center justify-between gap-16 rounded border border-panel-border-light border-panel-border-dark bg-panel-body-light px-6 py-4 drop-shadow-sm dark:bg-panel-body-dark">
<div className="flex items-center justify-between gap-16 px-6 py-4 border rounded border-panel-border-light border-panel-border-dark bg-panel-body-light drop-shadow-sm dark:bg-panel-body-dark">
<div>
<div className="flex items-center space-x-2">
<p>Enable spend cap</p>
<IconHelpCircle
size={16}
strokeWidth={1.5}
className="cursor-pointer opacity-50 transition hover:opacity-100"
className="transition opacity-50 cursor-pointer hover:opacity-100"
onClick={() => setShowSpendCapHelperModal(true)}
/>
</div>
@@ -342,6 +348,7 @@ const ProUpgrade: FC<Props> = ({
onSelectAddNewPaymentMethod={() => {
setShowAddPaymentMethodModal(true)
}}
beforeConfirmPayment={beforeConfirmPayment}
onConfirmPayment={onConfirmPayment}
isSubmitting={isSubmitting}
captcha={
@@ -375,7 +382,7 @@ const ProUpgrade: FC<Props> = ({
header="Enabling spend cap"
onCancel={() => setShowSpendCapHelperModal(false)}
>
<div className="space-y-4 py-4">
<div className="py-4 space-y-4">
<Modal.Content>
<div className="space-y-4">
<p className="text-sm">
@@ -390,7 +397,7 @@ const ProUpgrade: FC<Props> = ({
</p>
{/* Maybe instead of a table, show something more interactive like a spend cap playground */}
{/* Maybe ideate this in Figma first but this is good enough for now */}
<div className="rounded border border-scale-600 bg-scale-500">
<div className="border rounded border-scale-600 bg-scale-500">
<div className="flex items-center px-4 pt-2 pb-1">
<p className="w-[50%] text-sm text-scale-1100">Item</p>
<p className="w-[25%] text-sm text-scale-1100">Limit</p>
@@ -417,7 +424,7 @@ const ProUpgrade: FC<Props> = ({
<IconHelpCircle
size={16}
strokeWidth={1.5}
className="cursor-pointer opacity-50 transition hover:opacity-100"
className="transition opacity-50 cursor-pointer hover:opacity-100"
/>
</Tooltip.Trigger>
<Tooltip.Content side="bottom">
@@ -812,7 +812,7 @@ create publication supabase_realtime
sql: `
-- Create a table for public profiles
create table profiles (
id uuid references auth.users not null primary key,
id uuid references auth.users on delete cascade not null primary key,
updated_at timestamp with time zone,
username text unique,
full_name text,
@@ -122,8 +122,10 @@ const BucketRow = ({
<ProductMenuItem
key={bucket.id}
name={
<div className="flex items-center space-x-2">
<p>{bucket.name}</p>
<div className="flex items-center justify-between space-x-2 truncate w-full">
<p className="truncate" title={bucket.name}>
{bucket.name}
</p>
{bucket.public && <Badge color="yellow">Public</Badge>}
</div>
}
@@ -34,7 +34,7 @@ const HeaderPathEdit = ({ loading, breadcrumbs, togglePathEdit }) => {
</div>
) : (
<div className="flex cursor-pointer items-center">
<p className="ml-3 text-sm">{breadcrumbs[breadcrumbs.length - 1] || ''}</p>
<p className="ml-3 text-sm truncate">{breadcrumbs[breadcrumbs.length - 1] || ''}</p>
<div className="ml-3 flex items-center space-x-2 opacity-0 transition group-hover:opacity-100">
<Button type="text" icon={<IconEdit2 />}>
Navigate
@@ -224,6 +224,7 @@ const FileExplorerHeader = ({
autoFocus
key="pathSet"
type="text"
size="small"
value={pathString}
onChange={onUpdatePathString}
placeholder="e.g Parent Folder/Child Folder"
@@ -31,16 +31,16 @@ const ProductMenuItem: FC<Props> = ({
}) => {
const menuItem = (
<Menu.Item icon={icon} rounded active={isActive} onClick={onClick}>
<div className="flex w-full items-center justify-between">
<span
<div className="flex w-full items-center justify-between gap-1">
<div
title={hoverText ? hoverText : typeof name === 'string' ? name : ''}
className={'flex items-center gap-2 truncate ' + textClassName}
className={'flex items-center gap-2 truncate w-full ' + textClassName}
>
{name}{' '}
{label !== undefined && (
<span className="text-orange-800 text-xs font-normal">{label}</span>
)}
</span>
</div>
{action}
</div>
</Menu.Item>
-1
View File
@@ -154,7 +154,6 @@ export default class MetaStore implements IMetaStore {
'extensions',
'information_schema',
'net',
'pg_catalog',
'pgsodium',
'pgsodium_masks',
'pgbouncer',
+8
View File
@@ -27,6 +27,14 @@ export default class SchemaStore extends PostgresMetaInterface<PostgresSchema> {
this.views = []
}
// Dashboard to hide schemas with pg_ prefix
list(filter: any) {
const schemasFilter = (schema: PostgresSchema) =>
!schema.name.startsWith('pg_') && (typeof filter === 'function' ? filter(schema) : true)
return super.list(schemasFilter)
}
async loadViews(schema: string) {
const query = `
select schemaname as schema, viewname as name from pg_catalog.pg_views
+2 -2
View File
@@ -20,8 +20,8 @@ export default class TriggersStore extends PostgresMetaInterface<any> {
*/
list(filter: any) {
const triggersFilter = (h: any) =>
h.function_schema != 'supabase_functions' &&
h.schema != 'net' &&
h.function_schema !== 'supabase_functions' &&
h.schema !== 'net' &&
(typeof filter === 'function' ? filter(h) : true)
return super.list(triggersFilter)