Compare commits

..

8 Commits

Author SHA1 Message Date
Karl Burtram
087a6a0810 Bump SQL Ops to 0.28.3 (#1125) 2018-04-11 13:27:05 -07:00
Abbie Petchtes
495b4ee7c2 fix all high constrast issues in sqlops (#1115) 2018-04-11 12:36:00 -07:00
Leila Lali
7833c28b7a fixed the bug with using vs code url to download manually (#1108) 2018-04-11 11:59:56 -07:00
Abbie Petchtes
bbfb68b082 fix the keyboard issue where table is empty (#1110) 2018-04-10 16:09:18 -07:00
Matt Irvine
b32e7a777c Bump tools service for node path change (#1114) 2018-04-10 15:53:06 -07:00
Anthony Dresser
a327889d05 Fix Dashboard Errors (#1106)
* fix ordering of component instance calls to fix erros

* add more verification methods
2018-04-10 13:46:07 -07:00
Abbie Petchtes
5ac89e5a49 Open query plan link when select XML showplan in the result grid (#1092)
* open query plan link

* address comments
2018-04-09 10:27:32 -07:00
Kevin Cunnane
849653927a Fix #1095 "Run kinit" helper no longer runs kinit (#1102)
VSCode refactored their terminal to have more delayed initialization,
but still return as complete before the actual instance is ready for focus
and paste events. The fix is to add a delay so this can complete before
calling the paste action. As this doesn't affect extensions (the hop to the
extension host causes a delay) I'm not raising this with VSCode as an
upstream issue, just fixing on our side
2018-04-07 13:16:05 -07:00
18 changed files with 101 additions and 30 deletions

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "1.4.0-alpha.19",
"version": "1.4.0-alpha.20",
"downloadFileNames": {
"Windows_86": "win-x86-netcoreapp2.0.zip",
"Windows_64": "win-x64-netcoreapp2.0.zip",

View File

@@ -56,7 +56,7 @@
"tab.activeBackground": "#212121",
"tab.activeForeground": "#ffffff",
"tab.inactiveBackground": "#444444",
"tab.inactiveForeground": "#888888",
"tab.inactiveForeground": "#b6b6b6",
"tab.border": "#3c3c3c",
"panel.background": "#212121",
"panel.border": "#515151",

View File

@@ -66,7 +66,7 @@
"tab.activeBackground": "#FFFFFE",
"tab.activeForeground": "#4A4A4A",
"tab.inactiveBackground": "#f4f4f4",
"tab.inactiveForeground": "#888888",
"tab.inactiveForeground": "#707070",
"tab.border": "#EAEAEA",
"tab.unfocusedInactiveForeground": "#888888",
"tab.unfocusedActiveForeground": "#212121",

View File

@@ -1,6 +1,6 @@
{
"name": "sqlops",
"version": "0.28.2",
"version": "0.28.3",
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
"author": {
"name": "Microsoft Corporation"

View File

@@ -71,7 +71,7 @@ panel {
}
.tabbedPanel .tabList .tab .tabLabel {
opacity: 0.6;
opacity: 0.8;
}
.tabbedPanel .tabList .tab .tabLabel.icon {

View File

@@ -5,13 +5,13 @@
import 'vs/css!./media/panel';
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER } from 'vs/workbench/common/theme';
import { TAB_ACTIVE_FOREGROUND, TAB_INACTIVE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER } from 'vs/workbench/common/theme';
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
// Title Active
const titleActive = theme.getColor(PANEL_ACTIVE_TITLE_FOREGROUND);
const titleActive = theme.getColor(TAB_ACTIVE_FOREGROUND);
const titleActiveBorder = theme.getColor(PANEL_ACTIVE_TITLE_BORDER);
if (titleActive || titleActiveBorder) {
collector.addRule(`
@@ -28,7 +28,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
}
// Title Inactive
const titleInactive = theme.getColor(PANEL_INACTIVE_TITLE_FOREGROUND);
const titleInactive = theme.getColor(TAB_INACTIVE_FOREGROUND);
if (titleInactive) {
collector.addRule(`
.tabbedPanel > .title > .tabList .tab .tabLabel {

View File

@@ -256,7 +256,7 @@ export class Table<T extends Slick.SlickData> implements IThemable {
}
if (styles.listSelectionOutline) {
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected.active { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
}
/* Commented out andresse 8/17/2017; keeping for reference as we iterate on the table styling */

View File

@@ -7,8 +7,10 @@ import { registerColor, foreground } from 'vs/platform/theme/common/colorRegistr
import { Color, RGBA } from 'vs/base/common/color';
import * as nls from 'vs/nls';
export const tableHeaderBackground = registerColor('table.headerBackground', { dark: new Color(new RGBA(51, 51, 52)), light: new Color(new RGBA(245, 245, 245)), hc: null }, nls.localize('tableHeaderBackground', 'Table header background color'));
export const tableHeaderForeground = registerColor('table.headerForeground', { dark: new Color(new RGBA(229, 229, 229)), light: new Color(new RGBA(16, 16, 16)), hc: null }, nls.localize('tableHeaderForeground', 'Table header foreground color'));
export const tableHeaderBackground = registerColor('table.headerBackground', { dark: new Color(new RGBA(51, 51, 52)), light: new Color(new RGBA(245, 245, 245)), hc: '#333334' }, nls.localize('tableHeaderBackground', 'Table header background color'));
export const tableHeaderForeground = registerColor('table.headerForeground', { dark: new Color(new RGBA(229, 229, 229)), light: new Color(new RGBA(16, 16, 16)), hc: '#e5e5e5' }, nls.localize('tableHeaderForeground', 'Table header foreground color'));
export const disabledInputBackground = registerColor('input.disabled.background', { dark: '#444444', light: '#dcdcdc', hc: Color.black }, nls.localize('disabledInputBoxBackground', "Disabled Input box background."));
export const disabledInputForeground = registerColor('input.disabled.foreground', { dark: '#888888', light: '#888888', hc: foreground }, nls.localize('disabledInputBoxForeground', "Disabled Input box foreground."));
export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused."));
export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused."));
export const listFocusAndSelectionBackground = registerColor('list.focusAndSelectionBackground', { dark: '#2c3295', light: '#2c3295', hc: null }, nls.localize('listFocusAndSelectionBackground', "List/Table background color for the selected and focus item when the list/table is active"));

View File

@@ -146,9 +146,9 @@ export function attachTableStyler(widget: IThemable, themeService: IThemeService
return attachStyler(themeService, {
listFocusBackground: (style && style.listFocusBackground) || cr.listFocusBackground,
listFocusForeground: (style && style.listFocusForeground) || cr.listFocusForeground,
listActiveSelectionBackground: (style && style.listActiveSelectionBackground) || cr.lighten(cr.listActiveSelectionBackground, 0.1),
listActiveSelectionBackground: (style && style.listActiveSelectionBackground) || cr.listActiveSelectionBackground,
listActiveSelectionForeground: (style && style.listActiveSelectionForeground) || cr.listActiveSelectionForeground,
listFocusAndSelectionBackground: style && style.listFocusAndSelectionBackground || cr.listActiveSelectionBackground,
listFocusAndSelectionBackground: style && style.listFocusAndSelectionBackground || sqlcolors.listFocusAndSelectionBackground,
listFocusAndSelectionForeground: (style && style.listFocusAndSelectionForeground) || cr.listActiveSelectionForeground,
listInactiveFocusBackground: (style && style.listInactiveFocusBackground),
listInactiveSelectionBackground: (style && style.listInactiveSelectionBackground) || cr.listInactiveSelectionBackground,

View File

@@ -346,7 +346,10 @@ export class ConnectionDialogService implements IConnectionDialogService {
this._connectionDialog.close();
this._clipboardService.writeText('kinit\r');
this._commandService.executeCommand('workbench.action.terminal.focus').then(resolve => {
return this._commandService.executeCommand('workbench.action.terminal.paste');
// setTimeout to allow for terminal Instance to load.
setTimeout(() => {
return this._commandService.executeCommand('workbench.action.terminal.paste');
}, 10);
}).then(resolve => null, reject => null);
return null;
}));

View File

@@ -13,6 +13,10 @@ panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .ta
border-bottom: 0px solid;
}
panel.dashboard-panel > .tabbedPanel .tabList .tab .tabLabel {
opacity: 1;
}
panel.dashboard-panel > .tabbedPanel > .title > .title-actions,
panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab-header {
box-sizing: border-box;

View File

@@ -198,11 +198,11 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
let componentRef = this.componentHost.viewContainerRef.createComponent(componentFactory);
let componentInstance = componentRef.instance;
componentInstance.data = { columns: result.columnInfo.map(item => item.columnName), rows: result.rows.map(row => row.map(item => item.displayValue)) };
// check if the setter is defined
if (componentInstance.setConfig) {
componentInstance.setConfig(this.insightConfig.type[this._typeKey]);
}
componentInstance.data = { columns: result.columnInfo.map(item => item.columnName), rows: result.rows.map(row => row.map(item => item.displayValue)) };
if (componentInstance.init) {
componentInstance.init();

View File

@@ -90,7 +90,7 @@ export const defaultChartConfig: IChartConfig = {
@Component({
template: ` <div style="display: block; width: 100%; height: 100%; position: relative">
<canvas #canvas *ngIf="_isDataAvailable"
<canvas #canvas *ngIf="_isDataAvailable && _hasInit"
baseChart
[datasets]="chartData"
[labels]="labels"
@@ -101,6 +101,7 @@ export const defaultChartConfig: IChartConfig = {
})
export abstract class ChartInsight extends Disposable implements IInsightsView {
private _isDataAvailable: boolean = false;
private _hasInit: boolean = false;
private _options: any = {};
@ViewChild(BaseChartDirective) private _chart: BaseChartDirective;
@@ -126,6 +127,7 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
// This is because chart.js doesn't auto-update anything other than dataset when re-rendering so defaults are used
// hence it's easier to not render until ready
this.options = mixin(this.options, { maintainAspectRatio: false });
this._hasInit = true;
this._changeRef.detectChanges();
TelemetryUtils.addTelemetry(this._bootstrapService.telemetryService, TelemetryKeys.ChartCreated, { type: this.chartType });
}
@@ -160,7 +162,9 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
public refresh() {
// cheaper refresh but causes problems when change data for rerender
this._chart.ngOnChanges({});
if (this._chart) {
this._chart.ngOnChanges({});
}
}
public getCanvasData(): string {

View File

@@ -96,10 +96,13 @@ export class RestoreDialog extends Modal {
private _fileListTable: Table<FileListElement>;
private _fileListData: TableDataView<FileListElement>;
private _fileListTableContainer: HTMLElement;
private _restorePlanTable: Table<Slick.SlickData>;
private _restorePlanData: TableDataView<Slick.SlickData>;
private _restorePlanColumn;
private _restorePlanTableContainer: HTMLElement;
private _isRenderedRestorePlanTable: boolean;
private _onRestore = new Emitter<boolean>();
public onRestore: Event<boolean> = this._onRestore.event;
@@ -141,6 +144,8 @@ export class RestoreDialog extends Modal {
this.viewModel.onSetRestoreOption((optionParams) => this.updateRestoreOption(optionParams));
this.viewModel.onUpdateBackupSetsToRestore((backupSets) => this.updateBackupSetsToRestore(backupSets));
this.viewModel.onUpdateRestoreDatabaseFiles((files) => this.updateRestoreDatabaseFiles(files));
this._isRenderedRestorePlanTable = false;
}
public render() {
@@ -254,6 +259,8 @@ export class RestoreDialog extends Modal {
// Backup sets table
restorePlanContainer.div({ class: 'dialog-input-section restore-list' }, (labelContainer) => {
this._restorePlanTableContainer = labelContainer.getHTMLElement();
labelContainer.hide();
this._restorePlanData = new TableDataView<Slick.SlickData>();
this._restorePlanTable = new Table<Slick.SlickData>(labelContainer.getHTMLElement(), this._restorePlanData, this._restorePlanColumn, { enableColumnReorder: false });
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
@@ -287,6 +294,8 @@ export class RestoreDialog extends Modal {
this.createLabelElement(sectionContainer, localize('restoreDatabaseFileDetails', 'Restore database file details'), true);
// file list table
sectionContainer.div({ class: 'dialog-input-section restore-list' }, (fileNameContainer) => {
this._fileListTableContainer = fileNameContainer.getHTMLElement();
fileNameContainer.hide();
let logicalFileName = localize('logicalFileName', 'Logical file Name');
let fileType = localize('fileType', 'File type');
let originalFileName = localize('originalFileName', 'Original File Name');
@@ -540,9 +549,23 @@ export class RestoreDialog extends Modal {
return inputBox;
}
private clearRestorePlanDataTable(): void {
if (this._restorePlanData.getLength() > 0) {
this._restorePlanData.clear();
new Builder(this._restorePlanTableContainer).hide();
}
}
private clearFileListTable(): void {
if (this._fileListData.getLength() > 0) {
this._fileListData.clear();
new Builder(this._fileListTableContainer).hide();
}
}
private resetRestoreContent(): void {
this._restorePlanData.clear();
this._fileListData.clear();
this.clearRestorePlanDataTable();
this.clearFileListTable();
this._restoreButton.enabled = false;
this._scriptButton.enabled = false;
}
@@ -803,8 +826,8 @@ export class RestoreDialog extends Modal {
}
private updateRestoreDatabaseFiles(dbFiles: sqlops.RestoreDatabaseFileInfo[]) {
this._fileListData.clear();
if (dbFiles) {
this.clearFileListTable();
if (dbFiles && dbFiles.length > 0) {
let data = [];
for (let i = 0; i < dbFiles.length; i++) {
data[i] = {
@@ -814,7 +837,7 @@ export class RestoreDialog extends Modal {
restoreAs: dbFiles[i].restoreAsFileName
};
}
new Builder(this._fileListTableContainer).show();
this._fileListData.push(data);
// Select the first row for the table by default
@@ -833,7 +856,7 @@ export class RestoreDialog extends Modal {
}
this._restorePlanTable.setSelectedRows(selectedRow);
} else {
this._restorePlanData.clear();
this.clearRestorePlanDataTable();
if (backupSetsToRestore && backupSetsToRestore.length > 0) {
if (!this._restorePlanColumn) {
let firstRow = backupSetsToRestore[0];
@@ -865,9 +888,16 @@ export class RestoreDialog extends Modal {
selectedRow.push(i);
}
}
new Builder(this._restorePlanTableContainer).show();
this._restorePlanData.push(data);
this._restorePlanTable.setSelectedRows(selectedRow);
this._restorePlanTable.setActiveCell(selectedRow[0], 0);
if (!this._isRenderedRestorePlanTable) {
this._isRenderedRestorePlanTable = true;
this._restorePlanTable.resizeCanvas();
this._restorePlanTable.autosizeColumns();
}
}
}
}

View File

@@ -477,7 +477,13 @@ export abstract class GridParentComponent {
*/
xmlLinkHandler = (cellRef: string, row: number, dataContext: JSON, colDef: any) => {
const self = this;
self.handleLink(cellRef, row, dataContext, colDef, 'xml');
let value = self.getCellValueString(dataContext, colDef);
if (value.startsWith('<ShowPlanXML') && colDef.name !== 'XML Showplan') {
self.handleQueryPlanLink(cellRef, value);
} else {
self.handleLink(cellRef, row, dataContext, colDef, 'xml');
}
}
/**
@@ -488,6 +494,13 @@ export abstract class GridParentComponent {
self.handleLink(cellRef, row, dataContext, colDef, 'json');
}
private handleQueryPlanLink(cellRef: string, value: string): void {
const self = this;
$(cellRef).children('.xmlLink').click(function (): void {
self._bootstrapService.queryEditorService.newQueryPlanEditor(value);
});
}
private handleLink(cellRef: string, row: number, dataContext: JSON, colDef: any, linkType: string): void {
const self = this;
let value = self.getCellValueString(dataContext, colDef);

View File

@@ -5,7 +5,7 @@
.empty-task-message {
padding: 10px 22px 0 22px;
opacity: 0.5;
opacity: 0.8;
}
.monaco-tree .monaco-tree-rows > .monaco-tree-row > .content > .task-group {

View File

@@ -150,7 +150,9 @@ export const descriptionForeground = registerColor('descriptionForeground', { li
export const focusBorder = registerColor('focusBorder', { dark: Color.fromHex('#0E639C').transparent(0.6), light: Color.fromHex('#007ACC').transparent(0.4), hc: '#F38518' }, nls.localize('focusBorder', "Overall border color for focused elements. This color is only used if not overridden by a component."));
export const contrastBorder = registerColor('contrastBorder', { light: null, dark: null, hc: '#6FC3DF' }, nls.localize('contrastBorder', "An extra border around elements to separate them from others for greater contrast."));
// {{SQL CARBON EDIT}} -- Update contrastBorder color for HC
export const contrastBorder = registerColor('contrastBorder', { light: null, dark: null, hc: '#2b56f2' }, nls.localize('contrastBorder', "An extra border around elements to separate them from others for greater contrast."));
export const activeContrastBorder = registerColor('contrastActiveBorder', { light: null, dark: null, hc: focusBorder }, nls.localize('activeContrastBorder', "An extra border around active elements to separate them from others for greater contrast."));
export const selectionBackground = registerColor('selection.background', { light: null, dark: null, hc: null }, nls.localize('selectionBackground', "The background color of text selections in the workbench (e.g. for input fields or text areas). Note that this does not apply to selections within the editor."));

View File

@@ -114,7 +114,7 @@ class Extension implements IExtension {
return null;
}
return `${product.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`;
return product.extensionsGallery.itemUrl && `${product.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`;
}
get downloadUrl(): string {
@@ -122,7 +122,9 @@ class Extension implements IExtension {
return null;
}
return `${product.extensionsGallery.serviceUrl}/publishers/${this.publisher}/vsextensions/${this.name}/${this.latestVersion}/vspackage`;
// {{SQL CARBON EDIT}}
return this.gallery && this.gallery.assets && this.gallery.assets.download && this.gallery.assets.download.uri;
//return `${product.extensionsGallery.serviceUrl}/publishers/${this.publisher}/vsextensions/${this.name}/${this.latestVersion}/vspackage`;
}
get iconUrl(): string {
@@ -612,7 +614,18 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
location: ProgressLocation.Extensions,
title: nls.localize('installingMarketPlaceExtension', 'Installing extension from Marketplace....'),
tooltip: `${extension.id}`
}, () => this.extensionService.installFromGallery(gallery));
// {{SQL CARBON EDIT}}
}, () => this.downloadOrBrowse(ext));
}
// {{SQL CARBON EDIT}}
private downloadOrBrowse(ext: Extension): TPromise<void> {
if (ext.gallery.assets.downloadPage && ext.gallery.assets.downloadPage.uri) {
window.open(ext.gallery.assets.downloadPage.uri);
return TPromise.wrap<void>(void 0);
} else {
return this.extensionService.installFromGallery(ext.gallery);
}
}
setEnablement(extension: IExtension, enablementState: EnablementState): TPromise<void> {