Skip to content
Open
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
Binary file modified diagram-editor/dist.tar.gz
Binary file not shown.
24 changes: 24 additions & 0 deletions diagram-editor/frontend/api.preprocessed.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,17 @@
"default_trace": {
"$ref": "#/$defs/TraceToggle"
},
"description": {
"description": "Optional text to describe the workflow.",
"type": "string"
},
"example_inputs": {
"description": "Examples of inputs that can be used with this workflow.",
"items": {
"$ref": "#/$defs/ExampleInput"
},
"type": "array"
},
"extensions": {
"additionalProperties": true,
"default": {},
Expand Down Expand Up @@ -569,6 +580,19 @@
}
]
},
"ExampleInput": {
"properties": {
"description": {
"type": "string"
},
"value": true
},
"required": [
"value",
"description"
],
"type": "object"
},
"ForkCloneSchema": {
"description": "If the request is cloneable, clone it into multiple responses that can\n each be sent to a different operation. The `next` property is an array.\n\n This creates multiple simultaneous branches of execution within the\n workflow. Usually when you have multiple branches you will either\n * race - connect all branches to `terminate` and the first branch to\n finish \"wins\" the race and gets to the be output\n * join - connect each branch into a buffer and then use the `join`\n operation to reunite them\n * collect - TODO(@mxgrey): [add the collect operation](https://github.com/open-rmf/crossflow/issues/59)\n\n # Examples\n ```\n # crossflow::Diagram::from_json_str(r#\"\n {\n \"version\": \"0.1.0\",\n \"start\": \"begin_race\",\n \"ops\": {\n \"begin_race\": {\n \"type\": \"fork_clone\",\n \"next\": [\n \"ferrari\",\n \"mustang\"\n ]\n },\n \"ferrari\": {\n \"type\": \"node\",\n \"builder\": \"drive\",\n \"config\": \"ferrari\",\n \"next\": { \"builtin\": \"terminate\" }\n },\n \"mustang\": {\n \"type\": \"node\",\n \"builder\": \"drive\",\n \"config\": \"mustang\",\n \"next\": { \"builtin\": \"terminate\" }\n }\n }\n }\n # \"#)?;\n # Ok::<_, serde_json::Error>(())",
"properties": {
Expand Down
28 changes: 26 additions & 2 deletions diagram-editor/frontend/command-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, ButtonGroup, styled, Tooltip } from '@mui/material';
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';
Expand All @@ -7,6 +7,7 @@ import { EditorMode, useEditorMode } from './editor-mode';
import type { DiagramEditorNode } from './nodes';
import { MaterialSymbol } from './nodes';
import { RunButton } from './run-button';
import DiagramPropertiesDrawer from './diagram-properties-drawer';

export interface CommandPanelProps {
onNodeChanges: (changes: NodeChange<DiagramEditorNode>[]) => void;
Expand All @@ -31,15 +32,34 @@ function CommandPanel({
onExportClick,
onLoadDiagram,
}: CommandPanelProps) {
const theme = useTheme();
const [openEditTemplatesDialog, setOpenEditTemplatesDialog] =
React.useState(false);
const [openDiagramPropertiesDrawer, setOpenDiagramPropertiesDrawer] =
React.useState(false);
const [editorMode] = useEditorMode();

return (
<>
<Panel position="top-center">
<ButtonGroup variant="contained">
{editorMode.mode === EditorMode.Normal && <RunButton />}
{editorMode.mode === EditorMode.Normal && (
<RunButton requestJsonString=''/>
)}
{editorMode.mode === EditorMode.Normal && (
<Tooltip title="Diagram properties">
<Button
onClick={() => setOpenDiagramPropertiesDrawer((prev) => !prev)}
sx={
openDiagramPropertiesDrawer
? { backgroundColor: theme.palette.primary.light }
: undefined
}
>
<MaterialSymbol symbol="info" />
</Button>
</Tooltip>
)}
{editorMode.mode === EditorMode.Normal && (
<Tooltip title="Templates">
<Button onClick={() => setOpenEditTemplatesDialog(true)}>
Expand Down Expand Up @@ -84,6 +104,10 @@ function CommandPanel({
open={openEditTemplatesDialog}
onClose={() => setOpenEditTemplatesDialog(false)}
/>
<DiagramPropertiesDrawer
open={openDiagramPropertiesDrawer}
onClose={() => setOpenDiagramPropertiesDrawer(false)}
/>
</>
);
}
Expand Down
15 changes: 14 additions & 1 deletion diagram-editor/frontend/diagram-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { ExportDiagramDialog } from './export-diagram-dialog';
import { defaultEdgeData, EditEdgeForm, EditNodeForm } from './forms';
import EditScopeForm from './forms/edit-scope-form';
import { type LoadContext, LoadContextProvider } from './load-context-provider';
import { type DiagramProperties, DiagramPropertiesProvider } from './diagram-properties-provider';
import { NodeManager, NodeManagerProvider } from './node-manager';
import {
type DiagramEditorNode,
Expand Down Expand Up @@ -119,20 +120,26 @@ interface ProvidersProps {
loadContext: LoadContext | null;
nodeManager: NodeManager;
edges: DiagramEditorEdge[];
diagramProperties: DiagramProperties;
}

function Providers({
editorModeContext,
loadContext,
nodeManager,
edges,
diagramProperties,
children,
}: React.PropsWithChildren<ProvidersProps>) {
return (
<EditorModeProvider value={editorModeContext}>
<LoadContextProvider value={loadContext}>
<NodeManagerProvider value={nodeManager}>
<EdgesProvider value={edges}>{children}</EdgesProvider>
<EdgesProvider value={edges}>
<DiagramPropertiesProvider value={diagramProperties}>
{children}
</DiagramPropertiesProvider>
</EdgesProvider>
</NodeManagerProvider>
</LoadContextProvider>
</EditorModeProvider>
Expand Down Expand Up @@ -509,12 +516,17 @@ function DiagramEditor() {
const [loadContext, setLoadContext] = React.useState<LoadContext | null>(
null,
);
const [diagramProperties, setDiagramProperties] =
React.useState<DiagramProperties>({});

const loadDiagram = React.useCallback(
async (jsonStr: string) => {
try {
const [diagram, { graph, isRestored }] = await loadDiagramJson(jsonStr);
setLoadContext({ diagram });
setDiagramProperties({
description: diagram.description,
example_inputs: diagram.example_inputs });
// do not perform auto layout if the diagram is restored from previous state.
if (!isRestored) {
const changes = autoLayout(graph.nodes, graph.edges, LAYOUT_OPTIONS);
Expand Down Expand Up @@ -604,6 +616,7 @@ function DiagramEditor() {
loadContext={loadContext}
nodeManager={nodeManager}
edges={edges}
diagramProperties={diagramProperties}
>
<ReactFlow
nodes={nodes}
Expand Down
Loading