mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 00:55:47 -06:00
* Playing around * This is getting interesting * Updates * Updated * Observable experiments * This is tricky * VizPanel panel renderer * New model progress * Maybe this could be something * Updated * Rename * updates * Updated * Query runners? not sure * Updated * updates * flex box layout starting to work * Testing * Tested an action * Parent context sort of working * Progress * Progress * Updated * Starting to work * Things are working * Scene list, nested scene demo * Progress on repeats * Moving things * Pretty big progress * More things working * Great progress * Progress * Name changing * Minor tweaks * Simplified sizing * Move toggleDirection to SceneFlexLayout * add feature flag (#50990) * removed new useObservable hook * Rename folder and feature toggle to scenes * Caching scenes so you can go back to another scene without having to re-query data * Fix issue with subs on re-mount * Fixing test * Added SceneCanvasText to play around with layout elements with size based on content * Scene: Edit mode and component edit wrapper that handles selection (#51078) * First step for scene variables * Started playing around with a scene edit mode * Better way to set component * Progress on edit mode * Update * Progress on edit mode * Progress on editor * Progress on editor * Updates * More working * Progress * Minor update * removed unnessary file * Moving things around * Updated * Making time range separate from time picker * minor rename of methods * The most basic variable start * Minor renames * Fixed interpolate issue if not found at closest level * An embryo of event model and url sync handling * Update url sync types * Removed unnessary any type arg Co-authored-by: Ryan McKinley <ryantxu@gmail.com> Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import React, { CSSProperties } from 'react';
|
|
|
|
import { Field, RadioButtonGroup } from '@grafana/ui';
|
|
|
|
import { SceneObjectBase } from '../core/SceneObjectBase';
|
|
import { SceneObject, SceneObjectSize, SceneObjectState, SceneLayoutState, SceneComponentProps } from '../core/types';
|
|
|
|
export type FlexLayoutDirection = 'column' | 'row';
|
|
|
|
interface SceneFlexLayoutState extends SceneObjectState, SceneLayoutState {
|
|
direction?: FlexLayoutDirection;
|
|
}
|
|
|
|
export class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> {
|
|
static Component = FlexLayoutRenderer;
|
|
static Editor = FlexLayoutEditor;
|
|
|
|
toggleDirection() {
|
|
this.setState({
|
|
direction: this.state.direction === 'row' ? 'column' : 'row',
|
|
});
|
|
}
|
|
}
|
|
|
|
function FlexLayoutRenderer({ model, isEditing }: SceneComponentProps<SceneFlexLayout>) {
|
|
const { direction = 'row', children } = model.useState();
|
|
|
|
return (
|
|
<div style={{ flexGrow: 1, flexDirection: direction, display: 'flex', gap: '8px' }}>
|
|
{children.map((item) => (
|
|
<FlexLayoutChildComponent key={item.state.key} item={item} direction={direction} isEditing={isEditing} />
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function FlexLayoutChildComponent({
|
|
item,
|
|
direction,
|
|
isEditing,
|
|
}: {
|
|
item: SceneObject<SceneObjectState>;
|
|
direction: FlexLayoutDirection;
|
|
isEditing?: boolean;
|
|
}) {
|
|
const { size } = item.useState();
|
|
|
|
return (
|
|
<div style={getItemStyles(direction, size)}>
|
|
<item.Component model={item} isEditing={isEditing} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function getItemStyles(direction: FlexLayoutDirection, sizing: SceneObjectSize = {}) {
|
|
const { xSizing = 'fill', ySizing = 'fill' } = sizing;
|
|
|
|
const style: CSSProperties = {
|
|
display: 'flex',
|
|
flexDirection: direction,
|
|
minWidth: sizing.minWidth,
|
|
minHeight: sizing.minHeight,
|
|
};
|
|
|
|
if (direction === 'column') {
|
|
if (sizing.height) {
|
|
style.height = sizing.height;
|
|
} else {
|
|
style.flexGrow = ySizing === 'fill' ? 1 : 0;
|
|
}
|
|
|
|
if (sizing.width) {
|
|
style.width = sizing.width;
|
|
} else {
|
|
style.alignSelf = xSizing === 'fill' ? 'stretch' : 'flex-start';
|
|
}
|
|
} else {
|
|
if (sizing.height) {
|
|
style.height = sizing.height;
|
|
} else {
|
|
style.alignSelf = ySizing === 'fill' ? 'stretch' : 'flex-start';
|
|
}
|
|
|
|
if (sizing.width) {
|
|
style.width = sizing.width;
|
|
} else {
|
|
style.flexGrow = xSizing === 'fill' ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
return style;
|
|
}
|
|
|
|
function FlexLayoutEditor({ model }: SceneComponentProps<SceneFlexLayout>) {
|
|
const { direction = 'row' } = model.useState();
|
|
const options = [
|
|
{ icon: 'arrow-right', value: 'row' },
|
|
{ icon: 'arrow-down', value: 'column' },
|
|
];
|
|
|
|
return (
|
|
<Field label="Direction">
|
|
<RadioButtonGroup
|
|
options={options}
|
|
value={direction}
|
|
onChange={(value) => model.setState({ direction: value as FlexLayoutDirection })}
|
|
/>
|
|
</Field>
|
|
);
|
|
}
|