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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: CI

on:
push:
branches:
- main
paths-ignore:
- "conductor-clients/**"
pull_request:
Expand Down
20 changes: 0 additions & 20 deletions ui-next/src/components/ui/Banner.jsx

This file was deleted.

35 changes: 2 additions & 33 deletions ui-next/src/pages/definition/EditorPanel/AssistantPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Box } from "@mui/material";
import Agent from "components/features/agent/Agent";
import { AgentDisplayMode } from "components/features/agent/agent-types";
import React, { useEffect, useRef } from "react";
import React from "react";
import { ActorRef } from "xstate";
import { WorkflowDefinitionEvents } from "../state/types";
import { AssistantPanelHeader } from "./AssistantPanelHeader";

export const SHRINKED_HEIGHT = 430;

interface AssistantPanelProps {
isAgentExpanded: boolean;
agentPanelHeight: number | null;
Expand All @@ -18,7 +16,6 @@ interface AssistantPanelProps {
onHeaderClick: (e: React.MouseEvent) => void;
onToggleExpanded: () => void;
onMaximize: () => void;
onHeightChange: (height: number) => void;
isResizing: boolean;
}

Expand All @@ -32,34 +29,10 @@ export const AssistantPanel = ({
onHeaderClick,
onToggleExpanded,
onMaximize,
onHeightChange,
isResizing,
}: AssistantPanelProps) => {
const agentPanelRef = useRef<HTMLDivElement>(null);

// Handle clicks outside the assistant panel to resize it to SHRINKED_HEIGHT (currently 430px)
useEffect(() => {
if (!isAgentExpanded) return;

const handleClickOutside = (event: MouseEvent) => {
if (
agentPanelRef.current &&
!agentPanelRef.current.contains(event.target as Node) &&
!isResizing
) {
onHeightChange(SHRINKED_HEIGHT);
}
};

document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isAgentExpanded, isResizing, onHeightChange]);

return (
<Box
ref={agentPanelRef}
sx={{
position: "absolute",
display: "flex",
Expand All @@ -73,11 +46,7 @@ export const AssistantPanel = ({
: errorInspectorActor
? `calc(100% - ${tabsHeight}px - 50px)`
: `calc(100% - ${tabsHeight}px)`
: "50px", // Fixed height when collapsed for smooth animation
top:
isAgentExpanded && agentPanelHeight === null
? `${tabsHeight}px`
: "auto",
: "50px",
background: "#ffffff",
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EditEvent,
DebounceEditEvent,
CodeMachineEventTypes,
ForceWorkflowEvent,
HighlightTextReferenceEvent,
} from "./types";
import { ErrorInspectorEventTypes } from "pages/definition/errorInspector/state/types";
Expand Down Expand Up @@ -39,3 +40,10 @@ export const checkForErrorsInWorkflow = send<CodeMachineContext, any>(
);

export const cancelDebounceEditChanges = cancel("debounce_edit_event");

export const forceWorkflowChanges = assign<
CodeMachineContext,
ForceWorkflowEvent
>({
editorChanges: (_, { workflow }) => JSON.stringify(workflow, null, 2),
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export const codeMachine = createMachine<CodeMachineContext, CodeMachineEvents>(
[CodeMachineEventTypes.JUMP_TO_FIRST_ERROR]: {
target: ".showFirstError",
},
[CodeMachineEventTypes.FORCE_WORKFLOW]: {
actions: ["forceWorkflowChanges"],
},
},
initial: "idle",
states: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export enum CodeMachineEventTypes {
EDIT_DEBOUNCE_EVT = "EDIT_DEBOUNCE_EVT",
HIGHLIGHT_TEXT_REFERENCE = "HIGHLIGHT_TEXT_REFERENCE",
JUMP_TO_FIRST_ERROR = "JUMP_TO_FIRST_ERROR",
FORCE_WORKFLOW = "FORCE_WORKFLOW",
}

export type EditEvent = {
Expand All @@ -44,9 +45,15 @@ export type JumpToFirstErrorEvent = {
type: CodeMachineEventTypes.JUMP_TO_FIRST_ERROR;
};

export type ForceWorkflowEvent = {
type: CodeMachineEventTypes.FORCE_WORKFLOW;
workflow: Partial<WorkflowDef>;
};

export type CodeMachineEvents =
| EditEvent
| DebounceEditEvent
| WorkflowWithNoErrorsEvent
| HighlightTextReferenceEvent
| JumpToFirstErrorEvent;
| JumpToFirstErrorEvent
| ForceWorkflowEvent;
122 changes: 42 additions & 80 deletions ui-next/src/pages/definition/EditorPanel/EditorPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { Box } from "@mui/material";
import { useSelector } from "@xstate/react";
import React, {
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { colors } from "theme/tokens/variables";
import { FEATURES, featureFlags, logger } from "utils";
import { FEATURES, featureFlags } from "utils";
import { ActorRef, EventObject, State } from "xstate";
import ErrorInspector from "../errorInspector/ErrorInspector";
import {
DefinitionMachineContext,
DefinitionMachineEventTypes,
WorkflowDefinitionEvents,
} from "../state/types";
import { AssistantPanel, SHRINKED_HEIGHT } from "./AssistantPanel";
import { AssistantPanel } from "./AssistantPanel";
import { ConfirmationDialogs } from "./ConfirmationDialogs";
import { EditorTabs } from "./EditorTabs";
import { TabContent } from "./TabContent";
Expand Down Expand Up @@ -109,6 +102,7 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
} | null>(null);
const shouldHandleClickRef = useRef<{ wasCollapsed: boolean } | null>(null);
const editorPanelContainerRef = useRef<HTMLDivElement>(null);
const isMountedRef = useRef(false);

// Handle document-level mouse events during resize
// Note: We use refs (wasCollapsed) instead of XState state (isAgentExpanded) during drag
Expand Down Expand Up @@ -197,18 +191,19 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
}, [isResizing, handleMouseMove, handleMouseUp]);

useEffect(() => {
if (!tabsContainerRef.current) return;

const updateTabsHeight = () => {
if (tabsContainerRef.current) {
const height = tabsContainerRef.current.offsetHeight || 48;
setTabsHeight((prev) => (prev !== height ? height : prev));
}
};
const el = tabsContainerRef.current;
if (!el) return;

const resizeObserver = new ResizeObserver((entries) => {
const height =
entries[0]?.borderBoxSize?.[0]?.blockSize ??
entries[0]?.contentRect?.height ??
el.offsetHeight ??
48;
setTabsHeight((prev) => (prev !== height ? height : prev));
});

updateTabsHeight();
const resizeObserver = new ResizeObserver(updateTabsHeight);
resizeObserver.observe(tabsContainerRef.current);
resizeObserver.observe(el);

return () => {
resizeObserver.disconnect();
Expand All @@ -227,8 +222,6 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
);
};

logger.debug("Rendering Editor Panel");

const handleResetConfirmation = (val: boolean) =>
(val ? handleConfirmReset : handleCancelRequest)();

Expand All @@ -249,24 +242,23 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
state.context.errorInspectorMachine,
);

// When auto-expanded (e.g. new workflow) with no height set, measure container and set full height
useLayoutEffect(() => {
if (!isAgentExpanded || agentPanelHeight !== null) return;
if (!editorPanelContainerRef.current) return;
const containerRect =
editorPanelContainerRef.current.getBoundingClientRect();
const maxHeight =
containerRect.height - tabsHeight - (errorInspectorActor ? 50 : 0);
if (maxHeight > 0) setAgentPanelHeight(maxHeight);
}, [isAgentExpanded, agentPanelHeight, tabsHeight, errorInspectorActor]);

// Effective height: use measured value when expanded, or explicit agentPanelHeight
const effectiveAgentPanelHeight = useMemo(() => {
if (isAgentExpanded && agentPanelHeight === null) {
return SHRINKED_HEIGHT;
// Persist expanded state so it survives navigation to a new workflow
useEffect(() => {
localStorage.setItem("agentExpanded", String(isAgentExpanded));
}, [isAgentExpanded]);

// Reset height when navigating to a different workflow so the layout effect re-measures.
// Skip on initial mount — agentPanelHeight is already null and the layout effect below
// has already run (effects execute after layout effects, so resetting here would undo it).
useEffect(() => {
if (!isMountedRef.current) {
isMountedRef.current = true;
return;
}
return agentPanelHeight;
}, [isAgentExpanded, agentPanelHeight]);
setAgentPanelHeight(null);
}, [definitionActor]);

const effectiveAgentPanelHeight = agentPanelHeight;

// Calculate available height for tab content (accounting for error inspector and assistant panel)
const getTabContentHeight = useCallback(() => {
Expand Down Expand Up @@ -299,41 +291,16 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {

// When collapsed, start with collapsed height (50px)
// When expanded, use current height or maxHeight
const startHeight = isAgentExpanded ? agentPanelHeight || maxHeight : 50; // Collapsed height

// If starting from collapsed, calculate initial height based on mouse position
// This prevents the panel from using calc() value when it expands
if (!isAgentExpanded && agentPanelHeight === null) {
// Calculate height based on distance from bottom of container
// Mouse Y position relative to container bottom
const mouseYFromBottom = containerRect.bottom - e.clientY;
// Initial height is the distance from bottom, clamped between min and max
const initialHeight = Math.max(
200,
Math.min(maxHeight, mouseYFromBottom),
);
// Set height immediately so it's available when panel expands
setAgentPanelHeight(initialHeight);
// Store resize state with collapsed height as start point
resizeStateRef.current = {
startY: e.clientY,
startHeight: 50, // Use 50px (collapsed height) as starting point for drag calculations
maxHeight,
containerRect,
wasCollapsed: true,
hasExpanded: false,
};
} else {
// Store resize state in refs for the useEffect to use
resizeStateRef.current = {
startY: e.clientY,
startHeight,
maxHeight,
containerRect,
wasCollapsed: !isAgentExpanded,
hasExpanded: false,
};
}
const startHeight = isAgentExpanded ? agentPanelHeight || maxHeight : 50;

resizeStateRef.current = {
startY: e.clientY,
startHeight,
maxHeight,
containerRect,
wasCollapsed: !isAgentExpanded,
hasExpanded: false,
};

resizeStartRef.current = { x: e.clientX, y: e.clientY };
isResizingRef.current = false;
Expand Down Expand Up @@ -402,10 +369,6 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
setAgentPanelHeight(maxHeight);
}, [tabsHeight, errorInspectorActor]);

const handleHeightChange = useCallback((height: number) => {
setAgentPanelHeight(height);
}, []);

return (
<>
{isResizing && (
Expand Down Expand Up @@ -489,7 +452,6 @@ const EditorPanel = ({ definitionActor }: EditorPanelProps) => {
onHeaderClick={handleHeaderClick}
onToggleExpanded={handleToggleExpanded}
onMaximize={handleMaximize}
onHeightChange={handleHeightChange}
isResizing={isResizing}
/>
)}
Expand Down
Loading
Loading