diff --git a/src/sql/base/browser/ui/table/formatters.ts b/src/sql/base/browser/ui/table/formatters.ts
index ac97390802..bd0e7f63bf 100644
--- a/src/sql/base/browser/ui/table/formatters.ts
+++ b/src/sql/base/browser/ui/table/formatters.ts
@@ -70,7 +70,6 @@ export function hyperLinkFormatter(row: number | undefined, cell: any | undefine
if (DBCellValue.isDBCellValue(value)) {
valueToDisplay = 'NULL';
if (!value.isNull) {
- cellClasses += ' xmlLink';
valueToDisplay = getCellDisplayValue(value.displayValue);
return `${valueToDisplay}`;
} else {
diff --git a/src/sql/base/browser/ui/table/media/slickColorTheme.css b/src/sql/base/browser/ui/table/media/slickColorTheme.css
index dee9cc4f2c..afdcb7d03c 100644
--- a/src/sql/base/browser/ui/table/media/slickColorTheme.css
+++ b/src/sql/base/browser/ui/table/media/slickColorTheme.css
@@ -17,18 +17,24 @@
}
.slick-cell a,
-.slick-cell a:link,
-.resultsMessageValue a,
-.resultsMessageValue a:link {
+.resultsMessageValue a {
color: var(--color-grid-link);
- text-decoration: underline;
cursor: pointer;
white-space: inherit;
}
+.resultsMessageValue a {
+ text-decoration: underline;
+}
+
+.slick-cell a {
+ text-decoration: none;
+}
+
.slick-cell a:hover,
.resultsMessageValue a:hover {
color: var(--color-grid-link-hover);
+ text-decoration: underline;
}
/*
diff --git a/src/sql/platform/query/common/query.ts b/src/sql/platform/query/common/query.ts
index e50b4ad61a..1aec4b4a84 100644
--- a/src/sql/platform/query/common/query.ts
+++ b/src/sql/platform/query/common/query.ts
@@ -6,40 +6,52 @@
export interface IQueryEditorConfiguration {
readonly results: {
readonly saveAsCsv: {
- readonly includeHeaders: boolean,
- readonly delimiter: string,
- readonly lineSeperator: string,
- readonly textIdentifier: string,
- readonly encoding: string
- },
+ readonly includeHeaders: boolean;
+ readonly delimiter: string;
+ readonly lineSeperator: string;
+ readonly textIdentifier: string;
+ readonly encoding: string;
+ };
readonly saveAsExcel: {
- readonly includeHeaders: boolean,
- },
+ readonly includeHeaders: boolean;
+ };
readonly saveAsMarkdown: {
- readonly encoding: string,
- readonly includeHeaders: boolean,
- readonly lineSeparator: string,
- }
+ readonly encoding: string;
+ readonly includeHeaders: boolean;
+ readonly lineSeparator: string;
+ };
readonly saveAsXml: {
- readonly formatted: boolean,
- readonly encoding: string
- },
- readonly streaming: boolean,
- readonly copyIncludeHeaders: boolean,
- readonly copyRemoveNewLine: boolean,
- readonly optimizedTable: boolean,
- readonly inMemoryDataProcessingThreshold: number,
- readonly openAfterSave: boolean
+ readonly formatted: boolean;
+ readonly encoding: string;
+ };
+ readonly streaming: boolean;
+ readonly copyIncludeHeaders: boolean;
+ readonly copyRemoveNewLine: boolean;
+ readonly optimizedTable: boolean;
+ readonly inMemoryDataProcessingThreshold: number;
+ readonly openAfterSave: boolean;
readonly showActionBar: boolean;
},
readonly messages: {
- readonly showBatchTime: boolean,
- readonly wordwrap: boolean
- },
+ readonly showBatchTime: boolean;
+ readonly wordwrap: boolean;
+ };
readonly chart: {
readonly defaultChartType: 'bar' | 'doughnut' | 'horizontalBar' | 'line' | 'pie' | 'scatter' | 'timeSeries',
- },
- readonly tabColorMode: 'off' | 'border' | 'fill',
+ };
+ readonly tabColorMode: 'off' | 'border' | 'fill';
readonly showConnectionInfoInTitle: boolean;
readonly promptToSaveGeneratedFiles: boolean;
}
+
+export interface IResultGridConfiguration {
+ fontFamily: string;
+ fontWeight: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
+ fontSize: number;
+ letterSpacing: number;
+ rowHeight: number;
+ cellPadding: number | number[];
+ autoSizeColumns: boolean;
+ maxColumnWidth: number;
+ showJsonAsLink: boolean;
+}
diff --git a/src/sql/workbench/contrib/query/browser/gridPanel.ts b/src/sql/workbench/contrib/query/browser/gridPanel.ts
index e972ece250..c3410e56a2 100644
--- a/src/sql/workbench/contrib/query/browser/gridPanel.ts
+++ b/src/sql/workbench/contrib/query/browser/gridPanel.ts
@@ -43,7 +43,7 @@ import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/commo
import { SaveFormat } from 'sql/workbench/services/query/common/resultSerializer';
import { Progress } from 'vs/platform/progress/common/progress';
import { ScrollableView, IView } from 'sql/base/browser/ui/scrollableView/scrollableView';
-import { IQueryEditorConfiguration } from 'sql/platform/query/common/query';
+import { IQueryEditorConfiguration, IResultGridConfiguration } from 'sql/platform/query/common/query';
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
import { FilterButtonWidth, HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
@@ -362,6 +362,7 @@ export abstract class GridTableBase extends Disposable implements IView {
private dataProvider: HybridDataProvider;
private filterPlugin: HeaderFilter;
private isDisposed: boolean = false;
+ private gridConfig: IResultGridConfiguration;
private columns: Slick.Column[];
@@ -417,8 +418,8 @@ export abstract class GridTableBase extends Disposable implements IView {
super();
this.options = { ...defaultGridTableOptions, ...options };
- let config = this.configurationService.getValue<{ rowHeight: number }>('resultsGrid');
- this.rowHeight = config && config.rowHeight ? config.rowHeight : ROW_HEIGHT;
+ this.gridConfig = this.configurationService.getValue('resultsGrid');
+ this.rowHeight = this.gridConfig.rowHeight ?? ROW_HEIGHT;
this.state = state;
this.container.style.width = '100%';
this.container.style.height = '100%';
@@ -430,7 +431,9 @@ export abstract class GridTableBase extends Disposable implements IView {
? localize('xmlShowplan', "XML Showplan")
: escape(c.columnName),
field: i.toString(),
- formatter: c.isXml ? hyperLinkFormatter : queryResultTextFormatter,
+ formatter: c.isXml ? hyperLinkFormatter : (row: number | undefined, cell: any | undefined, value: ICellValue, columnDef: any | undefined, dataContext: any | undefined): string => {
+ return queryResultTextFormatter(this.gridConfig.showJsonAsLink, row, cell, value, columnDef, dataContext);
+ },
width: this.state.columnSizes && this.state.columnSizes[i] ? this.state.columnSizes[i] : undefined
};
});
@@ -535,8 +538,8 @@ export abstract class GridTableBase extends Disposable implements IView {
this.table.setTableTitle(localize('resultsGrid', "Results grid"));
this.table.setSelectionModel(this.selectionModel);
this.table.registerPlugin(new MouseWheelSupport());
- const autoSizeOnRender: boolean = !this.state.columnSizes && this.configurationService.getValue('resultsGrid.autoSizeColumns');
- this.table.registerPlugin(new AutoColumnSize({ autoSizeOnRender: autoSizeOnRender, maxWidth: this.configurationService.getValue('resultsGrid.maxColumnWidth'), extraColumnHeaderWidth: FilterButtonWidth }));
+ const autoSizeOnRender: boolean = !this.state.columnSizes && this.gridConfig.autoSizeColumns;
+ this.table.registerPlugin(new AutoColumnSize({ autoSizeOnRender: autoSizeOnRender, maxWidth: this.gridConfig.maxColumnWidth, extraColumnHeaderWidth: FilterButtonWidth }));
this.table.registerPlugin(this.rowNumberColumn);
this.table.registerPlugin(new AdditionalKeyBindings());
this._register(this.dataProvider.onFilterStateChange(() => { this.layout(); }));
@@ -730,8 +733,7 @@ export abstract class GridTableBase extends Disposable implements IView {
if (column) {
const subset = await this.getRowData(event.cell.row, 1);
const value = subset[0][event.cell.cell - 1];
- const isJson = isJsonCell(value);
- if (column.isXml || isJson) {
+ if (column.isXml || (this.gridConfig.showJsonAsLink && isJsonCell(value))) {
const result = await this.executionPlanService.isExecutionPlan(this.providerId, value.displayValue);
if (result.isExecutionPlan) {
const executionPlanGraphInfo = {
@@ -1002,8 +1004,8 @@ function isJsonCell(value: ICellValue): boolean {
return !!(value && !value.isNull && value.displayValue?.match(IsJsonRegex));
}
-function queryResultTextFormatter(row: number | undefined, cell: any | undefined, value: ICellValue, columnDef: any | undefined, dataContext: any | undefined): string {
- if (isJsonCell(value)) {
+function queryResultTextFormatter(showJsonAsLink: boolean, row: number | undefined, cell: any | undefined, value: ICellValue, columnDef: any | undefined, dataContext: any | undefined): string {
+ if (showJsonAsLink && isJsonCell(value)) {
return hyperLinkFormatter(row, cell, value, columnDef, dataContext);
} else {
return textFormatter(row, cell, value, columnDef, dataContext);
diff --git a/src/sql/workbench/contrib/query/browser/queryResultsEditor.ts b/src/sql/workbench/contrib/query/browser/queryResultsEditor.ts
index 939b65d283..32d81375c1 100644
--- a/src/sql/workbench/contrib/query/browser/queryResultsEditor.ts
+++ b/src/sql/workbench/contrib/query/browser/queryResultsEditor.ts
@@ -21,19 +21,13 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/common/constants';
import { IEditorOptions } from 'vs/platform/editor/common/editor';
+import { IResultGridConfiguration } from 'sql/platform/query/common/query';
export const TextCompareEditorVisible = new RawContextKey('textCompareEditorVisible', false);
export class BareResultsGridInfo extends BareFontInfo {
- public static override createFromRawSettings(opts: {
- fontFamily?: string;
- fontWeight?: string;
- fontSize?: number;
- lineHeight?: number;
- letterSpacing?: number;
- cellPadding?: number | number[];
- }, zoomLevel: number): BareResultsGridInfo {
+ public static override createFromRawSettings(opts: IResultGridConfiguration, zoomLevel: number): BareResultsGridInfo {
let cellPadding = !types.isUndefinedOrNull(opts.cellPadding) ? opts.cellPadding : RESULTS_GRID_DEFAULTS.cellPadding;
return new BareResultsGridInfo(BareFontInfo.createFromRawSettings(opts, PixelRatio.value, false), { cellPadding });
}
diff --git a/src/sql/workbench/contrib/query/common/resultsGrid.contribution.ts b/src/sql/workbench/contrib/query/common/resultsGrid.contribution.ts
index 873a0828bd..3969f8a32e 100644
--- a/src/sql/workbench/contrib/query/common/resultsGrid.contribution.ts
+++ b/src/sql/workbench/contrib/query/common/resultsGrid.contribution.ts
@@ -67,6 +67,11 @@ const resultsGridConfiguration: IConfigurationNode = {
type: 'number',
default: 212,
description: nls.localize('maxColumnWidth', "The maximum width in pixels for auto-sized columns")
+ },
+ 'resultsGrid.showJsonAsLink': {
+ 'type': 'boolean',
+ 'description': nls.localize('resultsGrid.showJsonAsLink', "Whether to show cells with JSON formatted string as hyperlink. When enabled, upon click the JSON value will be opened in another tab. The default value is true."),
+ 'default': true
}
}
};