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
40 changes: 40 additions & 0 deletions apps/report/src/components/detail-side/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,32 @@
}
}

.title-collapsible {
cursor: pointer;
user-select: none;
display: flex;
align-items: center;

.collapse-icon {
font-size: 10px;
margin-left: 6px;
color: #00000073;
transition: transform 0.2s;
}

&:hover {
color: #1677ff;

.collapse-icon {
color: #1677ff;
}
}
}

.item-collapsible {
margin-bottom: 4px;
}

.subtitle {
padding-left: 20px;
font-weight: normal;
Expand Down Expand Up @@ -390,6 +416,20 @@
}
}

.title-collapsible {
.collapse-icon {
color: #9599a6;
}

&:hover {
color: #4096ff;

.collapse-icon {
color: #4096ff;
}
}
}

.subtitle {
color: #f8fafd;
}
Expand Down
110 changes: 43 additions & 67 deletions apps/report/src/components/detail-side/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
'use client';
import './index.less';

import { FileImageOutlined, RadiusSettingOutlined } from '@ant-design/icons';
import {
DownOutlined,
FileImageOutlined,
RadiusSettingOutlined,
RightOutlined,
} from '@ant-design/icons';
import { useState } from 'react';
import type {
ExecutionTaskAction,
ExecutionTaskInsightAssertion,
Expand All @@ -19,8 +25,6 @@ import { Tag, Tooltip } from 'antd';
import { fullTimeStrWithMilliseconds } from '../../../../../packages/visualizer/src/utils';
import { isElementField, useExecutionDump } from '../store';

const noop = () => {};

function isPlainObject(value: unknown): value is Record<string, any> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
Expand All @@ -30,19 +34,10 @@ const Card = (props: {
title?: string;
subtitle?: string;
characteristic?: string;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
content: any;
}) => {
const {
highlightWithColor,
title,
subtitle,
onMouseEnter,
onMouseLeave,
content,
characteristic,
} = props;
const { highlightWithColor, title, subtitle, content, characteristic } =
props;
const titleTag = props.characteristic ? (
<div className="item-extra">
<div className="title-tag">
Expand Down Expand Up @@ -70,8 +65,6 @@ const Card = (props: {
<div
className={`item ${modeClass} ${highlightWithColor ? 'item-highlight' : ''}`}
style={{ ...highlightStyle }}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
{/* {extraSection} */}

Expand All @@ -98,6 +91,35 @@ const Card = (props: {
);
};

// Collapsible card component for reasoning content (collapsed by default)
const CollapsibleCard = (props: {
title: string;
content: any;
defaultCollapsed?: boolean;
}) => {
const { title, content, defaultCollapsed = true } = props;
const [collapsed, setCollapsed] = useState(defaultCollapsed);

return (
<div className="item item-lite item-collapsible">
<div
className="title title-collapsible"
onClick={() => setCollapsed(!collapsed)}
>
{title}
<span className="collapse-icon">
{collapsed ? <RightOutlined /> : <DownOutlined />}
</span>
</div>
{!collapsed && (
<div className="description">
<pre className="description-content">{content}</pre>
</div>
)}
</div>
);
};

// Shared helper function to render element detail box
const renderElementDetailBox = (_value: LocateResultElement) => {
const hasCenter = _value.center && Array.isArray(_value.center);
Expand Down Expand Up @@ -601,8 +623,6 @@ const DetailSide = (): JSX.Element => {
<Card
liteMode={true}
title="error"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content" style={{ color: '#F00' }}>
{errorText}
Expand Down Expand Up @@ -665,33 +685,21 @@ const DetailSide = (): JSX.Element => {
<Card
liteMode={true}
title="thought"
onMouseEnter={noop}
onMouseLeave={noop}
content={<pre className="description-content">{thought}</pre>}
/>
)}

<Card
liteMode={true}
title="assertion result"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">
{JSON.stringify(output, undefined, 2)}
</pre>
}
/>
{reasoningContent && (
<Card
liteMode={true}
title="reasoning"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">{reasoningContent}</pre>
}
/>
<CollapsibleCard title="reasoning" content={reasoningContent} />
)}
</>
);
Expand All @@ -701,8 +709,6 @@ const DetailSide = (): JSX.Element => {
<Card
liteMode={true}
title=""
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content yaml-content">
{(task as ExecutionTaskPlanning).output?.yamlString}
Expand All @@ -720,8 +726,6 @@ const DetailSide = (): JSX.Element => {
key="thought"
liteMode={true}
title="thought"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">
{(task as ExecutionTaskPlanning).output?.thought || ''}
Expand All @@ -738,8 +742,6 @@ const DetailSide = (): JSX.Element => {
key="memory"
liteMode={true}
title="memory"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">
{(task as ExecutionTaskPlanning).output?.memory}
Expand All @@ -764,8 +766,6 @@ const DetailSide = (): JSX.Element => {
key="sub-goals"
liteMode={true}
title="sub-goals"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">{subGoalsContent}</pre>
}
Expand All @@ -782,8 +782,6 @@ const DetailSide = (): JSX.Element => {
key="mark-finished"
liteMode={true}
title="marked finished"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">
Sub-goal indexes: {markFinishedIndexes.join(', ')}
Expand Down Expand Up @@ -852,8 +850,6 @@ const DetailSide = (): JSX.Element => {
liteMode={true}
title={`${actionType}.${key}`}
subtitle={action.thought}
onMouseEnter={noop}
onMouseLeave={noop}
content={content}
/>,
);
Expand All @@ -875,8 +871,6 @@ const DetailSide = (): JSX.Element => {
liteMode={true}
title={typeStr(action as any)}
subtitle={action.thought}
onMouseEnter={noop}
onMouseLeave={noop}
content={nonObjectContent}
/>,
);
Expand All @@ -891,8 +885,6 @@ const DetailSide = (): JSX.Element => {
key="output-message"
liteMode={true}
title="output"
onMouseEnter={noop}
onMouseLeave={noop}
content={<pre className="description-content">{outputMessage}</pre>}
/>,
);
Expand All @@ -908,8 +900,6 @@ const DetailSide = (): JSX.Element => {
key="more-actions"
liteMode={true}
title="should continue planning"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">
{(task as ExecutionTaskPlanning).output?.shouldContinuePlanning
Expand All @@ -924,15 +914,10 @@ const DetailSide = (): JSX.Element => {
// Add reasoning at the end
if (reasoningContent) {
planItems.push(
<Card
<CollapsibleCard
key="reasoning"
liteMode={true}
title="reasoning"
onMouseEnter={noop}
onMouseLeave={noop}
content={
<pre className="description-content">{reasoningContent}</pre>
}
content={reasoningContent}
Comment on lines 916 to +920

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset collapsed state when switching tasks

Because CollapsibleCard keeps its own useState and is keyed as a constant (key="reasoning"), React will reuse the same instance when you switch between tasks that both have reasoning. That means if a user expands one task’s reasoning, the next task’s reasoning will stay expanded, which contradicts the “collapsed by default” behavior described in the PR. This shows up whenever you navigate between tasks in the detail panel. Consider keying by task identity (or resetting state in an effect when content changes) so each task’s reasoning starts collapsed.

Useful? React with 👍 / 👎.

/>,
);
}
Expand All @@ -959,8 +944,6 @@ const DetailSide = (): JSX.Element => {
<Card
key="thought"
liteMode={true}
onMouseEnter={noop}
onMouseLeave={noop}
content={<pre>{thought}</pre>}
title="thought"
/>,
Expand Down Expand Up @@ -1002,8 +985,6 @@ const DetailSide = (): JSX.Element => {
<Card
key={key}
liteMode={true}
onMouseEnter={noop}
onMouseLeave={noop}
title={key}
content={content}
/>,
Expand All @@ -1015,8 +996,6 @@ const DetailSide = (): JSX.Element => {
<Card
key="output"
liteMode={true}
onMouseEnter={noop}
onMouseLeave={noop}
title="output"
content={
<pre className="description-content">
Expand All @@ -1030,13 +1009,10 @@ const DetailSide = (): JSX.Element => {
// Add reasoning at the end
if (reasoningContent) {
outputItems.push(
<Card
<CollapsibleCard
key="reasoning"
liteMode={true}
onMouseEnter={noop}
onMouseLeave={noop}
content={<pre>{reasoningContent}</pre>}
title="reasoning"
content={reasoningContent}
/>,
);
}
Expand Down
Loading