diff --git a/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.module.css b/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.module.css new file mode 100644 index 00000000..0a753b7d --- /dev/null +++ b/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.module.css @@ -0,0 +1,19 @@ +.hamburger-menu { + cursor: pointer; + color: var(--primary-text-color); +} + +.hamburger-menu-withBackground { + display: inline-flex; + flex-direction: column; + align-items: center; + vertical-align: middle; + justify-content: center; + background-color: rgba(204, 204, 220, 0.16); + border: 1px solid transparent; + height: 32px; + width: 30px; + padding: 4px; + cursor: pointer; + color: var(--primary-text-color); +} diff --git a/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.tsx b/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.tsx new file mode 100644 index 00000000..7b7c1b48 --- /dev/null +++ b/grafana-plugin/src/components/HamburgerMenu/HamburgerMenu.tsx @@ -0,0 +1,39 @@ +import React, { useRef } from 'react'; + +import { Icon } from '@grafana/ui'; +import cn from 'classnames/bind'; + +import styles from './HamburgerMenu.module.css'; + +interface HamburgerMenuProps { + openMenu: React.MouseEventHandler; + listWidth: number; + listBorder: number; + withBackground?: boolean; + className?: string; +} + +const cx = cn.bind(styles); + +const HamburgerMenu: React.FC = (props) => { + const ref = useRef(); + const { openMenu, listBorder, listWidth, withBackground, className } = props; + return ( +
{ + const boundingRect = ref.current.getBoundingClientRect(); + + openMenu({ + pageX: boundingRect.right - listWidth + listBorder * 2, + pageY: boundingRect.top + boundingRect.height, + } as any); + }} + > + +
+ ); +}; + +export default HamburgerMenu; diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss index c6ac32bf..72c5715b 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss @@ -6,3 +6,45 @@ width: 700px; } } + +.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(--gray-9); + } +} + +.hamburgerMenu-small { + display: inline-flex; + flex-direction: column; + align-items: center; + vertical-align: middle; + justify-content: center; + background-color: rgba(204, 204, 220, 0.16); + color: var(--secondary-background); + border: 1px solid transparent; + height: 24px; + width: 22px; + padding: 4px; + cursor: pointer; + color: var(--primary-text-color); +} diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index cf24abe8..bccbd1c9 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -14,13 +14,16 @@ import { } from '@grafana/ui'; import cn from 'classnames/bind'; import { observer } from 'mobx-react'; +import CopyToClipboard from 'react-copy-to-clipboard'; +import HamburgerMenu from 'components/HamburgerMenu/HamburgerMenu'; import IntegrationBlock from 'components/Integrations/IntegrationBlock'; import IntegrationBlockItem from 'components/Integrations/IntegrationBlockItem'; import MonacoEditor from 'components/MonacoEditor/MonacoEditor'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; import TooltipBadge from 'components/TooltipBadge/TooltipBadge'; +import { WithContextMenu } from 'components/WithContextMenu/WithContextMenu'; import { ChatOpsConnectors } from 'containers/AlertRules/parts'; import EscalationChainSteps from 'containers/EscalationChainSteps/EscalationChainSteps'; import styles from 'containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.module.scss'; @@ -33,6 +36,7 @@ import { EscalationChain } from 'models/escalation_chain/escalation_chain.types' import { MONACO_INPUT_HEIGHT_SMALL, MONACO_OPTIONS } from 'pages/integration_2/Integration2.config'; import IntegrationHelper from 'pages/integration_2/Integration2.helper'; import { useStore } from 'state/useStore'; +import { openNotification } from 'utils'; import { UserActions } from 'utils/authorization'; const cx = cn.bind(styles); @@ -341,11 +345,38 @@ export const RouteButtonsDisplay: React.FC = ({ )} {!channelFilter.is_default && ( - - -