mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
476d4a5851
## What kind of change does this PR introduce? Mechanical cleanup on top of the Button default-variant change (#50160). ## What is the current behavior? Many callsites still pass `variant="default"` even though that is now the component default. ## What is the new behavior? Removes redundant static `variant="default"` from legacy `Button` and `ButtonTooltip` callsites. Keeps explicit defaults where they document the API: - `button-default.tsx` and `button-sizes.tsx` demos - `DocsButton`, which pins neutral styling at the wrapper boundary ## To test Studio: - [Auth → Rate Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits): dirty the form so Cancel appears; Cancel stays neutral, Save stays green - [Project Settings → API Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys): `DocsButton` in the header actions stays neutral Design system: - [Design system → Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button): `button-default` / `button-sizes` still show explicit default styling; Primary (green) is restricted to the Primary section (and `asChild`) WWW: - [www → Brand assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets): Download logo kit / Download button kit stay neutral
220 lines
9.2 KiB
TypeScript
220 lines
9.2 KiB
TypeScript
import { useParams } from 'common'
|
|
import Link from 'next/link'
|
|
import { Button } from 'ui'
|
|
import { Admonition } from 'ui-patterns/Admonition'
|
|
|
|
import { InlineLink } from '@/components/ui/InlineLink'
|
|
import {
|
|
ProjectUpgradeEligibilityValidationError,
|
|
ProjectUpgradeEligibilityWarning,
|
|
} from '@/data/config/project-upgrade-eligibility-query'
|
|
import { DOCS_URL } from '@/lib/constants'
|
|
|
|
export const ReadReplicasWarning = ({ latestPgVersion }: { latestPgVersion: string }) => {
|
|
const { ref } = useParams()
|
|
|
|
return (
|
|
<Admonition
|
|
type="note"
|
|
showIcon={false}
|
|
title="A newer version of Postgres is available"
|
|
description={`You will need to remove all read replicas prior to upgrading your Postgres version to the latest available (${latestPgVersion}).`}
|
|
actions={
|
|
<Button asChild>
|
|
<Link href={`/project/${ref}/database/replication`}>Manage read replicas</Link>
|
|
</Button>
|
|
}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const getValidationErrorTitle = (error: ProjectUpgradeEligibilityValidationError): string => {
|
|
switch (error.type) {
|
|
case 'objects_depending_on_pg_cron':
|
|
return (error.dependents ?? []).join(', ') || 'Objects depending on pg_cron'
|
|
case 'indexes_referencing_ll_to_earth':
|
|
return `${error.schema_name}.${error.index_name}`
|
|
case 'function_using_obsolete_lang':
|
|
return `${error.schema_name}.${error.function_name}`
|
|
case 'unsupported_extension':
|
|
return error.extension_name
|
|
case 'unsupported_fdw_handler':
|
|
return error.fdw_name
|
|
case 'unlogged_table_with_persistent_sequence':
|
|
return `${error.schema_name}.${error.table_name}`
|
|
case 'user_defined_objects_in_internal_schemas':
|
|
return `${error.schema_name}.${error.obj_name}`
|
|
case 'active_replication_slot':
|
|
return error.slot_name
|
|
case 'project_hibernating':
|
|
return 'Project is hibernating'
|
|
case 'x86_architecture':
|
|
return 'Project is running on x86 architecture'
|
|
}
|
|
}
|
|
|
|
const getValidationErrorDescription = (error: ProjectUpgradeEligibilityValidationError): string => {
|
|
switch (error.type) {
|
|
case 'objects_depending_on_pg_cron':
|
|
return 'Remove objects that depend on pg_cron'
|
|
case 'indexes_referencing_ll_to_earth':
|
|
return `Drop or recreate the index on table ${error.schema_name}.${error.table_name} that references ll_to_earth()`
|
|
case 'function_using_obsolete_lang':
|
|
return `Update the function to use a supported language instead of ${error.lang_name}`
|
|
case 'unsupported_extension':
|
|
return 'Remove the unsupported extension'
|
|
case 'unsupported_fdw_handler':
|
|
return `Update or remove the FDW using the obsolete handler ${error.fdw_handler_name}`
|
|
case 'unlogged_table_with_persistent_sequence':
|
|
return `Convert the sequence ${error.sequence_name} to unlogged or convert the table to logged`
|
|
case 'user_defined_objects_in_internal_schemas':
|
|
return `Move the ${error.obj_type} to your own schema`
|
|
case 'active_replication_slot':
|
|
return 'Drop the active replication slot'
|
|
case 'project_hibernating':
|
|
return 'The project is currently hibernating and will wake on next supported request'
|
|
case 'x86_architecture':
|
|
return 'The project is running on x86 architecture and cannot be upgraded'
|
|
}
|
|
}
|
|
|
|
const ValidationErrorItem = ({ error }: { error: ProjectUpgradeEligibilityValidationError }) => {
|
|
const { ref: projectRef } = useParams()
|
|
const title = getValidationErrorTitle(error)
|
|
const description = getValidationErrorDescription(error)
|
|
|
|
const getManageLink = (): string | null => {
|
|
const encode = encodeURIComponent
|
|
switch (error.type) {
|
|
case 'function_using_obsolete_lang':
|
|
return `/project/${projectRef}/database/functions?schema=${encode(error.schema_name)}&search=${encode(error.function_name)}`
|
|
case 'unsupported_extension':
|
|
return `/project/${projectRef}/database/extensions?filter=${encode(error.extension_name)}`
|
|
case 'indexes_referencing_ll_to_earth':
|
|
return `/project/${projectRef}/database/indexes?schema=${encode(error.schema_name)}&search=${encode(error.index_name)}`
|
|
case 'unlogged_table_with_persistent_sequence':
|
|
return `/project/${projectRef}/database/tables?schema=${encode(error.schema_name)}&search=${encode(error.table_name)}`
|
|
case 'user_defined_objects_in_internal_schemas':
|
|
if (error.obj_type === 'function') {
|
|
return `/project/${projectRef}/database/functions?schema=${encode(error.schema_name)}&search=${encode(error.obj_name)}`
|
|
}
|
|
if (error.obj_type === 'table') {
|
|
return `/project/${projectRef}/database/tables?schema=${encode(error.schema_name)}&search=${encode(error.obj_name)}`
|
|
}
|
|
return null
|
|
case 'active_replication_slot':
|
|
return null
|
|
case 'unsupported_fdw_handler':
|
|
return `/project/${projectRef}/integrations`
|
|
case 'objects_depending_on_pg_cron':
|
|
return null
|
|
default:
|
|
return null
|
|
}
|
|
}
|
|
|
|
const manageLink = getManageLink()
|
|
|
|
return (
|
|
<li className="py-3 last:pb-0 flex flex-row gap-x-3 justify-between items-center">
|
|
<div className="flex flex-col gap-y-0.5 flex-1 min-w-0">
|
|
<h6 className="overflow-hidden text-ellipsis whitespace-nowrap min-w-0 text-sm font-normal text-foreground">
|
|
{title}
|
|
</h6>
|
|
<p className="text-foreground-lighter text-xs">{description}</p>
|
|
</div>
|
|
{manageLink && (
|
|
<Button size="tiny" asChild>
|
|
<Link href={manageLink}>Manage</Link>
|
|
</Button>
|
|
)}
|
|
</li>
|
|
)
|
|
}
|
|
|
|
export const ValidationErrorsWarning = ({
|
|
validationErrors,
|
|
}: {
|
|
validationErrors: ProjectUpgradeEligibilityValidationError[]
|
|
}) => {
|
|
if (validationErrors.length === 0) return null
|
|
|
|
return (
|
|
<Admonition type="note" showIcon={false} title="A newer version of Postgres is available">
|
|
<div className="flex flex-col gap-3">
|
|
<p>
|
|
The following issues must be resolved before upgrading.{' '}
|
|
<InlineLink href={`${DOCS_URL}/guides/platform/upgrading`}>Learn more</InlineLink>
|
|
</p>
|
|
<ul className="border-t border-border-muted flex flex-col divide-y divide-border-muted">
|
|
{validationErrors.map((error, idx) => (
|
|
<ValidationErrorItem key={`${error.type}-${idx}`} error={error} />
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</Admonition>
|
|
)
|
|
}
|
|
|
|
const getWarningTitle = (warning: ProjectUpgradeEligibilityWarning): string => {
|
|
switch (warning.type) {
|
|
case 'pg_graphql_introspection_change':
|
|
return 'GraphQL introspection will be disabled by default after upgrade'
|
|
case 'ltree_reindex_required':
|
|
return 'ltree indexes must be reindexed after this upgrade'
|
|
case 'operator_estimator_gate':
|
|
return 'Custom operators may need attention after this upgrade'
|
|
case 'btree_gist_nan_reindex':
|
|
return 'btree_gist indexes on float columns must be reindexed after this upgrade'
|
|
}
|
|
}
|
|
|
|
const getWarningDescription = (warning: ProjectUpgradeEligibilityWarning): string => {
|
|
switch (warning.type) {
|
|
case 'pg_graphql_introspection_change':
|
|
return 'After upgrading, queries to `__schema` and `__type` will return an error unless introspection is explicitly re-enabled on the schema. Regular data queries are not affected.'
|
|
case 'ltree_reindex_required':
|
|
return 'After upgrading, ltree indexes on this database can return incomplete results until they are rebuilt. Run `REINDEX INDEX CONCURRENTLY` on the affected indexes — this runs online with no downtime.'
|
|
case 'operator_estimator_gate':
|
|
return 'After upgrading, recreating an operator that references a non-built-in selectivity estimator (for example during a restore or branch) requires superuser and may fail. Most projects are not affected.'
|
|
case 'btree_gist_nan_reindex':
|
|
return 'After upgrading, btree_gist indexes on float columns can return wrong results for rows containing NaN until they are rebuilt. If those columns may contain NaN values, run `REINDEX INDEX CONCURRENTLY` on the affected indexes — this runs online with no downtime.'
|
|
}
|
|
}
|
|
|
|
const getWarningLink = (warning: ProjectUpgradeEligibilityWarning): string => {
|
|
switch (warning.type) {
|
|
case 'pg_graphql_introspection_change':
|
|
return `${DOCS_URL}/guides/platform/upgrading#upgrading-to-pg_graphql-160`
|
|
case 'ltree_reindex_required':
|
|
return `${DOCS_URL}/guides/platform/upgrading#ltree-indexes-require-reindexing-after-upgrade`
|
|
case 'operator_estimator_gate':
|
|
return `${DOCS_URL}/guides/platform/upgrading#custom-operator-selectivity-estimators`
|
|
case 'btree_gist_nan_reindex':
|
|
return `${DOCS_URL}/guides/platform/upgrading#btree_gist-indexes-on-float-columns-require-reindexing-after-upgrade`
|
|
}
|
|
}
|
|
|
|
export const ValidationWarningsAdmonition = ({
|
|
warnings,
|
|
}: {
|
|
warnings: ProjectUpgradeEligibilityWarning[]
|
|
}) => {
|
|
if (warnings.length === 0) return null
|
|
|
|
return warnings.map((warning, idx) => (
|
|
<Admonition
|
|
key={`${warning.type}-${idx}`}
|
|
type="default"
|
|
title={getWarningTitle(warning)}
|
|
description={getWarningDescription(warning)}
|
|
>
|
|
<Button asChild className="mt-2">
|
|
<Link href={getWarningLink(warning)} target="_blank" rel="noreferrer">
|
|
Read upgrade notes
|
|
</Link>
|
|
</Button>
|
|
</Admonition>
|
|
))
|
|
}
|