Skip to content

Commit

Permalink
Use common rendering code path as table data cells for column names
Browse files Browse the repository at this point in the history
  • Loading branch information
wesm committed Dec 19, 2024
1 parent 8c36957 commit dc14c13
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@
font-weight: var(--positron-data-grid-column-header-title-font-weight);
}

.data-grid-column-header
.content
.title-description
.title
.whitespace {
opacity: 50%;
}

.data-grid-column-header
.content
.title-description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { selectionType } from '../utilities/mouseUtilities.js';
import { VerticalSplitter } from '../../../../base/browser/ui/positronComponents/splitters/verticalSplitter.js';
import { ColumnSelectionState } from '../classes/dataGridInstance.js';
import { usePositronDataGridContext } from '../positronDataGridContext.js';
import { getDisplayedColumnName } from '../../../services/positronDataExplorer/common/utils.js';
import { renderLeadingTrailingWhitespace } from '../../../services/positronDataExplorer/browser/components/tableDataCell.js';

/**
* Constants.
Expand Down Expand Up @@ -104,7 +104,7 @@ export const DataGridColumnHeader = (props: DataGridColumnHeaderProps) => {
// Determine whether the column is selected.
const selected = (columnSelectionState & ColumnSelectionState.Selected) !== 0;

const displayedColumnName = getDisplayedColumnName(props.column?.name);
const renderedColumn = renderLeadingTrailingWhitespace(props.column?.name);

// Render.
return (
Expand Down Expand Up @@ -140,7 +140,7 @@ export const DataGridColumnHeader = (props: DataGridColumnHeaderProps) => {
}}
>
<div className='title-description'>
<div className='title'>{displayedColumnName}</div>
<div className='title'>{renderedColumn}</div>
{props.column?.description &&
<div className='description'>{props.column.description}</div>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
grid-column: title / sparkline;
}

.data-grid-row-cell .content .column-summary .basic-info .column-name .whitespace {
opacity: 50%;
}

/* column-sparkline */

.data-grid-row-cell .content .column-summary .basic-info .column-sparkline {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ColumnProfileDatetime } from './columnProfileDatetime.js';
import { TableSummaryDataGridInstance } from '../tableSummaryDataGridInstance.js';
import { ColumnDisplayType, ColumnProfileType, ColumnSchema } from '../../../languageRuntime/common/positronDataExplorerComm.js';
import { dataExplorerExperimentalFeatureEnabled } from '../../common/positronDataExplorerExperimentalConfig.js';
import { getDisplayedColumnName } from '../../common/utils.js';
import { renderLeadingTrailingWhitespace } from './tableDataCell.js';

/**
* Constants.
Expand Down Expand Up @@ -355,6 +355,8 @@ export const ColumnSummaryCell = (props: ColumnSummaryCellProps) => {
break;
}

const renderedColumn = renderLeadingTrailingWhitespace(props.columnSchema.column_name);

// Determine whether this is the cursor.
const cursor = props.columnIndex === props.instance.cursorRowIndex;

Expand Down Expand Up @@ -414,7 +416,7 @@ export const ColumnSummaryCell = (props: ColumnSummaryCellProps) => {
onMouseLeave={() => props.hoverService.hideHover()}
/>
<div className='column-name'>
{getDisplayedColumnName(props.columnSchema.column_name)}
{renderedColumn}
</div>
{!expanded && <ColumnSparkline />}
<ColumnNullPercent />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,28 @@ interface TableDataCellProps {
dataCell: DataCell;
}

/**
* TableDataCell component.
* @param props A TableDataCellProps that contains the component properties.
* @returns The rendered component.
*/
export const TableDataCell = (props: TableDataCellProps) => {
const EMPTY_SPACE_SYMBOL = '\u00B7';
export function renderLeadingTrailingWhitespace(text: string | undefined) {
const parts: (string | JSX.Element)[] = [];

let isSpecialValue = props.dataCell.kind !== DataCellKind.NON_NULL;
text = text ?? '';

// Render empty strings as special value
// Initialize rendered output parts
const parts: (string | JSX.Element)[] = [];
const formattedText = props.dataCell.formatted
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n');
if (text === '') {
// TODO: is this what we want?
return [<span className='whitespace'>{'<empty>'}</span>];
}

const EMPTY_SPACE_SYMBOL = '\u00B7';

// Handle text that is only whitespace
if (formattedText.trim() === '') {
if (text.trim() === '') {
parts.push(
<span className='whitespace'>
{EMPTY_SPACE_SYMBOL.repeat(formattedText.length)}
{EMPTY_SPACE_SYMBOL.repeat(text.length)}
</span>
);
} else {
// Handle leading whitespace
const leadingMatch = formattedText.match(/^\s+/);
const leadingMatch = text.match(/^\s+/);
if (leadingMatch) {
parts.push(
<span className='whitespace'>
Expand All @@ -59,11 +54,11 @@ export const TableDataCell = (props: TableDataCellProps) => {
}

// Add the main content
const mainContent = formattedText.trim();
const mainContent = text.trim();
parts.push(mainContent);

// Handle trailing whitespace
const trailingMatch = formattedText.match(/\s+$/);
const trailingMatch = text.match(/\s+$/);
if (trailingMatch) {
parts.push(
<span className='whitespace'>
Expand All @@ -72,6 +67,26 @@ export const TableDataCell = (props: TableDataCellProps) => {
);
}
}

return parts;
}

/**
* TableDataCell component.
* @param props A TableDataCellProps that contains the component properties.
* @returns The rendered component.
*/
export const TableDataCell = (props: TableDataCellProps) => {
// Render empty strings as special value
// Initialize rendered output parts
const formattedText = props.dataCell.formatted
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n');

const parts = renderLeadingTrailingWhitespace(formattedText);

let isSpecialValue = props.dataCell.kind !== DataCellKind.NON_NULL;

let renderedOutput = parts;
if (props.dataCell.kind === DataCellKind.NON_NULL && formattedText === '') {
isSpecialValue = true;
Expand Down
17 changes: 0 additions & 17 deletions src/vs/workbench/services/positronDataExplorer/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,3 @@ export const arrayFromIndexRange = (startIndex: number, endIndex: number) =>
export const linearConversion = (value: number, from: Range, to: Range) =>
((value - from.min) / (from.max - from.min)) * (to.max - to.min) + to.min;


/**
* Add quoting to column name in case it is an empty string or contains leading whitespace.
* @param name The column name from the backend
* @returns A modified column name that helps distinguish whitespace
*/
export function getDisplayedColumnName(name: string | undefined) {
let result = name ?? '';

const EMPTY_SPACE_SYMBOL = '\u2423';
// If a column name is an empty string (allowed by pandas, at least) or contains
// leading whitespace, then we surround the column name with quotations.
if (result === '' || result.match(/^\s/)) {
result = `"${result}"`.replace(/ /g, EMPTY_SPACE_SYMBOL);
}
return result;
}

0 comments on commit dc14c13

Please sign in to comment.