-
- Cancel
-
+ {onCancel ? (
+
+ ) : (
+
+ Cancel
+
+ )}
diff --git a/src/modules/garden/manifest.tsx b/src/modules/garden/manifest.tsx
index 5ad8c3f..b6fe552 100644
--- a/src/modules/garden/manifest.tsx
+++ b/src/modules/garden/manifest.tsx
@@ -203,18 +203,21 @@ const gardenManifest: ModuleManifest = {
label: "Add plant",
icon: "leaf",
url: "/garden/plants/new",
+ createKey: "garden.plant",
},
{
id: "garden.add-container",
label: "Add container",
icon: "box",
url: "/garden/containers/new",
+ createKey: "garden.container",
},
{
id: "garden.log-care",
label: "Log plant care",
icon: "droplets",
url: "/garden?logCare=1",
+ createKey: "garden.log-care",
},
],
};
diff --git a/src/modules/garden/server/queries.ts b/src/modules/garden/server/queries.ts
index eb28493..567293b 100644
--- a/src/modules/garden/server/queries.ts
+++ b/src/modules/garden/server/queries.ts
@@ -1,3 +1,5 @@
+"use server";
+
import { and, desc, eq, lte, sql } from "drizzle-orm";
import { db } from "@/lib/db";
import { getCurrentSession } from "@/lib/session";
diff --git a/src/modules/lists/manifest.tsx b/src/modules/lists/manifest.tsx
index 2dfb433..8dc2a90 100644
--- a/src/modules/lists/manifest.tsx
+++ b/src/modules/lists/manifest.tsx
@@ -93,18 +93,21 @@ const manifest: ModuleManifest = {
label: "Add to shopping",
icon: "shopping-cart",
url: "/lists",
+ createKey: "lists.add-shopping",
},
{
id: "lists.add-task",
label: "Add to tasks",
icon: "list-checks",
url: "/lists",
+ createKey: "lists.add-task",
},
{
id: "lists.new-list",
label: "New list",
icon: "list-plus",
url: "/lists",
+ createKey: "lists.new-list",
},
],
};
diff --git a/src/modules/notes/manifest.tsx b/src/modules/notes/manifest.tsx
index 3fa2de1..fc7c116 100644
--- a/src/modules/notes/manifest.tsx
+++ b/src/modules/notes/manifest.tsx
@@ -106,6 +106,7 @@ const manifest: ModuleManifest = {
label: "New note",
icon: "file-plus",
url: "/notes/new",
+ createKey: "notes.note",
},
],
};
diff --git a/tests/e2e/quick-add.spec.ts b/tests/e2e/quick-add.spec.ts
new file mode 100644
index 0000000..0876c0c
--- /dev/null
+++ b/tests/e2e/quick-add.spec.ts
@@ -0,0 +1,43 @@
+import { expect, test, type Page } from "@playwright/test";
+
+async function ensureSignedIn(page: Page) {
+ await page.goto("/");
+ const devLogin = page.getByRole("button", { name: "Dev login" });
+ if (await devLogin.isVisible().catch(() => false)) {
+ await devLogin.click();
+ await page.waitForURL((url) => url.pathname === "/");
+ }
+ await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
+}
+
+test.describe("quick-add create UI", () => {
+ test("FAB opens new note dialog on dashboard", async ({ page }) => {
+ await ensureSignedIn(page);
+
+ await page.getByRole("button", { name: "Quick add" }).click();
+ await expect(page.getByRole("dialog", { name: "Quick add" })).toBeVisible();
+
+ await page.getByRole("button", { name: "New note" }).click();
+
+ await expect(page).toHaveURL("/");
+ await expect(page.getByRole("dialog", { name: "New note" })).toBeVisible();
+ await expect(page.getByLabel("Title")).toBeVisible();
+ await expect(page.getByLabel("Body")).toBeVisible();
+ await expect(page.getByRole("button", { name: "Save note" })).toBeVisible();
+ });
+
+ test("command palette opens new event dialog on dashboard", async ({ page }) => {
+ await ensureSignedIn(page);
+
+ const isMac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform));
+ await page.keyboard.press(isMac ? "Meta+k" : "Control+k");
+
+ await expect(page.getByRole("dialog", { name: "Command palette" })).toBeVisible();
+ await page.getByRole("option", { name: /New event/i }).click();
+
+ await expect(page).toHaveURL("/");
+ await expect(page.getByRole("dialog", { name: "New event" })).toBeVisible();
+ await expect(page.getByLabel("Title")).toBeVisible();
+ await expect(page.getByRole("button", { name: "Save event" })).toBeVisible();
+ });
+});