From 4c2210b08951c606154968d30436466b0c5f6ed8 Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Wed, 30 Nov 2022 10:46:42 -0500 Subject: [PATCH 1/7] Add webview for get started --- extension/package.json | 4 +-- extension/src/experiments/workspace.test.ts | 2 ++ extension/src/experiments/workspace.ts | 4 ++- extension/src/extension.ts | 13 +++++++-- extension/src/telemetry/constants.ts | 10 ++++++- .../experiments/model/filterBy/tree.test.ts | 2 ++ extension/src/test/suite/experiments/util.ts | 5 +++- extension/src/webview/constants.ts | 23 +++++++++++++-- extension/src/webview/factory.ts | 10 ++++--- extension/src/webview/workspace.ts | 28 +++++++++++++++++++ webview/.eslintrc.js | 3 +- webview/index.d.ts | 1 + webview/index.js | 1 + webview/src/getStarted/components/App.tsx | 12 ++++++++ webview/src/getStarted/index.tsx | 7 +++++ webview/webpack.config.ts | 6 +++- 16 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 webview/src/getStarted/components/App.tsx create mode 100644 webview/src/getStarted/index.tsx diff --git a/extension/package.json b/extension/package.json index 2e6d644b95..efcf665703 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1309,7 +1309,7 @@ { "id": "dvc.views.webviews", "name": "Views", - "when": "dvc.commands.available && dvc.project.available" + "when": "true" }, { "id": "dvc.views.experimentsColumnsTree", @@ -1351,7 +1351,7 @@ { "view": "dvc.views.webviews", "contents": "[Show Experiments](command:dvc.showExperiments)\n[Show Plots](command:dvc.showPlots)\n[Show Experiments and Plots](command:dvc.showExperimentsAndPlots)", - "when": "dvc.commands.available && dvc.project.available" + "when": "true" }, { "view": "dvc.views.welcome", diff --git a/extension/src/experiments/workspace.test.ts b/extension/src/experiments/workspace.test.ts index d898a82b53..aa57598551 100644 --- a/extension/src/experiments/workspace.test.ts +++ b/extension/src/experiments/workspace.test.ts @@ -13,6 +13,7 @@ import { buildMockedEventEmitter } from '../test/util/jest' import { OutputChannel } from '../vscode/outputChannel' import { Title } from '../vscode/title' import { Args } from '../cli/dvc/constants' +import { ResourceLocator } from '../resourceLocator' const mockedShowWebview = jest.fn() const mockedDisposable = jest.mocked(Disposable) @@ -60,6 +61,7 @@ describe('Experiments', () => { mockedInternalCommands, mockedUpdatesPaused, buildMockMemento(), + {} as ResourceLocator, { '/my/dvc/root': { getDvcRoot: () => mockedDvcRoot, diff --git a/extension/src/experiments/workspace.ts b/extension/src/experiments/workspace.ts index 0a85d46233..10ff637612 100644 --- a/extension/src/experiments/workspace.ts +++ b/extension/src/experiments/workspace.ts @@ -35,10 +35,12 @@ export class WorkspaceExperiments extends BaseWorkspaceWebviews< internalCommands: InternalCommands, updatesPaused: EventEmitter, workspaceState: Memento, + resourceLocator: ResourceLocator, + noDvc: boolean, experiments?: Record, checkpointsChanged?: EventEmitter ) { - super(internalCommands, workspaceState, experiments) + super(internalCommands, workspaceState, resourceLocator, noDvc, experiments) this.updatesPaused = updatesPaused diff --git a/extension/src/extension.ts b/extension/src/extension.ts index 6053d6bc6a..4f627fb4b8 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -141,16 +141,25 @@ export class Extension extends Disposable implements IExtension { ]) ) + const noDvc = !this.cliAccessible || !this.cliCompatible || !this.hasRoots + this.experiments = this.dispose.track( new WorkspaceExperiments( this.internalCommands, this.updatesPaused, - context.workspaceState + context.workspaceState, + this.resourceLocator, + noDvc ) ) this.plots = this.dispose.track( - new WorkspacePlots(this.internalCommands, context.workspaceState) + new WorkspacePlots( + this.internalCommands, + context.workspaceState, + this.resourceLocator, + noDvc + ) ) this.repositories = this.dispose.track( diff --git a/extension/src/telemetry/constants.ts b/extension/src/telemetry/constants.ts index d5cece3e5a..f39cd2b755 100644 --- a/extension/src/telemetry/constants.ts +++ b/extension/src/telemetry/constants.ts @@ -76,7 +76,11 @@ export const EventName = Object.assign( VIEWS_TERMINAL_CLOSED: 'views.terminal.closed', VIEWS_TERMINAL_CREATED: 'views.terminal.created', - VIEWS_TERMINAL_FOCUS_CHANGED: 'views.terminal.focusChanged' + VIEWS_TERMINAL_FOCUS_CHANGED: 'views.terminal.focusChanged', + + VIEWS_GET_STARTED_CLOSE: 'view.GET_STARTED.closed', + VIEWS_GET_STARTED_CREATED: 'view.GET_STARTED.created', + VIEWS_GET_STARTED_FOCUS_CHANGED: 'views.GET_STARTED.focusChanged' } as const, ViewOpenedEvent, RegisteredCliCommands, @@ -252,4 +256,8 @@ export interface IEventNamePropertyMapping { [EventName.VIEWS_TERMINAL_CREATED]: undefined [EventName.VIEWS_TRACKED_EXPLORER_TREE_OPENED]: DvcRootCount + + [EventName.VIEWS_GET_STARTED_CLOSE]: undefined + [EventName.VIEWS_GET_STARTED_CREATED]: undefined + [EventName.VIEWS_GET_STARTED_FOCUS_CHANGED]: undefined } diff --git a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts index 31054debaf..459da45a0b 100644 --- a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts +++ b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts @@ -41,6 +41,7 @@ import { FilterItem } from '../../../../../experiments/model/filterBy/tree' import { starredFilter } from '../../../../../experiments/model/filterBy/constants' +import { ResourceLocator } from '../../../../../resourceLocator' suite('Experiments Filter By Tree Test Suite', () => { const disposable = Disposable.fn() @@ -357,6 +358,7 @@ suite('Experiments Filter By Tree Test Suite', () => { internalCommands, disposable.track(new EventEmitter()), buildMockMemento(), + {} as ResourceLocator, { [dvcDemoPath]: experiments }, disposable.track(new EventEmitter()) ) diff --git a/extension/src/test/suite/experiments/util.ts b/extension/src/test/suite/experiments/util.ts index 68f40708aa..71f62e3f08 100644 --- a/extension/src/test/suite/experiments/util.ts +++ b/extension/src/test/suite/experiments/util.ts @@ -19,6 +19,7 @@ import { FileSystemData } from '../../../fileSystem/data' import * as Watcher from '../../../fileSystem/watcher' import { ExperimentsModel } from '../../../experiments/model' import { ColumnsModel } from '../../../experiments/columns/model' +import { ResourceLocator } from '../../../resourceLocator' const hasCheckpoints = (data: ExperimentsOutput) => { const [experimentsWithBaseline] = Object.values(omit(data, 'workspace')) @@ -104,6 +105,7 @@ export const buildMultiRepoExperiments = (disposer: Disposer) => { internalCommands, updatesPaused, buildMockMemento(), + resourceLocator, { 'other/dvc/root': mockExperiments } @@ -132,7 +134,8 @@ export const buildSingleRepoExperiments = (disposer: Disposer) => { new WorkspaceExperiments( internalCommands, updatesPaused, - buildMockMemento() + buildMockMemento(), + {} as ResourceLocator ) ) const [experiments] = workspaceExperiments.create( diff --git a/extension/src/webview/constants.ts b/extension/src/webview/constants.ts index 417feb8bd5..7b60631c81 100644 --- a/extension/src/webview/constants.ts +++ b/extension/src/webview/constants.ts @@ -1,9 +1,16 @@ -import { distPath, react, experiments, plots } from 'dvc-vscode-webview' +import { + distPath, + react, + experiments, + plots, + getStarted +} from 'dvc-vscode-webview' import { EventName, IEventNamePropertyMapping } from '../telemetry/constants' export enum ViewKey { EXPERIMENTS = 'dvc-experiments', - PLOTS = 'dvc-plots' + PLOTS = 'dvc-plots', + GET_STARTED = 'dvc-getStarted' } type Name = keyof IEventNamePropertyMapping @@ -46,5 +53,17 @@ export const WebviewDetails: { scripts: [react, plots], title: 'Plots', viewKey: ViewKey.PLOTS + }, + [ViewKey.GET_STARTED]: { + contextKey: 'dvc.getStarted.webviewActive', + distPath, + eventNames: { + closedEvent: EventName.VIEWS_GET_STARTED_CLOSE, + createdEvent: EventName.VIEWS_GET_STARTED_CREATED, + focusChangedEvent: EventName.VIEWS_GET_STARTED_FOCUS_CHANGED + }, + scripts: [react, getStarted], + title: 'DVC is not initialized', + viewKey: ViewKey.GET_STARTED } } as const diff --git a/extension/src/webview/factory.ts b/extension/src/webview/factory.ts index c0b24708c6..7c8f35f1a9 100644 --- a/extension/src/webview/factory.ts +++ b/extension/src/webview/factory.ts @@ -10,9 +10,10 @@ export const isValidDvcRoot = (dvcRoot?: string): dvcRoot is string => !!dvcRoot const create = ( viewKey: ViewKey, webviewPanel: WebviewPanel, - dvcRoot: string + dvcRoot: string, + bypassDvcRoot?: boolean ) => { - if (!isValidDvcRoot(dvcRoot)) { + if (!bypassDvcRoot && !isValidDvcRoot(dvcRoot)) { throw new Error(`trying to set invalid state into ${viewKey}`) } @@ -25,7 +26,8 @@ export const createWebview = async ( viewKey: ViewKey, dvcRoot: string, iconPath: Resource, - viewColumn?: ViewColumn + viewColumn?: ViewColumn, + bypassDvcRoot?: boolean ) => { const { title, distPath } = WebviewDetails[viewKey] @@ -42,7 +44,7 @@ export const createWebview = async ( webviewPanel.iconPath = iconPath - const view = create(viewKey, webviewPanel, dvcRoot) + const view = create(viewKey, webviewPanel, dvcRoot, bypassDvcRoot) await view.isReady() return view } diff --git a/extension/src/webview/workspace.ts b/extension/src/webview/workspace.ts index d1fb18d9d7..0e1cb6a2b0 100644 --- a/extension/src/webview/workspace.ts +++ b/extension/src/webview/workspace.ts @@ -1,8 +1,11 @@ import { Memento, ViewColumn } from 'vscode' import { BaseRepository } from './repository' import { WebviewData } from './contract' +import { createWebview } from './factory' +import { ViewKey } from './constants' import { InternalCommands } from '../commands/internal' import { BaseWorkspace } from '../workspace' +import { ResourceLocator } from '../resourceLocator' export abstract class BaseWorkspaceWebviews< T extends BaseRepository, @@ -12,22 +15,37 @@ export abstract class BaseWorkspaceWebviews< protected focusedWebviewDvcRoot: string | undefined + private resourceLocator: ResourceLocator + private noDvc: boolean + constructor( internalCommands: InternalCommands, workspaceState: Memento, + resourceLocator: ResourceLocator, + noDvc: boolean, repositories?: Record ) { super(internalCommands) this.workspaceState = workspaceState + this.resourceLocator = resourceLocator + + this.noDvc = noDvc + if (repositories) { this.repositories = repositories } } public async showWebview(overrideRoot: string, viewColumn?: ViewColumn) { + if (this.noDvc) { + this.showEmptyWebview(viewColumn) + return + } + const dvcRoot = overrideRoot || (await this.getOnlyOrPickProject()) + if (!dvcRoot) { return } @@ -48,5 +66,15 @@ export abstract class BaseWorkspaceWebviews< return overrideRoot || (await this.getFocusedOrOnlyOrPickProject()) } + protected async showEmptyWebview(viewColumn?: ViewColumn) { + await createWebview( + ViewKey.GET_STARTED, + '', + this.resourceLocator.dvcIcon, + viewColumn, + true + ) + } + abstract getFocusedOrOnlyOrPickProject(): string | Promise } diff --git a/webview/.eslintrc.js b/webview/.eslintrc.js index 61a21600bf..1fb6f085ff 100644 --- a/webview/.eslintrc.js +++ b/webview/.eslintrc.js @@ -16,7 +16,8 @@ module.exports = { files: [ 'src/experiments/index.tsx', 'src/plots/index.tsx', - 'src/shared/components/icons/index.ts' + 'src/shared/components/icons/index.ts', + 'src/getStarted/index.tsx' ], rules: { 'check-file/no-index': 'off' diff --git a/webview/index.d.ts b/webview/index.d.ts index 537e3211d1..55e2c6a605 100644 --- a/webview/index.d.ts +++ b/webview/index.d.ts @@ -1,4 +1,5 @@ export const distPath: string export const experiments: string export const plots: string +export const getStarted: string export const react: string diff --git a/webview/index.js b/webview/index.js index b69ccb78c6..5989aa67a1 100644 --- a/webview/index.js +++ b/webview/index.js @@ -8,4 +8,5 @@ const path = require('path') module.exports.distPath = path.join(__dirname, 'dist') module.exports.experiments = path.join(__dirname, 'dist/experiments.js') module.exports.plots = path.join(__dirname, 'dist/plots.js') +module.exports.getStarted = path.join(__dirname, 'dist/getStarted.js') module.exports.react = path.join(__dirname, 'dist/react.js') diff --git a/webview/src/getStarted/components/App.tsx b/webview/src/getStarted/components/App.tsx new file mode 100644 index 0000000000..bae7796e2f --- /dev/null +++ b/webview/src/getStarted/components/App.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import { EmptyState } from '../../shared/components/emptyState/EmptyState' + +export const App: React.FC = () => { + return ( + +
+

DVC is not available or not initialized

+
+
+ ) +} diff --git a/webview/src/getStarted/index.tsx b/webview/src/getStarted/index.tsx new file mode 100644 index 0000000000..95de9279c6 --- /dev/null +++ b/webview/src/getStarted/index.tsx @@ -0,0 +1,7 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import '../shared/style.scss' +import { App } from './components/App' + +const root = ReactDOM.createRoot(document.querySelector('#root') as HTMLElement) +root.render() diff --git a/webview/webpack.config.ts b/webview/webpack.config.ts index 1ff8980c0e..5feb4471bc 100644 --- a/webview/webpack.config.ts +++ b/webview/webpack.config.ts @@ -26,7 +26,11 @@ export default { entry: { experiments: { dependOn: 'react', import: r('src/experiments/index.tsx') }, plots: { dependOn: 'react', import: r('src/plots/index.tsx') }, - react: ['react', 'react-dom'] + react: ['react', 'react-dom'], + getStarted: { + dependOn: 'react', + import: r('src/getStarted/index.tsx') + } }, module: { rules: [ From 3159c9d9bc11f45672dc246faefc6a5d693f24bd Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Wed, 30 Nov 2022 13:51:50 -0500 Subject: [PATCH 2/7] Allow incompatible dvc to show webviews --- extension/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/src/extension.ts b/extension/src/extension.ts index 4f627fb4b8..e12fb5a298 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -141,7 +141,7 @@ export class Extension extends Disposable implements IExtension { ]) ) - const noDvc = !this.cliAccessible || !this.cliCompatible || !this.hasRoots + const noDvc = !this.cliAccessible || !this.hasRoots this.experiments = this.dispose.track( new WorkspaceExperiments( From f0e8a7467fa894a4ae56c2f8820149746100cabf Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Wed, 30 Nov 2022 14:32:24 -0500 Subject: [PATCH 3/7] Fix tests and lint errors --- extension/src/experiments/workspace.test.ts | 1 + extension/src/telemetry/constants.ts | 10 +++++----- .../test/suite/experiments/model/filterBy/tree.test.ts | 1 + extension/src/test/suite/experiments/util.ts | 4 +++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/extension/src/experiments/workspace.test.ts b/extension/src/experiments/workspace.test.ts index aa57598551..01fb71880e 100644 --- a/extension/src/experiments/workspace.test.ts +++ b/extension/src/experiments/workspace.test.ts @@ -62,6 +62,7 @@ describe('Experiments', () => { mockedUpdatesPaused, buildMockMemento(), {} as ResourceLocator, + false, { '/my/dvc/root': { getDvcRoot: () => mockedDvcRoot, diff --git a/extension/src/telemetry/constants.ts b/extension/src/telemetry/constants.ts index f39cd2b755..c71be2e58d 100644 --- a/extension/src/telemetry/constants.ts +++ b/extension/src/telemetry/constants.ts @@ -58,6 +58,10 @@ export const EventName = Object.assign( VIEWS_EXPERIMENTS_TABLE_SORT_COLUMN: 'views.experimentsTable.columnSortAdded', + VIEWS_GET_STARTED_CLOSE: 'view.GET_STARTED.closed', + VIEWS_GET_STARTED_CREATED: 'view.GET_STARTED.created', + VIEWS_GET_STARTED_FOCUS_CHANGED: 'views.GET_STARTED.focusChanged', + VIEWS_PLOTS_CLOSED: 'views.plots.closed', VIEWS_PLOTS_COMPARISON_ROWS_REORDERED: 'views.plots.comparisonRowsReordered', @@ -76,11 +80,7 @@ export const EventName = Object.assign( VIEWS_TERMINAL_CLOSED: 'views.terminal.closed', VIEWS_TERMINAL_CREATED: 'views.terminal.created', - VIEWS_TERMINAL_FOCUS_CHANGED: 'views.terminal.focusChanged', - - VIEWS_GET_STARTED_CLOSE: 'view.GET_STARTED.closed', - VIEWS_GET_STARTED_CREATED: 'view.GET_STARTED.created', - VIEWS_GET_STARTED_FOCUS_CHANGED: 'views.GET_STARTED.focusChanged' + VIEWS_TERMINAL_FOCUS_CHANGED: 'views.terminal.focusChanged' } as const, ViewOpenedEvent, RegisteredCliCommands, diff --git a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts index 459da45a0b..71d4073c90 100644 --- a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts +++ b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts @@ -359,6 +359,7 @@ suite('Experiments Filter By Tree Test Suite', () => { disposable.track(new EventEmitter()), buildMockMemento(), {} as ResourceLocator, + false, { [dvcDemoPath]: experiments }, disposable.track(new EventEmitter()) ) diff --git a/extension/src/test/suite/experiments/util.ts b/extension/src/test/suite/experiments/util.ts index 71f62e3f08..c1375a60cc 100644 --- a/extension/src/test/suite/experiments/util.ts +++ b/extension/src/test/suite/experiments/util.ts @@ -106,6 +106,7 @@ export const buildMultiRepoExperiments = (disposer: Disposer) => { updatesPaused, buildMockMemento(), resourceLocator, + false, { 'other/dvc/root': mockExperiments } @@ -135,7 +136,8 @@ export const buildSingleRepoExperiments = (disposer: Disposer) => { internalCommands, updatesPaused, buildMockMemento(), - {} as ResourceLocator + {} as ResourceLocator, + false ) ) const [experiments] = workspaceExperiments.create( From 07ee526b90f61ef1c2d58ace7c13c52b591cf644 Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Wed, 30 Nov 2022 18:17:16 -0500 Subject: [PATCH 4/7] Make sure webviews load after initialization --- extension/src/experiments/workspace.test.ts | 2 +- extension/src/experiments/workspace.ts | 10 ++++++++-- extension/src/extension.ts | 10 ++++++---- .../test/suite/experiments/model/filterBy/tree.test.ts | 2 +- extension/src/test/suite/experiments/util.ts | 4 ++-- extension/src/webview/workspace.ts | 8 ++++---- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/extension/src/experiments/workspace.test.ts b/extension/src/experiments/workspace.test.ts index 01fb71880e..835e8b5f51 100644 --- a/extension/src/experiments/workspace.test.ts +++ b/extension/src/experiments/workspace.test.ts @@ -62,7 +62,7 @@ describe('Experiments', () => { mockedUpdatesPaused, buildMockMemento(), {} as ResourceLocator, - false, + () => true, { '/my/dvc/root': { getDvcRoot: () => mockedDvcRoot, diff --git a/extension/src/experiments/workspace.ts b/extension/src/experiments/workspace.ts index 10ff637612..a4a69d02e3 100644 --- a/extension/src/experiments/workspace.ts +++ b/extension/src/experiments/workspace.ts @@ -36,11 +36,17 @@ export class WorkspaceExperiments extends BaseWorkspaceWebviews< updatesPaused: EventEmitter, workspaceState: Memento, resourceLocator: ResourceLocator, - noDvc: boolean, + getAvailable: () => boolean, experiments?: Record, checkpointsChanged?: EventEmitter ) { - super(internalCommands, workspaceState, resourceLocator, noDvc, experiments) + super( + internalCommands, + workspaceState, + resourceLocator, + getAvailable, + experiments + ) this.updatesPaused = updatesPaused diff --git a/extension/src/extension.ts b/extension/src/extension.ts index e12fb5a298..fab9171090 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -141,15 +141,13 @@ export class Extension extends Disposable implements IExtension { ]) ) - const noDvc = !this.cliAccessible || !this.hasRoots - this.experiments = this.dispose.track( new WorkspaceExperiments( this.internalCommands, this.updatesPaused, context.workspaceState, this.resourceLocator, - noDvc + () => this.getAvailable() ) ) @@ -158,7 +156,7 @@ export class Extension extends Disposable implements IExtension { this.internalCommands, context.workspaceState, this.resourceLocator, - noDvc + () => this.getAvailable() ) ) @@ -442,6 +440,10 @@ export class Extension extends Disposable implements IExtension { return available } + public getAvailable() { + return this.cliAccessible + } + private setCommandsAvailability(available: boolean) { setContextValue('dvc.commands.available', available) } diff --git a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts index 71d4073c90..77b4a71ce2 100644 --- a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts +++ b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts @@ -359,7 +359,7 @@ suite('Experiments Filter By Tree Test Suite', () => { disposable.track(new EventEmitter()), buildMockMemento(), {} as ResourceLocator, - false, + () => true, { [dvcDemoPath]: experiments }, disposable.track(new EventEmitter()) ) diff --git a/extension/src/test/suite/experiments/util.ts b/extension/src/test/suite/experiments/util.ts index c1375a60cc..22ffd906e4 100644 --- a/extension/src/test/suite/experiments/util.ts +++ b/extension/src/test/suite/experiments/util.ts @@ -106,7 +106,7 @@ export const buildMultiRepoExperiments = (disposer: Disposer) => { updatesPaused, buildMockMemento(), resourceLocator, - false, + () => true, { 'other/dvc/root': mockExperiments } @@ -137,7 +137,7 @@ export const buildSingleRepoExperiments = (disposer: Disposer) => { updatesPaused, buildMockMemento(), {} as ResourceLocator, - false + () => true ) ) const [experiments] = workspaceExperiments.create( diff --git a/extension/src/webview/workspace.ts b/extension/src/webview/workspace.ts index 0e1cb6a2b0..05a2940c7c 100644 --- a/extension/src/webview/workspace.ts +++ b/extension/src/webview/workspace.ts @@ -16,13 +16,13 @@ export abstract class BaseWorkspaceWebviews< protected focusedWebviewDvcRoot: string | undefined private resourceLocator: ResourceLocator - private noDvc: boolean + private getAvailable: () => boolean constructor( internalCommands: InternalCommands, workspaceState: Memento, resourceLocator: ResourceLocator, - noDvc: boolean, + getAvailable: () => boolean, repositories?: Record ) { super(internalCommands) @@ -31,7 +31,7 @@ export abstract class BaseWorkspaceWebviews< this.resourceLocator = resourceLocator - this.noDvc = noDvc + this.getAvailable = getAvailable if (repositories) { this.repositories = repositories @@ -39,7 +39,7 @@ export abstract class BaseWorkspaceWebviews< } public async showWebview(overrideRoot: string, viewColumn?: ViewColumn) { - if (this.noDvc) { + if (!this.getAvailable() || this.getDvcRoots().length === 0) { this.showEmptyWebview(viewColumn) return } From bd3b9c8c1a997055604479d9794d7b53872209f6 Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Wed, 30 Nov 2022 18:41:04 -0500 Subject: [PATCH 5/7] Change order of sidebar views --- extension/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extension/package.json b/extension/package.json index 6d5bc04054..6cda176e17 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1306,11 +1306,6 @@ } ], "dvc-views": [ - { - "id": "dvc.views.webviews", - "name": "Views", - "when": "true" - }, { "id": "dvc.views.experimentsColumnsTree", "name": "Columns", @@ -1321,6 +1316,11 @@ "name": "Welcome", "when": "!dvc.commands.available || dvc.cli.incompatible || !dvc.project.available" }, + { + "id": "dvc.views.webviews", + "name": "Views", + "when": "true" + }, { "id": "dvc.views.experimentsTree", "name": "Experiments", From 2e7f2dbf3918cd0075a926613215114d3eee8887 Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Thu, 1 Dec 2022 10:17:04 -0500 Subject: [PATCH 6/7] Register open get started webview to simplify code paths --- extension/package.json | 7 ++++- extension/src/commands/external.ts | 4 ++- extension/src/experiments/workspace.test.ts | 3 --- extension/src/experiments/workspace.ts | 10 +------ extension/src/extension.ts | 26 +++++++++++------- extension/src/telemetry/constants.ts | 2 ++ .../experiments/model/filterBy/tree.test.ts | 3 --- extension/src/test/suite/experiments/util.ts | 7 +---- extension/src/webview/workspace.ts | 27 ------------------- 9 files changed, 30 insertions(+), 59 deletions(-) diff --git a/extension/package.json b/extension/package.json index 6cda176e17..527b7aa9ad 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1351,7 +1351,12 @@ { "view": "dvc.views.webviews", "contents": "[Show Experiments](command:dvc.showExperiments)\n[Show Plots](command:dvc.showPlots)\n[Show Experiments and Plots](command:dvc.showExperimentsAndPlots)", - "when": "true" + "when": "dvc.commands.available && dvc.project.available" + }, + { + "view": "dvc.views.webviews", + "contents": "[Show Experiments](command:dvc.showGetStartedWebview)\n[Show Plots](command:dvc.showGetStartedWebview)\n[Show Experiments and Plots](command:dvc.showGetStartedWebview)", + "when": "!dvc.commands.available || !dvc.project.available" }, { "view": "dvc.views.welcome", diff --git a/extension/src/commands/external.ts b/extension/src/commands/external.ts index e53883bcf4..dae75d81e1 100644 --- a/extension/src/commands/external.ts +++ b/extension/src/commands/external.ts @@ -90,5 +90,7 @@ export enum RegisteredCommands { TRACKED_EXPLORER_COPY_REL_FILE_PATH = 'dvc.copyRelativeFilePath', TRACKED_EXPLORER_FIND_IN_FOLDER = 'dvc.findInFolder', TRACKED_EXPLORER_OPEN_TO_THE_SIDE = 'dvc.openToTheSide', - TRACKED_EXPLORER_SELECT_FOR_COMPARE = 'dvc.selectForCompare' + TRACKED_EXPLORER_SELECT_FOR_COMPARE = 'dvc.selectForCompare', + + GET_STARTED_WEBVIEW_SHOW = 'dvc.showGetStartedWebview' } diff --git a/extension/src/experiments/workspace.test.ts b/extension/src/experiments/workspace.test.ts index 835e8b5f51..d898a82b53 100644 --- a/extension/src/experiments/workspace.test.ts +++ b/extension/src/experiments/workspace.test.ts @@ -13,7 +13,6 @@ import { buildMockedEventEmitter } from '../test/util/jest' import { OutputChannel } from '../vscode/outputChannel' import { Title } from '../vscode/title' import { Args } from '../cli/dvc/constants' -import { ResourceLocator } from '../resourceLocator' const mockedShowWebview = jest.fn() const mockedDisposable = jest.mocked(Disposable) @@ -61,8 +60,6 @@ describe('Experiments', () => { mockedInternalCommands, mockedUpdatesPaused, buildMockMemento(), - {} as ResourceLocator, - () => true, { '/my/dvc/root': { getDvcRoot: () => mockedDvcRoot, diff --git a/extension/src/experiments/workspace.ts b/extension/src/experiments/workspace.ts index a4a69d02e3..0a85d46233 100644 --- a/extension/src/experiments/workspace.ts +++ b/extension/src/experiments/workspace.ts @@ -35,18 +35,10 @@ export class WorkspaceExperiments extends BaseWorkspaceWebviews< internalCommands: InternalCommands, updatesPaused: EventEmitter, workspaceState: Memento, - resourceLocator: ResourceLocator, - getAvailable: () => boolean, experiments?: Record, checkpointsChanged?: EventEmitter ) { - super( - internalCommands, - workspaceState, - resourceLocator, - getAvailable, - experiments - ) + super(internalCommands, workspaceState, experiments) this.updatesPaused = updatesPaused diff --git a/extension/src/extension.ts b/extension/src/extension.ts index fab9171090..bfafccaba2 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -61,6 +61,8 @@ import { collectWorkspaceScale } from './telemetry/collect' import { createFileSystemWatcher } from './fileSystem/watcher' import { GitExecutor } from './cli/git/executor' import { GitReader } from './cli/git/reader' +import { createWebview } from './webview/factory' +import { ViewKey } from './webview/constants' export class Extension extends Disposable implements IExtension { protected readonly internalCommands: InternalCommands @@ -145,19 +147,12 @@ export class Extension extends Disposable implements IExtension { new WorkspaceExperiments( this.internalCommands, this.updatesPaused, - context.workspaceState, - this.resourceLocator, - () => this.getAvailable() + context.workspaceState ) ) this.plots = this.dispose.track( - new WorkspacePlots( - this.internalCommands, - context.workspaceState, - this.resourceLocator, - () => this.getAvailable() - ) + new WorkspacePlots(this.internalCommands, context.workspaceState) ) this.repositories = this.dispose.track( @@ -259,6 +254,19 @@ export class Extension extends Disposable implements IExtension { } ) + this.internalCommands.registerExternalCommand( + RegisteredCommands.GET_STARTED_WEBVIEW_SHOW, + async () => { + await createWebview( + ViewKey.GET_STARTED, + '', + this.resourceLocator.dvcIcon, + ViewColumn.Active, + true + ) + } + ) + this.dispose.track( commands.registerCommand(RegisteredCommands.STOP_EXPERIMENT, async () => { const stopWatch = new StopWatch() diff --git a/extension/src/telemetry/constants.ts b/extension/src/telemetry/constants.ts index c71be2e58d..9dab056d7a 100644 --- a/extension/src/telemetry/constants.ts +++ b/extension/src/telemetry/constants.ts @@ -260,4 +260,6 @@ export interface IEventNamePropertyMapping { [EventName.VIEWS_GET_STARTED_CLOSE]: undefined [EventName.VIEWS_GET_STARTED_CREATED]: undefined [EventName.VIEWS_GET_STARTED_FOCUS_CHANGED]: undefined + + [EventName.GET_STARTED_WEBVIEW_SHOW]: undefined } diff --git a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts index 77b4a71ce2..31054debaf 100644 --- a/extension/src/test/suite/experiments/model/filterBy/tree.test.ts +++ b/extension/src/test/suite/experiments/model/filterBy/tree.test.ts @@ -41,7 +41,6 @@ import { FilterItem } from '../../../../../experiments/model/filterBy/tree' import { starredFilter } from '../../../../../experiments/model/filterBy/constants' -import { ResourceLocator } from '../../../../../resourceLocator' suite('Experiments Filter By Tree Test Suite', () => { const disposable = Disposable.fn() @@ -358,8 +357,6 @@ suite('Experiments Filter By Tree Test Suite', () => { internalCommands, disposable.track(new EventEmitter()), buildMockMemento(), - {} as ResourceLocator, - () => true, { [dvcDemoPath]: experiments }, disposable.track(new EventEmitter()) ) diff --git a/extension/src/test/suite/experiments/util.ts b/extension/src/test/suite/experiments/util.ts index 22ffd906e4..68f40708aa 100644 --- a/extension/src/test/suite/experiments/util.ts +++ b/extension/src/test/suite/experiments/util.ts @@ -19,7 +19,6 @@ import { FileSystemData } from '../../../fileSystem/data' import * as Watcher from '../../../fileSystem/watcher' import { ExperimentsModel } from '../../../experiments/model' import { ColumnsModel } from '../../../experiments/columns/model' -import { ResourceLocator } from '../../../resourceLocator' const hasCheckpoints = (data: ExperimentsOutput) => { const [experimentsWithBaseline] = Object.values(omit(data, 'workspace')) @@ -105,8 +104,6 @@ export const buildMultiRepoExperiments = (disposer: Disposer) => { internalCommands, updatesPaused, buildMockMemento(), - resourceLocator, - () => true, { 'other/dvc/root': mockExperiments } @@ -135,9 +132,7 @@ export const buildSingleRepoExperiments = (disposer: Disposer) => { new WorkspaceExperiments( internalCommands, updatesPaused, - buildMockMemento(), - {} as ResourceLocator, - () => true + buildMockMemento() ) ) const [experiments] = workspaceExperiments.create( diff --git a/extension/src/webview/workspace.ts b/extension/src/webview/workspace.ts index 05a2940c7c..1dfde94e4a 100644 --- a/extension/src/webview/workspace.ts +++ b/extension/src/webview/workspace.ts @@ -1,11 +1,8 @@ import { Memento, ViewColumn } from 'vscode' import { BaseRepository } from './repository' import { WebviewData } from './contract' -import { createWebview } from './factory' -import { ViewKey } from './constants' import { InternalCommands } from '../commands/internal' import { BaseWorkspace } from '../workspace' -import { ResourceLocator } from '../resourceLocator' export abstract class BaseWorkspaceWebviews< T extends BaseRepository, @@ -15,35 +12,21 @@ export abstract class BaseWorkspaceWebviews< protected focusedWebviewDvcRoot: string | undefined - private resourceLocator: ResourceLocator - private getAvailable: () => boolean - constructor( internalCommands: InternalCommands, workspaceState: Memento, - resourceLocator: ResourceLocator, - getAvailable: () => boolean, repositories?: Record ) { super(internalCommands) this.workspaceState = workspaceState - this.resourceLocator = resourceLocator - - this.getAvailable = getAvailable - if (repositories) { this.repositories = repositories } } public async showWebview(overrideRoot: string, viewColumn?: ViewColumn) { - if (!this.getAvailable() || this.getDvcRoots().length === 0) { - this.showEmptyWebview(viewColumn) - return - } - const dvcRoot = overrideRoot || (await this.getOnlyOrPickProject()) if (!dvcRoot) { @@ -66,15 +49,5 @@ export abstract class BaseWorkspaceWebviews< return overrideRoot || (await this.getFocusedOrOnlyOrPickProject()) } - protected async showEmptyWebview(viewColumn?: ViewColumn) { - await createWebview( - ViewKey.GET_STARTED, - '', - this.resourceLocator.dvcIcon, - viewColumn, - true - ) - } - abstract getFocusedOrOnlyOrPickProject(): string | Promise } From 64e52fc7c8cae4f1377a12d133e4e166a343717d Mon Sep 17 00:00:00 2001 From: Stephanie Roy Date: Thu, 1 Dec 2022 10:21:45 -0500 Subject: [PATCH 7/7] Remove useless changes --- extension/src/extension.ts | 4 ---- extension/src/webview/workspace.ts | 1 - 2 files changed, 5 deletions(-) diff --git a/extension/src/extension.ts b/extension/src/extension.ts index bfafccaba2..667ceef07e 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -448,10 +448,6 @@ export class Extension extends Disposable implements IExtension { return available } - public getAvailable() { - return this.cliAccessible - } - private setCommandsAvailability(available: boolean) { setContextValue('dvc.commands.available', available) } diff --git a/extension/src/webview/workspace.ts b/extension/src/webview/workspace.ts index 1dfde94e4a..d1fb18d9d7 100644 --- a/extension/src/webview/workspace.ts +++ b/extension/src/webview/workspace.ts @@ -28,7 +28,6 @@ export abstract class BaseWorkspaceWebviews< public async showWebview(overrideRoot: string, viewColumn?: ViewColumn) { const dvcRoot = overrideRoot || (await this.getOnlyOrPickProject()) - if (!dvcRoot) { return }