Move identity state labels into lib

This commit is contained in:
Rūdolfs Ošiņš
2026-10-01 18:20:25 +02:00
parent a1c3622f05
commit 9a023b625c
4 changed files with 72 additions and 35 deletions
+3 -31
View File
@@ -1,36 +1,8 @@
<script lang="ts" module>
<script lang="ts">
import type { State } from "@bindings/identity/State";
import { formatOid } from "@app/lib/utils";
import { stateCaption, stateIcon, stateLabel } from "@app/lib/identityState";
const icons = {
active: "hourglass",
accepted: "checkmark",
rejected: "close",
} as const;
const labels = {
active: "Active",
accepted: "Accepted",
rejected: "Rejected",
};
export function stateIcon(state: State): (typeof icons)[State["status"]] {
return icons[state.status];
}
export function stateCaption(state: State): string | undefined {
if (state.status === "rejected") {
if (state.reason.type === "vote") return "Rejected by delegate votes";
if (state.reason.type === "parent")
return "Rejected because its parent revision was rejected";
return `Rejected because sibling ${formatOid(state.reason.revision)} was accepted`;
}
return undefined;
}
</script>
<script lang="ts">
import Icon from "@app/components/Icon.svelte";
interface Props {
@@ -68,5 +40,5 @@
class:rejected={state.status === "rejected"}
title={stateCaption(state)}>
<Icon name={stateIcon(state)} />
{labels[state.status]}
{stateLabel(state)}
</span>
+33
View File
@@ -0,0 +1,33 @@
import type { State } from "@bindings/identity/State";
import { formatOid } from "@app/lib/utils";
const icons = {
active: "hourglass",
accepted: "checkmark",
rejected: "close",
} as const;
const labels = {
active: "Active",
accepted: "Accepted",
rejected: "Rejected",
};
export function stateIcon(state: State): (typeof icons)[State["status"]] {
return icons[state.status];
}
export function stateLabel(state: State): string {
return labels[state.status];
}
export function stateCaption(state: State): string | undefined {
if (state.status === "rejected") {
if (state.reason.type === "vote") return "Rejected by delegate votes";
if (state.reason.type === "parent")
return "Rejected because its parent revision was rejected";
return `Rejected because sibling ${formatOid(state.reason.revision)} was accepted`;
}
return undefined;
}
+2 -4
View File
@@ -4,6 +4,7 @@
import { slide } from "svelte/transition";
import { stateCaption, stateIcon } from "@app/lib/identityState";
import type { SidebarData } from "@app/lib/router/definitions";
import {
absoluteTimestamp,
@@ -17,10 +18,7 @@
import IdentityChanges from "@app/components/IdentityChanges.svelte";
import IdentityDocument from "@app/components/IdentityDocument.svelte";
import IdentityJsonButton from "@app/components/IdentityJsonButton.svelte";
import IdentityStateBadge, {
stateCaption,
stateIcon,
} from "@app/components/IdentityStateBadge.svelte";
import IdentityStateBadge from "@app/components/IdentityStateBadge.svelte";
import Markdown from "@app/components/Markdown.svelte";
import NodeId from "@app/components/NodeId.svelte";
import RepoHeader from "@app/components/RepoHeader.svelte";
+34
View File
@@ -0,0 +1,34 @@
import type { State } from "@bindings/identity/State";
import { expect, test } from "vitest";
import { stateCaption, stateIcon, stateLabel } from "@app/lib/identityState";
const sibling = "4b2d0a1e9f5c3b7a6d8e0f1a2b3c4d5e6f7a8b9c";
test.each<[State, string, string, string | undefined]>([
[{ status: "active" }, "hourglass", "Active", undefined],
[{ status: "accepted" }, "checkmark", "Accepted", undefined],
[
{ status: "rejected", reason: { type: "vote" } },
"close",
"Rejected",
"Rejected by delegate votes",
],
[
{ status: "rejected", reason: { type: "parent" } },
"close",
"Rejected",
"Rejected because its parent revision was rejected",
],
[
{ status: "rejected", reason: { type: "sibling", revision: sibling } },
"close",
"Rejected",
"Rejected because sibling 4b2d0a1 was accepted",
],
])("%j", (state, icon, label, caption) => {
expect(stateIcon(state)).toBe(icon);
expect(stateLabel(state)).toBe(label);
expect(stateCaption(state)).toBe(caption);
});