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:
Родитель
758b60e9f7
Коммит
f5c0ff099b
|
@ -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 () => {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче