From d8d410db6e217b1821fa890c63c057dc65eccda3 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Sat, 4 Mar 2023 19:39:55 -0800 Subject: [PATCH] chore: implement project filter (#21402) --- packages/trace-viewer/src/ui/watchMode.tsx | 125 +++++++++++++-------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/packages/trace-viewer/src/ui/watchMode.tsx b/packages/trace-viewer/src/ui/watchMode.tsx index b971ce9658..4d5fffb1e2 100644 --- a/packages/trace-viewer/src/ui/watchMode.tsx +++ b/packages/trace-viewer/src/ui/watchMode.tsx @@ -27,20 +27,19 @@ import './watchMode.css'; import { ToolbarButton } from '@web/components/toolbarButton'; import { Toolbar } from '@web/components/toolbar'; -let rootSuite: Suite | undefined; - -let updateList: () => void = () => {}; +let updateRootSuite: (rootSuite: Suite) => void = () => {}; let updateProgress: () => void = () => {}; let runWatchedTests = () => {}; -const expandedItems = new Map(); export const WatchModeView: React.FC<{}> = ({ }) => { - const [updateCounter, setUpdateCounter] = React.useState(0); - updateList = () => setUpdateCounter(updateCounter + 1); + const [rootSuite, setRootSuite] = React.useState<{ value: Suite | undefined }>({ value: undefined }); + updateRootSuite = (rootSuite: Suite) => setRootSuite({ value: rootSuite }); const [selectedTreeItemId, setSelectedTreeItemId] = React.useState(); const [isRunningTest, setIsRunningTest] = React.useState(false); const [filterText, setFilterText] = React.useState(''); + const [projectNames, setProjectNames] = React.useState([]); + const [expandedItems, setExpandedItems] = React.useState>(new Map()); const inputRef = React.useRef(null); @@ -49,10 +48,13 @@ export const WatchModeView: React.FC<{}> = ({ sendMessageNoReply('list'); }, []); - const { treeItemMap, visibleTestIds, listItems } = React.useMemo(() => { - // updateCounter is used to trigger the compute. - noop(updateCounter); - const treeItems = createTree(rootSuite); + React.useEffect(() => { + if (projectNames.length === 0 && rootSuite.value?.suites.length) + setProjectNames([rootSuite.value?.suites[0].title]); + }, [projectNames, rootSuite]); + + const { filteredItems, treeItemMap, visibleTestIds } = React.useMemo(() => { + const treeItems = createTree(rootSuite.value, projectNames); const filteredItems = filterTree(treeItems, filterText); const treeItemMap = new Map(); @@ -64,9 +66,14 @@ export const WatchModeView: React.FC<{}> = ({ treeItemMap.set(treeItem.id, treeItem); }; filteredItems.forEach(visit); + return { treeItemMap, visibleTestIds, filteredItems }; + }, [filterText, rootSuite, projectNames]); + + + const { listItems } = React.useMemo(() => { const listItems = flattenTree(filteredItems, expandedItems, !!filterText.trim()); - return { treeItemMap, visibleTestIds, listItems }; - }, [filterText, updateCounter]); + return { listItems }; + }, [filteredItems, filterText, expandedItems]); const selectedTreeItem = selectedTreeItemId ? treeItemMap.get(selectedTreeItemId) : undefined; @@ -136,16 +143,19 @@ export const WatchModeView: React.FC<{}> = ({ selectedItem={selectedTreeItem} onAccepted={runTreeItem} onLeftArrow={(treeItem: TreeItem) => { - if (treeItem.children && treeItem.expanded) + if (treeItem.children && treeItem.expanded) { expandedItems.set(treeItem.id, false); - else + setExpandedItems(new Map(expandedItems)); + } else { setSelectedTreeItemId(treeItem.parent?.id); - updateList(); + } }} onRightArrow={(treeItem: TreeItem) => { - if (treeItem.children) + if (treeItem.children) { expandedItems.set(treeItem.id, true); - updateList(); + setExpandedItems(new Map(expandedItems)); + } + setRootSuite({ ...rootSuite }); }} onSelected={(treeItem: TreeItem) => { setSelectedTreeItemId(treeItem.id); @@ -157,9 +167,25 @@ export const WatchModeView: React.FC<{}> = ({ expandedItems.set(treeItem.id, false); else expandedItems.set(treeItem.id, true); - updateList(); + setExpandedItems(new Map(expandedItems)); }} showNoItemsMessage={true}> + {(rootSuite.value?.suites.length || 0) > 1 &&
+ { + const copy = [...projectNames]; + copy.includes(suite.title) ? copy.splice(copy.indexOf(suite.title), 1) : copy.push(suite.title); + setProjectNames(copy); + }} + itemRender={(suite: Suite) => { + return ; + }} + /> +
} ; }; @@ -229,37 +255,40 @@ declare global { } } -const receiver = new TeleReporterReceiver({ - onBegin: (config: FullConfig, suite: Suite) => { - if (!rootSuite) - rootSuite = suite; - updateList(); - }, +{ + let rootSuite: Suite; + const receiver = new TeleReporterReceiver({ + onBegin: (config: FullConfig, suite: Suite) => { + if (!rootSuite) + rootSuite = suite; + updateRootSuite(rootSuite); + }, - onTestBegin: () => { - updateList(); - }, + onTestBegin: () => { + updateRootSuite(rootSuite); + }, - onTestEnd: () => { - updateList(); - }, + onTestEnd: () => { + updateRootSuite(rootSuite); + }, - onStepBegin: () => { - updateProgress(); - }, + onStepBegin: () => { + updateProgress(); + }, - onStepEnd: () => { - updateProgress(); - }, -}); + onStepEnd: () => { + updateProgress(); + }, + }); -(window as any).dispatch = (message: any) => { - if (message.method === 'fileChanged') - runWatchedTests(); - else - receiver.dispatch(message); -}; + (window as any).dispatch = (message: any) => { + if (message.method === 'fileChanged') + runWatchedTests(); + else + receiver.dispatch(message); + }; +} const sendMessage = async (method: string, params: any) => { await (window as any).sendMessage({ method, params }); @@ -318,9 +347,11 @@ type TestItem = TreeItemBase & { type TreeItem = FileItem | TestCaseItem | TestItem; -function createTree(rootSuite?: Suite): FileItem[] { +function createTree(rootSuite: Suite | undefined, projectNames: string[]): FileItem[] { const fileItems = new Map(); for (const projectSuite of rootSuite?.suites || []) { + if (!projectNames.includes(projectSuite.title)) + continue; for (const fileSuite of projectSuite.suites) { const file = fileSuite.location!.file; @@ -391,8 +422,8 @@ function flattenTree(fileItems: FileItem[], expandedItems: Map