From 86e54180c6831fbcdd62ac4f346c3071f97d3427 Mon Sep 17 00:00:00 2001
From: Julie G <43496356+julieg18@users.noreply.github.com>
Date: Tue, 9 May 2023 07:55:02 -0500
Subject: [PATCH] Autoclose DVC Section if completed (#3809)
---
webview/src/setup/components/App.test.tsx | 69 +++++++++++--------
webview/src/setup/components/App.tsx | 5 +-
webview/src/setup/components/dvc/Dvc.tsx | 65 ++++++++++-------
webview/src/setup/hooks/usePrevious.ts | 11 +++
.../sectionContainer/SectionContainer.tsx | 6 +-
5 files changed, 103 insertions(+), 53 deletions(-)
create mode 100644 webview/src/setup/hooks/usePrevious.ts
diff --git a/webview/src/setup/components/App.test.tsx b/webview/src/setup/components/App.test.tsx
index c057c3e938..5ecebf5ff2 100644
--- a/webview/src/setup/components/App.test.tsx
+++ b/webview/src/setup/components/App.test.tsx
@@ -56,6 +56,16 @@ const renderApp = ({
)
}
+const sendSetDataMessage = (data: SetupData) => {
+ const message = new MessageEvent('message', {
+ data: {
+ data,
+ type: MessageToWebviewType.SET_DATA
+ }
+ })
+ fireEvent(window, message)
+}
+
describe('App', () => {
it('should send the initialized message on first render', () => {
render()
@@ -422,8 +432,8 @@ describe('App', () => {
})
})
- it('should open the experiments section when clicking the Open Experiments button when the project is initialized but has no data', () => {
- renderApp({
+ it('should autoclose and open other sections when user finishes setup', () => {
+ const dvcNotSetup = {
canGitInitialize: false,
cliCompatible: true,
dvcCliDetails: {
@@ -434,30 +444,25 @@ describe('App', () => {
isPythonExtensionUsed: false,
isStudioConnected: false,
needsGitCommit: false,
- needsGitInitialized: undefined,
- projectInitialized: true,
+ needsGitInitialized: true,
+ projectInitialized: false,
pythonBinPath: undefined,
- sectionCollapsed: undefined,
+ sectionCollapsed: {
+ [SetupSection.DVC]: false,
+ [SetupSection.STUDIO]: true,
+ [SetupSection.EXPERIMENTS]: true
+ },
shareLiveToStudio: false
- })
-
- mockPostMessage.mockClear()
- const button = screen.getAllByText('Show Experiments')[0]
- fireEvent.click(button)
-
- expect(screen.getByText('Your project contains no data')).toBeVisible()
- expect(screen.getByText('Setup Complete')).not.toBeVisible()
- })
+ }
- it('should enable the user to open the experiments webview when they have completed onboarding', () => {
- renderApp({
+ const dvcSetup = {
canGitInitialize: false,
cliCompatible: true,
dvcCliDetails: {
command: 'python -m dvc',
version: '1.0.0'
},
- hasData: true,
+ hasData: false,
isPythonExtensionUsed: true,
isStudioConnected: true,
needsGitCommit: false,
@@ -466,14 +471,25 @@ describe('App', () => {
pythonBinPath: 'python',
sectionCollapsed: undefined,
shareLiveToStudio: false
- })
- mockPostMessage.mockClear()
- const button = screen.getAllByText('Show Experiments')[0]
- fireEvent.click(button)
- expect(mockPostMessage).toHaveBeenCalledTimes(1)
- expect(mockPostMessage).toHaveBeenCalledWith({
- type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW
- })
+ }
+
+ renderApp(dvcNotSetup)
+
+ const dvcDetails = screen.getByTestId('dvc-section-details')
+ const experimentsDetails = screen.getByTestId(
+ 'experiments-section-details'
+ )
+ const studioDetails = screen.getByTestId('studio-section-details')
+
+ expect(dvcDetails).toHaveAttribute('open')
+ expect(experimentsDetails).not.toHaveAttribute('open')
+ expect(studioDetails).not.toHaveAttribute('open')
+
+ sendSetDataMessage(dvcSetup)
+
+ expect(dvcDetails).not.toHaveAttribute('open')
+ expect(experimentsDetails).toHaveAttribute('open')
+ expect(studioDetails).toHaveAttribute('open')
})
it('should show the user the version if dvc is installed', () => {
@@ -869,8 +885,7 @@ describe('App', () => {
shareLiveToStudio: false
})
mockPostMessage.mockClear()
- const button = screen.getAllByText('Show Experiments')[1]
- fireEvent.click(button)
+ fireEvent.click(screen.getByText('Show Experiments'))
expect(mockPostMessage).toHaveBeenCalledTimes(1)
expect(mockPostMessage).toHaveBeenCalledWith({
type: MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW
diff --git a/webview/src/setup/components/App.tsx b/webview/src/setup/components/App.tsx
index d1026d9c3e..9ac4b25fd7 100644
--- a/webview/src/setup/components/App.tsx
+++ b/webview/src/setup/components/App.tsx
@@ -43,6 +43,8 @@ export const App: React.FC = () => {
const [isStudioConnected, setIsStudioConnected] = useState(false)
const [shareLiveToStudio, setShareLiveToStudioValue] =
useState(false)
+ const [hasReceivedMessageFromVsCode, setHasReceivedMessageFromVsCode] =
+ useState(false)
useVsCodeMessaging(
useCallback(
@@ -64,6 +66,7 @@ export const App: React.FC = () => {
setSectionCollapsed(data.data.sectionCollapsed)
}
setShareLiveToStudioValue(data.data.shareLiveToStudio)
+ setHasReceivedMessageFromVsCode(true)
},
[
setCanGitInitialized,
@@ -109,8 +112,8 @@ export const App: React.FC = () => {
needsGitInitialized={needsGitInitialized}
projectInitialized={projectInitialized}
pythonBinPath={pythonBinPath}
- isExperimentsAvailable={hasData}
setSectionCollapsed={setSectionCollapsed}
+ hasReceivedMessageFromVsCode={hasReceivedMessageFromVsCode}
/>
void
+ hasReceivedMessageFromVsCode: boolean
}
export const Dvc: React.FC = ({
@@ -36,9 +38,35 @@ export const Dvc: React.FC = ({
needsGitInitialized,
projectInitialized,
pythonBinPath,
- setSectionCollapsed,
- isExperimentsAvailable
+ hasReceivedMessageFromVsCode,
+ setSectionCollapsed
}) => {
+ const [isComplete, setIsComplete] = useState(null)
+ const previousIsComplete = usePrevious(isComplete)
+
+ useEffect(() => {
+ const isSetup = projectInitialized && !!cliCompatible
+
+ if (hasReceivedMessageFromVsCode) {
+ setIsComplete(isSetup)
+ }
+
+ if (previousIsComplete === false && isComplete) {
+ setSectionCollapsed({
+ [SetupSection.DVC]: true,
+ [SetupSection.EXPERIMENTS]: false,
+ [SetupSection.STUDIO]: false
+ })
+ }
+ }, [
+ projectInitialized,
+ cliCompatible,
+ isComplete,
+ previousIsComplete,
+ setSectionCollapsed,
+ hasReceivedMessageFromVsCode
+ ])
+
const children = dvcCliDetails && (
= ({
/>
)
+ if (!hasReceivedMessageFromVsCode) {
+ return Loading...
+ }
+
if (cliCompatible === false) {
return (
@@ -82,21 +114,6 @@ export const Dvc: React.FC = ({
Setup Complete
{children}
-
- setSectionCollapsed({
- dvc: true,
- experiments: false,
- studio: true
- })
- }
- text="Show Experiments"
- />
)
}
diff --git a/webview/src/setup/hooks/usePrevious.ts b/webview/src/setup/hooks/usePrevious.ts
new file mode 100644
index 0000000000..175aae06b9
--- /dev/null
+++ b/webview/src/setup/hooks/usePrevious.ts
@@ -0,0 +1,11 @@
+import { useRef, useEffect } from 'react'
+
+export const usePrevious = (value: T): T | undefined => {
+ const ref = useRef()
+
+ useEffect(() => {
+ ref.current = value
+ }, [value])
+
+ return ref.current
+}
diff --git a/webview/src/shared/components/sectionContainer/SectionContainer.tsx b/webview/src/shared/components/sectionContainer/SectionContainer.tsx
index 9435594d14..5b82f7091b 100644
--- a/webview/src/shared/components/sectionContainer/SectionContainer.tsx
+++ b/webview/src/shared/components/sectionContainer/SectionContainer.tsx
@@ -117,7 +117,11 @@ export const SectionContainer: React.FC<
className={cx(styles.sectionContainerWrapper, className)}
data-testid="section-container"
>
-
+