Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/ci_linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6

- name: Update apt index
run: sudo apt-get update
Expand All @@ -35,12 +35,15 @@ jobs:
run: rustup default ${{ matrix.rust-version }}

- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@v6
with:
version: latest

- name: Setup nodejs
run: pnpm env use --global lts
uses: actions/setup-node@v6
with:
node-version: lts/*
cache: pnpm

- name: Test default features
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_web.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Add wasm32 target
run: rustup target add wasm32-unknown-unknown

- uses: actions/checkout@v3
- uses: actions/checkout@v6

- name: Build package
run: cargo build --target wasm32-unknown-unknown --release --features single_threaded_async
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

steps:
- name: checkout
uses: actions/checkout@v3
uses: actions/checkout@v6

# Run build
- name: Install Rustup using win.rustup.rs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/style.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

steps:

- uses: actions/checkout@v3
- uses: actions/checkout@v6

- name: rustfmt
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Add ticket to inbox
uses: actions/add-to-project@v1.0.2
uses: actions/add-to-project@v2
with:
project-url: https://github.com/orgs/open-rmf/projects/10
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ storybook-static

.env/
venv/
.DS_Store
4 changes: 2 additions & 2 deletions diagram-editor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ tower = "0.5.2"

[features]
default = ["frontend", "router", "python"]
debug = ["router", "axum/ws"]
debug = ["router"]
frontend = ["router", "dep:flate2", "dep:tar"]
router = []
router = ["axum/ws"]
json_schema = ["dep:schemars", "dep:indexmap"]
basic_executor = [
"router",
Expand Down
Binary file modified diagram-editor/dist.tar.gz
Binary file not shown.
6 changes: 3 additions & 3 deletions diagram-editor/frontend/api-client/base-api-client.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Observable } from 'rxjs';
import type { Diagram, DiagramElementMetadata } from '../types/api';
import type { DebugSession } from './debug-session';

export interface BaseApiClient {
getRegistry(): Observable<DiagramElementMetdata>;
getRegistry(): Observable<DiagramElementMetadata>;
postRunWorkflow(diagram: Diagram, request: unknown): Observable<unknown>;
// WIP
// wsDebugWorkflow(diagram: Diagram, request: unknown): Promise<DebugSession>;
wsDebugWorkflow?(diagram: Diagram, request: unknown): Promise<DebugSession>;
}
26 changes: 22 additions & 4 deletions diagram-editor/frontend/api-client/debug-session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Observable, Subject } from 'rxjs';
import { type Observable, ReplaySubject } from 'rxjs';
import type { DebugSessionMessage } from '../types/api';
import { getSchema } from '../utils/ajv';

Expand All @@ -8,21 +8,39 @@ const validateDebugSessionMessage = getSchema<DebugSessionMessage>(

export class DebugSession {
debugFeedback$: Observable<DebugSessionMessage>;
private debugFeedbackSubject$: ReplaySubject<DebugSessionMessage>;
private ws: WebSocket;

constructor(ws: WebSocket) {
const debugFeedbackSubject$ = new Subject<DebugSessionMessage>();
this.ws = ws;
this.debugFeedbackSubject$ = new ReplaySubject<DebugSessionMessage>(1000);
ws.onmessage = (ev) => {
try {
const msg = JSON.parse(ev.data);
if (!validateDebugSessionMessage(msg)) {
console.error(validateDebugSessionMessage.errors);
return;
}
debugFeedbackSubject$.next(msg);
this.debugFeedbackSubject$.next(msg);
} catch (e) {
console.error((e as Error).message);
}
};
this.debugFeedback$ = debugFeedbackSubject$;
ws.onerror = () => {
this.debugFeedbackSubject$.error(new Error('debug websocket error'));
};
ws.onclose = () => {
this.debugFeedbackSubject$.complete();
};
this.debugFeedback$ = this.debugFeedbackSubject$;
}

close() {
if (
this.ws.readyState === WebSocket.OPEN ||
this.ws.readyState === WebSocket.CONNECTING
) {
this.ws.close();
}
}
}
12 changes: 7 additions & 5 deletions diagram-editor/frontend/api-client/rest-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,20 @@ export class ApiClient implements BaseApiClient {
diagram: Diagram,
request: unknown,
): Promise<DebugSession> {
const ws = new WebSocket('/api/executor/debug');
await new Promise((resolve, reject) => {
const url = new URL('/api/executor/debug', window.location.href);
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(url);
return new Promise((resolve, reject) => {
ws.onopen = () => {
const session = new DebugSession(ws);
const body: PostRunRequest = {
diagram,
request,
};
ws.send(JSON.stringify(body));
resolve(ws);
resolve(session);
};
ws.onerror = reject;
ws.onerror = () => reject(new Error('debug websocket error'));
});
return new DebugSession(ws);
}
}
54 changes: 43 additions & 11 deletions diagram-editor/frontend/command-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { Button, ButtonGroup, styled, Tooltip, useTheme } from '@mui/material';
import { type NodeChange, Panel } from '@xyflow/react';
import React from 'react';
import AutoLayoutButton from './auto-layout-button';
import DiagramPropertiesDrawer from './diagram-properties-drawer';
import DiagramSidePanel, {
type DiagramSidePanelTab,
} from './diagram-side-panel';
import EditTemplatesDialog from './edit-templates-dialog';
import { EditorMode, useEditorMode } from './editor-mode';
import { ScriptEnvironmentManagerDialog } from './forms/script-environment-manager-dialog';
import type { DiagramEditorNode } from './nodes';
import { MaterialSymbol } from './nodes';
import { RunButton } from './run-button';

export interface CommandPanelProps {
onNodeChanges: (changes: NodeChange<DiagramEditorNode>[]) => void;
Expand Down Expand Up @@ -38,17 +39,44 @@ function CommandPanel({
const theme = useTheme();
const [openEditTemplatesDialog, setOpenEditTemplatesDialog] =
React.useState(false);
const [openDiagramPropertiesDrawer, setOpenDiagramPropertiesDrawer] =
React.useState(true);
const [openSidePanel, setOpenSidePanel] = React.useState(true);
const [sidePanelTab, setSidePanelTab] =
React.useState<DiagramSidePanelTab>('run');
const [runRequestJson, setRunRequestJson] = React.useState('');
const [openScriptEnvManager, setOpenScriptEnvManager] = React.useState(false);
const [editorMode] = useEditorMode();

const showSidePanelTab = (tab: DiagramSidePanelTab) => {
setSidePanelTab(tab);
setOpenSidePanel(true);
};

const toggleSidePanelTab = (tab: DiagramSidePanelTab) => {
if (openSidePanel && sidePanelTab === tab) {
setOpenSidePanel(false);
return;
}

showSidePanelTab(tab);
};

return (
<>
<Panel position="top-center">
<ButtonGroup variant="contained">
{editorMode.mode === EditorMode.Normal && (
<RunButton requestJsonString="" />
<Tooltip title="Run Workflow">
<Button
onClick={() => toggleSidePanelTab('run')}
sx={
openSidePanel && sidePanelTab === 'run'
? { backgroundColor: theme.palette.primary.light }
: undefined
}
>
<MaterialSymbol symbol="play_arrow" />
</Button>
</Tooltip>
)}
{editorMode.mode === EditorMode.Normal && (
<Tooltip title="Script Environment Manager">
Expand All @@ -60,9 +88,9 @@ function CommandPanel({
{editorMode.mode === EditorMode.Normal && (
<Tooltip title="Diagram properties">
<Button
onClick={() => setOpenDiagramPropertiesDrawer((prev) => !prev)}
onClick={() => toggleSidePanelTab('properties')}
sx={
openDiagramPropertiesDrawer
openSidePanel && sidePanelTab === 'properties'
? { backgroundColor: theme.palette.primary.light }
: undefined
}
Expand Down Expand Up @@ -119,14 +147,18 @@ function CommandPanel({
open={openEditTemplatesDialog}
onClose={() => setOpenEditTemplatesDialog(false)}
/>
<DiagramPropertiesDrawer
open={openDiagramPropertiesDrawer}
onClose={() => setOpenDiagramPropertiesDrawer(false)}
/>
<ScriptEnvironmentManagerDialog
open={openScriptEnvManager}
onClose={() => setOpenScriptEnvManager(false)}
/>
<DiagramSidePanel
open={openSidePanel}
tab={sidePanelTab}
runRequestJson={runRequestJson}
onClose={() => setOpenSidePanel(false)}
onRunRequestJsonChange={setRunRequestJson}
onTabChange={(tab) => showSidePanelTab(tab)}
/>
</>
);
}
Expand Down
36 changes: 36 additions & 0 deletions diagram-editor/frontend/debug-visualization-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createContext, type PropsWithChildren, useContext } from 'react';

export interface DebugVisualizationContext {
activeNodeIds: Set<string>;
latestNodeId: string | null;
clearDebugVisualization: () => void;
markDebugFinished: () => void;
markDebugOperationStarted: (operationId: string) => void;
}

const DefaultDebugVisualizationContext: DebugVisualizationContext = {
activeNodeIds: new Set(),
latestNodeId: null,
clearDebugVisualization: () => {},
markDebugFinished: () => {},
markDebugOperationStarted: () => {},
};

const DebugVisualizationContextComp = createContext<DebugVisualizationContext>(
DefaultDebugVisualizationContext,
);

export function DebugVisualizationProvider({
value,
children,
}: PropsWithChildren<{ value: DebugVisualizationContext }>) {
return (
<DebugVisualizationContextComp.Provider value={value}>
{children}
</DebugVisualizationContextComp.Provider>
);
}

export function useDebugVisualization() {
return useContext(DebugVisualizationContextComp);
}
Loading
Loading