From 9af2c1252c03c2eac6c174ad937073c4e5158f19 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Wed, 29 Apr 2026 16:17:31 +0800 Subject: [PATCH] fix(web): remove node --- .../metric-section/__tests__/index.spec.tsx | 17 +++++++++++++++++ .../metric-section/builtin-metric-card.tsx | 17 +++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx b/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx index 6b240966bf..4cdf58a5dc 100644 --- a/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx +++ b/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx @@ -131,6 +131,23 @@ describe('MetricSection', () => { expect(screen.getByText('Answer Node')).toBeInTheDocument() }) + it('should remove the builtin metric when removing its last selected node', () => { + // Arrange + act(() => { + useEvaluationStore.getState().addBuiltinMetric(resourceType, resourceId, 'answer-correctness', [ + { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, + ]) + }) + + // Act + renderMetricSection() + fireEvent.click(screen.getByRole('button', { name: 'Answer Node' })) + + // Assert + expect(screen.queryByText('Answer Correctness')).not.toBeInTheDocument() + expect(useEvaluationStore.getState().resources[`${resourceType}:${resourceId}`]!.metrics).toHaveLength(0) + }) + it('should show only unselected nodes in the add-node dropdown and append the selected node', () => { // Arrange mockUseDefaultEvaluationMetrics.mockReturnValue({ diff --git a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx index eb661e3a14..8013ceb2af 100644 --- a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx +++ b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx @@ -39,6 +39,16 @@ const BuiltinMetricCard = ({ ? availableNodeInfoList.filter(nodeInfo => !selectedNodeIdSet.has(nodeInfo.node_id)) : [] const shouldShowAddNode = selectableNodeInfoList.length > 0 + const handleRemoveNode = (nodeId: string) => { + const nextSelectedNodeInfoList = selectedNodeInfoList.filter(item => item.node_id !== nodeId) + + if (nextSelectedNodeInfoList.length === 0) { + removeMetric(resourceType, resourceId, metric.id) + return + } + + updateBuiltinMetric(resourceType, resourceId, metric.optionId, nextSelectedNodeInfoList) + } return (
@@ -92,12 +102,7 @@ const BuiltinMetricCard = ({ type="button" className="flex h-4 w-4 items-center justify-center rounded-sm text-text-quaternary transition-colors hover:text-text-secondary" aria-label={nodeInfo.title} - onClick={() => updateBuiltinMetric( - resourceType, - resourceId, - metric.optionId, - selectedNodeInfoList.filter(item => item.node_id !== nodeInfo.node_id), - )} + onClick={() => handleRemoveNode(nodeInfo.node_id)} >