mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
handle json (#21915)
This commit is contained in:
@@ -70,7 +70,6 @@ export function hyperLinkFormatter(row: number | undefined, cell: any | undefine
|
|||||||
if (DBCellValue.isDBCellValue(value)) {
|
if (DBCellValue.isDBCellValue(value)) {
|
||||||
valueToDisplay = 'NULL';
|
valueToDisplay = 'NULL';
|
||||||
if (!value.isNull) {
|
if (!value.isNull) {
|
||||||
cellClasses += ' xmlLink';
|
|
||||||
valueToDisplay = getCellDisplayValue(value.displayValue);
|
valueToDisplay = getCellDisplayValue(value.displayValue);
|
||||||
return `<a class="${cellClasses}">${valueToDisplay}</a>`;
|
return `<a class="${cellClasses}">${valueToDisplay}</a>`;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,18 +17,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.slick-cell a,
|
.slick-cell a,
|
||||||
.slick-cell a:link,
|
.resultsMessageValue a {
|
||||||
.resultsMessageValue a,
|
|
||||||
.resultsMessageValue a:link {
|
|
||||||
color: var(--color-grid-link);
|
color: var(--color-grid-link);
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: inherit;
|
white-space: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.resultsMessageValue a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-cell a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.slick-cell a:hover,
|
.slick-cell a:hover,
|
||||||
.resultsMessageValue a:hover {
|
.resultsMessageValue a:hover {
|
||||||
color: var(--color-grid-link-hover);
|
color: var(--color-grid-link-hover);
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -6,40 +6,52 @@
|
|||||||
export interface IQueryEditorConfiguration {
|
export interface IQueryEditorConfiguration {
|
||||||
readonly results: {
|
readonly results: {
|
||||||
readonly saveAsCsv: {
|
readonly saveAsCsv: {
|
||||||
readonly includeHeaders: boolean,
|
readonly includeHeaders: boolean;
|
||||||
readonly delimiter: string,
|
readonly delimiter: string;
|
||||||
readonly lineSeperator: string,
|
readonly lineSeperator: string;
|
||||||
readonly textIdentifier: string,
|
readonly textIdentifier: string;
|
||||||
readonly encoding: string
|
readonly encoding: string;
|
||||||
},
|
};
|
||||||
readonly saveAsExcel: {
|
readonly saveAsExcel: {
|
||||||
readonly includeHeaders: boolean,
|
readonly includeHeaders: boolean;
|
||||||
},
|
};
|
||||||
readonly saveAsMarkdown: {
|
readonly saveAsMarkdown: {
|
||||||
readonly encoding: string,
|
readonly encoding: string;
|
||||||
readonly includeHeaders: boolean,
|
readonly includeHeaders: boolean;
|
||||||
readonly lineSeparator: string,
|
readonly lineSeparator: string;
|
||||||
}
|
};
|
||||||
readonly saveAsXml: {
|
readonly saveAsXml: {
|
||||||
readonly formatted: boolean,
|
readonly formatted: boolean;
|
||||||
readonly encoding: string
|
readonly encoding: string;
|
||||||
},
|
};
|
||||||
readonly streaming: boolean,
|
readonly streaming: boolean;
|
||||||
readonly copyIncludeHeaders: boolean,
|
readonly copyIncludeHeaders: boolean;
|
||||||
readonly copyRemoveNewLine: boolean,
|
readonly copyRemoveNewLine: boolean;
|
||||||
readonly optimizedTable: boolean,
|
readonly optimizedTable: boolean;
|
||||||
readonly inMemoryDataProcessingThreshold: number,
|
readonly inMemoryDataProcessingThreshold: number;
|
||||||
readonly openAfterSave: boolean
|
readonly openAfterSave: boolean;
|
||||||
readonly showActionBar: boolean;
|
readonly showActionBar: boolean;
|
||||||
},
|
},
|
||||||
readonly messages: {
|
readonly messages: {
|
||||||
readonly showBatchTime: boolean,
|
readonly showBatchTime: boolean;
|
||||||
readonly wordwrap: boolean
|
readonly wordwrap: boolean;
|
||||||
},
|
};
|
||||||
readonly chart: {
|
readonly chart: {
|
||||||
readonly defaultChartType: 'bar' | 'doughnut' | 'horizontalBar' | 'line' | 'pie' | 'scatter' | 'timeSeries',
|
readonly defaultChartType: 'bar' | 'doughnut' | 'horizontalBar' | 'line' | 'pie' | 'scatter' | 'timeSeries',
|
||||||
},
|
};
|
||||||
readonly tabColorMode: 'off' | 'border' | 'fill',
|
readonly tabColorMode: 'off' | 'border' | 'fill';
|
||||||
readonly showConnectionInfoInTitle: boolean;
|
readonly showConnectionInfoInTitle: boolean;
|
||||||
readonly promptToSaveGeneratedFiles: 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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/commo
|
|||||||
import { SaveFormat } from 'sql/workbench/services/query/common/resultSerializer';
|
import { SaveFormat } from 'sql/workbench/services/query/common/resultSerializer';
|
||||||
import { Progress } from 'vs/platform/progress/common/progress';
|
import { Progress } from 'vs/platform/progress/common/progress';
|
||||||
import { ScrollableView, IView } from 'sql/base/browser/ui/scrollableView/scrollableView';
|
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 { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||||
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
|
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
|
||||||
import { FilterButtonWidth, HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
import { FilterButtonWidth, HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
||||||
@@ -362,6 +362,7 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
private dataProvider: HybridDataProvider<T>;
|
private dataProvider: HybridDataProvider<T>;
|
||||||
private filterPlugin: HeaderFilter<T>;
|
private filterPlugin: HeaderFilter<T>;
|
||||||
private isDisposed: boolean = false;
|
private isDisposed: boolean = false;
|
||||||
|
private gridConfig: IResultGridConfiguration;
|
||||||
|
|
||||||
private columns: Slick.Column<T>[];
|
private columns: Slick.Column<T>[];
|
||||||
|
|
||||||
@@ -417,8 +418,8 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.options = { ...defaultGridTableOptions, ...options };
|
this.options = { ...defaultGridTableOptions, ...options };
|
||||||
let config = this.configurationService.getValue<{ rowHeight: number }>('resultsGrid');
|
this.gridConfig = this.configurationService.getValue<IResultGridConfiguration>('resultsGrid');
|
||||||
this.rowHeight = config && config.rowHeight ? config.rowHeight : ROW_HEIGHT;
|
this.rowHeight = this.gridConfig.rowHeight ?? ROW_HEIGHT;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.container.style.width = '100%';
|
this.container.style.width = '100%';
|
||||||
this.container.style.height = '100%';
|
this.container.style.height = '100%';
|
||||||
@@ -430,7 +431,9 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
? localize('xmlShowplan', "XML Showplan")
|
? localize('xmlShowplan', "XML Showplan")
|
||||||
: escape(c.columnName),
|
: escape(c.columnName),
|
||||||
field: i.toString(),
|
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
|
width: this.state.columnSizes && this.state.columnSizes[i] ? this.state.columnSizes[i] : undefined
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -535,8 +538,8 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
this.table.setTableTitle(localize('resultsGrid', "Results grid"));
|
this.table.setTableTitle(localize('resultsGrid', "Results grid"));
|
||||||
this.table.setSelectionModel(this.selectionModel);
|
this.table.setSelectionModel(this.selectionModel);
|
||||||
this.table.registerPlugin(new MouseWheelSupport());
|
this.table.registerPlugin(new MouseWheelSupport());
|
||||||
const autoSizeOnRender: boolean = !this.state.columnSizes && this.configurationService.getValue('resultsGrid.autoSizeColumns');
|
const autoSizeOnRender: boolean = !this.state.columnSizes && this.gridConfig.autoSizeColumns;
|
||||||
this.table.registerPlugin(new AutoColumnSize({ autoSizeOnRender: autoSizeOnRender, maxWidth: this.configurationService.getValue<number>('resultsGrid.maxColumnWidth'), extraColumnHeaderWidth: FilterButtonWidth }));
|
this.table.registerPlugin(new AutoColumnSize({ autoSizeOnRender: autoSizeOnRender, maxWidth: this.gridConfig.maxColumnWidth, extraColumnHeaderWidth: FilterButtonWidth }));
|
||||||
this.table.registerPlugin(this.rowNumberColumn);
|
this.table.registerPlugin(this.rowNumberColumn);
|
||||||
this.table.registerPlugin(new AdditionalKeyBindings());
|
this.table.registerPlugin(new AdditionalKeyBindings());
|
||||||
this._register(this.dataProvider.onFilterStateChange(() => { this.layout(); }));
|
this._register(this.dataProvider.onFilterStateChange(() => { this.layout(); }));
|
||||||
@@ -730,8 +733,7 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
|
|||||||
if (column) {
|
if (column) {
|
||||||
const subset = await this.getRowData(event.cell.row, 1);
|
const subset = await this.getRowData(event.cell.row, 1);
|
||||||
const value = subset[0][event.cell.cell - 1];
|
const value = subset[0][event.cell.cell - 1];
|
||||||
const isJson = isJsonCell(value);
|
if (column.isXml || (this.gridConfig.showJsonAsLink && isJsonCell(value))) {
|
||||||
if (column.isXml || isJson) {
|
|
||||||
const result = await this.executionPlanService.isExecutionPlan(this.providerId, value.displayValue);
|
const result = await this.executionPlanService.isExecutionPlan(this.providerId, value.displayValue);
|
||||||
if (result.isExecutionPlan) {
|
if (result.isExecutionPlan) {
|
||||||
const executionPlanGraphInfo = {
|
const executionPlanGraphInfo = {
|
||||||
@@ -1002,8 +1004,8 @@ function isJsonCell(value: ICellValue): boolean {
|
|||||||
return !!(value && !value.isNull && value.displayValue?.match(IsJsonRegex));
|
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 {
|
function queryResultTextFormatter(showJsonAsLink: boolean, row: number | undefined, cell: any | undefined, value: ICellValue, columnDef: any | undefined, dataContext: any | undefined): string {
|
||||||
if (isJsonCell(value)) {
|
if (showJsonAsLink && isJsonCell(value)) {
|
||||||
return hyperLinkFormatter(row, cell, value, columnDef, dataContext);
|
return hyperLinkFormatter(row, cell, value, columnDef, dataContext);
|
||||||
} else {
|
} else {
|
||||||
return textFormatter(row, cell, value, columnDef, dataContext);
|
return textFormatter(row, cell, value, columnDef, dataContext);
|
||||||
|
|||||||
@@ -21,19 +21,13 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
|||||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/common/constants';
|
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/common/constants';
|
||||||
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||||
|
import { IResultGridConfiguration } from 'sql/platform/query/common/query';
|
||||||
|
|
||||||
export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareEditorVisible', false);
|
export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareEditorVisible', false);
|
||||||
|
|
||||||
export class BareResultsGridInfo extends BareFontInfo {
|
export class BareResultsGridInfo extends BareFontInfo {
|
||||||
|
|
||||||
public static override createFromRawSettings(opts: {
|
public static override createFromRawSettings(opts: IResultGridConfiguration, zoomLevel: number): BareResultsGridInfo {
|
||||||
fontFamily?: string;
|
|
||||||
fontWeight?: string;
|
|
||||||
fontSize?: number;
|
|
||||||
lineHeight?: number;
|
|
||||||
letterSpacing?: number;
|
|
||||||
cellPadding?: number | number[];
|
|
||||||
}, zoomLevel: number): BareResultsGridInfo {
|
|
||||||
let cellPadding = !types.isUndefinedOrNull(opts.cellPadding) ? opts.cellPadding : RESULTS_GRID_DEFAULTS.cellPadding;
|
let cellPadding = !types.isUndefinedOrNull(opts.cellPadding) ? opts.cellPadding : RESULTS_GRID_DEFAULTS.cellPadding;
|
||||||
return new BareResultsGridInfo(BareFontInfo.createFromRawSettings(opts, PixelRatio.value, false), { cellPadding });
|
return new BareResultsGridInfo(BareFontInfo.createFromRawSettings(opts, PixelRatio.value, false), { cellPadding });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ const resultsGridConfiguration: IConfigurationNode = {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
default: 212,
|
default: 212,
|
||||||
description: nls.localize('maxColumnWidth', "The maximum width in pixels for auto-sized columns")
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user