mirror of
https://github.com/open-webui/open-webui
synced 2025-06-03 19:27:12 +00:00
feat: model ordering
This commit is contained in:
parent
9c67a94542
commit
fc2b314c4f
6
package-lock.json
generated
6
package-lock.json
generated
@ -24,6 +24,7 @@
|
||||
"katex": "^0.16.9",
|
||||
"marked": "^9.1.0",
|
||||
"pyodide": "^0.26.0-alpha.4",
|
||||
"sortablejs": "^1.15.2",
|
||||
"svelte-sonner": "^0.3.19",
|
||||
"tippy.js": "^6.3.7",
|
||||
"uuid": "^9.0.1"
|
||||
@ -6913,6 +6914,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/sortablejs": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz",
|
||||
"integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA=="
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
|
@ -64,6 +64,7 @@
|
||||
"katex": "^0.16.9",
|
||||
"marked": "^9.1.0",
|
||||
"pyodide": "^0.26.0-alpha.4",
|
||||
"sortablejs": "^1.15.2",
|
||||
"svelte-sonner": "^0.3.19",
|
||||
"tippy.js": "^6.3.7",
|
||||
"uuid": "^9.0.1"
|
||||
|
@ -29,8 +29,24 @@ export const getModels = async (token: string = '') => {
|
||||
|
||||
models = models
|
||||
.filter((models) => models)
|
||||
// Sort the models
|
||||
.sort((a, b) => {
|
||||
// Compare case-insensitively
|
||||
// Check if models have position property
|
||||
const aHasPosition = a.info?.meta?.position !== undefined;
|
||||
const bHasPosition = b.info?.meta?.position !== undefined;
|
||||
|
||||
// If both a and b have the position property
|
||||
if (aHasPosition && bHasPosition) {
|
||||
return a.info.meta.position - b.info.meta.position;
|
||||
}
|
||||
|
||||
// If only a has the position property, it should come first
|
||||
if (aHasPosition) return -1;
|
||||
|
||||
// If only b has the position property, it should come first
|
||||
if (bHasPosition) return 1;
|
||||
|
||||
// Compare case-insensitively by name for models without position property
|
||||
const lowerA = a.name.toLowerCase();
|
||||
const lowerB = b.name.toLowerCase();
|
||||
|
||||
@ -39,8 +55,8 @@ export const getModels = async (token: string = '') => {
|
||||
|
||||
// If same case-insensitively, sort by original strings,
|
||||
// lowercase will come before uppercase due to ASCII values
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
|
||||
return 0; // They are equal
|
||||
});
|
||||
|
@ -1,9 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Sortable from 'sortablejs';
|
||||
|
||||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { onMount, getContext, tick } from 'svelte';
|
||||
|
||||
import { WEBUI_NAME, modelfiles, models, settings, user } from '$lib/stores';
|
||||
import { addNewModel, deleteModelById, getModelInfos, updateModelById } from '$lib/apis/models';
|
||||
@ -12,6 +14,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import { getModels } from '$lib/apis';
|
||||
|
||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||
import ModelMenu from './Models/ModelMenu.svelte';
|
||||
|
||||
@ -22,6 +25,9 @@
|
||||
let importFiles;
|
||||
let modelsImportInputElement: HTMLInputElement;
|
||||
|
||||
let _models = [];
|
||||
|
||||
let sortable = null;
|
||||
let searchValue = '';
|
||||
|
||||
const deleteModelHandler = async (model) => {
|
||||
@ -42,6 +48,7 @@
|
||||
}
|
||||
|
||||
await models.set(await getModels(localStorage.token));
|
||||
_models = $models;
|
||||
};
|
||||
|
||||
const cloneModelHandler = async (model) => {
|
||||
@ -109,6 +116,7 @@
|
||||
}
|
||||
|
||||
await models.set(await getModels(localStorage.token));
|
||||
_models = $models;
|
||||
};
|
||||
|
||||
const downloadModels = async (models) => {
|
||||
@ -118,13 +126,58 @@
|
||||
saveAs(blob, `models-export-${Date.now()}.json`);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
const positionChangeHanlder = async () => {
|
||||
// Get the new order of the models
|
||||
const modelIds = Array.from(document.getElementById('model-list').children).map((child) =>
|
||||
child.id.replace('model-item-', '')
|
||||
);
|
||||
|
||||
// Update the position of the models
|
||||
for (const [index, id] of modelIds.entries()) {
|
||||
const model = $models.find((m) => m.id === id);
|
||||
if (model) {
|
||||
let info = model.info;
|
||||
|
||||
if (!info) {
|
||||
info = {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
meta: {
|
||||
position: index
|
||||
},
|
||||
params: {}
|
||||
};
|
||||
}
|
||||
|
||||
info.meta = {
|
||||
...info.meta,
|
||||
position: index
|
||||
};
|
||||
await updateModelById(localStorage.token, info.id, info);
|
||||
}
|
||||
}
|
||||
|
||||
await tick();
|
||||
await models.set(await getModels(localStorage.token));
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
// Legacy code to sync localModelfiles with models
|
||||
_models = $models;
|
||||
localModelfiles = JSON.parse(localStorage.getItem('modelfiles') ?? '[]');
|
||||
|
||||
if (localModelfiles) {
|
||||
console.log(localModelfiles);
|
||||
}
|
||||
|
||||
// SortableJS
|
||||
sortable = new Sortable(document.getElementById('model-list'), {
|
||||
animation: 150,
|
||||
onUpdate: async (event) => {
|
||||
console.log(event);
|
||||
positionChangeHanlder();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -202,12 +255,13 @@
|
||||
|
||||
<hr class=" dark:border-gray-850" />
|
||||
|
||||
<div class=" my-2 mb-5">
|
||||
{#each $models.filter((m) => searchValue === '' || m.name
|
||||
<div class=" my-2 mb-5" id="model-list">
|
||||
{#each _models.filter((m) => searchValue === '' || m.name
|
||||
.toLowerCase()
|
||||
.includes(searchValue.toLowerCase())) as model}
|
||||
<div
|
||||
class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
|
||||
id="model-item-{model.id}"
|
||||
>
|
||||
<a
|
||||
class=" flex flex-1 space-x-3.5 cursor-pointer w-full"
|
||||
|
Loading…
Reference in New Issue
Block a user