import type { TemplateResult } from "lit";
import type { HtmlTemplateTag, PiWebComponentStatus, PiWebPlugin, PiWebStatusResponse, PluginRuntimeState, WorkspacePanelTerminal } from "@jmfederico/pi-web/plugin-api";
import { additionalCommands, formatVersion, installationLabel, messageCount, recommendedCommand, shouldShowUpdatesPanel, statusFor } from "./updatesLogic.js";
function runCommandInTerminal(terminal: WorkspacePanelTerminal, label: string, command: string): void {
void terminal.runCommand({
title: label,
command,
open: true,
metadata: { "pi.plugin": "updates" },
}).catch((error: unknown) => {
console.error(`Updates plugin failed to run "${label}"`, error);
});
}
function renderComponent(html: HtmlTemplateTag, component: PiWebComponentStatus): TemplateResult {
const status = !component.available
? "unavailable"
: component.stale
? "restart needed"
: "current";
return html`
${component.label}
${status}
running ${formatVersion(component.runtimeVersion)} · installed ${formatVersion(component.installedVersion)}
${installationLabel(component.installation)}${component.installation?.path === undefined ? "" : ` · ${component.installation.path}`}
`;
}
function renderCommandActions(html: HtmlTemplateTag, terminal: WorkspacePanelTerminal | undefined, label: string, command: string): TemplateResult {
return html`
${terminal === undefined ? null : html``}
`;
}
function renderCommand(html: HtmlTemplateTag, terminal: WorkspacePanelTerminal | undefined, label: string, command: string): TemplateResult {
return html`
${label}
${command}
${renderCommandActions(html, terminal, label, command)}
`;
}
function renderCommands(html: HtmlTemplateTag, terminal: WorkspacePanelTerminal | undefined, status: PiWebStatusResponse): TemplateResult | undefined {
const recommended = recommendedCommand(status);
const additional = additionalCommands(status, recommended);
if (recommended === undefined && additional.length === 0) return undefined;
return html`
${recommended === undefined ? null : html`
Recommended
Run this one command to bring this installation fully up to date. Nothing else is required.
${renderCommand(html, terminal, recommended.label, recommended.command)}
`}
${additional.length === 0 ? null : html`
${recommended === undefined ? "Suggested commands" : "Additional commands (optional)"}
${recommended === undefined ? null : html`Only needed for finer control, such as restarting a single service.
`}
${additional.map((entry) => renderCommand(html, terminal, entry.label, entry.command))}
`}
`;
}
function renderUpdatesPanel(html: HtmlTemplateTag, terminal: WorkspacePanelTerminal | undefined, state: PluginRuntimeState | undefined): TemplateResult {
const status = statusFor(state);
if (status === undefined) {
return html`
Checking PI WEB update status…
`;
}
const messages = status.messages;
return html`
${messages.length === 0 ? html`No PI WEB update or restart messages.
` : messages.map((message) => html`
${message.title}${message.severity}
${message.body}
${message.command === undefined ? null : html`
${message.command}
${renderCommandActions(html, terminal, message.title, message.command)}
`}
`)}
Installed services
${renderComponent(html, status.components.web)}
${renderComponent(html, status.components.sessiond)}
${renderCommands(html, terminal, status)}
`;
}
const plugin: PiWebPlugin = {
apiVersion: 1,
name: "Updates",
activate: ({ html, svg }) => ({
contributions: {
workspacePanels: [
{
id: "workspace.updates",
title: "Updates",
icon: svg`
`,
order: 100,
visible: (context) => shouldShowUpdatesPanel(context.state),
badge: (context) => {
const count = messageCount(context.state);
return count > 0 ? count : undefined;
},
render: (context) => renderUpdatesPanel(html, context.terminal, context.state),
},
],
},
}),
};
export default plugin;