From a1fb73c503455f6906fb70ba4e1022d4010f016a Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Thu, 30 Jun 2022 14:01:02 +0200 Subject: [PATCH 001/114] Alerting: Adds contact point template syntax highlighting (#51559) --- .betterer.results | 6 +- .../components/receivers/TemplateEditor.tsx | 53 ++++++++ .../components/receivers/TemplateForm.tsx | 31 ++++- .../components/receivers/TemplatesTable.tsx | 13 +- .../components/receivers/editor/definition.ts | 12 ++ .../components/receivers/editor/language.ts | 128 ++++++++++++++++++ .../components/receivers/editor/register.ts | 34 +++++ 7 files changed, 266 insertions(+), 11 deletions(-) create mode 100644 public/app/features/alerting/unified/components/receivers/TemplateEditor.tsx create mode 100644 public/app/features/alerting/unified/components/receivers/editor/definition.ts create mode 100644 public/app/features/alerting/unified/components/receivers/editor/language.ts create mode 100644 public/app/features/alerting/unified/components/receivers/editor/register.ts diff --git a/.betterer.results b/.betterer.results index 3d25ebbffdc..02dd9926785 100644 --- a/.betterer.results +++ b/.betterer.results @@ -4271,9 +4271,9 @@ exports[`better eslint`] = { "public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx:3093815801": [ [126, 10, 1271, "Do not use any type assertions.", "441563991"] ], - "public/app/features/alerting/unified/components/receivers/TemplateForm.tsx:312681720": [ - [101, 29, 12, "Do not use any type assertions.", "3304544793"], - [101, 38, 3, "Unexpected any. Specify a different type.", "193409811"] + "public/app/features/alerting/unified/components/receivers/TemplateForm.tsx:2509382344": [ + [106, 29, 12, "Do not use any type assertions.", "3304544793"], + [106, 38, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx:2192936556": [ [31, 28, 30, "Do not use any type assertions.", "1841535999"], diff --git a/public/app/features/alerting/unified/components/receivers/TemplateEditor.tsx b/public/app/features/alerting/unified/components/receivers/TemplateEditor.tsx new file mode 100644 index 00000000000..556b29b2ac5 --- /dev/null +++ b/public/app/features/alerting/unified/components/receivers/TemplateEditor.tsx @@ -0,0 +1,53 @@ +/** + * This file contains the template editor we'll be using for alertmanager templates. + * + * It includes auto-complete for template data and syntax highlighting + */ +import { editor } from 'monaco-editor'; +import React, { FC } from 'react'; + +import { CodeEditor } from '@grafana/ui'; +import { CodeEditorProps } from '@grafana/ui/src/components/Monaco/types'; + +import goTemplateLanguageDefinition, { GO_TEMPLATE_LANGUAGE_ID } from './editor/definition'; +import { registerLanguage } from './editor/register'; + +const getSuggestions = () => { + return []; +}; + +type TemplateEditorProps = Omit & { + autoHeight?: boolean; +}; + +const TemplateEditor: FC = (props) => { + const shouldAutoHeight = Boolean(props.autoHeight); + + const onEditorDidMount = (editor: editor.IStandaloneCodeEditor) => { + if (shouldAutoHeight) { + const contentHeight = editor.getContentHeight(); + + try { + // we're passing NaN in to the width because the type definition wants a number (NaN is a number, go figure) + // but the width could be defined as a string "auto", passing NaN seems to just ignore our width update here + editor.layout({ height: contentHeight, width: NaN }); + } catch (err) {} + } + }; + + return ( + { + registerLanguage(monaco, goTemplateLanguageDefinition); + }} + language={GO_TEMPLATE_LANGUAGE_ID} + /> + ); +}; + +export { TemplateEditor }; diff --git a/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx b/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx index 3348b3c3fce..2eba93cb61e 100644 --- a/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx @@ -2,9 +2,10 @@ import { css } from '@emotion/css'; import React, { FC } from 'react'; import { useForm, Validate } from 'react-hook-form'; import { useDispatch } from 'react-redux'; +import AutoSizer from 'react-virtualized-auto-sizer'; import { GrafanaTheme2 } from '@grafana/data'; -import { Alert, Button, Field, FieldSet, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui'; +import { Alert, Button, Field, FieldSet, Input, LinkButton, useStyles2 } from '@grafana/ui'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; @@ -14,6 +15,8 @@ import { makeAMLink } from '../../utils/misc'; import { ensureDefine } from '../../utils/templates'; import { ProvisionedResource, ProvisioningAlert } from '../Provisioning'; +import { TemplateEditor } from './TemplateEditor'; + interface Values { name: string; content: string; @@ -83,6 +86,8 @@ export const TemplateForm: FC = ({ existing, alertManagerSourceName, conf handleSubmit, register, formState: { errors }, + getValues, + setValue, } = useForm({ mode: 'onSubmit', defaultValues: existing ?? defaults, @@ -143,12 +148,18 @@ export const TemplateForm: FC = ({ existing, alertManagerSourceName, conf invalid={!!errors.content?.message} required > -