fix: make mobile workflow node details full height
This commit is contained in:
@@ -1705,4 +1705,21 @@
|
|||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wf-editor-body--mobile-node-detail .wf-editor-canvas-wrap {
|
||||||
|
display: none;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wf-editor-body--mobile-node-detail .wf-editor-inspector {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
max-height: none;
|
||||||
|
border-left: none;
|
||||||
|
border-top: none;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1879,6 +1879,11 @@ function InnerEditor({
|
|||||||
}, [nodes, unplaced, serverNodeError, t]);
|
}, [nodes, unplaced, serverNodeError, t]);
|
||||||
|
|
||||||
const selectedNode = nodes.find((n) => n.id === selectedNodeId) ?? null;
|
const selectedNode = nodes.find((n) => n.id === selectedNodeId) ?? null;
|
||||||
|
const selectedNodeHasInspector =
|
||||||
|
selectedNode !== null &&
|
||||||
|
selectedNode.data.kind !== "start" &&
|
||||||
|
selectedNode.data.kind !== "end";
|
||||||
|
const mobileNodeDetailStage = isMobileViewport && selectedNodeHasInspector && !inspectorCollapsed;
|
||||||
const selectedEdge = edges.find((e) => e.id === selectedEdgeId) ?? null;
|
const selectedEdge = edges.find((e) => e.id === selectedEdgeId) ?? null;
|
||||||
const [isPromptExpanded, setIsPromptExpanded] = useState(false);
|
const [isPromptExpanded, setIsPromptExpanded] = useState(false);
|
||||||
const handleTogglePromptExpand = useCallback(() => {
|
const handleTogglePromptExpand = useCallback(() => {
|
||||||
@@ -2210,6 +2215,7 @@ function InnerEditor({
|
|||||||
<div
|
<div
|
||||||
className={`wf-editor-body${workflowListStageOpen ? " wf-editor-body--list-stage" : " wf-editor-body--editor-stage"}${
|
className={`wf-editor-body${workflowListStageOpen ? " wf-editor-body--list-stage" : " wf-editor-body--editor-stage"}${
|
||||||
simpleLayoutEnabled ? " wf-editor-body--simple-layout" : ""
|
simpleLayoutEnabled ? " wf-editor-body--simple-layout" : ""
|
||||||
|
}${mobileNodeDetailStage ? " wf-editor-body--mobile-node-detail" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<aside className="wf-editor-sidebar">
|
<aside className="wf-editor-sidebar">
|
||||||
@@ -2508,6 +2514,7 @@ function InnerEditor({
|
|||||||
onSelectNode={(id) => {
|
onSelectNode={(id) => {
|
||||||
setSelectedNodeId(id);
|
setSelectedNodeId(id);
|
||||||
setSelectedEdgeId(null);
|
setSelectedEdgeId(null);
|
||||||
|
setInspectorCollapsed(false);
|
||||||
}}
|
}}
|
||||||
onSelectEdge={(id) => {
|
onSelectEdge={(id) => {
|
||||||
setSelectedEdgeId(id);
|
setSelectedEdgeId(id);
|
||||||
@@ -3101,6 +3108,7 @@ function InnerEditor({
|
|||||||
onNodeClick={(_, node) => {
|
onNodeClick={(_, node) => {
|
||||||
setSelectedNodeId(node.id);
|
setSelectedNodeId(node.id);
|
||||||
setSelectedEdgeId(null);
|
setSelectedEdgeId(null);
|
||||||
|
setInspectorCollapsed(false);
|
||||||
}}
|
}}
|
||||||
onEdgeClick={(_, edge) => {
|
onEdgeClick={(_, edge) => {
|
||||||
setSelectedEdgeId(edge.id);
|
setSelectedEdgeId(edge.id);
|
||||||
@@ -3143,9 +3151,7 @@ function InnerEditor({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{selectedNode &&
|
{selectedNodeHasInspector &&
|
||||||
selectedNode.data.kind !== "start" &&
|
|
||||||
selectedNode.data.kind !== "end" &&
|
|
||||||
!(isMobileViewport && inspectorCollapsed) &&
|
!(isMobileViewport && inspectorCollapsed) &&
|
||||||
!(compactLayoutEnabled && !isMobileViewport) && (
|
!(compactLayoutEnabled && !isMobileViewport) && (
|
||||||
<aside className="wf-editor-inspector" data-testid="wf-node-inspector">
|
<aside className="wf-editor-inspector" data-testid="wf-node-inspector">
|
||||||
@@ -3157,7 +3163,13 @@ function InnerEditor({
|
|||||||
className="wf-inspector-toggle wf-inspector-toggle--expanded"
|
className="wf-inspector-toggle wf-inspector-toggle--expanded"
|
||||||
data-testid="wf-inspector-toggle"
|
data-testid="wf-inspector-toggle"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
onClick={() => setInspectorCollapsed(true)}
|
onClick={() => {
|
||||||
|
if (simpleLayoutEnabled) {
|
||||||
|
setSelectedNodeId(null);
|
||||||
|
} else {
|
||||||
|
setInspectorCollapsed(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ChevronDown size={13} />
|
<ChevronDown size={13} />
|
||||||
<span>{t("workflowNodes.collapseInspector", "Collapse")}</span>
|
<span>{t("workflowNodes.collapseInspector", "Collapse")}</span>
|
||||||
|
|||||||
@@ -100,6 +100,15 @@ describe("WorkflowNodeEditor mobile CSS contract", () => {
|
|||||||
expect(inspectorRule).toMatch(/flex\s*:\s*1 1 auto\s*;/);
|
expect(inspectorRule).toMatch(/flex\s*:\s*1 1 auto\s*;/);
|
||||||
expect(inspectorRule).toMatch(/min-height\s*:\s*0\s*;/);
|
expect(inspectorRule).toMatch(/min-height\s*:\s*0\s*;/);
|
||||||
|
|
||||||
|
const mobileDetailCanvasRule = findRule(mobileBlocks, /\.wf-editor-body--mobile-node-detail \.wf-editor-canvas-wrap\s*\{[^}]*\}/);
|
||||||
|
expect(mobileDetailCanvasRule).toMatch(/display\s*:\s*none\s*;/);
|
||||||
|
|
||||||
|
const mobileDetailInspectorRule = findRule(mobileBlocks, /\.wf-editor-body--mobile-node-detail \.wf-editor-inspector\s*\{[^}]*\}/);
|
||||||
|
expect(mobileDetailInspectorRule).toMatch(/display\s*:\s*flex\s*;/);
|
||||||
|
expect(mobileDetailInspectorRule).toMatch(/flex\s*:\s*1 1 auto\s*;/);
|
||||||
|
expect(mobileDetailInspectorRule).toMatch(/min-height\s*:\s*0\s*;/);
|
||||||
|
expect(mobileDetailInspectorRule).toMatch(/max-height\s*:\s*none\s*;/);
|
||||||
|
|
||||||
const collapsedToggleRule = findRule([editorCss], /\.wf-inspector-toggle--collapsed\s*\{[^}]*\}/);
|
const collapsedToggleRule = findRule([editorCss], /\.wf-inspector-toggle--collapsed\s*\{[^}]*\}/);
|
||||||
expect(collapsedToggleRule).toMatch(/position\s*:\s*absolute\s*;/);
|
expect(collapsedToggleRule).toMatch(/position\s*:\s*absolute\s*;/);
|
||||||
expect(collapsedToggleRule).toMatch(/bottom\s*:\s*var\(--space-sm\)\s*;/);
|
expect(collapsedToggleRule).toMatch(/bottom\s*:\s*var\(--space-sm\)\s*;/);
|
||||||
|
|||||||
@@ -499,18 +499,20 @@ describe("WorkflowNodeEditor", () => {
|
|||||||
render(<WorkflowNodeEditor isOpen onClose={() => {}} addToast={() => {}} />);
|
render(<WorkflowNodeEditor isOpen onClose={() => {}} addToast={() => {}} />);
|
||||||
|
|
||||||
fireEvent.click(await screen.findByRole("button", { name: "QA" }));
|
fireEvent.click(await screen.findByRole("button", { name: "QA" }));
|
||||||
fireEvent.click(await screen.findByTestId("wf-node-gate"));
|
const mobileGateRow = await screen.findByTestId("mobile-wf-node-lint");
|
||||||
|
fireEvent.click(within(mobileGateRow).getByRole("button"));
|
||||||
|
|
||||||
const inspector = await screen.findByTestId("wf-node-inspector");
|
const inspector = await screen.findByTestId("wf-node-inspector");
|
||||||
expect(within(inspector).getByLabelText("Prompt")).toBeInTheDocument();
|
expect(within(inspector).getByLabelText("Prompt")).toBeInTheDocument();
|
||||||
|
expect(inspector.closest(".wf-editor-body")).toHaveClass("wf-editor-body--mobile-node-detail");
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId("wf-inspector-toggle"));
|
fireEvent.click(screen.getByTestId("wf-inspector-toggle"));
|
||||||
|
|
||||||
await waitFor(() => expect(screen.queryByTestId("wf-node-inspector")).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByTestId("wf-node-inspector")).not.toBeInTheDocument());
|
||||||
expect(screen.queryByLabelText("Prompt")).not.toBeInTheDocument();
|
expect(screen.queryByLabelText("Prompt")).not.toBeInTheDocument();
|
||||||
expect(screen.getByTestId("wf-inspector-toggle")).toHaveAttribute("aria-expanded", "false");
|
expect(await screen.findByTestId("mobile-wf-graph")).toBeVisible();
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId("wf-inspector-toggle"));
|
fireEvent.click(within(await screen.findByTestId("mobile-wf-node-lint")).getByRole("button"));
|
||||||
|
|
||||||
expect(await screen.findByTestId("wf-node-inspector")).toBeInTheDocument();
|
expect(await screen.findByTestId("wf-node-inspector")).toBeInTheDocument();
|
||||||
expect(screen.getByTestId("wf-inspector-toggle")).toHaveAttribute("aria-expanded", "true");
|
expect(screen.getByTestId("wf-inspector-toggle")).toHaveAttribute("aria-expanded", "true");
|
||||||
@@ -523,13 +525,13 @@ describe("WorkflowNodeEditor", () => {
|
|||||||
render(<WorkflowNodeEditor isOpen onClose={() => {}} addToast={() => {}} />);
|
render(<WorkflowNodeEditor isOpen onClose={() => {}} addToast={() => {}} />);
|
||||||
|
|
||||||
fireEvent.click(await screen.findByRole("button", { name: "QA" }));
|
fireEvent.click(await screen.findByRole("button", { name: "QA" }));
|
||||||
fireEvent.click(await screen.findByTestId("wf-node-gate"));
|
fireEvent.click(within(await screen.findByTestId("mobile-wf-node-lint")).getByRole("button"));
|
||||||
expect(await screen.findByTestId("wf-node-inspector")).toBeInTheDocument();
|
expect(await screen.findByTestId("wf-node-inspector")).toBeInTheDocument();
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId("wf-inspector-toggle"));
|
fireEvent.click(screen.getByTestId("wf-inspector-toggle"));
|
||||||
await waitFor(() => expect(screen.queryByTestId("wf-node-inspector")).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByTestId("wf-node-inspector")).not.toBeInTheDocument());
|
||||||
|
|
||||||
fireEvent.click(await screen.findByTestId("wf-node-merge"));
|
fireEvent.click(within(await screen.findByTestId("mobile-wf-node-merge")).getByRole("button"));
|
||||||
|
|
||||||
const inspector = await screen.findByTestId("wf-node-inspector");
|
const inspector = await screen.findByTestId("wf-node-inspector");
|
||||||
expect(within(inspector).getByLabelText("Name")).toBeInTheDocument();
|
expect(within(inspector).getByLabelText("Name")).toBeInTheDocument();
|
||||||
|
|||||||
Reference in New Issue
Block a user