From d96542f69104fbfd3a3367259ef397f6c00ba12f Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:30:40 -0800 Subject: [PATCH] Rerun Command Button (#1265) Adds a button in widgets with a "cmd" controller that allows the command to be rerun without accessing a context menu. --- docs/docs/customwidgets.mdx | 2 +- frontend/app/view/term/term.tsx | 43 +++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/docs/docs/customwidgets.mdx b/docs/docs/customwidgets.mdx index 899a8d26d..8056377d8 100644 --- a/docs/docs/customwidgets.mdx +++ b/docs/docs/customwidgets.mdx @@ -88,7 +88,7 @@ The `WidgetConfigType` takes the usual options common to all widgets. The `MetaT | Key | Description | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | "view" | A string that specifies the general type of widget. In the case of custom terminal widgets, this must be set to `"term"`. | -| "controller" | A string that specifies the type of command being used. For more persistent shell sessions, set it to "shell". For one off commands, set it to "cmd". Note that it is often possible to achieve the same result through each depending on the command being used. | +| "controller" | A string that specifies the type of command being used. For more persistent shell sessions, set it to "shell". For one off commands, set it to `"cmd"`. When `"cmd"` is set, the widget has an additional refresh button in its header that allows the command to be re-run. | | "cmd" | (optional) When the `"controller"` is set to `"cmd"`, this option provides the actual command to be run. Note that because it is run as a command, there is no shell session unless you are launching a command that contains a shell session itself. Defaults to an empty string. | | "cmd:interactive" | (optional) When the `"controller"` is set to `"term", this boolean adds the interactive flag to the launched terminal. Defaults to false. | | "cmd:login" | (optional) When the `"controller"` is set to `"term"`, this boolean adds the login flag to the term command. Defaults to false. | diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index 23c2333cf..c5914258e 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -61,6 +61,7 @@ class TermViewModel { fontSizeAtom: jotai.Atom; termThemeNameAtom: jotai.Atom; noPadding: jotai.PrimitiveAtom; + endIconButtons: jotai.Atom; constructor(blockId: string, nodeModel: BlockNodeModel) { this.viewType = "term"; @@ -176,6 +177,20 @@ class TermViewModel { }); }); this.noPadding = jotai.atom(true); + this.endIconButtons = jotai.atom((get) => { + const blockData = get(this.blockAtom); + if (blockData?.meta?.["controller"] != "cmd") { + return []; + } + return [ + { + elemtype: "iconbutton", + icon: "refresh", + click: this.forceRestartController.bind(this), + title: "Force Restart Controller", + }, + ]; + }); } setTermMode(mode: "term" | "vdom") { @@ -296,6 +311,20 @@ class TermViewModel { }); } + forceRestartController() { + const termsize = { + rows: this.termRef.current?.terminal?.rows, + cols: this.termRef.current?.terminal?.cols, + }; + const prtn = RpcApi.ControllerResyncCommand(TabRpcClient, { + tabid: globalStore.get(atoms.staticTabId), + blockid: this.blockId, + forcerestart: true, + rtopts: { termsize: termsize }, + }); + prtn.catch((e) => console.log("error controller resync (force restart)", e)); + } + getSettingsMenuItems(): ContextMenuItem[] { const fullConfig = globalStore.get(atoms.fullConfigAtom); const termThemes = fullConfig?.termthemes ?? {}; @@ -354,19 +383,7 @@ class TermViewModel { fullMenu.push({ type: "separator" }); fullMenu.push({ label: "Force Restart Controller", - click: () => { - const termsize = { - rows: this.termRef.current?.terminal?.rows, - cols: this.termRef.current?.terminal?.cols, - }; - const prtn = RpcApi.ControllerResyncCommand(TabRpcClient, { - tabid: globalStore.get(atoms.staticTabId), - blockid: this.blockId, - forcerestart: true, - rtopts: { termsize: termsize }, - }); - prtn.catch((e) => console.log("error controller resync (force restart)", e)); - }, + click: this.forceRestartController.bind(this), }); if (blockData?.meta?.["term:vdomtoolbarblockid"]) { fullMenu.push({ type: "separator" });