From a9fbd4f7a42f8427664e058105aa495dc86baf13 Mon Sep 17 00:00:00 2001 From: Matt Seddon <37993418+mattseddon@users.noreply.github.com> Date: Wed, 15 Mar 2023 11:06:45 +1100 Subject: [PATCH] Add show experiments button to final experiments screen (#3463) --- extension/src/setup/index.ts | 3 +- extension/src/setup/webview/messages.ts | 7 +++- extension/src/test/suite/setup/index.test.ts | 16 +++++++ extension/src/webview/contract.ts | 2 + webview/src/setup/components/App.test.tsx | 23 ++++++++++ webview/src/setup/components/Experiments.tsx | 42 ++++++++++++------- webview/src/setup/components/messages.ts | 4 ++ webview/src/shared/components/Icon.tsx | 3 +- .../src/shared/components/icons/Beaker.tsx | 15 +++++++ webview/src/shared/components/icons/index.ts | 1 + 10 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 webview/src/shared/components/icons/Beaker.tsx diff --git a/extension/src/setup/index.ts b/extension/src/setup/index.ts index a5fb6cdca2..9eba4ef5ec 100644 --- a/extension/src/setup/index.ts +++ b/extension/src/setup/index.ts @@ -367,7 +367,8 @@ export class Setup private createWebviewMessageHandler() { const webviewMessages = new WebviewMessages( () => this.getWebview(), - () => this.initializeGit() + () => this.initializeGit(), + () => this.showExperiments() ) this.dispose.track( this.onDidReceivedWebviewMessage(message => diff --git a/extension/src/setup/webview/messages.ts b/extension/src/setup/webview/messages.ts index 636e56fecd..b43d4597ee 100644 --- a/extension/src/setup/webview/messages.ts +++ b/extension/src/setup/webview/messages.ts @@ -20,13 +20,16 @@ import { openUrl } from '../../vscode/external' export class WebviewMessages { private readonly getWebview: () => BaseWebview | undefined private readonly initializeGit: () => void + private readonly showExperiments: () => void constructor( getWebview: () => BaseWebview | undefined, - initializeGit: () => void + initializeGit: () => void, + showExperiments: () => void ) { this.getWebview = getWebview this.initializeGit = initializeGit + this.showExperiments = showExperiments } public sendWebviewMessage({ @@ -94,6 +97,8 @@ export class WebviewMessages { ConfigKey.STUDIO_SHARE_EXPERIMENTS_LIVE, message.payload ) + case MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW: + return this.showExperiments() default: Logger.error(`Unexpected message: ${JSON.stringify(message)}`) diff --git a/extension/src/test/suite/setup/index.test.ts b/extension/src/test/suite/setup/index.test.ts index 2dd09bf6fb..980386353d 100644 --- a/extension/src/test/suite/setup/index.test.ts +++ b/extension/src/test/suite/setup/index.test.ts @@ -791,6 +791,22 @@ suite('Setup Test Suite', () => { expect(mockDelete).to.be.calledWithExactly(STUDIO_ACCESS_TOKEN_KEY) }) + it('should handle a message to open the experiments webview', async () => { + const { messageSpy, setup, mockOpenExperiments } = buildSetup(disposable) + + const webview = await setup.showWebview() + await webview.isReady() + + const mockMessageReceived = getMessageReceivedEmitter(webview) + + messageSpy.resetHistory() + mockMessageReceived.fire({ + type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW + }) + + expect(mockOpenExperiments).to.be.calledOnce + }).timeout(WEBVIEW_TEST_TIMEOUT) + it('should send the appropriate messages to the webview to focus different sections', async () => { const { setup, messageSpy } = buildSetup(disposable) messageSpy.restore() diff --git a/extension/src/webview/contract.ts b/extension/src/webview/contract.ts index 965b8291b2..ba313c50e4 100644 --- a/extension/src/webview/contract.ts +++ b/extension/src/webview/contract.ts @@ -20,6 +20,7 @@ export enum MessageFromWebviewType { CREATE_BRANCH_FROM_EXPERIMENT = 'create-branch-from-experiment', FOCUS_FILTERS_TREE = 'focus-filters-tree', FOCUS_SORTS_TREE = 'focus-sorts-tree', + OPEN_EXPERIMENTS_WEBVIEW = 'open-experiments-webview', OPEN_PARAMS_FILE_TO_THE_SIDE = 'open-params-file-to-the-side', OPEN_PLOTS_WEBVIEW = 'open-plots-webview', OPEN_STUDIO = 'open-studio', @@ -238,6 +239,7 @@ export type MessageFromWebview = | { type: MessageFromWebviewType.SAVE_STUDIO_TOKEN } | { type: MessageFromWebviewType.ADD_CONFIGURATION } | { type: MessageFromWebviewType.ZOOM_PLOT } + | { type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW } export type MessageToWebview = { type: MessageToWebviewType.SET_DATA diff --git a/webview/src/setup/components/App.test.tsx b/webview/src/setup/components/App.test.tsx index 652192c283..77557f558e 100644 --- a/webview/src/setup/components/App.test.tsx +++ b/webview/src/setup/components/App.test.tsx @@ -399,6 +399,29 @@ describe('App', () => { screen.queryByText('Your project contains no data') ).not.toBeInTheDocument() }) + + it('should enable the user to open the experiments webview when they have completed onboarding', () => { + renderApp({ + canGitInitialize: false, + cliCompatible: true, + hasData: true, + isPythonExtensionInstalled: true, + isStudioConnected: true, + needsGitCommit: false, + needsGitInitialized: false, + projectInitialized: true, + pythonBinPath: 'python', + sectionCollapsed: undefined, + shareLiveToStudio: false + }) + mockPostMessage.mockClear() + const button = screen.getByText('Show Experiments') + fireEvent.click(button) + expect(mockPostMessage).toHaveBeenCalledTimes(1) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW + }) + }) }) describe('Studio not connected', () => { diff --git a/webview/src/setup/components/Experiments.tsx b/webview/src/setup/components/Experiments.tsx index de02909e74..ef186379f2 100644 --- a/webview/src/setup/components/Experiments.tsx +++ b/webview/src/setup/components/Experiments.tsx @@ -9,11 +9,38 @@ import { installDvc, selectPythonInterpreter, setupWorkspace, + showExperiments, showScmPanel } from './messages' import { NeedsGitCommit } from './NeedsGitCommit' import { NoData } from './NoData' import { EmptyState } from '../../shared/components/emptyState/EmptyState' +import { IconButton } from '../../shared/components/button/IconButton' +import { Beaker } from '../../shared/components/icons' + +const ProjectSetup: React.FC<{ hasData: boolean | undefined }> = ({ + hasData +}) => { + if (hasData === undefined) { + return Loading Project... + } + + if (!hasData) { + return + } + + return ( + +

Setup Complete

+ +
+ ) +} export type ExperimentsProps = { canGitInitialize: boolean | undefined @@ -35,7 +62,6 @@ export const Experiments: React.FC = ({ needsGitCommit, projectInitialized, pythonBinPath - // eslint-disable-next-line sonarjs/cognitive-complexity }) => { if (cliCompatible === false) { return @@ -68,17 +94,5 @@ export const Experiments: React.FC = ({ return } - if (hasData === undefined) { - return Loading Project... - } - - if (!hasData) { - return - } - - return ( - -

{"You're all setup"}

-
- ) + return } diff --git a/webview/src/setup/components/messages.ts b/webview/src/setup/components/messages.ts index 2b60384219..e7f7af33b4 100644 --- a/webview/src/setup/components/messages.ts +++ b/webview/src/setup/components/messages.ts @@ -33,6 +33,10 @@ export const setupWorkspace = () => { sendMessage({ type: MessageFromWebviewType.SETUP_WORKSPACE }) } +export const showExperiments = () => { + sendMessage({ type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW }) +} + export const openStudio = () => sendMessage({ type: MessageFromWebviewType.OPEN_STUDIO }) diff --git a/webview/src/shared/components/Icon.tsx b/webview/src/shared/components/Icon.tsx index 873b454248..b7e6d29f9e 100644 --- a/webview/src/shared/components/Icon.tsx +++ b/webview/src/shared/components/Icon.tsx @@ -15,9 +15,8 @@ export const Icon: React.FC = ({ ...other }) => { const I = icon - const fill = 'magenta' // This color is used to make sure we change it in CSS const w = width || 20 const h = height || 20 - return + return } diff --git a/webview/src/shared/components/icons/Beaker.tsx b/webview/src/shared/components/icons/Beaker.tsx new file mode 100644 index 0000000000..b9d50e733b --- /dev/null +++ b/webview/src/shared/components/icons/Beaker.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' +import { SVGProps } from 'react' +const SvgBeaker = (props: SVGProps) => ( + + + +) +export default SvgBeaker diff --git a/webview/src/shared/components/icons/index.ts b/webview/src/shared/components/icons/index.ts index db0a6b4e15..60499e9ca7 100644 --- a/webview/src/shared/components/icons/index.ts +++ b/webview/src/shared/components/icons/index.ts @@ -1,4 +1,5 @@ export { default as Add } from './Add' +export { default as Beaker } from './Beaker' export { default as Check } from './Check' export { default as ChevronDown } from './ChevronDown' export { default as ChevronRight } from './ChevronRight'