diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt index c3e5f64..bd20b23 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt @@ -71,7 +71,7 @@ class CoderRemoteEnvironment( }, ) actionsList.add( - Action("Stop", enabled = { status.ready() || status.pending() }) { + Action("Stop", enabled = { status.canStop() }) { val build = client.stopWorkspace(workspace) workspace = workspace.copy(latestBuild = build) update(workspace, agent) @@ -128,7 +128,32 @@ class CoderRemoteEnvironment( } override fun onDelete() { - throw NotImplementedError() + cs.launch { + // TODO info and cancel pop-ups only appear on the main page where all environments are listed. + // However, #showSnackbar works on other pages. Until JetBrains fixes this issue we are going to use the snackbar + val shouldDelete = if (status.canStop()) { + ui.showOkCancelPopup( + "Delete running workspace?", + "Workspace will be closed and all the information in this workspace will be lost, including all files, unsaved changes and historical.", + "Delete", + "Cancel" + ) + } else { + ui.showOkCancelPopup( + "Delete workspace?", + "All the information in this workspace will be lost, including all files, unsaved changes and historical.", + "Delete", + "Cancel" + ) + } + if (shouldDelete) { + if (status.canStop()) { + client.stopWorkspace(workspace) + } + + client.removeWorkspace(workspace) + } + } } /** diff --git a/src/main/kotlin/com/coder/toolbox/models/WorkspaceAndAgentStatus.kt b/src/main/kotlin/com/coder/toolbox/models/WorkspaceAndAgentStatus.kt index 63bf37f..12ef4ca 100644 --- a/src/main/kotlin/com/coder/toolbox/models/WorkspaceAndAgentStatus.kt +++ b/src/main/kotlin/com/coder/toolbox/models/WorkspaceAndAgentStatus.kt @@ -107,6 +107,11 @@ enum class WorkspaceAndAgentStatus(val label: String, val description: String) { fun canStart(): Boolean = listOf(STOPPED, FAILED, CANCELED) .contains(this) + /** + * Return true if the workspace can be stopped. + */ + fun canStop(): Boolean = ready() || pending() + // We want to check that the workspace is `running`, the agent is // `connected`, and the agent lifecycle state is `ready` to ensure the best // possible scenario for attempting a connection. diff --git a/src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt b/src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt index 4f4f7e0..371c818 100644 --- a/src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt +++ b/src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt @@ -30,7 +30,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory import java.net.HttpURLConnection import java.net.ProxySelector import java.net.URL -import java.util.* +import java.util.UUID import javax.net.ssl.X509TrustManager /** @@ -229,7 +229,6 @@ open class CoderRestClient( } /** - * @throws [APIResponseException]. */ fun stopWorkspace(workspace: Workspace): WorkspaceBuild { val buildRequest = CreateWorkspaceBuildRequest(null, WorkspaceTransition.STOP) @@ -240,6 +239,17 @@ open class CoderRestClient( return buildResponse.body()!! } + /** + * @throws [APIResponseException] if issues are encountered during deletion + */ + fun removeWorkspace(workspace: Workspace) { + val buildRequest = CreateWorkspaceBuildRequest(null, WorkspaceTransition.DELETE, false) + val buildResponse = retroRestClient.createWorkspaceBuild(workspace.id, buildRequest).execute() + if (buildResponse.code() != HttpURLConnection.HTTP_CREATED) { + throw APIResponseException("delete workspace ${workspace.name}", url, buildResponse) + } + } + /** * Start the workspace with the latest template version. Best practice is * to STOP a workspace before doing an update if it is started. diff --git a/src/main/kotlin/com/coder/toolbox/sdk/v2/models/CreateWorkspaceBuildRequest.kt b/src/main/kotlin/com/coder/toolbox/sdk/v2/models/CreateWorkspaceBuildRequest.kt index 65e310c..6b59529 100644 --- a/src/main/kotlin/com/coder/toolbox/sdk/v2/models/CreateWorkspaceBuildRequest.kt +++ b/src/main/kotlin/com/coder/toolbox/sdk/v2/models/CreateWorkspaceBuildRequest.kt @@ -8,8 +8,9 @@ import java.util.UUID data class CreateWorkspaceBuildRequest( // Use to update the workspace to a new template version. @Json(name = "template_version_id") val templateVersionID: UUID?, - // Use to start and stop the workspace. + // Use to start, stop and delete the workspace. @Json(name = "transition") val transition: WorkspaceTransition, + @Json(name = "orphan") var orphan: Boolean? = null ) { override fun equals(other: Any?): Boolean { if (this === other) return true