mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 00:55:47 -06:00
* 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>
86 lines
2.6 KiB
TypeScript
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>
|
|
);
|
|
}
|