This introduces a new Tauri command to clone a remote repository into a validated destination folder, then return the full repository bundle for immediate rendering. The Svelte app gains a clone dialog and a new action in repository management, wiring the cloned bundle into existing refresh helpers. Dialog backdrops were also adjusted to rely on explicit close controls. - Add clone_repository command and core cloning logic in Rust - Create CloneRepositoryDialog and integrate it into App.svelte - Improve clone-related styling and tighten dialog backdrop behavior
108 lines
3.3 KiB
Svelte
108 lines
3.3 KiB
Svelte
<script lang="ts">
|
|
import { ArrowRight, GitCompare, LoaderCircle, X } from "@lucide/svelte";
|
|
import type { GitCommit } from "../types";
|
|
|
|
interface Props {
|
|
commits: GitCommit[];
|
|
compareFrom: string;
|
|
compareTo: string;
|
|
canCompare: boolean;
|
|
isBusy: boolean;
|
|
operation: string;
|
|
onCompareFromChange: (val: string) => void;
|
|
onCompareToChange: (val: string) => void;
|
|
onCompare: () => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
let {
|
|
commits = [],
|
|
compareFrom = "",
|
|
compareTo = "",
|
|
canCompare = false,
|
|
isBusy = false,
|
|
operation = "",
|
|
onCompareFromChange = () => {},
|
|
onCompareToChange = () => {},
|
|
onCompare = () => {},
|
|
onClose = () => {},
|
|
}: Props = $props();
|
|
|
|
function commitOptionLabel(item: GitCommit): string {
|
|
return `${item.short_hash} - ${item.summary}`;
|
|
}
|
|
|
|
function handleSubmit(event: SubmitEvent) {
|
|
event.preventDefault();
|
|
onCompare();
|
|
}
|
|
</script>
|
|
|
|
<div
|
|
class="dialog-backdrop"
|
|
role="presentation"
|
|
>
|
|
<div class="dialog compare-select-dialog" role="dialog" aria-modal="true" aria-label="Select commits to compare" tabindex="-1">
|
|
<header class="dialog-header">
|
|
<div>
|
|
<span class="eyebrow">Compare</span>
|
|
<h2 class="mt-0.5 text-ink text-base font-bold leading-tight">Select commits</h2>
|
|
</div>
|
|
<button class="dialog-close" type="button" onclick={onClose} title="Close">
|
|
<X size={18} aria-hidden="true" />
|
|
</button>
|
|
</header>
|
|
|
|
{#if commits.length < 2}
|
|
<div class="blank-state">At least two commits are needed to compare.</div>
|
|
{:else}
|
|
<form class="compare-form" onsubmit={handleSubmit}>
|
|
<label class="compare-field">
|
|
<span>From (older)</span>
|
|
<select
|
|
value={compareFrom}
|
|
onchange={(e) => onCompareFromChange((e.target as HTMLSelectElement).value)}
|
|
disabled={isBusy}
|
|
>
|
|
<option value="" disabled>Select a commit</option>
|
|
{#each commits as item (item.hash)}
|
|
<option value={item.hash}>{commitOptionLabel(item)}</option>
|
|
{/each}
|
|
</select>
|
|
</label>
|
|
|
|
<ArrowRight class="compare-arrow" size={18} aria-hidden="true" />
|
|
|
|
<label class="compare-field">
|
|
<span>To (newer)</span>
|
|
<select
|
|
value={compareTo}
|
|
onchange={(e) => onCompareToChange((e.target as HTMLSelectElement).value)}
|
|
disabled={isBusy}
|
|
>
|
|
<option value="" disabled>Select a commit</option>
|
|
{#each commits as item (item.hash)}
|
|
<option value={item.hash}>{commitOptionLabel(item)}</option>
|
|
{/each}
|
|
</select>
|
|
</label>
|
|
|
|
<button class="btn-primary" type="submit" disabled={!canCompare}>
|
|
{#if operation === "Comparing commits"}
|
|
<LoaderCircle class="spin" size={16} aria-hidden="true" />
|
|
{:else}
|
|
<GitCompare size={16} aria-hidden="true" />
|
|
{/if}
|
|
Compare
|
|
</button>
|
|
</form>
|
|
|
|
{#if compareFrom && compareTo && compareFrom === compareTo}
|
|
<div class="blank-state">Select two different commits to compare.</div>
|
|
{:else}
|
|
<div class="blank-state">Pick two commits and run a comparison.</div>
|
|
{/if}
|
|
{/if}
|
|
</div>
|
|
</div>
|