Table panel: Improve cell inspector (#91862)
* Improve cell inspector * Update types * Prettier * Type checking fixes
This commit is contained in:
@@ -129,7 +129,8 @@ class UnthemedCodeEditor extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { theme, language, width, height, showMiniMap, showLineNumbers, readOnly, monacoOptions } = this.props;
|
||||
const { theme, language, width, height, showMiniMap, showLineNumbers, readOnly, wordWrap, monacoOptions } =
|
||||
this.props;
|
||||
const { alwaysConsumeMouseWheel, ...restMonacoOptions } = monacoOptions ?? {};
|
||||
|
||||
const value = this.props.value ?? '';
|
||||
@@ -138,7 +139,7 @@ class UnthemedCodeEditor extends PureComponent<Props> {
|
||||
const containerStyles = this.props.containerStyles ?? getStyles(theme).container;
|
||||
|
||||
const options: MonacoOptions = {
|
||||
wordWrap: 'off',
|
||||
wordWrap: wordWrap ? 'on' : 'off',
|
||||
tabSize: 2,
|
||||
codeLens: false,
|
||||
contextmenu: false,
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface CodeEditorProps {
|
||||
readOnly?: boolean;
|
||||
showMiniMap?: boolean;
|
||||
showLineNumbers?: boolean;
|
||||
wordWrap?: boolean;
|
||||
monacoOptions?: MonacoOptions;
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,12 +6,12 @@ import { IconButton } from '../IconButton/IconButton';
|
||||
import { Stack } from '../Layout/Stack/Stack';
|
||||
import { TooltipPlacement } from '../Tooltip';
|
||||
|
||||
import { TableCellInspector } from './TableCellInspector';
|
||||
import { TableCellInspector, TableCellInspectorMode } from './TableCellInspector';
|
||||
import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableCellProps } from './types';
|
||||
import { getTextAlign } from './utils';
|
||||
|
||||
interface CellActionProps extends TableCellProps {
|
||||
previewMode: 'text' | 'code';
|
||||
previewMode: TableCellInspectorMode;
|
||||
}
|
||||
|
||||
interface CommonButtonProps {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { clearLinkButtonStyles } from '../Button';
|
||||
import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu';
|
||||
|
||||
import { CellActions } from './CellActions';
|
||||
import { TableCellInspectorMode } from './TableCellInspector';
|
||||
import { TableStyles } from './styles';
|
||||
import { TableCellProps, CustomCellRendererProps, TableCellOptions } from './types';
|
||||
import { getCellColors, getCellOptions } from './utils';
|
||||
@@ -114,7 +115,9 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
</DataLinksContextMenu>
|
||||
)}
|
||||
|
||||
{hover && showActions && <CellActions {...props} previewMode="text" showFilters={showFilters} />}
|
||||
{hover && showActions && (
|
||||
<CellActions {...props} previewMode={TableCellInspectorMode.text} showFilters={showFilters} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button, clearLinkButtonStyles } from '../Button';
|
||||
import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu';
|
||||
|
||||
import { CellActions } from './CellActions';
|
||||
import { TableCellInspectorMode } from './TableCellInspector';
|
||||
import { TableCellProps } from './types';
|
||||
|
||||
export function JSONViewCell(props: TableCellProps): JSX.Element {
|
||||
@@ -51,7 +52,7 @@ export function JSONViewCell(props: TableCellProps): JSX.Element {
|
||||
</DataLinksContextMenu>
|
||||
)}
|
||||
</div>
|
||||
{inspectEnabled && <CellActions {...props} previewMode="code" />}
|
||||
{inspectEnabled && <CellActions {...props} previewMode={TableCellInspectorMode.code} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,57 +1,84 @@
|
||||
import { isString } from 'lodash';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ClipboardButton } from '../ClipboardButton/ClipboardButton';
|
||||
import { Drawer } from '../Drawer/Drawer';
|
||||
import { Stack } from '../Layout/Stack/Stack';
|
||||
import { CodeEditor } from '../Monaco/CodeEditor';
|
||||
import { Tab, TabsBar } from '../Tabs';
|
||||
|
||||
export enum TableCellInspectorMode {
|
||||
code = 'code',
|
||||
text = 'text',
|
||||
}
|
||||
|
||||
interface TableCellInspectorProps {
|
||||
value: any;
|
||||
onDismiss: () => void;
|
||||
mode: 'code' | 'text';
|
||||
mode: TableCellInspectorMode;
|
||||
}
|
||||
|
||||
export function TableCellInspector({ value, onDismiss, mode }: TableCellInspectorProps) {
|
||||
let displayValue = value;
|
||||
const [currentMode, setMode] = useState(mode);
|
||||
|
||||
if (isString(value)) {
|
||||
const trimmedValue = value.trim();
|
||||
// Exclude numeric strings like '123' from being displayed in code/JSON mode
|
||||
if (trimmedValue[0] === '{' || trimmedValue[0] === '[' || mode === 'code') {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
mode = 'code';
|
||||
} catch {
|
||||
mode = 'text';
|
||||
} // ignore errors
|
||||
} else {
|
||||
mode = 'text';
|
||||
} catch {}
|
||||
}
|
||||
} else {
|
||||
displayValue = JSON.stringify(value, null, ' ');
|
||||
}
|
||||
let text = displayValue;
|
||||
|
||||
if (mode === 'code') {
|
||||
text = JSON.stringify(value, null, ' ');
|
||||
}
|
||||
const tabs = [
|
||||
{
|
||||
label: 'Plain text',
|
||||
value: 'text',
|
||||
},
|
||||
{
|
||||
label: 'Code editor',
|
||||
value: 'code',
|
||||
},
|
||||
];
|
||||
|
||||
const changeTabs = () => {
|
||||
setMode(currentMode === TableCellInspectorMode.text ? TableCellInspectorMode.code : TableCellInspectorMode.text);
|
||||
};
|
||||
|
||||
const tabBar = (
|
||||
<TabsBar>
|
||||
{tabs.map((t, index) => (
|
||||
<Tab key={`${t.value}-${index}`} label={t.label} active={t.value === currentMode} onChangeTab={changeTabs} />
|
||||
))}
|
||||
</TabsBar>
|
||||
);
|
||||
|
||||
return (
|
||||
<Drawer onClose={onDismiss} title="Inspect value">
|
||||
{mode === 'code' ? (
|
||||
<CodeEditor
|
||||
width="100%"
|
||||
height={500}
|
||||
language="json"
|
||||
showLineNumbers={true}
|
||||
showMiniMap={(text && text.length) > 100}
|
||||
value={text}
|
||||
readOnly={true}
|
||||
/>
|
||||
) : (
|
||||
<pre>{text}</pre>
|
||||
)}
|
||||
<ClipboardButton icon="copy" getText={() => text}>
|
||||
Copy to Clipboard
|
||||
</ClipboardButton>
|
||||
<Drawer onClose={onDismiss} title="Inspect value" tabs={tabBar}>
|
||||
<Stack direction="column" gap={2}>
|
||||
<ClipboardButton icon="copy" getText={() => text} style={{ marginLeft: 'auto', width: '200px' }}>
|
||||
Copy to Clipboard
|
||||
</ClipboardButton>
|
||||
{currentMode === 'code' ? (
|
||||
<CodeEditor
|
||||
width="100%"
|
||||
height={500}
|
||||
language="json"
|
||||
showLineNumbers={true}
|
||||
showMiniMap={(text && text.length) > 100}
|
||||
value={text}
|
||||
readOnly={true}
|
||||
wordWrap={true}
|
||||
/>
|
||||
) : (
|
||||
<pre>{text}</pre>
|
||||
)}
|
||||
</Stack>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user