WIP: frontend clone_mode removal in create form and API

- Remove clone_mode/branch/new_branch from createInstance API helper
- Remove clone mode UI and branch fields from CreateSessionForm

Remaining: wire workspace_id in form/tool-starter, remove session-card badge, tests
This commit is contained in:
Developer
2026-06-12 15:31:50 +00:00
parent 79aabd6f43
commit 3da7ea6408
5 changed files with 72 additions and 208 deletions
+1 -9
View File
@@ -31,8 +31,6 @@ export interface Session {
url: string | null;
container_status?: string;
probe_status?: string;
clone_mode?: string;
branch?: string | null;
created_at?: string;
}
@@ -51,12 +49,9 @@ export async function createInstance(
repoId: string,
toolTypeId: string,
displayName?: string,
cloneMode?: string,
branch?: string,
newBranch?: string,
workspaceId?: string,
configProfileId?: string,
sshKeyIds?: string[],
workspaceId?: string,
): Promise<ToolInstance> {
const response = await apiClient.post(
`/projects/${projectId}/repositories/${repoId}/instances`,
@@ -64,9 +59,6 @@ export async function createInstance(
tool_type_id: toolTypeId,
display_name: displayName,
workspace_id: workspaceId || undefined,
clone_mode: cloneMode || "mount",
branch: branch || undefined,
new_branch: newBranch || undefined,
config_profile_id: configProfileId,
ssh_key_ids: sshKeyIds || [],
},
@@ -6,11 +6,7 @@ import {
type ToolInstance,
} from "../../../api/sessions";
import type { Project } from "../../../types";
import {
listRepositoryBranches,
type GitRepository,
type Branch,
} from "../../../api/git-repositories";
import type { GitRepository } from "../../../api/git-repositories";
import type { ToolType } from "../../../api/tool-types";
import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys";
import {
@@ -26,7 +22,6 @@ interface CreateSessionFormProps {
fixedRepoId?: string;
projectName?: string;
repoName?: string;
showCloneMode?: boolean;
showFixedFields?: boolean;
onProjectChange?: (projectId: string) => void;
onSuccess?: (instance: ToolInstance) => void;
@@ -43,7 +38,6 @@ export const CreateSessionForm = ({
fixedRepoId,
projectName,
repoName,
showCloneMode = true,
showFixedFields = true,
onProjectChange,
onSuccess,
@@ -55,19 +49,11 @@ export const CreateSessionForm = ({
const [selectedRepo, setSelectedRepo] = useState(fixedRepoId || "");
const [selectedToolType, setSelectedToolType] = useState("");
const [displayName, setDisplayName] = useState("");
const [cloneMode, setCloneMode] = useState<"mount" | "clone">("mount");
const [branch, setBranch] = useState("main");
const [sshKeys, setSshKeys] = useState<SSHKey[]>([]);
const [configProfiles, setConfigProfiles] = useState<ConfigProfile[]>([]);
const [selectedConfigProfile, setSelectedConfigProfile] = useState("");
const [selectedSshKeyIds, setSelectedSshKeyIds] = useState<string[]>([]);
const [branches, setBranches] = useState<Branch[]>([]);
const [isLoadingBranches, setIsLoadingBranches] = useState(false);
const [isCreatingNewBranch, setIsCreatingNewBranch] = useState(false);
const [newBranchName, setNewBranchName] = useState("");
const [baseBranch, setBaseBranch] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -108,31 +94,6 @@ export const CreateSessionForm = ({
void loadProfiles();
}, [selectedToolType, selectedProject, fixedProjectId]);
// Load branches when selected repo changes
useEffect(() => {
const projectId = fixedProjectId || selectedProject;
if (!selectedRepo || !projectId || !showCloneMode) {
setBranches([]);
return;
}
const loadBranches = async () => {
setIsLoadingBranches(true);
try {
const response = await listRepositoryBranches(projectId, selectedRepo);
setBranches(response.branches);
if (response.default_branch) {
setBranch(response.default_branch);
setBaseBranch(response.default_branch);
}
} catch {
// ignore
} finally {
setIsLoadingBranches(false);
}
};
void loadBranches();
}, [selectedRepo, selectedProject, fixedProjectId, showCloneMode]);
// Filter repositories by selected project
const availableRepos = selectedProject
? repositories.filter((r) => r.project_id === selectedProject)
@@ -143,12 +104,6 @@ export const CreateSessionForm = ({
if (!fixedRepoId) setSelectedRepo("");
setSelectedToolType("");
setDisplayName("");
setCloneMode("mount");
setBranch("main");
setIsCreatingNewBranch(false);
setNewBranchName("");
setBaseBranch("");
setBranches([]);
setSelectedSshKeyIds([]);
setSelectedConfigProfile("");
};
@@ -165,14 +120,6 @@ export const CreateSessionForm = ({
return;
}
if (showCloneMode && cloneMode === "clone") {
const repo = repositories.find((r) => r.id === repoId);
if (!repo?.ssh_key_id) {
setError("Repository must have an SSH key assigned for clone mode");
return;
}
}
setIsSubmitting(true);
try {
@@ -181,15 +128,7 @@ export const CreateSessionForm = ({
repoId,
selectedToolType,
displayName || undefined,
showCloneMode ? cloneMode : undefined,
showCloneMode && cloneMode === "clone"
? isCreatingNewBranch
? baseBranch
: branch
: undefined,
showCloneMode && cloneMode === "clone" && isCreatingNewBranch
? newBranchName
: undefined,
undefined,
selectedConfigProfile || undefined,
selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined,
);
@@ -240,8 +179,6 @@ export const CreateSessionForm = ({
setSelectedProject(value);
setSelectedRepo("");
setSelectedToolType("");
setCloneMode("mount");
setIsCreatingNewBranch(false);
onProjectChange?.(value);
}}
disabled={isSubmitting}
@@ -277,8 +214,6 @@ export const CreateSessionForm = ({
onChange={(e) => {
setSelectedRepo(e.target.value);
setSelectedToolType("");
setCloneMode("mount");
setIsCreatingNewBranch(false);
}}
disabled={!hasProject || isSubmitting}
>
@@ -301,8 +236,6 @@ export const CreateSessionForm = ({
value={selectedToolType}
onChange={(e) => {
setSelectedToolType(e.target.value);
setCloneMode("mount");
setIsCreatingNewBranch(false);
}}
disabled={!hasRepo || isSubmitting}
>
@@ -382,134 +315,6 @@ export const CreateSessionForm = ({
</div>
)}
{/* Clone Mode & Branch */}
{showCloneMode && hasToolType && (
<div className="form-field">
<label>Repository Access</label>
<div className="radio-group">
<label className="radio-label">
<input
type="radio"
name="cloneMode"
value="mount"
checked={cloneMode === "mount"}
onChange={(e) => {
setCloneMode(e.target.value as "mount" | "clone");
setIsCreatingNewBranch(false);
}}
disabled={isSubmitting}
/>
Mount (live sync)
</label>
<label className="radio-label">
<input
type="radio"
name="cloneMode"
value="clone"
checked={cloneMode === "clone"}
onChange={(e) => {
setCloneMode(e.target.value as "mount" | "clone");
setIsCreatingNewBranch(false);
}}
disabled={isSubmitting}
/>
Clone fresh copy
</label>
</div>
{cloneMode === "clone" && (
<>
<label className="form-field">
Branch
{isLoadingBranches ? (
<span className="muted">Loading branches...</span>
) : (
<select
value={isCreatingNewBranch ? "__new__" : branch}
onChange={(e) => {
const value = e.target.value;
if (value === "__new__") {
setIsCreatingNewBranch(true);
setNewBranchName("");
} else {
setIsCreatingNewBranch(false);
setBranch(value);
setBaseBranch(value);
}
}}
disabled={isSubmitting}
>
{branches.map((b) => (
<option key={b.name} value={b.name}>
{b.name} {b.is_default ? "(default)" : ""}
</option>
))}
<option value="__new__">Create new branch...</option>
</select>
)}
</label>
{isCreatingNewBranch && (
<>
<label className="form-field">
New Branch Name
<input
type="text"
value={newBranchName}
onChange={(e) => setNewBranchName(e.target.value)}
placeholder="feature/my-new-branch"
required
disabled={isSubmitting}
/>
</label>
<label className="form-field">
Base Branch
<select
value={baseBranch}
onChange={(e) => setBaseBranch(e.target.value)}
disabled={isSubmitting}
>
{branches.map((b) => (
<option key={b.name} value={b.name}>
{b.name} {b.is_default ? "(default)" : ""}
</option>
))}
</select>
</label>
</>
)}
{selectedRepo && (
<div className="form-field ssh-key-info">
{(() => {
const repo = repositories.find(
(r) => r.id === selectedRepo,
);
if (!repo) return null;
if (repo.ssh_key_id) {
const key = sshKeys.find(
(k) => k.id === repo.ssh_key_id,
);
return (
<span className="success-text">
SSH key: {key?.name || "Assigned"}
</span>
);
}
return (
<span className="warning-text">
No SSH key assigned to this repository. Clone mode
requires an SSH key.
</span>
);
})()}
</div>
)}
</>
)}
</div>
)}
{/* Display Name */}
{hasToolType && (
<div className="form-field">