mirror of https://github.com/openclaw/openclaw.git
ui: add onboarding mode for control ui
This commit is contained in:
parent
019726f2d1
commit
447db67b18
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Clawdbot Control</title>
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
<link rel="icon" href="./favicon.ico" sizes="any" />
|
||||
<script type="module" crossorigin src="./assets/index-bYQnHP3a.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BPDeGGxb.css">
|
||||
</head>
|
||||
<body>
|
||||
<clawdbot-app></clawdbot-app>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -37,6 +37,18 @@
|
|||
grid-template-columns: 0px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.shell--onboarding {
|
||||
grid-template-rows: 0 1fr;
|
||||
}
|
||||
|
||||
.shell--onboarding .topbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shell--onboarding .content {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.shell--chat-focus .content {
|
||||
padding-top: 0;
|
||||
gap: 0;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ type GatewayHost = {
|
|||
connected: boolean;
|
||||
hello: GatewayHelloOk | null;
|
||||
lastError: string | null;
|
||||
onboarding?: boolean;
|
||||
eventLogBuffer: EventLogEntry[];
|
||||
eventLog: EventLogEntry[];
|
||||
tab: Tab;
|
||||
|
|
@ -153,6 +154,7 @@ export function handleGatewayEvent(host: GatewayHost, evt: GatewayEventFrame) {
|
|||
}
|
||||
|
||||
if (evt.event === "agent") {
|
||||
if (host.onboarding) return;
|
||||
handleAgentEvent(
|
||||
host as unknown as Parameters<typeof handleAgentEvent>[0],
|
||||
evt.payload as AgentEventPayload | undefined,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ export function renderTab(state: AppViewState, tab: Tab) {
|
|||
|
||||
export function renderChatControls(state: AppViewState) {
|
||||
const sessionOptions = resolveSessionOptions(state.sessionKey, state.sessionsResult);
|
||||
const disableThinkingToggle = state.onboarding;
|
||||
const disableFocusToggle = state.onboarding;
|
||||
const showThinking = state.onboarding ? false : state.settings.chatShowThinking;
|
||||
const focusActive = state.onboarding ? true : state.settings.chatFocusMode;
|
||||
// Refresh icon
|
||||
const refreshIcon = html`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg>`;
|
||||
const focusIcon = html`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h3"></path><path d="M20 7V4h-3"></path><path d="M4 17v3h3"></path><path d="M20 17v3h-3"></path><circle cx="12" cy="12" r="3"></circle></svg>`;
|
||||
|
|
@ -90,26 +94,36 @@ export function renderChatControls(state: AppViewState) {
|
|||
</button>
|
||||
<span class="chat-controls__separator">|</span>
|
||||
<button
|
||||
class="btn btn--sm btn--icon ${state.settings.chatShowThinking ? "active" : ""}"
|
||||
@click=${() =>
|
||||
class="btn btn--sm btn--icon ${showThinking ? "active" : ""}"
|
||||
?disabled=${disableThinkingToggle}
|
||||
@click=${() => {
|
||||
if (disableThinkingToggle) return;
|
||||
state.applySettings({
|
||||
...state.settings,
|
||||
chatShowThinking: !state.settings.chatShowThinking,
|
||||
})}
|
||||
aria-pressed=${state.settings.chatShowThinking}
|
||||
title="Toggle assistant thinking/working output"
|
||||
});
|
||||
}}
|
||||
aria-pressed=${showThinking}
|
||||
title=${disableThinkingToggle
|
||||
? "Disabled during onboarding"
|
||||
: "Toggle assistant thinking/working output"}
|
||||
>
|
||||
🧠
|
||||
</button>
|
||||
<button
|
||||
class="btn btn--sm btn--icon ${state.settings.chatFocusMode ? "active" : ""}"
|
||||
@click=${() =>
|
||||
class="btn btn--sm btn--icon ${focusActive ? "active" : ""}"
|
||||
?disabled=${disableFocusToggle}
|
||||
@click=${() => {
|
||||
if (disableFocusToggle) return;
|
||||
state.applySettings({
|
||||
...state.settings,
|
||||
chatFocusMode: !state.settings.chatFocusMode,
|
||||
})}
|
||||
aria-pressed=${state.settings.chatFocusMode}
|
||||
title="Toggle focus mode (hide sidebar + page header)"
|
||||
});
|
||||
}}
|
||||
aria-pressed=${focusActive}
|
||||
title=${disableFocusToggle
|
||||
? "Disabled during onboarding"
|
||||
: "Toggle focus mode (hide sidebar + page header)"}
|
||||
>
|
||||
${focusIcon}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -105,12 +105,13 @@ export function renderApp(state: AppViewState) {
|
|||
const cronNext = state.cronStatus?.nextWakeAtMs ?? null;
|
||||
const chatDisabledReason = state.connected ? null : "Disconnected from gateway.";
|
||||
const isChat = state.tab === "chat";
|
||||
const chatFocus = isChat && state.settings.chatFocusMode;
|
||||
const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);
|
||||
const showThinking = state.onboarding ? false : state.settings.chatShowThinking;
|
||||
const assistantAvatarUrl = resolveAssistantAvatarUrl(state);
|
||||
const chatAvatarUrl = state.chatAvatarUrl ?? assistantAvatarUrl ?? null;
|
||||
|
||||
return html`
|
||||
<div class="shell ${isChat ? "shell--chat" : ""} ${chatFocus ? "shell--chat-focus" : ""} ${state.settings.navCollapsed ? "shell--nav-collapsed" : ""}">
|
||||
<div class="shell ${isChat ? "shell--chat" : ""} ${chatFocus ? "shell--chat-focus" : ""} ${state.settings.navCollapsed ? "shell--nav-collapsed" : ""} ${state.onboarding ? "shell--onboarding" : ""}">
|
||||
<header class="topbar">
|
||||
<div class="topbar-left">
|
||||
<button
|
||||
|
|
@ -440,7 +441,7 @@ export function renderApp(state: AppViewState) {
|
|||
void refreshChatAvatar(state);
|
||||
},
|
||||
thinkingLevel: state.chatThinkingLevel,
|
||||
showThinking: state.settings.chatShowThinking,
|
||||
showThinking,
|
||||
loading: state.chatLoading,
|
||||
sending: state.chatSending,
|
||||
assistantAvatarUrl: chatAvatarUrl,
|
||||
|
|
@ -455,16 +456,18 @@ export function renderApp(state: AppViewState) {
|
|||
disabledReason: chatDisabledReason,
|
||||
error: state.lastError,
|
||||
sessions: state.sessionsResult,
|
||||
focusMode: state.settings.chatFocusMode,
|
||||
focusMode: chatFocus,
|
||||
onRefresh: () => {
|
||||
state.resetToolStream();
|
||||
return Promise.all([loadChatHistory(state), refreshChatAvatar(state)]);
|
||||
},
|
||||
onToggleFocusMode: () =>
|
||||
onToggleFocusMode: () => {
|
||||
if (state.onboarding) return;
|
||||
state.applySettings({
|
||||
...state.settings,
|
||||
chatFocusMode: !state.settings.chatFocusMode,
|
||||
}),
|
||||
});
|
||||
},
|
||||
onChatScroll: (event) => state.handleChatScroll(event),
|
||||
onDraftChange: (next) => (state.chatMessage = next),
|
||||
onSend: () => state.handleSendChat(),
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export type AppViewState = {
|
|||
settings: UiSettings;
|
||||
password: string;
|
||||
tab: Tab;
|
||||
onboarding: boolean;
|
||||
basePath: string;
|
||||
connected: boolean;
|
||||
theme: ThemeMode;
|
||||
|
|
|
|||
|
|
@ -87,11 +87,21 @@ declare global {
|
|||
|
||||
const injectedAssistantIdentity = resolveInjectedAssistantIdentity();
|
||||
|
||||
function resolveOnboardingMode(): boolean {
|
||||
if (!window.location.search) return false;
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const raw = params.get("onboarding");
|
||||
if (!raw) return false;
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
||||
}
|
||||
|
||||
@customElement("clawdbot-app")
|
||||
export class ClawdbotApp extends LitElement {
|
||||
@state() settings: UiSettings = loadSettings();
|
||||
@state() password = "";
|
||||
@state() tab: Tab = "chat";
|
||||
@state() onboarding = resolveOnboardingMode();
|
||||
@state() connected = false;
|
||||
@state() theme: ThemeMode = this.settings.theme ?? "system";
|
||||
@state() themeResolved: ResolvedTheme = "dark";
|
||||
|
|
|
|||
Loading…
Reference in New Issue