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

Commit164146c

Browse files
feat(site): Show update confirmation dialog (#7420)
1 parent6d24f7c commit164146c

File tree

8 files changed

+98
-27
lines changed

8 files changed

+98
-27
lines changed

‎site/src/components/Dialogs/Dialog.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export const DialogActionButtons: React.FC<DialogActionButtonsProps> = ({
6565
{onConfirm&&(
6666
<LoadingButton
6767
fullWidth
68+
data-testid="confirm-button"
6869
variant="contained"
6970
onClick={onConfirm}
7071
color={typeToColor(type)}

‎site/src/components/Resources/AgentRow.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ export const AgentRow: FC<AgentRowProps> = ({
114114
useEffect(()=>{
115115
// We only want to fetch logs when they are actually shown,
116116
// otherwise we can make a lot of requests that aren't necessary.
117-
if(showStartupLogs){
117+
if(showStartupLogs&&logsMachine.can("FETCH_STARTUP_LOGS")){
118118
sendLogsEvent("FETCH_STARTUP_LOGS")
119119
}
120-
},[sendLogsEvent,showStartupLogs])
120+
},[logsMachine,sendLogsEvent,showStartupLogs])
121121
constlogListRef=useRef<List>(null)
122122
constlogListDivRef=useRef<HTMLDivElement>(null)
123123
conststartupLogs=useMemo(()=>{

‎site/src/components/WorkspaceActions/Buttons.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const UpdateButton: FC<PropsWithChildren<WorkspaceAction>> = ({
2121

2222
return(
2323
<Button
24+
data-testid="workspace-update-button"
2425
variant="outlined"
2526
startIcon={<CloudQueueIcon/>}
2627
onClick={handleAction}

‎site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import{screen}from"@testing-library/react"
22
importWSfrom"jest-websocket-mock"
3-
import{
4-
MockWorkspace,
5-
MockWorkspaceBuild,
6-
renderWithAuth,
7-
}from"../../testHelpers/renderHelpers"
3+
import{renderWithAuth}from"../../testHelpers/renderHelpers"
84
import{WorkspaceBuildPage}from"./WorkspaceBuildPage"
5+
import{MockWorkspace,MockWorkspaceBuild}from"testHelpers/entities"
96

107
describe("WorkspaceBuildPage",()=>{
118
test("the mock server seamlessly handles JSON protocols",async()=>{

‎site/src/pages/WorkspacePage/WorkspacePage.test.tsx

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ const { t } = i18next
3535
constrenderWorkspacePage=async()=>{
3636
jest.spyOn(api,"getTemplate").mockResolvedValueOnce(MockTemplate)
3737
jest.spyOn(api,"getTemplateVersionRichParameters").mockResolvedValueOnce([])
38+
jest.spyOn(api,"watchStartupLogs").mockImplementation((_,options)=>{
39+
options.onDone()
40+
returnnewWebSocket("")
41+
})
3842
renderWithAuth(<WorkspacePage/>,{
3943
route:`/@${MockWorkspace.owner_name}/${MockWorkspace.name}`,
4044
path:"/@:username/:workspace",
@@ -188,22 +192,32 @@ describe("WorkspacePage", () => {
188192
})
189193

190194
it("requests an update when the user presses Update",async()=>{
195+
// Mocks
191196
jest
192197
.spyOn(api,"getWorkspaceByOwnerAndName")
193198
.mockResolvedValueOnce(MockOutdatedWorkspace)
199+
194200
constupdateWorkspaceMock=jest
195201
.spyOn(api,"updateWorkspace")
196202
.mockResolvedValueOnce(MockWorkspaceBuild)
197203

198-
awaittestButton(
199-
t("actionButton.update",{ns:"workspacePage"}),
200-
updateWorkspaceMock,
201-
)
204+
// Render
205+
awaitrenderWorkspacePage()
206+
207+
// Actions
208+
constuser=userEvent.setup()
209+
awaituser.click(screen.getByTestId("workspace-update-button"))
210+
constconfirmButton=awaitscreen.findByTestId("confirm-button")
211+
awaituser.click(confirmButton)
212+
213+
// Assertions
214+
awaitwaitFor(()=>{
215+
expect(updateWorkspaceMock).toBeCalled()
216+
})
202217
})
203218

204219
it("updates the parameters when they are missing during update",async()=>{
205-
// Setup mocks
206-
constuser=userEvent.setup()
220+
// Mocks
207221
jest
208222
.spyOn(api,"getWorkspaceByOwnerAndName")
209223
.mockResolvedValueOnce(MockOutdatedWorkspace)
@@ -215,23 +229,24 @@ describe("WorkspacePage", () => {
215229
MockTemplateVersionParameter2,
216230
]),
217231
)
218-
// Render page and wait for it to be loaded
219-
renderWithAuth(<WorkspacePage/>,{
220-
route:`/@${MockWorkspace.owner_name}/${MockWorkspace.name}`,
221-
path:"/@:username/:workspace",
222-
})
223-
awaitwaitForLoaderToBeRemoved()
224-
// Click on theupdatebutton
225-
constworkspaceActions=screen.getByTestId("workspace-actions")
226-
awaituser.click(
227-
within(workspaceActions).getByRole("button",{name:"Update"}),
228-
)
232+
233+
// Render
234+
awaitrenderWorkspacePage()
235+
236+
// Actions
237+
constuser=userEvent.setup()
238+
awaituser.click(screen.getByTestId("workspace-update-button"))
239+
constconfirmButton=awaitscreen.findByTestId("confirm-button")
240+
awaituser.click(confirmButton)
241+
242+
// The update was called
229243
awaitwaitFor(()=>{
230244
expect(api.updateWorkspace).toBeCalled()
231-
// We want to clear this mock to use it later
232245
updateWorkspaceSpy.mockClear()
233246
})
234-
// Fill the parameters and send the form
247+
248+
// After trying to update, a new dialog asking for missed parameters should
249+
// be displayed and filled
235250
constdialog=awaitscreen.findByTestId("dialog")
236251
constfirstParameterInput=within(dialog).getByLabelText(
237252
MockTemplateVersionParameter1.name,
@@ -246,6 +261,7 @@ describe("WorkspacePage", () => {
246261
awaituser.clear(secondParameterInput)
247262
awaituser.type(secondParameterInput,"2")
248263
awaituser.click(within(dialog).getByRole("button",{name:"Update"}))
264+
249265
// Check if the update was called using the values from the form
250266
awaitwaitFor(()=>{
251267
expect(api.updateWorkspace).toBeCalledWith(MockOutdatedWorkspace,[

‎site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { ChangeVersionDialog } from "./ChangeVersionDialog"
3131
import{useQuery}from"@tanstack/react-query"
3232
import{getTemplateVersions}from"api/api"
3333
import{useRestartWorkspace}from"./hooks"
34+
import{ConfirmDialog}from"components/Dialogs/ConfirmDialog/ConfirmDialog"
3435

3536
interfaceWorkspaceReadyPageProps{
3637
workspaceState:StateFrom<typeofworkspaceMachine>
@@ -76,6 +77,7 @@ export const WorkspaceReadyPage = ({
7677
queryFn:()=>getTemplateVersions(workspace.template_id),
7778
enabled:changeVersionDialogOpen,
7879
})
80+
const[isConfirmingUpdate,setIsConfirmingUpdate]=useState(false)
7981

8082
const{
8183
mutate:restartWorkspace,
@@ -132,7 +134,7 @@ export const WorkspaceReadyPage = ({
132134
handleStop={()=>workspaceSend({type:"STOP"})}
133135
handleRestart={()=>restartWorkspace(workspace)}
134136
handleDelete={()=>workspaceSend({type:"ASK_DELETE"})}
135-
handleUpdate={()=>workspaceSend({type:"UPDATE"})}
137+
handleUpdate={()=>setIsConfirmingUpdate(true)}
136138
handleCancel={()=>workspaceSend({type:"CANCEL"})}
137139
handleSettings={()=>navigate("settings")}
138140
handleBuildRetry={()=>workspaceSend({type:"RETRY_BUILD"})}
@@ -198,6 +200,19 @@ export const WorkspaceReadyPage = ({
198200
})
199201
}}
200202
/>
203+
<ConfirmDialog
204+
type="info"
205+
hideCancel={false}
206+
open={isConfirmingUpdate}
207+
onConfirm={()=>{
208+
workspaceSend({type:"UPDATE"})
209+
setIsConfirmingUpdate(false)
210+
}}
211+
onClose={()=>setIsConfirmingUpdate(false)}
212+
title="Confirm update"
213+
confirmText="Update"
214+
description="Are you sure you want to update your workspace? Updating your workspace will stop all running processes and delete non-persistent data."
215+
/>
201216
</>
202217
)
203218
}

‎site/src/testHelpers/entities.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,3 +1639,36 @@ export const MockDeploymentStats: TypesGen.DeploymentStats = {
16391639
tx_bytes:36113513253,
16401640
},
16411641
}
1642+
1643+
exportconstMockDeploymentSSH:TypesGen.SSHConfigResponse={
1644+
hostname_prefix:" coder.",
1645+
ssh_config_options:{},
1646+
}
1647+
1648+
exportconstMockStartupLogs:TypesGen.WorkspaceAgentStartupLog[]=[
1649+
{
1650+
id:166663,
1651+
created_at:"2023-05-04T11:30:41.402072Z",
1652+
output:"+ curl -fsSL https://code-server.dev/install.sh",
1653+
level:"info",
1654+
},
1655+
{
1656+
id:166664,
1657+
created_at:"2023-05-04T11:30:41.40228Z",
1658+
output:
1659+
"+ sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.8.3",
1660+
level:"info",
1661+
},
1662+
{
1663+
id:166665,
1664+
created_at:"2023-05-04T11:30:42.590731Z",
1665+
output:"Ubuntu 22.04.2 LTS",
1666+
level:"info",
1667+
},
1668+
{
1669+
id:166666,
1670+
created_at:"2023-05-04T11:30:42.593686Z",
1671+
output:"Installing v4.8.3 of the amd64 release from GitHub.",
1672+
level:"info",
1673+
},
1674+
]

‎site/src/testHelpers/handlers.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,12 @@ export const handlers = [
385385
)
386386
},
387387
),
388+
389+
rest.get("/api/v2/deployment/ssh",(_,res,ctx)=>{
390+
returnres(ctx.status(200),ctx.json(M.MockDeploymentSSH))
391+
}),
392+
393+
rest.get("/api/v2/workspaceagents/:agent/startup-logs",(_,res,ctx)=>{
394+
returnres(ctx.status(200),ctx.json(M.MockStartupLogs))
395+
}),
388396
]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp