diff --git a/grafana-plugin/src/assets/style/global.css b/grafana-plugin/src/assets/style/global.css index 5cc2b9ab..8c877e09 100644 --- a/grafana-plugin/src/assets/style/global.css +++ b/grafana-plugin/src/assets/style/global.css @@ -1,3 +1,13 @@ +.theme-light { + --working-hours-shades-color: rgba(17, 18, 23, 0.15); + --working-hours-shades-color-light: rgba(17, 18, 23, 0.04); +} + +.theme-dark:not(.theme-light) { + --working-hours-shades-color: rgba(17, 18, 23, 0.15); + --working-hours-shades-color-light: rgba(17, 18, 23, 0.1); +} + .configure-plugin { margin-top: 10px; } diff --git a/grafana-plugin/src/assets/style/utils.css b/grafana-plugin/src/assets/style/utils.css deleted file mode 100644 index 23d3a18f..00000000 --- a/grafana-plugin/src/assets/style/utils.css +++ /dev/null @@ -1,229 +0,0 @@ -/* ----- - * Flex - */ - -.u-flex { - display: flex !important; - flex-direction: row; -} - -.u-align-items-center { - align-items: center; -} - -.u-flex-center { - justify-content: center; - align-items: center; -} - -.u-flex-space-between { - justify-content: space-between; -} - -.u-flex-grow-1 { - flex-grow: 1; -} - -.u-flex-gap-xs { - gap: 4px; -} - -/* ----- - * Margins/Paddings - */ - -.u-margin-right-xs { - margin-right: 4px; -} - -.u-margin-left-xs { - margin-left: 4px; -} - -.u-margin-bottom-none { - margin-bottom: 0; -} - -.u-margin-bottom-md { - margin-bottom: 12px; -} - -.u-margin-bottom-xxs { - margin-bottom: 2px; -} - -.u-margin-top-xs { - margin-top: 4px; -} - -.u-padding-top-md { - padding-top: 12px; -} - -.u-padding-top-none { - padding-top: 0; -} - -.u-padding-left-lg { - padding-left: 24px; -} - -.u-padding-vertical-xs { - padding: 4px 0; -} - -.u-pull-right { - margin-left: auto; -} - -.u-pull-left { - margin-right: auto; -} - -/* ----- - * Display - */ - -.u-width-100 { - width: 100%; -} - -.u-height-100 { - height: 100%; -} - -.u-width-height-100 { - width: 100%; - height: 100%; -} - -.u-display-block { - display: block; -} - -/* ----- - * Other - */ - -.back-arrow { - padding-top: 8px; -} - -.link { - text-decoration: none !important; -} - -.u-position-relative { - position: relative; -} - -.u-break-word { - word-break: break-word; -} - -.u-opacity, -.u-disabled { - opacity: var(--opacity); -} - -.u-disabled { - cursor: not-allowed !important; - pointer-events: none; -} - -.u-cursor-default { - cursor: default; -} - -.thin-line-break { - width: 100%; - border-top: 1px solid var(--always-gray); - margin-top: 8px; - opacity: 15%; -} - -.buttons { - padding-bottom: 24px; -} - -.loadingPlaceholder { - margin-bottom: 0; - margin-right: 4px; -} - -/* ----- - * Overflow - */ - -.u-overflow-x-auto { - overflow-x: auto; -} - -.overflow-child { - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - white-space: initial; - line-clamp: 2; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; -} - -.overflow-child--line-1 { - line-clamp: 1; - -webkit-line-clamp: 1; -} - -.line-clamp-3 { - line-clamp: 3; - -webkit-line-clamp: 3; -} - -.break-word { - word-break: break-all; -} - -/* ----- - * CSSTransitionGroup fading - */ - -.fade-enter { - max-height: 0; - opacity: 0; -} - -.fade-enter.fade-enter-active { - max-height: 50px; - opacity: 1; - transition: opacity 300ms ease-in, max-height 300ms ease-in; -} - -.fade-leave { - opacity: 1; - max-height: 50px; -} - -.fade-leave.fade-leave-active { - max-height: 0; - opacity: 0; - transition: opacity 300ms ease-in, max-height 300ms ease-in; -} - -.fade-exit { - opacity: 1; - max-height: 50px; -} - -.fade-exit.fade-exit-active { - max-height: 0; - opacity: 0; - transition: opacity 300ms ease-in, max-height 300ms ease-in; -} - -/* ----- - * Widths - */ - -.u-max-width-1000 { - max-width: 1000px; -} diff --git a/grafana-plugin/src/assets/style/vars.css b/grafana-plugin/src/assets/style/vars.css deleted file mode 100644 index e9d6e9a7..00000000 --- a/grafana-plugin/src/assets/style/vars.css +++ /dev/null @@ -1,74 +0,0 @@ -:root { - --green-6: #73d13d; - --gray-9: #434343; - --cyan-1: #e6fffb; - --border-radius: 2px; - --gradient-brandVertical: linear-gradient(0.01deg, #f53e4c -31.2%, #f83 113.07%); - --always-gray: #ccccdc; - --title-marginBottom: 16px; - --opacity: 0.5; -} - -.theme-light { - --cards-background: rgba(244, 245, 245); - --highlighted-row-bg: var(--cyan-1); - --primary-background: rgb(255, 255, 255); - --secondary-background: rgb(244, 245, 245); - --border: 1px solid rgba(36, 41, 46, 0.12); - --primary-text-color: rgb(36, 41, 46); - --secondary-text-color: rgba(36, 41, 46, 0.75); - --disabled-text-color: rgba(36, 41, 46, 0.5); - --warning-text-color: #f5b73d; - --success-text-color: #1a7f4b; - --error-text-color: #ff5286; - --primary-text-link: #1f62e0; - --timeline-icon-background: rgba(70, 76, 84, 0); - --oncall-icon-stroke-color: #fff; - --hover-selected: #f4f5f5; - --background-canvas: #f4f5f5; - --background-secondary: #f4f5f5; - --background-disabled: rgba(204, 204, 220, 0.11); - --border-medium-color: rgba(36, 41, 46, 0.3); - --border-medium: 1px solid rgba(36, 41, 46, 0.3); - --border-strong: 1px solid rgba(36, 41, 46, 0.4); - --border-weak: 1px solid rgba(36, 41, 46, 0.12); - --shadows-z3: 0 13px 20px 1px rgba(24, 26, 27, 0.18); - --button-background: rgba(36, 41, 46, 0.08); - --button-hover-background: rgba(36, 41, 46, 0.15); - --box-background: rgba(244, 245, 245); - --working-hours-shades-color: rgba(17, 18, 23, 0.15); - --working-hours-shades-color-light: rgba(17, 18, 23, 0.04); -} - -.theme-dark:not(.theme-light) { - --cards-background: var(--gray-9); - --highlighted-row-bg: var(--gray-9); - --disabled-button-color: hsla(0, 0%, 100%, 0.08); - --primary-background: rgb(24, 27, 31); - --secondary-background: rgb(34, 37, 43); - --border: 1px solid rgba(204, 204, 220, 0.15); - --primary-text-color: rgb(204, 204, 220); - --secondary-text-color: rgba(204, 204, 220, 0.65); - --disabled-text-color: rgba(204, 204, 220, 0.4); - --warning-text-color: #f5b73d; - --success-text-color: #1a7f4b; - --error-text-color: #ff5286; - --primary-text-link: #6e9fff; - --timeline-icon-background: rgba(70, 76, 84, 1); - --timeline-icon-background-resolution-note: rgba(50, 116, 217, 1); - --focused-box-shadow: rgb(17 18 23) 0 0 0 2px, rgb(61 113 217) 0 0 0 4px; - --hover-selected: rgba(204, 204, 220, 0.12); - --hover-selected-hardcoded: #34363d; - --oncall-icon-stroke-color: #181b1f; - --background-canvas: #111217; - --background-secondary: #22252b; - --background-disabled: rgba(204, 204, 220, 0.04); - --border-medium-color: rgba(204, 204, 220, 0.15); - --border-medium: 1px solid rgba(204, 204, 220, 0.15); - --border-strong: 1px solid rgba(204, 204, 220, 0.25); - --border-weak: 1px solid rgba(204, 204, 220, 0.07); - --shadows-z3: 0 8px 24px rgb(1, 4, 9); - --box-background: rgba(10, 10, 10, 0.4); - --working-hours-shades-color: rgba(17, 18, 23, 0.15); - --working-hours-shades-color-light: rgba(17, 18, 23, 0.1); -} diff --git a/grafana-plugin/src/components/Collapse/Collapse.module.scss b/grafana-plugin/src/components/Collapse/Collapse.module.scss deleted file mode 100644 index 949524e2..00000000 --- a/grafana-plugin/src/components/Collapse/Collapse.module.scss +++ /dev/null @@ -1,35 +0,0 @@ -.root { - border: var(--border); - width: 100%; -} - -.header { - padding: 8px; - cursor: pointer; - display: flex; - align-items: center; -} - -.header_with-background { - background: var(--secondary-background); -} - -.label { - display: block; - margin-left: 8px; - flex-grow: 1; -} - -.content { - padding: 16px; -} - -.icon { - color: var(--secondary-text-color); - transform-origin: center; - transition: transform 0.2s; - - &--rotated { - transform: rotate(90deg); - } -} diff --git a/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx b/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx index 124c0220..bc7808fa 100644 --- a/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx +++ b/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx @@ -1,5 +1,6 @@ import React, { FC, useCallback, useEffect, useState } from 'react'; +import { css } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; import { Button, Icon, Select, Stack } from '@grafana/ui'; import { StackSize } from 'helpers/consts'; @@ -31,17 +32,27 @@ export const CursorPagination: FC = (props) => { }, []); return ( - - - Items per list + + + + Items per list + } key="search" - className={cx('responders-filters')} + className={styles.respondersFilters} data-testid="add-responders-search-input" value={search} placeholder="Search" @@ -300,13 +299,20 @@ export const AddRespondersPopup = observer( { value: TabOptions.Teams, label: 'Teams' }, { value: TabOptions.Users, label: 'Users' }, ]} - className={cx('radio-buttons')} + className={styles.radioButtons} value={activeOption} onChange={onChangeTab} fullWidth /> )} - {searchLoading && } + {searchLoading && ( + + )} {!searchLoading && activeOption === TabOptions.Teams && ( <> {selectedTeamResponder ? ( @@ -317,14 +323,14 @@ export const AddRespondersPopup = observer( ) : ( <> You can only page teams which have a Direct Paging integration that is configured.{' '} @@ -355,7 +361,7 @@ export const AddRespondersPopup = observer( {!searchLoading && activeOption === TabOptions.Users && ( <> = ({ disabled = false, important, onChange }) => ( + ) : ( { } return ( openNotification('Token copied')}> - + ); } @@ -137,6 +135,6 @@ export const ApiTokenForm = observer((props: TokenCreationModalProps) => { } }); -function getCurlExample(token, onCallApiUrl) { +function getCurlExample(token: string, onCallApiUrl: string) { return `curl -H "Authorization: ${token}" ${onCallApiUrl}/api/v1/integrations`; } diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.module.css b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.module.css deleted file mode 100644 index d0c5e808..00000000 --- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.module.css +++ /dev/null @@ -1,13 +0,0 @@ -.form { - margin: 20px 0; -} - -.incident-matcher { - margin: 20px 0; -} - -.header { - display: flex; - justify-content: space-between; - align-items: center; -} diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx index f91b5363..7e803a8f 100644 --- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx +++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx @@ -1,11 +1,11 @@ import React from 'react'; +import { css } from '@emotion/css'; import { Button, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; import { - generateMissingPermissionMessage, - isUserActionAllowed, UserActions, + isUserActionAllowed, + generateMissingPermissionMessage, } from 'helpers/authorization/authorization'; import { observer } from 'mobx-react'; import moment from 'moment-timezone'; @@ -20,10 +20,6 @@ import { withMobXProviderContext } from 'state/withStore'; import { ApiTokenForm } from './ApiTokenForm'; -import styles from './ApiTokenSettings.module.css'; - -const cx = cn.bind(styles); - const MAX_TOKENS_PER_USER = 5; const REQUIRED_PERMISSION_TO_VIEW = UserActions.APIKeysWrite; @@ -81,11 +77,13 @@ class _ApiTokenSettings extends React.Component { emptyText = 'No tokens found'; } + const styles = getStyles(); + return ( <> ( -
+
API Tokens @@ -161,4 +159,14 @@ class _ApiTokenSettings extends React.Component { }; } +const getStyles = () => { + return { + header: css` + display: flex; + justify-content: space-between; + align-items: center; + `, + }; +}; + export const ApiTokenSettings = withMobXProviderContext(_ApiTokenSettings); diff --git a/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.module.css b/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.module.css deleted file mode 100644 index 63d08ecc..00000000 --- a/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.root { - display: block; -} diff --git a/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.tsx b/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.tsx index 39019223..26dfd6e2 100644 --- a/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.tsx +++ b/grafana-plugin/src/containers/AttachIncidentForm/AttachIncidentForm.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useState } from 'react'; +import { css, cx } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; import { Button, Field, Icon, Modal, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; import { UserActions } from 'helpers/authorization/authorization'; import { observer } from 'mobx-react'; import moment from 'moment-timezone'; @@ -14,10 +14,6 @@ import { AlertGroupHelper } from 'models/alertgroup/alertgroup.helpers'; import { ApiSchemas } from 'network/oncall-api/api.types'; import { useStore } from 'state/useStore'; -import styles from './AttachIncidentForm.module.css'; - -const cx = cn.bind(styles); - interface AttachIncidentFormProps { id: ApiSchemas['AlertGroup']['pk']; onUpdate: () => void; @@ -70,7 +66,9 @@ export const AttachIncidentForm = observer(({ id, onUpdate, onHide }: AttachInci Attach to another alert group } - className={cx('root')} + className={css` + display: block; + `} onDismiss={onHide} > ; @@ -40,6 +37,11 @@ interface SearchResult extends Pick = observer( ({ isModalOpen, labelKeys, setIsModalOpen, inputRef }) => { const store = useStore(); @@ -108,7 +110,7 @@ export const ColumnsModal: React.FC = observer( {!result.isCollapsed && ( {result.values === undefined ? ( - + ) : ( renderLabelValues(result.name, result.values) )} @@ -138,7 +140,7 @@ export const ColumnsModal: React.FC = observer( failure: PROCESSING_REQUEST_ERROR, })} > - {isLoading ? : 'Add'} + {isLoading ? : 'Add'} diff --git a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.module.scss b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.module.scss deleted file mode 100644 index 849cf094..00000000 --- a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.module.scss +++ /dev/null @@ -1,14 +0,0 @@ -.root { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; -} - -/* --- GRAFANA UI TUNINGS --- */ - -.root :global(.filter-table) td { - white-space: break-spaces; - line-height: 20px; - height: auto; -} diff --git a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx index 3a13a3f5..aa1b1f7a 100644 --- a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx +++ b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx @@ -1,18 +1,14 @@ import React, { FC, ReactElement } from 'react'; -import { NavModelItem } from '@grafana/data'; +import { css, cx } from '@emotion/css'; +import { AppRootProps, NavModelItem } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; import { PluginPage } from 'PluginPage'; -import { AppRootProps } from 'app-types'; -import cn from 'classnames/bind'; import { observer } from 'mobx-react'; import { Alerts } from 'containers/Alerts/Alerts'; import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers'; -import styles from './DefaultPageLayout.module.scss'; - -const cx = cn.bind(styles); - interface DefaultPageLayoutProps extends AppRootProps { children?: any; page: string; @@ -21,6 +17,7 @@ interface DefaultPageLayoutProps extends AppRootProps { export const DefaultPageLayout: FC = observer((props) => { const { children, page, pageNav } = props; + const styles = useStyles2(getStyles); if (isTopNavbar()) { return renderTopNavbar(); @@ -31,7 +28,7 @@ export const DefaultPageLayout: FC = observer((props) => function renderTopNavbar(): ReactElement { return ( -
{children}
+
{children}
); } @@ -39,8 +36,15 @@ export const DefaultPageLayout: FC = observer((props) => function renderLegacyNavbar(): ReactElement { return ( -
-
+
+
{children}
@@ -49,3 +53,20 @@ export const DefaultPageLayout: FC = observer((props) => ); } }); + +const getStyles = () => { + return { + root: css` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + + .filter-table td { + white-space: break-spaces; + line-height: 20px; + height: auto; + } + `, + }; +}; diff --git a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.module.css b/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.module.css deleted file mode 100644 index 273537df..00000000 --- a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.regexp-template-code { - width: 100%; -} - -.regexp-template-code-error { - border: var(--error-text-color) 1px solid; -} - -.regexp-template-editor-modal { - width: 700px; -} diff --git a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx b/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx index e16ce0f0..77dd801e 100644 --- a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx +++ b/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx @@ -1,7 +1,8 @@ import React, { useState, useCallback } from 'react'; -import { Stack, Modal, Tooltip, Icon, Button } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Stack, Modal, Tooltip, Icon, Button, useStyles2 } from '@grafana/ui'; import { StackSize } from 'helpers/consts'; import { openErrorNotification } from 'helpers/helpers'; import { debounce } from 'lodash-es'; @@ -16,10 +17,6 @@ import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import { ApiSchemas } from 'network/oncall-api/api.types'; import { useStore } from 'state/useStore'; -import styles from './EditRegexpRouteTemplateModal.module.css'; - -const cx = cn.bind(styles); - interface EditRegexpRouteTemplateModalProps { channelFilterId: ChannelFilter['id']; template?: TemplateForEdit; @@ -32,6 +29,7 @@ interface EditRegexpRouteTemplateModalProps { export const EditRegexpRouteTemplateModal = observer((props: EditRegexpRouteTemplateModalProps) => { const { onHide, onUpdateRoute, channelFilterId, onOpenEditIntegrationTemplate, alertReceiveChannelId } = props; const store = useStore(); + const styles = useStyles2(getStyles); const regexpBody = store.alertReceiveChannelStore.channelFilters[channelFilterId]?.filtering_term; @@ -77,7 +75,7 @@ export const EditRegexpRouteTemplateModal = observer((props: EditRegexpRouteTemp isOpen onDismiss={onHide} title="Edit regular expression template" - className={cx('regexp-template-editor-modal')} + className={styles.regexTemplateEditorModal} > @@ -91,7 +89,7 @@ export const EditRegexpRouteTemplateModal = observer((props: EditRegexpRouteTemp -
+
); }); + +const getStyles = (theme: GrafanaTheme2) => { + return { + regexTemplateCode: css` + width: 100%; + `, + + regexTemplateCodeError: css` + border: 1px solid ${theme.colors.error.text}; + `, + + regexTemplateEditorModal: css` + width: 700px; + `, + }; +}; diff --git a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.module.css b/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.module.css deleted file mode 100644 index 4bcfcd17..00000000 --- a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.root { - display: block; -} - -.icon { - color: var(--success-text-color); -} diff --git a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx b/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx index 4dca5d91..22eb3c9e 100644 --- a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx +++ b/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { Stack, Badge } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Stack, Badge, useStyles2 } from '@grafana/ui'; import { StackSize } from 'helpers/consts'; import { observer } from 'mobx-react'; @@ -10,10 +11,6 @@ import { TeamName } from 'containers/TeamName/TeamName'; import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'; import { useStore } from 'state/useStore'; -import styles from './EscalationChainCard.module.css'; - -const cx = cn.bind(styles); - interface AlertReceiveChannelCardProps { id: EscalationChain['id']; } @@ -22,13 +19,14 @@ export const EscalationChainCard = observer((props: AlertReceiveChannelCardProps const { id } = props; const store = useStore(); + const styles = useStyles2(getStyles); const { escalationChainStore, grafanaTeamStore } = store; const escalationChain = escalationChainStore.items[id]; return ( -
+
@@ -57,3 +55,14 @@ export const EscalationChainCard = observer((props: AlertReceiveChannelCardProps
); }); + +const getStyles = (theme: GrafanaTheme2) => { + return { + root: css` + display: block; + `, + icon: css` + color: ${theme.colors.success.text}; + `, + }; +}; diff --git a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.module.css b/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.module.css deleted file mode 100644 index 63d08ecc..00000000 --- a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.root { - display: block; -} diff --git a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx b/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx index b72dee67..c3e676b7 100644 --- a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx +++ b/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; +import { css, cx } from '@emotion/css'; import { Button, Field, Input, Modal, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; import { openWarningNotification } from 'helpers/helpers'; import { observer } from 'mobx-react'; import { Controller, FormProvider, useForm } from 'react-hook-form'; @@ -11,8 +11,6 @@ import { EscalationChain } from 'models/escalation_chain/escalation_chain.types' import { GrafanaTeam } from 'models/grafana_team/grafana_team.types'; import { useStore } from 'state/useStore'; -import styles from 'containers/EscalationChainForm/EscalationChainForm.module.css'; - export enum EscalationChainFormMode { Create = 'Create', Copy = 'Copy', @@ -31,8 +29,6 @@ interface EscalationFormFields { name: string; } -const cx = cn.bind(styles); - export const EscalationChainForm: FC = observer((props) => { const { escalationChainId, onHide, onSubmit: onSubmitProp, mode } = props; @@ -68,7 +64,11 @@ export const EscalationChainForm: FC = observer((props return ( -
+
+ {addonBefore} {escalationPolicyIds ? ( escalationPolicyIds.map((escalationPolicyId, index) => { diff --git a/grafana-plugin/src/containers/GSelect/GSelect.module.scss b/grafana-plugin/src/containers/GSelect/GSelect.module.scss deleted file mode 100644 index 6d857b78..00000000 --- a/grafana-plugin/src/containers/GSelect/GSelect.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.root { - min-width: 200px; - - & > div { - // If not set then inner div will not benefit of min-width - min-width: 200px; - } -} diff --git a/grafana-plugin/src/containers/GSelect/GSelect.tsx b/grafana-plugin/src/containers/GSelect/GSelect.tsx index 3d87aaf2..606bbb9b 100644 --- a/grafana-plugin/src/containers/GSelect/GSelect.tsx +++ b/grafana-plugin/src/containers/GSelect/GSelect.tsx @@ -1,16 +1,12 @@ import React, { ReactElement, useCallback, useEffect } from 'react'; +import { cx, css } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; -import { AsyncMultiSelect, AsyncSelect } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { AsyncMultiSelect, AsyncSelect, useStyles2 } from '@grafana/ui'; import { useDebouncedCallback } from 'helpers/hooks'; import { get, isNil } from 'lodash-es'; import { observer } from 'mobx-react'; -import styles from './GSelect.module.scss'; - -const cx = cn.bind(styles); - interface GSelectProps { items: { [key: string]: Item; @@ -75,6 +71,8 @@ export const GSelect = observer((props: GSelectProps) => { dataTestId = null, } = props; + const styles = useStyles2(getGSelectStyles); + const onChangeCallback = useCallback( (option) => { if (isMulti) { @@ -152,7 +150,7 @@ export const GSelect = observer((props: GSelectProps) => { const Tag = isMulti ? AsyncMultiSelect : AsyncSelect; return ( -
+
(props: GSelectProps) => {
); }); + +const getGSelectStyles = () => { + return { + root: css` + min-width: 200px; + + & > div { + // If not set then inner div will not benefit of min-width + min-width: 200px; + } + `, + }; +}; diff --git a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.module.scss b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.module.scss deleted file mode 100644 index a8bc3349..00000000 --- a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.module.scss +++ /dev/null @@ -1,15 +0,0 @@ -.root { - width: 400px; -} - -.teamSelectLabel { - display: flex; -} - -.teamSelectLink { - color: var(--primary-text-link); -} - -.teamSelectInfo { - margin-left: 4px; -} diff --git a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx index d3f96bad..c3695c49 100644 --- a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx +++ b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx @@ -1,7 +1,8 @@ import React, { useCallback, useState } from 'react'; -import { Button, Icon, Label, Modal, Tooltip, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, Icon, Label, Modal, Tooltip, Stack, useStyles2 } from '@grafana/ui'; import { UserActions } from 'helpers/authorization/authorization'; import { observer } from 'mobx-react'; @@ -10,10 +11,6 @@ import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/W import { GrafanaTeam } from 'models/grafana_team/grafana_team.types'; import { useStore } from 'state/useStore'; -import styles from './GrafanaTeamSelect.module.scss'; - -const cx = cn.bind(styles); - interface GrafanaTeamSelectProps { onSelect: (id: GrafanaTeam['id']) => void; onHide?: () => void; @@ -24,6 +21,7 @@ interface GrafanaTeamSelectProps { export const GrafanaTeamSelect = observer( ({ onSelect, onHide, withoutModal, defaultValue }: GrafanaTeamSelectProps) => { const store = useStore(); + const styles = useStyles2(getTeamStyles); const { userStore, @@ -76,19 +74,19 @@ export const GrafanaTeamSelect = observer( } return ( - + -
{select}
+
{select}
- + Edit teams @@ -102,3 +100,23 @@ export const GrafanaTeamSelect = observer( ); } ); + +const getTeamStyles = (theme: GrafanaTheme2) => { + return { + root: css` + width: 400px; + `, + + teamSelectLabel: css` + display: flex; + `, + + teamSelectLink: css` + color: ${theme.colors.text.primary}; + `, + + teamSelectInfo: css` + margin-left: 4px; + `, + }; +}; diff --git a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.module.scss b/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.module.scss deleted file mode 100644 index ebd2a9cf..00000000 --- a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.module.scss +++ /dev/null @@ -1,44 +0,0 @@ -.heading-container { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - overflow: hidden; - gap: 12px; - - &__item { - display: flex; - white-space: nowrap; - flex-direction: row; - gap: 8px; - } - - &__item--large { - flex-grow: 1; - overflow: hidden; - } - - &__text { - overflow: hidden; - max-width: calc(100% - 48px); - text-overflow: ellipsis; - } -} - -.icon { - margin-right: 4px; -} - -.collapsedRoute { - &__container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 8px; - } - - &__item { - display: flex; - flex-direction: row; - } -} diff --git a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx index be5f9e59..218882d2 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx @@ -1,24 +1,22 @@ import React, { useMemo, useState } from 'react'; -import { ConfirmModal, Icon, IconName, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { css, cx } from '@emotion/css'; +import { ConfirmModal, Icon, IconName, Stack, useStyles2 } from '@grafana/ui'; import { StackSize } from 'helpers/consts'; import { observer } from 'mobx-react'; import { IntegrationBlock } from 'components/Integrations/IntegrationBlock'; import { PluginLink } from 'components/PluginLink/PluginLink'; import { Text } from 'components/Text/Text'; -import styles from 'containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.module.scss'; import { RouteButtonsDisplay } from 'containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay'; import { RouteHeading } from 'containers/IntegrationContainers/RouteHeading'; import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import { ApiSchemas } from 'network/oncall-api/api.types'; import { CommonIntegrationHelper } from 'pages/integration/CommonIntegration.helper'; import { IntegrationHelper } from 'pages/integration/Integration.helper'; +import { getIntegrationStyles } from 'pages/integration/Integration.styles'; import { useStore } from 'state/useStore'; -const cx = cn.bind(styles); - interface CollapsedIntegrationRouteDisplayProps { alertReceiveChannelId: ApiSchemas['AlertReceiveChannel']['id']; channelFilterId: ChannelFilter['id']; @@ -42,6 +40,9 @@ export const CollapsedIntegrationRouteDisplay: React.FC { const store = useStore(); + const styles = useStyles2(getStyles); + const integrationStyles = useStyles2(getIntegrationStyles); + const { escalationChainStore, alertReceiveChannelStore } = store; const [routeIdForDeletion, setRouteIdForDeletion] = useState(undefined); @@ -70,16 +71,16 @@ export const CollapsedIntegrationRouteDisplay: React.FC +
-
+
-
+
{chatOpsAvailableChannels.length > 0 && ( -
+
Publish to ChatOps @@ -103,9 +104,15 @@ export const CollapsedIntegrationRouteDisplay: React.FC (
- + {chatOpsChannel.name}
) @@ -114,27 +121,40 @@ export const CollapsedIntegrationRouteDisplay: React.FC )} -
-
+
+
- + Trigger escalation chain
{escalationChain?.name && ( - + {escalationChain?.name} )} {!escalationChain?.name && ( -
-
+
+
@@ -175,3 +195,50 @@ export const CollapsedIntegrationRouteDisplay: React.FC { + return { + headingContainer: css` + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + overflow: hidden; + gap: 12px; + `, + + headingContainerItem: css` + display: flex; + white-space: nowrap; + flex-direction: row; + gap: 8px; + `, + + headingContainerItemLarge: css` + flex-grow: 1; + overflow: hidden; + `, + + headingContainerText: css` + overflow: hidden; + max-width: calc(100% - 48px); + text-overflow: ellipsis; + `, + + icon: css` + margin-right: 4px; + `, + + collapsedRouteContainer: css` + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 8px; + `, + + collapsedRouteItem: css` + display: flex; + flex-direction: row; + `, + }; +}; diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss deleted file mode 100644 index d69a797e..00000000 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss +++ /dev/null @@ -1,92 +0,0 @@ -.input { - border: var(--border-weak); - - &--align { - width: 728px; - } -} - -.field { - margin-bottom: 0; -} - -.routing-alert { - width: 765px; -} - -.integrations-actionsList { - display: flex; - flex-direction: column; - width: 200px; - border-radius: 2px; -} - -.integrations-actionItem { - padding: 8px; - display: flex; - align-items: center; - flex-direction: row; - flex-shrink: 0; - white-space: nowrap; - border-left: 2px solid transparent; - cursor: pointer; - min-width: 84px; - display: flex; - gap: 8px; - flex-direction: row; - - &:hover { - background: var(--cards-background); - } -} - -.routing-template-container { - margin-bottom: 8px; -} - -.adjust-element-padding { - padding-top: 6px; -} - -.default-route-view { - min-height: 40px; -} - -.block { - width: 100%; - background-color: var(--background-secondary); - border: var(--border-medium) !important; -} - -.labels-panel { - display: flex; - width: 100%; - justify-content: space-between; -} - -.heading-container { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - overflow: hidden; - gap: 12px; - - &__item { - display: flex; - white-space: nowrap; - flex-direction: row; - gap: 8px; - } - - &__item--large { - flex-grow: 1; - overflow: hidden; - } - - &__text { - overflow: hidden; - max-width: calc(100% - 48px); - text-overflow: ellipsis; - } -} diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.styles.ts b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.styles.ts new file mode 100644 index 00000000..def1a70c --- /dev/null +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.styles.ts @@ -0,0 +1,100 @@ +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Colors } from 'styles/utils.styles'; + +export const getExpandedIntegrationRouteDisplayStyles = (theme: GrafanaTheme2) => { + return { + input: css` + border: 1px solid ${theme.colors.border.weak}; + `, + + inputAlign: css` + width: 728px; + `, + + fields: css` + margin-bottom: 0; + `, + + routingAlert: css` + width: 765px; + `, + + integrationsActionsList: css` + display: flex; + flex-direction: column; + width: 200px; + border-radius: 2px; + `, + + integrationsActionItem: css` + padding: 8px; + display: flex; + align-items: center; + flex-direction: row; + flex-shrink: 0; + white-space: nowrap; + border-left: 2px solid transparent; + cursor: pointer; + min-width: 84px; + display: flex; + gap: 8px; + flex-direction: row; + + &:hover { + background: ${theme.isLight ? Colors.HOVER : Colors.GRAY_9}; + } + `, + + routingTemplateContainer: css` + margin-bottom: 8px; + `, + + adjustElementPadding: css` + padding-top: 6px; + `, + + defaultRouteView: css` + min-height: 40px; + `, + + block: css` + width: 100%; + background-color: ${theme.colors.background.secondary}; + border: 1px solid ${theme.colors.border.medium} !important; + `, + + labelsPanel: css` + display: flex; + width: 100%; + justify-content: space-between; + `, + + headingContainer: css` + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + overflow: hidden; + gap: 12px; + `, + + headingContainerItem: css` + display: flex; + white-space: nowrap; + flex-direction: row; + gap: 8px; + `, + + headingContainerItemLarge: css` + flex-grow: 1; + overflow: hidden; + `, + + headingContainerItemText: css` + overflow: hidden; + max-width: calc(100% - 48px); + text-overflow: ellipsis; + `, + }; +}; diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index 5785c763..30455ffa 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useReducer, useState } from 'react'; +import { css, cx } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; import { Button, @@ -11,13 +12,14 @@ import { Select, RadioButtonGroup, Alert, + useStyles2, } from '@grafana/ui'; -import cn from 'classnames/bind'; import { UserActions } from 'helpers/authorization/authorization'; import { StackSize } from 'helpers/consts'; import { openNotification } from 'helpers/helpers'; import { observer } from 'mobx-react'; import CopyToClipboard from 'react-copy-to-clipboard'; +import { getUtilStyles } from 'styles/utils.styles'; import { CollapsibleTreeView, CollapsibleItem } from 'components/CollapsibleTreeView/CollapsibleTreeView'; import { HamburgerMenuIcon } from 'components/HamburgerMenuIcon/HamburgerMenuIcon'; @@ -30,7 +32,6 @@ import { Text } from 'components/Text/Text'; import { WithContextMenu } from 'components/WithContextMenu/WithContextMenu'; import { ChatOpsConnectors } from 'containers/AlertRules/AlertRules'; import { EscalationChainSteps } from 'containers/EscalationChainSteps/EscalationChainSteps'; -import styles from 'containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss'; import { RouteHeading } from 'containers/IntegrationContainers/RouteHeading'; import { RouteLabelsDisplay } from 'containers/RouteLabelsDisplay/RouteLabelsDisplay'; import { TeamName } from 'containers/TeamName/TeamName'; @@ -46,7 +47,7 @@ import { MONACO_INPUT_HEIGHT_SMALL } from 'pages/integration/IntegrationCommon.c import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; -const cx = cn.bind(styles); +import { getExpandedIntegrationRouteDisplayStyles } from './ExpandedIntegrationRouteDisplay.styles'; interface ExpandedIntegrationRouteDisplayProps { alertReceiveChannelId: ApiSchemas['AlertReceiveChannel']['id']; @@ -107,6 +108,7 @@ export const ExpandedIntegrationRouteDisplay: React.FC(undefined); const [labels, setLabels] = useState>([]); const [labelErrors, setLabelErrors] = useState([]); + const styles = useStyles2(getExpandedIntegrationRouteDisplayStyles); const [{ isEscalationCollapsed, isRefreshingEscalationChains, routeIdForDeletion }, setState] = useReducer( (state: ExpandedIntegrationRouteDisplayState, newState: Partial) => ({ @@ -170,9 +172,9 @@ export const ExpandedIntegrationRouteDisplay: React.FC ( -
+
{isDefault ? ( -
+
All unmatched alerts are directed to this route, grouped using the Grouping Template, sent to messengers, and trigger the escalation chain @@ -186,7 +188,7 @@ export const ExpandedIntegrationRouteDisplay: React.FC -
+
-
+
( -
+
Publish to ChatOps @@ -278,7 +280,7 @@ export const ExpandedIntegrationRouteDisplay: React.FC ( -
+
Trigger escalation chain @@ -322,7 +324,7 @@ export const ExpandedIntegrationRouteDisplay: React.FC - + +
-
+
= ({ const { alertReceiveChannelStore } = useStore(); const channelFilter = alertReceiveChannelStore.channelFilters[channelFilterId]; const channelFilterIds = alertReceiveChannelStore.channelFilterIds[alertReceiveChannelId]; + const styles = useStyles2(getExpandedIntegrationRouteDisplayStyles); + const utilStyles = useStyles2(getUtilStyles); return ( @@ -526,13 +530,13 @@ export const RouteButtonsDisplay: React.FC = ({ {!channelFilter.is_default && ( ( -
-
+
+
Edit Template
openNotification('Route ID is copied')}> -
+
@@ -541,10 +545,10 @@ export const RouteButtonsDisplay: React.FC = ({
-
+
-
+
@@ -561,7 +565,11 @@ export const RouteButtonsDisplay: React.FC = ({ openMenu={openMenu} listBorder={2} listWidth={200} - className={'hamburgerMenu--small'} + className={css` + height: 24px; + width: 22px; + cursor: pointer; + `} stopPropagation={true} /> )} diff --git a/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.module.scss b/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.module.scss deleted file mode 100644 index d5b6e3de..00000000 --- a/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.instruction { - ol, - ul { - padding: 0; - margin: 0; - list-style: none; - } -} diff --git a/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.tsx b/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.tsx index 3dff84fe..b92aaa65 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/IntegrationHeartbeatForm/IntegrationHeartbeatForm.tsx @@ -1,8 +1,8 @@ import React, { ReactElement, useEffect, useState } from 'react'; +import { css, cx } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; import { Button, Drawer, Field, Icon, Select, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; import { UserActions } from 'helpers/authorization/authorization'; import { StackSize } from 'helpers/consts'; import { openNotification } from 'helpers/helpers'; @@ -17,10 +17,6 @@ import { SelectOption } from 'state/types'; import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; -import styles from './IntegrationHeartbeatForm.module.scss'; - -const cx = cn.bind(styles); - interface IntegrationHeartbeatFormProps { alertReceveChannelId: ApiSchemas['AlertReceiveChannel']['id']; onClose?: () => void; @@ -56,7 +52,11 @@ const _IntegrationHeartbeatForm = observer(({ alertReceveChannelId, onClose }: I -
+
-
+
; onBlockClick: (option: ApiSchemas['AlertReceiveChannelIntegrationOptions']) => void; }> = ({ options, onBlockClick }) => { + const styles = useStyles2(getIntegrationFormContainerStyles); + return ( -
+
{options.length ? ( options.map((alertReceiveChannelChoice) => { return ( @@ -134,12 +136,11 @@ const IntegrationBlocks: React.FC<{ shadowed onClick={() => onBlockClick(alertReceiveChannelChoice)} key={alertReceiveChannelChoice.value} - className={cx('card', { card_featured: alertReceiveChannelChoice.featured })} + className={cx(styles.card, { [styles.cardFeatured]: alertReceiveChannelChoice.featured })} > -
- -
-
+ + +
diff --git a/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.module.css b/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.module.css deleted file mode 100644 index 1e9b21de..00000000 --- a/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.module.css +++ /dev/null @@ -1,14 +0,0 @@ -.labels-list { - margin: 0; - list-style-type: none; - - > li { - margin: 10px 0; - } -} - -.buttons { - width: 100%; - margin-top: 30px; - margin-bottom: 24px; -} diff --git a/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.tsx b/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.tsx index 68751867..a50c9a60 100644 --- a/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.tsx +++ b/grafana-plugin/src/containers/IntegrationLabelsForm/IntegrationLabelsForm.tsx @@ -1,9 +1,9 @@ import React, { ChangeEvent, useState } from 'react'; +import { css } from '@emotion/css'; import { ServiceLabels } from '@grafana/labels'; -import { Alert, Button, Drawer, Dropdown, InlineSwitch, Input, Menu, Stack } from '@grafana/ui'; -import cn from 'classnames/bind'; -import { DOCS_ROOT, GENERIC_ERROR, StackSize } from 'helpers/consts'; +import { Alert, Button, Drawer, Dropdown, InlineSwitch, Input, Menu, Stack, useStyles2 } from '@grafana/ui'; +import { DOCS_ROOT, StackSize, GENERIC_ERROR } from 'helpers/consts'; import { openErrorNotification } from 'helpers/helpers'; import { observer } from 'mobx-react'; @@ -12,6 +12,10 @@ import { MonacoEditor, MonacoLanguage } from 'components/MonacoEditor/MonacoEdit import { PluginLink } from 'components/PluginLink/PluginLink'; import { RenderConditionally } from 'components/RenderConditionally/RenderConditionally'; import { Text } from 'components/Text/Text'; +import { + getIsAddBtnDisabled, + getIsTooManyLabelsWarningVisible, +} from 'containers/IntegrationLabelsForm/IntegrationLabelsForm.helpers'; import { IntegrationTemplate } from 'containers/IntegrationTemplate/IntegrationTemplate'; import { splitToGroups } from 'models/label/label.helpers'; import { LabelsErrors } from 'models/label/label.types'; @@ -19,12 +23,6 @@ import { ApiSchemas } from 'network/oncall-api/api.types'; import { LabelTemplateOptions } from 'pages/integration/IntegrationCommon.config'; import { useStore } from 'state/useStore'; -import { getIsAddBtnDisabled, getIsTooManyLabelsWarningVisible } from './IntegrationLabelsForm.helpers'; - -import styles from './IntegrationLabelsForm.module.css'; - -const cx = cn.bind(styles); - const INPUT_WIDTH = 280; interface IntegrationLabelsFormProps { @@ -42,6 +40,7 @@ export const IntegrationLabelsForm = observer((props: IntegrationLabelsFormProps const [showTemplateEditor, setShowTemplateEditor] = useState(false); const [customLabelsErrors, setCustomLabelsErrors] = useState([]); const [customLabelIndexToShowTemplateEditor, setCustomLabelIndexToShowTemplateEditor] = useState(undefined); + const styles = useStyles2(getStyles); const { alertReceiveChannelStore } = store; @@ -83,7 +82,12 @@ export const IntegrationLabelsForm = observer((props: IntegrationLabelsFormProps scrollableContent title="Alert group labeling" subtitle={ - + Combination of settings that manage the labeling of alert groups. More information in{' '} documentation @@ -111,7 +115,7 @@ export const IntegrationLabelsForm = observer((props: IntegrationLabelsFormProps Labels inherited from the integration . This behavior can be disabled using the toggle option. -