diff --git a/extension/src/cli/dvc/actions.ts b/extension/src/cli/dvc/actions.ts index 6071e79312..2b0d2ee8ba 100644 --- a/extension/src/cli/dvc/actions.ts +++ b/extension/src/cli/dvc/actions.ts @@ -1,7 +1,7 @@ import { Args, Flag } from './constants' import { Prompt } from './output' import { MaybeConsoleError } from '../error' -import { warnOfConsequences } from '../../vscode/modal' +import { Modal } from '../../vscode/modal' import { CommandId, InternalCommands } from '../../commands/internal' import { Response } from '../../vscode/response' @@ -15,7 +15,7 @@ const offerToForce = async ( Prompt.TRY_FORCE, '\n\nWould you like to force this action?' ) - const response = await warnOfConsequences(text, Response.FORCE) + const response = await Modal.warnOfConsequences(text, Response.FORCE) if (response !== Response.FORCE) { return } diff --git a/extension/src/connect/index.ts b/extension/src/connect/index.ts index 76522d96b5..3914c814da 100644 --- a/extension/src/connect/index.ts +++ b/extension/src/connect/index.ts @@ -12,7 +12,7 @@ import { Title } from '../vscode/title' import { openUrl } from '../vscode/external' import { ContextKey, setContextValue } from '../vscode/context' import { RegisteredCommands } from '../commands/external' -import { showInformation } from '../vscode/modal' +import { Modal } from '../vscode/modal' export class Connect extends BaseRepository { public readonly viewKey = ViewKey.CONNECT @@ -96,7 +96,7 @@ export class Connect extends BaseRepository { const storedToken = await this.getStudioAccessToken() if (isStudioAccessToken(storedToken)) { if (this.deferred.state === 'resolved') { - void showInformation( + void Modal.showInformation( 'Studio is now connected. Use the "Share to Studio" command from an experiment\'s context menu to share experiments.' ) } diff --git a/extension/src/repository/commands/index.test.ts b/extension/src/repository/commands/index.test.ts index d57fe14d50..7ba9706bc4 100644 --- a/extension/src/repository/commands/index.test.ts +++ b/extension/src/repository/commands/index.test.ts @@ -1,13 +1,15 @@ import { join } from 'path' import { Uri } from 'vscode' import { getResourceCommand, getRootCommand, getSimpleResourceCommand } from '.' -import { warnOfConsequences } from '../../vscode/modal' +import { Modal } from '../../vscode/modal' import { CommandId, InternalCommands } from '../../commands/internal' import { OutputChannel } from '../../vscode/outputChannel' import { WorkspaceRepositories } from '../workspace' const mockedFunc = jest.fn() -const mockedGetWarningResponse = jest.mocked(warnOfConsequences) +const mockedModal = jest.mocked(Modal) +const mockedGetWarningResponse = jest.fn() +mockedModal.warnOfConsequences = mockedGetWarningResponse const mockedDvcRoot = join('some', 'path') const mockedRelPath = join('with', 'a', 'target') const mockedTarget = join(mockedDvcRoot, mockedRelPath) diff --git a/extension/src/repository/commands/index.ts b/extension/src/repository/commands/index.ts index a1d5ca915f..fafb1019e9 100644 --- a/extension/src/repository/commands/index.ts +++ b/extension/src/repository/commands/index.ts @@ -7,7 +7,7 @@ import { InternalCommands } from '../../commands/internal' import { relativeWithUri } from '../../fileSystem' -import { warnOfConsequences } from '../../vscode/modal' +import { Modal } from '../../vscode/modal' import { Response } from '../../vscode/response' import { WorkspaceRepositories } from '../workspace' @@ -135,7 +135,7 @@ export const getResetRootCommand = return } - const response = await warnOfConsequences( + const response = await Modal.warnOfConsequences( 'Are you sure you want to discard ALL workspace changes?\n' + 'This is IRREVERSIBLE!\n' + 'Your current working set will be FOREVER LOST if you proceed.', diff --git a/extension/src/repository/model/tree.ts b/extension/src/repository/model/tree.ts index f8b603f56b..14436f3de2 100644 --- a/extension/src/repository/model/tree.ts +++ b/extension/src/repository/model/tree.ts @@ -35,7 +35,7 @@ import { sendViewOpenedTelemetryEvent } from '../../telemetry' import { EventName } from '../../telemetry/constants' import { getInput } from '../../vscode/inputBox' import { pickResources } from '../../vscode/resourcePicker' -import { warnOfConsequences } from '../../vscode/modal' +import { Modal } from '../../vscode/modal' import { Response } from '../../vscode/response' import { Title } from '../../vscode/title' import { Disposable } from '../../class/dispose' @@ -229,7 +229,7 @@ export class RepositoriesTree async ({ resourceUri: destination }) => { const targets = await pickResources(Title.CHOOSE_RESOURCES) if (targets) { - const response = await warnOfConsequences( + const response = await Modal.warnOfConsequences( 'Are you sure you want to move the selected data into this dataset?', Response.MOVE ) diff --git a/extension/src/vscode/modal.test.ts b/extension/src/vscode/modal.test.ts index 54cf931d56..140a9b8433 100644 --- a/extension/src/vscode/modal.test.ts +++ b/extension/src/vscode/modal.test.ts @@ -1,5 +1,5 @@ import { window } from 'vscode' -import { warnOfConsequences } from './modal' +import { Modal } from './modal' import { Response } from './response' const mockedWindow = jest.mocked(window) @@ -14,28 +14,36 @@ beforeEach(() => { jest.resetAllMocks() }) -describe('warnOfConsequences', () => { - it('should return the text of the response provided by the user', async () => { - const userSelection = Response.YES - const options = [userSelection, Response.NO, Response.NEVER] +describe('Modal', () => { + describe('warnOfConsequences', () => { + it('should return the text of the response provided by the user', async () => { + const userSelection = Response.YES + const options = [userSelection, Response.NO, Response.NEVER] - mockedShowWarningMessage.mockResolvedValueOnce(Response.YES) + mockedShowWarningMessage.mockResolvedValueOnce(Response.YES) - const response = await warnOfConsequences('WHAT DO I DO?', ...options) + const response = await Modal.warnOfConsequences( + 'WHAT DO I DO?', + ...options + ) - expect(response).toStrictEqual(userSelection) - expect(mockedShowWarningMessage).toHaveBeenCalledTimes(1) - }) + expect(response).toStrictEqual(userSelection) + expect(mockedShowWarningMessage).toHaveBeenCalledTimes(1) + }) - it('should return undefined if the modal is cancelled', async () => { - const modalCancelled = undefined - const options = [Response.YES, Response.NO, Response.NEVER] + it('should return undefined if the modal is cancelled', async () => { + const modalCancelled = undefined + const options = [Response.YES, Response.NO, Response.NEVER] - mockedShowWarningMessage.mockResolvedValueOnce(modalCancelled) + mockedShowWarningMessage.mockResolvedValueOnce(modalCancelled) - const response = await warnOfConsequences('WHAT DO I DO?', ...options) + const response = await Modal.warnOfConsequences( + 'WHAT DO I DO?', + ...options + ) - expect(response).toStrictEqual(modalCancelled) - expect(mockedShowWarningMessage).toHaveBeenCalledTimes(1) + expect(response).toStrictEqual(modalCancelled) + expect(mockedShowWarningMessage).toHaveBeenCalledTimes(1) + }) }) }) diff --git a/extension/src/vscode/modal.ts b/extension/src/vscode/modal.ts index fcd68c985e..9442e04643 100644 --- a/extension/src/vscode/modal.ts +++ b/extension/src/vscode/modal.ts @@ -1,14 +1,25 @@ import { window } from 'vscode' import { Response } from './response' -export const warnOfConsequences = ( - text: string, - ...items: Response[] -): Thenable => - window.showWarningMessage(text, { modal: true }, ...items) - -export const showInformation = ( - text: string, - ...items: Response[] -): Thenable => - window.showInformationMessage(text, { modal: true }, ...items) +enum Level { + INFORMATION = 'Information', + WARNING = 'Warning' +} + +export class Modal { + public static showInformation(text: string, ...items: Response[]) { + return Modal.show(Level.INFORMATION, text, ...items) + } + + public static warnOfConsequences(text: string, ...items: Response[]) { + return Modal.show(Level.WARNING, text, ...items) + } + + private static show( + level: Level, + message: string, + ...items: Response[] + ): Thenable { + return window[`show${level}Message`](message, { modal: true }, ...items) + } +}