Skip to content

Commit a9fbd4f

Browse files
authored
Add show experiments button to final experiments screen (#3463)
1 parent 3c42134 commit a9fbd4f

File tree

10 files changed

+98
-18
lines changed

10 files changed

+98
-18
lines changed

extension/src/setup/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ export class Setup
367367
private createWebviewMessageHandler() {
368368
const webviewMessages = new WebviewMessages(
369369
() => this.getWebview(),
370-
() => this.initializeGit()
370+
() => this.initializeGit(),
371+
() => this.showExperiments()
371372
)
372373
this.dispose.track(
373374
this.onDidReceivedWebviewMessage(message =>

extension/src/setup/webview/messages.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ import { openUrl } from '../../vscode/external'
2020
export class WebviewMessages {
2121
private readonly getWebview: () => BaseWebview<TSetupData> | undefined
2222
private readonly initializeGit: () => void
23+
private readonly showExperiments: () => void
2324

2425
constructor(
2526
getWebview: () => BaseWebview<TSetupData> | undefined,
26-
initializeGit: () => void
27+
initializeGit: () => void,
28+
showExperiments: () => void
2729
) {
2830
this.getWebview = getWebview
2931
this.initializeGit = initializeGit
32+
this.showExperiments = showExperiments
3033
}
3134

3235
public sendWebviewMessage({
@@ -94,6 +97,8 @@ export class WebviewMessages {
9497
ConfigKey.STUDIO_SHARE_EXPERIMENTS_LIVE,
9598
message.payload
9699
)
100+
case MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW:
101+
return this.showExperiments()
97102

98103
default:
99104
Logger.error(`Unexpected message: ${JSON.stringify(message)}`)

extension/src/test/suite/setup/index.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,22 @@ suite('Setup Test Suite', () => {
791791
expect(mockDelete).to.be.calledWithExactly(STUDIO_ACCESS_TOKEN_KEY)
792792
})
793793

794+
it('should handle a message to open the experiments webview', async () => {
795+
const { messageSpy, setup, mockOpenExperiments } = buildSetup(disposable)
796+
797+
const webview = await setup.showWebview()
798+
await webview.isReady()
799+
800+
const mockMessageReceived = getMessageReceivedEmitter(webview)
801+
802+
messageSpy.resetHistory()
803+
mockMessageReceived.fire({
804+
type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW
805+
})
806+
807+
expect(mockOpenExperiments).to.be.calledOnce
808+
}).timeout(WEBVIEW_TEST_TIMEOUT)
809+
794810
it('should send the appropriate messages to the webview to focus different sections', async () => {
795811
const { setup, messageSpy } = buildSetup(disposable)
796812
messageSpy.restore()

extension/src/webview/contract.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export enum MessageFromWebviewType {
2020
CREATE_BRANCH_FROM_EXPERIMENT = 'create-branch-from-experiment',
2121
FOCUS_FILTERS_TREE = 'focus-filters-tree',
2222
FOCUS_SORTS_TREE = 'focus-sorts-tree',
23+
OPEN_EXPERIMENTS_WEBVIEW = 'open-experiments-webview',
2324
OPEN_PARAMS_FILE_TO_THE_SIDE = 'open-params-file-to-the-side',
2425
OPEN_PLOTS_WEBVIEW = 'open-plots-webview',
2526
OPEN_STUDIO = 'open-studio',
@@ -238,6 +239,7 @@ export type MessageFromWebview =
238239
| { type: MessageFromWebviewType.SAVE_STUDIO_TOKEN }
239240
| { type: MessageFromWebviewType.ADD_CONFIGURATION }
240241
| { type: MessageFromWebviewType.ZOOM_PLOT }
242+
| { type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW }
241243

242244
export type MessageToWebview<T extends WebviewData> = {
243245
type: MessageToWebviewType.SET_DATA

webview/src/setup/components/App.test.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,29 @@ describe('App', () => {
399399
screen.queryByText('Your project contains no data')
400400
).not.toBeInTheDocument()
401401
})
402+
403+
it('should enable the user to open the experiments webview when they have completed onboarding', () => {
404+
renderApp({
405+
canGitInitialize: false,
406+
cliCompatible: true,
407+
hasData: true,
408+
isPythonExtensionInstalled: true,
409+
isStudioConnected: true,
410+
needsGitCommit: false,
411+
needsGitInitialized: false,
412+
projectInitialized: true,
413+
pythonBinPath: 'python',
414+
sectionCollapsed: undefined,
415+
shareLiveToStudio: false
416+
})
417+
mockPostMessage.mockClear()
418+
const button = screen.getByText('Show Experiments')
419+
fireEvent.click(button)
420+
expect(mockPostMessage).toHaveBeenCalledTimes(1)
421+
expect(mockPostMessage).toHaveBeenCalledWith({
422+
type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW
423+
})
424+
})
402425
})
403426

404427
describe('Studio not connected', () => {

webview/src/setup/components/Experiments.tsx

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,38 @@ import {
99
installDvc,
1010
selectPythonInterpreter,
1111
setupWorkspace,
12+
showExperiments,
1213
showScmPanel
1314
} from './messages'
1415
import { NeedsGitCommit } from './NeedsGitCommit'
1516
import { NoData } from './NoData'
1617
import { EmptyState } from '../../shared/components/emptyState/EmptyState'
18+
import { IconButton } from '../../shared/components/button/IconButton'
19+
import { Beaker } from '../../shared/components/icons'
20+
21+
const ProjectSetup: React.FC<{ hasData: boolean | undefined }> = ({
22+
hasData
23+
}) => {
24+
if (hasData === undefined) {
25+
return <EmptyState isFullScreen={false}>Loading Project...</EmptyState>
26+
}
27+
28+
if (!hasData) {
29+
return <NoData />
30+
}
31+
32+
return (
33+
<EmptyState isFullScreen={false}>
34+
<h1>Setup Complete</h1>
35+
<IconButton
36+
appearance="primary"
37+
icon={Beaker}
38+
onClick={showExperiments}
39+
text="Show Experiments"
40+
/>
41+
</EmptyState>
42+
)
43+
}
1744

1845
export type ExperimentsProps = {
1946
canGitInitialize: boolean | undefined
@@ -35,7 +62,6 @@ export const Experiments: React.FC<ExperimentsProps> = ({
3562
needsGitCommit,
3663
projectInitialized,
3764
pythonBinPath
38-
// eslint-disable-next-line sonarjs/cognitive-complexity
3965
}) => {
4066
if (cliCompatible === false) {
4167
return <CliIncompatible checkCompatibility={checkCompatibility} />
@@ -68,17 +94,5 @@ export const Experiments: React.FC<ExperimentsProps> = ({
6894
return <NeedsGitCommit showScmPanel={showScmPanel} />
6995
}
7096

71-
if (hasData === undefined) {
72-
return <EmptyState isFullScreen={false}>Loading Project...</EmptyState>
73-
}
74-
75-
if (!hasData) {
76-
return <NoData />
77-
}
78-
79-
return (
80-
<EmptyState isFullScreen={false}>
81-
<h1>{"You're all setup"}</h1>
82-
</EmptyState>
83-
)
97+
return <ProjectSetup hasData={hasData} />
8498
}

webview/src/setup/components/messages.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export const setupWorkspace = () => {
3333
sendMessage({ type: MessageFromWebviewType.SETUP_WORKSPACE })
3434
}
3535

36+
export const showExperiments = () => {
37+
sendMessage({ type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW })
38+
}
39+
3640
export const openStudio = () =>
3741
sendMessage({ type: MessageFromWebviewType.OPEN_STUDIO })
3842

webview/src/shared/components/Icon.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ export const Icon: React.FC<IconProps> = ({
1515
...other
1616
}) => {
1717
const I = icon
18-
const fill = 'magenta' // This color is used to make sure we change it in CSS
1918
const w = width || 20
2019
const h = height || 20
2120

22-
return <I fill={fill} width={w} height={h} {...other} />
21+
return <I width={w} height={h} {...other} />
2322
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react'
2+
import { SVGProps } from 'react'
3+
const SvgBeaker = (props: SVGProps<SVGSVGElement>) => (
4+
<svg
5+
width={16}
6+
height={16}
7+
viewBox="0 0 16 16"
8+
xmlns="http://www.w3.org/2000/svg"
9+
fill="currentColor"
10+
{...props}
11+
>
12+
<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" />
13+
</svg>
14+
)
15+
export default SvgBeaker

webview/src/shared/components/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { default as Add } from './Add'
2+
export { default as Beaker } from './Beaker'
23
export { default as Check } from './Check'
34
export { default as ChevronDown } from './ChevronDown'
45
export { default as ChevronRight } from './ChevronRight'

0 commit comments

Comments
 (0)