config on overview
This commit is contained in:
parent
75e68f0638
commit
735886ba13
@ -1472,8 +1472,8 @@ export function renderApp(state: AppViewState) {
|
||||
<button class="claw-computer-close" @click=${() => state.toggleClawComputer()}>×</button>
|
||||
</div>
|
||||
<claw-computer-panel
|
||||
.vncUrl=${"127.0.0.1:5901"}
|
||||
.vncToken=${"123456"}
|
||||
.vncUrl=${state.settings.vncWsUrl}
|
||||
.password=${state.settings.vncPassword}
|
||||
></claw-computer-panel>
|
||||
</div>
|
||||
`
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
import RFB from "@novnc/novnc";
|
||||
// ui/src/ui/components/claw-computer-panel.ts
|
||||
import { LitElement, html, css } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
import { customElement, state, property } from "lit/decorators.js";
|
||||
import { createRef, ref, Ref } from "lit/directives/ref.js";
|
||||
// @ts-ignore - noVNC types are not available
|
||||
|
||||
// Compatible with both .default and non-.default versions
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -21,13 +22,16 @@ interface RFBInstance {
|
||||
|
||||
@customElement("claw-computer-panel")
|
||||
export class ClawComputerPanel extends LitElement {
|
||||
@property() vncUrl = "ws://localhost:8081";
|
||||
@property() password = "";
|
||||
|
||||
@state() status = "等待連接...";
|
||||
@state() isConnected = false;
|
||||
@state() isFitted = true;
|
||||
@state() password = "";
|
||||
|
||||
private rfb: RFBInstance | null = null;
|
||||
private screenRef: Ref<HTMLDivElement> = createRef<HTMLDivElement>();
|
||||
private autoConnectAttempted = false;
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
@ -120,7 +124,7 @@ export class ClawComputerPanel extends LitElement {
|
||||
<div class="container">
|
||||
<h2>noVNC - 自動調整版(穩定無錯誤)</h2>
|
||||
<p style="text-align:center; color:#888;">
|
||||
ws://localhost:8081(已轉發到你的 10.75.171.0:25900)
|
||||
${this.vncUrl}(已轉發到你的 10.75.171.0:25900)
|
||||
</p>
|
||||
<div class="controls">
|
||||
<label>VNC 密碼(如果有):</label>
|
||||
@ -152,7 +156,7 @@ export class ClawComputerPanel extends LitElement {
|
||||
}
|
||||
|
||||
private connect = async () => {
|
||||
const url = "ws://localhost:8081";
|
||||
const url = this.vncUrl || "ws://localhost:8081";
|
||||
if (this.rfb) {
|
||||
this.rfb.disconnect();
|
||||
}
|
||||
@ -243,6 +247,14 @@ export class ClawComputerPanel extends LitElement {
|
||||
|
||||
firstUpdated() {
|
||||
window.addEventListener("resize", this.handleResize);
|
||||
|
||||
// Auto-connect if URL is configured
|
||||
if (this.vncUrl) {
|
||||
// Use setTimeout to ensure DOM is fully ready and to allow UI to render first
|
||||
setTimeout(() => {
|
||||
void this.connect();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
|
||||
@ -22,6 +22,9 @@ export type UiSettings = {
|
||||
navWidth: number; // Sidebar width when expanded (240–400px)
|
||||
navGroupsCollapsed: Record<string, boolean>; // Which nav groups are collapsed
|
||||
locale?: string;
|
||||
vncWsUrl?: string;
|
||||
vncPassword?: string;
|
||||
vncTarget?: string;
|
||||
};
|
||||
|
||||
function isViteDevPage(): boolean {
|
||||
@ -135,6 +138,8 @@ export function loadSettings(): UiSettings {
|
||||
navCollapsed: false,
|
||||
navWidth: 220,
|
||||
navGroupsCollapsed: {},
|
||||
vncWsUrl: "ws://localhost:8081",
|
||||
vncTarget: "10.75.171.25900",
|
||||
};
|
||||
|
||||
try {
|
||||
@ -190,6 +195,9 @@ export function loadSettings(): UiSettings {
|
||||
? parsed.navGroupsCollapsed
|
||||
: defaults.navGroupsCollapsed,
|
||||
locale: isSupportedLocale(parsed.locale) ? parsed.locale : undefined,
|
||||
vncWsUrl: typeof parsed.vncWsUrl === "string" ? parsed.vncWsUrl : defaults.vncWsUrl,
|
||||
vncPassword: typeof parsed.vncPassword === "string" ? parsed.vncPassword : undefined,
|
||||
vncTarget: typeof parsed.vncTarget === "string" ? parsed.vncTarget : defaults.vncTarget,
|
||||
};
|
||||
if ("token" in parsed) {
|
||||
persistSettings(settings);
|
||||
@ -219,6 +227,9 @@ function persistSettings(next: UiSettings) {
|
||||
navWidth: next.navWidth,
|
||||
navGroupsCollapsed: next.navGroupsCollapsed,
|
||||
...(next.locale ? { locale: next.locale } : {}),
|
||||
vncWsUrl: next.vncWsUrl,
|
||||
vncPassword: next.vncPassword,
|
||||
vncTarget: next.vncTarget,
|
||||
};
|
||||
localStorage.setItem(KEY, JSON.stringify(persisted));
|
||||
}
|
||||
|
||||
@ -299,24 +299,13 @@ export function renderOverview(props: OverviewProps) {
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 14px;">
|
||||
<button class="btn" @click=${() => props.onConnect()}>${t("common.connect")}</button>
|
||||
<button class="btn" @click=${() => props.onRefresh()}>${t("common.refresh")}</button>
|
||||
<span class="muted">${
|
||||
isTrustedProxy ? t("overview.access.trustedProxy") : t("overview.access.connectHint")
|
||||
}</span>
|
||||
</div>
|
||||
${
|
||||
!props.connected
|
||||
? html`
|
||||
<div class="login-gate__help" style="margin-top: 16px;">
|
||||
<div class="login-gate__help-title">${t("overview.connection.title")}</div>
|
||||
<ol class="login-gate__steps">
|
||||
<li>${t("overview.connection.step1")}<code>openclaw gateway run</code></li>
|
||||
<li>${t("overview.connection.step2")}<code>openclaw dashboard --no-open</code></li>
|
||||
<li>${t("overview.connection.step3")}</li>
|
||||
<li>${t("overview.connection.step4")}<code>openclaw doctor --generate-gateway-token</code></li>
|
||||
</ol>
|
||||
<div class="login-gate" style="margin-top: 24px;">
|
||||
<button class="btn primary large" @click=${props.onConnect}>
|
||||
${t("overview.connection.connect")}
|
||||
</button>
|
||||
<div class="login-gate__docs">
|
||||
${t("overview.connection.docsHint")}
|
||||
<a
|
||||
@ -332,6 +321,47 @@ export function renderOverview(props: OverviewProps) {
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Remote Desktop</div>
|
||||
<div class="card-sub">Configure VNC connection details</div>
|
||||
<div class="ov-access-grid" style="margin-top: 16px;">
|
||||
<label class="field ov-access-grid__full">
|
||||
<span>WebSocket URL</span>
|
||||
<input
|
||||
.value=${props.settings.vncWsUrl ?? ""}
|
||||
@input=${(e: Event) => {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
props.onSettingsChange({ ...props.settings, vncWsUrl: v });
|
||||
}}
|
||||
placeholder="ws://localhost:8081"
|
||||
/>
|
||||
</label>
|
||||
<label class="field ov-access-grid__full">
|
||||
<span>Target (Host:Port)</span>
|
||||
<input
|
||||
.value=${props.settings.vncTarget ?? ""}
|
||||
@input=${(e: Event) => {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
props.onSettingsChange({ ...props.settings, vncTarget: v });
|
||||
}}
|
||||
placeholder="10.75.171.25900"
|
||||
/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Password</span>
|
||||
<input
|
||||
type="password"
|
||||
.value=${props.settings.vncPassword ?? ""}
|
||||
@input=${(e: Event) => {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
props.onSettingsChange({ ...props.settings, vncPassword: v });
|
||||
}}
|
||||
placeholder="VNC Password"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">${t("overview.snapshot.title")}</div>
|
||||
<div class="card-sub">${t("overview.snapshot.subtitle")}</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user