Table panel: Improve cell inspector (#91862)

* Improve cell inspector

* Update types

* Prettier

* Type checking fixes
pull/91799/head
Kyle Cunningham 9 months ago committed by GitHub
parent aaf33c7923
commit f14fd5828a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      packages/grafana-ui/src/components/Monaco/CodeEditor.tsx
  2. 1
      packages/grafana-ui/src/components/Monaco/types.ts
  3. 4
      packages/grafana-ui/src/components/Table/CellActions.tsx
  4. 5
      packages/grafana-ui/src/components/Table/DefaultCell.tsx
  5. 3
      packages/grafana-ui/src/components/Table/JSONViewCell.tsx
  6. 81
      packages/grafana-ui/src/components/Table/TableCellInspector.tsx

@ -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>
);
}

Loading…
Cancel
Save