From 3deef1e192f0a50261a7c07d843a80e738d0593f Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Wed, 12 Aug 2026 12:08:33 +0100 Subject: [PATCH] web/api: sort branches before display need a good way to do this without repetition Signed-off-by: oppiliappan --- web/src/lib/api/repo.ts | 16 ++++++++++++++++ web/src/lib/api/repoIndex.ts | 3 ++- .../lib/components/repo/pulls/PullCompose.svelte | 10 +++++----- web/src/routes/[handle]/[repo]/branches/+page.ts | 4 ++-- .../routes/[handle]/[repo]/pulls/new/+page.ts | 4 ++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/web/src/lib/api/repo.ts b/web/src/lib/api/repo.ts index cc1d6f9c..547ec2b9 100644 --- a/web/src/lib/api/repo.ts +++ b/web/src/lib/api/repo.ts @@ -272,6 +272,22 @@ export const toBranchSummary = (branch: BranchEntry): BranchSummary => ({ message: branch.commit?.Message }); +// canonical order for branch lists: default branch first, then newest commit first +export const sortBranches = ( + branches: readonly T[] +): T[] => + branches + .map((branch, index) => ({ branch, index })) + .sort((a, b) => { + if (a.branch.isDefault !== b.branch.isDefault) return a.branch.isDefault ? -1 : 1; + const at = a.branch.when ? Date.parse(a.branch.when) : NaN; + const bt = b.branch.when ? Date.parse(b.branch.when) : NaN; + const av = Number.isNaN(at) ? -Infinity : at; + const bv = Number.isNaN(bt) ? -Infinity : bt; + return bv - av || a.index - b.index; + }) + .map(({ branch }) => branch); + export interface TagSummary { name: string; hash: string; diff --git a/web/src/lib/api/repoIndex.ts b/web/src/lib/api/repoIndex.ts index 93820135..1132a1cc 100644 --- a/web/src/lib/api/repoIndex.ts +++ b/web/src/lib/api/repoIndex.ts @@ -11,6 +11,7 @@ import { } from "$lib/api/gitclient"; import { parallel } from "$lib/api/load"; import { + sortBranches, sortTreeEntries, tagsByCommitHash, toBranchSummary, @@ -161,7 +162,7 @@ export const loadRepoIndex = async ( languages: attempt(gitLanguages(git, ref)) }); - const branches = (results.branches.value?.branches ?? []).map(toBranchSummary); + const branches = sortBranches((results.branches.value?.branches ?? []).map(toBranchSummary)); const tags = (results.tags.value?.tags ?? []).map(toTagSummary); const commits = await withAuthorHandles( (results.log.value?.commits ?? []).map(toCommitSummary), diff --git a/web/src/lib/components/repo/pulls/PullCompose.svelte b/web/src/lib/components/repo/pulls/PullCompose.svelte index 233987b4..8d2dbbd9 100644 --- a/web/src/lib/components/repo/pulls/PullCompose.svelte +++ b/web/src/lib/components/repo/pulls/PullCompose.svelte @@ -26,14 +26,14 @@ import Textarea from "$lib/components/ui/Textarea.svelte"; import TimeAgo from "$lib/components/ui/TimeAgo.svelte"; import type { PullRecord } from "$lib/api/records"; - import type { BranchEntry, CommitSummary } from "$lib/api/repo"; + import type { BranchEntry, BranchSummary, CommitSummary } from "$lib/api/repo"; import type { SelectOption } from "$lib/components/ui/selectField"; import type { MarkupContext } from "$lib/markup"; import type { ForkOption } from "../../../../routes/[handle]/[repo]/pulls/new/+page"; /** everything the route's load derived, passed through whole */ interface Compose { - branches: BranchEntry[]; + branches: BranchSummary[]; sourceBranches: BranchEntry[]; forkBranches: BranchEntry[]; forks: ForkOption[]; @@ -102,10 +102,10 @@ const isSource = compose.source === "branch" && Boolean(compose.sourceBranch) && - branch.reference.name === compose.sourceBranch; + branch.name === compose.sourceBranch; return { - value: branch.reference.name, - hint: isSource ? "source" : defaultHint(branch), + value: branch.name, + hint: isSource ? "source" : branch.isDefault ? "default" : undefined, disabled: isSource }; }) diff --git a/web/src/routes/[handle]/[repo]/branches/+page.ts b/web/src/routes/[handle]/[repo]/branches/+page.ts index 1a3d2850..a2c80fd7 100644 --- a/web/src/routes/[handle]/[repo]/branches/+page.ts +++ b/web/src/routes/[handle]/[repo]/branches/+page.ts @@ -1,6 +1,6 @@ import { branches, gitTarget } from "$lib/api/gitclient"; import { REF_LIMIT } from "$lib/api/repoIndex"; -import { toBranchSummary } from "$lib/api/repo"; +import { sortBranches, toBranchSummary } from "$lib/api/repo"; import type { PageLoad } from "./$types"; export const load: PageLoad = async (event) => { @@ -11,7 +11,7 @@ export const load: PageLoad = async (event) => { const page = parsed >= 1 ? parsed : 1; const cursor = page > 1 ? String((page - 1) * REF_LIMIT) : undefined; const results = await branches(git, REF_LIMIT, cursor); - const list = (results.branches ?? []).map(toBranchSummary); + const list = sortBranches((results.branches ?? []).map(toBranchSummary)); const total = results.total ?? 0; const pageCount = total > 0 ? Math.ceil(total / REF_LIMIT) : page + (list.length === REF_LIMIT ? 1 : 0); diff --git a/web/src/routes/[handle]/[repo]/pulls/new/+page.ts b/web/src/routes/[handle]/[repo]/pulls/new/+page.ts index f7131744..05eb9dd2 100644 --- a/web/src/routes/[handle]/[repo]/pulls/new/+page.ts +++ b/web/src/routes/[handle]/[repo]/pulls/new/+page.ts @@ -11,7 +11,7 @@ import { type PullSource } from "$lib/api/pullCompose"; import { listRepos } from "$lib/api/records"; -import { repoNameOf } from "$lib/api/repo"; +import { repoNameOf, sortBranches, toBranchSummary } from "$lib/api/repo"; import type { Did } from "@atcute/lexicons/syntax"; import type { BranchEntry, CommitSummary } from "$lib/api/repo"; import type { PageLoad } from "./$types"; @@ -120,7 +120,7 @@ export const load: PageLoad = async (event) => { sourceRepoPath: forkRepo ? `${parent.auth?.handle ?? parent.repo.ownerHandle}/${forkRepo.name}` : `${parent.repo.ownerHandle}/${parent.repo.name}`, - branches: branchList, + branches: sortBranches(branchList.map(toBranchSummary)), sourceBranches, forkBranches, forks: forkList, -- 2.51.2