Skip to content

Commit 08641f0

Browse files
authored
Show information toast when trying to exceed max number of plotted experiments (#4085)
1 parent 1597fc0 commit 08641f0

File tree

5 files changed

+98
-13
lines changed

5 files changed

+98
-13
lines changed

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,17 @@ These are the VS Code [settings] available for the Extension:
145145

146146
[settings]: https://code.visualstudio.com/docs/getstarted/settings
147147

148-
| **Option** | **Description** |
149-
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
150-
| `dvc.dvcPath` | Path or shell command to the DVC binary. Required unless Microsoft's [Python extension] is installed and the `dvc` package found in its environment. |
151-
| `dvc.pythonPath` | Path to the desired Python interpreter to use with DVC. Should only be utilized when using a virtual environment without Microsoft's [Python extension]. |
152-
| `dvc.experimentsTableHeadMaxHeight` | Maximum height of experiment table head rows. |
153-
| `dvc.focusedProjects` | A subset of paths to the workspace's available DVC projects. Using this option will override project auto-discovery. |
154-
| `dvc.doNotShowSetupAfterInstall` | Do not prompt to show the setup page after installing. Useful for pre-configured development environments |
155-
| `dvc.doNotRecommendAddStudioToken` | Do not prompt to add a [studio.token] to the global DVC config, which enables automatic sharing of experiments to [Studio]. |
156-
| `dvc.doNotRecommendRedHatExtension` | Do not prompt to install the Red Hat YAML extension, which helps with DVC YAML schema validation (`dvc.yaml` and `.dvc` files). |
157-
| `dvc.doNotShowCliUnavailable` | Do not warn when the workspace contains a DVC project but the DVC binary is unavailable. |
148+
| **Option** | **Description** |
149+
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
150+
| `dvc.dvcPath` | Path or shell command to the DVC binary. Required unless Microsoft's [Python extension] is installed and the `dvc` package found in its environment. |
151+
| `dvc.pythonPath` | Path to the desired Python interpreter to use with DVC. Should only be utilized when using a virtual environment without Microsoft's [Python extension]. |
152+
| `dvc.experimentsTableHeadMaxHeight` | Maximum height of experiment table head rows. |
153+
| `dvc.focusedProjects` | A subset of paths to the workspace's available DVC projects. Using this option will override project auto-discovery. |
154+
| `dvc.doNotInformMaxExperimentsPlotted` | Do not inform when plotting more experiments is blocked (maximum number selected). |
155+
| `dvc.doNotShowSetupAfterInstall` | Do not prompt to show the setup page after installing. Useful for pre-configured development environments. |
156+
| `dvc.doNotRecommendAddStudioToken` | Do not prompt to add a [studio.token] to the global DVC config, which enables automatic sharing of experiments to [Studio]. |
157+
| `dvc.doNotRecommendRedHatExtension` | Do not prompt to install the Red Hat YAML extension, which helps with DVC YAML schema validation (`dvc.yaml` and `.dvc` files). |
158+
| `dvc.doNotShowCliUnavailable` | Do not warn when the workspace contains a DVC project but the DVC binary is unavailable. |
158159

159160
> **Note** that the `Setup The Workspace` command helps you set up the basic
160161
> ones at the [Workspace level] (saved to `.vscode/setting.json`).

extension/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,11 @@
600600
"configuration": {
601601
"title": "DVC",
602602
"properties": {
603+
"dvc.doNotInformMaxExperimentsPlotted": {
604+
"description": "Do not inform when plotting more experiments is blocked (maximum number selected).",
605+
"type": "boolean",
606+
"default": null
607+
},
603608
"dvc.doNotRecommendRedHatExtension": {
604609
"description": "Do not prompt to install the Red Hat YAML extension, which helps with DVC YAML schema validation.",
605610
"type": "boolean",

extension/src/experiments/index.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
pickFiltersToRemove
2222
} from './model/filterBy/quickPick'
2323
import { Color } from './model/status/colors'
24-
import { UNSELECTED } from './model/status'
24+
import { MAX_SELECTED_EXPERIMENTS, UNSELECTED } from './model/status'
2525
import { starredSort } from './model/sortBy/constants'
2626
import { pickSortsToRemove, pickSortToAdd } from './model/sortBy/quickPick'
2727
import { ColumnsModel } from './columns/model'
@@ -40,9 +40,10 @@ import { Title } from '../vscode/title'
4040
import { createTypedAccumulator } from '../util/object'
4141
import { pickPaths } from '../path/selection/quickPick'
4242
import { Toast } from '../vscode/toast'
43-
import { ConfigKey } from '../vscode/config'
43+
import { ConfigKey, getConfigValue, setUserConfigValue } from '../vscode/config'
4444
import { checkSignalFile, pollSignalFileForProcess } from '../fileSystem'
4545
import { DVCLIVE_ONLY_RUNNING_SIGNAL_FILE } from '../cli/dvc/constants'
46+
import { Response } from '../vscode/response'
4647

4748
export const ExperimentsScale = {
4849
...omit(ColumnType, 'TIMESTAMP'),
@@ -219,6 +220,7 @@ export class Experiments extends BaseRepository<TableData> {
219220
): Color | typeof UNSELECTED | undefined {
220221
const selected = this.experiments.isSelected(id)
221222
if (!selected && !this.experiments.canSelect()) {
223+
void this.informMaxSelected()
222224
return
223225
}
224226

@@ -617,4 +619,18 @@ export class Experiments extends BaseRepository<TableData> {
617619
}
618620
return dvcLiveOnly
619621
}
622+
623+
private async informMaxSelected() {
624+
if (getConfigValue(ConfigKey.DO_NOT_INFORM_MAX_PLOTTED, false)) {
625+
return
626+
}
627+
const response = await Toast.infoWithOptions(
628+
`Cannot plot more than ${MAX_SELECTED_EXPERIMENTS} experiments.`,
629+
Response.NEVER
630+
)
631+
632+
if (response === Response.NEVER) {
633+
return setUserConfigValue(ConfigKey.DO_NOT_INFORM_MAX_PLOTTED, true)
634+
}
635+
}
620636
}

extension/src/test/suite/experiments/index.test.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import {
1010
Uri,
1111
QuickPickItem,
1212
ViewColumn,
13-
CancellationToken
13+
CancellationToken,
14+
WorkspaceConfiguration,
15+
MessageItem,
16+
ConfigurationTarget
1417
} from 'vscode'
1518
import {
1619
DEFAULT_EXPERIMENTS_OUTPUT,
@@ -87,6 +90,7 @@ import { DvcViewer } from '../../../cli/dvc/viewer'
8790
import { DEFAULT_NB_ITEMS_PER_ROW } from '../../../plots/webview/contract'
8891
import { Toast } from '../../../vscode/toast'
8992
import { Response } from '../../../vscode/response'
93+
import { MAX_SELECTED_EXPERIMENTS } from '../../../experiments/model/status'
9094

9195
const { openFileInEditor } = FileSystem
9296

@@ -977,6 +981,64 @@ suite('Experiments Test Suite', () => {
977981
).to.be.false
978982
}).timeout(WEBVIEW_TEST_TIMEOUT)
979983

984+
it('should show an information toast when the user tries to toggle an experiment when the max number are already selected', async () => {
985+
const { experiments, experimentsModel } = buildExperiments({
986+
disposer: disposable
987+
})
988+
989+
await experiments.isReady()
990+
991+
const mockShowInformationMessage = stub(
992+
window,
993+
'showInformationMessage'
994+
).resolves(Response.NEVER as unknown as MessageItem)
995+
996+
const mockUpdate = stub()
997+
const updateCalled = new Promise(resolve =>
998+
mockUpdate.callsFake(() => {
999+
resolve(undefined)
1000+
return Promise.resolve()
1001+
})
1002+
)
1003+
stub(workspace, 'getConfiguration').returns({
1004+
get: stub(),
1005+
update: mockUpdate
1006+
} as unknown as WorkspaceConfiguration)
1007+
1008+
const allExperiments =
1009+
experimentsModel.getWorkspaceCommitsAndExperiments()
1010+
1011+
const experimentsToSelect = allExperiments.slice(
1012+
0,
1013+
MAX_SELECTED_EXPERIMENTS
1014+
)
1015+
1016+
const overMaxSelected = allExperiments[MAX_SELECTED_EXPERIMENTS].id
1017+
1018+
experimentsModel.setSelected(experimentsToSelect)
1019+
expect(experiments.getSelectedRevisions()).to.have.lengthOf(
1020+
MAX_SELECTED_EXPERIMENTS
1021+
)
1022+
1023+
experiments.toggleExperimentStatus(overMaxSelected)
1024+
1025+
await updateCalled
1026+
1027+
expect(
1028+
!!experimentsModel
1029+
.getCombinedList()
1030+
.find(({ id }) => id === overMaxSelected)?.selected,
1031+
'experiment is not selected'
1032+
).to.be.false
1033+
1034+
expect(mockShowInformationMessage).to.be.called
1035+
expect(mockUpdate).to.be.calledWithExactly(
1036+
ConfigKey.DO_NOT_INFORM_MAX_PLOTTED,
1037+
true,
1038+
ConfigurationTarget.Global
1039+
)
1040+
})
1041+
9801042
it('should be able to handle a message to select columns', async () => {
9811043
stub(DvcReader.prototype, 'listStages').resolves('train')
9821044

extension/src/vscode/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ConfigurationTarget, workspace } from 'vscode'
22

33
export enum ConfigKey {
4+
DO_NOT_INFORM_MAX_PLOTTED = 'dvc.doNotInformMaxExperimentsPlotted',
45
DO_NOT_RECOMMEND_ADD_STUDIO_TOKEN = 'dvc.doNotRecommendAddStudioToken',
56
DO_NOT_RECOMMEND_RED_HAT = 'dvc.doNotRecommendRedHatExtension',
67
DO_NOT_SHOW_CLI_UNAVAILABLE = 'dvc.doNotShowCliUnavailable',

0 commit comments

Comments
 (0)