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
4 changes: 2 additions & 2 deletions packages/demo/pages/ui/+Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ConfigProvider.setConfig({
timeout: 15000,
baseURL:
// "https://station-developer-dev-staging.aevatar.ai/testproject-client",
"https://station-developer-dev-staging.aevatar.ai/default-project-113b-5a7ed924-client",
"https://station-developer-testing.aevatar.ai/default-project-2a9a-b17730ff-44fd-client",
},
});

Expand Down Expand Up @@ -119,7 +119,7 @@ export default function UI() {

const getTokenByclient = useCallback(async () => {
const TOKEN =
"Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg5QzAwNzc1RTlGNDhEQUZGN0QzQzZGMjBBNkZDQTdDN0FDMzNDQjIiLCJ4NXQiOiJpY0FIZGVuMGphXzMwOGJ5Q21fS2ZIckRQTEkiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGgtc3RhdGlvbi1kZXYtc3RhZ2luZy5hZXZhdGFyLmFpLyIsImV4cCI6MTc2MDUxMTkwOSwiaWF0IjoxNzYwMzM5MTEwLCJhdWQiOiJBZXZhdGFyIiwic2NvcGUiOiJBZXZhdGFyIG9mZmxpbmVfYWNjZXNzIiwianRpIjoiNzY0N2ZjZTAtOWFmYS00N2ZiLWJhMTMtOWVhOGRjNGZhMDAxIiwic3ViIjoiNTdiYWIyMjAtOTVkZS1kNDYxLTFlODMtM2ExY2VlOGYwYzIzIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWZ2b2ppIiwiZW1haWwiOiJhZnZvamlAc25hcG1haWwuY2MiLCJyb2xlIjpbImJhc2ljVXNlciIsIjgwNmQzY2M2LTI2OTMtYTg0NS05Y2FhLTNhMWNlZThmNDY2ZV9Pd25lciIsIjVhN2VkOTI0LTM4NWYtMDA2YS04OWU2LTNhMWNlZThmNDU1NV9Pd25lciJdLCJwaG9uZV9udW1iZXJfdmVyaWZpZWQiOiJGYWxzZSIsImVtYWlsX3ZlcmlmaWVkIjoiRmFsc2UiLCJ1bmlxdWVfbmFtZSI6ImFmdm9qaSIsInNlY3VyaXR5X3N0YW1wIjoiR1NCNE4ySUIyTElBWk5CRzUyM0tGNVo0T0YyUUo3WDIiLCJvaV9wcnN0IjoiQWV2YXRhckF1dGhTZXJ2ZXIiLCJvaV9hdV9pZCI6ImFlNzQ5Yzk4LTg0YzgtODFmMy1lZTkzLTNhMWNlZThmMGUxMiIsImNsaWVudF9pZCI6IkFldmF0YXJBdXRoU2VydmVyIiwib2lfdGtuX2lkIjoiNGM1YWVkZDMtMGU4NS0xODEwLTE5YjAtM2ExY2VlOTAwNDFmIn0.of4itZLslUAmoJsfuY1vmmgELUyRs6HBm3Y1Ki1tdEPNZlLqzmhJZ41RUYKwGEljaWWvA2lQ-lktrHP0KhJZOHCkdd3Z3Refvo7C7GG9yDKFszsOX00pwjHXZhx3FusuTmhcJiXeBPjc-w2l_0YQ3OVnH1FdC31MCReF-rxwQXxrpkDUkkc0ixJAJegGvgcH8OuU1Ce0r47S2tpqnPv6O6sv8wpIIF0IWh05YvsrLWUnfKGb_Q0uh_Jo2m43T5_KdkfOXtmWq-wLAlWwBjjNXUHYEN51LA3xIOtsMpaeFVV8uDu31qgAmZeqNlk0AkBf_CTu4mHIHPBy-kBhEwcmVA";
"Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjZERTNDMzQzNTgxNEIxQ0NDQkQ2RkIyMzk2RjQxRjEyMjVFRUVGOEMiLCJ4NXQiOiJiZVBEUTFnVXNjekwxdnNqbHZRZkVpWHU3NHciLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODIvIiwiZXhwIjoxNzYwNzY0ODMzLCJpYXQiOjE3NjA1OTIwMzQsImF1ZCI6IkFldmF0YXIiLCJzY29wZSI6IkFldmF0YXIgb2ZmbGluZV9hY2Nlc3MiLCJqdGkiOiI2YjkyNDk4Yi1hMTdlLTQ2ZGMtODY2Yy0zYTZkZWJiZmU1YTMiLCJzdWIiOiJkZDJkZjhjNC1lMDc0LTI5MzAtNzgwZS0zYTFjZmRhMjc5NzAiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJydW51bHIiLCJlbWFpbCI6InJ1bnVsckBzbmFwbWFpbC5jYyIsInJvbGUiOlsiMGIzYWY3YTktODlkZi1hMTQ5LWIzYjctM2ExY2ZkYTI5YTllX093bmVyIiwiYmFzaWNVc2VyIiwiYjE3NzMwZmYtNmIzOS01MjQ1LTY0Y2MtM2ExY2ZkYTI5OTk2X093bmVyIl0sInBob25lX251bWJlcl92ZXJpZmllZCI6IkZhbHNlIiwiZW1haWxfdmVyaWZpZWQiOiJGYWxzZSIsInVuaXF1ZV9uYW1lIjoicnVudWxyIiwic2VjdXJpdHlfc3RhbXAiOiJKSU42Wk1UQTZDSU9OS1QyQ0hXRU1SR1RBUUlWSkZESSIsIm9pX3Byc3QiOiJBZXZhdGFyQXV0aFNlcnZlciIsIm9pX2F1X2lkIjoiMTczNTQ5ZDItNjI4Yy05OGY4LWIxMzQtM2ExY2ZkYTI3ZWYxIiwiY2xpZW50X2lkIjoiQWV2YXRhckF1dGhTZXJ2ZXIiLCJvaV90a25faWQiOiI0MjQyZjNhMy00ODg3LTE5YjQtOGM1OC0zYTFjZmRhMzU0OWYifQ.IrwJncCMtd7vbZfAXfB3yBKNtopCe0mvD3VbA636-aYdLu4w54RbgiW52RRlqQSOGXcn1rsvcu8N-2p1UgajE-17r3MaAOjT63vPgW5xNEOrzfm__2kzR6Znw1IfBgMYm_onmD7iENR4fhxKVQsW0bGH9Btlch-6zzOY24eimRdjaVJZ-qUezEJa8jycNm7uOlUKYDhnP7ZiVxdZL-m29iwDZX_kBzZfCLnB9KkGvw3D94cB56LzhalaIARv044-lJUHJ8jKI_8Rh9JdBsKh1syQ5fkqj_vmWWiC32FKZEqHD_vWKHFobDCXYQJG4b_Gv4XigtN4tNsCQv_IwwarsQ";
aevatarAI.fetchRequest.setHeaders({
Authorization: TOKEN,
});
Expand Down
5 changes: 3 additions & 2 deletions packages/ui-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@
"@aevatar-react-sdk/services": "workspace:*",
"@aevatar-react-sdk/types": "workspace:*",
"@aevatar-react-sdk/utils": "workspace:*",
"@dagrejs/dagre": "^1.1.5",
"@fontsource/geist": "^5.2.7",
"@hookform/resolvers": "^3.9.1",
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-checkbox": "^1.1.5",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-icons": "^1.3.2",
Expand All @@ -76,7 +78,6 @@
"@radix-ui/react-toggle": "^1.1.1",
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.6",
"@radix-ui/react-accordion": "^1.2.2",
"@rjsf/core": "6.0.0-beta.1",
"@rjsf/shadcn": "6.0.0-beta.1",
"@rjsf/utils": "6.0.0-beta.1",
Expand All @@ -96,8 +97,8 @@
"react-dnd-touch-backend": "^16.0.1",
"react-dropzone": "^14.3.5",
"react-hook-form": "^7.54.2",
"react-loading": "^2.0.3",
"react-json-tree": "^0.20.0",
"react-loading": "^2.0.3",
"react-use": "^17.6.0",
"tailwind-merge": "^2.5.5",
"uuid": "^11.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function AevatarCardInner({
"sdk:aevatar-item-background sdk:border sdk:border-[var(--sdk-color-bg-primary)] sdk:group-hover:border-[var(--sdk-border-foreground)]",
selected && "sdk:border-[var(--sdk-border-foreground)]! ",
// "sdk:border-b-[var(--sdk-bg-accent)]!",
'sdk:pb-[6px]',
"sdk:pb-[6px]",
"sdk:max-h-[300px] sdk:overflow-y-auto",
className
)}
Expand All @@ -97,7 +97,8 @@ export default function AevatarCardInner({
<ChevronDown
className={clsx(
"sdk:w-[16px] sdk:h-[16px] sdk:cursor-pointer sdk:transition-all sdk:duration-200 sdk:ease-in-out",
showMore && "sdk:rotate-180"
showMore && "sdk:rotate-180",
propertiesInfo.length <= 0 && "sdk:hidden"
)}
onClick={(e) => {
e.stopPropagation();
Expand Down
65 changes: 55 additions & 10 deletions packages/ui-react/src/components/Workflow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,18 @@ import {
TooltipTrigger,
} from "../ui/tooltip";
import { getPropertiesByDefaultValues } from "../../utils/jsonSchemaParse";
import { applyHorizontalLayout } from "./layoutUtils";
import { LayoutDashboard } from "lucide-react";

const getId = () => `${uuidv4()}`;

const fitViewOptions = {
padding: 0.1,
includeHiddenNodes: false,
minZoom: 0.1,
maxZoom: 1,
};

interface IProps {
gaevatarList?: IAgentInfoDetail[];
editWorkflow?: {
Expand Down Expand Up @@ -200,7 +209,7 @@ export const Workflow = forwardRef(
[onRemoveNode, setNodes, setEdges]
);

const { screenToFlowPosition } = useReactFlow();
const { screenToFlowPosition, fitView } = useReactFlow();
const [dragInfo] = useDnD();
const nodesRef = useRef<INode[]>(nodes);
const gaevatarListRef = useRef<IAgentInfoDetail[]>([]);
Expand Down Expand Up @@ -547,7 +556,7 @@ export const Workflow = forwardRef(
},
measured: {
width: 234,
height: 301,
height: 100,
},
}
: {
Expand All @@ -563,7 +572,7 @@ export const Workflow = forwardRef(
},
measured: {
width: 234,
height: 301,
height: 100,
},
};
setNodes((nds) => nds.concat(newNode as any));
Expand Down Expand Up @@ -607,7 +616,11 @@ export const Workflow = forwardRef(
const edgeTypes = useMemo(
() => ({
bezier: (edgeProps) => (
<CustomEdge {...edgeProps} isRunning={isRunning} setEdges={setEdges} />
<CustomEdge
{...edgeProps}
isRunning={isRunning}
setEdges={setEdges}
/>
),
}),
[setEdges, isRunning]
Expand Down Expand Up @@ -647,6 +660,16 @@ export const Workflow = forwardRef(
}
}, [redo, setNodes, setEdges, onRedoAction]);

const onFormatLayoutHandler = useCallback(() => {
if (nodes.length === 0) return;

const { nodes: layoutedNodes, edges: layoutedEdges } =
applyHorizontalLayout(nodes, edges);
setNodes(layoutedNodes);
setEdges(layoutedEdges);
fitView(fitViewOptions);
}, [nodes, edges, setNodes, fitView, setEdges]);

return (
<div
className={clsx(
Expand All @@ -670,12 +693,7 @@ export const Workflow = forwardRef(
// onDrop={onDrop} // Remove native onDrop
onDragOver={onDragOver}
fitView
fitViewOptions={{
padding: 0.1,
includeHiddenNodes: false,
minZoom: 0.1,
maxZoom: 1,
}}
fitViewOptions={fitViewOptions}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
defaultEdgeOptions={{ type: "bezier" }}
Expand Down Expand Up @@ -745,6 +763,33 @@ export const Workflow = forwardRef(
</Tooltip>
</TooltipProvider>

<TooltipProvider delayDuration={0}>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
className={clsx(
"sdk:cursor-pointer sdk:p-[7px]",
(nodes.length === 0 || isRunning) &&
"sdk:opacity-50 sdk:cursor-not-allowed"
)}
onClick={onFormatLayoutHandler}
disabled={nodes.length === 0 || isRunning}
aria-label="format layout">
<LayoutDashboard className="sdk:w-[14px] sdk:h-[14px]" />
</Button>
</TooltipTrigger>
<TooltipContent
className={clsx(
"sdk:z-1000 sdk:text-[12px] sdk:font-geist sdk:text-[var(--sdk-muted-foreground)] sdk:bg-[var(--sdk-color-bg-primary)] sdk:p-[4px]",
"sdk:whitespace-pre-wrap sdk:break-words sdk:text-left"
)}
side="top">
Format Layout
</TooltipContent>
</Tooltip>
</TooltipProvider>

<Button
variant="outline"
disabled={disabledRun}
Expand Down
50 changes: 50 additions & 0 deletions packages/ui-react/src/components/Workflow/layoutUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import dagre from "@dagrejs/dagre";
import type { Node, Edge } from "@xyflow/react";
const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));

// Define node dimensions for layout calculation
const NODE_WIDTH = 234;
const NODE_HEIGHT = 120;
/**
* Apply horizontal layout to workflow nodes using dagre
* @param nodes - Array of ReactFlow nodes
* @param edges - Array of ReactFlow edges
* @returns Updated nodes and edges with new positions
*/
export const applyHorizontalLayout = (
nodes: Node[],
edges: Edge[],
direction: "LR" | "TB" = "LR"
): { nodes: Node[]; edges: Edge[] } => {
const isHorizontal = direction === "LR";
dagreGraph.setGraph({ rankdir: direction });

nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT });
});

edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});

dagre.layout(dagreGraph);

const newNodes: Node[] = nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
const newNode: any = {
...node,
targetPosition: isHorizontal ? "left" : "top",
sourcePosition: isHorizontal ? "right" : "bottom",
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
position: {
x: nodeWithPosition.x - NODE_WIDTH / 2,
y: nodeWithPosition.y - NODE_HEIGHT / 2,
},
};

return newNode;
});

return { nodes: newNodes, edges };
};
2 changes: 1 addition & 1 deletion packages/ui-react/src/components/Workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const generateWorkflowGraph = (
},
measured: {
width: 234,
height: 301,
height: 100,
},
});
}
Expand Down
Loading