Skip to content

Commit 1f5f2df

Browse files
authored
improvement: show toast for waiting on stdin (#4854)
![Screenshot 2025-05-08 at 4 39 40 PM](https://github.com/user-attachments/assets/9d32e175-d83a-444f-a0ca-ce8f82ff0e95)
1 parent 63dfa9d commit 1f5f2df

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

.github/workflows/test_cli.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
filters: |
2323
cli:
2424
- '**'
25-
- '!{docs/**,examples/**,README.md,tests/**}'
25+
- '!{docs/**,examples/**,README.md,tests/**,frontend/**}'
2626
2727
build_wheel:
2828
needs: changes

frontend/src/components/editor/output/ConsoleOutput.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ const StdInput = (props: {
177177
{renderText(props.output)}
178178
<Input
179179
data-testid="console-input"
180+
// This is used in <StdinBlockingAlert> to find the input
181+
data-stdin-blocking={true}
180182
type="text"
181183
autoComplete="off"
182184
autoFocus={true}

frontend/src/components/editor/renderers/CellArray.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { SortableCellsProvider } from "@/components/sort/SortableCellsProvider";
5252
import { Column } from "../columns/cell-column";
5353
import type { CellColumnId, CollapsibleTree } from "@/utils/id-tree";
5454
import type { CellId } from "@/core/cells/ids";
55+
import { StdinBlockingAlert } from "../stdin-blocking-alert";
5556

5657
interface CellArrayProps {
5758
mode: AppMode;
@@ -126,6 +127,7 @@ const CellArrayInternal: React.FC<CellArrayProps> = ({
126127
innerClassName="pr-4" // For the floating actions
127128
>
128129
<PackageAlert />
130+
<StdinBlockingAlert />
129131
<NotebookBanner width={appConfig.width} />
130132
<div
131133
className={cn(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/* Copyright 2024 Marimo. All rights reserved. */
2+
3+
import { Banner } from "@/plugins/impl/common/error-banner";
4+
import { Button } from "../ui/button";
5+
import { notebookAtom } from "@/core/cells/cells";
6+
import { atom, useAtomValue } from "jotai";
7+
import { Logger } from "@/utils/Logger";
8+
import { Kbd } from "../ui/kbd";
9+
import { DelayMount } from "../utils/delay-mount";
10+
11+
// Atom to check if there is a cell with unresolved stdin
12+
const hasBlockingStdinAtom = atom((get) => {
13+
const notebook = get(notebookAtom);
14+
15+
// Check each cell in order
16+
for (const cellId of notebook.cellIds.inOrderIds) {
17+
// Check if the cell is idle and has unresolved stdin
18+
const runtime = notebook.cellRuntime[cellId];
19+
if (runtime.status === "idle") {
20+
const hasUnresolvedStdin = runtime.consoleOutputs.some(
21+
(output) => output.channel === "stdin" && output.response === undefined,
22+
);
23+
if (hasUnresolvedStdin) {
24+
return true;
25+
}
26+
}
27+
}
28+
29+
return false;
30+
});
31+
32+
export const StdinBlockingAlert: React.FC = () => {
33+
const hasBlockingStdin = useAtomValue(hasBlockingStdinAtom);
34+
35+
const handleJumpToStdin = () => {
36+
const el = document.querySelector<HTMLElement>("[data-stdin-blocking]");
37+
if (el) {
38+
el.scrollIntoView({ behavior: "smooth", block: "center" });
39+
requestAnimationFrame(() => {
40+
el.focus();
41+
});
42+
} else {
43+
Logger.error("No element with data-stdin-blocking found");
44+
}
45+
};
46+
47+
if (!hasBlockingStdin) {
48+
return null;
49+
}
50+
51+
const body = (
52+
<div className="flex flex-col gap-4 mb-5 fixed top-5 left-1/2 transform -translate-x-1/2 z-[200] opacity-95">
53+
<Banner
54+
kind="info"
55+
className="flex flex-col rounded py-2 px-4 animate-in slide-in-from-top w-fit"
56+
>
57+
<div className="flex justify-between">
58+
<span className="font-bold text-lg flex items-center mb-1">
59+
Program waiting for input
60+
</span>
61+
</div>
62+
<div className="flex flex-col gap-4 justify-between items-start text-muted-foreground text-base">
63+
<div>
64+
<p>
65+
The program is still running, but blocked on{" "}
66+
<Kbd className="inline">stdin</Kbd>.
67+
<Button
68+
variant="link"
69+
className="h-auto font-normal"
70+
onClick={handleJumpToStdin}
71+
>
72+
Jump to the cell
73+
</Button>
74+
</p>
75+
</div>
76+
</div>
77+
</Banner>
78+
</div>
79+
);
80+
81+
// Delay the mount to avoid flickering
82+
return <DelayMount milliseconds={2000}>{body}</DelayMount>;
83+
};

0 commit comments

Comments
 (0)