mirror of
https://github.com/umami-software/umami.git
synced 2026-02-16 02:25:35 +01:00
Prevent unnecessary chart and board component re-renders
This commit is contained in:
parent
1f0de47c01
commit
400a35d7af
4 changed files with 104 additions and 22 deletions
17
src/app/(main)/boards/[boardId]/BoardColumn.module.css
Normal file
17
src/app/(main)/boards/[boardId]/BoardColumn.module.css
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.column {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.columnAction {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: opacity 120ms ease;
|
||||
}
|
||||
|
||||
.column:hover .columnAction,
|
||||
.column:focus-within .columnAction {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
|
@ -8,10 +8,11 @@ import {
|
|||
Tooltip,
|
||||
TooltipTrigger,
|
||||
} from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useBoard, useMessages } from '@/components/hooks';
|
||||
import { Pencil, Plus, X } from '@/components/icons';
|
||||
import type { BoardComponentConfig } from '@/lib/types';
|
||||
import styles from './BoardColumn.module.css';
|
||||
import { BoardComponentRenderer } from './BoardComponentRenderer';
|
||||
import { BoardComponentSelect } from './BoardComponentSelect';
|
||||
|
||||
|
|
@ -34,6 +35,13 @@ export function BoardColumn({
|
|||
const { board } = useBoard();
|
||||
const { t, labels } = useMessages();
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
const renderedComponent = useMemo(() => {
|
||||
if (!component || !websiteId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <BoardComponentRenderer config={component} websiteId={websiteId} />;
|
||||
}, [component, websiteId]);
|
||||
|
||||
const handleSelect = (config: BoardComponentConfig) => {
|
||||
onSetComponent?.(id, config);
|
||||
|
|
@ -50,11 +58,18 @@ export function BoardColumn({
|
|||
justifyContent="center"
|
||||
backgroundColor="surface-sunken"
|
||||
position="relative"
|
||||
className={styles.column}
|
||||
>
|
||||
{editing && canRemove && (
|
||||
<Box position="absolute" top="10px" right="20px" zIndex={100}>
|
||||
<Box
|
||||
className={styles.columnAction}
|
||||
position="absolute"
|
||||
top="10px"
|
||||
right="20px"
|
||||
zIndex={100}
|
||||
>
|
||||
<TooltipTrigger delay={0}>
|
||||
<Button variant="quiet" onPress={() => onRemove?.(id)}>
|
||||
<Button variant="outline" onPress={() => onRemove?.(id)}>
|
||||
<Icon size="sm">
|
||||
<X />
|
||||
</Icon>
|
||||
|
|
@ -63,15 +78,21 @@ export function BoardColumn({
|
|||
</TooltipTrigger>
|
||||
</Box>
|
||||
)}
|
||||
{component && websiteId ? (
|
||||
{renderedComponent ? (
|
||||
<>
|
||||
<Box width="100%" height="100%" overflow="auto">
|
||||
<BoardComponentRenderer config={component} websiteId={websiteId} />
|
||||
{renderedComponent}
|
||||
</Box>
|
||||
{editing && (
|
||||
<Box position="absolute" bottom="10px" right="20px" zIndex={100}>
|
||||
<Box
|
||||
className={styles.columnAction}
|
||||
position="absolute"
|
||||
bottom="10px"
|
||||
right="20px"
|
||||
zIndex={100}
|
||||
>
|
||||
<TooltipTrigger delay={0}>
|
||||
<Button variant="quiet" onPress={() => setShowSelect(true)}>
|
||||
<Button variant="outline" onPress={() => setShowSelect(true)}>
|
||||
<Icon size="sm">
|
||||
<Pencil />
|
||||
</Icon>
|
||||
|
|
@ -94,7 +115,7 @@ export function BoardColumn({
|
|||
<Dialog
|
||||
title={t(labels.selectComponent)}
|
||||
style={{
|
||||
width: '750px',
|
||||
width: '1200px',
|
||||
maxWidth: 'calc(100vw - 40px)',
|
||||
maxHeight: 'calc(100dvh - 40px)',
|
||||
padding: '32px',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { Column, Text } from '@umami/react-zen';
|
||||
import { memo } from 'react';
|
||||
import type { BoardComponentConfig } from '@/lib/types';
|
||||
import { getComponentDefinition } from '../boardComponentRegistry';
|
||||
|
||||
export function BoardComponentRenderer({
|
||||
function BoardComponentRendererComponent({
|
||||
config,
|
||||
websiteId,
|
||||
}: {
|
||||
|
|
@ -23,3 +24,11 @@ export function BoardComponentRenderer({
|
|||
|
||||
return <Component websiteId={websiteId} {...config.props} />;
|
||||
}
|
||||
|
||||
export const BoardComponentRenderer = memo(
|
||||
BoardComponentRendererComponent,
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.websiteId === nextProps.websiteId && prevProps.config === nextProps.config,
|
||||
);
|
||||
|
||||
BoardComponentRenderer.displayName = 'BoardComponentRenderer';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue