mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-11 20:05:19 +00:00
refac: styling
This commit is contained in:
parent
db95e96688
commit
4b4241273d
1 changed files with 194 additions and 186 deletions
|
|
@ -436,213 +436,221 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if (models ?? []).length !== 0}
|
{#if models !== null}
|
||||||
<div class=" px-3 my-2 gap-1 lg:gap-2 grid lg:grid-cols-2" id="model-list">
|
{#if (models ?? []).length !== 0}
|
||||||
{#each models as model (model.id)}
|
<div class=" px-3 my-2 gap-1 lg:gap-2 grid lg:grid-cols-2" id="model-list">
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
{#each models as model (model.id)}
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
class=" flex cursor-pointer dark:hover:bg-gray-850/50 hover:bg-gray-50 transition rounded-2xl w-full p-2.5"
|
<div
|
||||||
id="model-item-{model.id}"
|
class=" flex cursor-pointer dark:hover:bg-gray-850/50 hover:bg-gray-50 transition rounded-2xl w-full p-2.5"
|
||||||
on:click={() => {
|
id="model-item-{model.id}"
|
||||||
if (
|
on:click={() => {
|
||||||
$user?.role === 'admin' ||
|
if (
|
||||||
model.user_id === $user?.id ||
|
$user?.role === 'admin' ||
|
||||||
model.access_control.write.group_ids.some((wg) => groupIds.includes(wg))
|
model.user_id === $user?.id ||
|
||||||
) {
|
model.access_control.write.group_ids.some((wg) => groupIds.includes(wg))
|
||||||
goto(`/workspace/models/edit?id=${encodeURIComponent(model.id)}`);
|
) {
|
||||||
}
|
goto(`/workspace/models/edit?id=${encodeURIComponent(model.id)}`);
|
||||||
}}
|
}
|
||||||
>
|
}}
|
||||||
<div class="flex group/item gap-3.5 w-full">
|
>
|
||||||
<div class="self-center pl-0.5">
|
<div class="flex group/item gap-3.5 w-full">
|
||||||
<div class="flex bg-white rounded-2xl">
|
<div class="self-center pl-0.5">
|
||||||
<div
|
<div class="flex bg-white rounded-2xl">
|
||||||
class="{model.is_active
|
<div
|
||||||
? ''
|
class="{model.is_active
|
||||||
: 'opacity-50 dark:opacity-50'} bg-transparent rounded-2xl"
|
? ''
|
||||||
>
|
: 'opacity-50 dark:opacity-50'} bg-transparent rounded-2xl"
|
||||||
<img
|
>
|
||||||
src={`${WEBUI_API_BASE_URL}/models/model/profile/image?id=${model.id}&lang=${$i18n.language}`}
|
<img
|
||||||
alt="modelfile profile"
|
src={`${WEBUI_API_BASE_URL}/models/model/profile/image?id=${model.id}&lang=${$i18n.language}`}
|
||||||
class=" rounded-2xl size-12 object-cover"
|
alt="modelfile profile"
|
||||||
/>
|
class=" rounded-2xl size-12 object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class=" shrink-0 flex w-full min-w-0 flex-1 pr-1 self-center">
|
<div class=" shrink-0 flex w-full min-w-0 flex-1 pr-1 self-center">
|
||||||
<div class="flex h-full w-full flex-1 flex-col justify-start self-center group">
|
<div class="flex h-full w-full flex-1 flex-col justify-start self-center group">
|
||||||
<div class="flex-1 w-full">
|
<div class="flex-1 w-full">
|
||||||
<div class="flex items-center justify-between w-full">
|
<div class="flex items-center justify-between w-full">
|
||||||
<Tooltip content={model.name} className=" w-fit" placement="top-start">
|
<Tooltip content={model.name} className=" w-fit" placement="top-start">
|
||||||
<a
|
<a
|
||||||
class=" font-medium line-clamp-1 hover:underline capitalize"
|
class=" font-medium line-clamp-1 hover:underline capitalize"
|
||||||
href={`/?models=${encodeURIComponent(model.id)}`}
|
href={`/?models=${encodeURIComponent(model.id)}`}
|
||||||
>
|
>
|
||||||
{model.name}
|
{model.name}
|
||||||
</a>
|
</a>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<div class=" flex items-center gap-1">
|
<div class=" flex items-center gap-1">
|
||||||
<div
|
<div
|
||||||
class="flex justify-end w-full {model.is_active ? '' : 'text-gray-500'}"
|
class="flex justify-end w-full {model.is_active ? '' : 'text-gray-500'}"
|
||||||
>
|
>
|
||||||
<div class="flex justify-between items-center w-full">
|
<div class="flex justify-between items-center w-full">
|
||||||
<div class=""></div>
|
<div class=""></div>
|
||||||
<div class="flex flex-row gap-0.5 items-center">
|
<div class="flex flex-row gap-0.5 items-center">
|
||||||
{#if shiftKey}
|
{#if shiftKey}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={model?.meta?.hidden ? $i18n.t('Show') : $i18n.t('Hide')}
|
content={model?.meta?.hidden
|
||||||
>
|
? $i18n.t('Show')
|
||||||
<button
|
: $i18n.t('Hide')}
|
||||||
class="self-center w-fit text-sm p-1.5 dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
>
|
||||||
type="button"
|
<button
|
||||||
on:click={(e) => {
|
class="self-center w-fit text-sm p-1.5 dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||||
e.stopPropagation();
|
type="button"
|
||||||
|
on:click={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
hideModelHandler(model);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if model?.meta?.hidden}
|
||||||
|
<EyeSlash />
|
||||||
|
{:else}
|
||||||
|
<Eye />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Tooltip content={$i18n.t('Delete')}>
|
||||||
|
<button
|
||||||
|
class="self-center w-fit text-sm p-1.5 dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||||
|
type="button"
|
||||||
|
on:click={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
deleteModelHandler(model);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<GarbageBin />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{:else}
|
||||||
|
<ModelMenu
|
||||||
|
user={$user}
|
||||||
|
{model}
|
||||||
|
editHandler={() => {
|
||||||
|
goto(
|
||||||
|
`/workspace/models/edit?id=${encodeURIComponent(model.id)}`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
shareHandler={() => {
|
||||||
|
shareModelHandler(model);
|
||||||
|
}}
|
||||||
|
cloneHandler={() => {
|
||||||
|
cloneModelHandler(model);
|
||||||
|
}}
|
||||||
|
exportHandler={() => {
|
||||||
|
exportModelHandler(model);
|
||||||
|
}}
|
||||||
|
hideHandler={() => {
|
||||||
hideModelHandler(model);
|
hideModelHandler(model);
|
||||||
}}
|
}}
|
||||||
>
|
copyLinkHandler={() => {
|
||||||
{#if model?.meta?.hidden}
|
copyLinkHandler(model);
|
||||||
<EyeSlash />
|
|
||||||
{:else}
|
|
||||||
<Eye />
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<Tooltip content={$i18n.t('Delete')}>
|
|
||||||
<button
|
|
||||||
class="self-center w-fit text-sm p-1.5 dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
|
||||||
type="button"
|
|
||||||
on:click={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
deleteModelHandler(model);
|
|
||||||
}}
|
}}
|
||||||
|
deleteHandler={() => {
|
||||||
|
selectedModel = model;
|
||||||
|
showModelDeleteConfirm = true;
|
||||||
|
}}
|
||||||
|
onClose={() => {}}
|
||||||
>
|
>
|
||||||
<GarbageBin />
|
<div
|
||||||
</button>
|
class="self-center w-fit p-1 text-sm dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||||
</Tooltip>
|
>
|
||||||
|
<EllipsisHorizontal className="size-5" />
|
||||||
|
</div>
|
||||||
|
</ModelMenu>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
on:click={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
content={model.is_active ? $i18n.t('Enabled') : $i18n.t('Disabled')}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
bind:state={model.is_active}
|
||||||
|
on:change={async () => {
|
||||||
|
toggleModelById(localStorage.token, model.id);
|
||||||
|
_models.set(
|
||||||
|
await getModels(
|
||||||
|
localStorage.token,
|
||||||
|
$config?.features?.enable_direct_connections &&
|
||||||
|
($settings?.directConnections ?? null)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=" flex gap-1 pr-2 -mt-1 items-center">
|
||||||
|
<Tooltip
|
||||||
|
content={model?.user?.email ?? $i18n.t('Deleted User')}
|
||||||
|
className="flex shrink-0"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<div class="shrink-0 text-gray-500 text-xs">
|
||||||
|
{$i18n.t('By {{name}}', {
|
||||||
|
name: capitalizeFirstLetter(
|
||||||
|
model?.user?.name ?? model?.user?.email ?? $i18n.t('Deleted User')
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<div>·</div>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
content={marked.parse(model?.meta?.description ?? model.id)}
|
||||||
|
className=" w-fit text-left"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<div class="flex gap-1 text-xs overflow-hidden">
|
||||||
|
<div class="line-clamp-1">
|
||||||
|
{#if (model?.meta?.description ?? '').trim()}
|
||||||
|
{model?.meta?.description}
|
||||||
{:else}
|
{:else}
|
||||||
<ModelMenu
|
{model.id}
|
||||||
user={$user}
|
|
||||||
{model}
|
|
||||||
editHandler={() => {
|
|
||||||
goto(
|
|
||||||
`/workspace/models/edit?id=${encodeURIComponent(model.id)}`
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
shareHandler={() => {
|
|
||||||
shareModelHandler(model);
|
|
||||||
}}
|
|
||||||
cloneHandler={() => {
|
|
||||||
cloneModelHandler(model);
|
|
||||||
}}
|
|
||||||
exportHandler={() => {
|
|
||||||
exportModelHandler(model);
|
|
||||||
}}
|
|
||||||
hideHandler={() => {
|
|
||||||
hideModelHandler(model);
|
|
||||||
}}
|
|
||||||
copyLinkHandler={() => {
|
|
||||||
copyLinkHandler(model);
|
|
||||||
}}
|
|
||||||
deleteHandler={() => {
|
|
||||||
selectedModel = model;
|
|
||||||
showModelDeleteConfirm = true;
|
|
||||||
}}
|
|
||||||
onClose={() => {}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="self-center w-fit p-1 text-sm dark:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
|
||||||
>
|
|
||||||
<EllipsisHorizontal className="size-5" />
|
|
||||||
</div>
|
|
||||||
</ModelMenu>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Tooltip>
|
||||||
|
|
||||||
<button
|
|
||||||
on:click={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Tooltip
|
|
||||||
content={model.is_active ? $i18n.t('Enabled') : $i18n.t('Disabled')}
|
|
||||||
>
|
|
||||||
<Switch
|
|
||||||
bind:state={model.is_active}
|
|
||||||
on:change={async () => {
|
|
||||||
toggleModelById(localStorage.token, model.id);
|
|
||||||
_models.set(
|
|
||||||
await getModels(
|
|
||||||
localStorage.token,
|
|
||||||
$config?.features?.enable_direct_connections &&
|
|
||||||
($settings?.directConnections ?? null)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex gap-1 pr-2 -mt-1 items-center">
|
|
||||||
<Tooltip
|
|
||||||
content={model?.user?.email ?? $i18n.t('Deleted User')}
|
|
||||||
className="flex shrink-0"
|
|
||||||
placement="top-start"
|
|
||||||
>
|
|
||||||
<div class="shrink-0 text-gray-500 text-xs">
|
|
||||||
{$i18n.t('By {{name}}', {
|
|
||||||
name: capitalizeFirstLetter(
|
|
||||||
model?.user?.name ?? model?.user?.email ?? $i18n.t('Deleted User')
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<div>·</div>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
content={marked.parse(model?.meta?.description ?? model.id)}
|
|
||||||
className=" w-fit text-left"
|
|
||||||
placement="top-start"
|
|
||||||
>
|
|
||||||
<div class="flex gap-1 text-xs overflow-hidden">
|
|
||||||
<div class="line-clamp-1">
|
|
||||||
{#if (model?.meta?.description ?? '').trim()}
|
|
||||||
{model?.meta?.description}
|
|
||||||
{:else}
|
|
||||||
{model.id}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
{/each}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if total > 30}
|
{#if total > 30}
|
||||||
<Pagination bind:page count={total} perPage={30} />
|
<Pagination bind:page count={total} perPage={30} />
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class=" w-full h-full flex flex-col justify-center items-center my-16 mb-24">
|
<div class=" w-full h-full flex flex-col justify-center items-center my-16 mb-24">
|
||||||
<div class="max-w-md text-center">
|
<div class="max-w-md text-center">
|
||||||
<div class=" text-3xl mb-3">😕</div>
|
<div class=" text-3xl mb-3">😕</div>
|
||||||
<div class=" text-lg font-medium mb-1">{$i18n.t('No models found')}</div>
|
<div class=" text-lg font-medium mb-1">{$i18n.t('No models found')}</div>
|
||||||
<div class=" text-gray-500 text-center text-xs">
|
<div class=" text-gray-500 text-center text-xs">
|
||||||
{$i18n.t('Try adjusting your search or filter to find what you are looking for.')}
|
{$i18n.t('Try adjusting your search or filter to find what you are looking for.')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<div class="w-full h-full flex justify-center items-center py-10">
|
||||||
|
<Spinner className="size-4" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue