Skip to content

Commit

Permalink
Add visual/json toggle and expose workflow template on editor (#189)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <[email protected]>
(cherry picked from commit 6efb453)
  • Loading branch information
ohltyler authored and github-actions[bot] committed Jun 20, 2024
1 parent 1e672b5 commit 2c44ec2
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 37 deletions.
5 changes: 4 additions & 1 deletion public/pages/workflow_detail/resizable_workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ export function ResizableWorkspace(props: ResizableWorkspaceProps) {
style={{ height: '100%' }}
>
<EuiFlexItem>
<Workspace uiConfig={uiConfig} />
<Workspace
workflow={props.workflow}
uiConfig={uiConfig}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiResizablePanel>
Expand Down
142 changes: 106 additions & 36 deletions public/pages/workflow_detail/workspace/workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useRef, useCallback, useEffect } from 'react';
import React, { useRef, useCallback, useEffect, useState } from 'react';
import ReactFlow, {
Controls,
Background,
Expand All @@ -13,9 +13,16 @@ import ReactFlow, {
BackgroundVariant,
MarkerType,
} from 'reactflow';
import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
import {
EuiFlexItem,
EuiFlexGroup,
EuiTitle,
EuiFilterGroup,
EuiFilterButton,
EuiCodeEditor,
} from '@elastic/eui';
import { setDirty, useAppDispatch } from '../../../store';
import { IComponentData, WorkflowConfig } from '../../../../common';
import { IComponentData, Workflow, WorkflowConfig } from '../../../../common';
import {
IngestGroupComponent,
SearchGroupComponent,
Expand All @@ -31,6 +38,7 @@ import './workspace-styles.scss';
import './workspace_edge/deletable-edge-styles.scss';

interface WorkspaceProps {
workflow?: Workflow;
uiConfig?: WorkflowConfig;
}

Expand All @@ -44,6 +52,22 @@ const edgeTypes = { customEdge: DeletableEdge };
export function Workspace(props: WorkspaceProps) {
const dispatch = useAppDispatch();

// Visual/JSON toggle states
const [visualSelected, setVisualSelected] = useState<boolean>(true);
function toggleSelection(): void {
setVisualSelected(!visualSelected);
}

// JSON state
const [provisionTemplate, setProvisionTemplate] = useState<string>('');
useEffect(() => {
if (props.workflow?.workflows.provision) {
const templateAsObj = props.workflow?.workflows.provision as {};
const templateAsStr = JSON.stringify(templateAsObj, undefined, 2);
setProvisionTemplate(templateAsStr);
}
}, [props.workflow]);

// ReactFlow state
const reactFlowWrapper = useRef(null);
const [nodes, setNodes, onNodesChange] = useNodesState<IComponentData>([]);
Expand Down Expand Up @@ -88,46 +112,92 @@ export function Workspace(props: WorkspaceProps) {
gutterSize="none"
justifyContent="spaceBetween"
>
<EuiFlexItem className="euiPanel euiPanel--hasShadow euiPanel--borderRadiusMedium">
<EuiFlexItem
className="euiPanel euiPanel--hasShadow euiPanel--borderRadiusMedium"
style={{ overflowX: 'hidden' }}
>
{/**
* We have these wrapper divs & reactFlowWrapper ref to control and calculate the
* ReactFlow bounds when calculating node positioning.
*/}
<div>
<EuiFlexGroup direction="row" style={{ padding: '12px' }}>
<EuiFlexItem grow={false}>
<EuiTitle>
<h2>Preview</h2>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFilterGroup>
<EuiFilterButton
size="l"
hasActiveFilters={visualSelected}
onClick={() => toggleSelection()}
>
Visual
</EuiFilterButton>
<EuiFilterButton
size="l"
hasActiveFilters={!visualSelected}
onClick={() => toggleSelection()}
>
JSON
</EuiFilterButton>
</EuiFilterGroup>
</EuiFlexItem>
</EuiFlexGroup>
</div>
<div className="reactflow-parent-wrapper">
<div className="reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
id="workspace"
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
// TODO: add custom edge types back if we want to support custom deletable buttons
// edgeTypes={edgeTypes}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
className="reactflow-workspace"
fitView
minZoom={0.2}
edgesUpdatable={false}
edgesFocusable={false}
nodesDraggable={false}
nodesConnectable={false}
nodesFocusable={false}
draggable={true}
panOnDrag={true}
elementsSelectable={false}
>
<Controls
showFitView={false}
showZoom={false}
showInteractive={false}
position="top-left"
></Controls>
<Background
color="#343741"
variant={'dots' as BackgroundVariant}
{visualSelected ? (
<ReactFlow
id="workspace"
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
// TODO: add custom edge types back if we want to support custom deletable buttons
// edgeTypes={edgeTypes}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
className="reactflow-workspace"
fitView
minZoom={0.2}
edgesUpdatable={false}
edgesFocusable={false}
nodesDraggable={false}
nodesConnectable={false}
nodesFocusable={false}
draggable={true}
panOnDrag={true}
elementsSelectable={false}
>
<Controls
showFitView={false}
showZoom={false}
showInteractive={false}
position="top-left"
></Controls>
<Background
color="#343741"
variant={'dots' as BackgroundVariant}
/>
</ReactFlow>
) : (
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height="100%"
value={provisionTemplate}
readOnly={true}
setOptions={{
fontSize: '12px',
autoScrollEditorIntoView: true,
}}
tabSize={2}
/>
</ReactFlow>
)}
</div>
</div>
</EuiFlexItem>
Expand Down

0 comments on commit 2c44ec2

Please sign in to comment.