diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 74c8a804673e..cb3d29d11752 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1059,7 +1059,6 @@ playwright.storybook.config.ts @grafana/grafana-frontend-platform /public/app/plugins/panel/text/ @grafana/dataviz-squad /public/app/plugins/panel/textng/ @grafana/dataviz-squad /public/app/plugins/panel/welcome/ @grafana/grafana-frontend-navigation -/public/app/plugins/schemas/ @grafana/dataviz-squad /public/app/plugins/panel/xychart/ @grafana/dataviz-squad /public/app/routes/ @grafana/grafana-frontend-navigation /public/app/store/ @grafana/grafana-frontend-platform diff --git a/packages/grafana-schema/src/raw/composable/textng/panelcfg/x/types.gen.ts b/packages/grafana-schema/src/raw/composable/textng/panelcfg/x/types.gen.ts deleted file mode 100644 index 33578c773785..000000000000 --- a/packages/grafana-schema/src/raw/composable/textng/panelcfg/x/types.gen.ts +++ /dev/null @@ -1,59 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. -// -// Generated by: -// public/app/plugins/gen.go -// Using jennies: -// TSTypesJenny -// PluginTsTypesJenny -// -// Run 'make gen-cue' from repository root to regenerate. - -// Generated from public/app/plugins/panel/textng/panelcfg.cue file. - -export const pluginVersion = "13.2.0-pre"; - -export enum TextMode { - Code = 'code', - HTML = 'html', - Markdown = 'markdown', -} - -export enum CodeLanguage { - Go = 'go', - Html = 'html', - Json = 'json', - Markdown = 'markdown', - Plaintext = 'plaintext', - Sql = 'sql', - Typescript = 'typescript', - Xml = 'xml', - Yaml = 'yaml', -} - -export const defaultCodeLanguage: CodeLanguage = CodeLanguage.Plaintext; - -export interface CodeOptions { - /** - * The language passed to the CodeMirror editor - */ - language: CodeLanguage; - showLineNumbers: boolean; -} - -export const defaultCodeOptions: Partial = { - language: CodeLanguage.Plaintext, - showLineNumbers: false, -}; - -export interface Options { - code?: CodeOptions; - content: string; - mode: TextMode; -} - -export const defaultOptions: Partial = { - content: `# Title - -For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)`, - mode: TextMode.Markdown, -}; diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 6f2224326494..f6f72c9f84dd 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -64,14 +64,8 @@ ], "dependencies": { "@codemirror/autocomplete": "^6.20.1", - "@codemirror/lang-go": "^6.0.1", - "@codemirror/lang-html": "^6.4.11", - "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lang-json": "^6.0.2", - "@codemirror/lang-markdown": "^6.5.1", "@codemirror/lang-sql": "^6.10.0", - "@codemirror/lang-xml": "^6.1.0", - "@codemirror/lang-yaml": "^6.1.3", "@codemirror/language": "^6.12.3", "@codemirror/state": "^6.6.0", "@codemirror/view": "^6.41.0", diff --git a/packages/grafana-ui/src/components/CodeMirror/CodeEditor.story.tsx b/packages/grafana-ui/src/components/CodeMirror/CodeEditor.story.tsx index 762b6e6a519a..c959413fabfb 100644 --- a/packages/grafana-ui/src/components/CodeMirror/CodeEditor.story.tsx +++ b/packages/grafana-ui/src/components/CodeMirror/CodeEditor.story.tsx @@ -6,16 +6,7 @@ import { CodeEditor } from './CodeEditor'; import mdx from './CodeEditor.mdx'; import type { CodeMirrorCompletionSource, CodeMirrorEditorLanguage } from './types'; -const languageOptions: CodeMirrorEditorLanguage[] = [ - 'go', - 'html', - 'json', - 'markdown', - 'sql', - 'typescript', - 'xml', - 'yaml', -]; +const languageOptions: CodeMirrorEditorLanguage[] = ['sql', 'json']; const keywordCompletionSource: CodeMirrorCompletionSource = (context) => { const word = context.matchBefore(/\w*/); diff --git a/packages/grafana-ui/src/components/CodeMirror/CodeEditor.tsx b/packages/grafana-ui/src/components/CodeMirror/CodeEditor.tsx index 385c1b3b5315..71f86b6b12e3 100644 --- a/packages/grafana-ui/src/components/CodeMirror/CodeEditor.tsx +++ b/packages/grafana-ui/src/components/CodeMirror/CodeEditor.tsx @@ -96,8 +96,6 @@ export const CodeEditor = memo(function CodeEditor({ theme: themeOverride, basicSetup, indentWithTab = true, - readOnly = false, - lineWrapping = false, }: CodeMirrorEditorProps) { const theme = useTheme2(); const { extension: languageExtension, error: languageExtensionError } = useLanguageExtension(language, sqlDialect); @@ -109,18 +107,9 @@ export const CodeEditor = memo(function CodeEditor({ ...getAccessibilityExtensions(ariaLabel, ariaLabelledby), ...(languageExtension ? [languageExtension] : []), ...getCompletionExtensions(completionSources, completionMode), - ...(lineWrapping ? [EditorView.lineWrapping] : []), ...(additionalExtensions ?? []), ], - [ - ariaLabel, - ariaLabelledby, - languageExtension, - completionSources, - completionMode, - lineWrapping, - additionalExtensions, - ] + [ariaLabel, ariaLabelledby, languageExtension, completionSources, completionMode, additionalExtensions] ); return ( <> @@ -140,7 +129,6 @@ export const CodeEditor = memo(function CodeEditor({ onChange={onChange} basicSetup={basicSetup} indentWithTab={indentWithTab} - readOnly={readOnly} /> ); diff --git a/packages/grafana-ui/src/components/CodeMirror/CodeEditorLazy.tsx b/packages/grafana-ui/src/components/CodeMirror/CodeEditorLazy.tsx index 6a0826eb453e..c000cf8ad112 100644 --- a/packages/grafana-ui/src/components/CodeMirror/CodeEditorLazy.tsx +++ b/packages/grafana-ui/src/components/CodeMirror/CodeEditorLazy.tsx @@ -21,11 +21,7 @@ export function CodeMirrorEditor(props: CodeMirrorEditorProps) { style="page" > - ) - } + fallback={} > diff --git a/packages/grafana-ui/src/components/CodeMirror/languageLoader.test.ts b/packages/grafana-ui/src/components/CodeMirror/languageLoader.test.ts index 8c5008dd11e0..ce86e1617a32 100644 --- a/packages/grafana-ui/src/components/CodeMirror/languageLoader.test.ts +++ b/packages/grafana-ui/src/components/CodeMirror/languageLoader.test.ts @@ -81,31 +81,4 @@ describe('loadLanguageExtension', () => { expect(standardAgain).toBe(standard); }); }); - - it.each(['go', 'html', 'json', 'markdown', 'typescript', 'xml', 'yaml'] as const)( - 'loads and memoizes the %s extension', - async (language) => { - await jest.isolateModulesAsync(async () => { - const { loadLanguageExtension } = await import('./languageLoader'); - const { Language } = await import('@codemirror/language'); - - const extension = await loadLanguageExtension(language); - const again = await loadLanguageExtension(language); - - expect(extension).toHaveProperty('language', expect.any(Language)); - expect(again).toBe(extension); - }); - } - ); - - it('configures the typescript loader for TypeScript syntax', async () => { - await jest.isolateModulesAsync(async () => { - const { loadLanguageExtension } = await import('./languageLoader'); - const { typescriptLanguage } = await import('@codemirror/lang-javascript'); - - const extension = await loadLanguageExtension('typescript'); - - expect(extension).toHaveProperty('language', typescriptLanguage); - }); - }); }); diff --git a/packages/grafana-ui/src/components/CodeMirror/languageLoader.ts b/packages/grafana-ui/src/components/CodeMirror/languageLoader.ts index 250b6f6d6a4a..0a5db287fc69 100644 --- a/packages/grafana-ui/src/components/CodeMirror/languageLoader.ts +++ b/packages/grafana-ui/src/components/CodeMirror/languageLoader.ts @@ -4,29 +4,9 @@ import { type CodeMirrorEditorLanguage, type CodeMirrorExtension, type CodeMirro const DEFAULT_SQL_DIALECT: CodeMirrorSqlDialect = 'standardSql'; -const loadGo = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-go" */ '@codemirror/lang-go')).go(); - -const loadHtml = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-html" */ '@codemirror/lang-html')).html(); - const loadJson = async (): Promise => (await import(/* webpackChunkName: "codemirror-lang-json" */ '@codemirror/lang-json')).json(); -const loadMarkdown = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-markdown" */ '@codemirror/lang-markdown')).markdown(); - -const loadTypescript = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-javascript" */ '@codemirror/lang-javascript')).javascript({ - typescript: true, - }); - -const loadXml = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-xml" */ '@codemirror/lang-xml')).xml(); - -const loadYaml = async (): Promise => - (await import(/* webpackChunkName: "codemirror-lang-yaml" */ '@codemirror/lang-yaml')).yaml(); - const loadSql = async (dialect: CodeMirrorSqlDialect): Promise => { const [{ sql, StandardSQL, MySQL }, { foldByIndentation }] = await Promise.all([ import(/* webpackChunkName: "codemirror-lang-sql" */ '@codemirror/lang-sql'), @@ -52,24 +32,12 @@ const resolveLoad = ( options: LoadLanguageOptions ): { cacheKey: string; load: () => Promise } => { switch (language) { - case 'go': - return { cacheKey: 'go', load: loadGo }; - case 'html': - return { cacheKey: 'html', load: loadHtml }; case 'json': return { cacheKey: 'json', load: loadJson }; - case 'markdown': - return { cacheKey: 'markdown', load: loadMarkdown }; case 'sql': { const dialect = options.sqlDialect ?? DEFAULT_SQL_DIALECT; return { cacheKey: `sql:${dialect}`, load: () => loadSql(dialect) }; } - case 'typescript': - return { cacheKey: 'typescript', load: loadTypescript }; - case 'xml': - return { cacheKey: 'xml', load: loadXml }; - case 'yaml': - return { cacheKey: 'yaml', load: loadYaml }; } }; diff --git a/packages/grafana-ui/src/components/CodeMirror/types.ts b/packages/grafana-ui/src/components/CodeMirror/types.ts index ff61f61adde1..3437e061579d 100644 --- a/packages/grafana-ui/src/components/CodeMirror/types.ts +++ b/packages/grafana-ui/src/components/CodeMirror/types.ts @@ -1,7 +1,6 @@ import type { Completion, CompletionContext, CompletionResult, CompletionSource } from '@codemirror/autocomplete'; import { type EditorState, type Extension } from '@codemirror/state'; import { type BasicSetupOptions } from '@uiw/react-codemirror'; -import { type ReactNode } from 'react'; export type CodeMirrorCompletion = Completion; export type CodeMirrorCompletionContext = CompletionContext; @@ -19,7 +18,7 @@ export type CodeMirrorCompletionMode = 'override' | 'merge'; */ export type CodeMirrorBasicSetup = boolean | BasicSetupOptions; -export type CodeMirrorEditorLanguage = 'go' | 'html' | 'json' | 'markdown' | 'sql' | 'typescript' | 'xml' | 'yaml'; +export type CodeMirrorEditorLanguage = 'json' | 'sql'; /** * SQL dialect used for syntax highlighting and keyword completion when @@ -161,18 +160,4 @@ export interface CodeMirrorEditorProps { * element instead of being captured as indentation (avoids a keyboard trap). */ indentWithTab?: boolean; - /** - * Rejects all edits while keeping the text selectable. - */ - readOnly?: boolean; - /** - * Wraps long lines instead of scrolling horizontally. - */ - lineWrapping?: boolean; - /** - * Rendered while the editor bundle is being lazily loaded. Defaults to a - * loading placeholder; pass a styled preview of the content to avoid a - * visual flash when the editor appears. - */ - loadingFallback?: ReactNode; } diff --git a/public/app/plugins/panel/textng/TextNGCodeView.tsx b/public/app/plugins/panel/textng/TextNGCodeView.tsx deleted file mode 100644 index 6795b1dede50..000000000000 --- a/public/app/plugins/panel/textng/TextNGCodeView.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { css } from '@emotion/css'; -import { useMemo } from 'react'; - -import { type GrafanaTheme2 } from '@grafana/data'; -import { t } from '@grafana/i18n'; -import { useStyles2 } from '@grafana/ui'; -import { CodeMirrorEditor } from '@grafana/ui/unstable'; - -import { type CodeLanguage } from '../../schemas/textng/panelcfg.gen'; - -import { getCodeMirrorLanguage } from './utils'; - -export interface TextNGCodeViewProps { - content: string; - language?: CodeLanguage; - showLineNumbers: boolean; -} - -/** - * Read-only, syntax-highlighted rendering of code-mode content - */ -export function TextNGCodeView({ content, language, showLineNumbers }: TextNGCodeViewProps) { - const styles = useStyles2(getStyles); - - const basicSetup = useMemo( - () => ({ - lineNumbers: showLineNumbers, - foldGutter: false, - highlightActiveLine: false, - highlightActiveLineGutter: false, - bracketMatching: false, - closeBrackets: false, - autocompletion: false, - highlightSelectionMatches: false, - history: false, - indentOnInput: false, - allowMultipleSelections: false, - rectangularSelection: false, - crosshairCursor: false, - dropCursor: false, - }), - [showLineNumbers] - ); - - return ( - {}} - language={getCodeMirrorLanguage(language)} - readOnly - lineWrapping - basicSetup={basicSetup} - height="100%" - aria-label={t('textng.code-view.aria-label-code-content', 'Code content')} - loadingFallback={
{content}
} - /> - ); -} - -const getStyles = (theme: GrafanaTheme2) => ({ - // Mirrors the CodeMirror theme - loadingFallback: css({ - margin: 0, - padding: '4px 2px 4px 6px', - height: '100%', - overflow: 'auto', - fontFamily: theme.typography.fontFamilyMonospace, - fontSize: theme.typography.code.fontSize, - lineHeight: theme.typography.code.lineHeight, - color: theme.components.input.text, - backgroundColor: theme.components.input.background, - whiteSpace: 'pre-wrap', - wordBreak: 'break-word', - }), -}); diff --git a/public/app/plugins/panel/textng/TextNGPanel.test.tsx b/public/app/plugins/panel/textng/TextNGPanel.test.tsx index 7759aea64212..ee1c004ca7ad 100644 --- a/public/app/plugins/panel/textng/TextNGPanel.test.tsx +++ b/public/app/plugins/panel/textng/TextNGPanel.test.tsx @@ -1,290 +1,59 @@ import { render, screen } from '@testing-library/react'; -import { CoreApp, dateTime, LoadingState, EventBusSrv } from '@grafana/data'; -import { PanelContextProvider, type PanelContext } from '@grafana/ui'; +import { type DataFrame, toDataFrame } from '@grafana/data'; -import { CodeLanguage, TextMode } from '../../schemas/textng/panelcfg.gen'; +import { getPanelProps } from '../test-utils'; -import { type Props, TextNGPanel } from './TextNGPanel'; +import { TextNGPanel } from './TextNGPanel'; -// Stub the heavy lazy CodeMirror bundle used by the inline editor and the -// read-only code view. -jest.mock('@grafana/ui/unstable', () => ({ - __esModule: true, - CodeMirrorEditor: ({ - value, - basicSetup, - 'aria-label': ariaLabel, - }: { - value: string; - basicSetup?: { lineNumbers?: boolean }; - 'aria-label'?: string; - }) => ( -