diff --git a/grafana-plugin/package.json b/grafana-plugin/package.json index 928b23e8..8f86c341 100644 --- a/grafana-plugin/package.json +++ b/grafana-plugin/package.json @@ -174,6 +174,7 @@ "stylelint": "^13.13.1", "stylelint-config-standard": "^22.0.0", "throttle-debounce": "^2.1.0", + "tinycolor2": "^1.6.0", "tslib": "2.5.3" }, "packageManager": "yarn@1.22.21" diff --git a/grafana-plugin/src/components/CardButton/CardButton.styles.ts b/grafana-plugin/src/components/CardButton/CardButton.styles.ts index ec773895..e2584fd5 100644 --- a/grafana-plugin/src/components/CardButton/CardButton.styles.ts +++ b/grafana-plugin/src/components/CardButton/CardButton.styles.ts @@ -23,17 +23,15 @@ export const getCardButtonStyles = (theme: GrafanaTheme2) => { `, rootSelected: css` - { - &::before { - display: block; - content: ''; - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 4px; - background-image: linear-gradient(270deg, #f55f3e 0%, #f83 100%); - } + &::before { + display: block; + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 4px; + background-image: ${theme.colors.gradients.brandVertical}; } `, }; diff --git a/grafana-plugin/src/components/Integrations/IntegrationTag.tsx b/grafana-plugin/src/components/Integrations/IntegrationTag.tsx index 105014d3..795edab6 100644 --- a/grafana-plugin/src/components/Integrations/IntegrationTag.tsx +++ b/grafana-plugin/src/components/Integrations/IntegrationTag.tsx @@ -1,10 +1,9 @@ import React, { FC } from 'react'; import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { Tag } from 'components/Tag/Tag'; +import { Tag, TagColor } from 'components/Tag/Tag'; import { Text } from 'components/Text/Text'; interface IntegrationTagProps { @@ -15,7 +14,7 @@ export const IntegrationTag: FC = ({ children }) => { const styles = useStyles2(getStyles); return ( - + {children} @@ -23,11 +22,9 @@ export const IntegrationTag: FC = ({ children }) => { ); }; -export const getStyles = (theme: GrafanaTheme2) => ({ +export const getStyles = () => ({ tag: css({ height: '25px', - background: theme.colors.background.secondary, - border: `1px solid ${theme.colors.border.weak}`, }), radius: css({ borderRadius: '4px', diff --git a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx index 0b1b4f95..53967b6b 100644 --- a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx @@ -7,6 +7,7 @@ import { observer } from 'mobx-react'; import moment from 'moment-timezone'; import { SortableElement } from 'react-sortable-hoc'; import reactStringReplace from 'react-string-replace'; +import { getLabelBackgroundTextColorObject } from 'styles/utils.styles'; import { PluginLink } from 'components/PluginLink/PluginLink'; import { Text } from 'components/Text/Text'; @@ -28,7 +29,6 @@ import { UserGroup } from 'models/user_group/user_group.types'; import { ApiSchemas } from 'network/oncall-api/api.types'; import { SelectOption, WithStoreProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; -import { getVar } from 'utils/DOM'; import { UserActions } from 'utils/authorization/authorization'; import { DragHandle } from './DragHandle'; @@ -80,12 +80,14 @@ class _EscalationPolicy extends React.Component { (escalationOption: EscalationPolicyOption) => escalationOption.value === step ); + const { textColor: itemTextColor } = getLabelBackgroundTextColorObject('green', this.props.theme); + return ( diff --git a/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.styles.ts b/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.styles.ts index 8ca90009..bc8cfc51 100644 --- a/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.styles.ts +++ b/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.styles.ts @@ -17,27 +17,6 @@ export const getScheduleQualityStyles = (_theme: GrafanaTheme2) => { tag: css` font-size: 12px; padding: 5px 10px; - - &--danger { - // TODO: emotionjs - background-color: var(--tag-background-danger); - color: var(--tag-text-danger); - border: 1px solid var(--tag-border-danger); - } - - &--warning { - // TODO: emotionjs - background-color: var(--tag-background-warning); - color: var(--tag-text-warning); - border: 1px solid var(--tag-border-warning); - } - - &--primary { - // TODO: emotionjs - background-color: var(--tag-background-success); - color: var(--tag-text-success); - border: 1px solid var(--tag-border-success); - } `, }; }; diff --git a/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.tsx b/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.tsx index 72e88d2c..e8896651 100644 --- a/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.tsx +++ b/grafana-plugin/src/components/ScheduleQuality/ScheduleQuality.tsx @@ -3,11 +3,11 @@ import React, { FC, useEffect } from 'react'; import { cx } from '@emotion/css'; import { Tooltip, VerticalGroup, useStyles2 } from '@grafana/ui'; import { observer } from 'mobx-react'; -import { bem, getUtilStyles } from 'styles/utils.styles'; +import { getUtilStyles } from 'styles/utils.styles'; import { PluginLink } from 'components/PluginLink/PluginLink'; import { ScheduleQualityDetails } from 'components/ScheduleQualityDetails/ScheduleQualityDetails'; -import { Tag } from 'components/Tag/Tag'; +import { Tag, TagColor } from 'components/Tag/Tag'; import { Text } from 'components/Text/Text'; import { TooltipBadge } from 'components/TooltipBadge/TooltipBadge'; import { Schedule, ScheduleScoreQualityResult } from 'models/schedule/schedule.types'; @@ -88,7 +88,7 @@ export const ScheduleQuality: FC = observer(({ schedule }) content={} >
- + Quality: {getScheduleQualityString(quality.total_score)}
@@ -115,11 +115,11 @@ export const ScheduleQuality: FC = observer(({ schedule }) function getTagSeverity() { if (quality?.total_score < 20) { - return 'danger'; + return TagColor.ERROR_LABEL; } if (quality?.total_score < 60) { - return 'warning'; + return TagColor.WARNING_LABEL; } - return 'primary'; + return TagColor.SUCCESS_LABEL; } }); diff --git a/grafana-plugin/src/components/Tag/Tag.tsx b/grafana-plugin/src/components/Tag/Tag.tsx index 7c072d69..3dc9feb4 100644 --- a/grafana-plugin/src/components/Tag/Tag.tsx +++ b/grafana-plugin/src/components/Tag/Tag.tsx @@ -3,10 +3,10 @@ import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { bem } from 'styles/utils.styles'; +import { bem, getLabelCss } from 'styles/utils.styles'; interface TagProps { - color?: string; + color?: string | TagColor; className?: string; border?: string; text?: string; @@ -16,43 +16,89 @@ interface TagProps { size?: 'small' | 'medium'; } +export enum TagColor { + SUCCESS = 'success', + WARNING = 'warning', + ERROR = 'error', + SECONDARY = 'secondary', + INFO = 'info', + + SUCCESS_LABEL = 'successLabel', + WARNING_LABEL = 'warningLabel', + ERROR_LABEL = 'errorLabel', +} + export const Tag: FC = (props) => { + const { color, children, className, onClick, size = 'medium' } = props; + const styles = useStyles2(getStyles); - const { children, color, text, className, border, onClick, size = 'medium' } = props; - const style: React.CSSProperties = { - backgroundColor: color, - color: text, - border, - }; return ( {children} ); -}; -const getStyles = (_theme: GrafanaTheme2) => { - return { - root: css` - border-radius: 2px; - line-height: 100%; - padding: 5px 8px; - color: #fff; - display: inline-block; - white-space: nowrap; - `, + function getMatchingClass() { + return styles[color] + ? // Either pick a defined style already or create one on the spot with the passed bgColor + styles[color] + : css` + background-color: ${color}; + color: text; + `; + } - size: css` - &--small { - font-size: 12px; - height: 24px; - } - `, - }; + function getStyles(theme: GrafanaTheme2) { + return { + root: css` + border-radius: 2px; + line-height: 100%; + padding: 5px 8px; + display: inline-block; + white-space: nowrap; + `, + + size: css` + &--small { + font-size: 12px; + height: 24px; + } + `, + + success: css` + background-color: ${theme.colors.success.main}; + border: solid 1px ${theme.colors.success.main}; + color: ${theme.isDark ? '#fff' : theme.colors.success.contrastText}; + `, + warning: css` + background-color: ${theme.colors.warning.main}; + border: solid 1px ${theme.colors.warning.main}; + color: #fff; + `, + error: css` + background-color: ${theme.colors.error.main}; + border: solid 1px ${theme.colors.error.main}; + color: ${theme.isDark ? '#fff' : theme.colors.error.contrastText}; + `, + secondary: css` + background-color: ${theme.colors.secondary.main}; + border: solid 1px ${theme.colors.secondary.main}; + color: ${theme.isDark ? '#fff' : theme.colors.secondary.contrastText}; + `, + info: css` + background-color: ${theme.colors.primary.main}; + border: solid 1px ${theme.colors.primary.main}; + color: ${theme.isDark ? '#fff' : theme.colors.info.contrastText}; + `, + + successLabel: getLabelCss('green', theme), + warningLabel: getLabelCss('orange', theme), + errorLabel: getLabelCss('red', theme), + }; + } }; diff --git a/grafana-plugin/src/components/Text/Text.styles.ts b/grafana-plugin/src/components/Text/Text.styles.ts index 0f8e20fe..901f30af 100644 --- a/grafana-plugin/src/components/Text/Text.styles.ts +++ b/grafana-plugin/src/components/Text/Text.styles.ts @@ -7,8 +7,8 @@ export const getTextStyles = (theme: GrafanaTheme2) => { root: css` display: inline; - &:hover .icon-button { - display: inline-block; + &:hover [data-emotion='iconButton'] { + display: inline-flex; } `, diff --git a/grafana-plugin/src/components/Text/Text.tsx b/grafana-plugin/src/components/Text/Text.tsx index 5877e4c4..493d9e0b 100644 --- a/grafana-plugin/src/components/Text/Text.tsx +++ b/grafana-plugin/src/components/Text/Text.tsx @@ -91,8 +91,8 @@ export const Text: TextInterface = (props) => { styles.root, styles.text, { [styles.maxWidth]: Boolean(maxWidth) }, - { [bem(styles.text, `${type}`)]: true }, - { [bem(styles.text, `${size}`)]: true }, + { [bem(styles.text, type)]: true }, + { [bem(styles.text, size)]: true }, { [bem(styles.text, `strong`)]: strong }, { [bem(styles.text, `underline`)]: underline }, { [bem(styles.text, 'clickable')]: clickable }, @@ -109,6 +109,7 @@ export const Text: TextInterface = (props) => { className={styles.iconButton} tooltip="Edit" tooltipPlacement="top" + data-emotion="iconButton" name="pen" /> )} @@ -124,6 +125,7 @@ export const Text: TextInterface = (props) => { className={styles.iconButton} tooltip="Copy to clipboard" tooltipPlacement="top" + data-emotion="iconButton" name="copy" /> diff --git a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.styles.ts b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.styles.ts index 455eb4d2..86a25ab6 100644 --- a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.styles.ts +++ b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.styles.ts @@ -1,8 +1,20 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; +import { getLabelCss } from 'styles/utils.styles'; export const getTooltipBadgeStyles = (theme: GrafanaTheme2) => { return { + primary: getLabelCss('blue', theme), + warning: getLabelCss('orange', theme), + success: getLabelCss('green', theme), + danger: getLabelCss('red', theme), + + secondary: css` + background: ${theme.colors.background.secondary}; + border: 1px solid ${theme.colors.border.weak}; + color: ${theme.colors.text.primary}; + `, + element: css` font-size: 12px; line-height: 16px; @@ -10,36 +22,6 @@ export const getTooltipBadgeStyles = (theme: GrafanaTheme2) => { border-radius: 2px; display: inline-block; - &--primary { - background: var(--tag-background-primary); - border: 1px solid var(--tag-border-primary); - color: var(--tag-text-primary); - } - - &--secondary { - background: ${theme.colors.background.secondary}; - border: 1px solid ${theme.colors.border.weak}; - color: ${theme.colors.text.primary}; - } - - &--warning { - background: var(--tag-background-warning); - border: 1px solid var(--tag-border-warning); - color: var(--tag-text-warning); - } - - &--success { - background: var(--tag-background-success); - border: 1px solid var(--tag-border-success); - color: var(--tag-text-success); - } - - &--danger { - background: var(--tag-background-danger); - border: 1px solid var(--tag-border-danger); - color: var(--tag-text-danger); - } - &--padding { padding: 3px 10px; } diff --git a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx index 1c40cf7f..858af3dc 100644 --- a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx +++ b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx @@ -55,12 +55,7 @@ export const TooltipBadge: FC = (props) => { } >
diff --git a/grafana-plugin/src/components/Unauthorized/__snapshots__/Unauthorized.test.tsx.snap b/grafana-plugin/src/components/Unauthorized/__snapshots__/Unauthorized.test.tsx.snap index 83950867..59b30dfb 100644 --- a/grafana-plugin/src/components/Unauthorized/__snapshots__/Unauthorized.test.tsx.snap +++ b/grafana-plugin/src/components/Unauthorized/__snapshots__/Unauthorized.test.tsx.snap @@ -20,7 +20,7 @@ exports[`Unauthorized renders properly - access control enabled: false 1`] = ` className="css-1fmhfo9" > Participants @@ -72,7 +72,7 @@ exports[`AddResponders should properly display the add responders button when hi class="css-u023fv" > Participants @@ -106,7 +106,7 @@ exports[`AddResponders should render properly in create mode 1`] = ` class="css-u023fv" > Participants @@ -159,7 +159,7 @@ exports[`AddResponders should render properly in update mode 1`] = ` class="css-u023fv" > Participants @@ -212,7 +212,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-u023fv" > Participants @@ -270,7 +270,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-18qv8yz-layoutChildrenWrapper" > my test team @@ -323,7 +323,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-18qv8yz-layoutChildrenWrapper" > my test user3 @@ -438,7 +438,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-18qv8yz-layoutChildrenWrapper" > my test user @@ -552,7 +552,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-18qv8yz-layoutChildrenWrapper" > my test user2 @@ -664,7 +664,7 @@ exports[`AddResponders should render selected team and users properly 1`] = ` class="css-9om60p" >
my test team diff --git a/grafana-plugin/src/containers/AddResponders/parts/UserResponder/__snapshots__/UserResponder.test.tsx.snap b/grafana-plugin/src/containers/AddResponders/parts/UserResponder/__snapshots__/UserResponder.test.tsx.snap index b2f33321..722f56a7 100644 --- a/grafana-plugin/src/containers/AddResponders/parts/UserResponder/__snapshots__/UserResponder.test.tsx.snap +++ b/grafana-plugin/src/containers/AddResponders/parts/UserResponder/__snapshots__/UserResponder.test.tsx.snap @@ -31,7 +31,7 @@ exports[`UserResponder it renders data properly 1`] = ` class="css-18qv8yz-layoutChildrenWrapper" > johnsmith diff --git a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx index c3b9cf57..82c2941c 100644 --- a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx +++ b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; -import { VerticalGroup } from '@grafana/ui'; +import { VerticalGroup, useTheme2 } from '@grafana/ui'; import { Timeline } from 'components/Timeline/Timeline'; import { MSTeamsConnector } from 'containers/AlertRules/parts/connectors/MSTeamsConnector'; @@ -9,7 +9,6 @@ import { TelegramConnector } from 'containers/AlertRules/parts/connectors/Telegr import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; -import { getVar } from 'utils/DOM'; interface ChatOpsConnectorsProps { channelFilterId: ChannelFilter['id']; @@ -20,6 +19,7 @@ export const ChatOpsConnectors = (props: ChatOpsConnectorsProps) => { const { channelFilterId, showLineNumber = true } = props; const store = useStore(); + const theme = useTheme2(); const { organizationStore, telegramChannelStore, msteamsChannelStore } = store; const isSlackInstalled = Boolean(organizationStore.currentOrganization?.slack_team_identity); @@ -37,7 +37,7 @@ export const ChatOpsConnectors = (props: ChatOpsConnectorsProps) => { } return ( - + {isSlackInstalled && } {isTelegramInstalled && } diff --git a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx index 9faffc51..97ae2cd4 100644 --- a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx +++ b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx @@ -2,10 +2,11 @@ import React, { ReactElement, useCallback, useEffect } from 'react'; import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; -import { LoadingPlaceholder, Select, useStyles2 } from '@grafana/ui'; +import { LoadingPlaceholder, Select, useStyles2, useTheme2 } from '@grafana/ui'; import cn from 'classnames/bind'; import { get } from 'lodash-es'; import { observer } from 'mobx-react'; +import { getLabelBackgroundTextColorObject } from 'styles/utils.styles'; import { EscalationPolicy, EscalationPolicyProps } from 'components/Policy/EscalationPolicy'; import { SortableList } from 'components/SortableList/SortableList'; @@ -14,7 +15,6 @@ import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/W import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'; import { EscalationPolicyOption } from 'models/escalation_policy/escalation_policy.types'; import { useStore } from 'state/useStore'; -import { getVar } from 'utils/DOM'; import { UserActions } from 'utils/authorization/authorization'; import styles from './EscalationChainSteps.module.css'; @@ -41,6 +41,7 @@ export const EscalationChainSteps = observer((props: EscalationChainStepsProps) const store = useStore(); const styles = useStyles2(getStyles); + const theme = useTheme2(); const { escalationPolicyStore } = store; @@ -74,6 +75,7 @@ export const EscalationChainSteps = observer((props: EscalationChainStepsProps) const escalationPolicyIds = escalationPolicyStore.escalationChainToEscalationPolicy[id]; const isSlackInstalled = Boolean(store.organizationStore.currentOrganization?.slack_team_identity); + const { bgColor: successBgColor, textColor: successTextColor } = getLabelBackgroundTextColorObject('green', theme); return ( // @ts-ignore @@ -124,8 +126,8 @@ export const EscalationChainSteps = observer((props: EscalationChainStepsProps) {!isDisabled && (