grafana/public/app/features/scenes/core/SceneComponentWrapper.tsx

59 lines
1.4 KiB
TypeScript
Raw Normal View History

import React, { useEffect } from 'react';
import { SceneComponentProps, SceneEditor, SceneObject } from './types';
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 02:49:39 -06:00
export function SceneComponentWrapper<T extends SceneObject>({
model,
isEditing,
...otherProps
}: SceneComponentProps<T>) {
const Component = (model as any).constructor['Component'] ?? EmptyRenderer;
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 02:49:39 -06:00
const inner = <Component {...otherProps} model={model} isEditing={isEditing} />;
// Handle component activation state state
useEffect(() => {
if (!model.isActive) {
model.activate();
}
return () => {
if (model.isActive) {
model.deactivate();
}
};
}, [model]);
/** Useful for tests and evaluating efficiency in reducing renderings */
// @ts-ignore
model._renderCount += 1;
if (!isEditing) {
return inner;
}
const editor = getSceneEditor(model);
const EditWrapper = getSceneEditor(model).getEditComponentWrapper();
return (
<EditWrapper model={model} editor={editor}>
{inner}
</EditWrapper>
);
}
function EmptyRenderer<T>(_: SceneComponentProps<T>): React.ReactElement | null {
return null;
}
function getSceneEditor(sceneObject: SceneObject): SceneEditor {
const { $editor } = sceneObject.state;
if ($editor) {
return $editor;
}
if (sceneObject.parent) {
return getSceneEditor(sceneObject.parent);
}
throw new Error('No editor found in scene tree');
}