grafana/public/app/features/scenes/components/VizPanel.tsx
Dominik Prokop 80e80221b9
Scenes: Grid layout (#56737)
* WIP: First approach to scene grid layout

* Flex layout

* Grid layout rows

* Allow passing custom props to scene object renderers

* Allow nesting grid layouts

* Re-layout nested grid's enclosing grids

* Update public/app/features/scenes/components/layout/SceneGridLayout.tsx

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>

* Review comments

* Got rid of flex & grid child layout objects

* WIP: Recreating rows behaviour (almost working)

* Major progress on rows

* remove nested grid example (not supported)

* Remove removal damn

* Trying to use children directly

* Ts fixes

* chore: Fix TS

* Fix issue when row bboxes when not updated on layout change

* Now the tricky part

* working

* Removing some code

* needs more work

* Getting some thing working

* Getting some thing working

* fix toggle row

* Starting to work

* Fix

* Yay it's working

* Updates

* Updates

* Added some sorting of children

* Updated comment

* Simplify sorting

* removed commented code

* Updated

* Pushed a fix so we can move a panel out from a row and into the parent grid

* simplify move logic

* Minor simplification

* Removed some unnesary code

* fixed comment

* Removed unnessary condition in findGridSceneParent

* remove unnessary if

* Simplify toGridCell

* removed duplicate if

* removed unused code

* Adds grid demo with different data scenarios

* Make it green

* Demo grid with multiple time ranges

* Move child atomically

* Add tests

* Cleanup

* Fix unused import

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Ivan Ortega <ivanortegaalba@gmail.com>
2022-11-15 00:49:39 -08:00

86 lines
2.6 KiB
TypeScript

import React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { AbsoluteTimeRange, FieldConfigSource, toUtc } from '@grafana/data';
import { PanelRenderer } from '@grafana/runtime';
import { Field, PanelChrome, Input } from '@grafana/ui';
import { SceneObjectBase } from '../core/SceneObjectBase';
import { SceneComponentProps, SceneLayoutChildState } from '../core/types';
import { SceneDragHandle } from './SceneDragHandle';
export interface VizPanelState extends SceneLayoutChildState {
title?: string;
pluginId: string;
options?: object;
fieldConfig?: FieldConfigSource;
}
export class VizPanel extends SceneObjectBase<VizPanelState> {
public static Component = ScenePanelRenderer;
public static Editor = VizPanelEditor;
public onSetTimeRange = (timeRange: AbsoluteTimeRange) => {
const sceneTimeRange = this.getTimeRange();
sceneTimeRange.setState({
raw: {
from: toUtc(timeRange.from),
to: toUtc(timeRange.to),
},
from: toUtc(timeRange.from),
to: toUtc(timeRange.to),
});
};
}
function ScenePanelRenderer({ model }: SceneComponentProps<VizPanel>) {
const { title, pluginId, options, fieldConfig, ...state } = model.useState();
const { data } = model.getData().useState();
const layout = model.getLayout();
const isDraggable = layout.state.isDraggable ? state.isDraggable : false;
const dragHandle = <SceneDragHandle layoutKey={layout.state.key!} />;
return (
<AutoSizer>
{({ width, height }) => {
if (width < 3 || height < 3) {
return null;
}
return (
<PanelChrome title={title} width={width} height={height} leftItems={isDraggable ? [dragHandle] : undefined}>
{(innerWidth, innerHeight) => (
<>
<PanelRenderer
title="Raw data"
pluginId={pluginId}
width={innerWidth}
height={innerHeight}
data={data}
options={options}
fieldConfig={fieldConfig}
onOptionsChange={() => {}}
onChangeTimeRange={model.onSetTimeRange}
/>
</>
)}
</PanelChrome>
);
}}
</AutoSizer>
);
}
ScenePanelRenderer.displayName = 'ScenePanelRenderer';
function VizPanelEditor({ model }: SceneComponentProps<VizPanel>) {
const { title } = model.useState();
return (
<Field label="Title">
<Input defaultValue={title} onBlur={(evt) => model.setState({ title: evt.currentTarget.value })} />
</Field>
);
}