diff --git a/ui/src/pages/ExecutionWorkspaceDetail.tsx b/ui/src/pages/ExecutionWorkspaceDetail.tsx index 99c91ea1cfb..462b0f9bc6b 100644 --- a/ui/src/pages/ExecutionWorkspaceDetail.tsx +++ b/ui/src/pages/ExecutionWorkspaceDetail.tsx @@ -15,7 +15,11 @@ import { issuesApi } from "../api/issues"; import { projectsApi } from "../api/projects"; import { IssuesList } from "../components/IssuesList"; import { PageTabBar } from "../components/PageTabBar"; -import { hasRunningRuntimeServices, WorkspaceRuntimeControls } from "../components/WorkspaceRuntimeControls"; +import { + buildWorkspaceRuntimeControlItems, + WorkspaceRuntimeControls, + type WorkspaceRuntimeControlRequest, +} from "../components/WorkspaceRuntimeControls"; import { useBreadcrumbs } from "../context/BreadcrumbContext"; import { useCompany } from "../context/CompanyContext"; import { queryKeys } from "../lib/queryKeys"; @@ -418,19 +422,19 @@ export function ExecutionWorkspaceDetail() { enabled: Boolean(workspaceId), }); const controlRuntimeServices = useMutation({ - mutationFn: (action: "start" | "stop" | "restart") => - executionWorkspacesApi.controlRuntimeServices(workspace!.id, action), - onSuccess: (result, action) => { + mutationFn: (request: WorkspaceRuntimeControlRequest) => + executionWorkspacesApi.controlRuntimeServices(workspace!.id, request.action, request), + onSuccess: (result, request) => { queryClient.setQueryData(queryKeys.executionWorkspaces.detail(result.workspace.id), result.workspace); queryClient.invalidateQueries({ queryKey: queryKeys.executionWorkspaces.workspaceOperations(result.workspace.id) }); queryClient.invalidateQueries({ queryKey: queryKeys.projects.detail(result.workspace.projectId) }); setErrorMessage(null); setRuntimeActionMessage( - action === "stop" - ? "Runtime services stopped." - : action === "restart" - ? "Runtime services restarted." - : "Runtime services started.", + request.action === "stop" + ? "Runtime service stopped." + : request.action === "restart" + ? "Runtime service restarted." + : "Runtime service started.", ); }, onError: (error) => { @@ -450,7 +454,11 @@ export function ExecutionWorkspaceDetail() { if (!workspace || !form || !initialState) return null; const canStartRuntimeServices = Boolean(effectiveRuntimeConfig) && Boolean(workspace.cwd); - const runtimeServicesRunning = hasRunningRuntimeServices(workspace.runtimeServices); + const runtimeControlItems = buildWorkspaceRuntimeControlItems({ + runtimeConfig: effectiveRuntimeConfig, + runtimeServices: workspace.runtimeServices ?? [], + canStartServices: canStartRuntimeServices, + }); const pendingRuntimeAction = controlRuntimeServices.isPending ? controlRuntimeServices.variables ?? null : null; if (workspaceId && activeTab === null) { @@ -534,46 +542,17 @@ export function ExecutionWorkspaceDetail() { controlRuntimeServices.mutate(action)} + onAction={(request) => controlRuntimeServices.mutate(request)} /> - - {workspace.runtimeServices && workspace.runtimeServices.length > 0 ? ( -
- {workspace.runtimeServices.map((service) => ( -
-
-
-
{service.serviceName}
-
{service.status} · {service.lifecycle}
-
- {service.url ? ( - - {service.url} - - - ) : null} - {service.port ?
Port {service.port}
: null} - {service.command ? : null} - {service.cwd ? : null} -
-
- {service.healthStatus} -
-
- ))} -
- ) : ( -

- {effectiveRuntimeConfig - ? "No runtime services are currently running for this execution workspace." - : "No runtime config is defined for this execution workspace yet."} -

- )} {!errorMessage && runtimeActionMessage ?

{runtimeActionMessage}

: null} @@ -749,7 +728,7 @@ export function ExecutionWorkspaceDetail() {