Adding a restart process button in Pluto

I’m trying to get a SnoopCompile workflow going inside a Pluto notebook. Since SnoopCompile requires a lot of process restarts, it would be nice to have a “Restart” button. I think that this should be possible by sending a CustomEvent to the backend, but I’m unable to locate the current notebook id.

HTML("""
<div>
	<button id="myrestart" href="#">Restart</button>
	
	<script>
		const div = currentScript.parentElement
		const button = div.querySelector("button#myrestart")
		button.onclick = function() { restart_nb() };
		function restart_nb() {
			div.dispatchEvent(
				new CustomEvent("restart_process"),
				{},
				{ notebook_id: div.state.notebook.notebook.id }
			);
		};
		
	</script>
</div>
""")

When clicking the button, this fails on

Uncaught TypeError: Cannot read properties of undefined (reading 'notebook')
    at restart_nb (eval at ga (editor.9e18b711.js:248:175), <anonymous>:12:30)
    at HTMLButtonElement.button.onclick (eval at ga (editor.9e18b711.js:248:175), <anonymous>:7:33)

So, the question is: where I can find the current notebook id?

3 Likes

Not a direct answer to your question but Pluto already has a restart option which gets triggered when you make changes to your environment, maybe have a look into how that works?

1 Like

It’s here. I already looked at it, but notebook is not defined in global Javascript scope.

Answering your question did help out :partying_face: The following code sets the process status to “no_process”. Clicking next to the cell will then show the “Restart required” message:

HTML("""
<!-- the wrapper span -->
<div>
	<button id="myrestart" href="#">Restart</button>
	
	<script>
		const div = currentScript.parentElement
		const button = div.querySelector("button#myrestart")
		console.log(button);
		button.onclick = function() { restart_nb() };
		console.log(div.dispatchEvent)
		function restart_nb() {
			console.log("Send event");
			editor_state.notebook.process_status = "no_process";
			window.dispatchEvent(
				new CustomEvent("restart_process"),
				{},
				{ notebook_id: editor_state.notebook.id }
			);
		};
	</script>
</div>
""")

It’s something

3 Likes

Here you go!! Based on what @rikh started, with changes:

  • use the react setter, editor_state_set instead of modifying react state directly
  • wait for the change to take effect, then search for the button an .click() it :slight_smile:

(This is not official API so it might break in a future patch.)

html"""
<script>
	const button = document.createElement("button")

	button.addEventListener("click", () => {
		editor_state_set(old_state => ({
			notebook: {
				...old_state.notebook,
				process_status: "no_process",
			},
		})).then(() => {
			window.requestAnimationFrame(() => {
				document.querySelector("#process_status a").click()
			})
		})
	})
	button.innerText = "Restart process"

	return button
</script>
"""
4 Likes

It would be nice to have that in a package, e.g. PlutoUI could be good place?

IMO, restarting and killing the current notebook is basic functionality and should be included in Pluto itself.

Right now the only way to shut down the notebook seems to be to click the Pluto logo and click the X/Close button in the list of running notebooks. This is unintuitive (why go back to the list of all running notebooks?) and takes too many clicks.

1 Like