| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- 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 type="default">
- <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
- }
- }
- 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'
- }
- }
- 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" type="default" 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'
- }
- }
- 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.'
- }
- }
- const getWarningLink = (warning: ProjectUpgradeEligibilityWarning): string => {
- switch (warning.type) {
- case 'pg_graphql_introspection_change':
- return `${DOCS_URL}/guides/platform/upgrading#upgrading-to-pg_graphql-160`
- }
- }
- 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 type="default" className="mt-2">
- <Link href={getWarningLink(warning)} target="_blank" rel="noreferrer">
- Read upgrade notes
- </Link>
- </Button>
- </Admonition>
- ))
- }
|