From 5e8df5f6515333528c9cc06de884779df0abc8ee Mon Sep 17 00:00:00 2001 From: AlexTemirov Date: Fri, 4 Sep 2026 08:21:29 -0700 Subject: [PATCH 1/2] Add interactive workflow app viewers --- docs/operator-apps.md | 17 +++- editor/src/components/LocalFilePicker.tsx | 4 +- .../src/components/WorkflowOperatorView.tsx | 80 +++++++++++++++++++ editor/src/index.css | 50 +++++++++++- editor/src/operatorView.ts | 17 +++- python/blacknode/package_index.py | 2 + tests/test_editor_operator_view.py | 33 ++++++++ 7 files changed, 191 insertions(+), 12 deletions(-) diff --git a/docs/operator-apps.md b/docs/operator-apps.md index 9e0911b..5a5dd8f 100644 --- a/docs/operator-apps.md +++ b/docs/operator-apps.md @@ -82,10 +82,19 @@ An operator view is declared inside workflow metadata: } ``` -Supported widgets are `image`, `status`, `metrics`, `fields`, and `actions`. -Image, status, and metric widgets read live node output ports. Field widgets -update declared node parameters. Actions can update parameters, cook a declared -node output, or call a node's existing direct-control endpoint. +Supported widgets are `image`, `viewer`, `status`, `metrics`, `fields`, and +`actions`. Image, viewer, status, and metric widgets read live node output +ports. A `viewer` embeds an HTTP(S) URL produced by a trusted workflow node and +is intended for managed simulation, robot-scene, and other interactive browser +surfaces. Field widgets update declared node parameters. Actions can update +parameters, cook a declared node output, or call a node's existing +direct-control endpoint. + +Use `input: "file_path"` for a path that must exist on the App host. It keeps +the path editable and adds a **Browse…** button backed by Blacknode's filesystem +browser. Declare `extensions` to filter selectable files, and optionally set +`picker_title` and `button_label`. This is appropriate for robot descriptions, +scenes, datasets, checkpoints, and other host-side artifacts. Sections render in the central workspace by default. Set a section's optional `region` to `parameters` to place its fields and actions in the right-side diff --git a/editor/src/components/LocalFilePicker.tsx b/editor/src/components/LocalFilePicker.tsx index c9902e2..bc9b748 100644 --- a/editor/src/components/LocalFilePicker.tsx +++ b/editor/src/components/LocalFilePicker.tsx @@ -76,7 +76,7 @@ export default function LocalFilePicker({
{title} - Select a local {extensions.join(', ')} scene + Select a local {extensions.join(', ')} file
@@ -118,7 +118,7 @@ export default function LocalFilePicker({ {loading &&
Opening folder…
} {!loading && error &&
{error}
} {!loading && !error && listing?.entries.length === 0 && ( -
No matching scene files or folders here.
+
No matching files or folders here.
)} {!loading && !error && listing?.entries.map(entry => (