forked from open-webui/open-webui
feat: Migrate hardcoded strings to i18n calls
This commit is contained in:
parent
7a77f3c2c0
commit
3c471ee2ca
46 changed files with 492 additions and 381 deletions
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { Confetti } from 'svelte-confetti';
|
||||
|
||||
import { WEBUI_NAME, config } from '$lib/stores';
|
||||
|
@ -9,6 +9,8 @@
|
|||
|
||||
import Modal from './common/Modal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
|
||||
let changelog = null;
|
||||
|
@ -45,7 +47,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="flex items-center mt-1">
|
||||
<div class="text-sm dark:text-gray-200">Release Notes</div>
|
||||
<div class="text-sm dark:text-gray-200">{$i18n.t('Release Notes')}</div>
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="text-sm dark:text-gray-200">
|
||||
v{WEBUI_VERSION}
|
||||
|
@ -108,7 +110,7 @@
|
|||
}}
|
||||
class=" px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-gray-100 transition rounded"
|
||||
>
|
||||
<span class="relative">Okay, Let's Go!</span>
|
||||
<span class="relative">{$i18n.t("Okay, Let's Go!")}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
import { toast } from 'svelte-sonner';
|
||||
import dayjs from 'dayjs';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { updateUserById } from '$lib/apis/users';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let show = false;
|
||||
|
@ -42,7 +43,7 @@
|
|||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Edit User</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Edit User')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -93,7 +94,7 @@
|
|||
|
||||
<div class=" flex flex-col space-y-1.5">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Email</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -108,7 +109,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Name</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Name')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -122,7 +123,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">New Password</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('New Password')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { downloadDatabase } from '$lib/apis/utils';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveHandler: Function;
|
||||
|
||||
|
@ -17,10 +19,10 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">Database</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Database')}</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<!-- <div class=" self-center text-xs font-medium">Allow Chat Deletion</div> -->
|
||||
<!-- <div class=" self-center text-xs font-medium">{$i18n.t('Allow Chat Deletion')}</div> -->
|
||||
|
||||
<button
|
||||
class=" flex rounded-md py-1.5 px-3 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
|
||||
|
@ -46,7 +48,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Download Database</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Download Database')}</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
updateDefaultUserRole,
|
||||
updateJWTExpiresDuration
|
||||
} from '$lib/apis/auths';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveHandler: Function;
|
||||
let signUpEnabled = true;
|
||||
|
@ -43,10 +45,10 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">General Settings</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('General Settings')}</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Enable New Sign Ups</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Enable New Sign Ups')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -66,7 +68,7 @@
|
|||
d="M11.5 1A3.5 3.5 0 0 0 8 4.5V7H2.5A1.5 1.5 0 0 0 1 8.5v5A1.5 1.5 0 0 0 2.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 9.5 7V4.5a2 2 0 1 1 4 0v1.75a.75.75 0 0 0 1.5 0V4.5A3.5 3.5 0 0 0 11.5 1Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="ml-2 self-center">Enabled</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Enabled')}</span>
|
||||
{:else}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -81,13 +83,13 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<span class="ml-2 self-center">Disabled</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Disabled')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Default User Role</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Default User Role')}</div>
|
||||
<div class="flex items-center relative">
|
||||
<select
|
||||
class="w-fit pr-8 rounded py-2 px-2 text-xs bg-transparent outline-none text-right"
|
||||
|
@ -97,9 +99,9 @@
|
|||
updateDefaultUserRoleHandler(e.target.value);
|
||||
}}
|
||||
>
|
||||
<option value="pending">Pending</option>
|
||||
<option value="user">User</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="pending">{$i18n.t('Pending')}</option>
|
||||
<option value="user">{$i18n.t('User')}</option>
|
||||
<option value="admin">{$i18n.t('Admin')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -108,7 +110,7 @@
|
|||
|
||||
<div class=" w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">JWT Expiration</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('JWT Expiration')}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex mt-2 space-x-2">
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { getSignUpEnabledStatus, toggleSignUpEnabledStatus } from '$lib/apis/auths';
|
||||
import { getUserPermissions, updateUserPermissions } from '$lib/apis/users';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveHandler: Function;
|
||||
|
||||
|
@ -26,10 +28,10 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">User Permissions</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('User Permissions')}</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Allow Chat Deletion</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Allow Chat Deletion')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -49,7 +51,7 @@
|
|||
d="M11.5 1A3.5 3.5 0 0 0 8 4.5V7H2.5A1.5 1.5 0 0 0 1 8.5v5A1.5 1.5 0 0 0 2.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 9.5 7V4.5a2 2 0 1 1 4 0v1.75a.75.75 0 0 0 1.5 0V4.5A3.5 3.5 0 0 0 11.5 1Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="ml-2 self-center">Allow</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Allow')}</span>
|
||||
{:else}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -64,7 +66,7 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<span class="ml-2 self-center">Don't Allow</span>
|
||||
<span class="ml-2 self-center">{$i18n.t("Don't Allow")}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
import Database from './Settings/Database.svelte';
|
||||
|
||||
import General from './Settings/General.svelte';
|
||||
import Users from './Settings/Users.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
|
||||
let selectedTab = 'general';
|
||||
|
@ -13,7 +16,7 @@
|
|||
<Modal bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Admin Settings</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Admin Settings')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -61,7 +64,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">General</div>
|
||||
<div class=" self-center">{$i18n.t('General')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -85,7 +88,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Users</div>
|
||||
<div class=" self-center">{$i18n.t('Users')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -113,7 +116,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Database</div>
|
||||
<div class=" self-center">{$i18n.t('Database')}</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 md:min-h-[380px]">
|
||||
|
|
|
@ -220,7 +220,7 @@
|
|||
isRecording = false;
|
||||
};
|
||||
} else {
|
||||
toast.error('SpeechRecognition API is not supported in this browser.');
|
||||
toast.error($i18n.t('SpeechRecognition API is not supported in this browser.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,12 +341,15 @@
|
|||
uploadDoc(file);
|
||||
} else {
|
||||
toast.error(
|
||||
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
|
||||
$i18n.t(
|
||||
`Unknown File Type '{{file_type}}', but accepting and treating as plain text`,
|
||||
{ file_type: file['type'] }
|
||||
)
|
||||
);
|
||||
uploadDoc(file);
|
||||
}
|
||||
} else {
|
||||
toast.error(`File not found.`);
|
||||
toast.error($i18n.t(`File not found.`));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,13 +488,16 @@
|
|||
filesInputElement.value = '';
|
||||
} else {
|
||||
toast.error(
|
||||
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
|
||||
$i18n.t(
|
||||
`Unknown File Type '{{file_type}}', but accepting and treating as plain text`,
|
||||
{ file_type: file['type'] }
|
||||
)
|
||||
);
|
||||
uploadDoc(file);
|
||||
filesInputElement.value = '';
|
||||
}
|
||||
} else {
|
||||
toast.error(`File not found.`);
|
||||
toast.error($i18n.t(`File not found.`));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -578,7 +584,7 @@
|
|||
{file.name}
|
||||
</div>
|
||||
|
||||
<div class=" text-gray-500 text-sm">Document</div>
|
||||
<div class=" text-gray-500 text-sm">{$i18n.t('Document')}</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else if file.type === 'collection'}
|
||||
|
@ -606,7 +612,7 @@
|
|||
{file?.title ?? `#${file.name}`}
|
||||
</div>
|
||||
|
||||
<div class=" text-gray-500 text-sm">Collection</div>
|
||||
<div class=" text-gray-500 text-sm">{$i18n.t('Collection')}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -640,7 +646,7 @@
|
|||
<div class=" flex">
|
||||
{#if fileUploadEnabled}
|
||||
<div class=" self-end mb-2 ml-1">
|
||||
<Tooltip content="Upload files">
|
||||
<Tooltip content={$i18n.t('Upload files')}>
|
||||
<button
|
||||
class="bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
|
||||
type="button"
|
||||
|
@ -811,7 +817,7 @@
|
|||
|
||||
<div class="self-end mb-2 flex space-x-1 mr-1">
|
||||
{#if messages.length == 0 || messages.at(-1).done == true}
|
||||
<Tooltip content="Record voice">
|
||||
<Tooltip content={$i18n.t('Record voice')}>
|
||||
{#if speechRecognitionEnabled}
|
||||
<button
|
||||
id="voice-input-button"
|
||||
|
@ -880,7 +886,7 @@
|
|||
{/if}
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Send message">
|
||||
<Tooltip content={$i18n.t('Send message')}>
|
||||
<button
|
||||
class="{prompt !== ''
|
||||
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
|
||||
|
@ -926,7 +932,7 @@
|
|||
</form>
|
||||
|
||||
<div class="mt-1.5 text-xs text-gray-500 text-center">
|
||||
LLMs can make mistakes. Verify important information.
|
||||
{$i18n.t('LLMs can make mistakes. Verify important information.')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
import { documents } from '$lib/stores';
|
||||
import { removeFirstHashWord, isValidHttpUrl } from '$lib/utils';
|
||||
import { tick } from 'svelte';
|
||||
import { tick, getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let prompt = '';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
@ -117,7 +119,7 @@
|
|||
{doc?.title ?? `#${doc.name}`}
|
||||
</div>
|
||||
|
||||
<div class=" text-xs text-gray-600 line-clamp-1">Collection</div>
|
||||
<div class=" text-xs text-gray-600 line-clamp-1">{$i18n.t('Collection')}</div>
|
||||
{:else}
|
||||
<div class=" font-medium text-black line-clamp-1">
|
||||
#{doc.name} ({doc.filename})
|
||||
|
@ -140,7 +142,9 @@
|
|||
confirmSelectWeb(url);
|
||||
} else {
|
||||
toast.error(
|
||||
$i18n.t(
|
||||
'Oops! Looks like the URL is invalid. Please double-check and try again.'
|
||||
)
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
@ -149,7 +153,7 @@
|
|||
{prompt.split(' ')?.at(0)?.substring(1)}
|
||||
</div>
|
||||
|
||||
<div class=" text-xs text-gray-600 line-clamp-1">Web</div>
|
||||
<div class=" text-xs text-gray-600 line-clamp-1">{$i18n.t('Web')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
user = JSON.parse(JSON.stringify(model.name));
|
||||
await tick();
|
||||
|
||||
chatInputPlaceholder = `'${model.name}' is thinking...`;
|
||||
chatInputPlaceholder = $i18n.t('{{modelName}} is thinking...', { modelName: model.name });
|
||||
|
||||
const chatInputElement = document.getElementById('chat-textarea');
|
||||
|
||||
|
@ -111,7 +111,7 @@
|
|||
toast.error(error.error);
|
||||
}
|
||||
} else {
|
||||
toast.error(`Uh-oh! There was an issue connecting to Ollama.`);
|
||||
toast.error($i18n.t('Uh-oh! There was an issue connecting to llama.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { prompts } from '$lib/stores';
|
||||
import { findWordIndices } from '$lib/utils';
|
||||
import { tick } from 'svelte';
|
||||
import { tick, getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let prompt = '';
|
||||
let selectedCommandIdx = 0;
|
||||
let filteredPromptCommands = [];
|
||||
|
@ -29,7 +31,7 @@
|
|||
|
||||
if (command.content.includes('{{CLIPBOARD}}')) {
|
||||
const clipboardText = await navigator.clipboard.readText().catch((err) => {
|
||||
toast.error('Failed to read clipboard contents');
|
||||
toast.error($i18n.t('Failed to read clipboard contents'));
|
||||
return '{{CLIPBOARD}}';
|
||||
});
|
||||
|
||||
|
@ -113,8 +115,9 @@
|
|||
</div>
|
||||
|
||||
<div class="line-clamp-1">
|
||||
Tip: Update multiple variable slots consecutively by pressing the tab key in the chat
|
||||
input after each replacement.
|
||||
{$i18n.t(
|
||||
'Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { chats, config, modelfiles, settings, user } from '$lib/stores';
|
||||
import { tick } from 'svelte';
|
||||
import { tick, getContext } from 'svelte';
|
||||
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { getChatList, updateChatById } from '$lib/apis/chats';
|
||||
|
@ -13,6 +13,8 @@
|
|||
import Spinner from '../common/Spinner.svelte';
|
||||
import { imageGenerations } from '$lib/apis/images';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let chatId = '';
|
||||
export let sendPrompt: Function;
|
||||
export let continueGeneration: Function;
|
||||
|
@ -67,7 +69,7 @@
|
|||
navigator.clipboard.writeText(text).then(
|
||||
function () {
|
||||
console.log('Async: Copying to clipboard was successful!');
|
||||
toast.success('Copying to clipboard was successful!');
|
||||
toast.success($i18n.t('Copying to clipboard was successful!'));
|
||||
},
|
||||
function (err) {
|
||||
console.error('Async: Could not copy text: ', err);
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
import 'katex/dist/katex.min.css';
|
||||
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
@ -355,7 +357,7 @@
|
|||
editMessageConfirmHandler();
|
||||
}}
|
||||
>
|
||||
Save
|
||||
{$i18n.t('Save')}
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -364,7 +366,7 @@
|
|||
cancelEditMessage();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
{$i18n.t('Cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<script lang="ts">
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { tick, createEventDispatcher } from 'svelte';
|
||||
import { tick, createEventDispatcher, getContext } from 'svelte';
|
||||
import Name from './Name.svelte';
|
||||
import ProfileImage from './ProfileImage.svelte';
|
||||
import { modelfiles, settings } from '$lib/stores';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let user;
|
||||
|
@ -123,7 +125,7 @@
|
|||
{file.name}
|
||||
</div>
|
||||
|
||||
<div class=" text-gray-500 text-sm">Document</div>
|
||||
<div class=" text-gray-500 text-sm">{$i18n.t('Document')}</div>
|
||||
</div>
|
||||
</button>
|
||||
{:else if file.type === 'collection'}
|
||||
|
@ -152,7 +154,7 @@
|
|||
{file?.title ?? `#${file.name}`}
|
||||
</div>
|
||||
|
||||
<div class=" text-gray-500 text-sm">Collection</div>
|
||||
<div class=" text-gray-500 text-sm">{$i18n.t('Collection')}</div>
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
@ -179,7 +181,7 @@
|
|||
editMessageConfirmHandler();
|
||||
}}
|
||||
>
|
||||
Save & Submit
|
||||
{$i18n.t('Save & Submit')}
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -188,7 +190,7 @@
|
|||
cancelEditMessage();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
{$i18n.t('Cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
const saveDefaultModel = async () => {
|
||||
const hasEmptyModel = selectedModels.filter((it) => it === '');
|
||||
if (hasEmptyModel.length) {
|
||||
toast.error('Choose a model before saving...');
|
||||
toast.error($i18n.t('Choose a model before saving...'));
|
||||
return;
|
||||
}
|
||||
settings.set({ ...$settings, models: selectedModels });
|
||||
|
@ -22,7 +22,7 @@
|
|||
console.log('setting default models globally');
|
||||
await setDefaultModels(localStorage.token, selectedModels.join(','));
|
||||
}
|
||||
toast.success('Default model updated');
|
||||
toast.success($i18n.t('Default model updated'));
|
||||
};
|
||||
|
||||
$: if (selectedModels.length > 0 && $models.length > 0) {
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
import { WEBUI_VERSION } from '$lib/constants';
|
||||
import { WEBUI_NAME, config, showChangelog } from '$lib/stores';
|
||||
import { compareVersion } from '$lib/utils';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let ollamaVersion = '';
|
||||
|
||||
|
@ -88,7 +90,7 @@
|
|||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Ollama Version</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Ollama Version')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
|
||||
{ollamaVersion ?? 'N/A'}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { user } from '$lib/stores';
|
||||
import { updateUserProfile } from '$lib/apis/auths';
|
||||
|
@ -9,6 +9,8 @@
|
|||
import { getGravatarUrl } from '$lib/apis/utils';
|
||||
import { copyToClipboard } from '$lib/utils';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveHandler: Function;
|
||||
|
||||
let profileImageUrl = '';
|
||||
|
@ -99,7 +101,7 @@
|
|||
}}
|
||||
/>
|
||||
|
||||
<div class=" mb-2.5 text-sm font-medium">Profile</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Profile')}</div>
|
||||
|
||||
<div class="flex space-x-5">
|
||||
<div class="flex flex-col">
|
||||
|
@ -147,7 +149,7 @@
|
|||
|
||||
<div class="flex-1">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Name</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Name')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -168,7 +170,7 @@
|
|||
|
||||
<div class=" w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">JWT Token</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('JWT Token')}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex mt-2">
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { updateUserPassword } from '$lib/apis/auths';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let show = false;
|
||||
let currentPassword = '';
|
||||
let newPassword = '';
|
||||
|
@ -17,7 +20,7 @@
|
|||
);
|
||||
|
||||
if (res) {
|
||||
toast.success('Successfully updated.');
|
||||
toast.success($i18n.t('Successfully updated.'));
|
||||
}
|
||||
|
||||
currentPassword = '';
|
||||
|
@ -40,7 +43,7 @@
|
|||
}}
|
||||
>
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<div class=" font-medium">Change Password</div>
|
||||
<div class=" font-medium">{$i18n.t('Change Password')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -53,7 +56,7 @@
|
|||
{#if show}
|
||||
<div class=" py-2.5 space-y-1.5">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Current Password</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Current Password')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -67,7 +70,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">New Password</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('New Password')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -81,7 +84,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Confirm Password</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Confirm Password')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
||||
import AdvancedParams from './Advanced/AdvancedParams.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import AdvancedParams from './Advanced/AdvancedParams.svelte';
|
||||
export let saveSettings: Function;
|
||||
|
||||
// Advanced
|
||||
|
@ -55,14 +57,14 @@
|
|||
|
||||
<div class="flex flex-col h-full justify-between text-sm">
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div class=" text-sm font-medium">Parameters</div>
|
||||
<div class=" text-sm font-medium">{$i18n.t('Parameters')}</div>
|
||||
|
||||
<AdvancedParams bind:options />
|
||||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div class=" py-1 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Keep Alive</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Keep Alive')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -72,9 +74,9 @@
|
|||
}}
|
||||
>
|
||||
{#if keepAlive === null}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -93,7 +95,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-1 flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-medium">Request Mode</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Request Mode')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -102,7 +104,7 @@
|
|||
}}
|
||||
>
|
||||
{#if requestFormat === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else if requestFormat === 'json'}
|
||||
<!-- <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -114,7 +116,7 @@
|
|||
d="M10 2a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 0110 2zM10 15a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 0110 15zM10 7a3 3 0 100 6 3 3 0 000-6zM15.657 5.404a.75.75 0 10-1.06-1.06l-1.061 1.06a.75.75 0 001.06 1.06l1.06-1.06zM6.464 14.596a.75.75 0 10-1.06-1.06l-1.06 1.06a.75.75 0 001.06 1.06l1.06-1.06zM18 10a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 0118 10zM5 10a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 015 10zM14.596 15.657a.75.75 0 001.06-1.06l-1.06-1.061a.75.75 0 10-1.06 1.06l1.06 1.06zM5.404 6.464a.75.75 0 001.06-1.06l-1.06-1.06a.75.75 0 10-1.061 1.06l1.06 1.06z"
|
||||
/>
|
||||
</svg> -->
|
||||
<span class="ml-2 self-center"> JSON </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' JSON ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let options = {
|
||||
// Advanced
|
||||
seed: 0,
|
||||
|
@ -20,7 +24,7 @@
|
|||
<div class=" space-y-3 text-xs">
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" w-20 text-xs font-medium self-center">Seed</div>
|
||||
<div class=" w-20 text-xs font-medium self-center">{$i18n.t('Seed')}</div>
|
||||
<div class=" flex-1 self-center">
|
||||
<input
|
||||
class="w-full rounded py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none border border-gray-100 dark:border-gray-600"
|
||||
|
@ -36,7 +40,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" w-20 text-xs font-medium self-center">Stop Sequence</div>
|
||||
<div class=" w-20 text-xs font-medium self-center">{$i18n.t('Stop Sequence')}</div>
|
||||
<div class=" flex-1 self-center">
|
||||
<input
|
||||
class="w-full rounded py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none border border-gray-100 dark:border-gray-600"
|
||||
|
@ -51,7 +55,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Temperature</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Temperature')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -61,9 +65,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.temperature === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -97,7 +101,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Mirostat</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Mirostat')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -107,9 +111,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.mirostat === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -143,7 +147,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Mirostat Eta</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Mirostat Eta')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -153,9 +157,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.mirostat_eta === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -189,7 +193,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Mirostat Tau</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Mirostat Tau')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -199,9 +203,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.mirostat_tau === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -235,7 +239,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Top K</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Top K')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -245,9 +249,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.top_k === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -281,7 +285,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Top P</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Top P')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -291,9 +295,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.top_p === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -327,7 +331,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Repeat Penalty</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Repeat Penalty')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -337,9 +341,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.repeat_penalty === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -373,7 +377,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Repeat Last N</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Repeat Last N')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -383,9 +387,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.repeat_last_n === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -419,7 +423,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Tfs Z</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Tfs Z')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -429,9 +433,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.tfs_z === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -465,7 +469,7 @@
|
|||
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Context Length</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Context Length')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -475,9 +479,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.num_ctx === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -510,7 +514,7 @@
|
|||
</div>
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Max Tokens</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Max Tokens')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -520,9 +524,9 @@
|
|||
}}
|
||||
>
|
||||
{#if options.num_predict === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveSettings: Function;
|
||||
|
||||
// Audio
|
||||
|
@ -101,10 +103,10 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div>
|
||||
<div class=" mb-1 text-sm font-medium">STT Settings</div>
|
||||
<div class=" mb-1 text-sm font-medium">{$i18n.t('STT Settings')}</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Speech-to-Text Engine</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Speech-to-Text Engine')}</div>
|
||||
<div class="flex items-center relative">
|
||||
<select
|
||||
class="w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
|
||||
|
@ -119,14 +121,14 @@
|
|||
}
|
||||
}}
|
||||
>
|
||||
<option value="">Default (Web API)</option>
|
||||
<option value="whisper-local">Whisper (Local)</option>
|
||||
<option value="">{$i18n.t('Default (Web API)')}</option>
|
||||
<option value="whisper-local">{$i18n.t('Whisper (Local)')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Conversation Mode</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Conversation Mode')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -136,15 +138,17 @@
|
|||
type="button"
|
||||
>
|
||||
{#if conversationMode === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Auto-send input after 3 sec.</div>
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Auto-send input after 3 sec.')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -154,19 +158,19 @@
|
|||
type="button"
|
||||
>
|
||||
{#if speechAutoSend === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-1 text-sm font-medium">TTS Settings</div>
|
||||
<div class=" mb-1 text-sm font-medium">{$i18n.t('TTS Settings')}</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Text-to-Speech Engine</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Text-to-Speech Engine')}</div>
|
||||
<div class="flex items-center relative">
|
||||
<select
|
||||
class="w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
|
||||
|
@ -182,14 +186,14 @@
|
|||
}
|
||||
}}
|
||||
>
|
||||
<option value="">Default (Web API)</option>
|
||||
<option value="openai">Open AI</option>
|
||||
<option value="">{$i18n.t('Default (Web API)')}</option>
|
||||
<option value="openai">{$i18n.t('Open AI')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Auto-playback response</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Auto-playback response')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -199,9 +203,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if responseAutoPlayback === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -211,7 +215,7 @@
|
|||
|
||||
{#if TTSEngine === ''}
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Voice</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Voice')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<select
|
||||
|
@ -230,7 +234,7 @@
|
|||
</div>
|
||||
{:else if TTSEngine === 'openai'}
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Voice</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Voice')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<select
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
getChatList
|
||||
} from '$lib/apis/chats';
|
||||
import { getImportOrigin, convertOpenAIChats } from '$lib/utils';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveSettings: Function;
|
||||
// Chats
|
||||
let saveChatHistory = true;
|
||||
|
@ -104,7 +106,7 @@
|
|||
class="flex flex-col justify-between rounded-md items-center py-2 px-3.5 w-full transition"
|
||||
>
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-medium">Chat History</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Chat History')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -128,7 +130,7 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<span class="ml-2 self-center"> On </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('On')} </span>
|
||||
{:else}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -146,7 +148,7 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -180,7 +182,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Import Chats</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Import Chats')}</div>
|
||||
</button>
|
||||
<button
|
||||
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
|
||||
|
@ -202,7 +204,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Export Chats</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Export Chats')}</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -288,7 +290,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Delete Chats</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Delete Chats')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
|
@ -316,7 +318,9 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Export All Chats (All Users)</div>
|
||||
<div class=" self-center text-sm font-medium">
|
||||
{$i18n.t('Export All Chats (All Users)')}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<hr class=" dark:border-gray-700" />
|
||||
|
@ -330,7 +334,7 @@
|
|||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Success');
|
||||
toast.success($i18n.t('Success'));
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -348,7 +352,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center text-sm font-medium">Reset Vector Storage</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Reset Vector Storage')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { models, user } from '$lib/stores';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import { getOllamaAPIUrl, getOllamaVersion, updateOllamaAPIUrl } from '$lib/apis/ollama';
|
||||
import { getOpenAIKey, getOpenAIUrl, updateOpenAIKey, updateOpenAIUrl } from '$lib/apis/openai';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let getModels: Function;
|
||||
|
||||
// External
|
||||
|
@ -34,7 +36,7 @@
|
|||
});
|
||||
|
||||
if (ollamaVersion) {
|
||||
toast.success('Server connection verified');
|
||||
toast.success($i18n.t('Server connection verified'));
|
||||
await models.set(await getModels());
|
||||
}
|
||||
};
|
||||
|
@ -64,7 +66,7 @@
|
|||
<div class=" space-y-3">
|
||||
<div class="mt-2 space-y-2 pr-1.5">
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<div class=" font-medium">OpenAI API</div>
|
||||
<div class=" font-medium">{$i18n.t('OpenAI API')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -76,7 +78,7 @@
|
|||
|
||||
{#if showOpenAI}
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">API Key</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('API Key')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -90,7 +92,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">API Base URL</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('API Base URL')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -114,7 +116,7 @@
|
|||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Ollama API URL</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Ollama API URL')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<input
|
||||
|
|
|
@ -91,10 +91,10 @@
|
|||
<div class="flex flex-col h-full justify-between text-sm">
|
||||
<div class=" pr-1.5 overflow-y-scroll max-h-[20.5rem]">
|
||||
<div class="">
|
||||
<div class=" mb-1 text-sm font-medium">WebUI Settings</div>
|
||||
<div class=" mb-1 text-sm font-medium">{$i18n.t('WebUI Settings')}</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Theme</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Theme')}</div>
|
||||
<div class="flex items-center relative">
|
||||
<div class=" absolute right-16">
|
||||
{#if theme === 'dark'}
|
||||
|
@ -146,16 +146,16 @@
|
|||
console.log(theme);
|
||||
}}
|
||||
>
|
||||
<option value="dark">Dark</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="rose-pine dark">Rosé Pine</option>
|
||||
<option value="rose-pine-dawn light">Rosé Pine Dawn</option>
|
||||
<option value="dark">{$i18n.t('Dark')}</option>
|
||||
<option value="light">{$i18n.t('Light')}</option>
|
||||
<option value="rose-pine dark">{$i18n.t('Rosé Pine')}</option>
|
||||
<option value="rose-pine-dawn light">{$i18n.t('Rosé Pine Dawn')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Language</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Language')}</div>
|
||||
<div class="flex items-center relative">
|
||||
<select
|
||||
class="w-fit pr-8 rounded py-2 px-2 text-xs bg-transparent outline-none text-right"
|
||||
|
@ -175,7 +175,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Notification</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Notification')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -185,9 +185,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if notificationEnabled === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -197,7 +197,7 @@
|
|||
<hr class=" dark:border-gray-700 my-3" />
|
||||
|
||||
<div>
|
||||
<div class=" my-2.5 text-sm font-medium">System Prompt</div>
|
||||
<div class=" my-2.5 text-sm font-medium">{$i18n.t('System Prompt')}</div>
|
||||
<textarea
|
||||
bind:value={system}
|
||||
class="w-full rounded p-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
|
||||
|
@ -207,7 +207,7 @@
|
|||
|
||||
<div class="mt-2 space-y-3 pr-1.5">
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<div class=" font-medium">Advanced Parameters</div>
|
||||
<div class=" font-medium">{$i18n.t('Advanced Parameters')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -223,7 +223,7 @@
|
|||
|
||||
<div class=" py-1 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Keep Alive</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Keep Alive')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -233,9 +233,9 @@
|
|||
}}
|
||||
>
|
||||
{#if keepAlive === null}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -254,7 +254,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-1 flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-medium">Request Mode</div>
|
||||
<div class=" self-center text-sm font-medium">{$i18n.t('Request Mode')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -263,7 +263,7 @@
|
|||
}}
|
||||
>
|
||||
{#if requestFormat === ''}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
|
||||
{:else if requestFormat === 'json'}
|
||||
<!-- <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -275,7 +275,7 @@
|
|||
d="M10 2a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 0110 2zM10 15a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 0110 15zM10 7a3 3 0 100 6 3 3 0 000-6zM15.657 5.404a.75.75 0 10-1.06-1.06l-1.061 1.06a.75.75 0 001.06 1.06l1.06-1.06zM6.464 14.596a.75.75 0 10-1.06-1.06l-1.06 1.06a.75.75 0 001.06 1.06l1.06-1.06zM18 10a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 0118 10zM5 10a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 015 10zM14.596 15.657a.75.75 0 001.06-1.06l-1.06-1.061a.75.75 0 10-1.06 1.06l1.06 1.06zM5.404 6.464a.75.75 0 001.06-1.06l-1.06-1.06a.75.75 0 10-1.061 1.06l1.06 1.06z"
|
||||
/>
|
||||
</svg> -->
|
||||
<span class="ml-2 self-center"> JSON </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('JSON')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
await getModels();
|
||||
|
||||
if (models) {
|
||||
toast.success('Server connection verified');
|
||||
toast.success($i18n.t('Server connection verified'));
|
||||
}
|
||||
} else {
|
||||
AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token);
|
||||
|
@ -117,11 +117,13 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-[20.5rem]">
|
||||
<div>
|
||||
<div class=" mb-1 text-sm font-medium">Image Settings</div>
|
||||
<div class=" mb-1 text-sm font-medium">{$i18n.t('Image Settings')}</div>
|
||||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Image Generation (Experimental)</div>
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Image Generation (Experimental)')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -131,9 +133,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if enableImageGeneration === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -141,7 +143,7 @@
|
|||
</div>
|
||||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div class=" mb-2.5 text-sm font-medium">AUTOMATIC1111 Base URL</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('AUTOMATIC1111 Base URL')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<input
|
||||
|
@ -189,7 +191,7 @@
|
|||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Default Model</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Default Model')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<select
|
||||
|
@ -211,7 +213,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Image Size</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Image Size')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<input
|
||||
|
@ -224,7 +226,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Steps</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Steps')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<input
|
||||
|
|
|
@ -96,11 +96,11 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll h-80">
|
||||
<div>
|
||||
<div class=" mb-1 text-sm font-medium">WebUI Add-ons</div>
|
||||
<div class=" mb-1 text-sm font-medium">{$i18n.t('WebUI Add-ons')}</div>
|
||||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Title Auto-Generation</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Title Auto-Generation')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -110,9 +110,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if titleAutoGenerate === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -120,7 +120,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Response AutoCopy to Clipboard</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Response AutoCopy to Clipboard')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -130,9 +130,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if responseAutoCopy === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -140,7 +140,7 @@
|
|||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Full Screen Mode</div>
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Full Screen Mode')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -150,9 +150,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if fullScreenMode === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -172,9 +172,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if showUsername === true}
|
||||
<span class="ml-2 self-center">On</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">Off</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -184,7 +184,7 @@
|
|||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Set Title Auto-Generation Model</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Title Auto-Generation Model')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<select
|
||||
|
@ -227,7 +227,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<div class=" mb-2.5 text-sm font-medium">Title Generation Prompt</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Title Generation Prompt')}</div>
|
||||
<textarea
|
||||
bind:value={titleGenerationPrompt}
|
||||
class="w-full rounded p-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
|
||||
|
@ -241,7 +241,7 @@
|
|||
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">Default Prompt Suggestions</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Default Prompt Suggestions')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
if (!data.success) {
|
||||
toast.error(data.error);
|
||||
} else {
|
||||
toast.success(`Model '${modelName}' has been successfully downloaded.`);
|
||||
toast.success($i18n.t(`Model '${modelName}' has been successfully downloaded.`));
|
||||
|
||||
const notification = new Notification($WEBUI_NAME, {
|
||||
body: `Model '${modelName}' has been successfully downloaded.`,
|
||||
|
@ -243,7 +243,7 @@
|
|||
});
|
||||
|
||||
if (res) {
|
||||
toast.success(`Deleted ${deleteModelTag}`);
|
||||
toast.success($i18n.t(`Deleted ${deleteModelTag}`));
|
||||
}
|
||||
|
||||
deleteModelTag = '';
|
||||
|
@ -372,7 +372,7 @@
|
|||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">Manage Ollama Models</div>
|
||||
|
||||
<div class=" mb-2 text-sm font-medium">Pull a model from Ollama.com</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Pull a model from Ollama.com')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<input
|
||||
|
@ -436,7 +436,7 @@
|
|||
To access the available model names for downloading, <a
|
||||
class=" text-gray-500 dark:text-gray-300 font-medium underline"
|
||||
href="https://ollama.com/library"
|
||||
target="_blank">click here.</a
|
||||
target="_blank">{$i18n.t('click here.')}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
|
@ -461,7 +461,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">Delete a model</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Delete a model')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<select
|
||||
|
@ -503,7 +503,7 @@
|
|||
|
||||
<div>
|
||||
<div class="flex justify-between items-center text-xs">
|
||||
<div class=" text-sm font-medium">Experimental</div>
|
||||
<div class=" text-sm font-medium">{$i18n.t('Experimental')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -521,7 +521,7 @@
|
|||
}}
|
||||
>
|
||||
<div class=" mb-2 flex w-full justify-between">
|
||||
<div class=" text-sm font-medium">Upload a GGUF model</div>
|
||||
<div class=" text-sm font-medium">{$i18n.t('Upload a GGUF model')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -535,9 +535,9 @@
|
|||
type="button"
|
||||
>
|
||||
{#if modelUploadMode === 'file'}
|
||||
<span class="ml-2 self-center">File Mode</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('File Mode')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">URL Mode</span>
|
||||
<span class="ml-2 self-center">{$i18n.t('URL Mode')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -642,7 +642,7 @@
|
|||
{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
|
||||
<div>
|
||||
<div>
|
||||
<div class=" my-2.5 text-sm font-medium">Modelfile Content</div>
|
||||
<div class=" my-2.5 text-sm font-medium">{$i18n.t('Modelfile Content')}</div>
|
||||
<textarea
|
||||
bind:value={modelFileContent}
|
||||
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
|
||||
|
@ -655,13 +655,13 @@
|
|||
To access the GGUF models available for downloading, <a
|
||||
class=" text-gray-500 dark:text-gray-300 font-medium underline"
|
||||
href="https://huggingface.co/models?search=gguf"
|
||||
target="_blank">click here.</a
|
||||
target="_blank">{$i18n.t('click here.')}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if uploadProgress !== null}
|
||||
<div class="mt-2">
|
||||
<div class=" mb-2 text-xs">Upload Progress</div>
|
||||
<div class=" mb-2 text-xs">{$i18n.t('Upload Progress')}</div>
|
||||
|
||||
<div class="w-full rounded-full dark:bg-gray-800">
|
||||
<div
|
||||
|
@ -685,11 +685,11 @@
|
|||
<div class=" space-y-3">
|
||||
<div class="mt-2 space-y-3 pr-1.5">
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">Manage LiteLLM Models</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Manage LiteLLM Models')}</div>
|
||||
|
||||
<div>
|
||||
<div class="flex justify-between items-center text-xs">
|
||||
<div class=" text-sm font-medium">Add a model</div>
|
||||
<div class=" text-sm font-medium">{$i18n.t('Add a model')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -732,7 +732,7 @@
|
|||
|
||||
{#if showLiteLLMParams}
|
||||
<div>
|
||||
<div class=" mb-1.5 text-sm font-medium">Model Name</div>
|
||||
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('Model Name')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -746,7 +746,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-1.5 text-sm font-medium">API Base URL</div>
|
||||
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('API Base URL')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -760,7 +760,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-1.5 text-sm font-medium">API Key</div>
|
||||
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('API Key')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -774,7 +774,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm font-medium">API RPM</div>
|
||||
<div class="mb-1.5 text-sm font-medium">{$i18n.t('API RPM')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -801,7 +801,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Delete a model</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Delete a model')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1 mr-2">
|
||||
<select
|
||||
|
@ -810,8 +810,7 @@
|
|||
placeholder={$i18n.t('Select a model')}
|
||||
>
|
||||
{#if !deleteLiteLLMModelId}
|
||||
<option value="" disabled selected>{$i18n.t('Select a model')}</option
|
||||
>
|
||||
<option value="" disabled selected>{$i18n.t('Select a model')}</option>
|
||||
{/if}
|
||||
{#each liteLLMModelInfo as model}
|
||||
<option value={model.model_info.id} class="bg-gray-100 dark:bg-gray-700"
|
||||
|
@ -846,7 +845,7 @@
|
|||
|
||||
<!-- <div class="mt-2 space-y-3 pr-1.5">
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">Add LiteLLM Model</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Add LiteLLM Model')}</div>
|
||||
<div class="flex w-full mb-2">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -859,7 +858,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<div class=" font-medium">Advanced Model Params</div>
|
||||
<div class=" font-medium">{$i18n.t('Advanced Model Params')}</div>
|
||||
<button
|
||||
class=" text-xs font-medium text-gray-500"
|
||||
type="button"
|
||||
|
@ -871,7 +870,7 @@
|
|||
|
||||
{#if showLiteLLMParams}
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">LiteLLM API Key</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('LiteLLM API Key')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -885,7 +884,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">LiteLLM API Base URL</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('LiteLLM API Base URL')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -899,7 +898,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">LiteLLM API RPM</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('LiteLLM API RPM')}</div>
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { models, settings, user } from '$lib/stores';
|
||||
|
||||
|
@ -17,6 +18,8 @@
|
|||
import Connections from './Settings/Connections.svelte';
|
||||
import Images from './Settings/Images.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
|
||||
const saveSettings = async (updated) => {
|
||||
|
@ -58,7 +61,7 @@
|
|||
<Modal bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Settings</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Settings')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -106,7 +109,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">General</div>
|
||||
<div class=" self-center">{$i18n.t('General')}</div>
|
||||
</button>
|
||||
|
||||
{#if $user?.role === 'admin'}
|
||||
|
@ -131,7 +134,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Connections</div>
|
||||
<div class=" self-center">{$i18n.t('Connections')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -157,7 +160,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Models</div>
|
||||
<div class=" self-center">{$i18n.t('Models')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
|
@ -184,7 +187,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Interface</div>
|
||||
<div class=" self-center">{$i18n.t('Interface')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -211,7 +214,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Audio</div>
|
||||
<div class=" self-center">{$i18n.t('Audio')}</div>
|
||||
</button>
|
||||
|
||||
{#if $user.role === 'admin'}
|
||||
|
@ -238,7 +241,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Images</div>
|
||||
<div class=" self-center">{$i18n.t('Images')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
|
@ -265,7 +268,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Chats</div>
|
||||
<div class=" self-center">{$i18n.t('Chats')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -291,7 +294,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">Account</div>
|
||||
<div class=" self-center">{$i18n.t('Account')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
@ -317,7 +320,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">About</div>
|
||||
<div class=" self-center">{$i18n.t('About')}</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 md:min-h-[380px]">
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let downloadChat: Function;
|
||||
export let shareChat: Function;
|
||||
|
||||
|
@ -17,11 +20,11 @@
|
|||
show = false;
|
||||
}}
|
||||
>
|
||||
Share to OpenWebUI Community
|
||||
{$i18n.t('Share to OpenWebUI Community')}
|
||||
</button>
|
||||
|
||||
<div class="flex justify-center space-x-1 mt-1.5">
|
||||
<div class=" self-center text-gray-400 text-xs font-medium">or</div>
|
||||
<div class=" self-center text-gray-400 text-xs font-medium">{$i18n.t('or')}</div>
|
||||
|
||||
<button
|
||||
class=" self-center rounded-full text-xs font-medium text-gray-700 dark:text-gray-500 underline"
|
||||
|
@ -31,7 +34,7 @@
|
|||
show = false;
|
||||
}}
|
||||
>
|
||||
Download as a File
|
||||
{$i18n.t('Download as a File')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
</script>
|
||||
|
||||
<Modal bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Keyboard shortcuts</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Keyboard shortcuts')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -32,7 +35,7 @@
|
|||
<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
|
||||
<div class="flex flex-col space-y-3 w-full self-start">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Open new chat</div>
|
||||
<div class=" text-sm">{$i18n.t('Open new chat')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -56,7 +59,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Focus chat input</div>
|
||||
<div class=" text-sm">{$i18n.t('Focus chat input')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -74,7 +77,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Copy last code block</div>
|
||||
<div class=" text-sm">{$i18n.t('Copy last code block')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -98,7 +101,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Copy last response</div>
|
||||
<div class=" text-sm">{$i18n.t('Copy last response')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -124,7 +127,7 @@
|
|||
|
||||
<div class="flex flex-col space-y-3 w-full self-start">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Toggle settings</div>
|
||||
<div class=" text-sm">{$i18n.t('Toggle settings')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -141,7 +144,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Toggle sidebar</div>
|
||||
<div class=" text-sm">{$i18n.t('Toggle sidebar')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -165,7 +168,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Delete chat</div>
|
||||
<div class=" text-sm">{$i18n.t('Delete chat')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
@ -188,7 +191,7 @@
|
|||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class=" text-sm">Show shortcuts</div>
|
||||
<div class=" text-sm">{$i18n.t('Show shortcuts')}</div>
|
||||
|
||||
<div class="flex space-x-1 text-xs">
|
||||
<div
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import dayjs from 'dayjs';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { createNewDoc, getDocs, tagDocByName, updateDocByName } from '$lib/apis/documents';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
|
@ -13,6 +13,8 @@
|
|||
import { transformFileName } from '$lib/utils';
|
||||
import { SUPPORTED_FILE_EXTENSIONS, SUPPORTED_FILE_TYPE } from '$lib/constants';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
export let selectedDoc;
|
||||
|
||||
|
@ -96,7 +98,7 @@
|
|||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Add Docs</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Add Docs')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -145,7 +147,7 @@
|
|||
|
||||
<div class=" flex flex-col space-y-1.5">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1.5 text-xs text-gray-500">Tags</div>
|
||||
<div class=" mb-1.5 text-xs text-gray-500">{$i18n.t('Tags')}</div>
|
||||
|
||||
<Tags {tags} addTag={addTagHandler} deleteTag={deleteTagHandler} />
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import dayjs from 'dayjs';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { getDocs, tagDocByName, updateDocByName } from '$lib/apis/documents';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
|
@ -10,6 +10,8 @@
|
|||
import Tags from '../common/Tags.svelte';
|
||||
import { addTagById } from '$lib/apis/chats';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
export let selectedDoc;
|
||||
|
||||
|
@ -74,7 +76,7 @@
|
|||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Edit Doc</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Edit Doc')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -105,7 +107,7 @@
|
|||
>
|
||||
<div class=" flex flex-col space-y-1.5">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Name Tag</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Name Tag')}</div>
|
||||
|
||||
<div class="flex flex-1">
|
||||
<div
|
||||
|
@ -134,7 +136,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1 text-xs text-gray-500">Title</div>
|
||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Title')}</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<input
|
||||
|
@ -148,7 +150,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full">
|
||||
<div class=" mb-1.5 text-xs text-gray-500">Tags</div>
|
||||
<div class=" mb-1.5 text-xs text-gray-500">{$i18n.t('Tags')}</div>
|
||||
|
||||
<Tags {tags} addTag={addTagHandler} deleteTag={deleteTagHandler} />
|
||||
</div>
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
updateRAGTemplate
|
||||
} from '$lib/apis/rag';
|
||||
import { documents } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveHandler: Function;
|
||||
|
||||
let loading = false;
|
||||
|
@ -27,7 +29,7 @@
|
|||
|
||||
if (res) {
|
||||
await documents.set(await getDocs(localStorage.token));
|
||||
toast.success('Scan complete!');
|
||||
toast.success($i18n.t('Scan complete!'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -57,10 +59,12 @@
|
|||
>
|
||||
<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">General Settings</div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('General Settings')}</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">Scan for documents from '/data/docs'</div>
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Scan for documents from {{path}}', { path: '/data/docs' })}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class=" self-center text-xs p-1 px-3 bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 rounded flex flex-row space-x-1 items-center {loading
|
||||
|
@ -73,7 +77,7 @@
|
|||
type="button"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class="self-center font-medium">Scan</div>
|
||||
<div class="self-center font-medium">{$i18n.t('Scan')}</div>
|
||||
|
||||
<!-- <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -122,11 +126,11 @@
|
|||
<hr class=" dark:border-gray-700" />
|
||||
|
||||
<div class=" ">
|
||||
<div class=" text-sm font-medium">Chunk Params</div>
|
||||
<div class=" text-sm font-medium">{$i18n.t('Chunk Params')}</div>
|
||||
|
||||
<div class=" flex">
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class="self-center text-xs font-medium min-w-fit">Chunk Size</div>
|
||||
<div class="self-center text-xs font-medium min-w-fit">{$i18n.t('Chunk Size')}</div>
|
||||
|
||||
<div class="self-center p-3">
|
||||
<input
|
||||
|
@ -141,7 +145,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class=" self-center text-xs font-medium min-w-fit">Chunk Overlap</div>
|
||||
<div class=" self-center text-xs font-medium min-w-fit">{$i18n.t('Chunk Overlap')}</div>
|
||||
|
||||
<div class="self-center p-3">
|
||||
<input
|
||||
|
@ -157,7 +161,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium">RAG Template</div>
|
||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('RAG Template')}</div>
|
||||
<textarea
|
||||
bind:value={template}
|
||||
class="w-full rounded p-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
import General from './Settings/General.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
|
||||
let selectedTab = 'general';
|
||||
|
@ -10,7 +13,7 @@
|
|||
<Modal bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||
<div class=" text-lg font-medium self-center">Document Settings</div>
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Document Settings')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
|
@ -58,7 +61,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">General</div>
|
||||
<div class=" self-center">{$i18n.t('General')}</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 md:min-h-[380px]">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
@ -9,6 +10,8 @@
|
|||
import TagInput from '../common/Tags/TagInput.svelte';
|
||||
import Tags from '../common/Tags.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let initNewChat: Function;
|
||||
export let title: string = $WEBUI_NAME;
|
||||
export let shareEnabled: boolean = false;
|
||||
|
@ -26,7 +29,7 @@
|
|||
const chat = (await getChatById(localStorage.token, $chatId)).chat;
|
||||
console.log('share', chat);
|
||||
|
||||
toast.success('Redirecting you to OpenWebUI Community');
|
||||
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
||||
const url = 'https://openwebui.com';
|
||||
// const url = 'http://localhost:5173';
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
import { goto, invalidateAll } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { user, chats, settings, showSettings, chatId, tags } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { getContext } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
@ -201,7 +200,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex self-center">
|
||||
<div class=" self-center font-medium text-sm">Prompts</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Prompts')}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -229,7 +228,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex self-center">
|
||||
<div class=" self-center font-medium text-sm">Documents</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Documents')}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -239,7 +238,7 @@
|
|||
{#if !($settings.saveChatHistory ?? true)}
|
||||
<div class="absolute z-40 w-full h-full bg-black/90 flex justify-center">
|
||||
<div class=" text-left px-5 py-2">
|
||||
<div class=" font-medium">Chat History is off for this browser.</div>
|
||||
<div class=" font-medium">{$i18n.t('Chat History is off for this browser.')}</div>
|
||||
<div class="text-xs mt-2">
|
||||
When history is turned off, new chats on this browser won't appear in your history on
|
||||
any of your devices. <span class=" font-semibold"
|
||||
|
@ -596,7 +595,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium">Admin Panel</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Admin Panel')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
|
@ -628,7 +627,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium">Settings</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Settings')}</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -662,7 +661,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium">Sign Out</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Sign Out')}</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
import { openDB, deleteDB } from 'idb';
|
||||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import { getOllamaModels, getOllamaVersion } from '$lib/apis/ollama';
|
||||
|
@ -35,6 +35,8 @@
|
|||
import ShortcutsModal from '$lib/components/chat/ShortcutsModal.svelte';
|
||||
import ChangelogModal from '$lib/components/ChangelogModal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let ollamaVersion = '';
|
||||
let loaded = false;
|
||||
|
||||
|
@ -266,12 +268,14 @@
|
|||
</div>
|
||||
|
||||
<div class=" mt-4 text-center text-sm dark:text-gray-200 w-full">
|
||||
Saving chat logs directly to your browser's storage is no longer supported. Please
|
||||
take a moment to download and delete your chat logs by clicking the button below.
|
||||
Don't worry, you can easily re-import your chat logs to the backend through <span
|
||||
class="font-semibold dark:text-white">Settings > Chats > Import Chats</span
|
||||
>. This ensures that your valuable conversations are securely saved to your backend
|
||||
database. Thank you!
|
||||
{$i18n.t(
|
||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through"
|
||||
)}
|
||||
<span class="font-semibold dark:text-white"
|
||||
>{$i18n.t('Settings')} > {$i18n.t('Chats')} > {$i18n.t('Import Chats')}</span
|
||||
>. {$i18n.t(
|
||||
'This ensures that your valuable conversations are securely saved to your backend database. Thank you!'
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div class=" mt-6 mx-auto relative group w-fit">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||
import { WEBUI_NAME, config, user } from '$lib/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
|||
import EditUserModal from '$lib/components/admin/EditUserModal.svelte';
|
||||
import SettingsModal from '$lib/components/admin/SettingsModal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loaded = false;
|
||||
let users = [];
|
||||
|
||||
|
@ -37,7 +39,7 @@
|
|||
});
|
||||
if (res) {
|
||||
users = await getUsers(localStorage.token);
|
||||
toast.success('Successfully updated');
|
||||
toast.success($i18n.t('Successfully updated'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -115,7 +117,7 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<div class=" text-xs">Admin Settings</div>
|
||||
<div class=" text-xs">{$i18n.t('Admin Settings')}</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,10 +133,10 @@
|
|||
class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"
|
||||
>
|
||||
<tr>
|
||||
<th scope="col" class="px-3 py-2"> Role </th>
|
||||
<th scope="col" class="px-3 py-2"> Name </th>
|
||||
<th scope="col" class="px-3 py-2"> Email </th>
|
||||
<th scope="col" class="px-3 py-2"> Action </th>
|
||||
<th scope="col" class="px-3 py-2"> {$i18n.t('Role')} </th>
|
||||
<th scope="col" class="px-3 py-2"> {$i18n.t('Name')} </th>
|
||||
<th scope="col" class="px-3 py-2"> {$i18n.t('Email')} </th>
|
||||
<th scope="col" class="px-3 py-2"> {$i18n.t('Action')} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { WEBUI_NAME, documents } from '$lib/stores';
|
||||
import { createNewDoc, deleteDocByName, getDocs } from '$lib/apis/documents';
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
|||
import AddFilesPlaceholder from '$lib/components/AddFilesPlaceholder.svelte';
|
||||
import SettingsModal from '$lib/components/documents/SettingsModal.svelte';
|
||||
import AddDocModal from '$lib/components/documents/AddDocModal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let importFiles = '';
|
||||
|
||||
let inputFiles = '';
|
||||
|
@ -188,7 +191,7 @@
|
|||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
|
||||
<div class="mb-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class=" text-2xl font-semibold self-center">My Documents</div>
|
||||
<div class=" text-2xl font-semibold self-center">{$i18n.t('My Documents')}</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
|
@ -211,7 +214,7 @@
|
|||
/>
|
||||
</svg>
|
||||
|
||||
<div class=" text-xs">Document Settings</div>
|
||||
<div class=" text-xs">{$i18n.t('Document Settings')}</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -274,7 +277,7 @@
|
|||
on:dragleave={onDragLeave}
|
||||
>
|
||||
<div class=" pointer-events-none">
|
||||
<div class="text-center dark:text-white text-2xl font-semibold z-50">Add Files</div>
|
||||
<div class="text-center dark:text-white text-2xl font-semibold z-50">{$i18n.t('Add Files')}</div>
|
||||
|
||||
<div class=" mt-2 text-center text-sm dark:text-gray-200 w-full">
|
||||
Drop any files here to add to my documents
|
||||
|
@ -314,7 +317,7 @@
|
|||
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
|
||||
}}
|
||||
>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">all</div>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">{$i18n.t('all')}</div>
|
||||
</button>
|
||||
|
||||
{#each tags as tag}
|
||||
|
@ -344,7 +347,7 @@
|
|||
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
|
||||
}}
|
||||
>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">add tags</div>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">{$i18n.t('add tags')}</div>
|
||||
</button> -->
|
||||
|
||||
<button
|
||||
|
@ -354,7 +357,9 @@
|
|||
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
|
||||
}}
|
||||
>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">delete</div>
|
||||
<div class=" text-xs font-medium self-center line-clamp-1">
|
||||
{$i18n.t('delete')}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -562,7 +567,7 @@
|
|||
document.getElementById('documents-import-input')?.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Import Documents Mapping</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Documents Mapping')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -589,7 +594,7 @@
|
|||
saveAs(blob, `documents-mapping-export-${Date.now()}.json`);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Export Documents Mapping</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Documents Mapping')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import { WEBUI_NAME, modelfiles, settings, user } from '$lib/stores';
|
||||
import { createModel, deleteModel } from '$lib/apis/ollama';
|
||||
|
@ -14,6 +14,8 @@
|
|||
} from '$lib/apis/modelfiles';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let localModelfiles = [];
|
||||
let importFiles;
|
||||
|
||||
|
@ -23,7 +25,7 @@
|
|||
success = await deleteModel(localStorage.token, tagName);
|
||||
|
||||
if (success) {
|
||||
toast.success(`Deleted ${tagName}`);
|
||||
toast.success($i18n.t(`Deleted {tagName}`, { tagName }));
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -36,7 +38,7 @@
|
|||
};
|
||||
|
||||
const shareModelfile = async (modelfile) => {
|
||||
toast.success('Redirecting you to OpenWebUI Community');
|
||||
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
||||
|
||||
const url = 'https://openwebui.com';
|
||||
|
||||
|
@ -78,7 +80,7 @@
|
|||
<div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
|
||||
<div class="flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
|
||||
<div class=" text-2xl font-semibold mb-3">My Modelfiles</div>
|
||||
<div class=" text-2xl font-semibold mb-3">{$i18n.t('My Modelfiles')}</div>
|
||||
|
||||
<a class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2" href="/modelfiles/create">
|
||||
<div class=" self-center w-10">
|
||||
|
@ -101,8 +103,8 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">Create a modelfile</div>
|
||||
<div class=" text-sm">Customize Ollama models for a specific purpose</div>
|
||||
<div class=" font-bold">{$i18n.t('Create a modelfile')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Customize Ollama models for a specific purpose')}</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
@ -266,7 +268,7 @@
|
|||
document.getElementById('modelfiles-import-input')?.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Import Modelfiles</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Modelfiles')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -290,7 +292,7 @@
|
|||
saveModelfiles($modelfiles);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Export Modelfiles</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Modelfiles')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -331,7 +333,7 @@
|
|||
await modelfiles.set(await getModelfiles(localStorage.token));
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Sync All</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Sync All')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -382,7 +384,7 @@
|
|||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-2xl font-semibold mb-3">Made by OpenWebUI Community</div>
|
||||
<div class=" text-2xl font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
|
||||
|
@ -409,8 +411,8 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">Discover a modelfile</div>
|
||||
<div class=" text-sm">Discover, download, and explore model presets</div>
|
||||
<div class=" font-bold">{$i18n.t('Discover a modelfile')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Discover, download, and explore model presets')}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
|
||||
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
|
||||
import { splitStream } from '$lib/utils';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
import { createModel } from '$lib/apis/ollama';
|
||||
import { createNewModelfile, getModelfileByTagName, getModelfiles } from '$lib/apis/modelfiles';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loading = false;
|
||||
|
||||
let filesInputElement;
|
||||
|
@ -349,7 +351,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
}}
|
||||
/>
|
||||
|
||||
<div class=" text-2xl font-semibold mb-6">My Modelfiles</div>
|
||||
<div class=" text-2xl font-semibold mb-6">{$i18n.t('My Modelfiles')}</div>
|
||||
|
||||
<button
|
||||
class="flex space-x-1"
|
||||
|
@ -371,7 +373,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium text-sm">Back</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
|
||||
</button>
|
||||
<hr class="my-3 dark:border-gray-700" />
|
||||
|
||||
|
@ -418,7 +420,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
|
||||
<div class="my-2 flex space-x-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">Name*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -431,7 +433,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">Model Tag Name*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Model Tag Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -445,7 +447,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Description*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Description')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -459,7 +461,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">Modelfile</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Modelfile')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -469,9 +471,9 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
}}
|
||||
>
|
||||
{#if raw}
|
||||
<span class="ml-2 self-center"> Raw Format </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Raw Format')} </span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Builder Mode </span>
|
||||
<span class="ml-2 self-center"> {$i18n.t('Builder Mode')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -480,7 +482,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
|
||||
{#if raw}
|
||||
<div class="mt-2">
|
||||
<div class=" text-xs font-semibold mb-2">Content*</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Content')}*</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
|
@ -493,12 +495,13 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="text-xs text-gray-400 dark:text-gray-500">
|
||||
Not sure what to write? Switch to <button
|
||||
{$i18n.t('Not sure what to write? Switch to')}
|
||||
<button
|
||||
class="text-gray-500 dark:text-gray-300 font-medium cursor-pointer"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
raw = !raw;
|
||||
}}>Builder Mode</button
|
||||
}}>{$i18n.t('Builder Mode')}</button
|
||||
>
|
||||
or
|
||||
<a
|
||||
|
@ -506,13 +509,13 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
href="https://openwebui.com"
|
||||
target="_blank"
|
||||
>
|
||||
Click here to check other modelfiles.
|
||||
{$i18n.t('Click here to check other modelfiles.')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="my-2">
|
||||
<div class=" text-xs font-semibold mb-2">From (Base Model)*</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('From (Base Model)')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -524,16 +527,17 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="mt-1 text-xs text-gray-400 dark:text-gray-500">
|
||||
To access the available model names for downloading, <a
|
||||
{$i18n.t('To access the available model names for downloading,')}
|
||||
<a
|
||||
class=" text-gray-500 dark:text-gray-300 font-medium"
|
||||
href="https://ollama.com/library"
|
||||
target="_blank">click here.</a
|
||||
target="_blank">{$i18n.t('click here.')}</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-1">
|
||||
<div class=" text-xs font-semibold mb-2">System Prompt</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('System Prompt')}</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
|
@ -546,7 +550,9 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">Modelfile Advanced Settings</div>
|
||||
<div class=" self-center text-sm font-semibold">
|
||||
{$i18n.t('Modelfile Advanced Settings')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -556,16 +562,16 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
}}
|
||||
>
|
||||
{#if advanced}
|
||||
<span class="ml-2 self-center"> Custom </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Custom ')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> Default </span>
|
||||
<span class="ml-2 self-center">{$i18n.t(' Default ')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if advanced}
|
||||
<div class="my-2">
|
||||
<div class=" text-xs font-semibold mb-2">Template</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Template')}</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
|
@ -578,7 +584,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-xs font-semibold mb-2">Parameters</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Parameters')}</div>
|
||||
|
||||
<div>
|
||||
<AdvancedParams bind:options />
|
||||
|
@ -590,7 +596,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">Prompt suggestions</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -647,7 +653,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Categories</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Categories')}</div>
|
||||
|
||||
<div class="grid grid-cols-4">
|
||||
{#each Object.keys(categories) as category}
|
||||
|
@ -661,7 +667,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
|
||||
{#if pullProgress !== null}
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Pull Progress</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Pull Progress')}</div>
|
||||
<div class="w-full rounded-full dark:bg-gray-800">
|
||||
<div
|
||||
class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
|
||||
|
@ -684,7 +690,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
|||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">Save & Create</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Create')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { toast } from 'svelte-sonner';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
import { settings, user, config, modelfiles } from '$lib/stores';
|
||||
|
@ -14,6 +14,8 @@
|
|||
|
||||
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loading = false;
|
||||
|
||||
let filesInputElement;
|
||||
|
@ -248,7 +250,7 @@
|
|||
}}
|
||||
/>
|
||||
|
||||
<div class=" text-2xl font-semibold mb-6">My Modelfiles</div>
|
||||
<div class=" text-2xl font-semibold mb-6">{$i18n.t('My Modelfiles')}</div>
|
||||
|
||||
<button
|
||||
class="flex space-x-1"
|
||||
|
@ -270,7 +272,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium text-sm">Back</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
|
||||
</button>
|
||||
<hr class="my-3 dark:border-gray-700" />
|
||||
|
||||
|
@ -317,7 +319,7 @@
|
|||
|
||||
<div class="my-2 flex space-x-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">Name*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -330,7 +332,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">Model Tag Name*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Model Tag Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -345,7 +347,7 @@
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Description*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Description')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -359,13 +361,13 @@
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">Modelfile</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Modelfile')}</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class=" text-sm font-semibold mb-2"></div> -->
|
||||
|
||||
<div class="mt-2">
|
||||
<div class=" text-xs font-semibold mb-2">Content*</div>
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Content')}*</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
|
@ -381,7 +383,7 @@
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">Prompt suggestions</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
|
@ -438,7 +440,7 @@
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Categories</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Categories')}</div>
|
||||
|
||||
<div class="grid grid-cols-4">
|
||||
{#each Object.keys(categories) as category}
|
||||
|
@ -453,7 +455,7 @@
|
|||
|
||||
{#if pullProgress !== null}
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Pull Progress</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Pull Progress')}</div>
|
||||
<div class="w-full rounded-full dark:bg-gray-800">
|
||||
<div
|
||||
class="dark:bg-gray-600 text-xs font-medium text-blue-100 text-center p-0.5 leading-none rounded-full"
|
||||
|
@ -476,7 +478,7 @@
|
|||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">Save & Update</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Update')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
|
|
|
@ -3,17 +3,19 @@
|
|||
import fileSaver from 'file-saver';
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { WEBUI_NAME, prompts } from '$lib/stores';
|
||||
import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let importFiles = '';
|
||||
let query = '';
|
||||
|
||||
const sharePrompt = async (prompt) => {
|
||||
toast.success('Redirecting you to OpenWebUI Community');
|
||||
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
||||
|
||||
const url = 'https://openwebui.com';
|
||||
|
||||
|
@ -46,7 +48,7 @@
|
|||
<div class="flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
|
||||
<div class="mb-6 flex justify-between items-center">
|
||||
<div class=" text-2xl font-semibold self-center">My Prompts</div>
|
||||
<div class=" text-2xl font-semibold self-center">{$i18n.t('My Prompts')}</div>
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full space-x-2">
|
||||
|
@ -245,7 +247,7 @@
|
|||
document.getElementById('prompts-import-input')?.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Import Prompts</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Prompts')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -273,7 +275,7 @@
|
|||
saveAs(blob, `prompts-export-${Date.now()}.json`);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">Export Prompts</div>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Prompts')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
@ -302,7 +304,7 @@
|
|||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-2xl font-semibold mb-3">Made by OpenWebUI Community</div>
|
||||
<div class=" text-2xl font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-3 px-3 py-2"
|
||||
|
@ -329,8 +331,8 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">Discover a prompt</div>
|
||||
<div class=" text-sm">Discover, download, and explore custom prompts</div>
|
||||
<div class=" font-bold">{$i18n.t('Discover a prompt')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Discover, download, and explore custom prompts')}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
import { goto } from '$app/navigation';
|
||||
import { prompts } from '$lib/stores';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
|
||||
import { createNewPrompt, getPrompts } from '$lib/apis/prompts';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loading = false;
|
||||
|
||||
// ///////////
|
||||
|
@ -92,7 +94,7 @@
|
|||
<div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
|
||||
<div class=" flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
|
||||
<div class=" text-2xl font-semibold mb-6">My Prompts</div>
|
||||
<div class=" text-2xl font-semibold mb-6">{$i18n.t('My Prompts')}</div>
|
||||
|
||||
<button
|
||||
class="flex space-x-1"
|
||||
|
@ -114,7 +116,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium text-sm">Back</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
|
||||
</button>
|
||||
<hr class="my-3 dark:border-gray-700" />
|
||||
|
||||
|
@ -125,7 +127,7 @@
|
|||
}}
|
||||
>
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Title*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Title')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -138,7 +140,7 @@
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Command*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Command')}*</div>
|
||||
|
||||
<div class="flex items-center mb-1">
|
||||
<div
|
||||
|
@ -168,7 +170,7 @@
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">Prompt Content*</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt Content')}*</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
|
@ -207,7 +209,7 @@
|
|||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">Save & Create</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Create')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
import { goto } from '$app/navigation';
|
||||
import { prompts } from '$lib/stores';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
import { getPrompts, updatePromptByCommand } from '$lib/apis/prompts';
|
||||
import { page } from '$app/stores';
|
||||
|
@ -74,7 +76,7 @@
|
|||
<div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
|
||||
<div class="flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
|
||||
<div class=" text-2xl font-semibold mb-6">My Prompts</div>
|
||||
<div class=" text-2xl font-semibold mb-6">{$i18n.t('My Prompts')}</div>
|
||||
|
||||
<button
|
||||
class="flex space-x-1"
|
||||
|
@ -96,7 +98,7 @@
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center font-medium text-sm">Back</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
|
||||
</button>
|
||||
<hr class="my-3 dark:border-gray-700" />
|
||||
|
||||
|
@ -107,7 +109,7 @@
|
|||
}}
|
||||
>
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Title*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Title')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
|
@ -120,7 +122,7 @@
|
|||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">Command*</div>
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Command')}*</div>
|
||||
|
||||
<div class="flex items-center mb-1">
|
||||
<div
|
||||
|
@ -151,7 +153,7 @@
|
|||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">Prompt Content*</div>
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt Content')}*</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
|
@ -184,7 +186,7 @@
|
|||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">Save & Update</div>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Update')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
import { userSignIn, userSignUp } from '$lib/apis/auths';
|
||||
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
|
||||
import { WEBUI_NAME, config, user } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loaded = false;
|
||||
let mode = 'signin';
|
||||
|
||||
|
@ -16,7 +18,7 @@
|
|||
const setSessionUser = async (sessionUser) => {
|
||||
if (sessionUser) {
|
||||
console.log(sessionUser);
|
||||
toast.success(`You're now logged in.`);
|
||||
toast.success($i18n.t(`You're now logged in.`));
|
||||
localStorage.token = sessionUser.token;
|
||||
await user.set(sessionUser);
|
||||
goto('/');
|
||||
|
@ -109,7 +111,7 @@
|
|||
<div class="flex flex-col mt-4">
|
||||
{#if mode === 'signup'}
|
||||
<div>
|
||||
<div class=" text-sm font-semibold text-left mb-1">Name</div>
|
||||
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Name')}</div>
|
||||
<input
|
||||
bind:value={name}
|
||||
type="text"
|
||||
|
@ -124,7 +126,7 @@
|
|||
{/if}
|
||||
|
||||
<div class="mb-2">
|
||||
<div class=" text-sm font-semibold text-left mb-1">Email</div>
|
||||
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Email')}</div>
|
||||
<input
|
||||
bind:value={email}
|
||||
type="email"
|
||||
|
@ -136,7 +138,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" text-sm font-semibold text-left mb-1">Password</div>
|
||||
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Password')}</div>
|
||||
<input
|
||||
bind:value={password}
|
||||
type="password"
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
import { WEBUI_NAME, config } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loaded = false;
|
||||
|
||||
|
@ -19,22 +21,25 @@
|
|||
<div class="absolute rounded-xl w-full h-full backdrop-blur flex justify-center">
|
||||
<div class="m-auto pb-44 flex flex-col justify-center">
|
||||
<div class="max-w-md">
|
||||
<div class="text-center text-2xl font-medium z-50">{$WEBUI_NAME} Backend Required</div>
|
||||
<div class="text-center text-2xl font-medium z-50">
|
||||
{$i18n.t('{{webui_name}} Backend Required', { webui_name: $WEBUI_NAME })}
|
||||
</div>
|
||||
|
||||
<div class=" mt-4 text-center text-sm w-full">
|
||||
Oops! You're using an unsupported method (frontend only). Please serve the WebUI from
|
||||
the backend.
|
||||
{$i18n.t(
|
||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend."
|
||||
)}
|
||||
|
||||
<br class=" " />
|
||||
<br class=" " />
|
||||
<a
|
||||
class=" font-semibold underline"
|
||||
href="https://github.com/open-webui/open-webui#how-to-install-"
|
||||
target="_blank">See readme.md for instructions</a
|
||||
target="_blank">{$i18n.t('See readme.md for instructions')}</a
|
||||
>
|
||||
or
|
||||
{$i18n.t('or')}
|
||||
<a class=" font-semibold underline" href="https://discord.gg/5rJgQTnV4s" target="_blank"
|
||||
>join our Discord for help.</a
|
||||
>{$i18n.t('join our Discord for help.')}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
|
@ -45,7 +50,7 @@
|
|||
location.href = '/';
|
||||
}}
|
||||
>
|
||||
Check Again
|
||||
{$i18n.t('Check Again')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue