mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-16 01:25:36 -05:00
table designer new features (#18682)
* support graph tables * ignore script compare * ability to refresh view after edit * reserve focus after refresh view * primary key and default constraint * bug fixes * vbump sts * comments * update type * fix issue
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs, DesignerPropertyPath, DesignerValidationError } from 'sql/workbench/browser/designer/interfaces';
|
||||
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs, DesignerPropertyPath, DesignerValidationError, ScriptProperty } from 'sql/workbench/browser/designer/interfaces';
|
||||
import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface';
|
||||
import { localize } from 'vs/nls';
|
||||
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
@@ -90,14 +90,18 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
this._provider.processTableEdit(this.tableInfo, edit).then(
|
||||
result => {
|
||||
this._viewModel = result.viewModel;
|
||||
if (result.view) {
|
||||
this.setDesignerView(result.view);
|
||||
}
|
||||
this._validationErrors = result.errors;
|
||||
this.updateState(result.isValid, !equals(this._viewModel, this._originalViewModel), undefined);
|
||||
this.updateState(result.isValid, this.isDirty(), undefined);
|
||||
|
||||
this._onEditProcessed.fire({
|
||||
edit: edit,
|
||||
result: {
|
||||
isValid: result.isValid,
|
||||
errors: result.errors
|
||||
errors: result.errors,
|
||||
refreshView: !!result.view
|
||||
}
|
||||
});
|
||||
editAction.withAdditionalMeasurements({
|
||||
@@ -152,6 +156,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
const result = await this._provider.publishChanges(this.tableInfo);
|
||||
this._viewModel = result.viewModel;
|
||||
this._originalViewModel = result.viewModel;
|
||||
this.setDesignerView(result.view);
|
||||
saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeSuccess', "The changes have been successfully published."));
|
||||
this.tableInfo = result.newTableInfo;
|
||||
this.updateState(true, false);
|
||||
@@ -185,7 +190,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
return;
|
||||
}
|
||||
const dialog = this._instantiationService.createInstance(TableDesignerPublishDialog);
|
||||
const result = await dialog.open(report);
|
||||
const result = await dialog.open(<any>report.report);
|
||||
if (result === TableDesignerPublishDialogResult.GenerateScript) {
|
||||
await this.generateScript();
|
||||
} else if (result === TableDesignerPublishDialogResult.UpdateDatabase) {
|
||||
@@ -239,31 +244,35 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
this.updateState(true, this.tableInfo.isNewTable);
|
||||
this._viewModel = designerInfo.viewModel;
|
||||
this._originalViewModel = this.tableInfo.isNewTable ? undefined : deepClone(this._viewModel);
|
||||
this.setDefaultData();
|
||||
this.setDesignerView(designerInfo.view);
|
||||
}
|
||||
|
||||
private setDesignerView(tableDesignerView: azdata.designers.TableDesignerView) {
|
||||
const tabs = [];
|
||||
|
||||
if (designerInfo.view.columnTableOptions?.showTable) {
|
||||
tabs.push(this.getColumnsTab(designerInfo.view.columnTableOptions, designerInfo.columnTypes));
|
||||
if (tableDesignerView.columnTableOptions?.showTable) {
|
||||
tabs.push(this.getColumnsTab(tableDesignerView.columnTableOptions));
|
||||
}
|
||||
|
||||
if (designerInfo.view.foreignKeyTableOptions?.showTable) {
|
||||
tabs.push(this.getForeignKeysTab(designerInfo.view.foreignKeyTableOptions));
|
||||
tabs.push(this.getPrimaryKeyTab(tableDesignerView));
|
||||
|
||||
if (tableDesignerView.foreignKeyTableOptions?.showTable) {
|
||||
tabs.push(this.getForeignKeysTab(tableDesignerView.foreignKeyTableOptions, tableDesignerView.foreignKeyColumnMappingTableOptions));
|
||||
}
|
||||
|
||||
if (designerInfo.view.checkConstraintTableOptions?.showTable) {
|
||||
tabs.push(this.getCheckConstraintsTab(designerInfo.view.checkConstraintTableOptions));
|
||||
if (tableDesignerView.checkConstraintTableOptions?.showTable) {
|
||||
tabs.push(this.getCheckConstraintsTab(tableDesignerView.checkConstraintTableOptions));
|
||||
}
|
||||
|
||||
if (designerInfo.view.indexTableOptions?.showTable) {
|
||||
tabs.push(this.getIndexesTab(designerInfo.view.indexTableOptions, designerInfo.view.indexColumnSpecificationTableOptions));
|
||||
if (tableDesignerView.indexTableOptions?.showTable) {
|
||||
tabs.push(this.getIndexesTab(tableDesignerView.indexTableOptions, tableDesignerView.indexColumnSpecificationTableOptions));
|
||||
}
|
||||
|
||||
if (designerInfo.view.additionalTabs) {
|
||||
tabs.push(...designerInfo.view.additionalTabs);
|
||||
if (tableDesignerView.additionalTabs) {
|
||||
tabs.push(...tableDesignerView.additionalTabs);
|
||||
}
|
||||
|
||||
tabs.push(this.getGeneralTab(designerInfo));
|
||||
tabs.push(this.getGeneralTab(tableDesignerView));
|
||||
|
||||
this._view = {
|
||||
components: [{
|
||||
@@ -279,7 +288,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
};
|
||||
}
|
||||
|
||||
private getGeneralTab(designerInfo: azdata.designers.TableDesignerInfo): DesignerTab {
|
||||
private getGeneralTab(tableDesignerView: azdata.designers.TableDesignerView): DesignerTab {
|
||||
const generalTabComponents: DesignerDataPropertyInfo[] = [
|
||||
{
|
||||
componentType: 'dropdown',
|
||||
@@ -287,7 +296,6 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
description: localize('designer.table.description.schema', "The schema that contains the table."),
|
||||
componentProperties: <DropDownProperties>{
|
||||
title: localize('tableDesigner.schemaTitle', "Schema"),
|
||||
values: designerInfo.schemas
|
||||
}
|
||||
}, {
|
||||
componentType: 'input',
|
||||
@@ -299,8 +307,8 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
}
|
||||
];
|
||||
|
||||
if (designerInfo.view.additionalTableProperties) {
|
||||
generalTabComponents.push(...designerInfo.view.additionalTableProperties);
|
||||
if (tableDesignerView.additionalTableProperties) {
|
||||
generalTabComponents.push(...tableDesignerView.additionalTableProperties);
|
||||
}
|
||||
|
||||
return <DesignerTab>{
|
||||
@@ -309,7 +317,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
};
|
||||
}
|
||||
|
||||
private getColumnsTab(options: azdata.designers.TableDesignerBuiltInTableViewOptions, columnTypes: string[]): DesignerTab {
|
||||
private getColumnsTab(options: azdata.designers.TableDesignerBuiltInTableViewOptions): DesignerTab {
|
||||
|
||||
const columnProperties: DesignerDataPropertyInfo[] = [
|
||||
{
|
||||
@@ -326,8 +334,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
description: localize('designer.column.description.dataType', "Displays the data type name for the column"),
|
||||
componentProperties: {
|
||||
title: localize('tableDesigner.columnTypeTitle', "Type"),
|
||||
width: 100,
|
||||
values: columnTypes
|
||||
width: 100
|
||||
}
|
||||
}, {
|
||||
componentType: 'input',
|
||||
@@ -404,14 +411,15 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation,
|
||||
labelForAddNewButton: options.labelForAddNewButton ?? localize('tableDesigner.addNewColumn', "New Column")
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private getForeignKeysTab(options: azdata.designers.TableDesignerBuiltInTableViewOptions): DesignerTab {
|
||||
private getForeignKeysTab(options: azdata.designers.TableDesignerBuiltInTableViewOptions, columnMappingTableOptions: azdata.designers.TableDesignerBuiltInTableViewOptions): DesignerTab {
|
||||
|
||||
const foreignKeyColumnMappingProperties: DesignerDataPropertyInfo[] = [
|
||||
{
|
||||
@@ -476,13 +484,12 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
group: localize('tableDesigner.foreignKeyColumns', "Columns"),
|
||||
componentProperties: <DesignerTableProperties>{
|
||||
ariaLabel: localize('tableDesigner.foreignKeyColumns', "Columns"),
|
||||
columns: [designers.ForeignKeyColumnMappingProperty.Column, designers.ForeignKeyColumnMappingProperty.ForeignColumn],
|
||||
itemProperties: foreignKeyColumnMappingProperties,
|
||||
objectTypeDisplayName: '',
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
columns: this.getTableDisplayProperties(columnMappingTableOptions, [designers.ForeignKeyColumnMappingProperty.Column, designers.ForeignKeyColumnMappingProperty.ForeignColumn]),
|
||||
itemProperties: this.addAdditionalTableProperties(columnMappingTableOptions, foreignKeyColumnMappingProperties),
|
||||
canAddRows: columnMappingTableOptions.canAddRows,
|
||||
canRemoveRows: columnMappingTableOptions.canRemoveRows,
|
||||
removeRowConfirmationMessage: columnMappingTableOptions.removeRowConfirmationMessage,
|
||||
labelForAddNewButton: columnMappingTableOptions.labelForAddNewButton ?? localize('tableDesigner.addNewColumnMapping', "New Column Mapping")
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -502,13 +509,70 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation,
|
||||
labelForAddNewButton: options.labelForAddNewButton ?? localize('tableDesigner.addForeignKey', "New Foreign Key")
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private getPrimaryKeyTab(view: azdata.designers.TableDesignerView): DesignerTab {
|
||||
const options = view.primaryKeyColumnSpecificationTableOptions;
|
||||
const columnSpecProperties: DesignerDataPropertyInfo[] = [
|
||||
{
|
||||
componentType: 'dropdown',
|
||||
propertyName: designers.TableIndexColumnSpecificationProperty.Column,
|
||||
description: localize('designer.index.column.description.name', "The name of the column."),
|
||||
componentProperties: {
|
||||
title: localize('tableDesigner.index.column.name', "Column"),
|
||||
width: 100
|
||||
}
|
||||
}];
|
||||
|
||||
const tabComponents = [];
|
||||
tabComponents.push(
|
||||
{
|
||||
componentType: 'input',
|
||||
propertyName: designers.TableProperty.PrimaryKeyName,
|
||||
showInPropertiesView: false,
|
||||
description: localize('designer.table.primaryKeyName.description', "Name of the primary key."),
|
||||
componentProperties: {
|
||||
title: localize('tableDesigner.primaryKeyNameTitle', "Name")
|
||||
}
|
||||
});
|
||||
if (view.additionalPrimaryKeyProperties) {
|
||||
view.additionalPrimaryKeyProperties.forEach(component => {
|
||||
component.showInPropertiesView = false;
|
||||
tabComponents.push(component);
|
||||
});
|
||||
}
|
||||
tabComponents.push({
|
||||
componentType: 'table',
|
||||
propertyName: designers.TableProperty.PrimaryKeyColumns,
|
||||
showInPropertiesView: false,
|
||||
description: localize('designer.table.primaryKeyColumns.description', "Columns in the primary key."),
|
||||
componentProperties: <DesignerTableProperties>{
|
||||
title: localize('tableDesigner.primaryKeyColumnsTitle', "Primary Key Columns"),
|
||||
ariaLabel: localize('tableDesigner.primaryKeyColumnsTitle', "Primary Key Columns"),
|
||||
columns: this.getTableDisplayProperties(options, [designers.TableIndexColumnSpecificationProperty.Column]),
|
||||
itemProperties: this.addAdditionalTableProperties(options, columnSpecProperties),
|
||||
objectTypeDisplayName: '',
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation,
|
||||
showItemDetailInPropertiesView: false,
|
||||
labelForAddNewButton: options.labelForAddNewButton ?? localize('tableDesigner.addNewColumnToPrimaryKey', "Add Column")
|
||||
}
|
||||
});
|
||||
|
||||
return <DesignerTab>{
|
||||
title: localize('tableDesigner.PrimaryKeyTabTitle', "Primary Key"),
|
||||
components: tabComponents
|
||||
};
|
||||
}
|
||||
|
||||
private getCheckConstraintsTab(options: azdata.designers.TableDesignerBuiltInTableViewOptions): DesignerTab {
|
||||
const checkConstraintProperties: DesignerDataPropertyInfo[] = [
|
||||
{
|
||||
@@ -545,7 +609,8 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation,
|
||||
labelForAddNewButton: options.labelForAddNewButton ?? localize('tableDesigner.addNewCheckConstraint', "New Check Constraint")
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -584,8 +649,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
objectTypeDisplayName: '',
|
||||
canAddRows: columnSpecTableOptions.canAddRows,
|
||||
canRemoveRows: columnSpecTableOptions.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
removeRowConfirmationMessage: columnSpecTableOptions.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: columnSpecTableOptions.showRemoveRowConfirmation,
|
||||
labelForAddNewButton: columnSpecTableOptions.labelForAddNewButton ?? localize('tableDesigner.addNewColumnToIndex', "Add Column")
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -605,7 +671,8 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
canAddRows: options.canAddRows,
|
||||
canRemoveRows: options.canRemoveRows,
|
||||
removeRowConfirmationMessage: options.removeRowConfirmationMessage,
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation
|
||||
showRemoveRowConfirmation: options.showRemoveRowConfirmation,
|
||||
labelForAddNewButton: options.labelForAddNewButton ?? localize('tableDesigner.addNewIndex', "New Index")
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -623,19 +690,6 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
return properties;
|
||||
}
|
||||
|
||||
private setDefaultData(): void {
|
||||
const properties = Object.keys(this._viewModel);
|
||||
this.setDefaultInputData(properties, designers.TableProperty.Name);
|
||||
this.setDefaultInputData(properties, designers.TableProperty.Schema);
|
||||
this.setDefaultInputData(properties, designers.TableProperty.Description);
|
||||
}
|
||||
|
||||
private setDefaultInputData(allProperties: string[], property: string): void {
|
||||
if (allProperties.indexOf(property) === -1) {
|
||||
this._viewModel[property] = {};
|
||||
}
|
||||
}
|
||||
|
||||
private createTelemetryInfo(): ITelemetryEventProperties {
|
||||
let telemetryInfo = {
|
||||
provider: this._provider.providerId,
|
||||
@@ -645,6 +699,21 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||
return telemetryInfo;
|
||||
}
|
||||
|
||||
private isDirty(): boolean {
|
||||
const copyOfViewModel = deepClone(this._viewModel);
|
||||
const copyOfOriginalViewModel = deepClone(this._originalViewModel);
|
||||
// The generated script might be slightly different even though the models are the same
|
||||
// espeically the order of the description property statements.
|
||||
// we should take the script out for comparison.
|
||||
if (copyOfViewModel) {
|
||||
delete copyOfViewModel[ScriptProperty];
|
||||
}
|
||||
if (copyOfOriginalViewModel) {
|
||||
delete copyOfOriginalViewModel[ScriptProperty];
|
||||
}
|
||||
return !equals(copyOfViewModel, copyOfOriginalViewModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. 'Add' scenario
|
||||
a. ['propertyName1']. Example: add a column to the columns property: ['columns'].
|
||||
|
||||
Reference in New Issue
Block a user