Skip to content

Commit 5622ebc

Browse files
authored
Review when plot sections should collapse (#2285)
* Apply comments on plot section collapse * Self review
1 parent 4459d27 commit 5622ebc

File tree

5 files changed

+95
-17
lines changed

5 files changed

+95
-17
lines changed

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { plotsReducers } from '../store'
4444
import { vsCodeApi } from '../../shared/api'
4545
import { createBubbledEvent, dragAndDrop, dragEnter } from '../../test/dragDrop'
4646
import { DragEnterDirection } from '../../shared/components/dragDrop/util'
47+
import { clearSelection, createWindowTextSelection } from '../../test/selection'
4748

4849
jest.mock('../../shared/api')
4950

@@ -338,6 +339,69 @@ describe('App', () => {
338339
).not.toBeInTheDocument()
339340
})
340341

342+
it('should not toggle the checkpoint plots section when its header is clicked and its title is selected', async () => {
343+
renderAppWithOptionalData({
344+
checkpoint: checkpointPlotsFixture
345+
})
346+
347+
const summaryElement = await screen.findByText('Trends')
348+
349+
createWindowTextSelection('Trends', 2)
350+
fireEvent.click(summaryElement, {
351+
bubbles: true,
352+
cancelable: true
353+
})
354+
355+
expect(mockPostMessage).not.toHaveBeenCalledWith({
356+
payload: { [Section.CHECKPOINT_PLOTS]: true },
357+
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
358+
})
359+
360+
clearSelection()
361+
fireEvent.click(summaryElement, {
362+
bubbles: true,
363+
cancelable: true
364+
})
365+
366+
expect(mockPostMessage).toBeCalledWith({
367+
payload: { [Section.CHECKPOINT_PLOTS]: true },
368+
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
369+
})
370+
})
371+
372+
it('should not toggle the checkpoint plots section when its header is clicked and the content of its tooltip is selected', async () => {
373+
renderAppWithOptionalData({
374+
checkpoint: checkpointPlotsFixture
375+
})
376+
377+
const summaryElement = await screen.findByText('Trends')
378+
createWindowTextSelection(
379+
// eslint-disable-next-line testing-library/no-node-access
380+
SectionDescription['checkpoint-plots'].props.children,
381+
2
382+
)
383+
fireEvent.click(summaryElement, {
384+
bubbles: true,
385+
cancelable: true
386+
})
387+
388+
expect(mockPostMessage).not.toHaveBeenCalledWith({
389+
payload: { [Section.CHECKPOINT_PLOTS]: true },
390+
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
391+
})
392+
393+
clearSelection()
394+
fireEvent.click(summaryElement, {
395+
bubbles: true,
396+
cancelable: true
397+
})
398+
399+
expect(mockPostMessage).toBeCalledWith({
400+
payload: { [Section.CHECKPOINT_PLOTS]: true },
401+
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
402+
})
403+
})
404+
341405
it('should toggle the visibility of plots when clicking the metrics in the metrics picker', async () => {
342406
renderAppWithOptionalData({
343407
checkpoint: checkpointPlotsFixture

webview/src/plots/components/PlotsContainer.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import cx from 'classnames'
2-
import React, { useEffect, useState } from 'react'
2+
import React, { MouseEvent, useEffect, useState } from 'react'
33
import { PlotSize, Section } from 'dvc/src/plots/webview/contract'
44
import { MessageFromWebviewType } from 'dvc/src/webview/contract'
55
import { PlotsPicker, PlotsPickerProps } from './PlotsPicker'
@@ -17,6 +17,7 @@ import {
1717
Info,
1818
Lines
1919
} from '../../shared/components/icons'
20+
import { isSelecting } from '../../util/strings'
2021

2122
export interface CommonPlotsContainerProps {
2223
onResize: (size: PlotSize) => void
@@ -113,20 +114,22 @@ export const PlotsContainer: React.FC<PlotsContainerProps> = ({
113114
</div>
114115
)
115116

117+
const toggleSection = (e: MouseEvent) => {
118+
e.preventDefault()
119+
if (!isSelecting([title, SectionDescription[sectionKey].props.children])) {
120+
sendMessage({
121+
payload: {
122+
[sectionKey]: !sectionCollapsed
123+
},
124+
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
125+
})
126+
}
127+
}
128+
116129
return (
117130
<div className={styles.plotsContainerWrapper} data-testid="plots-container">
118131
<details open={open} className={styles.plotsContainer}>
119-
<summary
120-
onClick={e => {
121-
e.preventDefault()
122-
sendMessage({
123-
payload: {
124-
[sectionKey]: !sectionCollapsed
125-
},
126-
type: MessageFromWebviewType.TOGGLE_PLOTS_SECTION
127-
})
128-
}}
129-
>
132+
<summary onClick={toggleSection}>
130133
<Icon
131134
icon={open ? ChevronDown : ChevronRight}
132135
data-testid="plots-container-details-chevron"

webview/src/plots/components/comparisonTable/ComparisonTableRow.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { sendMessage } from '../../../shared/vscode'
1010
import { ChevronDown, ChevronRight } from '../../../shared/components/icons'
1111
import { PlotsState } from '../../store'
1212
import { CopyButton } from '../../../shared/components/copyButton/CopyButton'
13+
import { isSelecting } from '../../../util/strings'
1314

1415
export interface ComparisonTableRowProps {
1516
path: string
@@ -30,11 +31,7 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
3031
const [isShown, setIsShown] = useState(true)
3132

3233
const toggleIsShownState = () => {
33-
const selection = window.getSelection()
34-
if (
35-
selection?.focusNode?.nodeValue === path &&
36-
selection.anchorOffset !== selection.focusOffset
37-
) {
34+
if (isSelecting([path])) {
3835
return
3936
}
4037
setIsShown(!isShown)

webview/src/plots/components/styles.module.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ $gap: 20px;
1919
font-size: 1.25rem;
2020
display: flex;
2121
align-items: center;
22+
width: max-content;
23+
24+
svg {
25+
cursor: pointer;
26+
}
2227
}
2328
}
2429

webview/src/util/strings.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,12 @@ export const capitalize = (s: string) =>
33

44
export const pluralize = (word: string, number: number | undefined) =>
55
number === 1 ? word : `${word}s`
6+
7+
export const isSelecting = (text: string[]) => {
8+
const selection = window.getSelection()
9+
10+
return (
11+
text.includes(selection?.focusNode?.nodeValue || '') &&
12+
selection?.anchorOffset !== selection?.focusOffset
13+
)
14+
}

0 commit comments

Comments
 (0)