refac
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
{#if tasks.length > 0 && hasActive}
|
{#if tasks.length > 0 && hasActive}
|
||||||
<div
|
<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 }}
|
transition:slide={{ duration: 200 }}
|
||||||
>
|
>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
@@ -26,7 +26,10 @@
|
|||||||
<div class="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-400">
|
<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" />
|
<TaskListIcon className="w-3.5 h-3.5" />
|
||||||
<span>
|
<span>
|
||||||
{completedCount} {$i18n.t('out of')} {totalCount} {$i18n.t('tasks completed')}
|
{completedCount}
|
||||||
|
{$i18n.t('out of')}
|
||||||
|
{totalCount}
|
||||||
|
{$i18n.t('tasks completed')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -50,19 +53,43 @@
|
|||||||
<div class="flex items-start gap-2 py-0.5 text-xs">
|
<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">
|
<span class="flex-shrink-0 mt-0.5 text-gray-400 dark:text-gray-500">
|
||||||
{#if task.status === 'completed'}
|
{#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" />
|
<path d="M5 13l4 4L19 7" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
</svg>
|
</svg>
|
||||||
{:else if task.status === 'in_progress'}
|
{: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" />
|
<path d="M12 3a9 9 0 1 0 9 9" stroke-linecap="round" />
|
||||||
</svg>
|
</svg>
|
||||||
{:else if task.status === 'cancelled'}
|
{: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" />
|
<circle cx="12" cy="12" r="9" stroke-dasharray="4 3" />
|
||||||
</svg>
|
</svg>
|
||||||
{:else}
|
{: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" />
|
<circle cx="12" cy="12" r="9" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
export let unloadModelHandler: (modelValue: string) => void = () => {};
|
export let unloadModelHandler: (modelValue: string) => void = () => {};
|
||||||
export let pinModelHandler: (modelId: string) => void = () => {};
|
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||||
|
export let deleteModelHandler: (model: any) => void = () => {};
|
||||||
|
|
||||||
export let onClick: () => void = () => {};
|
export let onClick: () => void = () => {};
|
||||||
|
|
||||||
@@ -255,6 +256,7 @@
|
|||||||
bind:show={showMenu}
|
bind:show={showMenu}
|
||||||
model={item.model}
|
model={item.model}
|
||||||
{pinModelHandler}
|
{pinModelHandler}
|
||||||
|
{deleteModelHandler}
|
||||||
copyLinkHandler={() => {
|
copyLinkHandler={() => {
|
||||||
copyLinkHandler(item.model);
|
copyLinkHandler(item.model);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
export let pinModelHandler: (modelId: string) => void = () => {};
|
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||||
export let copyLinkHandler: Function = () => {};
|
export let copyLinkHandler: Function = () => {};
|
||||||
|
export let deleteModelHandler: Function = () => {};
|
||||||
|
|
||||||
export let onClose: Function = () => {};
|
export let onClose: Function = () => {};
|
||||||
</script>
|
</script>
|
||||||
@@ -66,6 +67,37 @@
|
|||||||
<div class="flex items-center">{$i18n.t('Edit')}</div>
|
<div class="flex items-center">{$i18n.t('Edit')}</div>
|
||||||
</button>
|
</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" />
|
<hr class="border-gray-50 dark:border-gray-800/30 my-1" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||||
|
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||||
import { flyAndScale } from '$lib/utils/transitions';
|
import { flyAndScale } from '$lib/utils/transitions';
|
||||||
|
|
||||||
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
|
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 ITEM_HEIGHT = 42;
|
||||||
const OVERSCAN = 10;
|
const OVERSCAN = 10;
|
||||||
|
|
||||||
@@ -388,6 +424,15 @@
|
|||||||
);
|
);
|
||||||
</script>
|
</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
|
<DropdownMenu.Root
|
||||||
bind:open={show}
|
bind:open={show}
|
||||||
onOpenChange={async () => {
|
onOpenChange={async () => {
|
||||||
@@ -646,6 +691,7 @@
|
|||||||
{value}
|
{value}
|
||||||
{pinModelHandler}
|
{pinModelHandler}
|
||||||
{unloadModelHandler}
|
{unloadModelHandler}
|
||||||
|
{deleteModelHandler}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
value = item.value;
|
value = item.value;
|
||||||
selectedModelIdx = index;
|
selectedModelIdx = index;
|
||||||
|
|||||||
Reference in New Issue
Block a user