Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit57e48ea

Browse files
authored
Support for removing workspaces (#10)
- facade for Coder's REST endpoint to remove a workspace- pop-up dailog for user to confirm the workspace removal- add support for status icons and as a bonus Toolbox is now displayingnice animation around the header bar when workspace is starting orstopping-resolves#7 Small note: info and error dialogs created with ToolboxUi#showInfoPopup,ToolboxUi#showYesNoPopup, and ToolboxUi#showOkCancelPopup only appear onthe main page where all environments are listed. JetBrains is addressingthe issue but until then user can interact with the confirmation dialogonly from the front page.
1 parentf2dc464 commit57e48ea

File tree

4 files changed

+83
-11
lines changed

4 files changed

+83
-11
lines changed

‎src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt‎

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.coder.toolbox
33
importcom.coder.toolbox.browser.BrowserUtil
44
importcom.coder.toolbox.models.WorkspaceAndAgentStatus
55
importcom.coder.toolbox.sdk.CoderRestClient
6+
importcom.coder.toolbox.sdk.ex.APIResponseException
67
importcom.coder.toolbox.sdk.v2.models.Workspace
78
importcom.coder.toolbox.sdk.v2.models.WorkspaceAgent
89
importcom.coder.toolbox.util.withPath
@@ -13,9 +14,15 @@ import com.jetbrains.toolbox.api.remoteDev.AbstractRemoteProviderEnvironment
1314
importcom.jetbrains.toolbox.api.remoteDev.EnvironmentVisibilityState
1415
importcom.jetbrains.toolbox.api.remoteDev.environments.EnvironmentContentsView
1516
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateConsumer
17+
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
1618
importcom.jetbrains.toolbox.api.ui.ToolboxUi
1719
importkotlinx.coroutines.CoroutineScope
20+
importkotlinx.coroutines.delay
21+
importkotlinx.coroutines.isActive
1822
importkotlinx.coroutines.launch
23+
importkotlinx.coroutines.withTimeout
24+
importkotlin.time.Duration.Companion.minutes
25+
importkotlin.time.Duration.Companion.seconds
1926

2027
/**
2128
* Represents an agent and workspace combination.
@@ -71,7 +78,7 @@ class CoderRemoteEnvironment(
7178
},
7279
)
7380
actionsList.add(
74-
Action("Stop", enabled= { status.ready()|| status.pending() }) {
81+
Action("Stop", enabled= { status.canStop() }) {
7582
val build= client.stopWorkspace(workspace)
7683
workspace= workspace.copy(latestBuild= build)
7784
update(workspace, agent)
@@ -128,7 +135,46 @@ class CoderRemoteEnvironment(
128135
}
129136

130137
overridefunonDelete() {
131-
throwNotImplementedError()
138+
cs.launch {
139+
// TODO info and cancel pop-ups only appear on the main page where all environments are listed.
140+
// However, #showSnackbar works on other pages. Until JetBrains fixes this issue we are going to use the snackbar
141+
val shouldDelete=if (status.canStop()) {
142+
ui.showOkCancelPopup(
143+
"Delete running workspace?",
144+
"Workspace will be closed and all the information in this workspace will be lost, including all files, unsaved changes and historical.",
145+
"Delete",
146+
"Cancel"
147+
)
148+
}else {
149+
ui.showOkCancelPopup(
150+
"Delete workspace?",
151+
"All the information in this workspace will be lost, including all files, unsaved changes and historical.",
152+
"Delete",
153+
"Cancel"
154+
)
155+
}
156+
if (shouldDelete) {
157+
try {
158+
client.removeWorkspace(workspace)
159+
cs.launch {
160+
withTimeout(5.minutes) {
161+
var workspaceStillExists=true
162+
while (cs.isActive&& workspaceStillExists) {
163+
if (status==WorkspaceAndAgentStatus.DELETING|| status==WorkspaceAndAgentStatus.DELETED) {
164+
workspaceStillExists=false
165+
serviceLocator.getService(EnvironmentUiPageManager::class.java)
166+
.showPluginEnvironmentsPage()
167+
}else {
168+
delay(1.seconds)
169+
}
170+
}
171+
}
172+
}
173+
}catch (e:APIResponseException) {
174+
ui.showErrorInfoPopup(e)
175+
}
176+
}
177+
}
132178
}
133179

134180
/**

‎src/main/kotlin/com/coder/toolbox/models/WorkspaceAndAgentStatus.kt‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.jetbrains.toolbox.api.core.ServiceLocator
99
importcom.jetbrains.toolbox.api.core.ui.color.StateColor
1010
importcom.jetbrains.toolbox.api.remoteDev.states.CustomRemoteEnvironmentState
1111
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
12+
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateIcons
1213
importcom.jetbrains.toolbox.api.remoteDev.states.StandardRemoteEnvironmentState
1314

1415
/**
@@ -59,26 +60,34 @@ enum class WorkspaceAndAgentStatus(val label: String, val description: String) {
5960
* "disconnected" regardless of the label we give that status.
6061
*/
6162
funtoRemoteEnvironmentState(serviceLocator:ServiceLocator):CustomRemoteEnvironmentState {
62-
val stateColor= getStateColor(serviceLocator)
6363
returnCustomRemoteEnvironmentState(
6464
label,
65-
stateColor,
65+
getStateColor(serviceLocator),
6666
ready(),// reachable
6767
// TODO@JB: How does this work? Would like a spinner for pending states.
68-
null,// iconId
68+
getStateIcon()
6969
)
7070
}
7171

7272
privatefungetStateColor(serviceLocator:ServiceLocator):StateColor {
7373
val colorPalette= serviceLocator.getService(EnvironmentStateColorPalette::class.java)
7474

75-
7675
returnif (ready()) colorPalette.getColor(StandardRemoteEnvironmentState.Active)
7776
elseif (canStart()) colorPalette.getColor(StandardRemoteEnvironmentState.Failed)
7877
elseif (pending()) colorPalette.getColor(StandardRemoteEnvironmentState.Activating)
78+
elseif (this==DELETING) colorPalette.getColor(StandardRemoteEnvironmentState.Deleting)
79+
elseif (this==DELETED) colorPalette.getColor(StandardRemoteEnvironmentState.Deleted)
7980
else colorPalette.getColor(StandardRemoteEnvironmentState.Unreachable)
8081
}
8182

83+
privatefungetStateIcon():EnvironmentStateIcons {
84+
returnif (ready())EnvironmentStateIcons.Active
85+
elseif (canStart())EnvironmentStateIcons.Hibernated
86+
elseif (pending())EnvironmentStateIcons.Connecting
87+
elseif (this==DELETING||this==DELETED)EnvironmentStateIcons.Offline
88+
elseEnvironmentStateIcons.NoIcon
89+
}
90+
8291
/**
8392
* Return true if the agent is in a connectable state.
8493
*/
@@ -107,6 +116,11 @@ enum class WorkspaceAndAgentStatus(val label: String, val description: String) {
107116
funcanStart():Boolean=listOf(STOPPED,FAILED,CANCELED)
108117
.contains(this)
109118

119+
/**
120+
* Return true if the workspace can be stopped.
121+
*/
122+
funcanStop():Boolean= ready()|| pending()
123+
110124
// We want to check that the workspace is `running`, the agent is
111125
// `connected`, and the agent lifecycle state is `ready` to ensure the best
112126
// possible scenario for attempting a connection.

‎src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory
3030
importjava.net.HttpURLConnection
3131
importjava.net.ProxySelector
3232
importjava.net.URL
33-
importjava.util.*
33+
importjava.util.UUID
3434
importjavax.net.ssl.X509TrustManager
3535

3636
/**
@@ -229,7 +229,6 @@ open class CoderRestClient(
229229
}
230230

231231
/**
232-
* @throws [APIResponseException].
233232
*/
234233
funstopWorkspace(workspace:Workspace):WorkspaceBuild {
235234
val buildRequest=CreateWorkspaceBuildRequest(null,WorkspaceTransition.STOP)
@@ -240,6 +239,17 @@ open class CoderRestClient(
240239
return buildResponse.body()!!
241240
}
242241

242+
/**
243+
* @throws [APIResponseException] if issues are encountered during deletion
244+
*/
245+
funremoveWorkspace(workspace:Workspace) {
246+
val buildRequest=CreateWorkspaceBuildRequest(null,WorkspaceTransition.DELETE,false)
247+
val buildResponse= retroRestClient.createWorkspaceBuild(workspace.id, buildRequest).execute()
248+
if (buildResponse.code()!=HttpURLConnection.HTTP_CREATED) {
249+
throwAPIResponseException("delete workspace${workspace.name}", url, buildResponse)
250+
}
251+
}
252+
243253
/**
244254
* Start the workspace with the latest template version. Best practice is
245255
* to STOP a workspace before doing an update if it is started.

‎src/main/kotlin/com/coder/toolbox/sdk/v2/models/CreateWorkspaceBuildRequest.kt‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import java.util.UUID
88
data classCreateWorkspaceBuildRequest(
99
// Use to update the workspace to a new template version.
1010
@Json(name="template_version_id")valtemplateVersionID:UUID?,
11-
// Use to startandstop the workspace.
11+
// Use to start, stopanddelete the workspace.
1212
@Json(name="transition")valtransition:WorkspaceTransition,
13+
@Json(name="orphan")varorphan:Boolean? =null
1314
) {
1415
overridefunequals(other:Any?):Boolean {
1516
if (this=== other)returntrue
@@ -19,12 +20,13 @@ data class CreateWorkspaceBuildRequest(
1920

2021
if (templateVersionID!= other.templateVersionID)returnfalse
2122
if (transition!= other.transition)returnfalse
22-
23+
if (orphan!= other.orphan)returnfalse
2324
returntrue
2425
}
2526

2627
overridefunhashCode():Int {
27-
var result= templateVersionID?.hashCode()?:0
28+
var result= orphan?.hashCode()?:0
29+
result=31* result+ (templateVersionID?.hashCode()?:0)
2830
result=31* result+ transition.hashCode()
2931
return result
3032
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp