Absorb the local workspace drift for connection session handling, database switching, inspector readability helpers, and the bounded add-key preview flow. Co-Authored-By: Paperclip <noreply@paperclip.ing>
180 lines
4.9 KiB
TypeScript
180 lines
4.9 KiB
TypeScript
export type SessionConnection = {
|
|
id: string;
|
|
name: string;
|
|
detail: string;
|
|
status: "healthy" | "idle" | "checking" | "error";
|
|
target: {
|
|
database: number;
|
|
username: string | null;
|
|
};
|
|
};
|
|
|
|
export type ConnectionTestState = {
|
|
connectionId: string;
|
|
};
|
|
|
|
export type ConnectionSessionSummary = {
|
|
badgeLabel: string;
|
|
badgeVariant: "neutral" | "accent" | "danger";
|
|
summary: string;
|
|
hint: string;
|
|
};
|
|
|
|
export type ConnectionTestSuccessResult = {
|
|
roundTripStatus: string;
|
|
selectedDatabase: number;
|
|
authenticatedAs: string | null;
|
|
};
|
|
|
|
export function formatConnectionStatusLabel(connection: SessionConnection) {
|
|
if (connection.status === "healthy") {
|
|
return `Ready · ${connection.detail}`;
|
|
}
|
|
|
|
if (connection.status === "checking") {
|
|
return "Testing · Live contract probe";
|
|
}
|
|
|
|
if (connection.status === "error") {
|
|
return `Attention · ${connection.detail}`;
|
|
}
|
|
|
|
return `Idle · ${connection.detail}`;
|
|
}
|
|
|
|
export function formatConnectionCardDetailLabel(connection: SessionConnection) {
|
|
if (connection.status === "checking") {
|
|
return "live test in progress";
|
|
}
|
|
|
|
if (connection.status === "healthy") {
|
|
return `ready ${connection.detail}`;
|
|
}
|
|
|
|
if (connection.status === "error") {
|
|
return `retry ${connection.detail}`;
|
|
}
|
|
|
|
return connection.detail;
|
|
}
|
|
|
|
export function markConnectionTesting<T extends SessionConnection>(
|
|
connections: T[],
|
|
connectionId: string,
|
|
) {
|
|
return connections.map((connection) =>
|
|
connection.id === connectionId
|
|
? {
|
|
...connection,
|
|
status: "checking" as const,
|
|
detail: "Live test in progress",
|
|
}
|
|
: connection,
|
|
);
|
|
}
|
|
|
|
export function applyConnectionTestSuccess<T extends SessionConnection>(
|
|
connections: T[],
|
|
connectionId: string,
|
|
result: ConnectionTestSuccessResult,
|
|
) {
|
|
return connections.map((connection) =>
|
|
connection.id === connectionId
|
|
? {
|
|
...connection,
|
|
status: "healthy" as const,
|
|
detail: result.roundTripStatus,
|
|
target: {
|
|
...connection.target,
|
|
database: result.selectedDatabase,
|
|
username: result.authenticatedAs ?? connection.target.username,
|
|
},
|
|
}
|
|
: connection,
|
|
);
|
|
}
|
|
|
|
export function applyConnectionTestFailure<T extends SessionConnection>(
|
|
connections: T[],
|
|
connectionId: string,
|
|
detail: string,
|
|
) {
|
|
return connections.map((connection) =>
|
|
connection.id === connectionId
|
|
? {
|
|
...connection,
|
|
status: "error" as const,
|
|
detail,
|
|
}
|
|
: connection,
|
|
);
|
|
}
|
|
|
|
export function buildConnectionSessionSummary(args: {
|
|
connection: SessionConnection;
|
|
databaseLabel: string;
|
|
tauriAvailable: boolean;
|
|
activeTestRunning: boolean;
|
|
otherTestingConnectionName: string | null;
|
|
}): ConnectionSessionSummary {
|
|
const {
|
|
connection,
|
|
databaseLabel,
|
|
tauriAvailable,
|
|
activeTestRunning,
|
|
otherTestingConnectionName,
|
|
} = args;
|
|
|
|
if (!tauriAvailable) {
|
|
return {
|
|
badgeLabel: "Demo fallback",
|
|
badgeVariant: "neutral",
|
|
summary: `${connection.name} stays scoped to ${databaseLabel} in browser mode without contacting Redis.`,
|
|
hint: "Use Test demo to verify shell flow only, then switch to the Tauri desktop runtime for a live connection retry.",
|
|
};
|
|
}
|
|
|
|
if (activeTestRunning) {
|
|
return {
|
|
badgeLabel: "Testing",
|
|
badgeVariant: "accent",
|
|
summary: `Running a live connection probe for ${connection.name} on ${databaseLabel}.`,
|
|
hint: "Keep this scope selected if you want the tested database and retry messaging to update in place.",
|
|
};
|
|
}
|
|
|
|
if (otherTestingConnectionName) {
|
|
return {
|
|
badgeLabel: "Ready",
|
|
badgeVariant: "neutral",
|
|
summary: `${connection.name} remains selected on ${databaseLabel} while ${otherTestingConnectionName} finishes a separate live test.`,
|
|
hint: "The current workspace stays stable. Switch back to the testing connection after the probe completes if you need to review its result.",
|
|
};
|
|
}
|
|
|
|
if (connection.status === "healthy") {
|
|
return {
|
|
badgeLabel: "Ready",
|
|
badgeVariant: "accent",
|
|
summary: `${connection.name} last passed a live connection check on ${databaseLabel}.`,
|
|
hint: "Re-run Test live after changing host, DB, credentials, or after recovering from a Redis outage.",
|
|
};
|
|
}
|
|
|
|
if (connection.status === "error") {
|
|
return {
|
|
badgeLabel: "Retry needed",
|
|
badgeVariant: "danger",
|
|
summary: `${connection.name} last failed a live connection check on ${databaseLabel}.`,
|
|
hint: "Review the banner and connection card detail, adjust the profile if needed, then retry Test live from this same scope.",
|
|
};
|
|
}
|
|
|
|
return {
|
|
badgeLabel: "Ready to test",
|
|
badgeVariant: "neutral",
|
|
summary: `${connection.name} is selected on ${databaseLabel} but has not completed a live check in the current session.`,
|
|
hint: "Run Test live before treating browse, inspect, or command results as current Redis evidence.",
|
|
};
|
|
}
|