Skip to content

Commit

Permalink
Give Setup webview a single section (#3448)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattseddon authored Mar 14, 2023
1 parent 38dc789 commit 40e7d96
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 85 deletions.
10 changes: 10 additions & 0 deletions extension/src/setup/webview/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ export type SetupData = {
projectInitialized: boolean
pythonBinPath: string | undefined
}

export enum Section {
EXPERIMENTS = 'experiments'
}

export const DEFAULT_SECTION_COLLAPSED = {
[Section.EXPERIMENTS]: false
}

export type SectionCollapsed = typeof DEFAULT_SECTION_COLLAPSED
112 changes: 31 additions & 81 deletions webview/src/setup/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { SetupData } from 'dvc/src/setup/webview/contract'
import {
MessageFromWebviewType,
MessageToWebview
} from 'dvc/src/webview/contract'
DEFAULT_SECTION_COLLAPSED,
Section,
SetupData
} from 'dvc/src/setup/webview/contract'
import { MessageToWebview } from 'dvc/src/webview/contract'
import React, { useCallback, useState } from 'react'
import { CliIncompatible } from './CliIncompatible'
import { CliUnavailable } from './CliUnavailable'
import { ProjectUninitialized } from './ProjectUninitialized'
import { NoData } from './NoData'
import { NeedsGitCommit } from './NeedsGitCommit'
import { SetupExperiments } from './Experiments'
import { SectionContainer } from '../../shared/components/sectionContainer/SectionContainer'
import { useVsCodeMessaging } from '../../shared/hooks/useVsCodeMessaging'
import { sendMessage } from '../../shared/vscode'
import { EmptyState } from '../../shared/components/emptyState/EmptyState'

// eslint-disable-next-line sonarjs/cognitive-complexity
export const App: React.FC = () => {
const [cliCompatible, setCliCompatible] = useState<boolean | undefined>(
undefined
Expand All @@ -32,6 +27,9 @@ export const App: React.FC = () => {
const [isPythonExtensionInstalled, setIsPythonExtensionInstalled] =
useState<boolean>(false)
const [hasData, setHasData] = useState<boolean | undefined>(false)
const [sectionCollapsed, setSectionCollapsed] = useState<
typeof DEFAULT_SECTION_COLLAPSED
>(DEFAULT_SECTION_COLLAPSED)

useVsCodeMessaging(
useCallback(
Expand All @@ -58,76 +56,28 @@ export const App: React.FC = () => {
)
)

const checkCompatibility = () => {
sendMessage({ type: MessageFromWebviewType.CHECK_CLI_COMPATIBLE })
}

const initializeGit = () => {
sendMessage({
type: MessageFromWebviewType.INITIALIZE_GIT
})
}

const initializeDvc = () => {
sendMessage({
type: MessageFromWebviewType.INITIALIZE_DVC
})
}

const showScmPanel = () => {
sendMessage({ type: MessageFromWebviewType.SHOW_SCM_PANEL })
}

const installDvc = () => {
sendMessage({ type: MessageFromWebviewType.INSTALL_DVC })
}

const selectPythonInterpreter = () => {
sendMessage({ type: MessageFromWebviewType.SELECT_PYTHON_INTERPRETER })
}

const setupWorkspace = () => {
sendMessage({ type: MessageFromWebviewType.SETUP_WORKSPACE })
}

if (cliCompatible === false) {
return <CliIncompatible checkCompatibility={checkCompatibility} />
}

if (cliCompatible === undefined) {
return (
<CliUnavailable
installDvc={installDvc}
isPythonExtensionInstalled={isPythonExtensionInstalled}
pythonBinPath={pythonBinPath}
selectPythonInterpreter={selectPythonInterpreter}
setupWorkspace={setupWorkspace}
/>
)
}

if (!projectInitialized) {
return (
<ProjectUninitialized
return (
<SectionContainer
sectionCollapsed={sectionCollapsed[Section.EXPERIMENTS]}
sectionKey={Section.EXPERIMENTS}
title={'Experiments'}
onToggleSection={() =>
setSectionCollapsed({
...sectionCollapsed,
[Section.EXPERIMENTS]: !sectionCollapsed[Section.EXPERIMENTS]
})
}
>
<SetupExperiments
canGitInitialize={canGitInitialize}
initializeDvc={initializeDvc}
initializeGit={initializeGit}
cliCompatible={cliCompatible}
hasData={hasData}
isPythonExtensionInstalled={isPythonExtensionInstalled}
needsGitInitialized={needsGitInitialized}
needsGitCommit={needsGitCommit}
projectInitialized={projectInitialized}
pythonBinPath={pythonBinPath}
/>
)
}

if (needsGitCommit) {
return <NeedsGitCommit showScmPanel={showScmPanel} />
}

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

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

return null
</SectionContainer>
)
}
80 changes: 80 additions & 0 deletions webview/src/setup/components/Experiments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from 'react'
import { CliIncompatible } from './CliIncompatible'
import { CliUnavailable } from './CliUnavailable'
import { ProjectUninitialized } from './ProjectUninitialized'
import {
checkCompatibility,
initializeDvc,
initializeGit,
installDvc,
selectPythonInterpreter,
setupWorkspace,
showScmPanel
} from './messages'
import { NeedsGitCommit } from './NeedsGitCommit'
import { NoData } from './NoData'
import { EmptyState } from '../../shared/components/emptyState/EmptyState'

export type SetupExperimentsProps = {
canGitInitialize: boolean | undefined
cliCompatible: boolean | undefined
hasData: boolean | undefined
isPythonExtensionInstalled: boolean
needsGitInitialized: boolean | undefined
needsGitCommit: boolean
projectInitialized: boolean
pythonBinPath: string | undefined
}

export const SetupExperiments: React.FC<SetupExperimentsProps> = ({
canGitInitialize,
cliCompatible,
hasData,
isPythonExtensionInstalled,
needsGitInitialized,
needsGitCommit,
projectInitialized,
pythonBinPath
// eslint-disable-next-line sonarjs/cognitive-complexity
}) => {
if (cliCompatible === false) {
return <CliIncompatible checkCompatibility={checkCompatibility} />
}

if (cliCompatible === undefined) {
return (
<CliUnavailable
installDvc={installDvc}
isPythonExtensionInstalled={isPythonExtensionInstalled}
pythonBinPath={pythonBinPath}
selectPythonInterpreter={selectPythonInterpreter}
setupWorkspace={setupWorkspace}
/>
)
}

if (!projectInitialized) {
return (
<ProjectUninitialized
canGitInitialize={canGitInitialize}
initializeDvc={initializeDvc}
initializeGit={initializeGit}
needsGitInitialized={needsGitInitialized}
/>
)
}

if (needsGitCommit) {
return <NeedsGitCommit showScmPanel={showScmPanel} />
}

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

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

return <EmptyState>{"You're all setup"}</EmptyState>
}
34 changes: 34 additions & 0 deletions webview/src/setup/components/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { MessageFromWebviewType } from 'dvc/src/webview/contract'
import { sendMessage } from '../../shared/vscode'

export const checkCompatibility = () => {
sendMessage({ type: MessageFromWebviewType.CHECK_CLI_COMPATIBLE })
}

export const initializeGit = () => {
sendMessage({
type: MessageFromWebviewType.INITIALIZE_GIT
})
}

export const initializeDvc = () => {
sendMessage({
type: MessageFromWebviewType.INITIALIZE_DVC
})
}

export const showScmPanel = () => {
sendMessage({ type: MessageFromWebviewType.SHOW_SCM_PANEL })
}

export const installDvc = () => {
sendMessage({ type: MessageFromWebviewType.INSTALL_DVC })
}

export const selectPythonInterpreter = () => {
sendMessage({ type: MessageFromWebviewType.SELECT_PYTHON_INTERPRETER })
}

export const setupWorkspace = () => {
sendMessage({ type: MessageFromWebviewType.SETUP_WORKSPACE })
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cx from 'classnames'
import React, { MouseEvent } from 'react'
import { Section as PlotsSection } from 'dvc/src/plots/webview/contract'
import { Section as SetupSection } from 'dvc/src/setup/webview/contract'
import styles from './styles.module.scss'
import { Icon } from '../Icon'
import { ChevronDown, ChevronRight, Info } from '../icons'
Expand Down Expand Up @@ -55,12 +56,22 @@ export const SectionDescription = {
</a>
.
</span>
),
// Setup Experiments
[SetupSection.EXPERIMENTS]: (
<span data-testid="tooltip-setup-experiments">
Configure the extension to start tracking and visualizing{' '}
<a href="https://dvc.org/doc/start/experiment-management/experiments">
experiments
</a>
.
</span>
)
} as const

export interface SectionContainerProps<T extends PlotsSection> {
export interface SectionContainerProps<T extends PlotsSection | SetupSection> {
children: React.ReactNode
menuItems: IconMenuItemProps[]
menuItems?: IconMenuItemProps[]
onToggleSection: () => void
sectionCollapsed: boolean
sectionKey: T
Expand All @@ -73,10 +84,10 @@ const InfoIcon = () => (
)

export const SectionContainer: React.FC<
SectionContainerProps<PlotsSection>
SectionContainerProps<PlotsSection | SetupSection>
> = ({
children,
menuItems,
menuItems = [],
onToggleSection,
sectionCollapsed,
sectionKey,
Expand Down

0 comments on commit 40e7d96

Please sign in to comment.