Skip to content

Dashboard: preview widget β€” embed a live URL with reload + viewport controls#101334

Closed
100yenadmin wants to merge 5 commits into
openclaw:mainfrom
100yenadmin:feat/dashboard-preview-widget
Closed

Dashboard: preview widget β€” embed a live URL with reload + viewport controls#101334
100yenadmin wants to merge 5 commits into
openclaw:mainfrom
100yenadmin:feat/dashboard-preview-widget

Conversation

@100yenadmin

Copy link
Copy Markdown
Contributor

A live preview panel in the dashboard: embed a running dev server or a deployed URL, with reload and device-frame controls.

Closes #101138 (phase 1). Stacked on #101098 β€” targets main with a cumulative diff; review the new preview widget files as the delta.

What problem this solves

Operators and maintainers have asked for a browser/preview panel in the dashboard for a long time (#27574). This delivers phase 1: a trusted builtin:preview widget that renders a URL inside the same sandboxed embed frame the dashboard already uses, with reload + viewport controls β€” so a preview is just another widget an agent or human can place.

What's in this PR

  • A new builtin:preview widget (ui/src/lib/dashboard/widgets/preview.ts) cloned from iframe-embed, reusing its sandbox + external-URL policy unchanged.
  • Chrome: a reload control, and desktop / tablet / mobile viewport presets that constrain the frame width (default via a widget prop).
  • Registered in BUILTIN_WIDGET_RENDERERS; preview added to BUILTIN_KIND_PATTERN.
  • Unit tests: renders the bound URL sandboxed, reload re-sets the frame src, the viewport switch resizes the frame, and the sandbox + external-URL policy match iframe-embed. The UI dashboard suite (100 tests) is green.

Scope

Phase 1 only β€” embed + reload + viewport. Phase 2 (agent-driven dev-server lifecycle + hot-reload) and phase 3 (browser-backed console/network/screenshot so the agent sees its own preview) are follow-on PRs tracked on #101138.

How it works

The preview widget reuses resolveEmbedSandbox and the external-URL gating from iframe-embed verbatim β€” it does not weaken the sandbox. The URL comes from the same static/rpc binding path every builtin uses. The added chrome (reload, viewport) is pure view state around the existing sandboxed frame.

Note: no new dependency β€” pnpm-lock.yaml is unchanged. The diff includes regenerated i18n locale bundles for the new dashboard.widget.preview.* keys (via the repo's ui:i18n:sync locale workflow); those generated files can be skipped in review.

Real behavior proof

Behavior or issue addressed: The dashboard has no preview/browser panel (#27574); there's no first-class way to watch a running dev server or a deployed URL inside a workspace. This adds a trusted builtin:preview widget with reload + viewport controls, reusing the existing sandboxed embed frame.
Evidence: pnpm vitest run src/lib/dashboard β†’ 100 passed (the preview widget renders the bound URL in a sandboxed frame, the reload control re-sets src, viewport buttons swap the frame width, and the sandbox + external-URL policy match iframe-embed); pnpm ui:build green; oxlint clean; pnpm ui:i18n:check clean after regenerating the locale bundles.

Eva added 5 commits July 6, 2026 23:57
New bundled plugin `extensions/dashboard`: a gateway-owned workspace
document (atomic JSON store with undo, size caps, schema validation),
14 `dashboard.*` gateway methods with change broadcasts, an
`openclaw dashboard` CLI, and 14 `dashboard_*` agent tools β€” all sharing
one validated store so humans, the CLI, and agents mutate the dashboard
through the same guarded path. Layout is data; no core changes.

Part of the modular-dashboard series (backend layer).
… (PR2)

The Workspaces bundled tab view for the dashboard plugin: tab strip, grid
with pointer drag/resize/collapse, the 9 builtin widgets + Overview-as-data
default workspace, and the UX polish (themed dialogs, page header, onboarding,
humane error cards, skeletons, (custom) suffix strip).

Wires the plugin's Control UI descriptor (registerControlUiDescriptor) and the
BUNDLED_TAB_VIEWS "dashboard/workspaces" entry, plus the #6 breadcrumb label
(app-host -> app-topbar -> dashboard-header currentLabel) so "Plugin" reads
"Workspaces".

Custom-widget (custom:<name>) rendering is the sandboxed-host feature landing in
the follow-up PR: this layer ships the TRUSTED widget-cell (builtin dispatch +
neutral placeholder for custom kinds, no iframe) and the view without the
manifest/custom-host plumbing, so it builds with no L5 files present.

i18n: en.ts carries all dashboard.* keys; non-English bundles regenerated with
English fallbacks (translation pass runs before the PR opens).
…n TM)

Reuses existing dashboard.* translations from the integration branch's
translation memory instead of an English-fallback sync, so the new
Workspaces Control UI keys ship translated in all 20 locales without
any LLM calls.
The custom-widget (custom:<name>) feature on top of the Workspaces UI: a
sandboxed iframe host for approved widgets, the operator approve/reject gate,
and the plugin HTTP route that serves approved widget assets under an
auth:"plugin" static-file-only path (jailed per widget dir, GET only).

Restores the FINAL widget-cell (custom-branch dispatch: approved -> iframe host,
pending -> approval card, rejected -> neutral placeholder, never an iframe
without a manifest) and the view's manifest-cache + custom-context plumbing that
PR2 held back so it could build with no L5 files present.

- extensions/dashboard/src: http-route, serve, manifest (+ tests) and the
  rpc-allowlist sync guard; index.ts registers the widgets HTTP route.
- ui: dashboard-custom-widget host + bridge (+ tests, e2e); plugin-page passes
  basePath/sessionKey so the iframe src and prompt dispatch resolve.

i18n keys (incl. approval.*) already shipped in PR2; no en.ts change.
…port controls

Adds a trusted builtin:preview widget (phase 1) cloned from iframe-embed: embeds a
URL in the same sandboxed frame (sandbox + external-URL policy unchanged), with a
reload control and desktop/tablet/mobile viewport presets.

- builtin:preview renderer + registration (BUILTIN_WIDGET_RENDERERS, BUILTIN_KIND_PATTERN)
- reuses resolveEmbedSandbox + evaluateEmbedUrl (no sandbox weakening)
- i18n keys dashboard.widget.preview.* + regenerated locale bundles

Implements openclaw#101138 (phase 1). Phases 2-3 (dev-server, browser-backed) are follow-ons.
Tests: ui dashboard 100, i18n check clean, build + oxlint green.
@100yenadmin
100yenadmin requested a review from a team as a code owner July 7, 2026 03:50
@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/dashboard/package.json
  • pnpm-lock.yaml

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Jul 7, 2026
@openclaw-barnacle openclaw-barnacle Bot added the r: too-many-prs Auto-close: author has more than twenty active PRs. label Jul 7, 2026
@100yenadmin

Copy link
Copy Markdown
Contributor Author

On the dependency-guard check: this PR is stacked on the not-yet-merged Wave 1 (#101098), so its cumulative diff against main includes Wave 1's single new-plugin pnpm-lock.yaml importer entry β€” which is what the guard flags. This PR adds no new dependency (it also touches only ui/ + regenerated i18n bundles); it clears once Wave 1 lands, or with the same head-SHA authorization noted on the Wave 1 PRs. Everything else is green locally: the UI dashboard suite (100 tests), ui:i18n:check, pnpm ui:build, and oxlint. The full CI test matrix is gated behind the standard fork-PR workflow approval.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Dependency graph changes are blocked

OpenClaw does not accept dependency graph changes through PRs unless a repository admin or security explicitly authorizes the current head SHA. Dependency updates are generated internally by maintainers so external PRs cannot change the resolved graph.

Detected dependency graph changes:

  • pnpm-lock.yaml changed.
  • extensions/dashboard/package.json changed dependencies, devDependencies, peerDependencies, peerDependenciesMeta, name, version.

Auto-scrub was not attempted because this PR changes package manifest dependency graph fields:

  • extensions/dashboard/package.json changed dependencies, devDependencies, peerDependencies, peerDependenciesMeta, name, version.

Dependency graph changes must be reviewed by security or handled by maintainers internally. Please remove lockfile changes manually if they are not needed.

To remove lockfile changes, restore them from the target branch:

git fetch origin
git checkout 'origin/main' -- 'pnpm-lock.yaml'
git commit -m 'chore: remove dependency lockfile change'
git push

If this PR intentionally needs a dependency graph change, ask a repository admin or member of @openclaw/openclaw-secops to comment:

/allow-dependencies-change

The action will approve the current head SHA (29a5ab9af831367bf2468b04733198bf49a5516a) when it reruns. A later push requires a fresh approval.

@openclaw-barnacle

Copy link
Copy Markdown

Closing this PR because the author has more than 20 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui dependencies-changed PR changes dependency-related files r: too-many-prs Auto-close: author has more than twenty active PRs. size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard: preview widget β€” live URL embed, dev-server preview, browser-backed inspection

1 participant