diff --git a/webview/src/experiments/components/App.test.tsx b/webview/src/experiments/components/App.test.tsx index 1e561c3fdb..24eb5a5b68 100644 --- a/webview/src/experiments/components/App.test.tsx +++ b/webview/src/experiments/components/App.test.tsx @@ -668,10 +668,10 @@ describe('App', () => { expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() - const radioButton = within(getRow(EXPERIMENT_WORKSPACE_ID)).getByTestId( + const plotIcon = within(getRow(EXPERIMENT_WORKSPACE_ID)).getByTestId( 'row-action-plot' ) - fireEvent.mouseEnter(radioButton) + fireEvent.mouseEnter(plotIcon) advanceTimersByTime(NORMAL_TOOLTIP_DELAY[0]) const tooltip = screen.queryByRole('tooltip') @@ -692,8 +692,8 @@ describe('App', () => { expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() - const radioButton = within(getRow('main')).getByTestId('row-action-star') - fireEvent.mouseEnter(radioButton) + const starIcon = within(getRow('main')).getByTestId('row-action-star') + fireEvent.mouseEnter(starIcon) advanceTimersByTime(NORMAL_TOOLTIP_DELAY[0]) const tooltip = screen.queryByRole('tooltip') diff --git a/webview/src/experiments/components/table/body/CellRowActions.tsx b/webview/src/experiments/components/table/body/CellRowActions.tsx index 6fa1385a81..8c42ec199f 100644 --- a/webview/src/experiments/components/table/body/CellRowActions.tsx +++ b/webview/src/experiments/components/table/body/CellRowActions.tsx @@ -1,26 +1,37 @@ import React, { MouseEventHandler, ReactElement } from 'react' -import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react' +import { + VSCodeCheckbox, + VSCodeProgressRing +} from '@vscode/webview-ui-toolkit/react' +import cx from 'classnames' import { ExperimentStatus, - isQueued + isQueued, + isRunning } from 'dvc/src/experiments/webview/contract' import { CellHintTooltip } from './CellHintTooltip' import { Indicator } from '../Indicators' import { addStarredFilter, openPlotsWebview } from '../../../util/messages' import styles from '../styles.module.scss' import { clickAndEnterProps } from '../../../../util/props' -import { Clock, StarFull, StarEmpty } from '../../../../shared/components/icons' +import { + Clock, + StarFull, + StarEmpty, + GraphScatter +} from '../../../../shared/components/icons' export type CellRowActionsProps = { - bulletColor?: string isRowSelected: boolean + plotColor?: string showSubRowStates: boolean starred?: boolean status?: ExperimentStatus subRowStates: { + plotSelections: number + running: number selections: number stars: number - plotSelections: number } toggleExperiment: () => void toggleRowSelection: () => void @@ -32,7 +43,7 @@ type CellRowActionProps = { subRowsAffected: number children: ReactElement testId: string - tooltipContent: string | ReactElement + tooltipContent: string | ReactElement | null onClick?: MouseEventHandler } @@ -46,20 +57,40 @@ const CellRowAction: React.FC = ({ }) => { const count = (showSubRowStates && subRowsAffected) || 0 - return ( - -
- - {children} - -
-
+ const action = ( +
+ + {children} + +
+ ) + + return tooltipContent ? ( + {action} + ) : ( + action ) } const getTooltipContent = (determiner: boolean, action: string): string => 'Click to ' + (determiner ? `un${action}` : action) +const getRunningTooltipContent = ( + running: boolean, + showSubRowStates: boolean, + subRowsRunning: number +): string | null => { + if (running) { + return 'Experiment is currently running' + } + + if (showSubRowStates && subRowsRunning) { + return `There are currently ${subRowsRunning} running under this commit.` + } + + return null +} + type ClickableTooltipContentProps = { clickableText: string helperText: string @@ -81,16 +112,18 @@ const ClickableTooltipContent: React.FC = ({ ) export const CellRowActions: React.FC = ({ - bulletColor, + plotColor, status, toggleExperiment, isRowSelected, showSubRowStates, starred, - subRowStates: { selections, stars, plotSelections }, + subRowStates: { plotSelections, running: subRowsRunning, selections, stars }, toggleRowSelection, toggleStarred }) => { + const running = isRunning(status) + return ( <> = ({ checked={isRowSelected} /> + + {running ? ( + + ) : ( +
+ )} + = ({ tooltipContent={ } onClick={toggleExperiment} > - + )} diff --git a/webview/src/experiments/components/table/body/Row.tsx b/webview/src/experiments/components/table/body/Row.tsx index cc267d79e8..b644f8bfe4 100644 --- a/webview/src/experiments/components/table/body/Row.tsx +++ b/webview/src/experiments/components/table/body/Row.tsx @@ -2,7 +2,7 @@ import cx from 'classnames' import React, { useCallback, useContext, useMemo } from 'react' import { useSelector } from 'react-redux' import { EXPERIMENT_WORKSPACE_ID } from 'dvc/src/cli/dvc/contract' -import { isQueued, isRunning } from 'dvc/src/experiments/webview/contract' +import { isRunning } from 'dvc/src/experiments/webview/contract' import { FirstCell, CellWrapper } from './Cell' import { RowContextMenu } from './RowContextMenu' import styles from '../styles.module.scss' @@ -24,9 +24,8 @@ export const RowContent: React.FC< const changes = useSelector( (state: ExperimentsState) => state.tableData.changes ) - const { getVisibleCells, original, index, getIsExpanded, subRows } = row - const { branch, displayColor, error, starred, id, status, selected } = - original + const { getVisibleCells, original, getIsExpanded, subRows } = row + const { branch, displayColor, error, starred, id } = original const [firstCell, ...cells] = getVisibleCells() const isWorkspace = id === EXPERIMENT_WORKSPACE_ID const changesIfWorkspace = isWorkspace ? changes : undefined @@ -53,6 +52,9 @@ export const RowContent: React.FC< const plotSelections = subRows?.filter(subRow => subRow.original.selected).length ?? 0 + const running = + subRows?.filter(subRow => isRunning(subRow.original.status)).length ?? 0 + const selections = subRows?.filter( subRow => @@ -63,16 +65,12 @@ export const RowContent: React.FC< return { plotSelections, + running, selections, stars } }, [subRows, selectedRows]) - const running = isRunning(status) - const queued = isQueued(status) - const unselected = selected === false - const isOdd = index % 2 !== 0 && !isRowSelected - return ( }> = ({ }) => (
{fetched && errors && '!'} - {!fetched && } + {!fetched && ( + + )}
)