Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
Svelte
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146<script module lang="ts"> export interface MigrationItem { id: string | number; name: string; migration: { status: "idle" | "submitting" | "error" | "success"; error?: string; task?: { taskId: string; name: string }; jobId?: string; jobStatus?: string; jobError?: string; repoDid?: string; }; }</script>
<script lang="ts"> import { resolve } from "$app/paths"; import ArrowRight from "$icon/arrow-right"; import CircleUserRound from "$icon/circle-user-round"; import { migrationRunning } from "$lib/api/migrator"; import Button from "$lib/components/ui/Button.svelte"; import MigrationRow, { stageLabel } from "./MigrationRow.svelte"; import StartedBanner from "./StartedBanner.svelte"; import Step from "./Step.svelte";
interface Props { number: number; title?: string; disabled?: boolean; items: MigrationItem[]; running?: boolean; failed?: boolean; userHandle?: string; bannerNote?: string; id?: string; }
let { number, title = "Migration", disabled = false, items, running, failed, userHandle, bannerNote, id }: Props = $props();
let bannerVisible = $state(true);
const isRunning = $derived( running ?? items.some((item) => { const m = item.migration; return ( m.status === "submitting" || (m.status === "success" && m.jobStatus !== undefined && migrationRunning(m.jobStatus)) ); }) );
const isFailed = $derived( failed ?? items.some((item) => { const m = item.migration; return ( m.status === "error" || (m.status === "success" && m.jobStatus !== "completed") ); }) );</script>
<Step {number} {title} disabled={disabled && items.length === 0} {id}> {#if !items.length} <p class="typography-paragraph-small text-foreground-muted">No migrations started yet.</p> {:else} {#if bannerVisible} <div class="mb-3"> <StartedBanner onDismiss={() => (bannerVisible = false)} note={bannerNote} /> </div> {/if} <div class="flex flex-col gap-2" aria-live="polite"> {#each items as item (item.id)} {@const m = item.migration} {@const itemFailed = m.status === "error" || (m.status === "success" && (m.jobStatus === "failed" || m.jobStatus === "authorization_required"))} {@const state = itemFailed ? "failed" : m.status === "success" && m.jobStatus === "completed" ? "done" : "running"} <div> <MigrationRow label={item.name} {state} percent={state === "done" ? 100 : undefined} stage={state === "running" && m.status === "success" && m.jobStatus ? stageLabel(m.jobStatus) : undefined} href={userHandle && m.status === "success" && m.jobStatus === "completed" && m.task ? resolve(`/${userHandle}/${m.task.name}` as "/") : undefined} /> {#if itemFailed && m.status === "error"} <p class="mt-1 px-1 typography-paragraph-small break-all text-foreground-danger" > {m.error} </p> {:else if itemFailed && m.status === "success"} <p class="mt-1 px-1 typography-paragraph-small break-all text-foreground-danger" > {m.jobStatus === "authorization_required" ? "The source rejected its saved credential. Reconnect GitHub and start the import again." : (m.jobError ?? "The migration failed")} </p> {/if} </div> {/each} </div> {#if !isRunning} <div class="mt-4 flex justify-end"> <Button href={userHandle ? (resolve(`/${userHandle}?tab=repos` as "/") as `/${string}`) : undefined} variant={isFailed ? "default" : "primary"} icon={CircleUserRound} > All my repositories<ArrowRight class="size-4" aria-hidden="true" /> </Button> </div> {/if} {/if}</Step>