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 (
+ }
+ onClick={onClick}
+ disabled={disabled}
+ >
+ {t("New")}
+
+ );
+}
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)} />
);