diff --git a/extensions/mssql/config.json b/extensions/mssql/config.json index d175eaf599..e5ab7ec0f4 100644 --- a/extensions/mssql/config.json +++ b/extensions/mssql/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "3.0.0-release.192", + "version": "3.0.0-release.193", "downloadFileNames": { "Windows_86": "win-x86-net6.0.zip", "Windows_64": "win-x64-net6.0.zip", diff --git a/extensions/mssql/src/contracts.ts b/extensions/mssql/src/contracts.ts index f5d00449ab..76e5545f0e 100644 --- a/extensions/mssql/src/contracts.ts +++ b/extensions/mssql/src/contracts.ts @@ -1056,7 +1056,7 @@ export namespace ProcessTableDesignerEditRequest { } export namespace PublishTableDesignerChangesRequest { - export const type = new RequestType('tabledesigner/publish'); + export const type = new RequestType('tabledesigner/publish'); } export namespace TableDesignerGenerateScriptRequest { diff --git a/extensions/mssql/src/features.ts b/extensions/mssql/src/features.ts index f4f6e8c896..bbbcf2183f 100644 --- a/extensions/mssql/src/features.ts +++ b/extensions/mssql/src/features.ts @@ -1131,7 +1131,7 @@ export class TableDesignerFeature extends SqlOpsFeature { } }; - const publishChanges = (tableInfo: azdata.designers.TableInfo): Thenable => { + const publishChanges = (tableInfo: azdata.designers.TableInfo): Thenable => { try { return client.sendRequest(contracts.PublishTableDesignerChangesRequest.type, tableInfo); } diff --git a/extensions/mssql/src/tableDesigner/tableDesigner.ts b/extensions/mssql/src/tableDesigner/tableDesigner.ts index 5b25ba2be0..df909c040b 100644 --- a/extensions/mssql/src/tableDesigner/tableDesigner.ts +++ b/extensions/mssql/src/tableDesigner/tableDesigner.ts @@ -31,7 +31,6 @@ export function registerTableDesignerCommands(appContext: AppContext) { const schema = context.nodeInfo.metadata.schema; const name = context.nodeInfo.metadata.name; const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true); - const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id); const serverInfo = await azdata.connection.getServerInfo(context.connectionProfile.id); let telemetryInfo: ITelemetryEventProperties = {}; telemetryInfo = Telemetry.fillServerInfo(telemetryInfo, serverInfo); @@ -41,7 +40,7 @@ export function registerTableDesignerCommands(appContext: AppContext) { isNewTable: false, name: name, schema: schema, - id: `${connectionUri}|${database}|${schema}|${name}`, + id: `${connectionString}|${database}|${schema}|${name}`, connectionString: connectionString }, telemetryInfo); })); diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index ca56f6a16f..fb34ceb08e 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -1042,7 +1042,7 @@ declare module 'azdata' { * Publish the changes. * @param table the table information */ - publishChanges(table: TableInfo): Thenable; + publishChanges(table: TableInfo): Thenable; /** * Generate script for the changes. @@ -1154,7 +1154,7 @@ declare module 'azdata' { */ export enum TableForeignKeyProperty { Name = 'name', - PrimaryKeyTable = 'primaryKeyTable', + ForeignTable = 'foreignTable', OnDeleteAction = 'onDeleteAction', OnUpdateAction = 'onUpdateAction', Columns = 'columns' @@ -1164,8 +1164,8 @@ declare module 'azdata' { * Name of the columns mapping properties for foreign key. */ export enum ForeignKeyColumnMappingProperty { - PrimaryKeyColumn = 'primaryKeyColumn', - ForeignKeyColumn = 'foreignKeyColumn' + Column = 'column', + ForeignColumn = 'foreignColumn' } /** @@ -1238,7 +1238,7 @@ declare module 'azdata' { indexColumnSpecificationTableOptions?: TableDesignerBuiltInTableViewOptions; } - export interface TableDesignerBuiltInTableViewOptions { + export interface TableDesignerBuiltInTableViewOptions extends DesignerTablePropertiesBase { /** * Whether to show the table. Default value is false. */ @@ -1247,14 +1247,6 @@ declare module 'azdata' { * Properties to be displayed in the table, other properties can be accessed in the properties view. */ propertiesToDisplay?: string[]; - /** - * Whether adding new rows is supported. - */ - canAddRows?: boolean; - /** - * Whether removing rows is supported. - */ - canRemoveRows?: boolean; /** * Additional properties for the entity. */ @@ -1317,39 +1309,45 @@ declare module 'azdata' { */ export type DesignerComponentTypeName = 'input' | 'checkbox' | 'dropdown' | 'table'; - /** - * The properties for the table component in the designer. - */ - export interface DesignerTableProperties extends ComponentProperties { - /** - * the name of the properties to be displayed, properties not in this list will be accessible in properties pane. - */ - columns?: string[]; - - /** - * The display name of the object type. - */ - objectTypeDisplayName: string; - - /** - * the properties of the table data item. - */ - itemProperties?: DesignerDataPropertyInfo[]; - - /** - * The data to be displayed. - */ - data?: DesignerTableComponentDataItem[]; - + export interface DesignerTablePropertiesBase { /** * Whether user can add new rows to the table. The default value is true. */ canAddRows?: boolean; - /** * Whether user can remove rows from the table. The default value is true. */ canRemoveRows?: boolean; + /** + * Whether to show confirmation when user removes a row. The default value is false. + */ + showRemoveRowConfirmation?: boolean; + /** + * The confirmation message to be displayed when user removes a row. + */ + removeRowConfirmationMessage?: string; + } + + /** + * The properties for the table component in the designer. + */ + export interface DesignerTableProperties extends ComponentProperties, DesignerTablePropertiesBase { + /** + * the name of the properties to be displayed, properties not in this list will be accessible in properties pane. + */ + columns?: string[]; + /** + * The display name of the object type. + */ + objectTypeDisplayName: string; + /** + * the properties of the table data item. + */ + itemProperties?: DesignerDataPropertyInfo[]; + /** + * The data to be displayed. + */ + data?: DesignerTableComponentDataItem[]; } /** @@ -1429,6 +1427,16 @@ declare module 'azdata' { */ errors?: { message: string, property?: DesignerEditPath }[]; } + + /** + * The result returned by the table designer provider after handling the publish changes request. + */ + export interface PublishChangesResult { + /** + * The new table information after the changes are published. + */ + newTableInfo: TableInfo; + } } export interface ExecutionPlanGraph { diff --git a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts index 440af71acc..8bb5f76c13 100644 --- a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts +++ b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts @@ -519,7 +519,7 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData processTableEdit(table, edit): Thenable { return self._proxy.$processTableDesignerEdit(handle, table, edit); }, - publishChanges(tableInfo: azdata.designers.TableInfo): Thenable { + publishChanges(tableInfo: azdata.designers.TableInfo): Thenable { return self._proxy.$publishTableDesignerChanges(handle, tableInfo); }, generateScript(tableInfo: azdata.designers.TableInfo): Thenable { diff --git a/src/sql/workbench/api/common/extHostDataProtocol.ts b/src/sql/workbench/api/common/extHostDataProtocol.ts index 5d8b0c86e2..69de4cba78 100644 --- a/src/sql/workbench/api/common/extHostDataProtocol.ts +++ b/src/sql/workbench/api/common/extHostDataProtocol.ts @@ -901,7 +901,7 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape { return this._resolveProvider(handle).processTableEdit(table, edit); } - public override $publishTableDesignerChanges(handle: number, table: azdata.designers.TableInfo): Thenable { + public override $publishTableDesignerChanges(handle: number, table: azdata.designers.TableInfo): Thenable { return this._resolveProvider(handle).publishChanges(table); } diff --git a/src/sql/workbench/api/common/sqlExtHost.protocol.ts b/src/sql/workbench/api/common/sqlExtHost.protocol.ts index c3a24a51ad..996aef6136 100644 --- a/src/sql/workbench/api/common/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/common/sqlExtHost.protocol.ts @@ -541,7 +541,7 @@ export abstract class ExtHostDataProtocolShape { /** * Publish the table designer changes. */ - $publishTableDesignerChanges(handle: number, table: azdata.designers.TableInfo): Thenable { throw ni(); } + $publishTableDesignerChanges(handle: number, table: azdata.designers.TableInfo): Thenable { throw ni(); } /** * Generate scripts. diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index b46de77aaf..129f7872a0 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -969,15 +969,15 @@ export namespace designers { export enum TableForeignKeyProperty { Name = 'name', - PrimaryKeyTable = 'primaryKeyTable', + ForeignTable = 'foreignTable', OnDeleteAction = 'onDeleteAction', OnUpdateAction = 'onUpdateAction', Columns = 'columns' } export enum ForeignKeyColumnMappingProperty { - PrimaryKeyColumn = 'primaryKeyColumn', - ForeignKeyColumn = 'foreignKeyColumn' + Column = 'column', + ForeignColumn = 'foreignColumn' } export enum TableCheckConstraintProperty { diff --git a/src/sql/workbench/browser/designer/designer.ts b/src/sql/workbench/browser/designer/designer.ts index f5e0f132b6..b4568d9b8c 100644 --- a/src/sql/workbench/browser/designer/designer.ts +++ b/src/sql/workbench/browser/designer/designer.ts @@ -36,6 +36,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti 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 { IDialogService } from 'vs/platform/dialogs/common/dialogs'; export interface IDesignerStyle { tabbedPanelStyles?: ITabbedPanelStyles; @@ -53,7 +54,7 @@ export type DesignerUIComponent = InputBox | Checkbox | Table | export type CreateComponentsFunc = (container: HTMLElement, components: DesignerDataPropertyInfo[], parentPath: DesignerEditPath) => DesignerUIComponent[]; export type SetComponentValueFunc = (definition: DesignerDataPropertyInfo, component: DesignerUIComponent, data: DesignerViewModel) => void; -const TableRowHeight = 23; +const TableRowHeight = 25; const TableHeaderRowHeight = 28; type DesignerUIArea = 'PropertiesView' | 'ScriptView' | 'TopContentView' | 'TabsView'; @@ -85,7 +86,8 @@ export class Designer extends Disposable implements IThemable { constructor(private readonly _container: HTMLElement, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IContextViewService private readonly _contextViewProvider: IContextViewService, - @INotificationService private readonly _notificationService: INotificationService) { + @INotificationService private readonly _notificationService: INotificationService, + @IDialogService private readonly _dialogService: IDialogService) { super(); this._tableCellEditorFactory = new TableCellEditorFactory( { @@ -303,11 +305,23 @@ export class Designer extends Disposable implements IThemable { const propertyName = edit.path[0] as string; const tableData = this._input.viewModel[propertyName] as DesignerTableProperties; const table = this._componentMap.get(propertyName).component as Table; - table.setActiveCell(tableData.data.length - 1, 0); + try { + table.setActiveCell(tableData.data.length - 1, 0); + } + catch { + // Ignore the slick grid error when setting active cell. + } + } else { + this.updatePropertiesPane(this._propertiesPane.objectPath); } } else if (edit.type === DesignerEditType.Update) { // for edit, update the properties pane with new values of current object. this.updatePropertiesPane(this._propertiesPane.objectPath); + } else if (edit.type === DesignerEditType.Remove) { + // removing the secondary level entities, the properties pane needs to be updated to reflect the changes. + if (edit.path.length === 4) { + this.updatePropertiesPane(this._propertiesPane.objectPath); + } } } catch (err) { this._notificationService.error(err); @@ -330,7 +344,7 @@ export class Designer extends Disposable implements IThemable { let message; let timeout; switch (action) { - case 'save': + case 'publish': message = showLoading ? localize('designer.publishingChanges', "Publishing changes...") : localize('designer.publishChangesCompleted', "Changes have been published"); timeout = 0; break; @@ -693,7 +707,17 @@ export class Designer extends Disposable implements IThemable { resizable: false, isFontIcon: true }); - deleteRowColumn.onClick((e) => { + deleteRowColumn.onClick(async (e) => { + if (tableProperties.showRemoveRowConfirmation) { + const confirmMessage = tableProperties.removeRowConfirmationMessage || localize('designer.defaultRemoveRowConfirmationMessage', "Are you sure you want to remove the row?"); + const result = await this._dialogService.confirm({ + type: 'question', + message: confirmMessage + }); + if (!result.confirmed) { + return; + } + } this.handleEdit({ type: DesignerEditType.Remove, path: [...propertyPath, e.row] diff --git a/src/sql/workbench/browser/designer/interfaces.ts b/src/sql/workbench/browser/designer/interfaces.ts index bcb989c4b7..c9cda32c4b 100644 --- a/src/sql/workbench/browser/designer/interfaces.ts +++ b/src/sql/workbench/browser/designer/interfaces.ts @@ -74,7 +74,7 @@ export interface DesignerUIState { activeTabId: PanelTabIdentifier; } -export type DesignerAction = 'save' | 'initialize' | 'processEdit' | 'generateScript' | 'generateReport'; +export type DesignerAction = 'publish' | 'initialize' | 'processEdit' | 'generateScript' | 'generateReport'; export interface DesignerEditProcessedEventArgs { result: DesignerEditResult; @@ -154,22 +154,18 @@ export interface DesignerTableProperties extends ComponentProperties { * the name of the properties to be displayed, properties not in this list will be accessible in details view. */ columns?: string[]; - /** * The display name of the object type. */ objectTypeDisplayName: string; - /** * The properties of the table data item. */ itemProperties?: DesignerDataPropertyInfo[]; - /** * The data to be displayed. */ data?: DesignerTableComponentRowData[]; - /** * Whether user can add new rows to the table. The default value is true. */ @@ -179,6 +175,14 @@ export interface DesignerTableProperties extends ComponentProperties { * Whether user can remove rows from the table. The default value is true. */ canRemoveRows?: boolean; + /** + * Whether to show confirmation when user removes a row. The default value is false. + */ + showRemoveRowConfirmation?: boolean; + /** + * The confirmation message to be displayed when user removes a row. + */ + removeRowConfirmationMessage?: string; } export interface DesignerTableComponentRowData { diff --git a/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts b/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts index b4988a3bd5..b05f47b544 100644 --- a/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts +++ b/src/sql/workbench/browser/editor/tableDesigner/tableDesignerInput.ts @@ -26,30 +26,23 @@ export class TableDesignerInput extends EditorInput { constructor( private _provider: TableDesignerProvider, - private _tableInfo: azdata.designers.TableInfo, + tableInfo: azdata.designers.TableInfo, telemetryInfo: { [key: string]: string }, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IEditorService editorService: IEditorService, + @IEditorService private readonly _editorService: IEditorService, @INotificationService private readonly _notificationService: INotificationService) { super(); - this._designerComponentInput = this._instantiationService.createInstance(TableDesignerComponentInput, this._provider, this._tableInfo, telemetryInfo); + this._designerComponentInput = this._instantiationService.createInstance(TableDesignerComponentInput, this._provider, tableInfo, telemetryInfo); this._register(this._designerComponentInput.onStateChange((e) => { + if (e.previousState.pendingAction === 'publish') { + this.setEditorLabel(); + this._onDidChangeLabel.fire(); + } if (e.currentState.dirty !== e.previousState.dirty) { this._onDidChangeDirty.fire(); } })); - if (this._tableInfo.isNewTable) { - const existingNames = editorService.editors.map(editor => editor.getName()); - // Find the next available unique name for the new table designer - let idx = 1; - do { - this._name = `${NewTable} ${idx}`; - idx++; - } while (existingNames.indexOf(this._name) !== -1); - } else { - this._name = `${this._tableInfo.schema}.${this._tableInfo.name}`; - } - this._title = `${this._tableInfo.server}.${this._tableInfo.database} - ${this._name}`; + this.setEditorLabel(); } get typeId(): string { @@ -80,7 +73,7 @@ export class TableDesignerInput extends EditorInput { } override isSaving(): boolean { - return this._designerComponentInput.pendingAction === 'save'; + return this._designerComponentInput.pendingAction === 'publish'; } override async save(group: GroupIdentifier, options?: ISaveOptions): Promise { @@ -99,11 +92,27 @@ export class TableDesignerInput extends EditorInput { override matches(otherInput: any): boolean { return otherInput instanceof TableDesignerInput && this._provider.providerId === otherInput._provider.providerId - && this._tableInfo.id === otherInput._tableInfo.id; + && this._designerComponentInput.tableInfo.id === otherInput._designerComponentInput.tableInfo.id; } override dispose(): void { super.dispose(); - this._provider.disposeTableDesigner(this._tableInfo).then(undefined, err => onUnexpectedError(err)); + this._provider.disposeTableDesigner(this._designerComponentInput.tableInfo).then(undefined, err => onUnexpectedError(err)); + } + + private setEditorLabel(): void { + const tableInfo = this._designerComponentInput.tableInfo; + if (tableInfo.isNewTable) { + const existingNames = this._editorService.editors.map(editor => editor.getName()); + // Find the next available unique name for the new table designer + let idx = 1; + do { + this._name = `${NewTable} ${idx}`; + idx++; + } while (existingNames.indexOf(this._name) !== -1); + } else { + this._name = `${tableInfo.schema}.${tableInfo.name}`; + } + this._title = `${tableInfo.server}.${tableInfo.database} - ${this._name}`; } } diff --git a/src/sql/workbench/contrib/tableDesigner/browser/tableDesignerEditor.ts b/src/sql/workbench/contrib/tableDesigner/browser/tableDesignerEditor.ts index 639cb29789..cdb714dd22 100644 --- a/src/sql/workbench/contrib/tableDesigner/browser/tableDesignerEditor.ts +++ b/src/sql/workbench/contrib/tableDesigner/browser/tableDesignerEditor.ts @@ -16,7 +16,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { IEditorOpenContext } from 'vs/workbench/common/editor'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { GenerateTableChangeScriptAction, PublishTableChangesAction } from 'sql/workbench/contrib/tableDesigner/browser/actions'; +import { PublishTableChangesAction } from 'sql/workbench/contrib/tableDesigner/browser/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IColorTheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { DesignerPaneSeparator } from 'sql/platform/theme/common/colorRegistry'; @@ -26,7 +26,6 @@ export class TableDesignerEditor extends EditorPane { private _designer: Designer; private _publishChangesAction: PublishTableChangesAction; - private _generateScriptAction: GenerateTableChangeScriptAction; constructor( @ITelemetryService telemetryService: ITelemetryService, @@ -46,7 +45,6 @@ export class TableDesignerEditor extends EditorPane { const designerInput = input.getComponentInput(); this._designer.setInput(designerInput); this._publishChangesAction.setContext(designerInput); - this._generateScriptAction.setContext(designerInput); } protected createEditor(parent: HTMLElement): void { @@ -58,9 +56,7 @@ export class TableDesignerEditor extends EditorPane { this._register(actionbar); this._publishChangesAction = this._instantiationService.createInstance(PublishTableChangesAction); this._publishChangesAction.enabled = false; - this._generateScriptAction = this._instantiationService.createInstance(GenerateTableChangeScriptAction); - this._generateScriptAction.enabled = false; - actionbar.push([this._publishChangesAction, this._generateScriptAction], { icon: true, label: false }); + actionbar.push([this._publishChangesAction], { icon: true, label: false }); this._designer = this._instantiationService.createInstance(Designer, designerContainer); this._register(attachDesignerStyler(this._designer, this.themeService)); diff --git a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts index 178b6393c1..6526d4d681 100644 --- a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts +++ b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts @@ -38,7 +38,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { }; constructor(private readonly _provider: TableDesignerProvider, - private _tableInfo: azdata.designers.TableInfo, + public tableInfo: azdata.designers.TableInfo, private _telemetryInfo: ITelemetryEventProperties, @INotificationService private readonly _notificationService: INotificationService, @IAdsTelemetryService readonly _adsTelemetryService: IAdsTelemetryService, @@ -77,7 +77,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { this.designerEditTypeDisplayValue[edit.type]).withAdditionalProperties(telemetryInfo); const startTime = new Date().getTime(); this.updateState(this.valid, this.dirty, 'processEdit'); - this._provider.processTableEdit(this._tableInfo, edit).then( + this._provider.processTableEdit(this.tableInfo, edit).then( result => { this._viewModel = result.viewModel; this.updateState(result.isValid, !equals(this._viewModel, this._originalViewModel), undefined); @@ -113,7 +113,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { const startTime = new Date().getTime(); try { this.updateState(this.valid, this.dirty, 'generateScript'); - const script = await this._provider.generateScript(this._tableInfo); + const script = await this._provider.generateScript(this.tableInfo); this._queryEditorService.newSqlEditor({ initalContent: script }); this.updateState(this.valid, this.dirty); notificationHandle.updateMessage(localize('tableDesigner.generatingScriptCompleted', "Script generated.")); @@ -133,16 +133,17 @@ export class TableDesignerComponentInput implements DesignerComponentInput { const publishEvent = this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner, TelemetryAction.PublishChanges).withAdditionalProperties(telemetryInfo); const saveNotificationHandle = this._notificationService.notify({ severity: Severity.Info, - message: localize('tableDesigner.savingChanges', "Saving table designer changes..."), + message: localize('tableDesigner.savingChanges', "Publishing table designer changes..."), sticky: true }); const startTime = new Date().getTime(); try { - this.updateState(this.valid, this.dirty, 'save'); - await this._provider.publishChanges(this._tableInfo); + this.updateState(this.valid, this.dirty, 'publish'); + const result = await this._provider.publishChanges(this.tableInfo); this._originalViewModel = this._viewModel; - this.updateState(true, false); saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeSuccess', "The changes have been successfully published.")); + this.tableInfo = result.newTableInfo; + this.updateState(true, false); publishEvent.withAdditionalMeasurements({ 'elapsedTimeMs': new Date().getTime() - startTime }).send(); @@ -164,7 +165,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { let report; try { this.updateState(this.valid, this.dirty, 'generateReport'); - report = await this._provider.generatePreviewReport(this._tableInfo); + report = await this._provider.generatePreviewReport(this.tableInfo); reportNotificationHandle.close(); this.updateState(this.valid, this.dirty); } catch (error) { @@ -216,7 +217,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { } this.updateState(this.valid, this.dirty, 'initialize'); - this._provider.initializeTableDesigner(this._tableInfo).then(result => { + this._provider.initializeTableDesigner(this.tableInfo).then(result => { this.doInitialization(result); this._onInitialized.fire(); }, error => { @@ -225,9 +226,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { } private doInitialization(designerInfo: azdata.designers.TableDesignerInfo): void { - this.updateState(true, false); + this.updateState(true, this.tableInfo.isNewTable); this._viewModel = designerInfo.viewModel; - this._originalViewModel = deepClone(this._viewModel); + this._originalViewModel = this.tableInfo.isNewTable ? undefined : deepClone(this._viewModel); this.setDefaultData(); const tabs = []; @@ -391,7 +392,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { itemProperties: this.addAdditionalTableProperties(options, columnProperties), objectTypeDisplayName: localize('tableDesigner.columnTypeName', "Column"), canAddRows: options.canAddRows, - canRemoveRows: options.canRemoveRows + canRemoveRows: options.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ] @@ -403,17 +406,17 @@ export class TableDesignerComponentInput implements DesignerComponentInput { const foreignKeyColumnMappingProperties: DesignerDataPropertyInfo[] = [ { componentType: 'dropdown', - propertyName: designers.ForeignKeyColumnMappingProperty.ForeignKeyColumn, + propertyName: designers.ForeignKeyColumnMappingProperty.ForeignColumn, componentProperties: { - title: localize('tableDesigner.foreignKeyColumn', "Foreign Key Column"), + title: localize('tableDesigner.foreignKey.foreignColumn', "Foreign Column"), width: 150 } }, { componentType: 'dropdown', - propertyName: designers.ForeignKeyColumnMappingProperty.PrimaryKeyColumn, + propertyName: designers.ForeignKeyColumnMappingProperty.Column, componentProperties: { - title: localize('tableDesigner.primaryKeyColumn', "Primary Key Column"), + title: localize('tableDesigner.foreignKey.column', "Column"), width: 150 } }, @@ -431,10 +434,10 @@ export class TableDesignerComponentInput implements DesignerComponentInput { }, { componentType: 'dropdown', - propertyName: designers.TableForeignKeyProperty.PrimaryKeyTable, + propertyName: designers.TableForeignKeyProperty.ForeignTable, description: localize('designer.foreignkey.description.primaryKeyTable', "The table which contains the primary or unique key column."), componentProperties: { - title: localize('tableDesigner.PrimaryKeyTableName', "Primary Key Table"), + title: localize('tableDesigner.ForeignTableName', "Foreign Table"), width: 200 } }, @@ -460,14 +463,16 @@ export class TableDesignerComponentInput implements DesignerComponentInput { componentType: 'table', propertyName: designers.TableForeignKeyProperty.Columns, description: localize('designer.foreignkey.description.columnMapping', "The mapping between foreign key columns and primary key columns."), - group: localize('tableDesigner.foreignKeyColumns', "Column Mapping"), + group: localize('tableDesigner.foreignKeyColumns', "Columns"), componentProperties: { - ariaLabel: localize('tableDesigner.foreignKeyColumns', "Column Mapping"), - columns: [designers.ForeignKeyColumnMappingProperty.ForeignKeyColumn, designers.ForeignKeyColumnMappingProperty.PrimaryKeyColumn], + ariaLabel: localize('tableDesigner.foreignKeyColumns', "Columns"), + columns: [designers.ForeignKeyColumnMappingProperty.Column, designers.ForeignKeyColumnMappingProperty.ForeignColumn], itemProperties: foreignKeyColumnMappingProperties, objectTypeDisplayName: '', canAddRows: options.canAddRows, - canRemoveRows: options.canRemoveRows + canRemoveRows: options.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ]; @@ -481,11 +486,13 @@ export class TableDesignerComponentInput implements DesignerComponentInput { showInPropertiesView: false, componentProperties: { ariaLabel: localize('tableDesigner.foreignKeysTabTitle', "Foreign Keys"), - columns: this.getTableDisplayProperties(options, [designers.TableForeignKeyProperty.Name, designers.TableForeignKeyProperty.PrimaryKeyTable]), + columns: this.getTableDisplayProperties(options, [designers.TableForeignKeyProperty.Name, designers.TableForeignKeyProperty.ForeignTable]), itemProperties: this.addAdditionalTableProperties(options, foreignKeyProperties), objectTypeDisplayName: localize('tableDesigner.ForeignKeyTypeName', "Foreign Key"), canAddRows: options.canAddRows, - canRemoveRows: options.canRemoveRows + canRemoveRows: options.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ] @@ -526,7 +533,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { itemProperties: this.addAdditionalTableProperties(options, checkConstraintProperties), objectTypeDisplayName: localize('tableDesigner.checkConstraintTypeName', "Check Constraint"), canAddRows: options.canAddRows, - canRemoveRows: options.canRemoveRows + canRemoveRows: options.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ] @@ -564,7 +573,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { itemProperties: this.addAdditionalTableProperties(columnSpecTableOptions, columnSpecProperties), objectTypeDisplayName: '', canAddRows: columnSpecTableOptions.canAddRows, - canRemoveRows: columnSpecTableOptions.canRemoveRows + canRemoveRows: columnSpecTableOptions.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ]; @@ -582,7 +593,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { itemProperties: this.addAdditionalTableProperties(options, indexProperties), objectTypeDisplayName: localize('tableDesigner.IndexTypeName', "Index"), canAddRows: options.canAddRows, - canRemoveRows: options.canRemoveRows + canRemoveRows: options.canRemoveRows, + removeRowConfirmationMessage: options.removeRowConfirmationMessage, + showRemoveRowConfirmation: options.showRemoveRowConfirmation } } ] @@ -616,7 +629,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { private createTelemetryInfo(): ITelemetryEventProperties { let telemetryInfo = { provider: this._provider.providerId, - isNewTable: this._tableInfo.isNewTable, + isNewTable: this.tableInfo.isNewTable, }; Object.assign(telemetryInfo, this._telemetryInfo); return telemetryInfo;