diff --git a/apps/client/src/features/base/components/views/kanban/base-kanban.tsx b/apps/client/src/features/base/components/views/kanban/base-kanban.tsx index 8498b2665..a9d55fb79 100644 --- a/apps/client/src/features/base/components/views/kanban/base-kanban.tsx +++ b/apps/client/src/features/base/components/views/kanban/base-kanban.tsx @@ -3,9 +3,11 @@ import { IBase, IBaseRow, IBaseView, + NO_VALUE_CHOICE_ID, } from "@/features/base/types/base.types"; import { useKanbanGroups } from "@/features/base/hooks/use-kanban-groups"; import { useUpdateViewMutation } from "@/features/base/queries/base-view-query"; +import { useCreateRowMutation } from "@/features/base/queries/base-row-query"; import { KanbanColumn } from "./kanban-column"; import { KanbanEmptyState } from "./kanban-empty-state"; import classes from "@/features/base/styles/kanban.module.css"; @@ -37,6 +39,7 @@ export function BaseKanban({ ); const isGroupable = property?.type === "select" || property?.type === "status"; const updateViewMutation = useUpdateViewMutation(); + const createRowMutation = useCreateRowMutation(); // Rules of Hooks: call useKanbanGroups unconditionally with `undefined` // when not groupable; switch the render path on isGroupable below. @@ -56,6 +59,21 @@ export function BaseKanban({ }); }; + const handleAddCard = (columnKey: string) => { + if (!groupByPropertyId) return; + const cells = + columnKey === NO_VALUE_CHOICE_ID + ? {} + : { [groupByPropertyId]: columnKey }; + const column = columns.find((c) => c.key === columnKey); + const afterRowId = column?.rows[column.rows.length - 1]?.id; + createRowMutation.mutate({ + pageId: base.id, + cells, + afterRowId, + }); + }; + if (!isGroupable) { return ; } @@ -68,6 +86,7 @@ export function BaseKanban({ column={column} primaryProperty={primaryProperty} onCardClick={onCardClick} + onAddCard={handleAddCard} /> ))} diff --git a/apps/client/src/features/base/components/views/kanban/kanban-add-card-button.tsx b/apps/client/src/features/base/components/views/kanban/kanban-add-card-button.tsx new file mode 100644 index 000000000..fc561c5e9 --- /dev/null +++ b/apps/client/src/features/base/components/views/kanban/kanban-add-card-button.tsx @@ -0,0 +1,29 @@ +import { Button } from "@mantine/core"; +import { IconPlus } from "@tabler/icons-react"; +import { useTranslation } from "react-i18next"; +import classes from "@/features/base/styles/kanban.module.css"; + +type KanbanAddCardButtonProps = { + onClick: () => void; + disabled?: boolean; +}; + +export function KanbanAddCardButton({ + onClick, + disabled, +}: KanbanAddCardButtonProps) { + const { t } = useTranslation(); + return ( + + ); +} diff --git a/apps/client/src/features/base/components/views/kanban/kanban-column.tsx b/apps/client/src/features/base/components/views/kanban/kanban-column.tsx index 464aba76c..fe0b3488f 100644 --- a/apps/client/src/features/base/components/views/kanban/kanban-column.tsx +++ b/apps/client/src/features/base/components/views/kanban/kanban-column.tsx @@ -2,18 +2,21 @@ import { KanbanColumnData } from "@/features/base/hooks/use-kanban-groups"; import { IBaseProperty } from "@/features/base/types/base.types"; import { KanbanCard } from "./kanban-card"; import { KanbanColumnHeader } from "./kanban-column-header"; +import { KanbanAddCardButton } from "./kanban-add-card-button"; import classes from "@/features/base/styles/kanban.module.css"; type KanbanColumnProps = { column: KanbanColumnData; primaryProperty: IBaseProperty | undefined; onCardClick: (rowId: string) => void; + onAddCard: (columnKey: string) => void; }; export function KanbanColumn({ column, primaryProperty, onCardClick, + onAddCard, }: KanbanColumnProps) { return (
@@ -31,6 +34,7 @@ export function KanbanColumn({ onClick={onCardClick} /> ))} + onAddCard(column.key)} />
);