Add extension setting to control showing cli success messages via inf… (#259)

* Add extension setting to control showing cli success messages via information messages or status bar.
This commit is contained in:
lcampos 2018-01-16 17:25:26 -08:00 коммит произвёл GitHub
Родитель 758b60e9f7
Коммит f5c0ff099b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 165 добавлений и 10 удалений

Просмотреть файл

@ -368,7 +368,14 @@
], ],
"configuration": { "configuration": {
"type": "object", "type": "object",
"title": "%feature_previews_title%" "title": "%feature_previews_title%",
"properties": {
"salesforcedx-vscode-core.show-cli-success-msg": {
"type": ["boolean"],
"default": true,
"description": "%show_cli_success_msg_description%"
}
}
} }
} }
} }

Просмотреть файл

@ -44,5 +44,7 @@
"SFDX: Execute Anonymous Apex with Currently Selected Text", "SFDX: Execute Anonymous Apex with Currently Selected Text",
"feature_previews_title": "Salesforce Feature Previews", "feature_previews_title": "Salesforce Feature Previews",
"force_project_create_text": "SFDX: Create Project", "force_project_create_text": "SFDX: Create Project",
"force_apex_trigger_create_text": "SFDX: Create Apex Trigger" "force_apex_trigger_create_text": "SFDX: Create Apex Trigger",
"show_cli_success_msg_description":
"Specifies whether status messages for Salesforce CLI commands run using the VS Code command palette will appear as pop-up information messages (true) or as status bar messages (false)."
} }

Просмотреть файл

@ -13,3 +13,6 @@ export const TERMINAL_INTEGRATED_ENVS = [
'terminal.integrated.env.linux', 'terminal.integrated.env.linux',
'terminal.integrated.env.windows' 'terminal.integrated.env.windows'
]; ];
export const SFDX_CORE_CONFIGURATION_NAME = 'salesforcedx-vscode-core';
export const STATUS_BAR_MSG_TIMEOUT_MS = 5000;
export const SHOW_CLI_SUCCESS_INFO_MSG = 'show-cli-success-msg';

Просмотреть файл

@ -28,6 +28,7 @@ export const messages = {
notification_canceled_execution_text: '%s was canceled', notification_canceled_execution_text: '%s was canceled',
notification_unsuccessful_execution_text: '%s failed to run', notification_unsuccessful_execution_text: '%s failed to run',
notification_show_button_text: 'Show', notification_show_button_text: 'Show',
notification_show_in_status_bar_button_text: 'Show Only in Status Bar',
predicates_no_folder_opened_text: predicates_no_folder_opened_text:
'No folder opened. Open a Salesforce DX project in VS Code.', 'No folder opened. Open a Salesforce DX project in VS Code.',

Просмотреть файл

@ -9,7 +9,9 @@ import { CommandExecution } from '@salesforce/salesforcedx-utils-vscode/out/src/
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { DEFAULT_SFDX_CHANNEL } from '../channels'; import { DEFAULT_SFDX_CHANNEL } from '../channels';
import { STATUS_BAR_MSG_TIMEOUT_MS } from '../constants';
import { nls } from '../messages'; import { nls } from '../messages';
import { sfdxCoreSettings } from '../settings';
/** /**
* A centralized location for all notification functionalities. * A centralized location for all notification functionalities.
@ -76,13 +78,28 @@ export class NotificationService {
) { ) {
observable.subscribe(async data => { observable.subscribe(async data => {
if (data != undefined && data.toString() === '0') { if (data != undefined && data.toString() === '0') {
const showButtonText = nls.localize('notification_show_button_text'); const message = nls.localize(
const selection = await this.showInformationMessage( 'notification_successful_execution_text',
nls.localize('notification_successful_execution_text', executionName), executionName
showButtonText
); );
if (selection && selection === showButtonText) { if (sfdxCoreSettings.getShowCLISuccessMsg()) {
this.channel.show(); const showButtonText = nls.localize('notification_show_button_text');
const showOnlyStatusBarButtonText = nls.localize(
'notification_show_in_status_bar_button_text'
);
const selection = await this.showInformationMessage(
message,
showButtonText,
showOnlyStatusBarButtonText
);
if (selection && selection === showButtonText) {
this.channel.show();
}
if (selection && selection === showOnlyStatusBarButtonText) {
sfdxCoreSettings.updateShowCLISuccessMsg(false);
}
} else {
vscode.window.setStatusBarMessage(message, STATUS_BAR_MSG_TIMEOUT_MS);
} }
} else { } else {
if (cancellationToken && cancellationToken.isCancellationRequested) { if (cancellationToken && cancellationToken.isCancellationRequested) {

Просмотреть файл

@ -0,0 +1,10 @@
/*
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { SfdxCoreSettings } from './sfdxCoreSettings';
export const sfdxCoreSettings = SfdxCoreSettings.getInstance();

Просмотреть файл

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import * as vscode from 'vscode';
import {
SFDX_CORE_CONFIGURATION_NAME,
SHOW_CLI_SUCCESS_INFO_MSG
} from '../constants';
/**
* A centralized location for interacting with sfdx-core settings.
*/
export class SfdxCoreSettings {
private static instance: SfdxCoreSettings;
public static getInstance() {
if (!SfdxCoreSettings.instance) {
SfdxCoreSettings.instance = new SfdxCoreSettings();
}
return SfdxCoreSettings.instance;
}
/**
* Get the configuration for a sfdx-core
*/
public getConfiguration(): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration(SFDX_CORE_CONFIGURATION_NAME);
}
public getShowCLISuccessMsg(): boolean {
return this.getConfigValue<boolean>(SHOW_CLI_SUCCESS_INFO_MSG, true);
}
public async updateShowCLISuccessMsg(value: boolean) {
await this.setConfigValue(SHOW_CLI_SUCCESS_INFO_MSG, value);
}
private getConfigValue<T>(key: string, defaultValue: T): T {
return this.getConfiguration().get<T>(key, defaultValue);
}
private async setConfigValue(key: string, value: any) {
await this.getConfiguration().update(key, value);
}
}

Просмотреть файл

@ -11,8 +11,12 @@ import { CancellationTokenSource, window } from 'vscode';
import { DEFAULT_SFDX_CHANNEL } from '../../src/channels/channelService'; import { DEFAULT_SFDX_CHANNEL } from '../../src/channels/channelService';
import { nls } from '../../src/messages'; import { nls } from '../../src/messages';
import { NotificationService } from '../../src/notifications/notificationService'; import { NotificationService } from '../../src/notifications/notificationService';
import { SfdxCoreSettings } from '../../src/settings/sfdxCoreSettings';
const SHOW_BUTTON_TEXT = nls.localize('notification_show_button_text'); const SHOW_BUTTON_TEXT = nls.localize('notification_show_button_text');
const SHOW_ONLY_STATUS_BAR_BUTTON_TEXT = nls.localize(
'notification_show_in_status_bar_button_text'
);
// tslint:disable:no-empty // tslint:disable:no-empty
describe('Notifications', () => { describe('Notifications', () => {
@ -20,6 +24,8 @@ describe('Notifications', () => {
let mShowWarningMessage: SinonStub; let mShowWarningMessage: SinonStub;
let mShowErrorMessage: SinonStub; let mShowErrorMessage: SinonStub;
let mShow: SinonStub; let mShow: SinonStub;
let mStatusBar: SinonStub;
let settings: SinonStub;
beforeEach(() => { beforeEach(() => {
mShow = stub(DEFAULT_SFDX_CHANNEL, 'show'); mShow = stub(DEFAULT_SFDX_CHANNEL, 'show');
@ -32,6 +38,12 @@ describe('Notifications', () => {
mShowErrorMessage = stub(window, 'showErrorMessage').returns( mShowErrorMessage = stub(window, 'showErrorMessage').returns(
Promise.resolve(null) Promise.resolve(null)
); );
mStatusBar = stub(window, 'setStatusBarMessage').returns(
Promise.resolve(null)
);
settings = stub(SfdxCoreSettings.prototype, 'getShowCLISuccessMsg').returns(
true
);
}); });
afterEach(() => { afterEach(() => {
@ -39,6 +51,8 @@ describe('Notifications', () => {
mShowInformation.restore(); mShowInformation.restore();
mShowWarningMessage.restore(); mShowWarningMessage.restore();
mShowErrorMessage.restore(); mShowErrorMessage.restore();
mStatusBar.restore();
settings.restore();
}); });
it('Should notify successful execution', async () => { it('Should notify successful execution', async () => {
@ -52,10 +66,12 @@ describe('Notifications', () => {
assert.calledWith( assert.calledWith(
mShowInformation, mShowInformation,
'mock command successfully ran', 'mock command successfully ran',
SHOW_BUTTON_TEXT SHOW_BUTTON_TEXT,
SHOW_ONLY_STATUS_BAR_BUTTON_TEXT
); );
assert.notCalled(mShowWarningMessage); assert.notCalled(mShowWarningMessage);
assert.notCalled(mShowErrorMessage); assert.notCalled(mShowErrorMessage);
assert.notCalled(mStatusBar);
}); });
it('Should notify successful and show channel as requested', async () => { it('Should notify successful and show channel as requested', async () => {
@ -74,10 +90,61 @@ describe('Notifications', () => {
assert.calledWith( assert.calledWith(
mShowInformation, mShowInformation,
'mock command successfully ran', 'mock command successfully ran',
SHOW_BUTTON_TEXT SHOW_BUTTON_TEXT,
SHOW_ONLY_STATUS_BAR_BUTTON_TEXT
); );
assert.notCalled(mShowWarningMessage); assert.notCalled(mShowWarningMessage);
assert.notCalled(mShowErrorMessage); assert.notCalled(mShowErrorMessage);
assert.notCalled(mStatusBar);
});
it('Should notify successful in status bar based on user configuration', async () => {
// Set user configuration to show success messages in status bar.
settings.restore();
settings = stub(SfdxCoreSettings.prototype, 'getShowCLISuccessMsg').returns(
false
);
const observable = new ReplaySubject<number | undefined>();
observable.next(0);
const notificationService = NotificationService.getInstance();
await notificationService.reportExecutionStatus('mock command', observable);
assert.notCalled(mShow);
assert.notCalled(mShowInformation);
assert.notCalled(mShowWarningMessage);
assert.notCalled(mShowErrorMessage);
assert.calledOnce(mStatusBar);
});
it('Should update setting to hide future information messages', async () => {
// For this particular test, we need it to return a different value
mShowInformation.restore();
mShowInformation = stub(window, 'showInformationMessage').returns(
Promise.resolve(SHOW_ONLY_STATUS_BAR_BUTTON_TEXT)
);
const updateSetting = stub(
SfdxCoreSettings.prototype,
'updateShowCLISuccessMsg'
);
const observable = new ReplaySubject<number | undefined>();
observable.next(0);
const notificationService = NotificationService.getInstance();
await notificationService.reportExecutionStatus('mock command', observable);
assert.calledWith(
mShowInformation,
'mock command successfully ran',
SHOW_BUTTON_TEXT,
SHOW_ONLY_STATUS_BAR_BUTTON_TEXT
);
assert.notCalled(mShow);
assert.notCalled(mShowWarningMessage);
assert.notCalled(mShowErrorMessage);
assert.notCalled(mStatusBar);
assert.calledOnce(updateSetting);
}); });
it('Should notify cancellation', async () => { it('Should notify cancellation', async () => {