diff --git a/src/sql/base/browser/ui/table/formatters.ts b/src/sql/base/browser/ui/table/formatters.ts index bd0e7f63bf..9857ee2ebf 100644 --- a/src/sql/base/browser/ui/table/formatters.ts +++ b/src/sql/base/browser/ui/table/formatters.ts @@ -85,7 +85,7 @@ export function hyperLinkFormatter(row: number | undefined, cell: any | undefine /** * Format all text to replace all new lines with spaces and performs HTML entity encoding */ -export function textFormatter(row: number | undefined, cell: any | undefined, value: any, columnDef: any | undefined, dataContext: any | undefined): string { +export function textFormatter(row: number | undefined, cell: any | undefined, value: any, columnDef: any | undefined, dataContext: any | undefined, addClasses?: string): string | { text: string, addClasses: string } { let cellClasses = 'grid-cell-value-container'; let valueToDisplay = ''; let titleValue = ''; @@ -122,7 +122,13 @@ export function textFormatter(row: number | undefined, cell: any | undefined, va titleValue = valueToDisplay; } - return `${valueToDisplay}`; + const formattedValue = `${valueToDisplay}`; + + if (addClasses) { + return { text: formattedValue, addClasses: addClasses }; + } + + return formattedValue; } function getCellDisplayValue(cellValue: string): string { @@ -132,7 +138,7 @@ function getCellDisplayValue(cellValue: string): string { } -export function iconCssFormatter(row: number | undefined, cell: any | undefined, value: any, columnDef: any | undefined, dataContext: any | undefined): string { +export function iconCssFormatter(row: number | undefined, cell: any | undefined, value: any, columnDef: any | undefined, dataContext: any | undefined): string | { text: string, addClasses: string } { if (isCssIconCellValue(value)) { return `
`; } diff --git a/src/sql/base/test/browser/ui/table/gridFormatters.test.ts b/src/sql/base/test/browser/ui/table/gridFormatters.test.ts index e6f61ed819..0a59bcbdd8 100644 --- a/src/sql/base/test/browser/ui/table/gridFormatters.test.ts +++ b/src/sql/base/test/browser/ui/table/gridFormatters.test.ts @@ -16,6 +16,9 @@ suite('Grid shared services tests', () => { isNull: false }; let formattedHtml = SharedServices.textFormatter(undefined, undefined, cellValue, undefined, undefined); + if (typeof formattedHtml !== 'string') { + formattedHtml = formattedHtml.text; + } // Then the result is HTML for a span element containing the cell value's display value as plain text verifyFormattedHtml(formattedHtml, testText); @@ -24,6 +27,9 @@ suite('Grid shared services tests', () => { test('textFormatter should encode HTML when formatting a string', () => { // If I format a string that contains HTML let formattedHtml = SharedServices.textFormatter(undefined, undefined, testText, undefined, undefined); + if (typeof formattedHtml !== 'string') { + formattedHtml = formattedHtml.text; + } // Then the result is HTML for a span element containing the given text as plain text verifyFormattedHtml(formattedHtml, testText); diff --git a/src/sql/platform/theme/common/colorRegistry.ts b/src/sql/platform/theme/common/colorRegistry.ts index 1270080742..4467a68a00 100644 --- a/src/sql/platform/theme/common/colorRegistry.ts +++ b/src/sql/platform/theme/common/colorRegistry.ts @@ -91,3 +91,6 @@ export const calloutDialogShadowColor = registerColor('calloutDialog.shadow', { // Designer export const DesignerPaneSeparator = registerColor('designer.paneSeparator', { light: '#DDDDDD', dark: '#8A8886', hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('designer.paneSeparator', 'The pane separator color.')); + +// Query Editor +export const queryEditorNullBackground = registerColor('queryEditor.nullBackground', { light: '#FFFFE1', dark: '#4B0082', hcDark: '#000000', hcLight: '#FFFFE1' }, nls.localize('queryEditorNullBackground', 'The background color for null values in the query editor results grid.')); diff --git a/src/sql/workbench/contrib/query/browser/gridPanel.ts b/src/sql/workbench/contrib/query/browser/gridPanel.ts index cae0f989f1..653f837e8c 100644 --- a/src/sql/workbench/contrib/query/browser/gridPanel.ts +++ b/src/sql/workbench/contrib/query/browser/gridPanel.ts @@ -17,14 +17,14 @@ import { IGridActionContext, SaveResultAction, CopyResultAction, SelectAllGridAc import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin'; import { RowNumberColumn } from 'sql/base/browser/ui/table/plugins/rowNumberColumn.plugin'; import { escape } from 'sql/base/common/strings'; -import { hyperLinkFormatter, textFormatter } from 'sql/base/browser/ui/table/formatters'; +import { DBCellValue, hyperLinkFormatter, textFormatter } from 'sql/base/browser/ui/table/formatters'; import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Emitter, Event } from 'vs/base/common/event'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { Disposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { range } from 'vs/base/common/arrays'; @@ -56,6 +56,7 @@ import { CopyAction } from 'vs/editor/contrib/clipboard/browser/clipboard'; import { formatDocumentWithSelectedProvider, FormattingMode } from 'vs/editor/contrib/format/browser/format'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { queryEditorNullBackground } from 'sql/platform/theme/common/colorRegistry'; const ROW_HEIGHT = 29; const HEADER_HEIGHT = 26; @@ -80,6 +81,9 @@ const MIN_GRID_HEIGHT = (MIN_GRID_HEIGHT_ROWS * ROW_HEIGHT) + HEADER_HEIGHT + ES // or '{', and there must be a '}' or ']' to close it. const IsJsonRegex = /^\s*[\{|\[][\S\s]*[\}\]]\s*$/g; +// The css class for null cell +const NULL_CELL_CSS_CLASS = 'cell-null'; + export class GridPanel extends Disposable { private container = document.createElement('div'); private scrollableView: ScrollableView; @@ -431,7 +435,7 @@ export abstract class GridTableBase