From 064b807ea4f4b8cf7291b338d77e02a894def583 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sat, 4 Apr 2026 16:45:36 -0400 Subject: [PATCH] Move search state into ToolControls and PromptControls, search response in history - ToolControls and PromptControls now manage searchText as local state and filter their lists internally (matches on name + title/description) - Removed searchText/onSearchChange props from ToolsScreen, PromptsScreen, and their associated stories - HistoryListPanel search now also matches against stringified response payloads Co-Authored-By: Claude Opus 4.6 (1M context) --- .../groups/HistoryListPanel/HistoryListPanel.tsx | 3 ++- .../PromptControls/PromptControls.stories.tsx | 3 --- .../groups/PromptControls/PromptControls.tsx | 15 ++++++++------- .../groups/ToolControls/ToolControls.stories.tsx | 3 --- .../groups/ToolControls/ToolControls.tsx | 15 ++++++++------- .../PromptsScreen/PromptsScreen.stories.tsx | 2 -- .../screens/PromptsScreen/PromptsScreen.tsx | 6 ------ .../screens/ToolsScreen/ToolsScreen.stories.tsx | 2 -- .../screens/ToolsScreen/ToolsScreen.tsx | 6 ------ .../views/ConnectedView/ConnectedView.stories.tsx | 4 ---- 10 files changed, 18 insertions(+), 41 deletions(-) diff --git a/clients/web/src/components/groups/HistoryListPanel/HistoryListPanel.tsx b/clients/web/src/components/groups/HistoryListPanel/HistoryListPanel.tsx index a249572d..e0094a9a 100644 --- a/clients/web/src/components/groups/HistoryListPanel/HistoryListPanel.tsx +++ b/clients/web/src/components/groups/HistoryListPanel/HistoryListPanel.tsx @@ -59,8 +59,9 @@ function matchesFilters( if (methodFilter && entry.method !== methodFilter) return false; if (searchText) { const term = searchText.toLowerCase(); + const responseText = entry.response ? JSON.stringify(entry.response) : ""; const searchable = - `${entry.method} ${entry.target ?? ""} ${entry.timestamp}`.toLowerCase(); + `${entry.method} ${entry.target ?? ""} ${entry.timestamp} ${responseText}`.toLowerCase(); if (!searchable.includes(term)) return false; } return true; diff --git a/clients/web/src/components/groups/PromptControls/PromptControls.stories.tsx b/clients/web/src/components/groups/PromptControls/PromptControls.stories.tsx index 53b85908..04d8c994 100644 --- a/clients/web/src/components/groups/PromptControls/PromptControls.stories.tsx +++ b/clients/web/src/components/groups/PromptControls/PromptControls.stories.tsx @@ -6,8 +6,6 @@ const meta: Meta = { title: "Groups/PromptControls", component: PromptControls, args: { - searchText: "", - onSearchChange: fn(), onRefreshList: fn(), onSelectPrompt: fn(), listChanged: false, @@ -58,7 +56,6 @@ export const WithSelection: Story = { export const WithSearch: Story = { args: { prompts: samplePrompts, - searchText: "sum", }, }; diff --git a/clients/web/src/components/groups/PromptControls/PromptControls.tsx b/clients/web/src/components/groups/PromptControls/PromptControls.tsx index fb445030..68ea074c 100644 --- a/clients/web/src/components/groups/PromptControls/PromptControls.tsx +++ b/clients/web/src/components/groups/PromptControls/PromptControls.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import { Group, ScrollArea, Stack, TextInput, Title } from "@mantine/core"; import { ListChangedIndicator } from "../../elements/ListChangedIndicator/ListChangedIndicator"; import { PromptListItem } from "../PromptListItem/PromptListItem"; @@ -6,8 +7,6 @@ import type { PromptItem } from "../../screens/PromptsScreen/PromptsScreen"; export interface PromptControlsProps { prompts: PromptItem[]; listChanged: boolean; - searchText: string; - onSearchChange: (text: string) => void; onRefreshList: () => void; onSelectPrompt: (name: string) => void; } @@ -19,13 +18,15 @@ function listMaxHeight(): string { export function PromptControls({ prompts, listChanged, - searchText, - onSearchChange, onRefreshList, onSelectPrompt, }: PromptControlsProps) { - const filteredPrompts = prompts.filter((p) => - p.name.toLowerCase().includes(searchText.toLowerCase()), + const [searchText, setSearchText] = useState(""); + const query = searchText.toLowerCase(); + const filteredPrompts = prompts.filter( + (p) => + p.name.toLowerCase().includes(query) || + (p.description?.toLowerCase().includes(query) ?? false), ); return ( @@ -37,7 +38,7 @@ export function PromptControls({ onSearchChange(e.currentTarget.value)} + onChange={(e) => setSearchText(e.currentTarget.value)} /> diff --git a/clients/web/src/components/groups/ToolControls/ToolControls.stories.tsx b/clients/web/src/components/groups/ToolControls/ToolControls.stories.tsx index 33be2c4d..9a5cc96a 100644 --- a/clients/web/src/components/groups/ToolControls/ToolControls.stories.tsx +++ b/clients/web/src/components/groups/ToolControls/ToolControls.stories.tsx @@ -6,8 +6,6 @@ const meta: Meta = { title: "Groups/ToolControls", component: ToolControls, args: { - searchText: "", - onSearchChange: fn(), onRefreshList: fn(), onSelectTool: fn(), listChanged: false, @@ -52,7 +50,6 @@ export const WithSelection: Story = { export const WithSearch: Story = { args: { tools: sampleTools, - searchText: "send", }, }; diff --git a/clients/web/src/components/groups/ToolControls/ToolControls.tsx b/clients/web/src/components/groups/ToolControls/ToolControls.tsx index 590140d7..33db7738 100644 --- a/clients/web/src/components/groups/ToolControls/ToolControls.tsx +++ b/clients/web/src/components/groups/ToolControls/ToolControls.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import { Group, ScrollArea, Stack, TextInput, Title } from "@mantine/core"; import { ListChangedIndicator } from "../../elements/ListChangedIndicator/ListChangedIndicator"; import { ToolListItem } from "../ToolListItem/ToolListItem"; @@ -6,8 +7,6 @@ import type { ToolListItemProps } from "../ToolListItem/ToolListItem"; export interface ToolControlsProps { tools: ToolListItemProps[]; listChanged: boolean; - searchText: string; - onSearchChange: (text: string) => void; onRefreshList: () => void; onSelectTool: (name: string) => void; } @@ -19,14 +18,16 @@ function listMaxHeight(): string { export function ToolControls({ tools, listChanged, - searchText, - onSearchChange, onRefreshList, onSelectTool, }: ToolControlsProps) { + const [searchText, setSearchText] = useState(""); + const query = searchText.toLowerCase(); const filteredTools = searchText - ? tools.filter((tool) => - tool.name.toLowerCase().includes(searchText.toLowerCase()), + ? tools.filter( + (tool) => + tool.name.toLowerCase().includes(query) || + (tool.title?.toLowerCase().includes(query) ?? false), ) : tools; @@ -39,7 +40,7 @@ export function ToolControls({ onSearchChange(e.currentTarget.value)} + onChange={(e) => setSearchText(e.currentTarget.value)} /> diff --git a/clients/web/src/components/screens/PromptsScreen/PromptsScreen.stories.tsx b/clients/web/src/components/screens/PromptsScreen/PromptsScreen.stories.tsx index ece2ee01..0185f80b 100644 --- a/clients/web/src/components/screens/PromptsScreen/PromptsScreen.stories.tsx +++ b/clients/web/src/components/screens/PromptsScreen/PromptsScreen.stories.tsx @@ -8,8 +8,6 @@ const meta: Meta = { component: PromptsScreen, parameters: { layout: "fullscreen" }, args: { - searchText: "", - onSearchChange: fn(), onRefreshList: fn(), onSelectPrompt: fn(), onArgumentChange: fn(), diff --git a/clients/web/src/components/screens/PromptsScreen/PromptsScreen.tsx b/clients/web/src/components/screens/PromptsScreen/PromptsScreen.tsx index 43df30f7..fdedc376 100644 --- a/clients/web/src/components/screens/PromptsScreen/PromptsScreen.tsx +++ b/clients/web/src/components/screens/PromptsScreen/PromptsScreen.tsx @@ -23,8 +23,6 @@ export interface PromptsScreenProps { selectedPrompt?: SelectedPrompt; messages?: PromptMessagesDisplayProps; listChanged: boolean; - searchText: string; - onSearchChange: (text: string) => void; onRefreshList: () => void; onSelectPrompt: (name: string) => void; onArgumentChange: (name: string, value: string) => void; @@ -64,8 +62,6 @@ export function PromptsScreen({ selectedPrompt, messages, listChanged, - searchText, - onSearchChange, onRefreshList, onSelectPrompt, onArgumentChange, @@ -78,8 +74,6 @@ export function PromptsScreen({ diff --git a/clients/web/src/components/screens/ToolsScreen/ToolsScreen.stories.tsx b/clients/web/src/components/screens/ToolsScreen/ToolsScreen.stories.tsx index 41e00163..a1725a02 100644 --- a/clients/web/src/components/screens/ToolsScreen/ToolsScreen.stories.tsx +++ b/clients/web/src/components/screens/ToolsScreen/ToolsScreen.stories.tsx @@ -10,9 +10,7 @@ const meta: Meta = { component: ToolsScreen, parameters: { layout: "fullscreen" }, args: { - searchText: "", listChanged: false, - onSearchChange: fn(), onRefreshList: fn(), onSelectTool: fn(), }, diff --git a/clients/web/src/components/screens/ToolsScreen/ToolsScreen.tsx b/clients/web/src/components/screens/ToolsScreen/ToolsScreen.tsx index fe757c14..e6636cfe 100644 --- a/clients/web/src/components/screens/ToolsScreen/ToolsScreen.tsx +++ b/clients/web/src/components/screens/ToolsScreen/ToolsScreen.tsx @@ -11,8 +11,6 @@ export interface ToolsScreenProps { selectedTool?: ToolDetailPanelProps; result?: ToolResultPanelProps; listChanged: boolean; - searchText: string; - onSearchChange: (text: string) => void; onRefreshList: () => void; onSelectTool: (name: string) => void; } @@ -51,8 +49,6 @@ export function ToolsScreen({ selectedTool, result, listChanged, - searchText, - onSearchChange, onRefreshList, onSelectTool, }: ToolsScreenProps) { @@ -63,8 +59,6 @@ export function ToolsScreen({ diff --git a/clients/web/src/components/views/ConnectedView/ConnectedView.stories.tsx b/clients/web/src/components/views/ConnectedView/ConnectedView.stories.tsx index cc47773a..7356c07c 100644 --- a/clients/web/src/components/views/ConnectedView/ConnectedView.stories.tsx +++ b/clients/web/src/components/views/ConnectedView/ConnectedView.stories.tsx @@ -394,9 +394,7 @@ export const ToolsActive: Story = { ], onClear: fn(), }} - searchText="" listChanged={true} - onSearchChange={fn()} onRefreshList={fn()} onSelectTool={fn()} /> @@ -677,8 +675,6 @@ export const PromptsActive: Story = { ], }} listChanged={true} - searchText="" - onSearchChange={fn()} onRefreshList={fn()} onSelectPrompt={fn()} onArgumentChange={fn()}