feat: PlanetScale managed-MySQL preset with setup guide and host detection (Task 3)
This commit is contained in:
@@ -8,7 +8,7 @@ import type { ConnectionFormData } from "./connectionFormData";
|
||||
export interface DetailedConnectionFormProps {
|
||||
form: ConnectionFormData;
|
||||
onChange: (updates: Partial<ConnectionFormData>) => void;
|
||||
managedPreset?: "supabase" | "neon" | null;
|
||||
managedPreset?: "supabase" | "neon" | "planetscale" | null;
|
||||
}
|
||||
|
||||
export function DetailedConnectionForm({ form, onChange, managedPreset }: DetailedConnectionFormProps) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { ConnectionFormData } from "./connectionFormData";
|
||||
export interface GeneralTabProps {
|
||||
form: ConnectionFormData;
|
||||
onChange: (updates: Partial<ConnectionFormData>) => void;
|
||||
managedPreset?: "supabase" | "neon" | null;
|
||||
managedPreset?: "supabase" | "neon" | "planetscale" | null;
|
||||
}
|
||||
|
||||
const AUTH_OPTIONS = ["User & Password"];
|
||||
@@ -32,7 +32,7 @@ export function GeneralTab({ form, onChange, managedPreset }: GeneralTabProps) {
|
||||
)}
|
||||
{managedPreset && (
|
||||
<p className="text-xs text-accent-muted mt-1.5">
|
||||
{managedPreset === "supabase" ? "Supabase" : "NeonDB"} requires SSL — enable it under SSH / SSL.
|
||||
{managedPreset === "supabase" ? "Supabase" : managedPreset === "planetscale" ? "PlanetScale" : "NeonDB"} requires SSL — enable it under SSH / SSL.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -74,7 +74,7 @@ export function NewConnectionScreen({
|
||||
}: NewConnectionScreenProps) {
|
||||
const [stage, setStage] = useState<Stage>("entry");
|
||||
const [managedPreset, setManagedPreset] = useState<
|
||||
"supabase" | "neon" | null
|
||||
"supabase" | "neon" | "planetscale" | null
|
||||
>(null);
|
||||
const [form, setForm] = useState<ConnectionFormData>(() =>
|
||||
createEmptyForm(
|
||||
@@ -99,7 +99,7 @@ export function NewConnectionScreen({
|
||||
const parsed = parseConnectionString(value);
|
||||
if (parsed) {
|
||||
const provider =
|
||||
parsed.db_type === "postgresql"
|
||||
parsed.db_type === "postgresql" || parsed.db_type === "mysql"
|
||||
? detectProviderFromHost(parsed.host)
|
||||
: null;
|
||||
setManagedPreset(provider);
|
||||
@@ -139,7 +139,9 @@ export function NewConnectionScreen({
|
||||
(id: ProviderId) => {
|
||||
const provider = getProviderById(id)!;
|
||||
setManagedPreset(
|
||||
provider.isManagedPreset ? (id as "supabase" | "neon") : null,
|
||||
provider.isManagedPreset
|
||||
? (id as "supabase" | "neon" | "planetscale")
|
||||
: null,
|
||||
);
|
||||
revealConfigured({
|
||||
db_type: provider.dbType,
|
||||
@@ -148,6 +150,7 @@ export function NewConnectionScreen({
|
||||
? null
|
||||
: getDefaultPort(provider.dbType),
|
||||
...(provider.dbType === "sqlite" ? { host: "" } : {}),
|
||||
...(id === "planetscale" ? { ssl_mode: "verify-full" } : {}),
|
||||
});
|
||||
},
|
||||
[revealConfigured],
|
||||
@@ -164,7 +167,7 @@ export function NewConnectionScreen({
|
||||
const parsed = parseConnectionString(value);
|
||||
if (parsed) {
|
||||
const provider =
|
||||
parsed.db_type === "postgresql"
|
||||
parsed.db_type === "postgresql" || parsed.db_type === "mysql"
|
||||
? detectProviderFromHost(parsed.host)
|
||||
: null;
|
||||
setManagedPreset(provider);
|
||||
|
||||
@@ -3,12 +3,13 @@ import { ChevronDown } from "lucide-react";
|
||||
import { SETUP_GUIDES } from "../../lib/providers";
|
||||
|
||||
interface ProviderSetupGuideProps {
|
||||
provider: "supabase" | "neon";
|
||||
provider: "supabase" | "neon" | "planetscale";
|
||||
}
|
||||
|
||||
const SSL_NOTE: Record<"supabase" | "neon", string> = {
|
||||
const SSL_NOTE: Record<"supabase" | "neon" | "planetscale", string> = {
|
||||
supabase: "SSL is required by Supabase.",
|
||||
neon: "Neon requires SSL.",
|
||||
planetscale: "PlanetScale requires SSL with identity verification.",
|
||||
};
|
||||
|
||||
export function ProviderSetupGuide({ provider }: ProviderSetupGuideProps) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export function ProviderTabsGrid({ selectedId, onSelect }: ProviderTabsGridProps
|
||||
}`}
|
||||
>
|
||||
<span className="w-8 h-8 flex items-center justify-center">
|
||||
{p.isManagedPreset ? <ProviderIcon id={p.id as "supabase" | "neon"} size={24} /> : <DbIcon type={p.dbType} size={24} />}
|
||||
{p.isManagedPreset ? <ProviderIcon id={p.id as "supabase" | "neon" | "planetscale"} size={24} /> : <DbIcon type={p.dbType} size={24} />}
|
||||
</span>
|
||||
<span className="text-sm font-medium">{p.label}</span>
|
||||
{p.isManagedPreset && (
|
||||
|
||||
Reference in New Issue
Block a user