From 8f750fe451ec0bbc4bd8cb38dd3175ed970eacd4 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Fri, 4 Sep 2026 15:00:11 +0200 Subject: [PATCH] ui : lift download delete/cancel confirmations into the options panel Move the two confirmation dialogs out of the quant download chip into the download-options parent, which now owns a single pair keyed by the acted-on repo+tag. The chip stays presentational and only signals delete/cancel intent. Assisted-by: llama-ui:Qwen3.8-Flash-Next --- ...odelsDiscoverDetailsDownloadOptions.svelte | 45 +++++++++++++++++- ...sDownloadOptionsQuantDownloadButton.svelte | 47 ++++--------------- ...lsDiscoverDetailsDownloadOptionsRow.svelte | 13 ++++- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptions.svelte b/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptions.svelte index 3f99329e34..40783ba065 100644 --- a/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptions.svelte +++ b/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptions.svelte @@ -2,6 +2,7 @@ import { classify, labelFor } from './download-options.utils'; import ModelsDiscoverDetailsDownloadOptionsDownloadCommand from './ModelsDiscoverDetailsDownloadOptionsDownloadCommand.svelte'; import ModelsDiscoverDetailsDownloadOptionsRow from './ModelsDiscoverDetailsDownloadOptionsRow.svelte'; + import DialogConfirmation from '$lib/components/app/dialogs/DialogConfirmation.svelte'; import { SelectableFileKind } from '$lib/enums'; import { HuggingFaceService, ModelsService } from '$lib/services'; import { modelsStore } from '$lib/stores'; @@ -22,6 +23,29 @@ let { bitDepthRows, getDownloadState, modelId }: Props = $props(); + // Destructive chip actions (delete a downloaded model, cancel a download) are + // confirmed here rather than inside each chip: one pair of dialogs owned by + // the options panel, keyed by the repo+tag the user acted on. + let pending: { action: 'cancel' | 'delete'; repoWithTag: string } | null = $state(null); + + function requestCancel(repoWithTag: string) { + pending = { action: 'cancel', repoWithTag }; + } + + function requestDelete(repoWithTag: string) { + pending = { action: 'delete', repoWithTag }; + } + + function closePending() { + pending = null; + } + + function confirmPending() { + if (pending) void modelsStore.status.cancelDownload(pending.repoWithTag); + + pending = null; + } + function stateFor(repoWithTag: string, filePath: string, isSidecar: boolean): DownloadEntryState { if (getDownloadState) return getDownloadState(repoWithTag, filePath, isSidecar); @@ -117,7 +141,12 @@ lifecycle state; nothing here selects anything. -->
{#each rows as row (row.bitDepth)} - + {/each}
@@ -127,3 +156,17 @@ {/if} + +{#if pending} + +{/if} diff --git a/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptionsQuantDownloadButton.svelte b/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptionsQuantDownloadButton.svelte index 1a47cd439c..1b376489f3 100644 --- a/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptionsQuantDownloadButton.svelte +++ b/tools/ui/src/lib/components/app/models/discover/ModelsDiscoverDetails/ModelsDiscoverDetailsDownloadOptions/ModelsDiscoverDetailsDownloadOptionsQuantDownloadButton.svelte @@ -2,7 +2,6 @@ import DownloadProgressBar from '../../DownloadProgressBar.svelte'; import { labelFor } from './download-options.utils'; import { Check, Download, Loader2, Pause, Play, RotateCw, X } from '@lucide/svelte'; - import DialogConfirmation from '$lib/components/app/dialogs/DialogConfirmation.svelte'; import * as Tooltip from '$lib/components/ui/tooltip'; import { HuggingFaceService } from '$lib/services'; import { modelsStore } from '$lib/stores'; @@ -13,13 +12,16 @@ file: HfModelSibling; /** Download state of the file, from the parent's status feed. */ entry: DownloadEntryState; + /** + * Ask the parent to confirm deleting a downloaded model. The chip owns no + * dialog; the parent renders the single confirmation and acts on confirm. + */ + onRequestDelete?: (repoWithTag: string) => void; + /** Ask the parent to confirm cancelling an in-flight download. */ + onRequestCancel?: (repoWithTag: string) => void; } - let { entry, file }: Props = $props(); - - // delete / cancel confirmation state - let confirmDeleteOpen = $state(false); - let confirmCancelOpen = $state(false); + let { entry, file, onRequestCancel, onRequestDelete }: Props = $props(); /** Queue the download; a failed attempt leaves partial files, drop them first. */ async function startDownload() { @@ -62,7 +64,7 @@ aria-label={tooltipText} class="group relative inline-flex h-auto cursor-pointer items-center gap-1 rounded-md! border px-2 py-1 text-left font-mono text-xs shadow-xs transition-[background-color,border-color,transform] duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] active:scale-[0.97] border-green-600/25 bg-green-500/5 hover:border-destructive/50 hover:bg-destructive/10 dark:border-green-500/30 dark:bg-green-500/10 dark:hover:border-destructive/50 dark:hover:bg-destructive/15" - onclick={() => (confirmDeleteOpen = true)} + onclick={() => onRequestDelete?.(entry.repoWithTag)} type="button" > {#if meta?.sidecar} @@ -98,20 +100,6 @@

{tooltipText}

- - (confirmDeleteOpen = false)} - onConfirm={() => { - confirmDeleteOpen = false; - - void modelsStore.status.cancelDownload(entry.repoWithTag); - }} - open={confirmDeleteOpen} - title="Delete model" - variant="destructive" - /> {:else if entry.isDownloading || entry.isPaused}