diff --git a/binderhub/static/js/components/BuilderLauncher.jsx b/binderhub/static/js/components/BuilderLauncher.jsx index bcb8439f5..73718662e 100644 --- a/binderhub/static/js/components/BuilderLauncher.jsx +++ b/binderhub/static/js/components/BuilderLauncher.jsx @@ -11,6 +11,7 @@ import { Spec } from "../spec.js"; * @param {URL} baseUrl * @param {Spec} spec * @param {Terminal} term + * @param {Array} logBuffer * @param {FitAddon} fitAddon * @param {(l: boolean) => void} setIsLaunching * @param {(p: PROGRESS_STATES) => void} setProgressState @@ -20,6 +21,7 @@ async function buildImage( baseUrl, spec, term, + logBuffer, fitAddon, setIsLaunching, setProgressState, @@ -29,12 +31,15 @@ async function buildImage( const image = new BinderRepository(spec.buildSpec, buildEndPointURL); // Clear the last line written, so we start from scratch term.write("\x1b[2K\r"); + logBuffer.length = 0; fitAddon.fit(); for await (const data of image.fetch()) { // Write message to the log terminal if there is a message if (data.message !== undefined) { // Write out all messages to the terminal! term.write(data.message); + // Keep a copy of the message in the logBuffer + logBuffer.push(data.message); // Resize our terminal to make sure it fits messages appropriately fitAddon.fit(); } else { @@ -94,12 +99,19 @@ async function buildImage( * @prop {(t: Terminal) => void} setTerm * @prop {(f: FitAddon) => void} setFitAddon * @prop {boolean} logsVisible + * @prop {Ref>} logBufferRef * @prop {(l: boolean) => void} setLogsVisible * * @param {ImageLogsProps} props * @returns */ -function ImageLogs({ setTerm, setFitAddon, logsVisible, setLogsVisible }) { +function ImageLogs({ + setTerm, + setFitAddon, + logsVisible, + setLogsVisible, + logBufferRef, +}) { const toggleLogsButton = useRef(); useEffect(() => { async function setup() { @@ -133,6 +145,21 @@ function ImageLogs({ setTerm, setFitAddon, logsVisible, setLogsVisible }) { > {logsVisible ? "hide" : "show"} +
{ async function setup() { if (isLaunching) { @@ -174,6 +202,7 @@ export function BuilderLauncher({ baseUrl, spec, term, + logBufferRef.current, fitAddon, setIsLaunching, setProgressState, @@ -191,6 +220,7 @@ export function BuilderLauncher({ setFitAddon={setFitAddon} logsVisible={logsVisible} setLogsVisible={setLogsVisible} + logBufferRef={logBufferRef} />
);