~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
93 lines · 3.5 KB Raw History
<script lang="ts">
	import type * as getQueue from '#lib/lexicons/dev/knotless/getQueue.ts';
	import type { QueueTypicalView } from '#lib/lexicons/dev/knotless/defs.ts';
	import { ago, landsAt, landsIn, plural } from '#lib/format.ts';
	import { zone } from '#lib/zone.svelte.ts';
	import Icon from '#lib/atoms/Icon.svelte';
	import Ref from '#lib/atoms/Ref.svelte';
	import Time from '#lib/atoms/Time.svelte';
	import CheckMark from '#lib/molecules/CheckMark.svelte';
	import ItemRow from '#lib/molecules/ItemRow.svelte';
	import Person from '#lib/molecules/Person.svelte';
	/**
	 * A branch's merge queue, of the repository whose page is at `base`, in
	 * the order it lands: each batch being checked or landing, with its
	 * checks and its pulls, then the pulls waiting for one, each saying
	 * where it stands, with its own checks, and when it should land, by
	 * `typical`, how long the queue takes.
	 */
	let {
		line,
		base,
		typical
	}: { line: getQueue.BranchView; base: string; typical?: QueueTypicalView } = $props();
	const waiting = $derived(line.pulls.filter((q) => q.batch === undefined));
	const inBatch = (i: number) => line.pulls.filter((q) => q.batch === i);
	/** When the newest batch being checked started: those waiting land after it. */
	const ahead = $derived(
		line.batches
			.filter((b) => b.state === 'checking')
			.map((b) => b.startedAt)
			.filter((t) => t !== undefined)
			.sort()
			.at(-1)
	);
	/** When a pull waiting for a batch should land, before the rest of its line. */
	const lands = (q: getQueue.QueuedView) => {
		const at = q.batch === undefined ? landsAt(q, typical, undefined, ahead, zone.now) : null;
		return at === null ? '' : `${landsIn(at)} · `;
	};
	/** When a batch should land, all its pulls together, after what is said of it. */
	const batchLands = (b: getQueue.BatchView) => {
		const at =
			b.state === 'checking'
				? landsAt({ stage: 'checking' }, typical, b.startedAt, undefined, zone.now)
				: null;
		return at === null ? '' : `, ${landsIn(at)}`;
	};
</script>

{#snippet row(q: getQueue.QueuedView)}
	<ItemRow item={q.pull} kind="pull" {base}>
		{#snippet meta()}{#if q.batch === undefined}<span class="said">{q.said}</span
				>{/if}{#if q.checks?.length}<CheckMark checks={q.checks} />{/if}<span
				>{`${lands(q)}queued `}<Time
					at={q.queuedAt}
					show={(t) => ago(t, 'on ')}
				/>{' · opened by'}</span
			><Person handle={q.pull.author.handle} bot={q.pull.author.bot} />{/snippet}
	</ItemRow>
{/snippet}

<div class="box queue-line">
	<div class="boxhead">
		<Icon name="queue" /><span>Into <Ref name={line.branch} /></span><span class="end mute"
			>{plural(line.pulls.length, 'pull', 'pulls')} queued</span
		>
	</div>
	{#each line.batches as b, i (b.commit)}
		<div class="queue-group {b.state}">
			<Icon name={b.state === 'landing' ? 'passed' : 'running'} />
			<b>{b.state === 'landing' ? 'Landing' : 'Being checked'}</b>
			<code class="sha">{b.commit.slice(0, 7)}</code>
			{#if b.startedAt}<span class="mute"
					>{`${plural(b.size, 'pull', 'pulls')}, started `}<Time
						at={b.startedAt}
						show={ago}
					/>{batchLands(b)}</span
				>{:else}<span class="mute">{plural(b.size, 'pull', 'pulls')}</span>{/if}
			<span class="end"><CheckMark checks={b.checks} /></span>
		</div>
		<ul class="list">
			{#each inBatch(i) as q (q.pull.uri)}{@render row(q)}{/each}
		</ul>
	{/each}
	{#if waiting.length}
		{#if line.batches.length}<div class="queue-group">
				<Icon name="clock" /><b>Not in a batch yet</b>
			</div>{/if}
		<ul class="list">
			{#each waiting as q (q.pull.uri)}{@render row(q)}{/each}
		</ul>
	{/if}
</div>