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
363 changes: 33 additions & 330 deletions telemetry/ui/package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions telemetry/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@tisoap/react-flow-smart-edge": "^3.0.0",
"@xyflow/react": "^12.0.0",
"@types/fuse": "^2.6.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.82",
Expand All @@ -32,7 +32,6 @@
"react-scripts": "5.0.1",
"react-select": "^5.8.1",
"react-syntax-highlighter": "^15.5.0",
"reactflow": "^11.10.4",
"remark-gfm": "^4.0.0",
"string.prototype.matchall": "^4.0.10",
"tailwindcss-question-mark": "^0.4.0",
Expand Down
2 changes: 2 additions & 0 deletions telemetry/ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { StreamingChatbotWithTelemetry } from './examples/StreamingChatbot';
import { AdminView } from './components/routes/AdminView';
import { AnnotationsViewContainer } from './components/routes/app/AnnotationsView';
import { DeepResearcherWithTelemetry } from './examples/DeepResearcher';
import GraphBuilder from './components/routes/graph-builder/components/GraphBuilder';

/**
* Basic application. We have an AppContainer -- this has a breadcrumb and a sidebar.
Expand Down Expand Up @@ -65,6 +66,7 @@ const App = () => {
<Route path="/demos/email-assistant" element={<EmailAssistantWithTelemetry />} />
<Route path="/demos/deep-researcher" element={<DeepResearcherWithTelemetry />} />
<Route path="/admin" element={<AdminView />} />
<Route path="/graph-builder" element={<GraphBuilder />} />
<Route path="*" element={<Navigate to="/projects" />} />
</Routes>
</AppContainer>
Expand Down
16 changes: 11 additions & 5 deletions telemetry/ui/src/components/nav/appcontainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Dialog, Disclosure, Transition } from '@headlessui/react';
import {
ComputerDesktopIcon,
Square2StackIcon,
SquaresPlusIcon,
QuestionMarkCircleIcon,
XMarkIcon,
ChatBubbleLeftEllipsisIcon,
Expand Down Expand Up @@ -100,6 +101,12 @@ export const AppContainer = (props: { children: React.ReactNode }) => {
icon: Square2StackIcon,
linkType: 'internal'
},
{
name: 'Graph Builder',
href: '/graph-builder',
icon: SquaresPlusIcon,
linkType: 'internal'
},
{
name: 'Examples',
href: 'https://github.com/DAGWorks-Inc/burr/tree/main/examples',
Expand Down Expand Up @@ -384,13 +391,12 @@ export const AppContainer = (props: { children: React.ReactNode }) => {
<ToggleOpenButton open={sidebarOpen} toggleSidebar={toggleSidebar} />
</div>

{/* This is a bit hacky -- just quickly prototyping and these margins were the ones that worked! */}
<main className={`py-14 -my-1 ${sidebarOpen ? 'lg:pl-72' : 'lg:pl-5'} h-full`}>
<div className="flex items-center px-5 sm:px-7 lg:px-9 pb-8 -my-4">
<main className={`${sidebarOpen ? 'lg:pl-72' : 'lg:pl-5'} h-full flex flex-col`}>
<div className="flex items-center px-5 sm:px-7 lg:px-9 h-14 flex-shrink-0">
<BreadCrumb />
</div>
<div className="flex h-full flex-col">
<div className="px-4 sm:px-6 lg:px-2 max-h-full h-full flex-1"> {props.children}</div>
<div className="flex-1 flex flex-col min-h-0">
<div className="px-4 sm:px-6 lg:px-2 h-full flex-1 min-h-0">{props.children}</div>
</div>
</main>
</div>
Expand Down
43 changes: 15 additions & 28 deletions telemetry/ui/src/components/routes/app/GraphView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import { ActionModel, ApplicationModel, Step } from '../../../api';

import dagre from 'dagre';
import React, { createContext, useLayoutEffect, useRef, useState } from 'react';
import ReactFlow, {
import {
ReactFlow,
BaseEdge,
Controls,
EdgeProps,
Expand All @@ -30,14 +31,12 @@ import ReactFlow, {
Position,
ReactFlowProvider,
getBezierPath,
useNodes,
useReactFlow
} from 'reactflow';
} from '@xyflow/react';

import 'reactflow/dist/style.css';
import '@xyflow/react/dist/style.css';
import { backgroundColorsForIndex } from './AppView';
import { getActionStatus } from '../../../utils';
import { getSmartEdge } from '@tisoap/react-flow-smart-edge';

const dagreGraph = new dagre.graphlib.Graph();

Expand Down Expand Up @@ -149,46 +148,34 @@ export const ActionActionEdge = ({
markerEnd,
data
}: EdgeProps) => {
const nodes = useNodes();
data = data as EdgeData;
const edgeData = data as EdgeData | undefined;
const { highlightedActions: previousActions, currentAction } =
React.useContext(NodeStateProvider);
const allActionsInPath = [...(previousActions || []), ...(currentAction ? [currentAction] : [])];
const containsFrom = allActionsInPath.some(
(action) => action.step_start_log.action === data.from
(action) => action.step_start_log.action === edgeData?.from
);
const containsTo = allActionsInPath.some(
(action) => action.step_start_log.action === edgeData?.to
);
const containsTo = allActionsInPath.some((action) => action.step_start_log.action === data.to);
const shouldHighlight = containsFrom && containsTo;
const getSmartEdgeResponse = getSmartEdge({
sourcePosition,
targetPosition,

const [edgePath] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
nodes
targetPosition
});
let edgePath = null;
if (getSmartEdgeResponse !== null) {
edgePath = getSmartEdgeResponse.svgPathString;
} else {
edgePath = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition
})[0];
}

const style = {
markerColor: shouldHighlight ? 'black' : 'gray',
strokeWidth: shouldHighlight ? 2 : 0.5
};
return (
<>
<BaseEdge path={edgePath} markerEnd={markerEnd} style={style} label={'test'} />
<BaseEdge path={edgePath} markerEnd={markerEnd} style={style} />
</>
);
};
Expand Down Expand Up @@ -359,7 +346,7 @@ export const _Graph = (props: {
<ReactFlow
nodes={nodes}
edges={edges}
edgesUpdatable={false}
edgesReconnectable={false}
nodesDraggable={false}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React from 'react';
import { Button } from '../../../common/button';
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline';

interface ConfirmLoadExampleDialogProps {
open: boolean;
onClose: () => void;
onConfirm: () => void;
exampleTitle: string;
hasExistingContent: boolean;
}

const ConfirmLoadExampleDialog: React.FC<ConfirmLoadExampleDialogProps> = ({
open,
onClose,
onConfirm,
exampleTitle,
hasExistingContent
}) => {
if (!open) return null;

return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 w-full max-w-md mx-4">
<div className="flex items-center gap-2 mb-4">
<ExclamationTriangleIcon className="w-6 h-6 text-amber-500" />
<h2 className="text-lg font-semibold">Load Example Graph</h2>
</div>

<div className="space-y-4">
<p className="text-gray-700">
Are you sure you want to load the &quot;{exampleTitle}&quot; example?
</p>

{hasExistingContent && (
<div className="bg-amber-50 border border-amber-200 rounded-md p-3">
<p className="text-sm text-amber-800">
This will replace your current graph. Any unsaved changes will be lost.
</p>
</div>
)}

<div className="text-sm text-gray-500">
You can always export your current work as JSON or Python code before loading the
example.
</div>
</div>

<div className="flex justify-end space-x-2 mt-6">
<Button onClick={onClose} outline>
Cancel
</Button>
<Button onClick={onConfirm} color={hasExistingContent ? 'amber' : 'blue'}>
{hasExistingContent ? 'Replace Graph' : 'Load Example'}
</Button>
</div>
</div>
</div>
);
};

export default ConfirmLoadExampleDialog;
Loading