Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/simulation/workbench/components/amlModeToolbar.tsx
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Badge, Checkbox, Dropdown, Input, Option } from '@fluentui/react-components';
7
import * as mobxlite from 'mobx-react-lite';
8
import * as React from 'react';
9
import { useEffect, useMemo } from 'react';
10
import { AMLProvider } from '../stores/amlSimulations';
11
import { SimulationTestsProvider } from '../stores/simulationTestsProvider';
12
import { AMLPicker } from './amlPicker';
13
import { createAnnotationFilter, createFilterer, createLanguageFilter, createResultTypeFilter, createTestNameFilter } from './filterUtils';
14
import { TestFilterer } from './testFilterer';
15
16
type Props = {
17
amlProvider: AMLProvider;
18
simulationTestsProvider: SimulationTestsProvider;
19
onFiltererChange: (filterer: TestFilterer | undefined) => void;
20
allLanguageIds: readonly string[];
21
};
22
23
24
export const AMLModeToolbar = mobxlite.observer(({ amlProvider, simulationTestsProvider, onFiltererChange, allLanguageIds }: Props) => {
25
26
const [resultFilterSelected, setResultFilterSelected] = React.useState<string | undefined>(undefined);
27
const [languageSelected, setLanguageSelected] = React.useState<string | undefined>(undefined);
28
const [testNameFilterSelected, setTestNameFilterSelected] = React.useState<string | undefined>(undefined);
29
const [showOnlyTestsWithAnnotations, setShowOnlyTestsWithAnnotations] = React.useState<boolean | undefined>(undefined);
30
const [selectedAnnotations, setSelectedAnnotations] = React.useState<string[]>([]);
31
32
// Create a memoized filterer instance that only updates when filter criteria change
33
const filterer = useMemo(() => {
34
const predicates = [
35
createResultTypeFilter(resultFilterSelected),
36
createLanguageFilter(languageSelected),
37
createAnnotationFilter(showOnlyTestsWithAnnotations ? new Set(selectedAnnotations) : undefined),
38
createTestNameFilter(testNameFilterSelected)
39
];
40
41
return createFilterer(predicates);
42
}, [resultFilterSelected, languageSelected, showOnlyTestsWithAnnotations, selectedAnnotations, testNameFilterSelected]);
43
44
// Update parent component when filter changes
45
useEffect(() => {
46
onFiltererChange(filterer);
47
}, [filterer, onFiltererChange]);
48
49
const [knownAnnotations, setKnownAnnotations] = React.useState<string[]>([]);
50
const updateKnownAnnotations = () => {
51
const newAnnotations = new Set<string>(knownAnnotations);
52
for (const test of simulationTestsProvider.tests) {
53
if (test.runnerStatus) {
54
for (const run of test.runnerStatus.runs) {
55
for (const annotation of run.annotations) {
56
newAnnotations.add(annotation.label);
57
}
58
}
59
}
60
}
61
setKnownAnnotations([...newAnnotations].sort());
62
};
63
64
const onLanguageIdChange = (e: React.FormEvent<HTMLSelectElement>) => {
65
let langId: string | undefined = (e.target as HTMLSelectElement).value;
66
langId = langId !== 'no-language-filter' ? langId : undefined;
67
setLanguageSelected(langId);
68
};
69
70
const onResultFilterChange = (e: React.FormEvent<HTMLSelectElement>) => {
71
let resultFilter: string | undefined = (e.target as HTMLSelectElement).value;
72
resultFilter = resultFilter !== 'no-result-filter' ? resultFilter : undefined;
73
setResultFilterSelected(resultFilter);
74
};
75
76
const onTestNameFilterChange = (e: React.FormEvent<HTMLInputElement>) => {
77
let testNameFilter: string | undefined = (e.target as HTMLInputElement).value;
78
testNameFilter = testNameFilter !== '' ? testNameFilter : undefined;
79
setTestNameFilterSelected(testNameFilter);
80
};
81
82
const defaultLanguageId = (languageSelected && allLanguageIds.includes(languageSelected))
83
? languageSelected : undefined;
84
85
return (
86
<div className='toolbar' style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
87
<div>
88
<AMLPicker amlProvider={amlProvider} />
89
90
<div className='external-toolbar-filter'>
91
<label className='title'>Filter by test name</label>
92
<Input
93
id='grep'
94
size='small'
95
placeholder='grep'
96
title='Filter by test name'
97
value={testNameFilterSelected}
98
onChange={onTestNameFilterChange}
99
style={{ width: '100px', maxWidth: '25vw', marginLeft: '10px' }}
100
/>
101
</div>
102
103
<div className='external-toolbar-filter'>
104
<label className='title'>Filter by results</label>
105
<select className='external-toolbar-dropdown' onChange={onResultFilterChange} value={defaultLanguageId}>
106
<option value='no-result-filter' key='no-result-filter'>All</option>
107
<option key={'failures'} value={'failures'}>
108
{'Failures'}
109
</option>
110
<option key={'regressions'} value={'regressions'}>
111
{'Regressions'}
112
</option>
113
<option key={'improvements'} value={'improvements'}>
114
{'Improvements'}
115
</option>
116
<option key={'differences'} value={'differences'}>
117
{'Differences'}
118
</option>
119
</select>
120
</div>
121
122
<div className='external-toolbar-filter'>
123
<label className='title'>Filter by language</label>
124
<select className='external-toolbar-dropdown' onChange={onLanguageIdChange} value={defaultLanguageId}>
125
<option value='no-language-filter' key='no-language-filter'>All</option>
126
{allLanguageIds.map((langId) => (
127
<option key={langId} value={langId}>
128
{langId}
129
</option>
130
))}
131
</select>
132
</div>
133
<Checkbox
134
label='Filter by annotations'
135
checked={showOnlyTestsWithAnnotations}
136
onChange={() => setShowOnlyTestsWithAnnotations(!showOnlyTestsWithAnnotations)}
137
/>
138
<Dropdown
139
multiselect
140
size='small'
141
placeholder='Select annotations'
142
defaultValue={selectedAnnotations.length ? selectedAnnotations.join(', ') : undefined}
143
defaultSelectedOptions={selectedAnnotations}
144
onOptionSelect={(e, o) => { setSelectedAnnotations(o.selectedOptions); setShowOnlyTestsWithAnnotations(o.selectedOptions.length > 0); }}
145
onOpenChange={(e, o) => o.open && updateKnownAnnotations()}
146
>
147
{knownAnnotations.map((option) => (
148
<Option key={option} text={option}>
149
<Badge key={option} shape='square' appearance='outline' size='small'>{option}</Badge>
150
</Option>
151
))}
152
</Dropdown>
153
</div>
154
</div>
155
);
156
});
157
158