From 9256fbd12cf55181097cb9cf99d882327ec64571 Mon Sep 17 00:00:00 2001 From: Dominik Broj Date: Fri, 29 Mar 2024 16:59:23 +0100 Subject: [PATCH] Snow polishing (#4136) # What this PR does - Webhook URL should be template editor + move it after HTTP method [Frontend] @brojd - Lack of scrollbar when templates are there in Outgoing webhook details drawer [Frontend] @brojd - On outgoing tab "Open ServiceNow configuration" does nothing [Frontend] @brojd - Remove OK tag next to url in outgoing tab [Frontend] @brojd https://github.com/grafana/oncall-private/issues/2615 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. --- .../src/pages/integration/Integration.tsx | 22 ++++-- .../integration/OutgoingTab/OutgoingTab.tsx | 11 ++- .../OutgoingTab/OutgoingWebhookFormFields.tsx | 71 +++++++++++++------ grafana-plugin/src/state/types.ts | 5 ++ grafana-plugin/src/utils/hoc.tsx | 11 +++ 5 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 grafana-plugin/src/utils/hoc.tsx diff --git a/grafana-plugin/src/pages/integration/Integration.tsx b/grafana-plugin/src/pages/integration/Integration.tsx index 5345a51b..2c0d7209 100644 --- a/grafana-plugin/src/pages/integration/Integration.tsx +++ b/grafana-plugin/src/pages/integration/Integration.tsx @@ -62,12 +62,13 @@ import { ApiSchemas } from 'network/oncall-api/api.types'; import { IntegrationHelper, getIsBidirectionalIntegration } from 'pages/integration/Integration.helper'; import styles from 'pages/integration/Integration.module.scss'; import { AppFeature } from 'state/features'; -import { PageProps, SelectOption, WithStoreProps } from 'state/types'; +import { PageProps, SelectOption, WithDrawerConfig, WithStoreProps } from 'state/types'; import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; import { LocationHelper } from 'utils/LocationHelper'; import { UserActions } from 'utils/authorization/authorization'; import { PLUGIN_ROOT } from 'utils/consts'; +import { withDrawer } from 'utils/hoc'; import { useDrawer } from 'utils/hooks'; import { getItem, setItem } from 'utils/localStorage'; import { sanitize } from 'utils/sanitize'; @@ -77,7 +78,11 @@ import { OutgoingTab } from './OutgoingTab/OutgoingTab'; const cx = cn.bind(styles); -interface IntegrationProps extends WithStoreProps, PageProps, RouteComponentProps<{ id: string }> {} +interface IntegrationProps + extends WithDrawerConfig, + WithStoreProps, + PageProps, + RouteComponentProps<{ id: string }> {} interface IntegrationState extends PageBaseState { isLoading: boolean; @@ -138,6 +143,7 @@ class _IntegrationPage extends React.Component this.setState({ isTemplateSettingsOpen: true })} isLegacyIntegration={isLegacyIntegration} + drawerConfig={drawerConfig} /> @@ -266,7 +273,10 @@ class _IntegrationPage extends React.Component }, + { + label: 'Outgoing', + content: drawerConfig.openDrawer('servicenow')} />, + }, ]} /> ) : ( @@ -807,6 +817,7 @@ interface IntegrationActionsProps { isLegacyIntegration: boolean; alertReceiveChannel: ApiSchemas['AlertReceiveChannel']; changeIsTemplateSettingsOpen: () => void; + drawerConfig: ReturnType>; } type IntegrationDrawerKey = 'servicenow' | 'completeConfig'; @@ -815,6 +826,7 @@ const IntegrationActions: React.FC = ({ alertReceiveChannel, isLegacyIntegration, changeIsTemplateSettingsOpen, + drawerConfig, }) => { const store = useStore(); const { alertReceiveChannelStore } = store; @@ -842,7 +854,7 @@ const IntegrationActions: React.FC = ({ alert_receive_channel_id: ApiSchemas['AlertReceiveChannel']['id']; }>(undefined); - const { closeDrawer, openDrawer, getIsDrawerOpened } = useDrawer(); + const { closeDrawer, openDrawer, getIsDrawerOpened } = drawerConfig; const { id } = alertReceiveChannel; @@ -1274,4 +1286,4 @@ const IntegrationHeader: React.FC = ({ } }; -export const IntegrationPage = withRouter(withMobXProviderContext(_IntegrationPage)); +export const IntegrationPage = withRouter(withMobXProviderContext(withDrawer(_IntegrationPage))); diff --git a/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingTab.tsx b/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingTab.tsx index 2834aeb3..f03890a1 100644 --- a/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingTab.tsx +++ b/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingTab.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useStyles2, Input, IconButton, Drawer, Badge, HorizontalGroup } from '@grafana/ui'; +import { useStyles2, Input, IconButton, Drawer, HorizontalGroup } from '@grafana/ui'; import { observer } from 'mobx-react'; import { Button } from 'components/Button/Button'; @@ -19,7 +19,7 @@ import { OutgoingTabDrawerKey } from './OutgoingTab.types'; import { OutgoingWebhookDetailsDrawerTabs } from './OutgoingWebhookDetailsDrawerTabs'; import { OutgoingWebhooksTable } from './OutgoingWebhooksTable'; -export const OutgoingTab = () => { +export const OutgoingTab = ({ openSnowConfigurationDrawer }: { openSnowConfigurationDrawer: () => void }) => { const { openDrawer, closeDrawer, getIsDrawerOpened } = useDrawer(); const styles = useStyles2(getStyles); @@ -45,7 +45,7 @@ export const OutgoingTab = () => { { customIcon: 'plug', startingElemPosition: '50%', - expandedView: () => , + expandedView: () => , }, { customIcon: 'plus', @@ -79,9 +79,8 @@ export const OutgoingTab = () => { ); }; -const Connection = observer(() => { +const Connection = observer(({ openSnowConfigurationDrawer }: { openSnowConfigurationDrawer: () => void }) => { const styles = useStyles2(getStyles); - const integration = useCurrentIntegration(); // TODO: remove casting once backend narrows down the types const url = integration?.additional_settings?.instance_url as string; @@ -94,7 +93,6 @@ const Connection = observer(() => { heading={
ServiceNow connection - { name="cog" aria-label="Open ServiceNow configuration" className={styles.openConfigurationBtn} + onClick={openSnowConfigurationDrawer} />
} diff --git a/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingWebhookFormFields.tsx b/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingWebhookFormFields.tsx index fa2172fc..fdeb0059 100644 --- a/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingWebhookFormFields.tsx +++ b/grafana-plugin/src/pages/integration/OutgoingTab/OutgoingWebhookFormFields.tsx @@ -5,7 +5,6 @@ import { Field, HorizontalGroup, Icon, - Input, Label, Select, Switch, @@ -17,7 +16,7 @@ import cn from 'classnames'; import { Controller, useFormContext } from 'react-hook-form'; import { MonacoEditor } from 'components/MonacoEditor/MonacoEditor'; -import { MONACO_READONLY_CONFIG } from 'components/MonacoEditor/MonacoEditor.config'; +import { MONACO_EDITABLE_CONFIG, MONACO_READONLY_CONFIG } from 'components/MonacoEditor/MonacoEditor.config'; import { WebhooksTemplateEditor } from 'containers/WebhooksTemplateEditor/WebhooksTemplateEditor'; import { HTTP_METHOD_OPTIONS, WEBHOOK_TRIGGGER_TYPE_OPTIONS } from 'models/outgoing_webhook/outgoing_webhook.types'; @@ -37,7 +36,7 @@ interface OutgoingWebhookFormFieldsProps { export const OutgoingWebhookFormFields: FC = ({ webhookId }) => { const styles = useStyles2(getStyles); - const { control, watch, formState, register } = useFormContext(); + const { control, watch, formState } = useFormContext(); const [templateToEdit, setTemplateToEdit] = useState(); const [showTriggerTemplate] = watch(['triggerTemplateToogle']); @@ -83,26 +82,6 @@ export const OutgoingWebhookFormFields: FC = ({ )} /> - - Webhook URL  - - - - - } - className={styles.selectField} - > - - = ({ )} /> + ( + + + +