diff --git a/e2e/suite1/specs/inspect-drawer.spec.ts b/e2e/suite1/specs/inspect-drawer.spec.ts index 70210875b45..efbee7782e7 100644 --- a/e2e/suite1/specs/inspect-drawer.spec.ts +++ b/e2e/suite1/specs/inspect-drawer.spec.ts @@ -74,9 +74,24 @@ const expectDrawerTabsAndContent = () => { e2e.components.PanelInspector.Stats.content().should('not.be.visible'); e2e.components.PanelInspector.Query.content().should('not.be.visible'); + e2e().wait(250); + /* Monaco Editor specific wait that fixes error below https://github.com/microsoft/monaco-editor/issues/354 + TypeError: Cannot read property 'getText' of null + at Object.getFoldingRanges (http://localhost:3001/public/build/json.worker.js:18829:102) + at JSONWorker.getFoldingRanges (http://localhost:3001/public/build/json.worker.js:23818:40) + at EditorSimpleWorker.fmr (http://localhost:3001/public/build/json.worker.js:10407:58) + at SimpleWorkerServer._handleMessage (http://localhost:3001/public/build/json.worker.js:6939:59) + at Object.handleMessage (http://localhost:3001/public/build/json.worker.js:6920:22) + at SimpleWorkerProtocol._handleMessage (http://localhost:3001/public/build/json.worker.js:6757:32) + at SimpleWorkerProtocol.handleMessage (http://localhost:3001/public/build/json.worker.js:6719:10) + at SimpleWorkerServer.onmessage (http://localhost:3001/public/build/json.worker.js:6926:20) + at self.onmessage (http://localhost:3001/public/build/json.worker.js:12050:18) + */ + e2e.components.Tab.title('Query') .should('be.visible') .click(); + e2e.components.PanelInspector.Query.content().should('be.visible'); e2e.components.PanelInspector.Data.content().should('not.be.visible'); e2e.components.PanelInspector.Stats.content().should('not.be.visible'); diff --git a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts index 925e89c2987..2fe708b94c4 100644 --- a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts +++ b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts @@ -3,17 +3,18 @@ import { ComponentType } from 'react'; import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; import { DataFrame, InterpolateFunction, VariableSuggestionsScope, VariableSuggestion } from '../types'; -export interface StandardEditorContext { +export interface StandardEditorContext { data?: DataFrame[]; // All results replaceVariables?: InterpolateFunction; getSuggestions?: (scope?: VariableSuggestionsScope) => VariableSuggestion[]; + options?: TOptions; } -export interface StandardEditorProps { +export interface StandardEditorProps { value: TValue; onChange: (value?: TValue) => void; item: StandardEditorsRegistryItem; - context: StandardEditorContext; + context: StandardEditorContext; } export interface StandardEditorsRegistryItem extends RegistryItem { editor: ComponentType>; diff --git a/packages/grafana-data/src/types/fieldOverrides.ts b/packages/grafana-data/src/types/fieldOverrides.ts index 55b0d115095..44f60d3bb6c 100644 --- a/packages/grafana-data/src/types/fieldOverrides.ts +++ b/packages/grafana-data/src/types/fieldOverrides.ts @@ -22,7 +22,7 @@ export interface FieldConfigSource { overrides: ConfigOverrideRule[]; } -export interface FieldOverrideContext extends StandardEditorContext { +export interface FieldOverrideContext extends StandardEditorContext { field?: Field; dataFrameIndex?: number; // The index for the selected field frame data: DataFrame[]; // All results diff --git a/public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx b/public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx index 8cc0eec485a..401862b6a9c 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx @@ -1,10 +1,10 @@ import React, { useMemo } from 'react'; import { + DataFrame, + InterpolateFunction, PanelOptionsEditorItem, PanelPlugin, - DataFrame, StandardEditorContext, - InterpolateFunction, } from '@grafana/data'; import { get as lodashGet, set as lodashSet } from 'lodash'; import { Field, Label } from '@grafana/ui'; @@ -37,9 +37,10 @@ export const PanelOptionsEditor: React.FC> = ({ onChange(newOptions); }; - const context: StandardEditorContext = { + const context: StandardEditorContext = { data: data ?? [], replaceVariables, + options, }; return ( diff --git a/public/app/plugins/panel/text/TextPanelEditor.tsx b/public/app/plugins/panel/text/TextPanelEditor.tsx new file mode 100644 index 00000000000..39936acbbba --- /dev/null +++ b/public/app/plugins/panel/text/TextPanelEditor.tsx @@ -0,0 +1,46 @@ +import React, { FC, useMemo } from 'react'; +import { css, cx } from 'emotion'; +import AutoSizer from 'react-virtualized-auto-sizer'; +import { CodeEditor, stylesFactory, useTheme } from '@grafana/ui'; +import { GrafanaTheme, StandardEditorProps } from '@grafana/data'; + +import { TextOptions } from './types'; + +export const TextPanelEditor: FC> = ({ value, onChange, context }) => { + const language = useMemo(() => context.options?.mode ?? 'markdown', [context]); + const theme = useTheme(); + const styles = getStyles(theme); + return ( +
+ + {({ width }) => { + if (width === 0) { + return null; + } + + return ( + + ); + }} + +
+ ); +}; + +const getStyles = stylesFactory((theme: GrafanaTheme) => ({ + editorBox: css` + label: editorBox; + border: ${theme.border.width.sm} solid ${theme.colors.border2}; + border-radius: ${theme.border.radius.sm}; + margin: ${theme.spacing.xs} 0; + width: 100%; + `, +})); diff --git a/public/app/plugins/panel/text/module.tsx b/public/app/plugins/panel/text/module.tsx index 206e8f17f0a..d9cdd384d31 100644 --- a/public/app/plugins/panel/text/module.tsx +++ b/public/app/plugins/panel/text/module.tsx @@ -3,6 +3,7 @@ import { PanelPlugin } from '@grafana/data'; import { TextPanel } from './TextPanel'; import { TextOptions } from './types'; import { textPanelMigrationHandler } from './textPanelMigrationHandler'; +import { TextPanelEditor } from './TextPanelEditor'; export const plugin = new PanelPlugin(TextPanel) .setPanelOptions(builder => { @@ -19,18 +20,16 @@ export const plugin = new PanelPlugin(TextPanel) }, defaultValue: 'markdown', }) - .addTextInput({ + .addCustomEditor({ + id: 'content', path: 'content', name: 'Content', description: 'Content of the panel', - settings: { - useTextarea: true, - rows: 5, - }, defaultValue: `# Title For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/) `, + editor: TextPanelEditor, }); }) .setMigrationHandler(textPanelMigrationHandler);