Repository: supabase/supabase
File: apps/studio/components/interfaces/Settings/Infrastructure/UpgradeWarnings.tsx (TypeScript)

Code before:
const ValidationErrorItem = ({
  error,
  projectRef,
}: {
  error: ProjectUpgradeEligibilityValidationError
  projectRef: string
}) => {
  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':
        return error.obj_type === 'function'
          ? `/project/${projectRef}/database/functions?schema=${encode(error.schema_name)}&search=${encode(error.obj_name)}`
          : error.obj_type === 'table'
            ? `/project/${projectRef}/database/tables?schema=${encode(error.schema_name)}&search=${encode(error.obj_name)}`
            : 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>

Review comment (bug):
These two `/database/tables/` links include URL query parameters that won't work until https://github.com/supabase/supabase/pull/42022 is merged.

It fails silently, which is why I’ve still included it in this PR.

Code after:
          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[]
}) => {
  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>