Add "preview features" config switch (#2334)

* Initial working commit for preview features config

* Clean up code

* Update tests

* Remove unused imports

* Update message and options

* Update don't show again message
This commit is contained in:
Matt Irvine
2018-09-06 14:16:47 -07:00
committed by GitHub
parent 21989aa88e
commit be2f9a6099
13 changed files with 190 additions and 26 deletions

View File

@@ -31,7 +31,7 @@ import * as nls from 'vs/nls';
import * as objects from 'vs/base/common/objects'; import * as objects from 'vs/base/common/objects';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import Severity from 'vs/base/common/severity'; import Severity from 'vs/base/common/severity';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -96,7 +96,8 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef,
@Inject(IInstantiationService) private instantiationService: IInstantiationService, @Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService, @Inject(INotificationService) private notificationService: INotificationService,
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService @Inject(IAngularEventingService) private angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) private configurationService: IConfigurationService
) { ) {
super(); super();
} }
@@ -138,6 +139,12 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
// Before separating tabs into pinned / shown, ensure that the home tab is always set up as expected // Before separating tabs into pinned / shown, ensure that the home tab is always set up as expected
allTabs = this.setAndRemoveHomeTab(allTabs, homeWidgets); allTabs = this.setAndRemoveHomeTab(allTabs, homeWidgets);
// If preview features are disabled only show the home tab
let extensionTabsEnabled = this.configurationService.getValue('workbench')['enablePreviewFeatures'];
if (!extensionTabsEnabled) {
allTabs = [];
}
// Load tab setting configs // Load tab setting configs
this._tabSettingConfigs = this.dashboardService.getSettings<Array<TabSettingConfig>>([this.context, 'tabs'].join('.')); this._tabSettingConfigs = this.dashboardService.getSettings<Array<TabSettingConfig>>([this.context, 'tabs'].join('.'));
@@ -164,9 +171,13 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
// Set panel actions // Set panel actions
let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs]; let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs];
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri()); if (extensionTabsEnabled) {
this._tabsDispose.push(addNewTabAction); let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
this.panelActions = [addNewTabAction]; this._tabsDispose.push(addNewTabAction);
this.panelActions = [addNewTabAction];
} else {
this.panelActions = [];
}
this._cd.detectChanges(); this._cd.detectChanges();
this._tabsDispose.push(this.dashboardService.onPinUnpinTab(e => { this._tabsDispose.push(this.dashboardService.onPinUnpinTab(e => {

View File

@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class DatabaseDashboardPage extends DashboardPage implements OnInit { export class DatabaseDashboardPage extends DashboardPage implements OnInit {
protected propertiesWidget: WidgetConfig = { protected propertiesWidget: WidgetConfig = {
@@ -43,9 +44,10 @@ export class DatabaseDashboardPage extends DashboardPage implements OnInit {
@Inject(forwardRef(() => ElementRef)) el: ElementRef, @Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IInstantiationService) instantiationService: IInstantiationService, @Inject(IInstantiationService) instantiationService: IInstantiationService,
@Inject(INotificationService) notificationService: INotificationService, @Inject(INotificationService) notificationService: INotificationService,
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService @Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) configurationService: IConfigurationService
) { ) {
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService); super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
this._register(dashboardService.onUpdatePage(() => { this._register(dashboardService.onUpdatePage(() => {
this.refresh(true); this.refresh(true);
this._cd.detectChanges(); this._cd.detectChanges();

View File

@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class ServerDashboardPage extends DashboardPage implements OnInit { export class ServerDashboardPage extends DashboardPage implements OnInit {
protected propertiesWidget: WidgetConfig = { protected propertiesWidget: WidgetConfig = {
@@ -44,9 +45,10 @@ export class ServerDashboardPage extends DashboardPage implements OnInit {
@Inject(forwardRef(() => ElementRef)) el: ElementRef, @Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IInstantiationService) instantiationService: IInstantiationService, @Inject(IInstantiationService) instantiationService: IInstantiationService,
@Inject(INotificationService) notificationService: INotificationService, @Inject(INotificationService) notificationService: INotificationService,
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService @Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) configurationService: IConfigurationService
) { ) {
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService); super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
// revert back to default database // revert back to default database
this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master'); this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master');
} }

View File

@@ -88,7 +88,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
@Inject(IBootstrapParams) params: IEditDataComponentParams, @Inject(IBootstrapParams) params: IEditDataComponentParams,
@Inject(IInstantiationService) private instantiationService: IInstantiationService, @Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService, @Inject(INotificationService) notificationService: INotificationService,
@Inject(IContextMenuService) contextMenuService: IContextMenuService, @Inject(IContextMenuService) contextMenuService: IContextMenuService,
@Inject(IKeybindingService) keybindingService: IKeybindingService, @Inject(IKeybindingService) keybindingService: IKeybindingService,
@Inject(IContextKeyService) contextKeyService: IContextKeyService, @Inject(IContextKeyService) contextKeyService: IContextKeyService,
@@ -96,7 +96,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
@Inject(IClipboardService) clipboardService: IClipboardService, @Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService @Inject(IQueryEditorService) queryEditorService: IQueryEditorService
) { ) {
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService); super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
this._el.nativeElement.className = 'slickgridContainer'; this._el.nativeElement.className = 'slickgridContainer';
this.dataService = params.dataService; this.dataService = params.dataService;
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow()); this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());

View File

@@ -37,6 +37,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { INotificationService } from 'vs/platform/notification/common/notification';
export abstract class GridParentComponent { export abstract class GridParentComponent {
// CONSTANTS // CONSTANTS
@@ -100,7 +101,8 @@ export abstract class GridParentComponent {
protected contextKeyService: IContextKeyService, protected contextKeyService: IContextKeyService,
protected configurationService: IConfigurationService, protected configurationService: IConfigurationService,
protected clipboardService: IClipboardService, protected clipboardService: IClipboardService,
protected queryEditorService: IQueryEditorService protected queryEditorService: IQueryEditorService,
protected notificationService: INotificationService
) { ) {
this.toDispose = []; this.toDispose = [];
} }

View File

@@ -42,6 +42,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { localize } from 'vs/nls';
export const QUERY_SELECTOR: string = 'query-component'; export const QUERY_SELECTOR: string = 'query-component';
@@ -126,7 +128,9 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
} }
}, },
{ {
showCondition: () => { return true; }, showCondition: () => {
return this.configurationService.getValue('workbench')['enablePreviewFeatures'];
},
icon: () => { return 'viewChart'; }, icon: () => { return 'viewChart'; },
hoverText: () => { return LocalizedConstants.viewChartLabel; }, hoverText: () => { return LocalizedConstants.viewChartLabel; },
functionality: (batchId, resultId, index) => { functionality: (batchId, resultId, index) => {
@@ -187,9 +191,10 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
@Inject(IContextKeyService) contextKeyService: IContextKeyService, @Inject(IContextKeyService) contextKeyService: IContextKeyService,
@Inject(IConfigurationService) configurationService: IConfigurationService, @Inject(IConfigurationService) configurationService: IConfigurationService,
@Inject(IClipboardService) clipboardService: IClipboardService, @Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService @Inject(IQueryEditorService) queryEditorService: IQueryEditorService,
@Inject(INotificationService) notificationService: INotificationService,
) { ) {
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService); super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
this._el.nativeElement.className = 'slickgridContainer'; this._el.nativeElement.className = 'slickgridContainer';
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight; this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
configurationService.onDidChangeConfiguration(e => { configurationService.onDidChangeConfiguration(e => {

View File

@@ -44,6 +44,7 @@ import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
import { IEditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService'; import { IEditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement'; import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { attachEditableDropdownStyler } from 'sql/common/theme/styler'; import { attachEditableDropdownStyler } from 'sql/common/theme/styler';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -96,7 +97,8 @@ export class QueryEditor extends BaseEditor {
@IQueryModelService private _queryModelService: IQueryModelService, @IQueryModelService private _queryModelService: IQueryModelService,
@IEditorDescriptorService private _editorDescriptorService: IEditorDescriptorService, @IEditorDescriptorService private _editorDescriptorService: IEditorDescriptorService,
@IContextKeyService contextKeyService: IContextKeyService, @IContextKeyService contextKeyService: IContextKeyService,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService @IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@IConfigurationService private _configurationService: IConfigurationService
) { ) {
super(QueryEditor.ID, _telemetryService, themeService); super(QueryEditor.ID, _telemetryService, themeService);
@@ -446,6 +448,16 @@ export class QueryEditor extends BaseEditor {
this._estimatedQueryPlanAction = this._instantiationService.createInstance(EstimatedQueryPlanAction, this); this._estimatedQueryPlanAction = this._instantiationService.createInstance(EstimatedQueryPlanAction, this);
this._actualQueryPlanAction = this._instantiationService.createInstance(ActualQueryPlanAction, this); this._actualQueryPlanAction = this._instantiationService.createInstance(ActualQueryPlanAction, this);
this.setTaskbarContent();
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes('workbench.enablePreviewFeatures')) {
this.setTaskbarContent();
}
});
}
private setTaskbarContent(): void {
// Create HTML Elements for the taskbar // Create HTML Elements for the taskbar
let separator = Taskbar.createTaskbarSeparator(); let separator = Taskbar.createTaskbarSeparator();
@@ -460,6 +472,13 @@ export class QueryEditor extends BaseEditor {
{ element: separator }, { element: separator },
{ action: this._estimatedQueryPlanAction } { action: this._estimatedQueryPlanAction }
]; ];
// Remove the estimated query plan action if preview features are not enabled
let previewFeaturesEnabled = this._configurationService.getValue('workbench')['enablePreviewFeatures'];
if (!previewFeaturesEnabled) {
content = content.slice(0, -2);
}
this._taskbar.setContent(content); this._taskbar.setContent(content);
} }

View File

@@ -22,6 +22,7 @@ import { PanelComponent, IPanelOptions } from 'sql/base/browser/ui/panel/panel.c
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export const QUERY_OUTPUT_SELECTOR: string = 'query-output-component'; export const QUERY_OUTPUT_SELECTOR: string = 'query-output-component';
@@ -66,7 +67,8 @@ export class QueryOutputComponent implements OnDestroy {
constructor( constructor(
@Inject(forwardRef(() => ElementRef)) el: ElementRef, @Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
@Inject(IBootstrapParams) public queryParameters: IQueryComponentParams @Inject(IBootstrapParams) public queryParameters: IQueryComponentParams,
@Inject(IConfigurationService) private _configurationService: IConfigurationService
) { ) {
} }
@@ -75,12 +77,14 @@ export class QueryOutputComponent implements OnDestroy {
*/ */
public ngAfterViewInit(): void { public ngAfterViewInit(): void {
this._disposables.push(toDisposableSubscription(this.queryComponent.queryPlanAvailable.subscribe((xml) => { this._disposables.push(toDisposableSubscription(this.queryComponent.queryPlanAvailable.subscribe((xml) => {
this.hasQueryPlan = true; if (this._configurationService.getValue('workbench')['enablePreviewFeatures']) {
this._cd.detectChanges(); this.hasQueryPlan = true;
this._panel.selectTab(this.topOperationsTabIdentifier); this._cd.detectChanges();
this.topOperationsComponent.planXml = xml; this._panel.selectTab(this.topOperationsTabIdentifier);
this._panel.selectTab(this.queryPlanTabIdentifier); this.topOperationsComponent.planXml = xml;
this.queryPlanComponent.planXml = xml; this._panel.selectTab(this.queryPlanTabIdentifier);
this.queryPlanComponent.planXml = xml;
}
}))); })));
this._disposables.push(toDisposableSubscription(this.queryComponent.showChartRequested.subscribe((dataSet) => { this._disposables.push(toDisposableSubscription(this.queryComponent.showChartRequested.subscribe((dataSet) => {

View File

@@ -14,6 +14,7 @@ import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/wor
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ShowCurrentReleaseNotesAction } from 'sql/workbench/update/releaseNotes'; import { ShowCurrentReleaseNotesAction } from 'sql/workbench/update/releaseNotes';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
new Actions.BackupAction().registerTask(false); new Actions.BackupAction().registerTask(false);
new Actions.RestoreAction().registerTask(false); new Actions.RestoreAction().registerTask(false);
@@ -23,3 +24,16 @@ new Actions.ConfigureDashboardAction().registerTask();
// add product update and release notes contributions // add product update and release notes contributions
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions) Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Show Getting Started'); .registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Show Getting Started');
Registry.as<IConfigurationRegistry>(ConfigExtensions.Configuration).registerConfiguration({
'id': 'previewFeatures',
'title': nls.localize('previewFeatures.configTitle', 'Preview Features'),
'type': 'object',
'properties': {
'workbench.enablePreviewFeatures': {
'type': 'boolean',
'default': undefined,
'description': nls.localize('previewFeatures.configEnable', 'Enable unreleased preview features')
}
}
});

View File

@@ -27,6 +27,8 @@ import { IWindowsService } from 'vs/platform/windows/common/windows';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
export interface BaseActionContext { export interface BaseActionContext {
object?: ObjectMetadata; object?: ObjectMetadata;
@@ -300,6 +302,14 @@ export class BackupAction extends Task {
} }
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> { runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
let configurationService = accessor.get<IWorkspaceConfigurationService>(IWorkspaceConfigurationService);
let previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures'];
if (!previewFeaturesEnabled) {
return new TPromise<void>((resolve, reject) => {
accessor.get<INotificationService>(INotificationService).info(nls.localize('backup.isPreviewFeature', 'You must enable preview features in order to use backup'));
});
}
return new TPromise<void>((resolve, reject) => { return new TPromise<void>((resolve, reject) => {
TaskUtilities.showBackup( TaskUtilities.showBackup(
profile, profile,
@@ -331,6 +341,14 @@ export class RestoreAction extends Task {
} }
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> { runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
let configurationService = accessor.get<IWorkspaceConfigurationService>(IWorkspaceConfigurationService);
let previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures'];
if (!previewFeaturesEnabled) {
return new TPromise<void>((resolve, reject) => {
accessor.get<INotificationService>(INotificationService).info(nls.localize('restore.isPreviewFeature', 'You must enable preview features in order to use restore'));
});
}
return new TPromise<void>((resolve, reject) => { return new TPromise<void>((resolve, reject) => {
TaskUtilities.showRestore( TaskUtilities.showRestore(
profile, profile,

View File

@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { localize } from 'vs/nls';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class EnablePreviewFeatures implements IWorkbenchContribution {
private static ENABLE_PREVIEW_FEATURES_SHOWN = 'workbench.enablePreviewFeaturesShown';
constructor(
@IStorageService storageService: IStorageService,
@IOpenerService openerService: IOpenerService,
@INotificationService notificationService: INotificationService,
@IWindowService windowService: IWindowService,
@IWindowsService windowsService: IWindowsService,
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService
) {
let previewFeaturesEnabled = configurationService.getValue('workbench')['enablePreviewFeatures'];
if (previewFeaturesEnabled || storageService.get(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN)) {
return;
}
Promise.all([
windowService.isFocused(),
windowsService.getWindowCount()
]).then(([focused, count]) => {
if (!focused && count > 1) {
return null;
}
configurationService.updateValue('workbench.enablePreviewFeatures', false);
const enablePreviewFeaturesNotice = localize('enablePreviewFeatures.notice', "Would you like to enable preview features?");
notificationService.prompt(
Severity.Info,
enablePreviewFeaturesNotice,
[{
label: localize('enablePreviewFeatures.yes', "Yes"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', true);
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
}
}, {
label: localize('enablePreviewFeatures.no', "No"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', false);
}
}, {
label: localize('enablePreviewFeatures.never', "No, don't show again"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', false);
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
},
isSecondary: true
}]
);
})
.then(null, onUnexpectedError);
}
}

View File

@@ -6,7 +6,6 @@
'use strict'; 'use strict';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { EditorInput } from 'vs/workbench/common/editor';
import { IEditorDescriptor } from 'vs/workbench/browser/editor'; import { IEditorDescriptor } from 'vs/workbench/browser/editor';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
@@ -30,8 +29,9 @@ import * as TypeMoq from 'typemoq';
import * as assert from 'assert'; import * as assert from 'assert';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { INotification, INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
suite('SQL QueryEditor Tests', () => { suite('SQL QueryEditor Tests', () => {
let queryModelService: QueryModelService; let queryModelService: QueryModelService;
@@ -40,6 +40,7 @@ suite('SQL QueryEditor Tests', () => {
let notificationService: TypeMoq.Mock<INotificationService>; let notificationService: TypeMoq.Mock<INotificationService>;
let editorDescriptorService: TypeMoq.Mock<EditorDescriptorService>; let editorDescriptorService: TypeMoq.Mock<EditorDescriptorService>;
let connectionManagementService: TypeMoq.Mock<ConnectionManagementService>; let connectionManagementService: TypeMoq.Mock<ConnectionManagementService>;
let configurationService: TypeMoq.Mock<ConfigurationService>;
let memento: TypeMoq.Mock<Memento>; let memento: TypeMoq.Mock<Memento>;
let queryInput: QueryInput; let queryInput: QueryInput;
@@ -57,7 +58,8 @@ suite('SQL QueryEditor Tests', () => {
undefined, undefined,
editorDescriptorService.object, editorDescriptorService.object,
undefined, undefined,
undefined); undefined,
configurationService.object);
}; };
setup(() => { setup(() => {
@@ -134,6 +136,14 @@ suite('SQL QueryEditor Tests', () => {
// Create a QueryModelService // Create a QueryModelService
queryModelService = new QueryModelService(instantiationService.object, notificationService.object); queryModelService = new QueryModelService(instantiationService.object, notificationService.object);
configurationService = TypeMoq.Mock.ofInstance({
getValue: () => undefined,
onDidChangeConfiguration: () => undefined
} as any);
configurationService.setup(x => x.getValue(TypeMoq.It.isAny())).returns(() => {
return { enablePreviewFeatures: true };
});
}); });
test('createEditor creates only the taskbar', (done) => { test('createEditor creates only the taskbar', (done) => {

View File

@@ -9,6 +9,8 @@ import { GettingStarted } from './gettingStarted';
import { TelemetryOptOut } from './telemetryOptOut'; import { TelemetryOptOut } from './telemetryOptOut';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
// {{SQL CARBON EDIT}} - Add preview feature switch
import { EnablePreviewFeatures } from 'sql/workbench/electron-browser/enablePreviewFeatures';
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
// Registry // Registry
@@ -22,3 +24,8 @@ Registry
Registry Registry
.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench) .as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(TelemetryOptOut, LifecyclePhase.Eventually); .registerWorkbenchContribution(TelemetryOptOut, LifecyclePhase.Eventually);
// {{SQL CARBON EDIT}} - Add preview feature switch
Registry
.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(EnablePreviewFeatures, LifecyclePhase.Eventually);