mirror of
https://github.com/umami-software/umami.git
synced 2026-02-19 03:55:37 +01:00
Add board component selector with live preview
Allows users to select and inject analytics components into board cells. Includes component registry, renderer, selector modal with category menu, config fields for MetricsTable, and live preview. Also scopes website select to team websites when editing a team board. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
28246b8c52
commit
87bde9da1f
10 changed files with 498 additions and 113 deletions
|
|
@ -1,21 +1,43 @@
|
|||
import { Box, Button, Column, Icon, Tooltip, TooltipTrigger } from '@umami/react-zen';
|
||||
import type { ReactElement } from 'react';
|
||||
import { Plus, X } from '@/components/icons';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Column,
|
||||
Dialog,
|
||||
Icon,
|
||||
Modal,
|
||||
Tooltip,
|
||||
TooltipTrigger,
|
||||
} from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useBoard } from '@/components/hooks';
|
||||
import { Pencil, Plus, X } from '@/components/icons';
|
||||
import type { BoardComponentConfig } from '@/lib/types';
|
||||
import { BoardComponentRenderer } from './BoardComponentRenderer';
|
||||
import { BoardComponentSelect } from './BoardComponentSelect';
|
||||
|
||||
export function BoardColumn({
|
||||
id,
|
||||
component,
|
||||
editing = false,
|
||||
onRemove,
|
||||
onSetComponent,
|
||||
canRemove = true,
|
||||
}: {
|
||||
id: string;
|
||||
component?: ReactElement;
|
||||
component?: BoardComponentConfig;
|
||||
editing?: boolean;
|
||||
onRemove?: (id: string) => void;
|
||||
onSetComponent?: (id: string, config: BoardComponentConfig | null) => void;
|
||||
canRemove?: boolean;
|
||||
}) {
|
||||
const handleAddComponent = () => {};
|
||||
const [showSelect, setShowSelect] = useState(false);
|
||||
const { board } = useBoard();
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
|
||||
const handleSelect = (config: BoardComponentConfig) => {
|
||||
onSetComponent?.(id, config);
|
||||
setShowSelect(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Column
|
||||
|
|
@ -40,13 +62,52 @@ export function BoardColumn({
|
|||
</TooltipTrigger>
|
||||
</Box>
|
||||
)}
|
||||
{editing && (
|
||||
<Button variant="outline" onPress={handleAddComponent}>
|
||||
<Icon>
|
||||
<Plus />
|
||||
</Icon>
|
||||
</Button>
|
||||
{component && websiteId ? (
|
||||
<>
|
||||
<Box width="100%" height="100%" overflow="auto">
|
||||
<BoardComponentRenderer config={component} websiteId={websiteId} />
|
||||
</Box>
|
||||
{editing && (
|
||||
<Box position="absolute" bottom="10px" right="20px" zIndex={100}>
|
||||
<TooltipTrigger delay={0}>
|
||||
<Button variant="quiet" onPress={() => setShowSelect(true)}>
|
||||
<Icon size="sm">
|
||||
<Pencil />
|
||||
</Icon>
|
||||
</Button>
|
||||
<Tooltip>Change component</Tooltip>
|
||||
</TooltipTrigger>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
editing && (
|
||||
<Button variant="outline" onPress={() => setShowSelect(true)}>
|
||||
<Icon>
|
||||
<Plus />
|
||||
</Icon>
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
<Modal isOpen={showSelect} onOpenChange={setShowSelect}>
|
||||
<Dialog
|
||||
title="Add component"
|
||||
style={{
|
||||
width: '750px',
|
||||
maxWidth: 'calc(100vw - 40px)',
|
||||
maxHeight: 'calc(100dvh - 40px)',
|
||||
padding: '32px',
|
||||
}}
|
||||
>
|
||||
{() => (
|
||||
<BoardComponentSelect
|
||||
websiteId={websiteId}
|
||||
onSelect={handleSelect}
|
||||
onClose={() => setShowSelect(false)}
|
||||
/>
|
||||
)}
|
||||
</Dialog>
|
||||
</Modal>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue