Path: blob/main/extensions/copilot/test/simulation/workbench/components/app.tsx
13399 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Checkbox, FluentProvider, MessageBar, MessageBarBody, MessageBarTitle, Text, ToggleButton, Tooltip, webDarkTheme, webLightTheme } from '@fluentui/react-components';6import { ListBar20Filled, ListBarTree20Filled } from '@fluentui/react-icons';7import * as mobx from 'mobx';8import * as mobxlite from 'mobx-react-lite';9import * as React from 'react';10import { InitArgs } from '../initArgs';11import { AMLProvider } from '../stores/amlSimulations';12import { NesExternalOptions } from '../stores/nesExternalOptions';13import { RunnerOptions } from '../stores/runnerOptions';14import { SimulationRunsProvider } from '../stores/simulationBaseline';15import { SimulationRunner } from '../stores/simulationRunner';16import { SimulationStorage, SimulationStorageValue } from '../stores/simulationStorage';17import { ISimulationTest, SimulationTestsProvider } from '../stores/simulationTestsProvider';18import { useLocalStorageState } from '../stores/storage';19import { TestSource } from '../stores/testSource';20import { ContextMenu, ContextMenuProvider } from './contextMenu';21import { Scorecard } from './scorecard';22import { ScorecardByLanguage } from './scorecardByLanguage';23import { TestFilterer } from './testFilterer';24import { TestList } from './testList';25import { Toolbar } from './toolbar';2627type Props = {28initArgs: InitArgs | undefined;29testsProvider: SimulationTestsProvider;30runner: SimulationRunner;31runnerOptions: RunnerOptions;32nesExternalOptions: NesExternalOptions;33simulationRunsProvider: SimulationRunsProvider;34amlProvider: AMLProvider;35displayOptions: DisplayOptions;36};3738export type ThemeKind = 'light' | 'dark';3940export const App = mobxlite.observer(41({ initArgs, testsProvider, runner, runnerOptions, nesExternalOptions, simulationRunsProvider, amlProvider, displayOptions }: Props) => {4243const [theme, setTheme] = useLocalStorageState<ThemeKind>('appTheme', undefined, 'light');4445const [filterer, setFilterer] = React.useState<TestFilterer | undefined>(undefined);4647const displayedTests = filterer48? filterer.filter(testsProvider.tests)49: testsProvider.tests;5051const toggleTheme = React.useCallback(() => setTheme(theme === 'dark' ? 'light' : 'dark'), [theme]);5253return (54<FluentProvider theme={theme === 'light' ? webLightTheme : webDarkTheme} style={{ minHeight: 'inherit' }}>55<ContextMenuProvider>56<div>57<ContextMenu />58<Toolbar59initArgs={initArgs}60runner={runner}61runnerOptions={runnerOptions}62nesExternalOptions={nesExternalOptions}63simulationRunsProvider={simulationRunsProvider}64simulationTestsProvider={testsProvider}65amlProvider={amlProvider}66testSource={testsProvider.testSource}67onFiltererChange={setFilterer}68allLanguageIds={testsProvider.allLanguageIds}69theme={theme}70toggleTheme={toggleTheme}71/>72{testsProvider.testSource.value === TestSource.External && (73<Scorecard amlProvider={amlProvider} />74)}75{testsProvider.testSource.value === TestSource.External && (76<ScorecardByLanguage amlProvider={amlProvider} />77)}78{(testsProvider.testSource.value === TestSource.Local || testsProvider.testSource.value === TestSource.NesExternal) && <TerminationMessageBar runner={runner} />}79<div style={{ margin: '5px', display: 'flex', justifyContent: 'space-between' }}>80<div style={{ textAlign: 'left' }}>81<TestsInfo tests={testsProvider.tests} displayedTests={displayedTests} />82</div>83<div style={{ textAlign: 'right' }}>84<Checkbox85label='Expand prompts'86defaultChecked={displayOptions.expandPrompts.value}87onChange={mobx.action(() => displayOptions.expandPrompts.value = !displayOptions.expandPrompts.value)}88/>89<DisplayToggle displayOptions={displayOptions} />90</div>91</div>92<TestList tests={displayedTests} runner={runner} runnerOptions={runnerOptions} nesExternalOptions={nesExternalOptions} testSource={testsProvider.testSource} displayOptions={displayOptions} />93</div>94</ContextMenuProvider>95</FluentProvider>96);97}98);99100const TerminationMessageBar = mobxlite.observer(({ runner }: { runner: SimulationRunner }) =>101runner.terminationReason === undefined102? null103: (104<MessageBar intent='error' layout='singleline'>105<MessageBarBody>106<MessageBarTitle>Simulation terminated early</MessageBarTitle>107<pre>{runner.terminationReason} </pre>108</MessageBarBody>109</MessageBar>110)111);112113const DisplayToggle = mobxlite.observer(({ displayOptions }: { displayOptions: DisplayOptions }) => (114<Tooltip content='Show all tests or by suites' relationship='label'>115<ToggleButton116icon={displayOptions.testsKind.value === 'suiteList' ? <ListBarTree20Filled /> : <ListBar20Filled />}117onClick={mobx.action(() => displayOptions.testsKind.value = displayOptions.testsKind.value === 'suiteList' ? 'testList' : 'suiteList')}118/>119</Tooltip>120));121122export class DisplayOptions {123124public testsKind: SimulationStorageValue<'suiteList' | 'testList'>;125126public expandPrompts: SimulationStorageValue<boolean>;127128constructor(storage: SimulationStorage) {129this.testsKind = new SimulationStorageValue(storage, 'displayTestsKind', 'suiteList');130this.expandPrompts = new SimulationStorageValue(storage, 'expandPrompts', false);131}132}133134type TestsInfoProps = {135tests: readonly ISimulationTest[];136displayedTests: readonly ISimulationTest[];137};138139const TestsInfo = mobxlite.observer(({ tests, displayedTests }: TestsInfoProps) => {140// TODO@ulugbekna: don't show "failing" if tests weren't run yet141return (142<Text size={400}>143# of tests: {tests.length} (<span>displayed:</span> {displayedTests.length})144</Text>145);146});147148149