From 0ff55294ea4181486cd7411b2b845f1e037f89da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C5=ABdolfs=20O=C5=A1i=C5=86=C5=A1?= Date: Fri, 14 Jun 2024 15:36:33 +0200 Subject: [PATCH] Redesign node view --- src/views/nodes/NodeAddress.svelte | 27 ++ src/views/nodes/NodeInfo.svelte | 76 +++++ src/views/nodes/ScopePolicyPopover.svelte | 63 ---- src/views/nodes/View.svelte | 382 +++++++++++++++------- src/views/nodes/router.ts | 12 +- src/views/projects/Commit.svelte | 3 +- src/views/projects/History.svelte | 3 +- src/views/projects/Issue.svelte | 2 + src/views/projects/Issues.svelte | 3 +- src/views/projects/Layout.svelte | 12 +- src/views/projects/Patch.svelte | 2 + src/views/projects/Patches.svelte | 3 +- src/views/projects/Source.svelte | 2 + src/views/projects/router.ts | 35 +- tests/e2e/node.spec.ts | 3 +- 15 files changed, 428 insertions(+), 200 deletions(-) create mode 100644 src/views/nodes/NodeAddress.svelte create mode 100644 src/views/nodes/NodeInfo.svelte delete mode 100644 src/views/nodes/ScopePolicyPopover.svelte diff --git a/src/views/nodes/NodeAddress.svelte b/src/views/nodes/NodeAddress.svelte new file mode 100644 index 0000000000..c1089096cf --- /dev/null +++ b/src/views/nodes/NodeAddress.svelte @@ -0,0 +1,27 @@ + + +{#each externalAddresses as address} + +{:else} +
+ +
+
+ +
+{/each} diff --git a/src/views/nodes/NodeInfo.svelte b/src/views/nodes/NodeInfo.svelte new file mode 100644 index 0000000000..f1262f7215 --- /dev/null +++ b/src/views/nodes/NodeInfo.svelte @@ -0,0 +1,76 @@ + + + + +
+
+
+ Seeding Policy +
+
+
+ {capitalize(shortScope)} +
+ (expandedNode = !expandedNode)}> + + +
+
+ {#if expandedNode && seedingPolicy} +
+ +
+ {/if} +
+
+ Radicle version + +
+
{formatUserAgent(agent)}
+
+
+
diff --git a/src/views/nodes/ScopePolicyPopover.svelte b/src/views/nodes/ScopePolicyPopover.svelte deleted file mode 100644 index ef8518337e..0000000000 --- a/src/views/nodes/ScopePolicyPopover.svelte +++ /dev/null @@ -1,63 +0,0 @@ - - - - -
- - Policy: - {capitalize(seedingPolicy.default)} - - - {#if seedingPolicy.default === "allow"} - - - Scope: - {capitalize(seedingPolicy.scope)} - - {/if} - - - - - - - - -
- -
-
-
-
diff --git a/src/views/nodes/View.svelte b/src/views/nodes/View.svelte index 1932b5ef7f..dad2bd2fca 100644 --- a/src/views/nodes/View.svelte +++ b/src/views/nodes/View.svelte @@ -1,48 +1,127 @@ - -
-
-
-
{baseUrl.hostname}
-
-
- {#each externalAddresses as address} - - - - {:else} - - -
- -
-
- -
- {/each} + + +
+
+
+ +
+ {#if !collapsedHeader} +
+
+
+ {baseUrl.hostname} +
+
+ {/if} +
+ +
+ -
-
Pinned repositories
-
- {#if seedingPolicy} - Seeding Policy: - {capitalize(shortScope)} -
- - - - - - +
+
+
+
+
+ {baseUrl.hostname}
- {/if} + +
- -
- {#await fetchProjectInfos( baseUrl, { show: "pinned", perPage: stats.repos.total }, )} -
- +
+
+
+ {#if name} +
{name}
+ {/if} + {#if description} +
+ {description} +
+ {/if}
- {:then projectInfos} - {#if projectInfos.length > 0} -
- {#each projectInfos as projectInfo} - - {/each} +
+
+ {isLocal(baseUrl.hostname) ? "Seeded" : "Pinned"} repositories
- {:else} -
-
No pinned repositories
-
- This node doesn't have any pinned repositories. +
+ +
+ {#await fetchProjectInfos( baseUrl, { show: isLocal(baseUrl.hostname) ? "all" : "pinned", perPage: stats.repos.total }, )} +
+
-
- {/if} - {:catch error} - {router.push(handleError(error, baseUrlToString(baseUrl)))} - {/await} + {:then projectInfos} + {#if projectInfos.length > 0} +
+ {#each projectInfos as projectInfo} + + {/each} +
+ {:else} +
+
No pinned repositories
+
This node doesn't have any pinned repositories.
+
+ {/if} + {:catch error} + {router.push(handleError(error, baseUrlToString(baseUrl)))} + {/await} +
+
+ +
- +
diff --git a/src/views/nodes/router.ts b/src/views/nodes/router.ts index 5ca5585692..13b02daea9 100644 --- a/src/views/nodes/router.ts +++ b/src/views/nodes/router.ts @@ -27,6 +27,9 @@ export interface NodesLoadedRoute { nid: string; stats: NodeStats; seedingPolicy?: DefaultSeedingPolicy; + imageUrl?: string; + name?: string; + description?: string; }; } @@ -58,7 +61,11 @@ export async function loadNodeRoute( } const api = new HttpdClient(params.baseUrl); try { - const [node, stats] = await Promise.all([api.getNode(), api.getStats()]); + const [node, stats, profile] = await Promise.all([ + api.getNode(), + api.getStats(), + api.profile.getProfile(), + ]); return { resource: "nodes", @@ -69,6 +76,9 @@ export async function loadNodeRoute( externalAddresses: node.config?.externalAddresses ?? [], seedingPolicy: node.config?.seedingPolicy, agent: node.agent, + imageUrl: profile.config.web.imageUrl, + name: profile.config.web.name, + description: profile.config.web.description, }, }; } catch (error) { diff --git a/src/views/projects/Commit.svelte b/src/views/projects/Commit.svelte index d58a859d68..03219efb95 100644 --- a/src/views/projects/Commit.svelte +++ b/src/views/projects/Commit.svelte @@ -15,6 +15,7 @@ export let seedingPolicy: SeedingPolicy; export let commit: Commit; export let project: Project; + export let imageUrl: string | undefined; $: header = commit.commit; @@ -45,7 +46,7 @@ } - +
diff --git a/src/views/projects/History.svelte b/src/views/projects/History.svelte index 56ba1044d9..fd01dfa4c4 100644 --- a/src/views/projects/History.svelte +++ b/src/views/projects/History.svelte @@ -32,6 +32,7 @@ export let project: Project; export let revision: string | undefined; export let tree: Tree; + export let imageUrl: string | undefined; const api = new HttpdClient(baseUrl); @@ -89,7 +90,7 @@ } - +
diff --git a/src/views/projects/Issue.svelte b/src/views/projects/Issue.svelte index 0783dea70f..9699e49ef1 100644 --- a/src/views/projects/Issue.svelte +++ b/src/views/projects/Issue.svelte @@ -26,6 +26,7 @@ export let issue: Issue; export let project: Project; export let rawPath: (commit?: string) => string; + export let imageUrl: string | undefined; $: uniqueEmbeds = uniqBy( issue.discussion.flatMap(comment => comment.embeds), @@ -120,6 +121,7 @@ diff --git a/src/views/projects/Issues.svelte b/src/views/projects/Issues.svelte index dfc0eddcee..ac3cd9b52d 100644 --- a/src/views/projects/Issues.svelte +++ b/src/views/projects/Issues.svelte @@ -32,6 +32,7 @@ export let issues: Issue[]; export let project: Project; export let state: IssueState["status"]; + export let imageUrl: string | undefined; let loading = false; let page = 0; @@ -115,7 +116,7 @@ } - +
-
+
diff --git a/src/views/projects/Patch.svelte b/src/views/projects/Patch.svelte index 5f773d144f..42e684cec5 100644 --- a/src/views/projects/Patch.svelte +++ b/src/views/projects/Patch.svelte @@ -79,6 +79,7 @@ export let rawPath: (commit?: string) => string; export let project: Project; export let view: PatchView; + export let imageUrl: string | undefined; function badgeColor(status: string): ComponentProps["variant"] { if (status === "draft") { @@ -290,6 +291,7 @@ diff --git a/src/views/projects/Patches.svelte b/src/views/projects/Patches.svelte index 07b4ee8256..89e535688b 100644 --- a/src/views/projects/Patches.svelte +++ b/src/views/projects/Patches.svelte @@ -32,6 +32,7 @@ export let patches: Patch[]; export let project: Project; export let state: PatchState["status"]; + export let imageUrl: string | undefined; let loading = false; let page = 0; @@ -123,7 +124,7 @@ } - +
string; export let revision: string | undefined; export let tree: Tree; + export let imageUrl: string | undefined; let mobileFileTree = false; @@ -120,6 +121,7 @@ {seedingPolicy} {baseUrl} {project} + {imageUrl} activeTab="source" stylePaddingBottom="0"> diff --git a/src/views/projects/router.ts b/src/views/projects/router.ts index e1a5853679..aed02201fc 100644 --- a/src/views/projects/router.ts +++ b/src/views/projects/router.ts @@ -121,6 +121,7 @@ export type ProjectLoadedRoute = path: string; rawPath: (commit?: string) => string; blobResult: BlobResult; + imageUrl: string | undefined; }; } | { @@ -135,6 +136,7 @@ export type ProjectLoadedRoute = revision: string | undefined; tree: Tree; commitHeaders: CommitHeader[]; + imageUrl: string | undefined; }; } | { @@ -144,6 +146,7 @@ export type ProjectLoadedRoute = seedingPolicy: SeedingPolicy; project: Project; commit: Commit; + imageUrl: string | undefined; }; } | { @@ -154,6 +157,7 @@ export type ProjectLoadedRoute = project: Project; rawPath: (commit?: string) => string; issue: Issue; + imageUrl: string | undefined; }; } | { @@ -164,6 +168,7 @@ export type ProjectLoadedRoute = project: Project; issues: Issue[]; state: IssueState["status"]; + imageUrl: string | undefined; }; } | { @@ -174,6 +179,7 @@ export type ProjectLoadedRoute = project: Project; patches: Patch[]; state: PatchState["status"]; + imageUrl: string | undefined; }; } | { @@ -186,6 +192,7 @@ export type ProjectLoadedRoute = patch: Patch; stats: Diff["stats"]; view: PatchView; + imageUrl: string | undefined; }; }; @@ -265,10 +272,11 @@ export async function loadProjectRoute( } else if (route.resource === "project.history") { return await loadHistoryView(route); } else if (route.resource === "project.commit") { - const [project, commit, seedingPolicy] = await Promise.all([ + const [project, commit, seedingPolicy, profile] = await Promise.all([ api.project.getById(route.project), api.project.getCommitBySha(route.project, route.commit), api.getPoliciesById(route.project), + api.profile.getProfile(), ]); return { @@ -278,6 +286,7 @@ export async function loadProjectRoute( seedingPolicy, project, commit, + imageUrl: profile.config.web.imageUrl, }, }; } else if (route.resource === "project.issue") { @@ -311,7 +320,7 @@ async function loadPatchesView( const searchParams = new URLSearchParams(route.search || ""); const state = (searchParams.get("state") as PatchState["status"]) || "open"; - const [project, patches, seedingPolicy] = await Promise.all([ + const [project, patches, seedingPolicy, profile] = await Promise.all([ api.project.getById(route.project), api.project.getAllPatches(route.project, { state, @@ -319,6 +328,7 @@ async function loadPatchesView( perPage: PATCHES_PER_PAGE, }), api.getPoliciesById(route.project), + api.profile.getProfile(), ]); return { @@ -329,6 +339,7 @@ async function loadPatchesView( patches, state, project, + imageUrl: profile.config.web.imageUrl, }, }; } @@ -339,7 +350,7 @@ async function loadIssuesView( const api = new HttpdClient(route.node); const state = route.state || "open"; - const [project, issues, seedingPolicy] = await Promise.all([ + const [project, issues, seedingPolicy, profile] = await Promise.all([ api.project.getById(route.project), api.project.getAllIssues(route.project, { state, @@ -347,6 +358,7 @@ async function loadIssuesView( perPage: ISSUES_PER_PAGE, }), api.getPoliciesById(route.project), + api.profile.getProfile(), ]); return { @@ -357,6 +369,7 @@ async function loadIssuesView( issues, state, project, + imageUrl: profile.config.web.imageUrl, }, }; } @@ -421,9 +434,10 @@ async function loadTreeView( branchMap, ); const path = route.path || "/"; - const [tree, blobResult] = await Promise.all([ + const [tree, blobResult, profile] = await Promise.all([ api.project.getTree(route.project, commit), loadBlob(api, project.id, commit, path), + api.profile.getProfile(), ]); return { resource: "project.source", @@ -439,6 +453,7 @@ async function loadTreeView( tree, path, blobResult, + imageUrl: profile.config.web.imageUrl, }, }; } @@ -519,13 +534,14 @@ async function loadHistoryView( ); } - const [tree, commitHeaders] = await Promise.all([ + const [tree, commitHeaders, profile] = await Promise.all([ api.project.getTree(route.project, commitId), await api.project.getAllCommits(project.id, { parent: commitId, page: 0, perPage: COMMITS_PER_PAGE, }), + api.profile.getProfile(), ]); return { @@ -540,6 +556,7 @@ async function loadHistoryView( revision: route.revision, tree, commitHeaders, + imageUrl: profile.config.web.imageUrl, }, }; } @@ -553,10 +570,11 @@ async function loadIssueView( route.project }${commit ? `/${commit}` : ""}`; - const [project, issue, seedingPolicy] = await Promise.all([ + const [project, issue, seedingPolicy, profile] = await Promise.all([ api.project.getById(route.project), api.project.getIssueById(route.project, route.issue), api.getPoliciesById(route.project), + api.profile.getProfile(), ]); return { resource: "project.issue", @@ -566,6 +584,7 @@ async function loadIssueView( project, rawPath, issue, + imageUrl: profile.config.web.imageUrl, }, }; } @@ -579,10 +598,11 @@ async function loadPatchView( route.project }${commit ? `/${commit}` : ""}`; - const [project, patch, seedingPolicy] = await Promise.all([ + const [project, patch, seedingPolicy, profile] = await Promise.all([ api.project.getById(route.project), api.project.getPatchById(route.project, route.patch), api.getPoliciesById(route.project), + api.profile.getProfile(), ]); const latestRevision = patch.revisions[patch.revisions.length - 1]; const { diff } = await api.project.getDiff( @@ -644,6 +664,7 @@ async function loadPatchView( patch, stats: diff.stats, view, + imageUrl: profile.config.web.imageUrl, }, }; } diff --git a/tests/e2e/node.spec.ts b/tests/e2e/node.spec.ts index 8da3003593..7246e01d8a 100644 --- a/tests/e2e/node.spec.ts +++ b/tests/e2e/node.spec.ts @@ -21,9 +21,8 @@ test("node metadata", async ({ page, peerManager }) => { await page.goto(peer.uiUrl()); - await expect(page.getByRole("link", { name: "127.0.0.1" })).toBeVisible(); await expect( - page.getByText(`${shortNodeRemote}@seed.radicle.test:8123`), + page.getByText(`${shortNodeRemote}@seed.radicle.test:8123`).nth(0), ).toBeVisible(); await expect(page.getByText("radicle:1.0.0-rc.11")).toBeVisible(); });