fix: clear the OCI confirmation screen after cancellation

This commit is contained in:
VAIO73
2026-10-21 07:04:41 +00:00
parent 7213fb2553
commit 441c34514d
3 changed files with 15 additions and 5 deletions
@@ -31,7 +31,7 @@ import {
import "xterm/css/xterm.css" import "xterm/css/xterm.css"
import { API_PORT } from "@/lib/api-config" import { API_PORT } from "@/lib/api-config"
import { getTicketedWsUrl } from "@/lib/terminal-ws" import { getTicketedWsUrl } from "@/lib/terminal-ws"
import { scriptCompletion } from "@/lib/script-completion" import { scriptCompletion, scriptCompletionOutput } from "@/lib/script-completion"
import { useT } from "../lib/i18n/provider" import { useT } from "../lib/i18n/provider"
interface WebInteraction { interface WebInteraction {
@@ -203,7 +203,7 @@ const initMessage = {
if (scriptCompletion(exitCode, cancelledExitCode).kind !== "cancelled") termRef.current?.write(event.data) if (scriptCompletion(exitCode, cancelledExitCode).kind !== "cancelled") termRef.current?.write(event.data)
completionReceivedRef.current = true completionReceivedRef.current = true
setIsComplete(true) setIsComplete(true)
termRef.current?.writeln(`\x1b[${scriptCompletion(exitCode, cancelledExitCode).color}m${getCompletionMessage(exitCode)}\x1b[0m`) termRef.current?.writeln(scriptCompletionOutput(exitCode, getCompletionMessage(exitCode), cancelledExitCode))
onCompleteRef.current?.(exitCode) onCompleteRef.current?.(exitCode)
if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete") if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete")
return return
@@ -234,7 +234,7 @@ const initMessage = {
const exitCode = Number(msg.exit_code ?? 1) const exitCode = Number(msg.exit_code ?? 1)
completionReceivedRef.current = true completionReceivedRef.current = true
setIsComplete(true) setIsComplete(true)
termRef.current?.writeln(`\x1b[${scriptCompletion(exitCode, cancelledExitCode).color}m${getCompletionMessage(exitCode)}\x1b[0m`) termRef.current?.writeln(scriptCompletionOutput(exitCode, getCompletionMessage(exitCode), cancelledExitCode))
onCompleteRef.current?.(exitCode) onCompleteRef.current?.(exitCode)
if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete") if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete")
return return
@@ -420,7 +420,7 @@ const initMessage = {
if (scriptCompletion(exitCode, cancelledExitCode).kind !== "cancelled") term.write(event.data) if (scriptCompletion(exitCode, cancelledExitCode).kind !== "cancelled") term.write(event.data)
completionReceivedRef.current = true completionReceivedRef.current = true
setIsComplete(true) setIsComplete(true)
term.writeln(`\x1b[${scriptCompletion(exitCode, cancelledExitCode).color}m${getCompletionMessage(exitCode)}\x1b[0m`) term.writeln(scriptCompletionOutput(exitCode, getCompletionMessage(exitCode), cancelledExitCode))
onCompleteRef.current?.(exitCode) onCompleteRef.current?.(exitCode)
if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete") if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete")
return return
@@ -453,7 +453,7 @@ const initMessage = {
const exitCode = Number(msg.exit_code ?? 1) const exitCode = Number(msg.exit_code ?? 1)
completionReceivedRef.current = true completionReceivedRef.current = true
setIsComplete(true) setIsComplete(true)
term.writeln(`\x1b[${scriptCompletion(exitCode, cancelledExitCode).color}m${getCompletionMessage(exitCode)}\x1b[0m`) term.writeln(scriptCompletionOutput(exitCode, getCompletionMessage(exitCode), cancelledExitCode))
onCompleteRef.current?.(exitCode) onCompleteRef.current?.(exitCode)
if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete") if (ws.readyState === WebSocket.OPEN) ws.close(1000, "script complete")
return return
+8
View File
@@ -12,3 +12,11 @@ export function scriptCompletion(exitCode: number, cancelledExitCode?: number) {
export function shouldRefreshOciAfterCompletion(exitCode?: number) { export function shouldRefreshOciAfterCompletion(exitCode?: number) {
return exitCode !== OCI_CANCELLED_EXIT_CODE return exitCode !== OCI_CANCELLED_EXIT_CODE
} }
export function scriptCompletionOutput(exitCode: number, message: string, cancelledExitCode?: number) {
const completion = scriptCompletion(exitCode, cancelledExitCode)
// Queue RIS with the result so earlier ncurses writes finish before reset.
// A synchronous terminal.reset() could be overwritten by that pending output.
const reset = completion.kind === "cancelled" ? "\x1bc" : ""
return `${reset}\x1b[${completion.color}m${message}\x1b[0m`
}
+2
View File
@@ -44,10 +44,12 @@ for (const handler of handlers) for (const locale of ['en','sk']) for (const fra
if(kind==='cancelled') { if(kind==='cancelled') {
assert.ok(rendered.includes(f.t('scriptTerminal.cancelled'))); assert.ok(rendered.includes(f.t('scriptTerminal.cancelled')));
assert.ok(rendered.includes('\x1b[36m')); assert.ok(rendered.includes('\x1b[36m'));
assert.ok(rendered.startsWith('\x1bc'),'cancel resets the obsolete dialog in the queued output');
assert.ok(!rendered.includes('Script exited with code')); assert.ok(!rendered.includes('Script exited with code'));
assert.ok(!rendered.includes('\x1b[31m')); assert.ok(!rendered.includes('\x1b[31m'));
assert.ok(!rendered.includes(f.t('scriptTerminal.completedSuccessfully'))); assert.ok(!rendered.includes(f.t('scriptTerminal.completedSuccessfully')));
} else { } else {
assert.ok(!rendered.includes('\x1bc'),'success/errors and non-opted-in scripts keep their logs');
assert.ok(rendered.includes(kind==='success'?f.t('scriptTerminal.completedSuccessfully'):f.t('scriptTerminal.completedWithError',{code}))); assert.ok(rendered.includes(kind==='success'?f.t('scriptTerminal.completedSuccessfully'):f.t('scriptTerminal.completedWithError',{code})));
} }
// Worker sends both forms; neither a second frame nor a heartbeat may complete twice. // Worker sends both forms; neither a second frame nor a heartbeat may complete twice.