DashboardControls: Render UNSAFE hidden dashboard controls (#113046)
* Render UNSAFE hidden dashboard controls * Remove unused imports * Extract to function and write test * Remove unnecessary context from test * Remove exclamation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { SceneVariableSet, TextBoxVariable } from '@grafana/scenes';
|
||||
import { SceneVariableSet, ScopesVariable, TextBoxVariable } from '@grafana/scenes';
|
||||
|
||||
import { DashboardControls, DashboardControlsState } from './DashboardControls';
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
@@ -97,6 +97,47 @@ describe('DashboardControls', () => {
|
||||
|
||||
expect(renderer.queryByTestId(selectors.pages.Dashboard.Controls)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render ScopesVariable Component even when hidden', () => {
|
||||
const scopeVariable = new ScopesVariable({
|
||||
enable: true,
|
||||
});
|
||||
|
||||
const dashboard = new DashboardScene({
|
||||
uid: 'test-dashboard',
|
||||
$variables: new SceneVariableSet({
|
||||
variables: [scopeVariable],
|
||||
}),
|
||||
controls: new DashboardControls({
|
||||
hideTimeControls: true,
|
||||
hideVariableControls: true,
|
||||
hideLinksControls: true,
|
||||
hideDashboardControls: true,
|
||||
}),
|
||||
});
|
||||
|
||||
dashboard.activate();
|
||||
|
||||
const controls = dashboard.state.controls as DashboardControls;
|
||||
|
||||
// Mock the Component getter - use 'as any' to bypass TypeScript's getter checking
|
||||
// Return a component function (not JSX directly) that renders our test element
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
jest.spyOn(scopeVariable as any, 'Component', 'get').mockReturnValue(() => {
|
||||
return <div>Mocked Component</div>;
|
||||
});
|
||||
|
||||
const renderer = render(<controls.Component model={controls} />);
|
||||
|
||||
// Verify UNSAFE_renderAsHidden is set (required for renderHiddenVariables to include it)
|
||||
expect(scopeVariable.UNSAFE_renderAsHidden).toBe(true);
|
||||
|
||||
// Check that the mocked component is rendered - this proves renderHiddenVariables
|
||||
// accessed the Component getter and rendered it
|
||||
expect(renderer.getByText('Mocked Component')).toBeInTheDocument();
|
||||
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
});
|
||||
|
||||
describe('UrlSync', () => {
|
||||
|
||||
@@ -153,7 +153,8 @@ function DashboardControlsRenderer({ model }: SceneComponentProps<DashboardContr
|
||||
|
||||
if (!model.hasControls()) {
|
||||
// To still have spacing when no controls are rendered
|
||||
return <Box padding={1} />;
|
||||
|
||||
return <Box padding={1}>{renderHiddenVariables(dashboard)}</Box>;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -200,6 +201,21 @@ function DataLayerControls({ dashboard }: { dashboard: DashboardScene }) {
|
||||
);
|
||||
}
|
||||
|
||||
function renderHiddenVariables(dashboard: DashboardScene) {
|
||||
const { variables } = sceneGraph.getVariables(dashboard).useState();
|
||||
const renderAsHiddenVariables = variables.filter((v) => v.UNSAFE_renderAsHidden);
|
||||
if (renderAsHiddenVariables && renderAsHiddenVariables.length > 0) {
|
||||
return (
|
||||
<>
|
||||
{renderAsHiddenVariables.map((v) => (
|
||||
<v.Component model={v} key={v.state.key} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
controls: css({
|
||||
|
||||
Reference in New Issue
Block a user