mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardScene: Move to new folder structure, some refactorings and progress on inspect (#73810)
* Progress refactoring * Update * Update * Update * DashboardScene: Folder struct propsal * Rename loading to persistance * Moving and renaming
This commit is contained in:
parent
2f22946f06
commit
eab6250142
@ -1952,6 +1952,13 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||||
],
|
],
|
||||||
|
"public/app/features/dashboard-scene/utils/test-utils.ts:5381": [
|
||||||
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
|
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||||
|
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||||
|
[0, 0, 0, "Do not use any type assertions.", "4"]
|
||||||
|
],
|
||||||
"public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx:5381": [
|
"public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||||
],
|
],
|
||||||
@ -2830,13 +2837,6 @@ exports[`better eslint`] = {
|
|||||||
"public/app/features/sandbox/TestStuffPage.tsx:5381": [
|
"public/app/features/sandbox/TestStuffPage.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||||
],
|
],
|
||||||
"public/app/features/scenes/dashboard/test-utils.ts:5381": [
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "4"]
|
|
||||||
],
|
|
||||||
"public/app/features/search/components/SearchCard.tsx:5381": [
|
"public/app/features/search/components/SearchCard.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { SceneComponentProps, SceneObjectBase, VizPanel } from '@grafana/scenes';
|
||||||
|
import { t } from 'app/core/internationalization';
|
||||||
|
|
||||||
|
import { InspectTab } from '../../inspector/types';
|
||||||
|
|
||||||
|
import { InspectTabState } from './types';
|
||||||
|
|
||||||
|
export class InspectDataTab extends SceneObjectBase<InspectTabState> {
|
||||||
|
constructor(public panel: VizPanel) {
|
||||||
|
super({ label: t('dashboard.inspect.data-tab', 'Data'), value: InspectTab.Data });
|
||||||
|
}
|
||||||
|
|
||||||
|
static Component = ({ model }: SceneComponentProps<InspectDataTab>) => {
|
||||||
|
//const data = sceneGraph.getData(model.panel).useState();
|
||||||
|
|
||||||
|
return <div>Data tab</div>;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { SceneComponentProps, SceneObjectBase, VizPanel } from '@grafana/scenes';
|
||||||
|
import { t } from 'app/core/internationalization';
|
||||||
|
|
||||||
|
import { InspectTab } from '../../inspector/types';
|
||||||
|
|
||||||
|
import { InspectTabState } from './types';
|
||||||
|
|
||||||
|
export class InspectJsonTab extends SceneObjectBase<InspectTabState> {
|
||||||
|
constructor(public panel: VizPanel) {
|
||||||
|
super({ label: t('dashboard.inspect.json-tab', 'JSON'), value: InspectTab.JSON });
|
||||||
|
}
|
||||||
|
|
||||||
|
static Component = ({ model }: SceneComponentProps<InspectJsonTab>) => {
|
||||||
|
return <div>JSON</div>;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { SceneComponentProps, sceneGraph, SceneObjectBase, VizPanel } from '@grafana/scenes';
|
||||||
|
import { t } from 'app/core/internationalization';
|
||||||
|
|
||||||
|
import { InspectStatsTab as OldInspectStatsTab } from '../../inspector/InspectStatsTab';
|
||||||
|
import { InspectTab } from '../../inspector/types';
|
||||||
|
|
||||||
|
import { InspectTabState } from './types';
|
||||||
|
|
||||||
|
export class InspectStatsTab extends SceneObjectBase<InspectTabState> {
|
||||||
|
constructor(public panel: VizPanel) {
|
||||||
|
super({ label: t('dashboard.inspect.stats-tab', 'Stats'), value: InspectTab.Stats });
|
||||||
|
}
|
||||||
|
|
||||||
|
static Component = ({ model }: SceneComponentProps<InspectStatsTab>) => {
|
||||||
|
const data = sceneGraph.getData(model.panel).useState();
|
||||||
|
const timeRange = sceneGraph.getTimeRange(model.panel);
|
||||||
|
|
||||||
|
if (!data.data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <OldInspectStatsTab data={data.data} timeZone={timeRange.getTimeZone()} />;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { locationUtil } from '@grafana/data';
|
||||||
|
import { locationService } from '@grafana/runtime';
|
||||||
|
import {
|
||||||
|
SceneComponentProps,
|
||||||
|
SceneObjectBase,
|
||||||
|
SceneObjectState,
|
||||||
|
SceneObject,
|
||||||
|
sceneGraph,
|
||||||
|
VizPanel,
|
||||||
|
} from '@grafana/scenes';
|
||||||
|
import { Drawer, Tab, TabsBar } from '@grafana/ui';
|
||||||
|
import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils';
|
||||||
|
|
||||||
|
import { InspectDataTab } from './InspectDataTab';
|
||||||
|
import { InspectJsonTab } from './InspectJsonTab';
|
||||||
|
import { InspectStatsTab } from './InspectStatsTab';
|
||||||
|
import { InspectTabState } from './types';
|
||||||
|
|
||||||
|
interface PanelInspectDrawerState extends SceneObjectState {
|
||||||
|
tabs?: Array<SceneObject<InspectTabState>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PanelInspectDrawer extends SceneObjectBase<PanelInspectDrawerState> {
|
||||||
|
static Component = ScenePanelInspectorRenderer;
|
||||||
|
|
||||||
|
// Not stored in state as this is just a reference and it never changes
|
||||||
|
private _panel: VizPanel;
|
||||||
|
|
||||||
|
constructor(panel: VizPanel) {
|
||||||
|
super({});
|
||||||
|
|
||||||
|
this._panel = panel;
|
||||||
|
this.buildTabs();
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTabs() {
|
||||||
|
const plugin = this._panel.getPlugin();
|
||||||
|
const tabs: Array<SceneObject<InspectTabState>> = [];
|
||||||
|
|
||||||
|
if (plugin) {
|
||||||
|
if (supportsDataQuery(plugin)) {
|
||||||
|
tabs.push(new InspectDataTab(this._panel));
|
||||||
|
tabs.push(new InspectStatsTab(this._panel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs.push(new InspectJsonTab(this._panel));
|
||||||
|
|
||||||
|
this.setState({ tabs });
|
||||||
|
}
|
||||||
|
|
||||||
|
getDrawerTitle() {
|
||||||
|
return sceneGraph.interpolate(this._panel, `Inspect: ${this._panel.state.title}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClose = () => {
|
||||||
|
locationService.partial({ inspect: null, inspectTab: null });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ScenePanelInspectorRenderer({ model }: SceneComponentProps<PanelInspectDrawer>) {
|
||||||
|
const { tabs } = model.useState();
|
||||||
|
const location = useLocation();
|
||||||
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
|
||||||
|
if (!tabs) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlTab = queryParams.get('inspectTab');
|
||||||
|
const currentTab = tabs.find((tab) => tab.state.value === urlTab) ?? tabs[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
title={model.getDrawerTitle()}
|
||||||
|
scrollableContent
|
||||||
|
onClose={model.onClose}
|
||||||
|
size="md"
|
||||||
|
tabs={
|
||||||
|
<TabsBar>
|
||||||
|
{tabs.map((tab) => {
|
||||||
|
return (
|
||||||
|
<Tab
|
||||||
|
key={tab.state.key!}
|
||||||
|
label={tab.state.label}
|
||||||
|
active={tab === currentTab}
|
||||||
|
href={locationUtil.getUrlForPartial(location, { inspectTab: tab.state.value })}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TabsBar>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{currentTab.Component && <currentTab.Component model={currentTab} />}
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
7
public/app/features/dashboard-scene/inspect/types.ts
Normal file
7
public/app/features/dashboard-scene/inspect/types.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { SceneObjectState } from '@grafana/scenes';
|
||||||
|
import { InspectTab } from 'app/features/inspector/types';
|
||||||
|
|
||||||
|
export interface InspectTabState extends SceneObjectState {
|
||||||
|
label: string;
|
||||||
|
value: InspectTab;
|
||||||
|
}
|
@ -9,8 +9,9 @@ import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
|
|||||||
import { config, locationService, setPluginImportUtils } from '@grafana/runtime';
|
import { config, locationService, setPluginImportUtils } from '@grafana/runtime';
|
||||||
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
||||||
|
|
||||||
|
import { setupLoadDashboardMock } from '../utils/test-utils';
|
||||||
|
|
||||||
import { DashboardScenePage, Props } from './DashboardScenePage';
|
import { DashboardScenePage, Props } from './DashboardScenePage';
|
||||||
import { setupLoadDashboardMock } from './test-utils';
|
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
const context = getGrafanaContextMock();
|
const context = getGrafanaContextMock();
|
@ -6,7 +6,7 @@ import { Page } from 'app/core/components/Page/Page';
|
|||||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||||
|
|
||||||
import { getDashboardLoader } from './DashboardsLoader';
|
import { getDashboardLoader } from '../serialization/DashboardsLoader';
|
||||||
|
|
||||||
export interface Props extends GrafanaRouteComponentProps<{ uid: string }> {}
|
export interface Props extends GrafanaRouteComponentProps<{ uid: string }> {}
|
||||||
|
|
@ -4,7 +4,6 @@ import { AppEvents, locationUtil, NavModelItem } from '@grafana/data';
|
|||||||
import { locationService } from '@grafana/runtime';
|
import { locationService } from '@grafana/runtime';
|
||||||
import {
|
import {
|
||||||
getUrlSyncManager,
|
getUrlSyncManager,
|
||||||
sceneGraph,
|
|
||||||
SceneGridItem,
|
SceneGridItem,
|
||||||
SceneGridLayout,
|
SceneGridLayout,
|
||||||
SceneObject,
|
SceneObject,
|
||||||
@ -13,12 +12,13 @@ import {
|
|||||||
SceneObjectStateChangedEvent,
|
SceneObjectStateChangedEvent,
|
||||||
SceneObjectUrlSyncHandler,
|
SceneObjectUrlSyncHandler,
|
||||||
SceneObjectUrlValues,
|
SceneObjectUrlValues,
|
||||||
VizPanel,
|
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
|
|
||||||
import { DashboardSceneRenderer } from './DashboardSceneRenderer';
|
import { PanelInspectDrawer } from '../inspect/PanelInspectDrawer';
|
||||||
import { forceRenderChildren } from './utils';
|
import { DashboardSceneRenderer } from '../scene/DashboardSceneRenderer';
|
||||||
|
import { findVizPanel } from '../utils/findVizPanel';
|
||||||
|
import { forceRenderChildren } from '../utils/utils';
|
||||||
|
|
||||||
export interface DashboardSceneState extends SceneObjectState {
|
export interface DashboardSceneState extends SceneObjectState {
|
||||||
title: string;
|
title: string;
|
||||||
@ -32,6 +32,8 @@ export interface DashboardSceneState extends SceneObjectState {
|
|||||||
inspectPanelKey?: string;
|
inspectPanelKey?: string;
|
||||||
/** Scene object key for object to view in fullscreen */
|
/** Scene object key for object to view in fullscreen */
|
||||||
viewPanelKey?: string;
|
viewPanelKey?: string;
|
||||||
|
/** Scene object that handles the current drawer */
|
||||||
|
drawer?: SceneObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||||
@ -51,19 +53,6 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
|||||||
this.subscribeToEvent(SceneObjectStateChangedEvent, this.onChildStateChanged);
|
this.subscribeToEvent(SceneObjectStateChangedEvent, this.onChildStateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
findPanel(key: string | undefined): VizPanel | null {
|
|
||||||
if (!key) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const obj = sceneGraph.findObject(this, (obj) => obj.state.key === key);
|
|
||||||
if (obj instanceof VizPanel) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onChildStateChanged = (event: SceneObjectStateChangedEvent) => {
|
onChildStateChanged = (event: SceneObjectStateChangedEvent) => {
|
||||||
// Temporary hacky way to detect changes
|
// Temporary hacky way to detect changes
|
||||||
if (event.payload.changedObject instanceof SceneGridItem) {
|
if (event.payload.changedObject instanceof SceneGridItem) {
|
||||||
@ -97,10 +86,6 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onCloseInspectDrawer = () => {
|
|
||||||
locationService.partial({ inspect: null });
|
|
||||||
};
|
|
||||||
|
|
||||||
getPageNav(location: H.Location) {
|
getPageNav(location: H.Location) {
|
||||||
let pageNav: NavModelItem = {
|
let pageNav: NavModelItem = {
|
||||||
text: this.state.title,
|
text: this.state.title,
|
||||||
@ -116,6 +101,14 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
|||||||
|
|
||||||
return pageNav;
|
return pageNav;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the body (layout) or the full view panel
|
||||||
|
*/
|
||||||
|
getBodyToRender(viewPanelKey?: string): SceneObject {
|
||||||
|
const viewPanel = findVizPanel(this, viewPanelKey);
|
||||||
|
return viewPanel ?? this.state.body;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
||||||
@ -136,7 +129,7 @@ class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
|||||||
|
|
||||||
// Handle inspect object state
|
// Handle inspect object state
|
||||||
if (typeof values.inspect === 'string') {
|
if (typeof values.inspect === 'string') {
|
||||||
const panel = this._scene.findPanel(values.inspect);
|
const panel = findVizPanel(this._scene, values.inspect);
|
||||||
if (!panel) {
|
if (!panel) {
|
||||||
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
||||||
locationService.partial({ inspect: null });
|
locationService.partial({ inspect: null });
|
||||||
@ -144,13 +137,15 @@ class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update.inspectPanelKey = values.inspect;
|
update.inspectPanelKey = values.inspect;
|
||||||
|
update.drawer = new PanelInspectDrawer(panel);
|
||||||
} else if (inspectPanelKey) {
|
} else if (inspectPanelKey) {
|
||||||
update.inspectPanelKey = undefined;
|
update.inspectPanelKey = undefined;
|
||||||
|
update.drawer = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle view panel state
|
// Handle view panel state
|
||||||
if (typeof values.viewPanel === 'string') {
|
if (typeof values.viewPanel === 'string') {
|
||||||
const panel = this._scene.findPanel(values.viewPanel);
|
const panel = findVizPanel(this._scene, values.viewPanel);
|
||||||
if (!panel) {
|
if (!panel) {
|
||||||
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
||||||
locationService.partial({ viewPanel: null });
|
locationService.partial({ viewPanel: null });
|
@ -9,15 +9,13 @@ import { Page } from 'app/core/components/Page/Page';
|
|||||||
|
|
||||||
import { DashboardScene } from './DashboardScene';
|
import { DashboardScene } from './DashboardScene';
|
||||||
import { NavToolbarActions } from './NavToolbarActions';
|
import { NavToolbarActions } from './NavToolbarActions';
|
||||||
import { ScenePanelInspector } from './ScenePanelInspector';
|
|
||||||
|
|
||||||
export function DashboardSceneRenderer({ model }: SceneComponentProps<DashboardScene>) {
|
export function DashboardSceneRenderer({ model }: SceneComponentProps<DashboardScene>) {
|
||||||
const { body, controls, inspectPanelKey, viewPanelKey } = model.useState();
|
const { controls, viewPanelKey, drawer } = model.useState();
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
const inspectPanel = model.findPanel(inspectPanelKey);
|
|
||||||
const viewPanel = model.findPanel(viewPanelKey);
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const pageNav = model.getPageNav(location);
|
const pageNav = model.getPageNav(location);
|
||||||
|
const bodyToRender = model.getBodyToRender(viewPanelKey);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page navId="scenes" pageNav={pageNav} layout={PageLayoutType.Custom}>
|
<Page navId="scenes" pageNav={pageNav} layout={PageLayoutType.Custom}>
|
||||||
@ -31,18 +29,12 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps<DashboardS
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{viewPanel ? (
|
<div className={styles.body}>
|
||||||
<div className={styles.viewPanel}>
|
<bodyToRender.Component model={bodyToRender} />
|
||||||
<viewPanel.Component model={viewPanel} />
|
</div>
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className={styles.body}>
|
|
||||||
<body.Component model={body} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</CustomScrollbar>
|
</CustomScrollbar>
|
||||||
{inspectPanel && <ScenePanelInspector panel={inspectPanel} dashboard={model} />}
|
{drawer && <drawer.Component model={drawer} />}
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -62,11 +54,6 @@ function getStyles(theme: GrafanaTheme2) {
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: '8px',
|
gap: '8px',
|
||||||
}),
|
|
||||||
viewPanel: css({
|
|
||||||
display: 'flex',
|
|
||||||
position: 'relative',
|
|
||||||
flexGrow: 1,
|
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
}),
|
}),
|
||||||
controls: css({
|
controls: css({
|
@ -4,7 +4,7 @@ import { SceneComponentProps, SceneObjectBase, SceneObjectState, VizPanel } from
|
|||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
import { getLibraryPanel } from 'app/features/library-panels/state/api';
|
import { getLibraryPanel } from 'app/features/library-panels/state/api';
|
||||||
|
|
||||||
import { createPanelDataProvider } from './utils/createPanelDataProvider';
|
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
|
||||||
|
|
||||||
interface LibraryVizPanelState extends SceneObjectState {
|
interface LibraryVizPanelState extends SceneObjectState {
|
||||||
// Library panels use title from dashboard JSON's panel model, not from library panel definition, hence we pass it.
|
// Library panels use title from dashboard JSON's panel model, not from library panel definition, hence we pass it.
|
@ -8,8 +8,9 @@ import {
|
|||||||
SceneObjectState,
|
SceneObjectState,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
|
import { activateFullSceneTree, getVizPanelKeyForPanelId } from '../utils/utils';
|
||||||
|
|
||||||
import { ShareQueryDataProvider } from './ShareQueryDataProvider';
|
import { ShareQueryDataProvider } from './ShareQueryDataProvider';
|
||||||
import { activateFullSceneTree, getVizPanelKeyForPanelId } from './utils';
|
|
||||||
|
|
||||||
export class SceneDummyPanel extends SceneObjectBase<SceneObjectState> {}
|
export class SceneDummyPanel extends SceneObjectBase<SceneObjectState> {}
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import { DashboardQuery } from 'app/plugins/datasource/dashboard/types';
|
import { DashboardQuery } from 'app/plugins/datasource/dashboard/types';
|
||||||
|
|
||||||
import { getVizPanelKeyForPanelId } from './utils';
|
import { getVizPanelKeyForPanelId } from '../utils/utils';
|
||||||
|
|
||||||
export interface ShareQueryDataProviderState extends SceneDataState {
|
export interface ShareQueryDataProviderState extends SceneDataState {
|
||||||
query: DashboardQuery;
|
query: DashboardQuery;
|
@ -19,15 +19,16 @@ import { createPanelJSONFixture } from 'app/features/dashboard/state/__fixtures_
|
|||||||
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard';
|
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard';
|
||||||
import { DASHBOARD_DATASOURCE_PLUGIN_ID } from 'app/plugins/datasource/dashboard/types';
|
import { DASHBOARD_DATASOURCE_PLUGIN_ID } from 'app/plugins/datasource/dashboard/types';
|
||||||
|
|
||||||
import { DashboardScene } from './DashboardScene';
|
import { DashboardScene } from '../scene/DashboardScene';
|
||||||
|
import { ShareQueryDataProvider } from '../scene/ShareQueryDataProvider';
|
||||||
|
import { setupLoadDashboardMock } from '../utils/test-utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createDashboardSceneFromDashboardModel,
|
createDashboardSceneFromDashboardModel,
|
||||||
createVizPanelFromPanelModel,
|
createVizPanelFromPanelModel,
|
||||||
createSceneVariableFromVariableModel,
|
createSceneVariableFromVariableModel,
|
||||||
DashboardLoader,
|
DashboardLoader,
|
||||||
} from './DashboardsLoader';
|
} from './DashboardsLoader';
|
||||||
import { ShareQueryDataProvider } from './ShareQueryDataProvider';
|
|
||||||
import { setupLoadDashboardMock } from './test-utils';
|
|
||||||
|
|
||||||
describe('DashboardLoader', () => {
|
describe('DashboardLoader', () => {
|
||||||
describe('when fetching/loading a dashboard', () => {
|
describe('when fetching/loading a dashboard', () => {
|
@ -29,11 +29,11 @@ import { StateManagerBase } from 'app/core/services/StateManagerBase';
|
|||||||
import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv';
|
import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv';
|
||||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||||
|
|
||||||
import { DashboardScene } from './DashboardScene';
|
import { DashboardScene } from '../scene/DashboardScene';
|
||||||
import { LibraryVizPanel } from './LibraryVizPanel';
|
import { LibraryVizPanel } from '../scene/LibraryVizPanel';
|
||||||
import { panelMenuBehavior } from './PanelMenuBehavior';
|
import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
|
||||||
import { getVizPanelKeyForPanelId } from './utils';
|
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
|
||||||
import { createPanelDataProvider } from './utils/createPanelDataProvider';
|
import { getVizPanelKeyForPanelId } from '../utils/utils';
|
||||||
|
|
||||||
export interface DashboardLoaderState {
|
export interface DashboardLoaderState {
|
||||||
dashboard?: DashboardScene;
|
dashboard?: DashboardScene;
|
@ -3,7 +3,7 @@ import { SceneDataProvider, SceneDataTransformer, SceneQueryRunner } from '@graf
|
|||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard';
|
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard';
|
||||||
|
|
||||||
import { ShareQueryDataProvider } from '../ShareQueryDataProvider';
|
import { ShareQueryDataProvider } from '../scene/ShareQueryDataProvider';
|
||||||
|
|
||||||
export function createPanelDataProvider(panel: PanelModel): SceneDataProvider | undefined {
|
export function createPanelDataProvider(panel: PanelModel): SceneDataProvider | undefined {
|
||||||
// Skip setting query runner for panels without queries
|
// Skip setting query runner for panels without queries
|
14
public/app/features/dashboard-scene/utils/findVizPanel.ts
Normal file
14
public/app/features/dashboard-scene/utils/findVizPanel.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { sceneGraph, SceneObject, VizPanel } from '@grafana/scenes';
|
||||||
|
|
||||||
|
export function findVizPanel(scene: SceneObject, key: string | undefined): VizPanel | null {
|
||||||
|
if (!key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const obj = sceneGraph.findObject(scene, (obj) => obj.state.key === key);
|
||||||
|
if (obj instanceof VizPanel) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { dateTimeFormat, formattedValueToString, getValueFormat, SelectableValue
|
|||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { SceneObject } from '@grafana/scenes';
|
import { SceneObject } from '@grafana/scenes';
|
||||||
import { StateManagerBase } from 'app/core/services/StateManagerBase';
|
import { StateManagerBase } from 'app/core/services/StateManagerBase';
|
||||||
import { createDashboardSceneFromDashboardModel } from 'app/features/scenes/dashboard/DashboardsLoader';
|
import { createDashboardSceneFromDashboardModel } from 'app/features/dashboard-scene/serialization/DashboardsLoader';
|
||||||
|
|
||||||
import { getTimeSrv } from '../../services/TimeSrv';
|
import { getTimeSrv } from '../../services/TimeSrv';
|
||||||
import { DashboardModel, PanelModel } from '../../state';
|
import { DashboardModel, PanelModel } from '../../state';
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { VizPanel } from '@grafana/scenes';
|
|
||||||
import { Drawer } from '@grafana/ui';
|
|
||||||
|
|
||||||
import { DashboardScene } from './DashboardScene';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
dashboard: DashboardScene;
|
|
||||||
panel: VizPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ScenePanelInspector = React.memo<Props>(({ panel, dashboard }) => {
|
|
||||||
return (
|
|
||||||
<Drawer
|
|
||||||
title={`Inspect: ${panel.state.title}`}
|
|
||||||
scrollableContent
|
|
||||||
onClose={dashboard.onCloseInspectDrawer}
|
|
||||||
size="md"
|
|
||||||
>
|
|
||||||
Magic content
|
|
||||||
</Drawer>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
ScenePanelInspector.displayName = 'ScenePanelInspector';
|
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
|
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
PanelBuilders,
|
PanelBuilders,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
|
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getGridWithMultipleTimeRanges } from './gridMultiTimeRange';
|
import { getGridWithMultipleTimeRanges } from './gridMultiTimeRange';
|
||||||
import { getMultipleGridLayoutTest } from './gridMultiple';
|
import { getMultipleGridLayoutTest } from './gridMultiple';
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
SceneFlexItem,
|
SceneFlexItem,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
export function getQueryVariableDemo(): DashboardScene {
|
export function getQueryVariableDemo(): DashboardScene {
|
||||||
return new DashboardScene({
|
return new DashboardScene({
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
PanelBuilders,
|
PanelBuilders,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
PanelBuilders,
|
PanelBuilders,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
PanelBuilders,
|
PanelBuilders,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { DashboardScene } from '../dashboard/DashboardScene';
|
import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene';
|
||||||
|
|
||||||
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
import { getQueryRunnerWithRandomWalkQuery } from './queries';
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@ export function getDynamicDashboardRoutes(cfg = config): RouteDescriptor[] {
|
|||||||
{
|
{
|
||||||
path: '/scenes/dashboard/:uid',
|
path: '/scenes/dashboard/:uid',
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "scenes"*/ 'app/features/scenes/dashboard/DashboardScenePage')
|
() => import(/* webpackChunkName: "scenes"*/ 'app/features/dashboard-scene/pages/DashboardScenePage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user