refactor: extract dashboard, workspace, tool-types, and tool-configs components (Task 4.3)
- Extract DashboardSummary, ActiveSessionsList, ProjectsSection, QuickCreateForm, RecentSessionsSection from dashboard.tsx (480 → 110 lines) - Extract WorkspaceSidebar from repo-workspace.tsx - Extract ToolTypeList + ToolTypeForm from tool-types.tsx (409 → 135 lines) - Extract ToolConfigList + ToolConfigForm from tool-configs.tsx (391 → 178 lines) - Add use-dashboard-actions hook for shared dashboard action handlers - Update feature barrels with new exports Quality gates: tsc (pass), eslint (pass) Refs: repo-restructure Task 4.3
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
createInstance,
|
||||
startInstance,
|
||||
stopInstance,
|
||||
deleteInstance,
|
||||
recreateInstanceTunnel,
|
||||
} from "../api/sessions";
|
||||
import { updateUserConfig } from "../api/settings";
|
||||
import type { Session } from "../types/session";
|
||||
|
||||
export function useDashboardActions(onRefresh: () => Promise<void>) {
|
||||
const navigate = useNavigate();
|
||||
const [saveState, setSaveState] = useState<"idle" | "saving" | "error">("idle");
|
||||
const [actionBusy, setActionBusy] = useState<string | null>(null);
|
||||
|
||||
const handleCreate = useCallback(
|
||||
async (data: {
|
||||
projectId: string;
|
||||
repoId: string;
|
||||
toolTypeId: string;
|
||||
displayName: string;
|
||||
}) => {
|
||||
setSaveState("saving");
|
||||
try {
|
||||
const instance = await createInstance(
|
||||
data.projectId,
|
||||
data.repoId,
|
||||
data.toolTypeId,
|
||||
data.displayName || undefined,
|
||||
);
|
||||
await startInstance(data.projectId, data.repoId, instance.id);
|
||||
await updateUserConfig({ last_session_id: instance.id });
|
||||
setSaveState("idle");
|
||||
await onRefresh();
|
||||
} catch {
|
||||
setSaveState("error");
|
||||
}
|
||||
},
|
||||
[onRefresh],
|
||||
);
|
||||
|
||||
const handleOpen = useCallback(
|
||||
(session: Session) => {
|
||||
if (session.url) {
|
||||
window.open(session.url, "_blank", "noopener,noreferrer");
|
||||
return;
|
||||
}
|
||||
if (session.tool_type_interfaces.includes("terminal")) {
|
||||
navigate(`/instances/${session.id}/terminal`);
|
||||
return;
|
||||
}
|
||||
navigate(`/projects/${session.project_id}`);
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const handleStop = useCallback(
|
||||
async (session: Session) => {
|
||||
setActionBusy(session.id);
|
||||
try {
|
||||
await stopInstance(session.project_id, session.repository_id, session.id);
|
||||
await onRefresh();
|
||||
} finally {
|
||||
setActionBusy(null);
|
||||
}
|
||||
},
|
||||
[onRefresh],
|
||||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
async (session: Session) => {
|
||||
setActionBusy(session.id);
|
||||
try {
|
||||
await deleteInstance(
|
||||
session.project_id,
|
||||
session.repository_id,
|
||||
session.id,
|
||||
);
|
||||
await onRefresh();
|
||||
} finally {
|
||||
setActionBusy(null);
|
||||
}
|
||||
},
|
||||
[onRefresh],
|
||||
);
|
||||
|
||||
const handleRecreateTunnel = useCallback(
|
||||
async (session: Session) => {
|
||||
setActionBusy(session.id);
|
||||
try {
|
||||
await recreateInstanceTunnel(
|
||||
session.project_id,
|
||||
session.repository_id,
|
||||
session.id,
|
||||
);
|
||||
await onRefresh();
|
||||
} finally {
|
||||
setActionBusy(null);
|
||||
}
|
||||
},
|
||||
[onRefresh],
|
||||
);
|
||||
|
||||
return {
|
||||
saveState,
|
||||
actionBusy,
|
||||
handleCreate,
|
||||
handleOpen,
|
||||
handleStop,
|
||||
handleDelete,
|
||||
handleRecreateTunnel,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user