diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 866bfd3212..36b12a6c0a 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -1123,6 +1123,14 @@ declare module 'azdata' { * The properties to be displayed in the columns table. Default values are: Name, Type, Length, Precision, Scale, IsPrimaryKey, AllowNulls, DefaultValue. */ columnsTableProperties?: string[]; + /** + * Whether user can add columns. The default value is true. + */ + canAddColumns?: boolean; + /** + * Whether user can remove columns. The default value is true. + */ + canRemoveColumns?: boolean; } /** @@ -1201,6 +1209,16 @@ declare module 'azdata' { * The data to be displayed. */ data?: DesignerTableComponentDataItem[]; + + /** + * 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; } /** diff --git a/src/sql/base/browser/ui/designer/designer.ts b/src/sql/base/browser/ui/designer/designer.ts index 1968fbd418..92e947f9e0 100644 --- a/src/sql/base/browser/ui/designer/designer.ts +++ b/src/sql/base/browser/ui/designer/designer.ts @@ -134,7 +134,7 @@ export class Designer extends Disposable implements IThemable { layout: size => { this.layoutTabbedPanel(); }, - minimumSize: 200, + minimumSize: 400, maximumSize: Number.POSITIVE_INFINITY, onDidChange: Event.None }, Sizing.Distribute); @@ -514,7 +514,7 @@ export class Designer extends Disposable implements IThemable { const groupNames = []; const componentsToCreate = skipTableCreation ? components.filter(component => component.componentType !== 'table') : components; componentsToCreate.forEach(component => { - if (component.group && groupNames.indexOf(component.group) === -1) { + if (groupNames.indexOf(component.group) === -1) { groupNames.push(component.group); } }); @@ -529,7 +529,7 @@ export class Designer extends Disposable implements IThemable { const groupHeader = container.appendChild(DOM.$('div.full-row')); groupHeaders.push(groupHeader); this.styleGroupHeader(groupHeader); - groupHeader.innerText = group; + groupHeader.innerText = group ?? localize('designer.generalGroupName', "General"); componentsToCreate.forEach(component => { if (component.group === group) { uiComponents.push(this.createComponent(container, component, identifierGetter(component), componentMap, setWidth)); @@ -591,24 +591,26 @@ export class Designer extends Disposable implements IThemable { break; case 'table': const tableProperties = componentDefinition.componentProperties as DesignerTableProperties; - const buttonContainer = container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('.add-row-button-container')); - const addNewText = localize('designer.newRowText', "Add New"); - const addRowButton = new Button(buttonContainer, { - title: addNewText, - secondary: true - }); - addRowButton.onDidClick(() => { - this.handleEdit({ - type: DesignerEditType.Add, - property: componentDefinition.propertyName, + if (tableProperties.canAddRows !== false) { + const buttonContainer = container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('.add-row-button-container')); + const addNewText = localize('designer.newRowText', "Add New"); + const addRowButton = new Button(buttonContainer, { + title: addNewText, + secondary: true }); - }); - this.styleComponent(addRowButton); - addRowButton.label = addNewText; - addRowButton.icon = { - id: `add-row-button new codicon` - }; - this._buttons.push(addRowButton); + addRowButton.onDidClick(() => { + this.handleEdit({ + type: DesignerEditType.Add, + property: componentDefinition.propertyName, + }); + }); + this.styleComponent(addRowButton); + addRowButton.label = addNewText; + addRowButton.icon = { + id: `add-row-button new codicon` + }; + this._buttons.push(addRowButton); + } const tableContainer = container.appendChild(DOM.$('.full-row')); const table = new Table(tableContainer, { dataProvider: new TableDataView() @@ -664,24 +666,26 @@ export class Designer extends Disposable implements IThemable { }; } }); - const deleteRowColumn = new ButtonColumn({ - id: 'deleteRow', - iconCssClass: Codicon.trash.classNames, - title: localize('designer.removeRowText', "Remove"), - width: 20, - resizable: false, - isFontIcon: true - }); - deleteRowColumn.onClick((e) => { - (this._input.viewModel[componentDefinition.propertyName] as DesignerTableProperties).data.splice(e.row, 1); - this.handleEdit({ - type: DesignerEditType.Remove, - property: componentDefinition.propertyName, - value: e.item + if (tableProperties.canRemoveRows !== false) { + const deleteRowColumn = new ButtonColumn({ + id: 'deleteRow', + iconCssClass: Codicon.trash.classNames, + title: localize('designer.removeRowText', "Remove"), + width: 20, + resizable: false, + isFontIcon: true }); - }); - table.registerPlugin(deleteRowColumn); - columns.push(deleteRowColumn.definition); + deleteRowColumn.onClick((e) => { + (this._input.viewModel[componentDefinition.propertyName] as DesignerTableProperties).data.splice(e.row, 1); + this.handleEdit({ + type: DesignerEditType.Remove, + property: componentDefinition.propertyName, + value: e.item + }); + }); + table.registerPlugin(deleteRowColumn); + columns.push(deleteRowColumn.definition); + } table.columns = columns; table.grid.onBeforeEditCell.subscribe((e, data): boolean => { return data.item[data.column.field].enabled !== false; diff --git a/src/sql/base/browser/ui/designer/interfaces.ts b/src/sql/base/browser/ui/designer/interfaces.ts index 6ed6373516..6267227eca 100644 --- a/src/sql/base/browser/ui/designer/interfaces.ts +++ b/src/sql/base/browser/ui/designer/interfaces.ts @@ -154,16 +154,29 @@ export interface DesignerTableProperties extends ComponentProperties { columns?: string[]; /** - * The display name of the object type + * The display name of the object type. */ objectTypeDisplayName: string; /** - * the properties of the table data item + * 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. + */ + canAddRows?: boolean; + + /** + * Whether user can remove rows from the table. The default value is true. + */ + canRemoveRows?: boolean; } export interface DesignerTableComponentRowData { diff --git a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts index 7b4f87dfa7..dea0e30165 100644 --- a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts +++ b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts @@ -232,7 +232,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput { columnProperties.push(...designerInfo.view.additionalTableColumnProperties); } - const columnsTableProperties = designerInfo.view.columnsTableProperties || [ + const columnsTableProperties = designerInfo.view.columnsTableProperties?.length > 0 ? designerInfo.view.columnsTableProperties : [ designers.TableColumnProperty.Name, designers.TableColumnProperty.Type, designers.TableColumnProperty.Length, @@ -253,7 +253,9 @@ export class TableDesignerComponentInput implements DesignerComponentInput { ariaLabel: localize('tableDesigner.columnsTabTitle', "Columns"), columns: columnsTableProperties, itemProperties: columnProperties, - objectTypeDisplayName: localize('tableDesigner.columnTypeName', "Column") + objectTypeDisplayName: localize('tableDesigner.columnTypeName', "Column"), + canAddRows: designerInfo.view.canAddColumns, + canRemoveRows: designerInfo.view.canRemoveColumns } } ]