Compare commits

...

8 Commits

Author SHA1 Message Date
Anthony Dresser
8004776eff Hide tabs on reexecute (#2624)
* add logic to hide tabs when a query rerun is executed

* remove double entry in the map
2018-09-18 21:42:38 -07:00
Abbie Petchtes
cdc07d9f08 Feat/add dom component (#2622)
* add dom component for model view

* formatting

* make css style hardcoded in dom.component

* comment out the unused CSS

* address comments

* address comment
2018-09-18 21:42:29 -07:00
Karl Burtram
6be511fab2 Bump SQL Tools Service to 1.5.0-alpha.34 (#2621) 2018-09-18 15:01:43 -07:00
ranasaria
b2a520fcbf Bug/oetimeout Fix - When timeout happens while fetching node children, the node becomes unusable (#2616)
This commit fixes issue when multiple OE nodes are expanded simultaneously. While the error was getting displayed the node was left in incorrect state which was leading to the node being unusable in future. This commit repairs this defect.
2018-09-18 14:27:29 -07:00
Aditya Bist
a21807318b fixed actual show plan command (#2620) 2018-09-18 13:42:48 -07:00
AlexFsmn
aac8f84fcc Added text underline CSS for DB NULL values when editing / showing data (#2597)
* Added text underline CSS for DB NULL values when editing / showing data
#217

* Changed db nulls styling to italic
2018-09-18 13:35:52 -07:00
Karl Burtram
83384e13f8 Switch off "preview feature" prompt 2018-09-18 12:35:28 -07:00
Karl Burtram
d32f8c40b0 Update version to 0.32.9 2018-09-17 18:15:09 -07:00
22 changed files with 709 additions and 50 deletions

View File

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

View File

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

View File

@@ -61,6 +61,8 @@ export class TabbedPanel extends Disposable implements IThemable {
private _onTabChange = new Emitter<PanelTabIdentifier>();
public onTabChange: Event<PanelTabIdentifier> = this._onTabChange.event;
private tabHistory: string[] = [];
constructor(private container: HTMLElement, private options: IPanelOptions = defaultOptions) {
super();
this.$parent = this._register($('.tabbedPanel'));
@@ -152,6 +154,7 @@ export class TabbedPanel extends Disposable implements IThemable {
}
this._shownTab = id;
this.tabHistory.push(id);
this.$body.clearChildren();
let tab = this._tabMap.get(this._shownTab);
this.$body.attr('aria-labelledby', tab.identifier);
@@ -173,6 +176,26 @@ export class TabbedPanel extends Disposable implements IThemable {
}
this._tabMap.get(tab).header.destroy();
this._tabMap.delete(tab);
if (this._shownTab === tab) {
this._shownTab = undefined;
while (this._shownTab === undefined && this.tabHistory.length > 0) {
let lastTab = this.tabHistory.shift();
if (this._tabMap.get(lastTab)) {
this.showTab(lastTab);
}
}
// this shouldn't happen but just in case
if (this._shownTab === undefined && this._tabMap.size > 0) {
this.showTab(this._tabMap.keys().next().value);
}
}
if (!this.options.showHeaderWhenSingleView && this._tabMap.size === 1 && this._headerVisible) {
this.$header.offDOM();
this._headerVisible = false;
this.layout(this._currentDimensions);
}
}
public style(styles: IPanelStyles): void {

View File

@@ -104,6 +104,11 @@ classes should alter those!
white-space: nowrap;
cursor: default;
}
.slick-cell .grid-cell-value-container.missing-value {
font-style: italic;
}
.slick-cell, .slick-headerrow-column{
border-bottom-color: silver;
}

View File

@@ -22,6 +22,7 @@ import TextComponent from './text.component';
import LoadingComponent from './loadingComponent.component';
import FileBrowserTreeComponent from './fileBrowserTree.component';
import EditorComponent from './editor.component';
import DomComponent from './dom.component';
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
@@ -85,3 +86,6 @@ registerComponentType(FILEBROWSERTREE_COMPONENT, ModelComponentTypes.FileBrowser
export const EDITOR_COMPONENT = 'editor-component';
registerComponentType(EDITOR_COMPONENT, ModelComponentTypes.Editor, EditorComponent);
export const DOM_COMPONENT = 'dom-component';
registerComponentType(DOM_COMPONENT, ModelComponentTypes.Dom, DomComponent);

View File

@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* 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!./dom';
import 'vs/css!./highlight';
import 'vs/css!./markdown';
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList
} from '@angular/core';
import * as sqlops from 'sqlops';
import * as DOM from 'vs/base/browser/dom';
import { $, Builder } from 'vs/base/browser/builder';
import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
@Component({
template: '',
selector: 'modelview-dom-component'
})
export default class DomComponent extends ComponentBase implements IComponent, OnDestroy {
@Input() descriptor: IComponentDescriptor;
@Input() modelStore: IModelStore;
private _renderedHtml: string;
private _rootElement: Builder;
private _bodyElement: Builder;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef, el);
}
ngOnInit(): void {
this.baseInit();
this.createDomElement();
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => {
this.layout();
}));
}
ngOnDestroy(): void {
this.baseDestroy();
}
private createDomElement() {
this._rootElement = new Builder(this._el.nativeElement);
this._bodyElement = $('.dom-body');
this._rootElement.append(this._bodyElement);
}
/// Dom Functions
private setHtml(): void {
if (this.html) {
this._renderedHtml = this.html;
this._bodyElement.innerHtml(this._renderedHtml);
}
}
/// IComponent implementation
public layout(): void {
super.layout();
let element = <HTMLElement>this._el.nativeElement;
element.style.width = this.getWidth();
element.style.height = this.getHeight();
}
public setLayout(layout: any): void {
// TODO allow configuring the look and feel
this.layout();
}
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
if (this.html !== this._renderedHtml) {
this.setHtml();
}
}
// CSS-bound properties
public get html(): string {
return this.getPropertyOrDefault<sqlops.DomProperties, string>((props) => props.html, '');
}
public set html(newValue: string) {
this.setPropertyFromUI<sqlops.DomProperties, string>((properties, html) => { properties.html = html; }, newValue);
}
}

View File

@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
modelview-dom-component {
display: block;
-webkit-user-select: text;
}

View File

@@ -0,0 +1,183 @@
/*
https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs2015.css
*/
/*
* Visual Studio 2015 dark style
* Author: Nicolas LLOBERA <nllobera@gmail.com>
*/
modelview-dom-component .hljs-keyword,
modelview-dom-component .hljs-literal,
modelview-dom-component .hljs-symbol,
modelview-dom-component .hljs-name {
color: #569CD6;
}
modelview-dom-component .hljs-link {
color: #569CD6;
text-decoration: underline;
}
modelview-dom-component .hljs-built_in,
modelview-dom-component .hljs-type {
color: #4EC9B0;
}
modelview-dom-component .hljs-number,
modelview-dom-component .hljs-class {
color: #B8D7A3;
}
modelview-dom-component .hljs-string,
modelview-dom-component .hljs-meta-string {
color: #D69D85;
}
modelview-dom-component .hljs-regexp,
modelview-dom-component .hljs-template-tag {
color: #9A5334;
}
modelview-dom-component .hljs-subst,
modelview-dom-component .hljs-function,
modelview-dom-component .hljs-title,
modelview-dom-component .hljs-params,
modelview-dom-component .hljs-formula {
color: #DCDCDC;
}
modelview-dom-component .hljs-comment,
modelview-dom-component .hljs-quote {
color: #57A64A;
font-style: italic;
}
modelview-dom-component .hljs-doctag {
color: #608B4E;
}
modelview-dom-component .hljs-meta,
modelview-dom-component .hljs-meta-keyword,
modelview-dom-component .hljs-tag {
color: #9B9B9B;
}
modelview-dom-component .hljs-variable,
modelview-dom-component .hljs-template-variable {
color: #BD63C5;
}
modelview-dom-component .hljs-attr,
modelview-dom-component .hljs-attribute,
modelview-dom-component .hljs-builtin-name {
color: #9CDCFE;
}
modelview-dom-component .hljs-section {
color: gold;
}
modelview-dom-component .hljs-emphasis {
font-style: italic;
}
modelview-dom-component .hljs-strong {
font-weight: bold;
}
/*.hljs-code {
font-family:'Monospace';
}*/
modelview-dom-component .hljs-bullet,
modelview-dom-component .hljs-selector-tag,
modelview-dom-component .hljs-selector-id,
modelview-dom-component .hljs-selector-class,
modelview-dom-component .hljs-selector-attr,
modelview-dom-component .hljs-selector-pseudo {
color: #D7BA7D;
}
modelview-dom-component .hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}
modelview-dom-component .hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}
/*
From https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs.css
*/
/*
Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name>
*/
/*
.vscode-light .hljs-function,
.vscode-light .hljs-params {
color: inherit;
}
.vscode-light .hljs-comment,
.vscode-light .hljs-quote,
.vscode-light .hljs-variable {
color: #008000;
}
.vscode-light .hljs-keyword,
.vscode-light .hljs-selector-tag,
.vscode-light .hljs-built_in,
.vscode-light .hljs-name,
.vscode-light .hljs-tag {
color: #00f;
}
.vscode-light .hljs-string,
.vscode-light .hljs-title,
.vscode-light .hljs-section,
.vscode-light .hljs-attribute,
.vscode-light .hljs-literal,
.vscode-light .hljs-template-tag,
.vscode-light .hljs-template-variable,
.vscode-light .hljs-type,
.vscode-light .hljs-addition {
color: #a31515;
}
.vscode-light .hljs-deletion,
.vscode-light .hljs-selector-attr,
.vscode-light .hljs-selector-pseudo,
.vscode-light .hljs-meta {
color: #2b91af;
}
.vscode-light .hljs-doctag {
color: #808080;
}
.vscode-light .hljs-attr {
color: #f00;
}
.vscode-light .hljs-symbol,
.vscode-light .hljs-bullet,
.vscode-light .hljs-link {
color: #00b0e8;
}
.vscode-light .hljs-emphasis {
font-style: italic;
}
.vscode-light .hljs-strong {
font-weight: bold;
}
*/

View File

@@ -0,0 +1,239 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
modelview-dom-component {
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
font-size: 14px;
padding: 0 26px;
line-height: 22px;
word-wrap: break-word;
}
modelview-dom-component #code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
modelview-dom-component #code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
modelview-dom-component .scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
modelview-dom-component .showEditorSelection .code-line {
position: relative;
}
modelview-dom-component .showEditorSelection .code-active-line:before,
modelview-dom-component .showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
modelview-dom-component .showEditorSelection li.code-active-line:before,
modelview-dom-component .showEditorSelection li.code-line:hover:before {
left: -30px;
}
modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.hc-black modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.hc-black modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
modelview-dom-component img {
max-width: 100%;
max-height: 100%;
}
modelview-dom-component a, a:link{
text-decoration: none;
color: rgb(0, 0, 238) !important;
}
modelview-dom-component a:hover, a:link {
text-decoration: underline;
}
modelview-dom-component a:focus,
modelview-dom-component input:focus,
modelview-dom-component select:focus,
modelview-dom-component textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
modelview-dom-component hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
modelview-dom-component h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
}
modelview-dom-component h1,
modelview-dom-component h2,
modelview-dom-component h3 {
font-weight: normal;
}
modelview-dom-component h1 code,
modelview-dom-component h2 code,
modelview-dom-component h3 code,
modelview-dom-component h4 code,
modelview-dom-component h5 code,
modelview-dom-component h6 code {
font-size: inherit;
line-height: auto;
}
modelview-dom-component table {
border-collapse: collapse;
}
modelview-dom-component table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
modelview-dom-component table > thead > tr > th,
modelview-dom-component table > thead > tr > td,
modelview-dom-component table > tbody > tr > th,
modelview-dom-component table > tbody > tr > td {
padding: 5px 10px;
}
modelview-dom-component table > tbody > tr + tr > td {
border-top: 1px solid;
}
modelview-dom-component blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left-width: 5px;
border-left-style: solid;
}
modelview-dom-component code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 14px;
line-height: 19px;
}
modelview-dom-component .wordWrap pre {
white-space: pre-wrap;
}
modelview-dom-component .mac code {
font-size: 12px;
line-height: 18px;
}
modelview-dom-component pre:not(.hljs),
modelview-dom-component pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
/** Theming */
modelview-dom-component pre code {
color: var(--vscode-editor-foreground);
}
modelview-dom-component pre {
background-color: rgba(220, 220, 220, 0.4);
}
.vs-dark .monaco-workbench modelview-dom-component pre {
background-color: rgba(10, 10, 10, 0.4);
}
.hc-black .monaco-workbench modelview-dom-component pre {
background-color: rgb(0, 0, 0);
}
.hc-black .monaco-workbench modelview-dom-component h1 {
border-color: rgb(0, 0, 0);
}
modelview-dom-component table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vs-dark .monaco-workbench modelview-dom-component table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
modelview-dom-component h1,
modelview-dom-component hr,
modelview-dom-component table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vs-dark .monaco-workbench modelview-dom-component h1,
.vs-dark .monaco-workbench modelview-dom-component hr,
.vs-dark .monaco-workbench modelview-dom-component table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}

View File

@@ -7,7 +7,7 @@
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ITree, IDataSource } from 'vs/base/parts/tree/browser/tree';
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
import { TreeNode, TreeItemCollapsibleState } from 'sql/parts/objectExplorer/common/treeNode';
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import { TPromise } from 'vs/base/common/winjs.base';
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
@@ -72,9 +72,13 @@ export class ServerTreeDataSource implements IDataSource {
if (node.children) {
resolve(node.children);
} else {
// These similar changes are probably needed for a ConnectionProfile group element as well. However, we do not have a repro of a failiure in that scenario so they will be tackled in a future checkin.
// It has been tested for connecting to the server in profile itself and things work fine there.
this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node).then(() => {
resolve(node.children);
}, expandError => {
node.setExpandedState(TreeItemCollapsibleState.Collapsed);
node.errorStateMessage = expandError;
this.showError(expandError);
resolve([]);
});

View File

@@ -223,5 +223,4 @@ export class ShowQueryPlanAction extends Action {
return TPromise.as(false);
}
}
}

View File

@@ -553,8 +553,11 @@ class GridTable<T> extends Disposable implements IView {
private loadData(offset: number, count: number): Thenable<T[]> {
return this.runner.getQueryRows(offset, count, this.resultSet.batchId, this.resultSet.id).then(response => {
if (this.runner.isQueryPlan) {
// it's a show plan response
if (response.resultSubset.rowCount === 1) {
this.instantiationService.createInstance(ShowQueryPlanAction).run(response.resultSubset.rows[0][0].displayValue);
}
}
return response.resultSubset.rows.map(r => {
let dataWithSchema = {};
// skip the first column since its a number column

View File

@@ -377,6 +377,26 @@ export class QueryEditor extends BaseEditor {
return undefined;
}
public getAllSelection(): ISelectionData {
if (this._sqlEditor && this._sqlEditor.getControl()) {
let control = this._sqlEditor.getControl();
let codeEditor: ICodeEditor = <ICodeEditor>control;
if (codeEditor) {
let model = codeEditor.getModel();
let totalLines = model.getLineCount();
let endColumn = model.getLineMaxColumn(totalLines);
let selection: ISelectionData = {
startLine: 0,
startColumn: 0,
endLine: totalLines - 1,
endColumn: endColumn - 1,
};
return selection;
}
}
return undefined;
}
public getSelectionText(): string {
if (this._sqlEditor && this._sqlEditor.getControl()) {
let control = this._sqlEditor.getControl();

View File

@@ -18,6 +18,7 @@ import { PanelViewlet } from 'vs/workbench/browser/parts/views/panelViewlet';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import * as DOM from 'vs/base/browser/dom';
import { once, anyEvent } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
class ResultsView implements IPanelView {
private panelViewlet: PanelViewlet;
@@ -155,6 +156,8 @@ export class QueryResultsView {
private chartTab: ChartTab;
private qpTab: QueryPlanTab;
private runnerDisposables: IDisposable[];
constructor(
container: HTMLElement,
@IInstantiationService instantiationService: IInstantiationService,
@@ -177,12 +180,20 @@ export class QueryResultsView {
public set input(input: QueryResultsInput) {
this._input = input;
dispose(this.runnerDisposables);
this.runnerDisposables = [];
this.resultsTab.view.state = this.input.state;
this.qpTab.view.state = this.input.state.queryPlanState;
this.chartTab.view.state = this.input.state.chartState;
let queryRunner = this.queryModelService._getQueryInfo(input.uri).queryRunner;
this.resultsTab.queryRunner = queryRunner;
this.chartTab.queryRunner = queryRunner;
this.runnerDisposables.push(queryRunner.onQueryStart(e => {
this.hideChart();
this.hidePlan();
this.input.state.visibleTabs = new Set();
this.input.state.activeTab = this.resultsTab.identifier;
}));
if (this.input.state.visibleTabs.has(this.chartTab.identifier)) {
if (!this._panelView.contains(this.chartTab)) {
this._panelView.pushTab(this.chartTab);
@@ -220,6 +231,12 @@ export class QueryResultsView {
this.chartTab.chart(dataId);
}
public hideChart() {
if (this._panelView.contains(this.chartTab)) {
this._panelView.removeTab(this.chartTab.identifier);
}
}
public showPlan(xml: string) {
this.input.state.visibleTabs.add(this.qpTab.identifier);
if (!this._panelView.contains(this.qpTab)) {
@@ -229,4 +246,10 @@ export class QueryResultsView {
this._panelView.showTab(this.qpTab.identifier);
this.qpTab.view.showPlan(xml);
}
public hidePlan() {
if (this._panelView.contains(this.qpTab)) {
this._panelView.removeTab(this.qpTab.identifier);
}
}
}

View File

@@ -271,7 +271,11 @@ export class ActualQueryPlanAction extends QueryTaskbarAction {
}
if (this.isConnected(editor)) {
editor.currentQueryInput.runQuery(editor.getSelection(), {
let selection = editor.getSelection();
if (!selection) {
selection = editor.getAllSelection();
}
editor.currentQueryInput.runQuery(selection, {
displayActualQueryPlan: true
});
}

View File

@@ -42,7 +42,6 @@ export class QueryPlanView implements IPanelView {
}
container.appendChild(this.container);
container.style.overflow = 'scroll';
container.style.background = '#FFFFFF';
}
public layout(dimension: Dimension): void {

View File

@@ -19,6 +19,7 @@ declare module 'sqlops' {
navContainer(): ContainerBuilder<NavContainer, any, any>;
divContainer(): DivBuilder;
flexContainer(): FlexBuilder;
dom(): ComponentBuilder<DomComponent>
card(): ComponentBuilder<CardComponent>;
inputBox(): ComponentBuilder<InputBoxComponent>;
checkBox(): ComponentBuilder<CheckBoxComponent>;
@@ -575,6 +576,13 @@ declare module 'sqlops' {
options?: vscode.WebviewOptions;
}
export interface DomProperties extends ComponentProperties {
/**
* Contents of the DOM component.
*/
html?: string;
}
/**
* Editor properties for the editor component
*/
@@ -618,6 +626,10 @@ declare module 'sqlops' {
onCardSelectedChanged: vscode.Event<any>;
}
export interface DomComponent extends Component, DomProperties {
}
export interface TextComponent extends Component {
value: string;
}

View File

@@ -152,7 +152,8 @@ export enum ModelComponentTypes {
LoadingComponent,
TreeComponent,
FileBrowserTree,
Editor
Editor,
Dom
}
export interface IComponentShape {

View File

@@ -191,6 +191,13 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
return builder;
}
dom(): sqlops.ComponentBuilder<sqlops.DomComponent> {
let id = this.getNextComponentId();
let builder: ComponentBuilderImpl<sqlops.DomComponent> = this.getComponentBuilder(new DomComponentWrapper(this._proxy, this._handle, id), id);
this._componentBuilders.set(id, builder);
return builder;
}
getComponentBuilder<T extends sqlops.Component>(component: ComponentWrapper, id: string): ComponentBuilderImpl<T> {
let componentBuilder: ComponentBuilderImpl<T> = new ComponentBuilderImpl<T>(component);
this._componentBuilders.set(id, componentBuilder);
@@ -840,8 +847,8 @@ class WebViewWrapper extends ComponentWrapper implements sqlops.WebViewComponent
public get html(): string {
return this.properties['html'];
}
public set html(v: string) {
this.setProperty('html', v);
public set html(html: string) {
this.setProperty('html', html);
}
public get onMessage(): vscode.Event<any> {
@@ -857,6 +864,21 @@ class WebViewWrapper extends ComponentWrapper implements sqlops.WebViewComponent
}
}
class DomComponentWrapper extends ComponentWrapper implements sqlops.DomComponent {
constructor(proxy: MainThreadModelViewShape, handle: number, id: string) {
super(proxy, handle, ModelComponentTypes.Dom, id);
this.properties = {};
}
public get html(): string {
return this.properties['html'];
}
public set html(html: string) {
this.setProperty('html', html);
}
}
class EditorWrapper extends ComponentWrapper implements sqlops.EditorComponent {
constructor(proxy: MainThreadModelViewShape, handle: number, id: string) {
super(proxy, handle, ModelComponentTypes.Editor, id);

View File

@@ -32,7 +32,7 @@ Registry.as<IConfigurationRegistry>(ConfigExtensions.Configuration).registerConf
'properties': {
'workbench.enablePreviewFeatures': {
'type': 'boolean',
'default': undefined,
'default': true,
'description': nls.localize('previewFeatures.configEnable', 'Enable unreleased preview features')
}
}

View File

@@ -27,44 +27,46 @@ export class EnablePreviewFeatures implements IWorkbenchContribution {
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService
) {
let previewFeaturesEnabled = configurationService.getValue('workbench')['enablePreviewFeatures'];
if (previewFeaturesEnabled || storageService.get(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN)) {
return;
}
Promise.all([
windowService.isFocused(),
windowsService.getWindowCount()
]).then(([focused, count]) => {
if (!focused && count > 1) {
return null;
}
configurationService.updateValue('workbench.enablePreviewFeatures', false);
const enablePreviewFeaturesNotice = localize('enablePreviewFeatures.notice', "Would you like to enable preview features?");
notificationService.prompt(
Severity.Info,
enablePreviewFeaturesNotice,
[{
label: localize('enablePreviewFeatures.yes', "Yes"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', true);
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
}
}, {
label: localize('enablePreviewFeatures.no', "No"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', false);
}
}, {
label: localize('enablePreviewFeatures.never', "No, don't show again"),
run: () => {
configurationService.updateValue('workbench.enablePreviewFeatures', false);
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
},
isSecondary: true
}]
);
})
.then(null, onUnexpectedError);
// let previewFeaturesEnabled = configurationService.getValue('workbench')['enablePreviewFeatures'];
// if (previewFeaturesEnabled || storageService.get(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN)) {
// return;
// }
// Promise.all([
// windowService.isFocused(),
// windowsService.getWindowCount()
// ]).then(([focused, count]) => {
// if (!focused && count > 1) {
// return null;
// }
// configurationService.updateValue('workbench.enablePreviewFeatures', false);
// const enablePreviewFeaturesNotice = localize('enablePreviewFeatures.notice', "Would you like to enable preview features?");
// notificationService.prompt(
// Severity.Info,
// enablePreviewFeaturesNotice,
// [{
// label: localize('enablePreviewFeatures.yes', "Yes"),
// run: () => {
// configurationService.updateValue('workbench.enablePreviewFeatures', true);
// storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
// }
// }, {
// label: localize('enablePreviewFeatures.no', "No"),
// run: () => {
// configurationService.updateValue('workbench.enablePreviewFeatures', false);
// }
// }, {
// label: localize('enablePreviewFeatures.never', "No, don't show again"),
// run: () => {
// configurationService.updateValue('workbench.enablePreviewFeatures', false);
// storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
// },
// isSecondary: true
// }]
// );
// })
// .then(null, onUnexpectedError);
}
}

View File

@@ -12,6 +12,8 @@ import { INavigator } from 'vs/base/common/iterator';
import * as WinJS from 'vs/base/common/winjs.base';
import * as _ from './tree';
import { Event, Emitter, once, EventMultiplexer, Relay } from 'vs/base/common/event';
// {{SQL CARBON EDIT}}
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
interface IMap<T> { [id: string]: T; }
interface IItemMap extends IMap<Item> { }
@@ -359,6 +361,12 @@ export class Item {
return WinJS.TPromise.as(false);
}
// {{SQL CARBON EDIT}} - Original code does not handle the need to refresh children in case previous refreshchildren errored out.
// resetting the errorStateMessage before we refresh children so we can track if there has been error in processing.
if (this.element instanceof TreeNode) {
this.element.errorStateMessage = null;
}
var result = this.lock.run(this, () => {
var eventData: IItemExpandEvent = { item: this };
var result: WinJS.Promise;
@@ -373,7 +381,14 @@ export class Item {
return result.then(() => {
this._setExpanded(true);
this._onDidExpand.fire(eventData);
// {{SQL CARBON EDIT}} - Original code does not handle the need to refresh children in case previous refreshchildren errored out.
if ((this.element instanceof TreeNode) && (this.element.errorStateMessage)) {
this.needsChildrenRefresh = true;
return false;
} // We may need special handling for other types of this.element apart from TreeNode as well.
else {
return true;
}
});
});