move code from parts to contrib (#8319)
@@ -0,0 +1,134 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/connectionViewletPanel';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView';
|
||||
import {
|
||||
ActiveConnectionsFilterAction,
|
||||
AddServerAction, AddServerGroupAction
|
||||
} from 'sql/workbench/contrib/objectExplorer/browser/connectionTreeAction';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
|
||||
export class ConnectionViewletPanel extends ViewletPanel {
|
||||
|
||||
public static readonly ID = 'dataExplorer.servers';
|
||||
|
||||
private _root: HTMLElement;
|
||||
private _serverTreeView: ServerTreeView;
|
||||
private _addServerAction: IAction;
|
||||
private _addServerGroupAction: IAction;
|
||||
private _activeConnectionsFilterAction: ActiveConnectionsFilterAction;
|
||||
|
||||
constructor(
|
||||
private options: IViewletViewOptions,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IObjectExplorerService private readonly objectExplorerService: IObjectExplorerService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService
|
||||
) {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
|
||||
this._addServerAction = this.instantiationService.createInstance(AddServerAction,
|
||||
AddServerAction.ID,
|
||||
AddServerAction.LABEL);
|
||||
this._addServerGroupAction = this.instantiationService.createInstance(AddServerGroupAction,
|
||||
AddServerGroupAction.ID,
|
||||
AddServerGroupAction.LABEL);
|
||||
this._serverTreeView = this.objectExplorerService.getServerTreeView();
|
||||
if (!this._serverTreeView) {
|
||||
this._serverTreeView = this.instantiationService.createInstance(ServerTreeView);
|
||||
this.objectExplorerService.registerServerTreeView(this._serverTreeView);
|
||||
}
|
||||
this._activeConnectionsFilterAction = this._serverTreeView.activeConnectionsFilterAction;
|
||||
}
|
||||
|
||||
protected renderHeader(container: HTMLElement): void {
|
||||
super.renderHeader(container);
|
||||
}
|
||||
|
||||
renderHeaderTitle(container: HTMLElement): void {
|
||||
super.renderHeaderTitle(container, this.options.title);
|
||||
}
|
||||
|
||||
renderBody(container: HTMLElement): void {
|
||||
const viewletContainer = DOM.append(container, DOM.$('div.server-explorer-viewlet'));
|
||||
const viewContainer = DOM.append(viewletContainer, DOM.$('div.object-explorer-view'));
|
||||
this._serverTreeView.renderBody(viewContainer).then(undefined, error => {
|
||||
console.warn('render registered servers: ' + error);
|
||||
});
|
||||
this._root = container;
|
||||
}
|
||||
|
||||
get serversTree(): ITree {
|
||||
return this._serverTreeView.tree;
|
||||
}
|
||||
|
||||
layoutBody(size: number): void {
|
||||
this._serverTreeView.layout(size);
|
||||
DOM.toggleClass(this._root, 'narrow', this._root.clientWidth < 300);
|
||||
}
|
||||
|
||||
show(): void {
|
||||
}
|
||||
|
||||
select(): void {
|
||||
}
|
||||
|
||||
showPrevious(): void {
|
||||
}
|
||||
|
||||
showPreviousPage(): void {
|
||||
}
|
||||
|
||||
showNext(): void {
|
||||
}
|
||||
|
||||
showNextPage(): void {
|
||||
}
|
||||
|
||||
count(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public getActions(): IAction[] {
|
||||
return [
|
||||
this._addServerAction,
|
||||
this._addServerGroupAction,
|
||||
this._activeConnectionsFilterAction
|
||||
];
|
||||
}
|
||||
|
||||
public clearSearch() {
|
||||
this._serverTreeView.refreshTree();
|
||||
}
|
||||
|
||||
public search(value: string): void {
|
||||
if (value) {
|
||||
this._serverTreeView.searchTree(value);
|
||||
} else {
|
||||
this.clearSearch();
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
super.focus();
|
||||
this._serverTreeView.tree.domFocus();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!sql/media/actionBarLabel';
|
||||
import 'vs/css!./media/dataExplorer.contribution';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { DataExplorerViewlet, DataExplorerViewletViewsContribution, OpenDataExplorerViewletAction, VIEWLET_ID } from 'sql/workbench/contrib/dataExplorer/browser/dataExplorerViewlet';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { DataExplorerContainerExtensionHandler } from 'sql/workbench/contrib/dataExplorer/browser/dataExplorerExtensionPoint';
|
||||
|
||||
// Data Explorer Viewlet
|
||||
const viewletDescriptor = new ViewletDescriptor(
|
||||
DataExplorerViewlet,
|
||||
VIEWLET_ID,
|
||||
localize('workbench.dataExplorer', "Connections"),
|
||||
'dataExplorer',
|
||||
0
|
||||
);
|
||||
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).setDefaultViewletId(VIEWLET_ID);
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(DataExplorerViewletViewsContribution, LifecyclePhase.Starting);
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(
|
||||
new SyncActionDescriptor(
|
||||
OpenDataExplorerViewletAction,
|
||||
OpenDataExplorerViewletAction.ID,
|
||||
OpenDataExplorerViewletAction.LABEL,
|
||||
{ primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_D }),
|
||||
'View: Show Data Explorer',
|
||||
localize('dataExplorer.view', "View")
|
||||
);
|
||||
|
||||
let configurationRegistry = <IConfigurationRegistry>Registry.as(Extensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
'id': 'databaseConnections',
|
||||
'order': 0,
|
||||
'title': localize('databaseConnections', "Database Connections"),
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'datasource.connections': {
|
||||
'description': localize('datasource.connections', "data source connections"),
|
||||
'type': 'array'
|
||||
},
|
||||
'datasource.connectionGroups': {
|
||||
'description': localize('datasource.connectionGroups', "data source groups"),
|
||||
'type': 'array'
|
||||
}
|
||||
}
|
||||
});
|
||||
configurationRegistry.registerConfiguration({
|
||||
'id': 'startupConfig',
|
||||
'title': localize('startupConfig', "Startup Configuration"),
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'startup.alwaysShowServersView': {
|
||||
'type': 'boolean',
|
||||
'description': localize('startup.alwaysShowServersView', "True for the Servers view to be shown on launch of Azure Data Studio default; false if the last opened view should be shown"),
|
||||
'default': true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
workbenchRegistry.registerWorkbenchContribution(DataExplorerContainerExtensionHandler, LifecyclePhase.Starting);
|
||||
@@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions, ITreeViewDescriptor, IViewsRegistry } from 'vs/workbench/common/views';
|
||||
import { IExtensionPoint, ExtensionsRegistry, ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
import { CustomTreeViewPanel, CustomTreeView } from 'sql/workbench/browser/parts/views/customView';
|
||||
import { VIEWLET_ID } from 'sql/workbench/contrib/dataExplorer/browser/dataExplorerViewlet';
|
||||
|
||||
interface IUserFriendlyViewDescriptor {
|
||||
id: string;
|
||||
name: string;
|
||||
when?: string;
|
||||
}
|
||||
|
||||
const viewDescriptor: IJSONSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
description: localize('vscode.extension.contributes.view.id', "Identifier of the view. Use this to register a data provider through `vscode.window.registerTreeDataProviderForView` API. Also to trigger activating your extension by registering `onView:${id}` event to `activationEvents`."),
|
||||
type: 'string'
|
||||
},
|
||||
name: {
|
||||
description: localize('vscode.extension.contributes.view.name', "The human-readable name of the view. Will be shown"),
|
||||
type: 'string'
|
||||
},
|
||||
when: {
|
||||
description: localize('vscode.extension.contributes.view.when', "Condition which must be true to show this view"),
|
||||
type: 'string'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const dataExplorerContribution: IJSONSchema = {
|
||||
description: localize('extension.contributes.dataExplorer', "Contributes views to the editor"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'dataExplorer': {
|
||||
description: localize('extension.dataExplorer', "Contributes views to Data Explorer container in the Activity bar"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
additionalProperties: {
|
||||
description: localize('dataExplorer.contributed', "Contributes views to contributed views container"),
|
||||
type: 'array',
|
||||
items: viewDescriptor,
|
||||
default: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const dataExplorerExtensionPoint: IExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }> = ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }>({ extensionPoint: 'dataExplorer', jsonSchema: dataExplorerContribution });
|
||||
|
||||
export class DataExplorerContainerExtensionHandler implements IWorkbenchContribution {
|
||||
|
||||
private viewContainersRegistry: IViewContainersRegistry;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
this.handleAndRegisterCustomViews();
|
||||
}
|
||||
|
||||
private handleAndRegisterCustomViews() {
|
||||
dataExplorerExtensionPoint.setHandler(extensions => {
|
||||
for (let extension of extensions) {
|
||||
const { value, collector } = extension;
|
||||
|
||||
forEach(value, entry => {
|
||||
if (!this.isValidViewDescriptors(entry.value, collector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let container = this.viewContainersRegistry.get(VIEWLET_ID);
|
||||
if (!container) {
|
||||
collector.warn(localize('ViewsContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Data Explorer'.", entry.key));
|
||||
container = this.viewContainersRegistry.get(VIEWLET_ID);
|
||||
}
|
||||
const registeredViews = Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry).getViews(container);
|
||||
const viewIds = [];
|
||||
const viewDescriptors = coalesce(entry.value.map(item => {
|
||||
// validate
|
||||
if (viewIds.indexOf(item.id) !== -1) {
|
||||
collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the view container `{1}`", item.id, container.id));
|
||||
return null;
|
||||
}
|
||||
if (registeredViews.some(v => v.id === item.id)) {
|
||||
collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the view container `{1}`", item.id, container.id));
|
||||
return null;
|
||||
}
|
||||
|
||||
const viewDescriptor = <ITreeViewDescriptor>{
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
ctorDescriptor: { ctor: CustomTreeViewPanel },
|
||||
when: ContextKeyExpr.deserialize(item.when),
|
||||
canToggleVisibility: true,
|
||||
collapsed: this.showCollapsed(container),
|
||||
treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name, container)
|
||||
};
|
||||
|
||||
viewIds.push(viewDescriptor.id);
|
||||
return viewDescriptor;
|
||||
}));
|
||||
Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry).registerViews(viewDescriptors, container);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private isValidViewDescriptors(viewDescriptors: IUserFriendlyViewDescriptor[], collector: ExtensionMessageCollector): boolean {
|
||||
if (!Array.isArray(viewDescriptors)) {
|
||||
collector.error(localize('requirearray', "views must be an array"));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let descriptor of viewDescriptors) {
|
||||
if (typeof descriptor.id !== 'string') {
|
||||
collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", "id"));
|
||||
return false;
|
||||
}
|
||||
if (typeof descriptor.name !== 'string') {
|
||||
collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", "name"));
|
||||
return false;
|
||||
}
|
||||
if (descriptor.when && typeof descriptor.when !== 'string') {
|
||||
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", "when"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private showCollapsed(container: ViewContainer): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { append, $, addClass, toggleClass, Dimension } from 'vs/base/browser/dom';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ViewContainerViewlet, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
|
||||
import { ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||
import { ConnectionViewletPanel } from 'sql/workbench/contrib/dataExplorer/browser/connectionViewletPanel';
|
||||
import { Extensions as ViewContainerExtensions, IViewDescriptor, IViewsRegistry, IViewContainersRegistry } from 'vs/workbench/common/views';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ShowViewletAction } from 'vs/workbench/browser/viewlet';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
|
||||
export const VIEWLET_ID = 'workbench.view.connections';
|
||||
|
||||
// Viewlet Action
|
||||
export class OpenDataExplorerViewletAction extends ShowViewletAction {
|
||||
public static ID = VIEWLET_ID;
|
||||
public static LABEL = localize('showDataExplorer', "Show Connections");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService
|
||||
) {
|
||||
super(id, label, VIEWLET_ID, viewletService, editorGroupService, layoutService);
|
||||
}
|
||||
}
|
||||
|
||||
export const VIEW_CONTAINER = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID);
|
||||
|
||||
export class DataExplorerViewletViewsContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor() {
|
||||
this.registerViews();
|
||||
}
|
||||
|
||||
private registerViews(): void {
|
||||
let viewDescriptors = [];
|
||||
viewDescriptors.push(this.createObjectExplorerViewDescriptor());
|
||||
Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry).registerViews(viewDescriptors, VIEW_CONTAINER);
|
||||
}
|
||||
|
||||
private createObjectExplorerViewDescriptor(): IViewDescriptor {
|
||||
return {
|
||||
id: ConnectionViewletPanel.ID,
|
||||
name: localize('dataExplorer.servers', "Servers"),
|
||||
ctorDescriptor: { ctor: ConnectionViewletPanel },
|
||||
weight: 100,
|
||||
canToggleVisibility: true,
|
||||
order: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class DataExplorerViewlet extends ViewContainerViewlet {
|
||||
private root: HTMLElement;
|
||||
|
||||
private dataSourcesBox: HTMLElement;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService
|
||||
) {
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
addClass(parent, 'dataExplorer-viewlet');
|
||||
this.root = parent;
|
||||
|
||||
this.dataSourcesBox = append(this.root, $('.dataSources'));
|
||||
|
||||
return super.create(this.dataSourcesBox);
|
||||
}
|
||||
|
||||
public updateStyles(): void {
|
||||
super.updateStyles();
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): void {
|
||||
toggleClass(this.root, 'narrow', dimension.width <= 300);
|
||||
super.layout(new Dimension(dimension.width, dimension.height));
|
||||
}
|
||||
|
||||
getOptimalWidth(): number {
|
||||
return 400;
|
||||
}
|
||||
|
||||
getActions(): IAction[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
getSecondaryActions(): IAction[] {
|
||||
let menu = this.menuService.createMenu(MenuId.DataExplorerAction, this.contextKeyService);
|
||||
let actions = [];
|
||||
menu.getActions({}).forEach(group => {
|
||||
if (group[0] === 'secondary') {
|
||||
actions.push(...group[1]);
|
||||
}
|
||||
});
|
||||
menu.dispose();
|
||||
return actions;
|
||||
}
|
||||
|
||||
protected onDidAddViews(added: IAddedViewDescriptorRef[]): ViewletPanel[] {
|
||||
const addedViews = super.onDidAddViews(added);
|
||||
return addedViews;
|
||||
}
|
||||
|
||||
protected createView(viewDescriptor: IViewDescriptor, options: IViewletViewOptions): ViewletPanel {
|
||||
let viewletPanel = this.instantiationService.createInstance(viewDescriptor.ctorDescriptor.ctor, options) as ViewletPanel;
|
||||
this._register(viewletPanel);
|
||||
return viewletPanel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
||||
import * as azdata from 'azdata';
|
||||
import { IOEShimService } from 'sql/workbench/contrib/objectExplorer/browser/objectExplorerViewTreeShim';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
|
||||
export const DATA_TIER_WIZARD_COMMAND_ID = 'dataExplorer.dataTierWizard';
|
||||
export const PROFILER_COMMAND_ID = 'dataExplorer.profiler';
|
||||
export const IMPORT_COMMAND_ID = 'dataExplorer.flatFileImport';
|
||||
export const SCHEMA_COMPARE_COMMAND_ID = 'dataExplorer.schemaCompare';
|
||||
export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts';
|
||||
export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties';
|
||||
|
||||
|
||||
// Data Tier Wizard
|
||||
CommandsRegistry.registerCommand({
|
||||
id: DATA_TIER_WIZARD_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload };
|
||||
return commandService.executeCommand('dacFx.start', connectedContext);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Flat File Import
|
||||
CommandsRegistry.registerCommand({
|
||||
id: IMPORT_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload };
|
||||
return commandService.executeCommand('flatFileImport.start', connectedContext);
|
||||
}
|
||||
});
|
||||
|
||||
// Schema Compare
|
||||
CommandsRegistry.registerCommand({
|
||||
id: SCHEMA_COMPARE_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload };
|
||||
return commandService.executeCommand('schemaCompare.start', connectedContext);
|
||||
}
|
||||
});
|
||||
|
||||
// Profiler
|
||||
CommandsRegistry.registerCommand({
|
||||
id: PROFILER_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const objectExplorerContext: azdata.ObjectExplorerContext = {
|
||||
connectionProfile: args.$treeItem.payload,
|
||||
isConnectionNode: true,
|
||||
nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem)
|
||||
};
|
||||
return commandService.executeCommand('profiler.newProfiler', objectExplorerContext);
|
||||
}
|
||||
});
|
||||
|
||||
// Generate Scripts
|
||||
CommandsRegistry.registerCommand({
|
||||
id: GENERATE_SCRIPTS_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const objectExplorerContext: azdata.ObjectExplorerContext = {
|
||||
connectionProfile: args.$treeItem.payload,
|
||||
isConnectionNode: true,
|
||||
nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem)
|
||||
};
|
||||
return commandService.executeCommand('adminToolExtWin.launchSsmsMinGswDialog', objectExplorerContext);
|
||||
}
|
||||
});
|
||||
|
||||
// Properties
|
||||
CommandsRegistry.registerCommand({
|
||||
id: PROPERTIES_COMMAND_ID,
|
||||
handler: async (accessor, args: TreeViewItemHandleArg) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const capabilitiesService = accessor.get(ICapabilitiesService);
|
||||
const connectionManagementService = accessor.get(IConnectionManagementService);
|
||||
const oeShimService = accessor.get(IOEShimService);
|
||||
const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload);
|
||||
await connectionManagementService.connectIfNotConnected(profile);
|
||||
const objectExplorerContext: azdata.ObjectExplorerContext = {
|
||||
connectionProfile: args.$treeItem.payload,
|
||||
isConnectionNode: true,
|
||||
nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem)
|
||||
};
|
||||
return commandService.executeCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', objectExplorerContext);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { DATA_TIER_WIZARD_COMMAND_ID, PROFILER_COMMAND_ID, IMPORT_COMMAND_ID, SCHEMA_COMPARE_COMMAND_ID, GENERATE_SCRIPTS_COMMAND_ID, PROPERTIES_COMMAND_ID } from 'sql/workbench/contrib/dataExplorer/browser/extensionActions';
|
||||
import { ContextKeyExpr, ContextKeyRegexExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MssqlNodeContext } from 'sql/workbench/contrib/dataExplorer/browser/mssqlNodeContext';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { NodeType } from 'sql/workbench/contrib/objectExplorer/common/nodeType';
|
||||
import { localize } from 'vs/nls';
|
||||
import { DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
|
||||
// Data-Tier Application Wizard
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'export',
|
||||
order: 7,
|
||||
command: {
|
||||
id: DATA_TIER_WIZARD_COMMAND_ID,
|
||||
title: localize('dacFx', "Data-tier Application Wizard")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.IsDatabaseOrServer, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'export',
|
||||
order: 7,
|
||||
command: {
|
||||
id: DATA_TIER_WIZARD_COMMAND_ID,
|
||||
title: localize('dacFx', "Data-tier Application Wizard")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Folder),
|
||||
MssqlNodeContext.NodeLabel.isEqualTo('Databases'),
|
||||
MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
// Profiler
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'profiler',
|
||||
order: 8,
|
||||
command: {
|
||||
id: PROFILER_COMMAND_ID,
|
||||
title: localize('profiler', "Launch Profiler")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
// Flat File Import
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'import',
|
||||
order: 10,
|
||||
command: {
|
||||
id: IMPORT_COMMAND_ID,
|
||||
title: localize('flatFileImport', "Import Wizard")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Database))
|
||||
});
|
||||
|
||||
// Schema Compare
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'export',
|
||||
order: 9,
|
||||
command: {
|
||||
id: SCHEMA_COMPARE_COMMAND_ID,
|
||||
title: localize('schemaCompare', "Schema Compare")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
// Generate Scripts Action
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'z-AdminToolExt@1',
|
||||
order: 11,
|
||||
command: {
|
||||
id: GENERATE_SCRIPTS_COMMAND_ID,
|
||||
title: localize('generateScripts', "Generate Scripts...")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Database),
|
||||
MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
// Properties Action
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'z-AdminToolExt@2',
|
||||
order: 12,
|
||||
command: {
|
||||
id: PROPERTIES_COMMAND_ID,
|
||||
title: localize('properties', "Properties")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), ContextKeyExpr.not('isCloud'),
|
||||
MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()))
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'z-AdminToolExt@2',
|
||||
order: 12,
|
||||
command: {
|
||||
id: PROPERTIES_COMMAND_ID,
|
||||
title: localize('properties', "Properties")
|
||||
},
|
||||
when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()),
|
||||
ContextKeyRegexExpr.create('nodeType', /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/))
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z"/></svg>
|
||||
|
After Width: | Height: | Size: 139 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}.cls-2{fill:#3bb44a;}</style></defs><title>connected_active_server_16x16</title><path class="cls-1" d="M1.29.07V16h9.59a3.31,3.31,0,0,1-1.94-1H2.29V11h6a3.31,3.31,0,0,1,.54-.8A1.81,1.81,0,0,1,9,10H2.29v-9h8.53v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.3,1.8V4.25H5.75V1.8Zm2,2H3.8V2.3H5.25Z"/><circle class="cls-2" cx="11.24" cy="12.52" r="3.47"/></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3bb44a;}</style></defs><title>connected_active_server_inverse_16x16</title><path class="cls-1" d="M1.29.07V16h9.59a3.31,3.31,0,0,1-1.94-1H2.29V11h6a3.31,3.31,0,0,1,.54-.8A1.81,1.81,0,0,1,9,10H2.29v-9h8.53v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.3,1.8V4.25H5.75V1.8Zm2,2H3.8V2.3H5.25Z"/><circle class="cls-2" cx="11.24" cy="12.52" r="3.47"/></svg>
|
||||
|
After Width: | Height: | Size: 507 B |
@@ -0,0 +1,132 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* --- Registered servers tree viewlet --- */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-row .content .server-group {
|
||||
cursor: default;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Bold font style does not go well with CJK fonts */
|
||||
.server-explorer-viewlet:lang(zh-Hans) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(zh-Hant) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(ja) .monaco-tree .monaco-tree-row .server-group,
|
||||
.server-explorer-viewlet:lang(ko) .monaco-tree .monaco-tree-row .server-group { font-weight: normal; }
|
||||
|
||||
/* High Contrast Theming */
|
||||
.hc-black .monaco-workbench .server-explorer-viewlet .server-group {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar .monaco-action-bar .action-label.serverTree {
|
||||
background-size: 22px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% !important;
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .object-explorer-view {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .server-group {
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.server-explorer-viewlet .monaco-action-bar .action-label {
|
||||
margin-right: 0.3em;
|
||||
margin-left: 0.3em;
|
||||
line-height: 15px;
|
||||
width: 10px !important;
|
||||
height: 10px !important;
|
||||
}
|
||||
|
||||
/* Add space beneath the button */
|
||||
.new-connection .monaco-text-button {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* display action buttons on hover */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-row > .content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Added to display the tree in connection dialog */
|
||||
.server-explorer-viewlet {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.explorer-servers {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* search box */
|
||||
.server-explorer-viewlet .search-box {
|
||||
padding-bottom: 4px;
|
||||
margin: auto;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* OE and connection element group */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* OE and connection label */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .label,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group > .label {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* OE and connection icon */
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon,
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .object-element-group > .icon {
|
||||
float: left;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page {
|
||||
background: url('default_server.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page,
|
||||
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .connection-tile > .icon.server-page{
|
||||
background: url('default_server_inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
/* loading for OE node */
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row > .codicon.in-progress .connection-tile:before,
|
||||
.server-explorer-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row > .codicon.in-progress .object-element-group:before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: -35px;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded.has-children > .content.server-group:before {
|
||||
background: url('expanded-dark.svg') 50% 50% no-repeat;
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content.server-group:before {
|
||||
background: url('collapsed-dark.svg') 50% 50% no-repeat;
|
||||
}
|
||||
|
||||
/* Add connection button */
|
||||
.server-explorer-viewlet .button-section {
|
||||
padding: 20px;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Activity Bar */
|
||||
.monaco-workbench .activitybar .monaco-action-bar .action-label.dataExplorer {
|
||||
-webkit-mask: url('server_page_inverse.svg') no-repeat 50% 50%;
|
||||
-webkit-mask-size: 25px 25px;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
viewBox="0 0 16 16"
|
||||
data-name="Layer 1"
|
||||
id="Layer_1">
|
||||
<metadata
|
||||
id="metadata15">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>server_16x16</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">.cls-1{fill:#212121;}.cls-2{fill:#231f20;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title6">server_16x16</title>
|
||||
<path
|
||||
style="fill:#212121"
|
||||
id="path8"
|
||||
d="m 2.735,0 v 16 h 10.53 V 0 Z m 1,1 h 8.53 v 9 h -8.53 z m 8.53,14 h -8.53 v -4 h 8.53 z"
|
||||
class="cls-1" />
|
||||
<path
|
||||
style="fill:#231f20"
|
||||
id="path10"
|
||||
d="M 7.125,4.23 H 4.675 V 1.77 h 2.45 z m -2,-0.5 h 1.5 V 2.27 h -1.45 z"
|
||||
class="cls-2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
viewBox="0 0 16 16"
|
||||
data-name="Layer 1"
|
||||
id="Layer_1">
|
||||
<metadata
|
||||
id="metadata15">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>server_16x16</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">.cls-1{fill:#212121;}.cls-2{fill:#231f20;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title6">server_16x16</title>
|
||||
<path
|
||||
style="fill:#ffffff"
|
||||
id="path8"
|
||||
d="m 2.735,0 v 16 h 10.53 V 0 Z m 1,1 h 8.53 v 9 h -8.53 z m 8.53,14 h -8.53 v -4 h 8.53 z"
|
||||
class="cls-1" />
|
||||
<path
|
||||
style="fill:#ffffff"
|
||||
id="path10"
|
||||
d="M 7.125,4.23 H 4.675 V 1.77 h 2.45 z m -2,-0.5 h 1.5 V 2.27 h -1.45 z"
|
||||
class="cls-2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}.cls-2{fill:#d02e00;}</style></defs><title>disconnected_server_16x16</title><path class="cls-1" d="M1.42.06V16H11a3.31,3.31,0,0,1-1.94-1H2.42V11h6a3.31,3.31,0,0,1,.54-.8,1.81,1.81,0,0,1,.19-.2H2.42v-9H11v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.43,1.79V4.24H5.89V1.79Zm2,2H3.93V2.29H5.39Z"/><path class="cls-2" d="M11.08,16a2.22,2.22,0,0,0,.45,0,2.59,2.59,0,0,0,.4,0Z"/><path class="cls-2" d="M12,9.08h0l-.39,0a3.68,3.68,0,0,0-.58,0A3.41,3.41,0,0,0,9.14,10a1.81,1.81,0,0,0-.19.2,3.46,3.46,0,0,0-.89,2.3,3.4,3.4,0,0,0,.85,2.26,1.29,1.29,0,0,0,.16.17A3.31,3.31,0,0,0,11,16H12a3.46,3.46,0,0,0,2.17-1.13,3.41,3.41,0,0,0,.88-2.3A3.47,3.47,0,0,0,12,9.08Zm0,5.72a1.72,1.72,0,0,1-.39,0,2.23,2.23,0,0,1-.77-.14,2.29,2.29,0,0,1-1.54-2.17A2.22,2.22,0,0,1,9.79,11a2.29,2.29,0,0,1,1-.67,2.23,2.23,0,0,1,.77-.14,1.72,1.72,0,0,1,.39,0h0a2.3,2.3,0,0,1,0,4.53Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1002 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#d02e00;}</style></defs><title>disconnected_server_inverse_16x16</title><path class="cls-1" d="M1.42.06V16H11a3.31,3.31,0,0,1-1.94-1H2.42V11h6a3.31,3.31,0,0,1,.54-.8,1.81,1.81,0,0,1,.19-.2H2.42v-9H11v8a3.68,3.68,0,0,1,.58,0l.39,0h0v-9Z"/><path class="cls-1" d="M3.43,1.79V4.24H5.89V1.79Zm2,2H3.93V2.29H5.39Z"/><path class="cls-2" d="M11.08,16a2.22,2.22,0,0,0,.45,0,2.59,2.59,0,0,0,.4,0Z"/><path class="cls-2" d="M12,9.08h0l-.39,0a3.68,3.68,0,0,0-.58,0A3.41,3.41,0,0,0,9.14,10a1.81,1.81,0,0,0-.19.2,3.46,3.46,0,0,0-.89,2.3,3.4,3.4,0,0,0,.85,2.26,1.29,1.29,0,0,0,.16.17A3.31,3.31,0,0,0,11,16H12a3.46,3.46,0,0,0,2.17-1.13,3.41,3.41,0,0,0,.88-2.3A3.47,3.47,0,0,0,12,9.08Zm0,5.72a1.72,1.72,0,0,1-.39,0,2.23,2.23,0,0,1-.77-.14,2.29,2.29,0,0,1-1.54-2.17A2.22,2.22,0,0,1,9.79,11a2.29,2.29,0,0,1,1-.67,2.23,2.23,0,0,1,.77-.14,1.72,1.72,0,0,1,.39,0h0a2.3,2.3,0,0,1,0,4.53Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1007 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M11 10H5.344L11 4.414V10z"/></svg>
|
||||
|
After Width: | Height: | Size: 118 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>server_inverse_16x16</title><path class="cls-1" d="M2.73,0V16H13.26V0Zm1,1h8.53v9H3.73ZM12.26,15H3.73V11h8.53Z"/><path class="cls-1" d="M7.21,4.23H4.75V1.77H7.21Zm-2-.5H6.71V2.27H5.25Z"/></svg>
|
||||
|
After Width: | Height: | Size: 339 B |
@@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { INodeContextValue } from 'sql/workbench/contrib/dataExplorer/browser/nodeContext';
|
||||
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { NodeType } from 'sql/workbench/contrib/objectExplorer/common/nodeType';
|
||||
import { ExtensionNodeType, DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
export class MssqlNodeContext extends Disposable {
|
||||
|
||||
static readonly canSelect = new Set([NodeType.Table, NodeType.View]);
|
||||
static readonly canEditData = new Set([NodeType.Table]);
|
||||
static readonly canCreateOrDelete = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction,
|
||||
NodeType.Schema, NodeType.StoredProcedure, NodeType.Table, NodeType.TableValuedFunction,
|
||||
NodeType.User, NodeType.UserDefinedTableType, NodeType.View]);
|
||||
static readonly canExecute = new Set([NodeType.StoredProcedure]);
|
||||
static readonly canAlter = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction,
|
||||
NodeType.StoredProcedure, NodeType.TableValuedFunction, NodeType.View]);
|
||||
|
||||
// General node context keys
|
||||
static NodeProvider = new RawContextKey<string>('nodeProvider', undefined);
|
||||
static IsDatabaseOrServer = new RawContextKey<boolean>('isDatabaseOrServer', false);
|
||||
static IsWindows = new RawContextKey<boolean>('isWindows', isWindows);
|
||||
static IsCloud = new RawContextKey<boolean>('isCloud', false);
|
||||
static NodeType = new RawContextKey<string>('nodeType', undefined);
|
||||
static NodeLabel = new RawContextKey<string>('nodeLabel', undefined);
|
||||
static EngineEdition = new RawContextKey<number>('engineEdition', DatabaseEngineEdition.Unknown);
|
||||
|
||||
// Scripting context keys
|
||||
static CanScriptAsSelect = new RawContextKey<boolean>('canScriptAsSelect', false);
|
||||
static CanEditData = new RawContextKey<boolean>('canEditData', false);
|
||||
static CanScriptAsCreateOrDelete = new RawContextKey<boolean>('canScriptAsCreateOeDelete', false);
|
||||
static CanScriptAsExecute = new RawContextKey<boolean>('canScriptAsExecute', false);
|
||||
static CanScriptAsAlter = new RawContextKey<boolean>('canScriptAsAlter', false);
|
||||
|
||||
private nodeProviderKey: IContextKey<string>;
|
||||
private isCloudKey: IContextKey<boolean>;
|
||||
private nodeTypeKey: IContextKey<string>;
|
||||
private nodeLabelKey: IContextKey<string>;
|
||||
private isDatabaseOrServerKey: IContextKey<boolean>;
|
||||
private engineEditionKey: IContextKey<number>;
|
||||
|
||||
private canScriptAsSelectKey: IContextKey<boolean>;
|
||||
private canEditDataKey: IContextKey<boolean>;
|
||||
private canScriptAsCreateOrDeleteKey: IContextKey<boolean>;
|
||||
private canScriptAsExecuteKey: IContextKey<boolean>;
|
||||
private canScriptAsAlterKey: IContextKey<boolean>;
|
||||
|
||||
constructor(
|
||||
private nodeContextValue: INodeContextValue,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||
@ICapabilitiesService private capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
super();
|
||||
this.bindContextKeys();
|
||||
|
||||
// Set additional node context keys
|
||||
if (this.nodeContextValue.node) {
|
||||
const node = this.nodeContextValue.node;
|
||||
if (node.payload) {
|
||||
this.setNodeProvider();
|
||||
this.setIsCloud();
|
||||
this.setEngineEdition();
|
||||
if (node.type) {
|
||||
this.setIsDatabaseOrServer();
|
||||
this.nodeTypeKey.set(node.type);
|
||||
} else if (node.contextValue && node.providerHandle === mssqlProviderName) {
|
||||
this.setIsDatabaseOrServer();
|
||||
this.setScriptingContextKeys();
|
||||
this.nodeTypeKey.set(node.contextValue);
|
||||
}
|
||||
}
|
||||
if (node.label) {
|
||||
this.nodeLabelKey.set(node.label.label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bindContextKeys(): void {
|
||||
this.isCloudKey = MssqlNodeContext.IsCloud.bindTo(this.contextKeyService);
|
||||
this.engineEditionKey = MssqlNodeContext.EngineEdition.bindTo(this.contextKeyService);
|
||||
this.nodeTypeKey = MssqlNodeContext.NodeType.bindTo(this.contextKeyService);
|
||||
this.nodeLabelKey = MssqlNodeContext.NodeLabel.bindTo(this.contextKeyService);
|
||||
this.isDatabaseOrServerKey = MssqlNodeContext.IsDatabaseOrServer.bindTo(this.contextKeyService);
|
||||
this.canScriptAsSelectKey = MssqlNodeContext.CanScriptAsSelect.bindTo(this.contextKeyService);
|
||||
this.canEditDataKey = MssqlNodeContext.CanEditData.bindTo(this.contextKeyService);
|
||||
this.canScriptAsCreateOrDeleteKey = MssqlNodeContext.CanScriptAsCreateOrDelete.bindTo(this.contextKeyService);
|
||||
this.canScriptAsExecuteKey = MssqlNodeContext.CanScriptAsExecute.bindTo(this.contextKeyService);
|
||||
this.canScriptAsAlterKey = MssqlNodeContext.CanScriptAsAlter.bindTo(this.contextKeyService);
|
||||
this.nodeProviderKey = MssqlNodeContext.NodeProvider.bindTo(this.contextKeyService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the node provider
|
||||
*/
|
||||
private setNodeProvider(): void {
|
||||
if (this.nodeContextValue.node.payload.providerName) {
|
||||
this.nodeProviderKey.set(this.nodeContextValue.node.payload.providerName);
|
||||
} else if (this.nodeContextValue.node.childProvider) {
|
||||
this.nodeProviderKey.set(this.nodeContextValue.node.childProvider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to tell whether a connected node is cloud or not
|
||||
*/
|
||||
private setIsCloud(): void {
|
||||
let serverInfo: azdata.ServerInfo = this.getServerInfo();
|
||||
if (serverInfo && serverInfo.isCloud) {
|
||||
this.isCloudKey.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to set engine edition
|
||||
*/
|
||||
private setEngineEdition(): void {
|
||||
|
||||
let serverInfo: azdata.ServerInfo = this.getServerInfo();
|
||||
if (serverInfo && serverInfo.engineEditionId) {
|
||||
this.engineEditionKey.set(serverInfo.engineEditionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function fetching the server info
|
||||
*/
|
||||
private getServerInfo(): azdata.ServerInfo | undefined {
|
||||
const profile = new ConnectionProfile(this.capabilitiesService,
|
||||
this.nodeContextValue.node.payload);
|
||||
const connection = this.connectionManagementService.findExistingConnection(profile);
|
||||
if (connection) {
|
||||
return this.connectionManagementService.getServerInfo(connection.id);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to tell whether a connected node is a database or a
|
||||
* server or not. Added this key because this is easier to write than
|
||||
* writing an OR statement in ContextKeyExpr
|
||||
*/
|
||||
private setIsDatabaseOrServer(): void {
|
||||
const isDatabaseOrServer = (this.nodeContextValue.node.contextValue === NodeType.Server ||
|
||||
this.nodeContextValue.node.contextValue === NodeType.Database ||
|
||||
this.nodeContextValue.node.type === ExtensionNodeType.Server ||
|
||||
this.nodeContextValue.node.type === ExtensionNodeType.Database);
|
||||
this.isDatabaseOrServerKey.set(isDatabaseOrServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the correct context from node for showing
|
||||
* scripting context menu actions
|
||||
*/
|
||||
private setScriptingContextKeys(): void {
|
||||
const nodeType = this.nodeContextValue.node.contextValue;
|
||||
if (MssqlNodeContext.canCreateOrDelete.has(nodeType)) {
|
||||
this.canScriptAsCreateOrDeleteKey.set(true);
|
||||
}
|
||||
if (MssqlNodeContext.canEditData.has(nodeType)) {
|
||||
this.canEditDataKey.set(true);
|
||||
}
|
||||
if (MssqlNodeContext.canAlter.has(nodeType)) {
|
||||
this.canScriptAsAlterKey.set(true);
|
||||
}
|
||||
if (MssqlNodeContext.canExecute.has(nodeType)) {
|
||||
this.canScriptAsExecuteKey.set(true);
|
||||
}
|
||||
if (MssqlNodeContext.canSelect.has(nodeType)) {
|
||||
this.canScriptAsSelectKey.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import {
|
||||
DISCONNECT_COMMAND_ID, REFRESH_COMMAND_ID
|
||||
} from './nodeCommands.common';
|
||||
import { ContextKeyExpr, ContextKeyNotEqualsExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { NodeContextKey } from 'sql/workbench/contrib/dataExplorer/browser/nodeContext';
|
||||
import { MssqlNodeContext } from 'sql/workbench/contrib/dataExplorer/browser/mssqlNodeContext';
|
||||
import { NodeType } from 'sql/workbench/contrib/objectExplorer/common/nodeType';
|
||||
|
||||
|
||||
// Disconnect
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'connection',
|
||||
order: 4,
|
||||
command: {
|
||||
id: DISCONNECT_COMMAND_ID,
|
||||
title: localize('disconnect', "Disconnect")
|
||||
},
|
||||
when: ContextKeyExpr.and(NodeContextKey.IsConnected,
|
||||
ContextKeyNotEqualsExpr.create('nodeProvider', mssqlProviderName),
|
||||
ContextKeyNotEqualsExpr.create('nodeType', NodeType.Folder))
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'connection',
|
||||
order: 3,
|
||||
command: {
|
||||
id: DISCONNECT_COMMAND_ID,
|
||||
title: localize('disconnect', "Disconnect")
|
||||
},
|
||||
when: ContextKeyExpr.and(NodeContextKey.IsConnected,
|
||||
MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName),
|
||||
MssqlNodeContext.IsDatabaseOrServer)
|
||||
});
|
||||
|
||||
// Refresh
|
||||
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
||||
group: 'connection',
|
||||
order: 6,
|
||||
command: {
|
||||
id: REFRESH_COMMAND_ID,
|
||||
title: localize('refresh', "Refresh")
|
||||
},
|
||||
when: NodeContextKey.IsConnectable
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IOEShimService } from 'sql/workbench/contrib/objectExplorer/browser/objectExplorerViewTreeShim';
|
||||
import { ICustomViewDescriptor, TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IViewsRegistry, Extensions } from 'vs/workbench/common/views';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
export const DISCONNECT_COMMAND_ID = 'dataExplorer.disconnect';
|
||||
export const REFRESH_COMMAND_ID = 'dataExplorer.refresh';
|
||||
|
||||
// Disconnect
|
||||
CommandsRegistry.registerCommand({
|
||||
id: DISCONNECT_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
if (args.$treeItem) {
|
||||
const oeService = accessor.get(IOEShimService);
|
||||
return oeService.disconnectNode(args.$treeViewId, args.$treeItem).then(() => {
|
||||
const { treeView } = (<ICustomViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(args.$treeViewId));
|
||||
// we need to collapse it then refresh it so that the tree doesn't try and use it's cache next time the user expands the node
|
||||
treeView.collapse(args.$treeItem);
|
||||
treeView.refresh([args.$treeItem]).then(() => true);
|
||||
});
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Refresh
|
||||
CommandsRegistry.registerCommand({
|
||||
id: REFRESH_COMMAND_ID,
|
||||
handler: (accessor, args: TreeViewItemHandleArg) => {
|
||||
const progressService = accessor.get(IProgressService);
|
||||
if (args.$treeItem) {
|
||||
const { treeView } = (<ICustomViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(args.$treeViewId));
|
||||
if (args.$treeContainerId) {
|
||||
return progressService.withProgress({ location: args.$treeContainerId }, () => treeView.refresh([args.$treeItem]).then(() => true));
|
||||
} else {
|
||||
return treeView.refresh([args.$treeItem]).then(() => true);
|
||||
}
|
||||
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ConnectionContextKey } from 'sql/workbench/contrib/connection/common/connectionContextKey';
|
||||
import { IOEShimService } from 'sql/workbench/contrib/objectExplorer/browser/objectExplorerViewTreeShim';
|
||||
import { ITreeItem } from 'sql/workbench/common/views';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IQueryManagementService } from 'sql/platform/query/common/queryManagement';
|
||||
import { MssqlNodeContext } from 'sql/workbench/contrib/dataExplorer/browser/mssqlNodeContext';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
|
||||
export interface INodeContextValue {
|
||||
node: ITreeItem;
|
||||
viewId: string;
|
||||
}
|
||||
|
||||
export class NodeContextKey extends Disposable implements IContextKey<INodeContextValue> {
|
||||
|
||||
static IsConnectable = new RawContextKey<boolean>('isConnectable', false);
|
||||
static IsConnected = new RawContextKey<boolean>('isConnected', false);
|
||||
static ViewId = new RawContextKey<string>('view', undefined);
|
||||
static ViewItem = new RawContextKey<string>('viewItem', undefined);
|
||||
static Node = new RawContextKey<INodeContextValue>('node', undefined);
|
||||
|
||||
private readonly _connectionContextKey: ConnectionContextKey;
|
||||
private readonly _connectableKey: IContextKey<boolean>;
|
||||
private readonly _connectedKey: IContextKey<boolean>;
|
||||
private readonly _viewIdKey: IContextKey<string>;
|
||||
private readonly _viewItemKey: IContextKey<string>;
|
||||
private readonly _nodeContextKey: IContextKey<INodeContextValue>;
|
||||
|
||||
private _nodeContextUtils: MssqlNodeContext;
|
||||
|
||||
constructor(
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IOEShimService private oeService: IOEShimService,
|
||||
@IQueryManagementService queryManagementService: IQueryManagementService,
|
||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||
@ICapabilitiesService private capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._connectableKey = NodeContextKey.IsConnectable.bindTo(contextKeyService);
|
||||
this._connectedKey = NodeContextKey.IsConnected.bindTo(contextKeyService);
|
||||
this._viewIdKey = NodeContextKey.ViewId.bindTo(contextKeyService);
|
||||
this._viewItemKey = NodeContextKey.ViewItem.bindTo(contextKeyService);
|
||||
this._nodeContextKey = NodeContextKey.Node.bindTo(contextKeyService);
|
||||
this._connectionContextKey = new ConnectionContextKey(contextKeyService, queryManagementService);
|
||||
}
|
||||
|
||||
set(value: INodeContextValue) {
|
||||
if (value.node && value.node.payload) {
|
||||
this._connectableKey.set(true);
|
||||
this._connectedKey.set(this.oeService.isNodeConnected(value.viewId, value.node));
|
||||
this._connectionContextKey.set(value.node.payload);
|
||||
} else {
|
||||
this._connectableKey.set(false);
|
||||
this._connectedKey.set(false);
|
||||
this._connectionContextKey.reset();
|
||||
}
|
||||
if (value.node) {
|
||||
this._viewItemKey.set(value.node.contextValue);
|
||||
} else {
|
||||
this._viewItemKey.reset();
|
||||
}
|
||||
this._nodeContextKey.set(value);
|
||||
this._viewIdKey.set(value.viewId);
|
||||
this._nodeContextUtils = new MssqlNodeContext(this._nodeContextKey.get(), this.contextKeyService,
|
||||
this.connectionManagementService, this.capabilitiesService);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._viewIdKey.reset();
|
||||
this._viewItemKey.reset();
|
||||
this._connectableKey.reset();
|
||||
this._connectedKey.reset();
|
||||
this._connectionContextKey.reset();
|
||||
this._nodeContextKey.reset();
|
||||
this._nodeContextUtils.dispose();
|
||||
}
|
||||
|
||||
get(): INodeContextValue | undefined {
|
||||
return this._nodeContextKey.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { INodeContextValue } from 'sql/workbench/contrib/dataExplorer/browser/nodeContext';
|
||||
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { NodeType } from 'sql/workbench/contrib/objectExplorer/common/nodeType';
|
||||
import { ExtensionNodeType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
export class NodeContextUtils extends Disposable {
|
||||
|
||||
static readonly canSelect = new Set([NodeType.Table, NodeType.View]);
|
||||
static readonly canEditData = new Set([NodeType.Table]);
|
||||
static readonly canCreateOrDelete = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction,
|
||||
NodeType.Schema, NodeType.StoredProcedure, NodeType.Table, NodeType.TableValuedFunction,
|
||||
NodeType.User, NodeType.UserDefinedTableType, NodeType.View]);
|
||||
static readonly canExecute = new Set([NodeType.StoredProcedure]);
|
||||
static readonly canAlter = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction,
|
||||
NodeType.StoredProcedure, NodeType.TableValuedFunction, NodeType.View]);
|
||||
|
||||
// General node context keys
|
||||
static NodeProvider = new RawContextKey<string>('nodeProvider', undefined);
|
||||
static IsDatabaseOrServer = new RawContextKey<boolean>('isDatabaseOrServer', false);
|
||||
static IsWindows = new RawContextKey<boolean>('isWindows', isWindows);
|
||||
static IsCloud = new RawContextKey<boolean>('isCloud', false);
|
||||
static NodeType = new RawContextKey<string>('nodeType', undefined);
|
||||
static NodeLabel = new RawContextKey<string>('nodeLabel', undefined);
|
||||
|
||||
// Scripting context keys
|
||||
static CanScriptAsSelect = new RawContextKey<boolean>('canScriptAsSelect', false);
|
||||
static CanEditData = new RawContextKey<boolean>('canEditData', false);
|
||||
static CanScriptAsCreateOrDelete = new RawContextKey<boolean>('canScriptAsCreateOeDelete', false);
|
||||
static CanScriptAsExecute = new RawContextKey<boolean>('canScriptAsExecute', false);
|
||||
static CanScriptAsAlter = new RawContextKey<boolean>('canScriptAsAlter', false);
|
||||
|
||||
private nodeProviderKey: IContextKey<string>;
|
||||
private isCloudKey: IContextKey<boolean>;
|
||||
private nodeTypeKey: IContextKey<string>;
|
||||
private nodeLabelKey: IContextKey<string>;
|
||||
private isDatabaseOrServerKey: IContextKey<boolean>;
|
||||
|
||||
private canScriptAsSelectKey: IContextKey<boolean>;
|
||||
private canEditDataKey: IContextKey<boolean>;
|
||||
private canScriptAsCreateOrDeleteKey: IContextKey<boolean>;
|
||||
private canScriptAsExecuteKey: IContextKey<boolean>;
|
||||
private canScriptAsAlterKey: IContextKey<boolean>;
|
||||
|
||||
constructor(
|
||||
private nodeContextValue: INodeContextValue,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||
@ICapabilitiesService private capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
super();
|
||||
this.bindContextKeys();
|
||||
|
||||
// Set additional node context keys
|
||||
if (this.nodeContextValue.node) {
|
||||
const node = this.nodeContextValue.node;
|
||||
if (node.payload) {
|
||||
this.setNodeProvider();
|
||||
this.setIsCloud();
|
||||
if (node.type) {
|
||||
this.setIsDatabaseOrServer();
|
||||
this.nodeTypeKey.set(node.type);
|
||||
} else if (node.contextValue && node.providerHandle === mssqlProviderName) {
|
||||
this.setIsDatabaseOrServer();
|
||||
this.setScriptingContextKeys();
|
||||
this.nodeTypeKey.set(node.contextValue);
|
||||
}
|
||||
}
|
||||
if (node.label) {
|
||||
this.nodeLabelKey.set(node.label.label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bindContextKeys(): void {
|
||||
this.isCloudKey = NodeContextUtils.IsCloud.bindTo(this.contextKeyService);
|
||||
this.nodeTypeKey = NodeContextUtils.NodeType.bindTo(this.contextKeyService);
|
||||
this.nodeLabelKey = NodeContextUtils.NodeLabel.bindTo(this.contextKeyService);
|
||||
this.isDatabaseOrServerKey = NodeContextUtils.IsDatabaseOrServer.bindTo(this.contextKeyService);
|
||||
this.canScriptAsSelectKey = NodeContextUtils.CanScriptAsSelect.bindTo(this.contextKeyService);
|
||||
this.canEditDataKey = NodeContextUtils.CanEditData.bindTo(this.contextKeyService);
|
||||
this.canScriptAsCreateOrDeleteKey = NodeContextUtils.CanScriptAsCreateOrDelete.bindTo(this.contextKeyService);
|
||||
this.canScriptAsExecuteKey = NodeContextUtils.CanScriptAsExecute.bindTo(this.contextKeyService);
|
||||
this.canScriptAsAlterKey = NodeContextUtils.CanScriptAsAlter.bindTo(this.contextKeyService);
|
||||
this.nodeProviderKey = NodeContextUtils.NodeProvider.bindTo(this.contextKeyService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the node provider
|
||||
*/
|
||||
private setNodeProvider(): void {
|
||||
if (this.nodeContextValue.node.payload.providerName) {
|
||||
this.nodeProviderKey.set(this.nodeContextValue.node.payload.providerName);
|
||||
} else if (this.nodeContextValue.node.childProvider) {
|
||||
this.nodeProviderKey.set(this.nodeContextValue.node.childProvider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to tell whether a connected node is cloud or not
|
||||
*/
|
||||
private setIsCloud(): void {
|
||||
const profile = new ConnectionProfile(this.capabilitiesService,
|
||||
this.nodeContextValue.node.payload);
|
||||
const connection = this.connectionManagementService.findExistingConnection(profile);
|
||||
if (connection) {
|
||||
const serverInfo = this.connectionManagementService.getServerInfo(connection.id);
|
||||
if (serverInfo.isCloud) {
|
||||
this.isCloudKey.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to tell whether a connected node is a database or a
|
||||
* server or not. Added this key because this is easier to write than
|
||||
* writing an OR statement in ContextKeyExpr
|
||||
*/
|
||||
private setIsDatabaseOrServer(): void {
|
||||
const isDatabaseOrServer = (this.nodeContextValue.node.contextValue === NodeType.Server ||
|
||||
this.nodeContextValue.node.contextValue === NodeType.Database ||
|
||||
this.nodeContextValue.node.type === ExtensionNodeType.Server ||
|
||||
this.nodeContextValue.node.type === ExtensionNodeType.Database);
|
||||
this.isDatabaseOrServerKey.set(isDatabaseOrServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the correct context from node for showing
|
||||
* scripting context menu actions
|
||||
*/
|
||||
private setScriptingContextKeys(): void {
|
||||
const nodeType = this.nodeContextValue.node.contextValue;
|
||||
if (NodeContextUtils.canCreateOrDelete.has(nodeType)) {
|
||||
this.canScriptAsCreateOrDeleteKey.set(true);
|
||||
}
|
||||
if (NodeContextUtils.canEditData.has(nodeType)) {
|
||||
this.canEditDataKey.set(true);
|
||||
}
|
||||
if (NodeContextUtils.canAlter.has(nodeType)) {
|
||||
this.canScriptAsAlterKey.set(true);
|
||||
}
|
||||
if (NodeContextUtils.canExecute.has(nodeType)) {
|
||||
this.canScriptAsExecuteKey.set(true);
|
||||
}
|
||||
if (NodeContextUtils.canSelect.has(nodeType)) {
|
||||
this.canScriptAsSelectKey.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as Platform from 'vs/platform/registry/common/platform';
|
||||
import { ViewletDescriptor, Extensions, Viewlet, ViewletRegistry } from 'vs/workbench/browser/viewlet';
|
||||
import * as Types from 'vs/base/common/types';
|
||||
|
||||
suite('Data Explorer Viewlet', () => {
|
||||
|
||||
class DataExplorerTestViewlet extends Viewlet {
|
||||
|
||||
constructor() {
|
||||
super('dataExplorer', null, null, null, null, null);
|
||||
}
|
||||
|
||||
public layout(dimension: any): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
test('ViewletDescriptor API', function () {
|
||||
let d = new ViewletDescriptor(DataExplorerTestViewlet, 'id', 'name', 'class', 1);
|
||||
assert.strictEqual(d.id, 'id');
|
||||
assert.strictEqual(d.name, 'name');
|
||||
assert.strictEqual(d.cssClass, 'class');
|
||||
assert.strictEqual(d.order, 1);
|
||||
});
|
||||
|
||||
test('Editor Aware ViewletDescriptor API', function () {
|
||||
let d = new ViewletDescriptor(DataExplorerTestViewlet, 'id', 'name', 'class', 5);
|
||||
assert.strictEqual(d.id, 'id');
|
||||
assert.strictEqual(d.name, 'name');
|
||||
|
||||
d = new ViewletDescriptor(DataExplorerTestViewlet, 'id', 'name', 'class', 5);
|
||||
assert.strictEqual(d.id, 'id');
|
||||
assert.strictEqual(d.name, 'name');
|
||||
});
|
||||
|
||||
test('Data Explorer Viewlet extension point and registration', function () {
|
||||
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet));
|
||||
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet));
|
||||
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets));
|
||||
|
||||
let oldCount = Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length;
|
||||
let d = new ViewletDescriptor(DataExplorerTestViewlet, 'dataExplorer-test-id', 'name');
|
||||
Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet(d);
|
||||
let retrieved = Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet('dataExplorer-test-id');
|
||||
assert(d === retrieved);
|
||||
let newCount = Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length;
|
||||
assert.equal(oldCount + 1, newCount);
|
||||
});
|
||||
});
|
||||