mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Add default row/column for new boards and prevent removing last column.
Some checks are pending
Node.js CI / build (push) Waiting to run
Some checks are pending
Node.js CI / build (push) Waiting to run
- New boards now start with one row containing one column - Hide remove column button when only one column remains in a row Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
385bdd6734
commit
6367d94552
2 changed files with 26 additions and 15 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { Loading, useToast } from '@umami/react-zen';
|
import { Loading, useToast } from '@umami/react-zen';
|
||||||
import { createContext, type ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
import { createContext, type ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
import { useApi, useMessages, useModified, useNavigation } from '@/components/hooks';
|
import { useApi, useMessages, useModified, useNavigation } from '@/components/hooks';
|
||||||
import { useBoardQuery } from '@/components/hooks/queries/useBoardQuery';
|
import { useBoardQuery } from '@/components/hooks/queries/useBoardQuery';
|
||||||
import type { Board, BoardParameters } from '@/lib/types';
|
import type { Board, BoardParameters } from '@/lib/types';
|
||||||
|
|
@ -17,11 +18,13 @@ export interface BoardContextValue {
|
||||||
|
|
||||||
export const BoardContext = createContext<BoardContextValue>(null);
|
export const BoardContext = createContext<BoardContextValue>(null);
|
||||||
|
|
||||||
const defaultBoard: Partial<Board> = {
|
const createDefaultBoard = (): Partial<Board> => ({
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
parameters: { rows: [] },
|
parameters: {
|
||||||
};
|
rows: [{ id: uuid(), columns: [{ id: uuid(), component: null }] }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export function BoardProvider({ boardId, children }: { boardId?: string; children: ReactNode }) {
|
export function BoardProvider({ boardId, children }: { boardId?: string; children: ReactNode }) {
|
||||||
const { data, isFetching, isLoading } = useBoardQuery(boardId);
|
const { data, isFetching, isLoading } = useBoardQuery(boardId);
|
||||||
|
|
@ -31,7 +34,7 @@ export function BoardProvider({ boardId, children }: { boardId?: string; childre
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const { router, renderUrl } = useNavigation();
|
const { router, renderUrl } = useNavigation();
|
||||||
|
|
||||||
const [board, setBoard] = useState<Partial<Board>>(data ?? defaultBoard);
|
const [board, setBoard] = useState<Partial<Board>>(data ?? createDefaultBoard());
|
||||||
const layoutGetterRef = useRef<LayoutGetter | null>(null);
|
const layoutGetterRef = useRef<LayoutGetter | null>(null);
|
||||||
|
|
||||||
const registerLayoutGetter = useCallback((getter: LayoutGetter) => {
|
const registerLayoutGetter = useCallback((getter: LayoutGetter) => {
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,11 @@ function BoardRow({
|
||||||
{columns?.map((column, index) => (
|
{columns?.map((column, index) => (
|
||||||
<Fragment key={column.id}>
|
<Fragment key={column.id}>
|
||||||
<Panel id={column.id} minSize={MIN_COLUMN_WIDTH} defaultSize={column.size}>
|
<Panel id={column.id} minSize={MIN_COLUMN_WIDTH} defaultSize={column.size}>
|
||||||
<BoardColumn {...column} onRemove={handleRemoveColumn} />
|
<BoardColumn
|
||||||
|
{...column}
|
||||||
|
onRemove={handleRemoveColumn}
|
||||||
|
canRemove={columns?.length > 1}
|
||||||
|
/>
|
||||||
</Panel>
|
</Panel>
|
||||||
{index < columns?.length - 1 && <Separator />}
|
{index < columns?.length - 1 && <Separator />}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
@ -276,10 +280,12 @@ function BoardColumn({
|
||||||
id,
|
id,
|
||||||
component,
|
component,
|
||||||
onRemove,
|
onRemove,
|
||||||
|
canRemove = true,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
component?: ReactElement;
|
component?: ReactElement;
|
||||||
onRemove?: (id: string) => void;
|
onRemove?: (id: string) => void;
|
||||||
|
canRemove?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const handleAddComponent = () => {};
|
const handleAddComponent = () => {};
|
||||||
|
|
||||||
|
|
@ -294,16 +300,18 @@ function BoardColumn({
|
||||||
backgroundColor="3"
|
backgroundColor="3"
|
||||||
position="relative"
|
position="relative"
|
||||||
>
|
>
|
||||||
<Box position="absolute" top="10px" right="20px" zIndex={100}>
|
{canRemove && (
|
||||||
<TooltipTrigger delay={0}>
|
<Box position="absolute" top="10px" right="20px" zIndex={100}>
|
||||||
<Button variant="quiet" onPress={() => onRemove?.(id)}>
|
<TooltipTrigger delay={0}>
|
||||||
<Icon size="sm">
|
<Button variant="quiet" onPress={() => onRemove?.(id)}>
|
||||||
<X />
|
<Icon size="sm">
|
||||||
</Icon>
|
<X />
|
||||||
</Button>
|
</Icon>
|
||||||
<Tooltip>Remove column</Tooltip>
|
</Button>
|
||||||
</TooltipTrigger>
|
<Tooltip>Remove column</Tooltip>
|
||||||
</Box>
|
</TooltipTrigger>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
<Button variant="outline" onPress={handleAddComponent}>
|
<Button variant="outline" onPress={handleAddComponent}>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Plus />
|
<Plus />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue