fix json cell handling issue (#19310)

* fix json cell handling issue

* pr comment
This commit is contained in:
Alan Ren
2022-05-09 16:54:06 -07:00
committed by GitHub
parent 51e5890c83
commit 75ab9b6812

View File

@@ -65,6 +65,13 @@ const ACTIONBAR_HEIGHT = 120;
// this handles min size if rows is greater than the min grid visible rows
const MIN_GRID_HEIGHT = (MIN_GRID_HEIGHT_ROWS * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT;
// The regex to check whether a string is a valid JSON string. It is used to determine:
// 1. whether the cell should be rendered as a hyperlink.
// 2. when user clicks a cell, whether the cell content should be displayed in a new text editor as json.
// Based on the requirements, the solution doesn't need to be very accurate, a simple regex is enough since it is more
// performant than trying to parse the string to object.
const IsJsonRegex = /({.*?})/g;
export class GridPanel extends Disposable {
private container = document.createElement('div');
private scrollableView: ScrollableView;
@@ -395,15 +402,13 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
this.container.style.height = '100%';
this.columns = this.resultSet.columnInfo.map((c, i) => {
let isLinked = c.isXml || c.isJson;
return <Slick.Column<T>>{
id: i.toString(),
name: c.columnName === 'Microsoft SQL Server 2005 XML Showplan'
? localize('xmlShowplan', "XML Showplan")
: escape(c.columnName),
field: i.toString(),
formatter: isLinked ? hyperLinkFormatter : textFormatter,
formatter: c.isXml ? hyperLinkFormatter : queryResultTextFormatter,
width: this.state.columnSizes && this.state.columnSizes[i] ? this.state.columnSizes[i] : undefined
};
});
@@ -693,17 +698,20 @@ export abstract class GridTableBase<T> extends Disposable implements IView {
private async onTableClick(event: ITableMouseEvent) {
// account for not having the number column
let column = this.resultSet.columnInfo[event.cell.cell - 1];
const column = this.resultSet.columnInfo[event.cell.cell - 1];
// handle if a showplan link was clicked
if (column && (column.isXml || column.isJson)) {
if (column) {
const subset = await this.getRowData(event.cell.row, 1);
let value = subset[0][event.cell.cell - 1];
let content = value.displayValue;
const input = this.untitledEditorService.create({ mode: column.isXml ? 'xml' : 'json', initialValue: content });
await input.resolve();
await this.instantiationService.invokeFunction(formatDocumentWithSelectedProvider, input.textEditorModel, FormattingMode.Explicit, Progress.None, CancellationToken.None);
input.setDirty(false);
await this.editorService.openEditor(input);
const value = subset[0][event.cell.cell - 1];
const isJson = isJsonCell(value);
if (column.isXml || isJson) {
const content = value.displayValue;
const input = this.untitledEditorService.create({ mode: column.isXml ? 'xml' : 'json', initialValue: content });
await input.resolve();
await this.instantiationService.invokeFunction(formatDocumentWithSelectedProvider, input.textEditorModel, FormattingMode.Explicit, Progress.None, CancellationToken.None);
input.setDirty(false);
await this.editorService.openEditor(input);
}
}
}
@@ -936,3 +944,15 @@ class GridTable<T> extends GridTableBase<T> {
];
}
}
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)) {
return hyperLinkFormatter(row, cell, value, columnDef, dataContext);
} else {
return textFormatter(row, cell, value, columnDef, dataContext);
}
}