Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a copy button for comparison table rows #2216

Merged
merged 11 commits into from
Aug 19, 2022
Original file line number Diff line number Diff line change
@@ -14,6 +14,10 @@ import {
} from './ComparisonTableRow'
import styles from '../styles.module.scss'
import { plotsReducers } from '../../store'
import {
clearSelection,
createWindowTextSelection
} from '../../../test/selection'

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

@@ -67,27 +71,56 @@ describe('ComparisonTableRow', () => {
renderRow()

const rowToggler = screen.getByText(basicProps.path)
const [plot] = screen.getAllByAltText(
/(Plot of path\/to\/the-file\/image\.png)/
)
const [row] = screen.getAllByTestId('row-images')

/* eslint-disable testing-library/no-node-access */
expect(plot.parentElement).not.toHaveClass(styles.cellHidden)
expect(row).not.toHaveClass(styles.cellHidden)

fireEvent.click(rowToggler, {
bubbles: true,
cancelable: true
})

/* eslint-disable testing-library/no-node-access */
expect(plot.parentElement).toHaveClass(styles.cellHidden)
expect(row).toHaveClass(styles.cellHidden)

fireEvent.click(rowToggler, {
bubbles: true,
cancelable: true
})

/* eslint-disable testing-library/no-node-access */
expect(plot.parentElement).not.toHaveClass(styles.cellHidden)
expect(row).not.toHaveClass(styles.cellHidden)
})

it('should not toggle the row if the path was selected', () => {
renderRow()

const rowToggler = screen.getByText(basicProps.path)
const [row] = screen.getAllByTestId('row-images')

createWindowTextSelection(basicProps.path, 5)
fireEvent.click(rowToggler)

expect(row).not.toHaveClass(styles.cellHidden)

clearSelection()
fireEvent.click(rowToggler)

expect(row).toHaveClass(styles.cellHidden)

createWindowTextSelection(basicProps.path, 0)
fireEvent.click(rowToggler)

expect(row).not.toHaveClass(styles.cellHidden)
})

it('should toggle the row if some other path is selected', () => {
renderRow()

const rowToggler = screen.getByText(basicProps.path)
const [row] = screen.getAllByTestId('row-images')

createWindowTextSelection('other/path/img.gif', 5)
fireEvent.click(rowToggler)

expect(row).toHaveClass(styles.cellHidden)
})
})
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import { RefreshButton } from '../../../shared/components/button/RefreshButton'
import { sendMessage } from '../../../shared/vscode'
import { ChevronDown, ChevronRight } from '../../../shared/components/icons'
import { PlotsState } from '../../store'
import { CopyButton } from '../../../shared/components/copyButton/CopyButton'

export interface ComparisonTableRowProps {
path: string
@@ -28,16 +29,28 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
)
const [isShown, setIsShown] = useState(true)

const toggleIsShownState = () => setIsShown(!isShown)
const toggleIsShownState = () => {
const selection = window.getSelection()
if (
selection?.focusNode?.nodeValue === path &&
selection.anchorOffset !== selection.focusOffset
) {
return
}
setIsShown(!isShown)
}

return (
<tbody>
<tr>
<td className={cx({ [styles.pinnedColumnCell]: pinnedColumn })}>
<button className={styles.rowToggler} onClick={toggleIsShownState}>
<Icon icon={isShown ? ChevronDown : ChevronRight} />
{path}
</button>
<div className={styles.rowPath}>
<button className={styles.rowToggler} onClick={toggleIsShownState}>
<Icon icon={isShown ? ChevronDown : ChevronRight} />
{path}
</button>
<CopyButton value={path} className={styles.copyButton} />
</div>
</td>
{nbColumns > 1 && <td colSpan={nbColumns - 1}></td>}
</tr>
@@ -56,6 +69,7 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
})}
>
<div
data-testid="row-images"
className={cx(styles.cell, { [styles.cellHidden]: !isShown })}
>
{missing ? (
Original file line number Diff line number Diff line change
@@ -90,11 +90,11 @@ $gap: 4px;

.rowToggler {
border: none;
width: 100%;
background: none;
color: $fg-color;
text-align: left;
display: flex;
user-select: text;

svg {
fill: $fg-color;
@@ -173,3 +173,18 @@ $gap: 4px;
opacity: 1;
color: $bg-color;
}

.copyButton {
display: none;
}

.rowPath {
display: flex;
justify-content: flex-start;
align-items: center;

&:hover .copyButton {
display: inline;
font-size: 0.8125rem;
}
}
14 changes: 14 additions & 0 deletions webview/src/test/selection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const createWindowTextSelection = (
nodeValue: string | null,
offset = 0
) => {
window.getSelection = () => {
return {
anchorOffset: 1,
focusNode: nodeValue ? ({ nodeValue } as Node) : null,
focusOffset: 1 + offset
} as Selection
}
}

export const clearSelection = () => createWindowTextSelection(null)