mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
table designer validation support (#18438)
* table designer validation * vbump sts
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||||
"version": "3.0.0-release.204",
|
"version": "3.0.0-release.206",
|
||||||
"downloadFileNames": {
|
"downloadFileNames": {
|
||||||
"Windows_86": "win-x86-net6.0.zip",
|
"Windows_86": "win-x86-net6.0.zip",
|
||||||
"Windows_64": "win-x64-net6.0.zip",
|
"Windows_64": "win-x64-net6.0.zip",
|
||||||
|
|||||||
2
src/sql/azdata.proposed.d.ts
vendored
2
src/sql/azdata.proposed.d.ts
vendored
@@ -1425,7 +1425,7 @@ declare module 'azdata' {
|
|||||||
/**
|
/**
|
||||||
* Error messages of current state, and the property the caused the error.
|
* Error messages of current state, and the property the caused the error.
|
||||||
*/
|
*/
|
||||||
errors?: { message: string, property?: DesignerEditPath }[];
|
errors?: { message: string, propertyPath?: DesignerEditPath }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ export class TabbedPanel extends Disposable {
|
|||||||
this._styleElement.remove();
|
this._styleElement.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public contains(tab: IPanelTab): boolean {
|
public contains(tabId: string): boolean {
|
||||||
return this._tabMap.has(tab.identifier);
|
return this._tabMap.has(tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public pushTab(tab: IPanelTab, index?: number, destroyTabBody?: boolean): PanelTabIdentifier {
|
public pushTab(tab: IPanelTab, index?: number, destroyTabBody?: boolean): PanelTabIdentifier {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import {
|
import {
|
||||||
DesignerComponentInput, DesignerEditType, DesignerTab, DesignerEdit, DesignerEditPath, DesignerViewModel, DesignerDataPropertyInfo,
|
DesignerComponentInput, DesignerEditType, DesignerTab, DesignerEdit, DesignerEditPath, DesignerViewModel, DesignerDataPropertyInfo,
|
||||||
DesignerTableComponentRowData, DesignerTableProperties, InputBoxProperties, DropDownProperties, CheckBoxProperties,
|
DesignerTableComponentRowData, DesignerTableProperties, InputBoxProperties, DropDownProperties, CheckBoxProperties,
|
||||||
DesignerEditProcessedEventArgs, DesignerStateChangedEventArgs, DesignerAction, DesignerUIState, DesignerTextEditor, ScriptProperty, DesignerRootObjectPath
|
DesignerEditProcessedEventArgs, DesignerStateChangedEventArgs, DesignerAction, DesignerUIState, ScriptProperty, DesignerRootObjectPath
|
||||||
}
|
}
|
||||||
from 'sql/workbench/browser/designer/interfaces';
|
from 'sql/workbench/browser/designer/interfaces';
|
||||||
import { IPanelTab, ITabbedPanelStyles, TabbedPanel } from 'sql/base/browser/ui/panel/panel';
|
import { IPanelTab, ITabbedPanelStyles, TabbedPanel } from 'sql/base/browser/ui/panel/panel';
|
||||||
@@ -34,9 +34,10 @@ import { Color } from 'vs/base/common/color';
|
|||||||
import { LoadingSpinner } from 'sql/base/browser/ui/loadingSpinner/loadingSpinner';
|
import { LoadingSpinner } from 'sql/base/browser/ui/loadingSpinner/loadingSpinner';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { DesignerScriptEditor } from 'sql/workbench/browser/designer/designerScriptEditor';
|
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
|
import { DesignerMessagesTabPanelView } from 'sql/workbench/browser/designer/designerMessagesTabPanelView';
|
||||||
|
import { DesignerScriptEditorTabPanelView } from 'sql/workbench/browser/designer/designerScriptEditorTabPanelView';
|
||||||
|
|
||||||
export interface IDesignerStyle {
|
export interface IDesignerStyle {
|
||||||
tabbedPanelStyles?: ITabbedPanelStyles;
|
tabbedPanelStyles?: ITabbedPanelStyles;
|
||||||
@@ -56,6 +57,8 @@ export type SetComponentValueFunc = (definition: DesignerDataPropertyInfo, compo
|
|||||||
|
|
||||||
const TableRowHeight = 25;
|
const TableRowHeight = 25;
|
||||||
const TableHeaderRowHeight = 28;
|
const TableHeaderRowHeight = 28;
|
||||||
|
const ScriptTabId = 'scripts';
|
||||||
|
const MessagesTabId = 'messages';
|
||||||
|
|
||||||
type DesignerUIArea = 'PropertiesView' | 'ScriptView' | 'TopContentView' | 'TabsView';
|
type DesignerUIArea = 'PropertiesView' | 'ScriptView' | 'TopContentView' | 'TabsView';
|
||||||
|
|
||||||
@@ -67,7 +70,8 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
private _editorContainer: HTMLElement;
|
private _editorContainer: HTMLElement;
|
||||||
private _horizontalSplitView: SplitView;
|
private _horizontalSplitView: SplitView;
|
||||||
private _verticalSplitView: SplitView;
|
private _verticalSplitView: SplitView;
|
||||||
private _tabbedPanel: TabbedPanel;
|
private _contentTabbedPanel: TabbedPanel;
|
||||||
|
private _scriptTabbedPannel: TabbedPanel;
|
||||||
private _contentContainer: HTMLElement;
|
private _contentContainer: HTMLElement;
|
||||||
private _topContentContainer: HTMLElement;
|
private _topContentContainer: HTMLElement;
|
||||||
private _propertiesPaneContainer: HTMLElement;
|
private _propertiesPaneContainer: HTMLElement;
|
||||||
@@ -81,7 +85,8 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
private _inputDisposable: DisposableStore;
|
private _inputDisposable: DisposableStore;
|
||||||
private _loadingTimeoutHandle: any;
|
private _loadingTimeoutHandle: any;
|
||||||
private _groupHeaders: HTMLElement[] = [];
|
private _groupHeaders: HTMLElement[] = [];
|
||||||
private _textEditor: DesignerTextEditor;
|
private _messagesView: DesignerMessagesTabPanelView;
|
||||||
|
private _scriptEditorView: DesignerScriptEditorTabPanelView;
|
||||||
|
|
||||||
constructor(private readonly _container: HTMLElement,
|
constructor(private readonly _container: HTMLElement,
|
||||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||||
@@ -119,7 +124,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
this._propertiesPaneContainer = DOM.$('.properties-container');
|
this._propertiesPaneContainer = DOM.$('.properties-container');
|
||||||
this._verticalSplitView = new SplitView(this._verticalSplitViewContainer, { orientation: Orientation.VERTICAL });
|
this._verticalSplitView = new SplitView(this._verticalSplitViewContainer, { orientation: Orientation.VERTICAL });
|
||||||
this._horizontalSplitView = new SplitView(this._horizontalSplitViewContainer, { orientation: Orientation.HORIZONTAL });
|
this._horizontalSplitView = new SplitView(this._horizontalSplitViewContainer, { orientation: Orientation.HORIZONTAL });
|
||||||
this._tabbedPanel = new TabbedPanel(this._tabbedPanelContainer);
|
this._contentTabbedPanel = new TabbedPanel(this._tabbedPanelContainer);
|
||||||
this._container.appendChild(this._verticalSplitViewContainer);
|
this._container.appendChild(this._verticalSplitViewContainer);
|
||||||
this._contentContainer.appendChild(this._topContentContainer);
|
this._contentContainer.appendChild(this._topContentContainer);
|
||||||
this._contentContainer.appendChild(this._tabbedPanelContainer);
|
this._contentContainer.appendChild(this._tabbedPanelContainer);
|
||||||
@@ -132,11 +137,18 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
maximumSize: Number.POSITIVE_INFINITY,
|
maximumSize: Number.POSITIVE_INFINITY,
|
||||||
onDidChange: Event.None
|
onDidChange: Event.None
|
||||||
}, Sizing.Distribute);
|
}, Sizing.Distribute);
|
||||||
this._textEditor = this._instantiationService.createInstance(DesignerScriptEditor, this._editorContainer);
|
this._scriptTabbedPannel = new TabbedPanel(this._editorContainer);
|
||||||
|
this._messagesView = new DesignerMessagesTabPanelView();
|
||||||
|
this._scriptEditorView = new DesignerScriptEditorTabPanelView(this._instantiationService);
|
||||||
|
this._scriptTabbedPannel.pushTab({
|
||||||
|
title: localize('designer.scriptTabTitle', "Scripts"),
|
||||||
|
identifier: ScriptTabId,
|
||||||
|
view: this._scriptEditorView
|
||||||
|
});
|
||||||
this._verticalSplitView.addView({
|
this._verticalSplitView.addView({
|
||||||
element: this._editorContainer,
|
element: this._editorContainer,
|
||||||
layout: size => {
|
layout: size => {
|
||||||
this._textEditor.layout(new DOM.Dimension(this._editorContainer.clientWidth, size));
|
this._scriptTabbedPannel.layout(new DOM.Dimension(this._editorContainer.clientWidth, size - this._scriptTabbedPannel.headersize));
|
||||||
},
|
},
|
||||||
minimumSize: 100,
|
minimumSize: 100,
|
||||||
maximumSize: Number.POSITIVE_INFINITY,
|
maximumSize: Number.POSITIVE_INFINITY,
|
||||||
@@ -163,6 +175,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
onDidChange: Event.None
|
onDidChange: Event.None
|
||||||
}, Sizing.Distribute);
|
}, Sizing.Distribute);
|
||||||
|
|
||||||
|
|
||||||
this._propertiesPane = new DesignerPropertiesPane(this._propertiesPaneContainer, (container, components, parentPath) => {
|
this._propertiesPane = new DesignerPropertiesPane(this._propertiesPaneContainer, (container, components, parentPath) => {
|
||||||
return this.createComponents(container, components, this._propertiesPane.componentMap, this._propertiesPane.groupHeaders, parentPath, 'PropertiesView');
|
return this.createComponents(container, components, this._propertiesPane.componentMap, this._propertiesPane.groupHeaders, parentPath, 'PropertiesView');
|
||||||
}, (definition, component, viewModel) => {
|
}, (definition, component, viewModel) => {
|
||||||
@@ -244,7 +257,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
this._buttons = [];
|
this._buttons = [];
|
||||||
this._componentMap.clear();
|
this._componentMap.clear();
|
||||||
DOM.clearNode(this._topContentContainer);
|
DOM.clearNode(this._topContentContainer);
|
||||||
this._tabbedPanel.clearTabs();
|
this._contentTabbedPanel.clearTabs();
|
||||||
this._propertiesPane.clear();
|
this._propertiesPane.clear();
|
||||||
this._inputDisposable?.dispose();
|
this._inputDisposable?.dispose();
|
||||||
this._groupHeaders = [];
|
this._groupHeaders = [];
|
||||||
@@ -287,7 +300,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
this.createComponents(this._topContentContainer, view.components, this._componentMap, this._groupHeaders, DesignerRootObjectPath, 'TopContentView');
|
this.createComponents(this._topContentContainer, view.components, this._componentMap, this._groupHeaders, DesignerRootObjectPath, 'TopContentView');
|
||||||
}
|
}
|
||||||
view.tabs.forEach(tab => {
|
view.tabs.forEach(tab => {
|
||||||
this._tabbedPanel.pushTab(this.createTabView(tab));
|
this._contentTabbedPanel.pushTab(this.createTabView(tab));
|
||||||
});
|
});
|
||||||
this.layoutTabbedPanel();
|
this.layoutTabbedPanel();
|
||||||
this.updateComponentValues();
|
this.updateComponentValues();
|
||||||
@@ -297,8 +310,6 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
|
|
||||||
private handleEditProcessedEvent(args: DesignerEditProcessedEventArgs): void {
|
private handleEditProcessedEvent(args: DesignerEditProcessedEventArgs): void {
|
||||||
const edit = args.edit;
|
const edit = args.edit;
|
||||||
const result = args.result;
|
|
||||||
if (result.isValid) {
|
|
||||||
this._supressEditProcessing = true;
|
this._supressEditProcessing = true;
|
||||||
try {
|
try {
|
||||||
this.updateComponentValues();
|
this.updateComponentValues();
|
||||||
@@ -330,9 +341,6 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
this._notificationService.error(err);
|
this._notificationService.error(err);
|
||||||
}
|
}
|
||||||
this._supressEditProcessing = false;
|
this._supressEditProcessing = false;
|
||||||
} else {
|
|
||||||
this._notificationService.error(result.errors.map(e => e.message));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleInputStateChangedEvent(args: DesignerStateChangedEventArgs): void {
|
private handleInputStateChangedEvent(args: DesignerStateChangedEventArgs): void {
|
||||||
@@ -378,7 +386,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private layoutTabbedPanel() {
|
private layoutTabbedPanel() {
|
||||||
this._tabbedPanel.layout(new DOM.Dimension(this._tabbedPanelContainer.clientWidth, this._tabbedPanelContainer.clientHeight));
|
this._contentTabbedPanel.layout(new DOM.Dimension(this._tabbedPanelContainer.clientWidth, this._tabbedPanelContainer.clientHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
private layoutPropertiesPane() {
|
private layoutPropertiesPane() {
|
||||||
@@ -431,16 +439,36 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateComponentValues(): void {
|
private updateComponentValues(): void {
|
||||||
|
this.updateMessagesTab();
|
||||||
const viewModel = this._input.viewModel;
|
const viewModel = this._input.viewModel;
|
||||||
const scriptProperty = viewModel[ScriptProperty] as InputBoxProperties;
|
const scriptProperty = viewModel[ScriptProperty] as InputBoxProperties;
|
||||||
if (scriptProperty) {
|
if (scriptProperty) {
|
||||||
this._textEditor.content = scriptProperty.value || '';
|
this._scriptEditorView.content = scriptProperty.value || '';
|
||||||
}
|
}
|
||||||
this._componentMap.forEach((value) => {
|
this._componentMap.forEach((value) => {
|
||||||
this.setComponentValue(value.defintion, value.component, viewModel);
|
this.setComponentValue(value.defintion, value.component, viewModel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateMessagesTab(): void {
|
||||||
|
if (!this._input) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this._scriptTabbedPannel.contains(MessagesTabId)) {
|
||||||
|
this._scriptTabbedPannel.removeTab(MessagesTabId);
|
||||||
|
}
|
||||||
|
if (this._input.validationErrors === undefined || this._input.validationErrors.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._scriptTabbedPannel.pushTab({
|
||||||
|
title: localize('designer.messagesTabTitle', "Errors ({0})", this._input.validationErrors.length),
|
||||||
|
identifier: MessagesTabId,
|
||||||
|
view: this._messagesView
|
||||||
|
});
|
||||||
|
this._scriptTabbedPannel.showTab(MessagesTabId);
|
||||||
|
this._messagesView.updateMessages(this._input.validationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
private handleEdit(edit: DesignerEdit): void {
|
private handleEdit(edit: DesignerEdit): void {
|
||||||
if (this._supressEditProcessing) {
|
if (this._supressEditProcessing) {
|
||||||
return;
|
return;
|
||||||
@@ -791,13 +819,13 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
|
|
||||||
private getUIState(): DesignerUIState {
|
private getUIState(): DesignerUIState {
|
||||||
return {
|
return {
|
||||||
activeTabId: this._tabbedPanel.activeTabId
|
activeTabId: this._contentTabbedPanel.activeTabId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private restoreUIState(): void {
|
private restoreUIState(): void {
|
||||||
if (this._input.designerUIState) {
|
if (this._input.designerUIState) {
|
||||||
this._tabbedPanel.showTab(this._input.designerUIState.activeTabId);
|
this._contentTabbedPanel.showTab(this._input.designerUIState.activeTabId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IPanelView } from 'sql/base/browser/ui/panel/panel';
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
|
import { DesignerValidationError } from 'sql/workbench/browser/designer/interfaces';
|
||||||
|
|
||||||
|
export class DesignerMessagesTabPanelView extends Disposable implements IPanelView {
|
||||||
|
private _container: HTMLElement;
|
||||||
|
|
||||||
|
render(container: HTMLElement): void {
|
||||||
|
this._container = container.appendChild(DOM.$('.messages-container'));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(dimension: DOM.Dimension): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMessages(errors: DesignerValidationError[]) {
|
||||||
|
if (this._container) {
|
||||||
|
DOM.clearNode(this._container);
|
||||||
|
errors?.forEach(error => {
|
||||||
|
const messageItem = this._container.appendChild(DOM.$('.message-item.codicon.error'));
|
||||||
|
messageItem.innerText = error.message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,9 +84,6 @@ export class DesignerScriptEditor extends BaseTextEditor implements DesignerText
|
|||||||
options.renderIndentGuides = false;
|
options.renderIndentGuides = false;
|
||||||
options.rulers = [];
|
options.rulers = [];
|
||||||
options.glyphMargin = true;
|
options.glyphMargin = true;
|
||||||
options.minimap = {
|
|
||||||
enabled: true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IPanelView } from 'sql/base/browser/ui/panel/panel';
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { DesignerScriptEditor } from 'sql/workbench/browser/designer/designerScriptEditor';
|
||||||
|
|
||||||
|
export class DesignerScriptEditorTabPanelView extends Disposable implements IPanelView {
|
||||||
|
private _textEditor: DesignerScriptEditor;
|
||||||
|
|
||||||
|
constructor(private _instantiationService: IInstantiationService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
render(container: HTMLElement): void {
|
||||||
|
this._textEditor = this._instantiationService.createInstance(DesignerScriptEditor, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(dimension: DOM.Dimension): void {
|
||||||
|
this._textEditor.layout(dimension);
|
||||||
|
}
|
||||||
|
|
||||||
|
set content(content: string) {
|
||||||
|
if (this._textEditor) {
|
||||||
|
this._textEditor.content = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,11 @@ export interface DesignerComponentInput {
|
|||||||
*/
|
*/
|
||||||
readonly viewModel: DesignerViewModel;
|
readonly viewModel: DesignerViewModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the validation errors.
|
||||||
|
*/
|
||||||
|
readonly validationErrors: DesignerValidationError[] | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start initilizing the designer input object.
|
* Start initilizing the designer input object.
|
||||||
*/
|
*/
|
||||||
@@ -210,9 +215,11 @@ export interface DesignerEdit {
|
|||||||
export type DesignerEditPath = (string | number)[];
|
export type DesignerEditPath = (string | number)[];
|
||||||
export const DesignerRootObjectPath: DesignerEditPath = [];
|
export const DesignerRootObjectPath: DesignerEditPath = [];
|
||||||
|
|
||||||
|
export type DesignerValidationError = { message: string, property?: DesignerEditPath };
|
||||||
|
|
||||||
export interface DesignerEditResult {
|
export interface DesignerEditResult {
|
||||||
isValid: boolean;
|
isValid: boolean;
|
||||||
errors?: { message: string, property?: DesignerEditPath }[];
|
errors?: DesignerValidationError[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DesignerTextEditor {
|
export interface DesignerTextEditor {
|
||||||
|
|||||||
@@ -29,6 +29,20 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.designer-component .messages-container {
|
||||||
|
overflow: scroll;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.designer-component .messages-container .message-item {
|
||||||
|
padding: 0px 5px 0px 25px;
|
||||||
|
background-position: 5px center;
|
||||||
|
background-size: 16px 16px;
|
||||||
|
user-select: text;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.designer-component .tabbed-panel-container {
|
.designer-component .tabbed-panel-container {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -257,27 +257,27 @@ export class QueryResultsView extends Disposable {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (this.input?.state.visibleTabs.has(this.chartTab.identifier) && !this._panelView.contains(this.chartTab)) {
|
if (this.input?.state.visibleTabs.has(this.chartTab.identifier) && !this._panelView.contains(this.chartTab.identifier)) {
|
||||||
this._panelView.pushTab(this.chartTab);
|
this._panelView.pushTab(this.chartTab);
|
||||||
} else if (!this.input?.state.visibleTabs.has(this.chartTab.identifier) && this._panelView.contains(this.chartTab)) {
|
} else if (!this.input?.state.visibleTabs.has(this.chartTab.identifier) && this._panelView.contains(this.chartTab.identifier)) {
|
||||||
this._panelView.removeTab(this.chartTab.identifier);
|
this._panelView.removeTab(this.chartTab.identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.input?.state.visibleTabs.has(this.qp2Tab.identifier) && !this._panelView.contains(this.qp2Tab)) {
|
if (this.input?.state.visibleTabs.has(this.qp2Tab.identifier) && !this._panelView.contains(this.qp2Tab.identifier)) {
|
||||||
this._panelView.pushTab(this.qp2Tab);
|
this._panelView.pushTab(this.qp2Tab);
|
||||||
} else if (!this.input?.state.visibleTabs.has(this.qp2Tab.identifier) && this._panelView.contains(this.qp2Tab)) {
|
} else if (!this.input?.state.visibleTabs.has(this.qp2Tab.identifier) && this._panelView.contains(this.qp2Tab.identifier)) {
|
||||||
this._panelView.removeTab(this.qp2Tab.identifier);
|
this._panelView.removeTab(this.qp2Tab.identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.input?.state.visibleTabs.has(this.topOperationsTab.identifier) && !this._panelView.contains(this.topOperationsTab)) {
|
if (this.input?.state.visibleTabs.has(this.topOperationsTab.identifier) && !this._panelView.contains(this.topOperationsTab.identifier)) {
|
||||||
this._panelView.pushTab(this.topOperationsTab);
|
this._panelView.pushTab(this.topOperationsTab);
|
||||||
} else if (!this.input?.state.visibleTabs.has(this.topOperationsTab.identifier) && this._panelView.contains(this.topOperationsTab)) {
|
} else if (!this.input?.state.visibleTabs.has(this.topOperationsTab.identifier) && this._panelView.contains(this.topOperationsTab.identifier)) {
|
||||||
this._panelView.removeTab(this.topOperationsTab.identifier);
|
this._panelView.removeTab(this.topOperationsTab.identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore query model view tabs
|
// restore query model view tabs
|
||||||
this.dynamicModelViewTabs.forEach(tab => {
|
this.dynamicModelViewTabs.forEach(tab => {
|
||||||
if (this._panelView.contains(tab)) {
|
if (this._panelView.contains(tab.identifier)) {
|
||||||
this._panelView.removeTab(tab.identifier);
|
this._panelView.removeTab(tab.identifier);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -291,7 +291,7 @@ export class QueryResultsView extends Disposable {
|
|||||||
let tab = this._register(new QueryModelViewTab(parts[1], this.instantiationService));
|
let tab = this._register(new QueryModelViewTab(parts[1], this.instantiationService));
|
||||||
tab.view.componentId = parts[2];
|
tab.view.componentId = parts[2];
|
||||||
this.dynamicModelViewTabs.push(tab);
|
this.dynamicModelViewTabs.push(tab);
|
||||||
if (!this._panelView.contains(tab)) {
|
if (!this._panelView.contains(tab.identifier)) {
|
||||||
this._panelView.pushTab(tab, undefined, true);
|
this._panelView.pushTab(tab, undefined, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ export class QueryResultsView extends Disposable {
|
|||||||
|
|
||||||
public chartData(dataId: { resultId: number, batchId: number }): void {
|
public chartData(dataId: { resultId: number, batchId: number }): void {
|
||||||
this.input?.state.visibleTabs.add(this.chartTab.identifier);
|
this.input?.state.visibleTabs.add(this.chartTab.identifier);
|
||||||
if (!this._panelView.contains(this.chartTab)) {
|
if (!this._panelView.contains(this.chartTab.identifier)) {
|
||||||
this._panelView.pushTab(this.chartTab);
|
this._panelView.pushTab(this.chartTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,19 +390,19 @@ export class QueryResultsView extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public hideChart() {
|
public hideChart() {
|
||||||
if (this._panelView.contains(this.chartTab)) {
|
if (this._panelView.contains(this.chartTab.identifier)) {
|
||||||
this._panelView.removeTab(this.chartTab.identifier);
|
this._panelView.removeTab(this.chartTab.identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideResults() {
|
public hideResults() {
|
||||||
if (this._panelView.contains(this.resultsTab)) {
|
if (this._panelView.contains(this.resultsTab.identifier)) {
|
||||||
this._panelView.removeTab(this.resultsTab.identifier);
|
this._panelView.removeTab(this.resultsTab.identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public showResults() {
|
public showResults() {
|
||||||
if (!this._panelView.contains(this.resultsTab)) {
|
if (!this._panelView.contains(this.resultsTab.identifier)) {
|
||||||
this._panelView.pushTab(this.resultsTab, 0);
|
this._panelView.pushTab(this.resultsTab, 0);
|
||||||
}
|
}
|
||||||
this._panelView.showTab(this.resultsTab.identifier);
|
this._panelView.showTab(this.resultsTab.identifier);
|
||||||
@@ -410,16 +410,16 @@ export class QueryResultsView extends Disposable {
|
|||||||
|
|
||||||
public showTopOperations(xml: string) {
|
public showTopOperations(xml: string) {
|
||||||
this.input?.state.visibleTabs.add(this.topOperationsTab.identifier);
|
this.input?.state.visibleTabs.add(this.topOperationsTab.identifier);
|
||||||
if (!this._panelView.contains(this.topOperationsTab)) {
|
if (!this._panelView.contains(this.topOperationsTab.identifier)) {
|
||||||
this._panelView.pushTab(this.topOperationsTab);
|
this._panelView.pushTab(this.topOperationsTab);
|
||||||
}
|
}
|
||||||
this.topOperationsTab.view.showPlan(xml);
|
this.topOperationsTab.view.showPlan(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
public showPlan2() {
|
public showPlan2() {
|
||||||
if (!this._panelView.contains(this.qp2Tab)) {
|
if (!this._panelView.contains(this.qp2Tab.identifier)) {
|
||||||
this.input?.state.visibleTabs.add(this.qp2Tab.identifier);
|
this.input?.state.visibleTabs.add(this.qp2Tab.identifier);
|
||||||
if (!this._panelView.contains(this.qp2Tab)) {
|
if (!this._panelView.contains(this.qp2Tab.identifier)) {
|
||||||
this._panelView.pushTab(this.qp2Tab);
|
this._panelView.pushTab(this.qp2Tab);
|
||||||
}
|
}
|
||||||
this._panelView.showTab(this.qp2Tab.identifier);
|
this._panelView.showTab(this.qp2Tab.identifier);
|
||||||
@@ -427,13 +427,13 @@ export class QueryResultsView extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public hideTopOperations() {
|
public hideTopOperations() {
|
||||||
if (this._panelView.contains(this.topOperationsTab)) {
|
if (this._panelView.contains(this.topOperationsTab.identifier)) {
|
||||||
this._panelView.removeTab(this.topOperationsTab.identifier);
|
this._panelView.removeTab(this.topOperationsTab.identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hidePlan2() {
|
public hidePlan2() {
|
||||||
if (this._panelView.contains(this.qp2Tab)) {
|
if (this._panelView.contains(this.qp2Tab.identifier)) {
|
||||||
this.qp2Tab.clear();
|
this.qp2Tab.clear();
|
||||||
this.input.state.queryPlan2State.clearQueryPlan2State();
|
this.input.state.queryPlan2State.clearQueryPlan2State();
|
||||||
this._panelView.removeTab(this.qp2Tab.identifier);
|
this._panelView.removeTab(this.qp2Tab.identifier);
|
||||||
@@ -442,7 +442,7 @@ export class QueryResultsView extends Disposable {
|
|||||||
|
|
||||||
public hideDynamicViewModelTabs() {
|
public hideDynamicViewModelTabs() {
|
||||||
this.dynamicModelViewTabs.forEach(tab => {
|
this.dynamicModelViewTabs.forEach(tab => {
|
||||||
if (this._panelView.contains(tab)) {
|
if (this._panelView.contains(tab.identifier)) {
|
||||||
this._panelView.removeTab(tab.identifier);
|
this._panelView.removeTab(tab.identifier);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -462,7 +462,7 @@ export class QueryResultsView extends Disposable {
|
|||||||
this.dynamicModelViewTabs.push(tab);
|
this.dynamicModelViewTabs.push(tab);
|
||||||
|
|
||||||
this.input?.state.visibleTabs.add('querymodelview;' + title + ';' + componentId);
|
this.input?.state.visibleTabs.add('querymodelview;' + title + ';' + componentId);
|
||||||
if (!this._panelView.contains(tab)) {
|
if (!this._panelView.contains(tab.identifier)) {
|
||||||
this._panelView.pushTab(tab, undefined, true);
|
this._panelView.pushTab(tab, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs, DesignerEditPath } from 'sql/workbench/browser/designer/interfaces';
|
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs, DesignerEditPath, DesignerValidationError } from 'sql/workbench/browser/designer/interfaces';
|
||||||
import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface';
|
import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
@@ -22,6 +22,7 @@ const ErrorDialogTitle: string = localize('tableDesigner.ErrorDialogTitle', "Tab
|
|||||||
export class TableDesignerComponentInput implements DesignerComponentInput {
|
export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||||
|
|
||||||
private _viewModel: DesignerViewModel;
|
private _viewModel: DesignerViewModel;
|
||||||
|
private _validationErrors?: DesignerValidationError[];
|
||||||
private _view: DesignerView;
|
private _view: DesignerView;
|
||||||
private _valid: boolean = true;
|
private _valid: boolean = true;
|
||||||
private _dirty: boolean = false;
|
private _dirty: boolean = false;
|
||||||
@@ -75,6 +76,10 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
return this._viewModel;
|
return this._viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get validationErrors(): DesignerValidationError[] | undefined {
|
||||||
|
return this._validationErrors;
|
||||||
|
}
|
||||||
|
|
||||||
processEdit(edit: DesignerEdit): void {
|
processEdit(edit: DesignerEdit): void {
|
||||||
const telemetryInfo = this.createTelemetryInfo();
|
const telemetryInfo = this.createTelemetryInfo();
|
||||||
telemetryInfo.tableObjectType = this.getObjectTypeFromPath(edit.path);
|
telemetryInfo.tableObjectType = this.getObjectTypeFromPath(edit.path);
|
||||||
@@ -85,6 +90,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
this._provider.processTableEdit(this.tableInfo, edit).then(
|
this._provider.processTableEdit(this.tableInfo, edit).then(
|
||||||
result => {
|
result => {
|
||||||
this._viewModel = result.viewModel;
|
this._viewModel = result.viewModel;
|
||||||
|
this._validationErrors = result.errors;
|
||||||
this.updateState(result.isValid, !equals(this._viewModel, this._originalViewModel), undefined);
|
this.updateState(result.isValid, !equals(this._viewModel, this._originalViewModel), undefined);
|
||||||
|
|
||||||
this._onEditProcessed.fire({
|
this._onEditProcessed.fire({
|
||||||
|
|||||||
Reference in New Issue
Block a user