From b4f7b1c51d9b085762c7382b1ba7e704bfdd87e6 Mon Sep 17 00:00:00 2001 From: Tomas Vik Date: Wed, 9 Jun 2021 11:13:54 +0200 Subject: [PATCH] fix: each overview tab gets opened only once --- src/extension.js | 2 +- src/webview_controller.ts | 19 ++++++++++++++++++- test/integration/webview.test.js | 19 +++++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/extension.js b/src/extension.js index 4bbc729..6c1ed58 100644 --- a/src/extension.js +++ b/src/extension.js @@ -77,7 +77,7 @@ const registerCommands = (context, outputChannel) => { [USER_COMMANDS.INSERT_SNIPPET]: insertSnippet, [USER_COMMANDS.VALIDATE_CI_CONFIG]: ciConfigValidator.validate, [USER_COMMANDS.REFRESH_SIDEBAR]: sidebar.refresh, - [PROGRAMMATIC_COMMANDS.SHOW_RICH_CONTENT]: webviewController.create.bind(webviewController), + [PROGRAMMATIC_COMMANDS.SHOW_RICH_CONTENT]: webviewController.open.bind(webviewController), [USER_COMMANDS.SHOW_OUTPUT]: () => outputChannel.show(), [USER_COMMANDS.RESOLVE_THREAD]: toggleResolved, [USER_COMMANDS.UNRESOLVE_THREAD]: toggleResolved, diff --git a/src/webview_controller.ts b/src/webview_controller.ts index c9c6663..ee11cb2 100644 --- a/src/webview_controller.ts +++ b/src/webview_controller.ts @@ -48,6 +48,8 @@ class WebviewController { isDev = false; + openedPanels: Record = {}; + init(context: vscode.ExtensionContext, isDev: boolean) { this.context = context; this.isDev = isDev; @@ -144,7 +146,22 @@ class WebviewController { : { light: lightIssueIcon, dark: darkIssueIcon }; } - async create(issuable: RestIssuable, repositoryRoot: string) { + async open(issuable: RestIssuable, repositoryRoot: string) { + const panelKey = `${repositoryRoot}-${issuable.id}`; + const openedPanel = this.openedPanels[panelKey]; + if (openedPanel) { + openedPanel.reveal(); + return openedPanel; + } + const newPanel = await this.create(issuable, repositoryRoot); + this.openedPanels[panelKey] = newPanel; + newPanel.onDidDispose(() => { + this.openedPanels[panelKey] = undefined; + }); + return newPanel; + } + + private async create(issuable: RestIssuable, repositoryRoot: string) { assert(this.context); const panel = this.createPanel(issuable); const html = this.replaceResources(panel); diff --git a/test/integration/webview.test.js b/test/integration/webview.test.js index 7cd4f8a..c4c076d 100644 --- a/test/integration/webview.test.js +++ b/test/integration/webview.test.js @@ -10,6 +10,7 @@ const { projectWithIssueDiscussions, note2 } = require('./fixtures/graphql/discu const { getServer, createJsonEndpoint } = require('./test_infrastructure/mock_server'); const { GITLAB_URL } = require('./test_infrastructure/constants'); +const { getRepositoryRoot } = require('./test_infrastructure/helpers'); const waitForMessage = (panel, type) => new Promise(resolve => { @@ -82,10 +83,7 @@ describe('GitLab webview', () => { beforeEach(async () => { server.resetHandlers(); replacePanelEventSystem(); - webviewPanel = await webviewController.create( - openIssueResponse, - vscode.workspace.workspaceFolders[0].uri.fsPath, - ); + webviewPanel = await webviewController.open(openIssueResponse, getRepositoryRoot()); }); afterEach(async () => { @@ -123,4 +121,17 @@ describe('GitLab webview', () => { assert.match(webviewPanel.webview.html, new RegExp(r, 'gm')); }); }); + + it('reveals existing panel instead of creating a new one', async () => { + const revealSpy = sandbox.spy(webviewPanel, 'reveal'); + const samePanel = await webviewController.open(openIssueResponse, getRepositoryRoot()); + assert(revealSpy.called); + assert.strictEqual(samePanel, webviewPanel); + }); + + it('creates a new panel if the previous one got disposed', async () => { + webviewPanel.dispose(); + const newPanel = await webviewController.open(openIssueResponse, getRepositoryRoot()); + assert.notStrictEqual(newPanel, webviewPanel); + }); }); -- GitLab