Simplify BranchSelector and PeerSelector props

We greatly reduce the numbers of properties that need to be passed to
`BranchSelector` and `PeerSelector` by constructing routes in
`SourceBrowsingHeader`. We’ll lift the logic out of
`SourceBrowsingHeader` in a follow-up.

Signed-off-by: Thomas Scholtes <geigerzaehler@axiom.fm>
This commit is contained in:
Thomas Scholtes
2023-07-19 15:00:39 +02:00
committed by Rūdolfs Ošiņš
parent afbc57079b
commit fdd074fd13
3 changed files with 109 additions and 133 deletions
+8 -54
View File
@@ -1,10 +1,4 @@
<script lang="ts">
import type { BaseUrl } from "@httpd-client";
import type {
LoadedSourceBrowsingView,
ProjectRoute,
} from "@app/views/projects/router";
import * as utils from "@app/lib/utils";
import { closeFocused } from "@app/components/Floating.svelte";
@@ -12,52 +6,14 @@
import DropdownItem from "@app/components/Dropdown/DropdownItem.svelte";
import Floating from "@app/components/Floating.svelte";
import Link from "@app/components/Link.svelte";
import type { Route } from "@app/lib/router";
export let baseUrl: BaseUrl;
export let branches: Record<string, string> | undefined;
export let peer: string | undefined;
export let projectId: string;
export let view: LoadedSourceBrowsingView;
export let selectedBranch: string | undefined;
export let selectedCommitId: string;
export let branches: Array<{ name: string; route: Route }>;
$: branchList = Object.keys(branches || {})
.sort()
.map(b => ({ key: b, value: b, title: `Switch to ${b}`, badge: null }));
$: showSelector = branchList.length > 1;
$: showSelector = branches.length > 1;
$: selectedCommitShortId = utils.formatCommit(selectedCommitId);
function routeFromView(
revision: string,
view: LoadedSourceBrowsingView,
): ProjectRoute {
if (view.resource === "tree") {
return {
resource: "project.tree",
seed: baseUrl,
project: projectId,
peer,
revision,
};
} else if (view.resource === "history") {
return {
resource: "project.history",
seed: baseUrl,
project: projectId,
peer,
revision,
};
} else if (view.resource === "commits") {
return {
resource: "project.commit",
seed: baseUrl,
project: projectId,
commit: view.commit.commit.id,
};
} else {
return utils.unreachable(view);
}
}
</script>
<style>
@@ -102,7 +58,7 @@
<div class="commit" title="Current branch">
<!-- Check for branches listing feature -->
{#if branchList.length > 0}
{#if branches.length > 0}
{#if selectedBranch}
<Floating disabled={!showSelector}>
<div
@@ -113,15 +69,13 @@
{selectedBranch}
</div>
<svelte:fragment slot="modal">
<Dropdown items={branchList}>
<Dropdown items={branches}>
<svelte:fragment slot="item" let:item>
<Link
route={routeFromView(item.value, view)}
on:afterNavigate={() => closeFocused()}>
<Link route={item.route} on:afterNavigate={() => closeFocused()}>
<DropdownItem
selected={item.value === selectedBranch}
selected={item.name === selectedBranch}
size="tiny">
{item.value}
{item.name}
</DropdownItem>
</Link>
</svelte:fragment>
+25 -71
View File
@@ -1,12 +1,9 @@
<script lang="ts">
import type { BaseUrl, Remote } from "@httpd-client";
import type {
LoadedSourceBrowsingView,
ProjectRoute,
} from "@app/views/projects/router";
import type { Remote } from "@httpd-client";
import { type Route } from "@app/lib/router";
import { closeFocused } from "@app/components/Floating.svelte";
import { formatNodeId, truncateId, unreachable } from "@app/lib/utils";
import { formatNodeId, truncateId } from "@app/lib/utils";
import { pluralize } from "@app/lib/pluralize";
import Avatar from "@app/components/Avatar.svelte";
@@ -17,13 +14,9 @@
import Icon from "@app/components/Icon.svelte";
import Link from "@app/components/Link.svelte";
export let baseUrl: BaseUrl;
export let peer: string | undefined = undefined;
export let peers: Remote[];
export let projectId: string;
export let view: LoadedSourceBrowsingView;
export let peers: Array<{ remote: Remote; selected: boolean; route: Route }>;
$: meta = peers.find(p => p.id === peer);
$: selectedPeer = peers.find(p => p.selected)?.remote;
function createTitle(p: Remote): string {
const nodeId = formatNodeId(p.id);
@@ -31,36 +24,6 @@
? `${nodeId} is a delegate of this project`
: `${nodeId} is a peer tracked by this node`;
}
function routeFromView(
peer: string,
view: LoadedSourceBrowsingView,
): ProjectRoute {
if (view.resource === "tree") {
return {
resource: "project.tree",
seed: baseUrl,
project: projectId,
peer,
};
} else if (view.resource === "history") {
return {
resource: "project.history",
seed: baseUrl,
project: projectId,
peer,
};
} else if (view.resource === "commits") {
return {
resource: "project.commit",
seed: baseUrl,
project: projectId,
commit: view.commit.commit.id,
};
} else {
return unreachable(view);
}
}
</script>
<style>
@@ -108,30 +71,23 @@
<Floating>
<div slot="toggle" class="selector" title="Change peer">
<div class="stat peer" class:not-allowed={!peers}>
{#if !peer}
<Icon size="small" name="fork" />{peers.length}
{pluralize("remote", peers.length)}
{/if}
{#if meta}
{#if selectedPeer}
<span class="avatar-id">
<Avatar nodeId={meta.id} inline />
<Avatar nodeId={selectedPeer.id} inline />
<!-- Ignore prettier to avoid getting a whitespace between
did:key: and the nid due to a newline. -->
<!-- prettier-ignore -->
<span><span style:color="var(--color-secondary-5)">did:key:</span>{truncateId(meta.id)}</span>
{#if meta.alias}
<span class="alias">({meta.alias})</span>
<span><span style:color="var(--color-secondary-5)">did:key:</span>{truncateId(selectedPeer.id)}</span>
{#if selectedPeer.alias}
<span class="alias">({selectedPeer.alias})</span>
{/if}
</span>
{#if meta.delegate}
{#if selectedPeer.delegate}
<Badge variant="primary">delegate</Badge>
{/if}
{:else if peer}
<span class="avatar-id">
<Avatar nodeId={peer} inline />
<!-- prettier-ignore -->
<span><span style:color="var(--color-secondary-5)">did:key:</span>{truncateId(peer)}</span>
</span>
{:else}
<Icon size="small" name="fork" />{peers.length}
{pluralize("remote", peers.length)}
{/if}
</div>
</div>
@@ -140,31 +96,29 @@
<Dropdown items={peers}>
<svelte:fragment slot="item" let:item>
<div class="dropdown-item">
<Link
on:afterNavigate={() => closeFocused()}
route={routeFromView(item.id, view)}>
<Link on:afterNavigate={() => closeFocused()} route={item.route}>
<DropdownItem
selected={item.id === peer}
title={createTitle(item)}
selected={item.selected}
title={createTitle(item.remote)}
size="tiny">
<span class="avatar-id">
<Avatar nodeId={item.id} inline />
<Avatar nodeId={item.remote.id} inline />
<div class="layout-desktop">
<!-- prettier-ignore -->
<span><span class="prefix">did:key:</span>{item.id}</span>
{#if item.alias}
<span class="alias">({item.alias})</span>
<span><span class="prefix">did:key:</span>{item.remote.id}</span>
{#if item.remote.alias}
<span class="alias">({item.remote.alias})</span>
{/if}
</div>
<div class="layout-mobile">
<!-- prettier-ignore -->
<span><span class="prefix">did:key:</span>{truncateId(item.id)}</span>
{#if item.alias}
<span class="alias">({item.alias})</span>
<span><span class="prefix">did:key:</span>{truncateId(item.remote.id)}</span>
{#if item.remote.alias}
<span class="alias">({item.remote.alias})</span>
{/if}
</div>
</span>
{#if item.delegate}
{#if item.remote.delegate}
<Badge variant="primary">delegate</Badge>
{/if}
</DropdownItem>
+76 -8
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import type { BaseUrl, Remote } from "@httpd-client";
import { type Route } from "@app/lib/router";
import type { LoadedSourceBrowsingView } from "@app/views/projects/router";
import { pluralize } from "@app/lib/pluralize";
@@ -8,6 +9,7 @@
import PeerSelector from "@app/views/projects/PeerSelector.svelte";
import Link from "@app/components/Link.svelte";
import SquareButton from "@app/components/SquareButton.svelte";
import { unreachable } from "@app/lib/utils";
export let baseUrl: BaseUrl;
export let branches: Record<string, string> | undefined;
@@ -32,6 +34,76 @@
} else {
selectedBranch = revision || defaultBranch;
}
$: peersWithRoute = peers.map(remote => ({
remote,
selected: remote.id === peer,
route: makePeerRoute(view, remote.id),
}));
function makePeerRoute(view: LoadedSourceBrowsingView, peer: string): Route {
if (view.resource === "tree") {
return {
resource: "project.tree",
seed: baseUrl,
project: projectId,
peer,
};
} else if (view.resource === "history") {
return {
resource: "project.history",
seed: baseUrl,
project: projectId,
peer,
};
} else if (view.resource === "commits") {
return {
resource: "project.commit",
seed: baseUrl,
project: projectId,
commit: view.commit.commit.id,
};
} else {
return unreachable(view);
}
}
$: branchesWithRoute = Object.keys(branches || {}).map(name => ({
name,
route: makeBranchRoute(name, view),
}));
function makeBranchRoute(
revision: string,
view: LoadedSourceBrowsingView,
): Route {
if (view.resource === "tree") {
return {
resource: "project.tree",
seed: baseUrl,
project: projectId,
peer,
revision,
};
} else if (view.resource === "history") {
return {
resource: "project.history",
seed: baseUrl,
project: projectId,
peer,
revision,
};
} else if (view.resource === "commits") {
return {
resource: "project.commit",
seed: baseUrl,
project: projectId,
commit: view.commit.commit.id,
};
} else {
return unreachable(view);
}
}
</script>
<style>
@@ -57,18 +129,14 @@
</style>
<div class="header">
{#if peers.length > 0}
<PeerSelector {baseUrl} {peers} {peer} {projectId} {view} />
{#if peersWithRoute.length > 0}
<PeerSelector peers={peersWithRoute} />
{/if}
<BranchSelector
branches={branchesWithRoute}
selectedCommitId={commitId}
{baseUrl}
{branches}
{peer}
{projectId}
{selectedBranch}
{view} />
{selectedBranch} />
<Link
route={{