mirror of https://github.com/grafana/grafana
Dashboard: Variable controls via simple react component (#103442)
* Dashboard: Variable controls refactor * Update tests * Fix name * fix lintpull/103450/head
parent
48877f9187
commit
5aa358c481
@ -0,0 +1,70 @@ |
|||||||
|
import { css } from '@emotion/css'; |
||||||
|
|
||||||
|
import { VariableHide } from '@grafana/data'; |
||||||
|
import { selectors } from '@grafana/e2e-selectors'; |
||||||
|
import { sceneGraph, useSceneObjectState, SceneVariable, SceneVariableState, ControlsLabel } from '@grafana/scenes'; |
||||||
|
|
||||||
|
import { DashboardScene } from './DashboardScene'; |
||||||
|
|
||||||
|
export function VariableControls({ dashboard }: { dashboard: DashboardScene }) { |
||||||
|
const variables = sceneGraph.getVariables(dashboard)!.useState(); |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
{variables.variables.map((variable) => ( |
||||||
|
<VariableValueSelectWrapper key={variable.state.key} variable={variable} /> |
||||||
|
))} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
interface VariableSelectProps { |
||||||
|
variable: SceneVariable; |
||||||
|
} |
||||||
|
|
||||||
|
export function VariableValueSelectWrapper({ variable }: VariableSelectProps) { |
||||||
|
const state = useSceneObjectState<SceneVariableState>(variable, { shouldActivateOrKeepAlive: true }); |
||||||
|
|
||||||
|
if (state.hide === VariableHide.hideVariable) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className={containerStyle} data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}> |
||||||
|
<VariableLabel variable={variable} /> |
||||||
|
<variable.Component model={variable} /> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
function VariableLabel({ variable }: VariableSelectProps) { |
||||||
|
const { state } = variable; |
||||||
|
|
||||||
|
if (variable.state.hide === VariableHide.hideLabel) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
const labelOrName = state.label || state.name; |
||||||
|
const elementId = `var-${state.key}`; |
||||||
|
|
||||||
|
return ( |
||||||
|
<ControlsLabel |
||||||
|
htmlFor={elementId} |
||||||
|
isLoading={state.loading} |
||||||
|
onCancel={() => variable.onCancel?.()} |
||||||
|
label={labelOrName} |
||||||
|
error={state.error} |
||||||
|
layout={'horizontal'} |
||||||
|
description={state.description ?? undefined} |
||||||
|
/> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const containerStyle = css({ |
||||||
|
display: 'flex', |
||||||
|
// No border for second element (inputs) as label and input border is shared
|
||||||
|
'> :nth-child(2)': css({ |
||||||
|
borderTopLeftRadius: 0, |
||||||
|
borderBottomLeftRadius: 0, |
||||||
|
}), |
||||||
|
}); |
||||||
Loading…
Reference in new issue