Skip to content

Commit

Permalink
Add show experiments button to final experiments screen (#3463)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattseddon authored Mar 15, 2023
1 parent 3c42134 commit a9fbd4f
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 18 deletions.
3 changes: 2 additions & 1 deletion extension/src/setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
Expand Down
7 changes: 6 additions & 1 deletion extension/src/setup/webview/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ import { openUrl } from '../../vscode/external'
export class WebviewMessages {
private readonly getWebview: () => BaseWebview<TSetupData> | undefined
private readonly initializeGit: () => void
private readonly showExperiments: () => void

constructor(
getWebview: () => BaseWebview<TSetupData> | undefined,
initializeGit: () => void
initializeGit: () => void,
showExperiments: () => void
) {
this.getWebview = getWebview
this.initializeGit = initializeGit
this.showExperiments = showExperiments
}

public sendWebviewMessage({
Expand Down Expand Up @@ -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)}`)
Expand Down
16 changes: 16 additions & 0 deletions extension/src/test/suite/setup/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions extension/src/webview/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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<T extends WebviewData> = {
type: MessageToWebviewType.SET_DATA
Expand Down
23 changes: 23 additions & 0 deletions webview/src/setup/components/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
42 changes: 28 additions & 14 deletions webview/src/setup/components/Experiments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <EmptyState isFullScreen={false}>Loading Project...</EmptyState>
}

if (!hasData) {
return <NoData />
}

return (
<EmptyState isFullScreen={false}>
<h1>Setup Complete</h1>
<IconButton
appearance="primary"
icon={Beaker}
onClick={showExperiments}
text="Show Experiments"
/>
</EmptyState>
)
}

export type ExperimentsProps = {
canGitInitialize: boolean | undefined
Expand All @@ -35,7 +62,6 @@ export const Experiments: React.FC<ExperimentsProps> = ({
needsGitCommit,
projectInitialized,
pythonBinPath
// eslint-disable-next-line sonarjs/cognitive-complexity
}) => {
if (cliCompatible === false) {
return <CliIncompatible checkCompatibility={checkCompatibility} />
Expand Down Expand Up @@ -68,17 +94,5 @@ export const Experiments: React.FC<ExperimentsProps> = ({
return <NeedsGitCommit showScmPanel={showScmPanel} />
}

if (hasData === undefined) {
return <EmptyState isFullScreen={false}>Loading Project...</EmptyState>
}

if (!hasData) {
return <NoData />
}

return (
<EmptyState isFullScreen={false}>
<h1>{"You're all setup"}</h1>
</EmptyState>
)
return <ProjectSetup hasData={hasData} />
}
4 changes: 4 additions & 0 deletions webview/src/setup/components/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 })

Expand Down
3 changes: 1 addition & 2 deletions webview/src/shared/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ export const Icon: React.FC<IconProps> = ({
...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 <I fill={fill} width={w} height={h} {...other} />
return <I width={w} height={h} {...other} />
}
15 changes: 15 additions & 0 deletions webview/src/shared/components/icons/Beaker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react'
import { SVGProps } from 'react'
const SvgBeaker = (props: SVGProps<SVGSVGElement>) => (
<svg
width={16}
height={16}
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
{...props}
>
<path d="M13.893 13.558L10 6.006v-4h1v-1H9.994V1l-.456.005H5V2h1v3.952l-3.894 7.609A1 1 0 0 0 3 15.006h10a1 1 0 0 0 .893-1.448zm-7-7.15L7 6.193V2.036l2-.024v4.237l.11.215 1.827 3.542H5.049l1.844-3.598zM3 14.017l1.54-3.011h6.916l1.547 3L3 14.017z" />
</svg>
)
export default SvgBeaker
1 change: 1 addition & 0 deletions webview/src/shared/components/icons/index.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down

0 comments on commit a9fbd4f

Please sign in to comment.