import { css } from '@emotion/css'; import { useState } from 'react'; import { ExploreUrlState, GrafanaTheme2, serializeStateToUrlParam, toURLRange } from '@grafana/data'; import { SceneComponentProps, SceneObjectBase, SceneObjectState, SceneTimeRangeState, SceneVariableSetState, sceneGraph, } from '@grafana/scenes'; import { DataQuery } from '@grafana/schema'; import { Button, Dropdown, Icon, IconButton, Menu, Modal, useStyles2 } from '@grafana/ui'; import { trackInsightsFeedback } from '../Analytics'; type DataQueryWithExpr = DataQuery & { expr: string }; const getPrometheusExploreUrl = ({ queries, range, variables, }: { queries?: DataQueryWithExpr[]; range: SceneTimeRangeState; variables: SceneVariableSetState; }): string => { // In Mimir-per-group panels, replace `$rule_group` in the query expression with the actual rule group value const ruleGroup = variables?.variables.find((v) => v.state.name === 'rule_group')?.getValue() || null; if (ruleGroup !== null) { queries = queries?.map((query) => { return { ...query, expr: query.expr.replace('$rule_group', String(ruleGroup)), }; }); } const urlState: ExploreUrlState = { datasource: (queries?.length && queries[0].datasource?.uid) || null, queries: queries?.map(({ expr, refId }, i) => { return { expr, refId }; }) || [], range: toURLRange(range ? { from: range.from, to: range.to } : { from: 'now-1h', to: 'now' }), }; const param = encodeURIComponent(serializeStateToUrlParam(urlState)); return `/explore?left=${param}`; }; const InsightsMenuButtonRenderer = ({ model }: SceneComponentProps) => { const data = sceneGraph.getData(model).useState(); const timeRange = sceneGraph.getTimeRange(model).useState(); const variables = sceneGraph.getVariables(model).useState(); const panel = model.state.panel; const url = getPrometheusExploreUrl({ queries: data.data?.request?.targets as DataQueryWithExpr[], range: timeRange, variables: variables, }); const styles = useStyles2(getStyles); const [showModal, setShowModal] = useState(false); const onDismiss = () => { setShowModal(false); }; const onButtonClick = (useful: boolean) => { trackInsightsFeedback({ useful, panel: panel }); onDismiss(); }; const modal = (

Help us improve this page by telling us whether this panel is useful to you!

); const menu = ( setShowModal(true)} /> ); return (
{modal}
); }; interface InsightsMenuButtonState extends SceneObjectState { panel: string; } export class InsightsMenuButton extends SceneObjectBase { static Component = InsightsMenuButtonRenderer; } const getStyles = (theme: GrafanaTheme2) => ({ buttonsContainer: css({ display: 'flex', flexDirection: 'row', justifyContent: 'center', alignItems: 'stretch', gap: '25px', }), buttonContainer: css({ height: '150px', width: '150px', cursor: 'pointer', justifyContent: 'center', }), button: css({ display: 'flex', flexDirection: 'column', }), container: css({ maxWidth: '370px', }), menu: css({ height: '25px', margin: '0', }), thumbsdown: css({ transform: 'scale(-1, -1);', }), });