AutoGridItemRenderer: Fix repeated panel lazy loading and drag and drop (#109334)
* wip: wrap individual grid items with lazy loader * fix repeated panel lazy loading and drag and drop in auto grid item
This commit is contained in:
+56
-24
@@ -1,11 +1,13 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data/';
|
||||
import { SceneComponentProps } from '@grafana/scenes';
|
||||
import { LazyLoader, SceneComponentProps, VizPanel } from '@grafana/scenes';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { useIsConditionallyHidden } from '../../conditional-rendering/useIsConditionallyHidden';
|
||||
import { useDashboardState } from '../../utils/utils';
|
||||
import { getIsLazy } from '../layouts-shared/utils';
|
||||
|
||||
import { AutoGridItem } from './AutoGridItem';
|
||||
import { DRAGGED_ITEM_HEIGHT, DRAGGED_ITEM_LEFT, DRAGGED_ITEM_TOP, DRAGGED_ITEM_WIDTH } from './const';
|
||||
@@ -13,11 +15,13 @@ import { DRAGGED_ITEM_HEIGHT, DRAGGED_ITEM_LEFT, DRAGGED_ITEM_TOP, DRAGGED_ITEM_
|
||||
export function AutoGridItemRenderer({ model }: SceneComponentProps<AutoGridItem>) {
|
||||
const { body, repeatedPanels, key } = model.useState();
|
||||
const { draggingKey } = model.getParentGrid().useState();
|
||||
const { isEditing } = useDashboardState(model);
|
||||
const { isEditing, preload } = useDashboardState(model);
|
||||
const [isConditionallyHidden, conditionalRenderingClass, conditionalRenderingOverlay] =
|
||||
useIsConditionallyHidden(model);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const isLazy = useMemo(() => getIsLazy(preload), [preload]);
|
||||
|
||||
if (isConditionallyHidden && !isEditing) {
|
||||
return null;
|
||||
}
|
||||
@@ -25,37 +29,65 @@ export function AutoGridItemRenderer({ model }: SceneComponentProps<AutoGridItem
|
||||
const isDragging = !!draggingKey;
|
||||
const isDragged = draggingKey === key;
|
||||
|
||||
const Wrapper = useMemo(
|
||||
() =>
|
||||
memo(
|
||||
({
|
||||
item,
|
||||
addDndContainer,
|
||||
isDragged,
|
||||
isDragging,
|
||||
}: {
|
||||
item: VizPanel;
|
||||
addDndContainer: boolean;
|
||||
isDragged: boolean;
|
||||
isDragging: boolean;
|
||||
}) => (
|
||||
<div
|
||||
{...(addDndContainer
|
||||
? { ref: model.containerRef, ['data-auto-grid-item-drop-target']: isDragging ? key : undefined }
|
||||
: {})}
|
||||
>
|
||||
{isDragged && <div className={styles.draggedPlaceholder} />}
|
||||
{isLazy ? (
|
||||
<LazyLoader
|
||||
key={item.state.key!}
|
||||
className={cx(conditionalRenderingClass, styles.wrapper, isDragged && styles.draggedWrapper)}
|
||||
>
|
||||
<item.Component model={item} />
|
||||
{conditionalRenderingOverlay}
|
||||
</LazyLoader>
|
||||
) : (
|
||||
<div className={cx(conditionalRenderingClass, styles.wrapper, isDragged && styles.draggedWrapper)}>
|
||||
<item.Component model={item} />
|
||||
{conditionalRenderingOverlay}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
),
|
||||
[conditionalRenderingClass, conditionalRenderingOverlay, isLazy, key, model.containerRef, styles]
|
||||
);
|
||||
|
||||
return repeatedPanels ? (
|
||||
<>
|
||||
{repeatedPanels.map((item) => (
|
||||
<div className={cx(conditionalRenderingClass, styles.wrapper)} key={item.state.key}>
|
||||
<item.Component model={item} />
|
||||
{conditionalRenderingOverlay}
|
||||
</div>
|
||||
{repeatedPanels.map((item, index) => (
|
||||
<Wrapper
|
||||
item={item}
|
||||
addDndContainer={index === 0}
|
||||
key={item.state.key!}
|
||||
isDragged={isDragged}
|
||||
isDragging={isDragging}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<div ref={model.containerRef} data-auto-grid-item-drop-target={isDragging ? key : undefined}>
|
||||
{isDragged && <div className={styles.draggedPlaceholder} />}
|
||||
|
||||
<div className={cx(!isDragged && conditionalRenderingClass, styles.wrapper, isDragged && styles.draggedWrapper)}>
|
||||
<body.Component model={body} />
|
||||
{conditionalRenderingOverlay}
|
||||
</div>
|
||||
</div>
|
||||
<Wrapper item={body} addDndContainer key={body.state.key!} isDragged={isDragged} isDragging={isDragging} />
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
container: css({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}),
|
||||
wrapper: css({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
}),
|
||||
wrapper: css({ width: '100%', height: '100%', position: 'relative' }),
|
||||
draggedWrapper: css({
|
||||
position: 'absolute',
|
||||
zIndex: 1000,
|
||||
|
||||
+7
-35
@@ -1,15 +1,13 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { LazyLoader, SceneComponentProps, sceneGraph } from '@grafana/scenes';
|
||||
import { SceneComponentProps, sceneGraph } from '@grafana/scenes';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { useHasClonedParents } from '../../utils/clone';
|
||||
import { useDashboardState } from '../../utils/utils';
|
||||
import { CanvasGridAddActions } from '../layouts-shared/CanvasGridAddActions';
|
||||
import { dashboardCanvasAddButtonHoverStyles } from '../layouts-shared/styles';
|
||||
import { getIsLazy } from '../layouts-shared/utils';
|
||||
|
||||
import { AutoGridLayout, AutoGridLayoutState } from './AutoGridLayout';
|
||||
import { AutoGridLayoutManager } from './AutoGridLayoutManager';
|
||||
@@ -18,12 +16,10 @@ export function AutoGridLayoutRenderer({ model }: SceneComponentProps<AutoGridLa
|
||||
const { children, isHidden } = model.useState();
|
||||
const hasClonedParents = useHasClonedParents(model);
|
||||
const styles = useStyles2(getStyles, model.state);
|
||||
const { layoutOrchestrator, isEditing, preload } = useDashboardState(model);
|
||||
const { layoutOrchestrator, isEditing } = useDashboardState(model);
|
||||
const layoutManager = sceneGraph.getAncestor(model, AutoGridLayoutManager);
|
||||
const { fillScreen } = layoutManager.useState();
|
||||
|
||||
const isLazy = useMemo(() => getIsLazy(preload), [preload]);
|
||||
|
||||
if (isHidden || !layoutOrchestrator) {
|
||||
return null;
|
||||
}
|
||||
@@ -35,15 +31,9 @@ export function AutoGridLayoutRenderer({ model }: SceneComponentProps<AutoGridLa
|
||||
className={cx(styles.container, fillScreen && styles.containerFillScreen, isEditing && styles.containerEditing)}
|
||||
ref={model.containerRef}
|
||||
>
|
||||
{children.map((item) =>
|
||||
isLazy ? (
|
||||
<LazyLoader key={item.state.key!} className={styles.container}>
|
||||
<item.Component key={item.state.key} model={item} />
|
||||
</LazyLoader>
|
||||
) : (
|
||||
<item.Component key={item.state.key} model={item} />
|
||||
)
|
||||
)}
|
||||
{children.map((item) => (
|
||||
<item.Component key={item.state.key} model={item} />
|
||||
))}
|
||||
{showCanvasActions && <CanvasGridAddActions layoutManager={layoutManager} />}
|
||||
</div>
|
||||
);
|
||||
@@ -75,24 +65,6 @@ const getStyles = (theme: GrafanaTheme2, state: AutoGridLayoutState) => ({
|
||||
// Show add action when hovering over the grid
|
||||
...dashboardCanvasAddButtonHoverStyles,
|
||||
}),
|
||||
containerFillScreen: css({
|
||||
flexGrow: 1,
|
||||
}),
|
||||
containerEditing: css({
|
||||
paddingBottom: theme.spacing(5),
|
||||
position: 'relative',
|
||||
}),
|
||||
wrapper: css({
|
||||
display: 'grid',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}),
|
||||
dragging: css({
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: theme.zIndex.portal + 1,
|
||||
pointerEvents: 'none',
|
||||
}),
|
||||
containerFillScreen: css({ flexGrow: 1 }),
|
||||
containerEditing: css({ paddingBottom: theme.spacing(5), position: 'relative' }),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user