mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-25 06:54:49 -06:00
refac
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
{#if tasks.length > 0 && hasActive}
|
||||
<div
|
||||
class="my-2 rounded-xl border border-gray-50 dark:border-gray-850 bg-white dark:bg-gray-900"
|
||||
class="my-2 rounded-2xl border border-gray-50 dark:border-gray-850 bg-white dark:bg-gray-900"
|
||||
transition:slide={{ duration: 200 }}
|
||||
>
|
||||
<!-- Header -->
|
||||
@@ -26,7 +26,10 @@
|
||||
<div class="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-400">
|
||||
<TaskListIcon className="w-3.5 h-3.5" />
|
||||
<span>
|
||||
{completedCount} {$i18n.t('out of')} {totalCount} {$i18n.t('tasks completed')}
|
||||
{completedCount}
|
||||
{$i18n.t('out of')}
|
||||
{totalCount}
|
||||
{$i18n.t('tasks completed')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -50,19 +53,43 @@
|
||||
<div class="flex items-start gap-2 py-0.5 text-xs">
|
||||
<span class="flex-shrink-0 mt-0.5 text-gray-400 dark:text-gray-500">
|
||||
{#if task.status === 'completed'}
|
||||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||
<svg
|
||||
class="w-3.5 h-3.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
>
|
||||
<path d="M5 13l4 4L19 7" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
{:else if task.status === 'in_progress'}
|
||||
<svg class="w-3.5 h-3.5 animate-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||
<svg
|
||||
class="w-3.5 h-3.5 animate-spin"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
>
|
||||
<path d="M12 3a9 9 0 1 0 9 9" stroke-linecap="round" />
|
||||
</svg>
|
||||
{:else if task.status === 'cancelled'}
|
||||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg
|
||||
class="w-3.5 h-3.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="12" cy="12" r="9" stroke-dasharray="4 3" />
|
||||
</svg>
|
||||
{:else}
|
||||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg
|
||||
class="w-3.5 h-3.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
export let unloadModelHandler: (modelValue: string) => void = () => {};
|
||||
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||
export let deleteModelHandler: (model: any) => void = () => {};
|
||||
|
||||
export let onClick: () => void = () => {};
|
||||
|
||||
@@ -255,6 +256,7 @@
|
||||
bind:show={showMenu}
|
||||
model={item.model}
|
||||
{pinModelHandler}
|
||||
{deleteModelHandler}
|
||||
copyLinkHandler={() => {
|
||||
copyLinkHandler(item.model);
|
||||
}}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||
export let copyLinkHandler: Function = () => {};
|
||||
export let deleteModelHandler: Function = () => {};
|
||||
|
||||
export let onClose: Function = () => {};
|
||||
</script>
|
||||
@@ -66,6 +67,37 @@
|
||||
<div class="flex items-center">{$i18n.t('Edit')}</div>
|
||||
</button>
|
||||
|
||||
{#if $user?.role === 'admin' && model?.owned_by === 'ollama'}
|
||||
<button
|
||||
type="button"
|
||||
class="select-none flex rounded-xl py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition items-center gap-2"
|
||||
on:click={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
deleteModelHandler(model);
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-4"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Delete')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<hr class="border-gray-50 dark:border-gray-800/30 my-1" />
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
|
||||
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
|
||||
@@ -375,6 +376,41 @@
|
||||
}
|
||||
};
|
||||
|
||||
let showDeleteConfirm = false;
|
||||
let deleteModelTarget: any = null;
|
||||
|
||||
const deleteModelHandler = async (model: any) => {
|
||||
deleteModelTarget = model;
|
||||
showDeleteConfirm = true;
|
||||
};
|
||||
|
||||
const confirmDeleteModel = async () => {
|
||||
const model = deleteModelTarget;
|
||||
if (!model) return;
|
||||
|
||||
const res = await deleteModel(localStorage.token, model.id).catch((error) => {
|
||||
toast.error($i18n.t('Error deleting model: {{error}}', { error }));
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Model {{modelName}} deleted successfully', { modelName: model.name ?? model.id }));
|
||||
|
||||
// If the deleted model was selected, clear the selection
|
||||
if (value === model.id) {
|
||||
value = '';
|
||||
}
|
||||
|
||||
models.set(
|
||||
await getModels(
|
||||
localStorage.token,
|
||||
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
deleteModelTarget = null;
|
||||
};
|
||||
|
||||
const ITEM_HEIGHT = 42;
|
||||
const OVERSCAN = 10;
|
||||
|
||||
@@ -388,6 +424,15 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<ConfirmDialog
|
||||
bind:show={showDeleteConfirm}
|
||||
title={$i18n.t('Delete Model')}
|
||||
message={$i18n.t('Are you sure you want to delete **{{modelName}}**?', { modelName: deleteModelTarget?.name ?? deleteModelTarget?.id ?? '' })}
|
||||
on:confirm={() => {
|
||||
confirmDeleteModel();
|
||||
}}
|
||||
/>
|
||||
|
||||
<DropdownMenu.Root
|
||||
bind:open={show}
|
||||
onOpenChange={async () => {
|
||||
@@ -646,6 +691,7 @@
|
||||
{value}
|
||||
{pinModelHandler}
|
||||
{unloadModelHandler}
|
||||
{deleteModelHandler}
|
||||
onClick={() => {
|
||||
value = item.value;
|
||||
selectedModelIdx = index;
|
||||
|
||||
Reference in New Issue
Block a user