Archived
refactor: simplify workspace panel terminal flow
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { Workspace } from "@jmfederico/pi-web/plugin-api";
|
||||
import { ACTIONS_CONFIG_PATH, type WorkspaceAction } from "./config.js";
|
||||
import { createWorkspaceTerminal, sendTerminalCommand } from "./terminalDispatcher.js";
|
||||
import { openTerminalPanel, requestPiWebRender } from "./piWebPrivateUi.js";
|
||||
import { requestPiWebRender } from "./piWebPrivateUi.js";
|
||||
import { loadWorkspaceActionsConfig, type WorkspaceActionsConfigLoadResult } from "./workspaceActionsClient.js";
|
||||
|
||||
export const actionsPanelTagName = "pi-web-actions-panel";
|
||||
@@ -94,7 +94,7 @@ class PiWebActionsPanel extends HTMLElement {
|
||||
}
|
||||
|
||||
this.root.querySelector("button[data-open-terminal]")?.addEventListener("click", () => {
|
||||
this.openWorkspaceTerminal(workspace);
|
||||
this.openWorkspaceTerminal();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class PiWebActionsPanel extends HTMLElement {
|
||||
if (state.kind === "unavailable") return `${renderUnavailableState(state)}${this.renderStatus()}`;
|
||||
if (state.config.actions.length === 0) return `<p class="muted">No actions configured in ${escapeHtml(ACTIONS_CONFIG_PATH)}.</p>${this.renderStatus()}`;
|
||||
return `
|
||||
<p class="muted">Actions create a new workspace terminal, send the command, then switch to the Terminal tab. Edit ${escapeHtml(ACTIONS_CONFIG_PATH)} and click Refresh to reload.</p>
|
||||
<p class="muted">Actions create a new workspace terminal, send the command, then switch to that terminal. Edit ${escapeHtml(ACTIONS_CONFIG_PATH)} and click Refresh to reload.</p>
|
||||
${renderActionGroups(state.config.actions, this.runningActionId)}
|
||||
${this.renderStatus()}
|
||||
`;
|
||||
@@ -148,7 +148,7 @@ class PiWebActionsPanel extends HTMLElement {
|
||||
};
|
||||
this.runningActionId = undefined;
|
||||
this.render();
|
||||
this.openWorkspaceTerminal(workspace, terminal.id);
|
||||
this.openWorkspaceTerminal(terminal.id);
|
||||
} catch (error) {
|
||||
this.runningActionId = undefined;
|
||||
this.status = { kind: "error", message: error instanceof Error ? error.message : String(error) };
|
||||
@@ -156,13 +156,14 @@ class PiWebActionsPanel extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
private openWorkspaceTerminal(workspace: Workspace, terminalId?: string): void {
|
||||
if (this.openTerminalValue !== undefined) {
|
||||
if (terminalId === undefined) this.openTerminalValue();
|
||||
else this.openTerminalValue({ terminalId });
|
||||
private openWorkspaceTerminal(terminalId?: string): void {
|
||||
if (this.openTerminalValue === undefined) {
|
||||
this.status = { kind: "error", message: "This Pi Web version does not provide terminal navigation to plugins." };
|
||||
this.render();
|
||||
return;
|
||||
}
|
||||
openTerminalPanel(workspace, terminalId);
|
||||
if (terminalId === undefined) this.openTerminalValue();
|
||||
else this.openTerminalValue({ terminalId });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,66 +1,12 @@
|
||||
import type { Workspace } from "@jmfederico/pi-web/plugin-api";
|
||||
import { terminalToolId, type TerminalInfo } from "./terminalDispatcher.js";
|
||||
|
||||
interface TerminalPanelElement {
|
||||
terminals: TerminalInfo[];
|
||||
selectTerminal: (terminalId: string) => void;
|
||||
}
|
||||
|
||||
interface Updatable {
|
||||
requestUpdate: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private Pi Web UI fallback used while the plugin API is still being dogfooded.
|
||||
* The current host provides a panel `openTerminal` helper; keep this fallback contained
|
||||
* for older hosts and replace/remove it once the public helper is required.
|
||||
*/
|
||||
export function openTerminalPanel(workspace: Workspace, terminalId?: string): void {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set("project", workspace.projectId);
|
||||
url.searchParams.set("workspace", workspace.id);
|
||||
url.searchParams.set("tool", terminalToolId);
|
||||
url.searchParams.set("view", terminalToolId);
|
||||
window.history.pushState({}, "", url);
|
||||
dispatchPopState();
|
||||
if (terminalId !== undefined) selectTerminalWhenAvailable(terminalId);
|
||||
}
|
||||
|
||||
export function requestPiWebRender(): void {
|
||||
const app = document.querySelector("pi-web-app");
|
||||
if (isUpdatable(app)) app.requestUpdate();
|
||||
}
|
||||
|
||||
function dispatchPopState(): void {
|
||||
if (typeof PopStateEvent === "function") {
|
||||
window.dispatchEvent(new PopStateEvent("popstate"));
|
||||
return;
|
||||
}
|
||||
window.dispatchEvent(new Event("popstate"));
|
||||
}
|
||||
|
||||
function selectTerminalWhenAvailable(terminalId: string, attempt = 0): void {
|
||||
const terminalPanel = findTerminalPanel();
|
||||
const terminals = terminalPanel?.terminals ?? [];
|
||||
const hasTerminal = terminals.some((terminal) => terminal.id === terminalId);
|
||||
|
||||
if (terminalPanel !== undefined && hasTerminal) {
|
||||
terminalPanel.selectTerminal(terminalId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attempt < 50) window.setTimeout(() => { selectTerminalWhenAvailable(terminalId, attempt + 1); }, 150);
|
||||
}
|
||||
|
||||
function findTerminalPanel(): TerminalPanelElement | undefined {
|
||||
const panel = document.querySelector("workspace-panel")?.shadowRoot?.querySelector("terminal-panel");
|
||||
return isTerminalPanelElement(panel) ? panel : undefined;
|
||||
}
|
||||
|
||||
function isTerminalPanelElement(value: unknown): value is TerminalPanelElement {
|
||||
return isRecord(value) && Array.isArray(value["terminals"]) && typeof value["selectTerminal"] === "function";
|
||||
}
|
||||
|
||||
function isUpdatable(value: unknown): value is Updatable {
|
||||
return isRecord(value) && typeof value["requestUpdate"] === "function";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Workspace } from "@jmfederico/pi-web/plugin-api";
|
||||
|
||||
export const terminalToolId = "core:workspace.terminal";
|
||||
export const actionTerminalCols = 120;
|
||||
export const actionTerminalRows = 32;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user