mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Add restoration failure state
This commit is contained in:
1 parent
1bf5aea50e
commit
1925955fe2
4 files changed
+67
-38
No files matched your search
@@ -39,7 +39,7 @@ interface Props {
|
||||
const SupportForm: FC<Props> = ({ setSentCategory }) => {
|
||||
const { ui, app } = useStore()
|
||||
const router = useRouter()
|
||||
const { ref, category } = router.query
|
||||
const { ref, subject, category } = router.query
|
||||
|
||||
const uploadButtonRef = useRef()
|
||||
const enableFreeSupport = useFlag('enableFreeSupport')
|
||||
@@ -82,7 +82,7 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
|
||||
|
||||
const selectedProject = sortedProjects.find((project) => project.ref === ref)
|
||||
const selectedCategory = CATEGORY_OPTIONS.find((option) => {
|
||||
if (option.value.toLowerCase() === category) return option
|
||||
if (option.value.toLowerCase() === ((category as string) ?? '').toLowerCase()) return option
|
||||
})
|
||||
const initialValues = {
|
||||
category: selectedCategory !== undefined ? selectedCategory.value : CATEGORY_OPTIONS[0].value,
|
||||
@@ -94,7 +94,7 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
|
||||
? sortedProjects[0].ref
|
||||
: 'no-project',
|
||||
library: 'no-library',
|
||||
subject: '',
|
||||
subject: subject ?? '',
|
||||
message: '',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Link from 'next/link'
|
||||
import { FC, useEffect, useRef, useState } from 'react'
|
||||
import { Button, IconCheckCircle, IconLoader } from 'ui'
|
||||
import { Button, IconAlertCircle, IconCheckCircle, IconLoader } from 'ui'
|
||||
|
||||
import { useStore } from 'hooks'
|
||||
import { API_URL, PROJECT_STATUS } from 'lib/constants'
|
||||
@@ -13,6 +14,7 @@ const RestoringState: FC<Props> = ({}) => {
|
||||
const checkServerInterval = useRef<number>()
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [isFailed, setIsFailed] = useState(false)
|
||||
const [isCompleted, setIsCompleted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -28,7 +30,10 @@ const RestoringState: FC<Props> = ({}) => {
|
||||
})
|
||||
if (projectStatus && !projectStatus.error) {
|
||||
const { status } = projectStatus
|
||||
if (status === PROJECT_STATUS.ACTIVE_HEALTHY) {
|
||||
if (status === PROJECT_STATUS.RESTORATION_FAILED) {
|
||||
clearInterval(checkServerInterval.current)
|
||||
setIsFailed(true)
|
||||
} else if (status === PROJECT_STATUS.ACTIVE_HEALTHY) {
|
||||
clearInterval(checkServerInterval.current)
|
||||
setIsCompleted(true)
|
||||
}
|
||||
@@ -42,43 +47,66 @@ const RestoringState: FC<Props> = ({}) => {
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<div
|
||||
className={[
|
||||
'grid grid-cols-12 gap-4',
|
||||
'bg-scale-300 border border-scale-400 rounded-md w-3/4 lg:w-1/2 px-8 py-6',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="bg-scale-300 border border-scale-400 rounded-md w-3/4 lg:w-1/2">
|
||||
{isCompleted ? (
|
||||
<>
|
||||
<div className="col-span-1">
|
||||
<IconCheckCircle className="text-brand-900" strokeWidth={2} />
|
||||
<div className="space-y-6 pt-6">
|
||||
<div className="flex px-8 space-x-8">
|
||||
<div className="mt-1">
|
||||
<IconCheckCircle className="text-brand-900" size={18} strokeWidth={2} />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p>Restoration complete!</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Your project has been successfully restored and is now back online.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-11 space-y-1">
|
||||
<p>Restoration complete!</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Your project has been successfully restored and is now back online.
|
||||
</p>
|
||||
<div className="border-t border-scale-400 flex items-center justify-end py-4 px-8">
|
||||
<Button disabled={loading} loading={loading} onClick={onConfirm}>
|
||||
Return to project
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
) : isFailed ? (
|
||||
<div className="space-y-6 pt-6">
|
||||
<div className="flex px-8 space-x-8">
|
||||
<div className="mt-1">
|
||||
<IconAlertCircle size={18} strokeWidth={2} />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p>Something went wrong while restoring your project</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Our engineers have already been notified of this, do hang tight while we are
|
||||
investigating into the issue.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{isFailed && (
|
||||
<div className="border-t border-scale-400 flex items-center justify-end py-4 px-8">
|
||||
<Link
|
||||
href={`/support/new?category=Database_unresponsive&ref=${project?.ref}&subject=Restoration%20failed%20for%20project`}
|
||||
>
|
||||
<a>
|
||||
<Button type="default">Contact support</Button>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="col-span-1">
|
||||
<IconLoader className="animate-spin" />
|
||||
<div className="space-y-6 py-6">
|
||||
<div className="flex px-8 space-x-8">
|
||||
<div className="mt-1">
|
||||
<IconLoader className="animate-spin" size={18} />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p>Restoration in progress</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Restoration can take from a few minutes up to several hours depending on the size
|
||||
of your database. Your project will be offline while the restoration is running.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-11 space-y-1">
|
||||
<p>Restoration in progress</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Restoration can take from a few minutes up to several hours depending on the size of
|
||||
your database. Your project will be offline while the restoration is running.
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{isCompleted && (
|
||||
<div className="col-start-2 col-span-11">
|
||||
<Button disabled={loading} loading={loading} onClick={onConfirm}>
|
||||
Return to project
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -105,6 +105,7 @@ export const PROJECT_STATUS = {
|
||||
INIT_FAILED: 'INIT_FAILED',
|
||||
REMOVED: 'REMOVED',
|
||||
RESTORING: 'RESTORING',
|
||||
RESTORATION_FAILED: 'RESTORATION_FAILED',
|
||||
}
|
||||
|
||||
export const STRIPE_PRODUCT_IDS: { [x: string]: string } = {
|
||||
|
||||
@@ -78,7 +78,7 @@ export default class ProjectStore extends PostgresMetaInterface<Project> {
|
||||
|
||||
async fetchSubscriptionTier(project: Project) {
|
||||
const { id: projectId, ref: projectRef, status } = project
|
||||
if (status === PROJECT_STATUS.ACTIVE_HEALTHY) {
|
||||
if (status !== PROJECT_STATUS.REMOVED) {
|
||||
const url = `${this.url}/${projectRef}/subscription`
|
||||
const headers = constructHeaders(this.headers)
|
||||
const response = await get(url, { headers })
|
||||
|
||||
Reference in new issue
Block a user