From 84e59a4a851b4519848cb9a90923dec2a78a02d1 Mon Sep 17 00:00:00 2001 From: Sosa <204860293+spyda600@users.noreply.github.com> Date: Tue, 28 Jul 2026 20:01:26 -0500 Subject: [PATCH] fix(desktop): allow creating first repository Co-authored-by: Sosa <204860293+spyda600@users.noreply.github.com> Signed-off-by: Sosa <204860293+spyda600@users.noreply.github.com> --- desktop/playwright.config.ts | 1 + .../src/features/projects/ui/ProjectCards.tsx | 5 ++- .../src/features/projects/ui/ProjectsView.tsx | 8 ++--- desktop/src/testing/e2eBridge.ts | 16 +++++++--- desktop/tests/e2e/projects-empty.spec.ts | 31 +++++++++++++++++++ desktop/tests/helpers/bridge.ts | 2 ++ 6 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 desktop/tests/e2e/projects-empty.spec.ts diff --git a/desktop/playwright.config.ts b/desktop/playwright.config.ts index 459fa75743..7a67438697 100644 --- a/desktop/playwright.config.ts +++ b/desktop/playwright.config.ts @@ -98,6 +98,7 @@ export default defineConfig({ "**/reaction-names.spec.ts", "**/inbox-reactions.spec.ts", "**/send-channel-binding.spec.ts", + "**/projects-empty.spec.ts", "**/project-commit-detail.spec.ts", "**/project-inbox.spec.ts", "**/project-pr-review.spec.ts", diff --git a/desktop/src/features/projects/ui/ProjectCards.tsx b/desktop/src/features/projects/ui/ProjectCards.tsx index 52308f7a05..3f7a3f3531 100644 --- a/desktop/src/features/projects/ui/ProjectCards.tsx +++ b/desktop/src/features/projects/ui/ProjectCards.tsx @@ -263,7 +263,7 @@ function StatusPill({ status }: { status: string }) { ); } -export function EmptyState() { +export function EmptyState({ onCreate }: { onCreate: () => void }) { return (
@@ -273,6 +273,9 @@ export function EmptyState() { Projects published to this relay will appear here.

+ ); } diff --git a/desktop/src/features/projects/ui/ProjectsView.tsx b/desktop/src/features/projects/ui/ProjectsView.tsx index 2f22bfe0c1..8c1a6fef5f 100644 --- a/desktop/src/features/projects/ui/ProjectsView.tsx +++ b/desktop/src/features/projects/ui/ProjectsView.tsx @@ -447,10 +447,6 @@ export function ProjectsView() { ); } - if (projects.length === 0) { - return ; - } - const repositoryItems = visibleProjects.length === 0 ? ( @@ -646,7 +642,9 @@ export function ProjectsView() {
- {filter === "all" ? ( + {projects.length === 0 ? ( + setCreateProjectOpen(true)} /> + ) : filter === "all" ? ( tag[0] === "a" && (tag[1] ?? "").startsWith("30617:"), ); diff --git a/desktop/tests/e2e/projects-empty.spec.ts b/desktop/tests/e2e/projects-empty.spec.ts new file mode 100644 index 0000000000..6605e86a32 --- /dev/null +++ b/desktop/tests/e2e/projects-empty.spec.ts @@ -0,0 +1,31 @@ +import { expect, test } from "@playwright/test"; + +import { installMockBridge } from "../helpers/bridge"; + +test("first repository can be created from the empty projects shell", async ({ + page, +}) => { + await installMockBridge(page, { emptyProjects: true }); + await page.goto("/", { waitUntil: "domcontentloaded" }); + await page.getByTestId("open-projects-view").click(); + + await expect( + page.getByRole("heading", { level: 1, name: "Projects" }), + ).toBeVisible(); + await expect(page.getByTestId("projects-create-menu")).toBeVisible(); + await expect(page.getByText("No projects yet")).toBeVisible(); + + await page.getByRole("button", { name: "Create repository" }).click(); + await expect(page.getByTestId("create-project-dialog")).toBeVisible(); + + await page.getByTestId("create-project-name").fill("first-repository"); + await page.getByTestId("create-project-submit").click(); + + await expect(page.getByTestId("create-project-dialog")).toBeHidden(); + await expect( + page.getByText('Project "first-repository" created.'), + ).toBeVisible(); + await expect( + page.getByText("first-repository", { exact: true }), + ).toBeVisible(); +}); diff --git a/desktop/tests/helpers/bridge.ts b/desktop/tests/helpers/bridge.ts index ca4d62ddd6..fead9edd7a 100644 --- a/desktop/tests/helpers/bridge.ts +++ b/desktop/tests/helpers/bridge.ts @@ -132,6 +132,8 @@ export type MockAgentMemoryListing = { }; type MockBridgeOptions = { + /** Start the mock relay without seeded NIP-34 repositories. */ + emptyProjects?: boolean; /** Advertised HEAD for the first mock project without adding that branch. */ projectHeadBranch?: string; /** Relay NIP-11 identity used to sign authoritative repository state. */