diff --git a/src/sql/workbench/browser/designer/designer.ts b/src/sql/workbench/browser/designer/designer.ts index d50a314e6f..a602bf39ab 100644 --- a/src/sql/workbench/browser/designer/designer.ts +++ b/src/sql/workbench/browser/designer/designer.ts @@ -56,6 +56,8 @@ export type SetComponentValueFunc = (definition: DesignerDataPropertyInfo, compo const TableRowHeight = 23; const TableHeaderRowHeight = 28; +type DesignerUIArea = 'PropertiesView' | 'ScriptView' | 'ContentView'; + export class Designer extends Disposable implements IThemable { private _loadingSpinner: LoadingSpinner; private _horizontalSplitViewContainer: HTMLElement; @@ -160,7 +162,7 @@ export class Designer extends Disposable implements IThemable { }, Sizing.Distribute); this._propertiesPane = new DesignerPropertiesPane(this._propertiesPaneContainer, (container, components, parentPath) => { - return this.createComponents(container, components, this._propertiesPane.componentMap, this._propertiesPane.groupHeaders, parentPath, false, false); + return this.createComponents(container, components, this._propertiesPane.componentMap, this._propertiesPane.groupHeaders, parentPath, false, 'PropertiesView'); }, (definition, component, viewModel) => { this.setComponentValue(definition, component, viewModel); }); @@ -217,6 +219,8 @@ export class Designer extends Disposable implements IThemable { this._propertiesPane.groupHeaders.forEach((header) => { this.styleGroupHeader(header); }); + + this._propertiesPane.descriptionElement.style.borderColor = styles.paneSeparator.toString(); } public layout(dimension: DOM.Dimension) { @@ -275,7 +279,7 @@ export class Designer extends Disposable implements IThemable { private initializeDesigner(): void { const view = this._input.view; if (view.components) { - this.createComponents(this._topContentContainer, view.components, this._componentMap, this._groupHeaders, DesignerRootObjectPath, true, true); + this.createComponents(this._topContentContainer, view.components, this._componentMap, this._groupHeaders, DesignerRootObjectPath, true, 'ContentView'); } view.tabs.forEach(tab => { this._tabbedPanel.pushTab(this.createTabView(tab)); @@ -422,7 +426,7 @@ export class Designer extends Disposable implements IThemable { private createTabView(tab: DesignerTab): IPanelTab { const view = new DesignerTabPanelView(tab, (container, components, identifierGetter) => { - return this.createComponents(container, components, this._componentMap, this._groupHeaders, identifierGetter, true, true); + return this.createComponents(container, components, this._componentMap, this._groupHeaders, identifierGetter, true, 'ContentView'); }); return { identifier: tab.title, @@ -498,10 +502,10 @@ export class Designer extends Disposable implements IThemable { componentMap: Map, groupHeaders: HTMLElement[], parentPath: DesignerEditPath, - setWidth: boolean, isMainView: boolean): DesignerUIComponent[] { + setWidth: boolean, area: DesignerUIArea): DesignerUIComponent[] { const uiComponents = []; const groupNames = []; - const componentsToCreate = !isMainView ? components.filter(component => component.showInPropertiesView !== false) : components; + const componentsToCreate = area === 'PropertiesView' ? components.filter(component => component.showInPropertiesView !== false) : components; componentsToCreate.forEach(component => { // Set the default group name if not set (undefined or null). component.group = component.group || localize('designer.generalGroupName', "General"); @@ -513,7 +517,7 @@ export class Designer extends Disposable implements IThemable { // only show groups when there are multiple of them. if (groupNames.length < 2) { componentsToCreate.forEach(component => { - uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, isMainView)); + uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, area)); }); } else { groupNames.forEach(group => { @@ -523,7 +527,7 @@ export class Designer extends Disposable implements IThemable { groupHeader.innerText = group; componentsToCreate.forEach(component => { if (component.group === group) { - uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, isMainView)); + uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, area)); } }); }); @@ -536,7 +540,7 @@ export class Designer extends Disposable implements IThemable { parentPath: DesignerEditPath, componentMap: Map, setWidth: boolean, - isMainView: boolean): DesignerUIComponent { + view: DesignerUIArea): DesignerUIComponent { const propertyPath = [...parentPath, componentDefinition.propertyName]; let component: DesignerUIComponent; switch (componentDefinition.componentType) { @@ -554,8 +558,10 @@ export class Designer extends Disposable implements IThemable { } }); input.onInputFocus(() => { - if (!isMainView) { + if (view === 'PropertiesView') { this._propertiesPane.updateDescription(componentDefinition); + } else if (view === 'ContentView') { + this.updatePropertiesPane(DesignerRootObjectPath); } }); if (setWidth && inputProperties.width !== undefined) { @@ -574,8 +580,10 @@ export class Designer extends Disposable implements IThemable { this.handleEdit({ type: DesignerEditType.Update, path: propertyPath, value: e.selected }); }); dropdown.onDidFocus(() => { - if (!isMainView) { + if (view === 'PropertiesView') { this._propertiesPane.updateDescription(componentDefinition); + } else if (view === 'ContentView') { + this.updatePropertiesPane(DesignerRootObjectPath); } }); component = dropdown; @@ -589,14 +597,16 @@ export class Designer extends Disposable implements IThemable { this.handleEdit({ type: DesignerEditType.Update, path: propertyPath, value: newValue }); }); checkbox.onFocus(() => { - if (!isMainView) { + if (view === 'PropertiesView') { this._propertiesPane.updateDescription(componentDefinition); + } else if (view === 'ContentView') { + this.updatePropertiesPane(DesignerRootObjectPath); } }); component = checkbox; break; case 'table': - if (!isMainView) { + if (view === 'PropertiesView') { container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? ''; } const tableProperties = componentDefinition.componentProperties as DesignerTableProperties; @@ -695,15 +705,21 @@ export class Designer extends Disposable implements IThemable { table.grid.onBeforeEditCell.subscribe((e, data): boolean => { return data.item[data.column.field].enabled !== false; }); - if (isMainView === true) { - table.grid.onActiveCellChanged.subscribe((e, data) => { + + table.grid.onActiveCellChanged.subscribe((e, data) => { + if (view === 'ContentView') { if (data.row !== undefined) { this.updatePropertiesPane([...propertyPath, data.row]); } else { this.updatePropertiesPane(DesignerRootObjectPath); } - }); - } + } else if (view === 'PropertiesView') { + if (data.row !== undefined) { + this._propertiesPane.updateDescription(componentDefinition); + } + } + }); + component = table; break; default: diff --git a/src/sql/workbench/browser/designer/designerPropertiesPane.ts b/src/sql/workbench/browser/designer/designerPropertiesPane.ts index cca76229c1..29bfe2acb5 100644 --- a/src/sql/workbench/browser/designer/designerPropertiesPane.ts +++ b/src/sql/workbench/browser/designer/designerPropertiesPane.ts @@ -40,6 +40,10 @@ export class DesignerPropertiesPane { return this._groupHeaders; } + public get descriptionElement(): HTMLElement { + return this._descriptionContainer; + } + public get componentMap(): Map { return this._componentMap; } @@ -50,7 +54,7 @@ export class DesignerPropertiesPane { public updateDescription(definition: DesignerDataPropertyInfo) { this._descriptionContainer.style.display = 'block'; - const title: string = definition.componentProperties.title ?? ''; + const title: string = definition.componentProperties.title || definition.componentProperties.ariaLabel || ''; const description: string = definition.description ?? ''; this._descriptionTitleContainer.innerText = title; this._descriptionTextContainer.innerText = description; diff --git a/src/sql/workbench/browser/designer/media/designer.css b/src/sql/workbench/browser/designer/media/designer.css index e9b717dc2e..b0c6481a3c 100644 --- a/src/sql/workbench/browser/designer/media/designer.css +++ b/src/sql/workbench/browser/designer/media/designer.css @@ -103,9 +103,10 @@ } .designer-component .description-component { - margin: 15px; - height: 90px; - overflow-y: auto; + padding: 10px; + flex: 0 0 auto; + border-width: 1px 0 0 0; + border-style: solid; } .designer-component .description-component-label.codicon.info { @@ -113,8 +114,7 @@ background-position: 2px center; padding-left: 25px; background-size: 16px; - font-size: 15px; - font-weight: 600; + font-weight: bold; margin-block-start: 0px; scroll-margin-block-end: 0px; } diff --git a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts index 03abcca83e..7f2973c15c 100644 --- a/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts +++ b/src/sql/workbench/services/tableDesigner/browser/tableDesignerComponentInput.ts @@ -374,6 +374,7 @@ 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"), componentProperties: { ariaLabel: localize('tableDesigner.foreignKeyColumns', "Column Mapping"),