Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
d5dc36b2
Commit
d5dc36b2
authored
Dec 30, 2023
by
Timothy J. Baek
Browse files
feat: delete all user chats
parent
ee8e7c30
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
189 additions
and
123 deletions
+189
-123
backend/apps/web/routers/chats.py
backend/apps/web/routers/chats.py
+20
-0
src/lib/apis/chats/index.ts
src/lib/apis/chats/index.ts
+32
-0
src/lib/components/chat/SettingsModal.svelte
src/lib/components/chat/SettingsModal.svelte
+137
-123
No files found.
backend/apps/web/routers/chats.py
View file @
d5dc36b2
...
@@ -159,3 +159,23 @@ async def delete_chat_by_id(id: str, cred=Depends(bearer_scheme)):
...
@@ -159,3 +159,23 @@ async def delete_chat_by_id(id: str, cred=Depends(bearer_scheme)):
status_code
=
status
.
HTTP_401_UNAUTHORIZED
,
status_code
=
status
.
HTTP_401_UNAUTHORIZED
,
detail
=
ERROR_MESSAGES
.
INVALID_TOKEN
,
detail
=
ERROR_MESSAGES
.
INVALID_TOKEN
,
)
)
############################
# DeleteAllChats
############################
@
router
.
delete
(
"/"
,
response_model
=
bool
)
async
def
delete_all_user_chats
(
cred
=
Depends
(
bearer_scheme
)):
token
=
cred
.
credentials
user
=
Users
.
get_user_by_token
(
token
)
if
user
:
result
=
Chats
.
delete_chats_by_user_id
(
user
.
id
)
return
result
else
:
raise
HTTPException
(
status_code
=
status
.
HTTP_401_UNAUTHORIZED
,
detail
=
ERROR_MESSAGES
.
INVALID_TOKEN
,
)
src/lib/apis/chats/index.ts
View file @
d5dc36b2
...
@@ -191,3 +191,35 @@ export const deleteChatById = async (token: string, id: string) => {
...
@@ -191,3 +191,35 @@ export const deleteChatById = async (token: string, id: string) => {
return
res
;
return
res
;
};
};
export
const
deleteAllChats
=
async
(
token
:
string
)
=>
{
let
error
=
null
;
const
res
=
await
fetch
(
`
${
WEBUI_API_BASE_URL
}
/chats/`
,
{
method
:
'
DELETE
'
,
headers
:
{
Accept
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
...(
token
&&
{
authorization
:
`Bearer
${
token
}
`
})
}
})
.
then
(
async
(
res
)
=>
{
if
(
!
res
.
ok
)
throw
await
res
.
json
();
return
res
.
json
();
})
.
then
((
json
)
=>
{
return
json
;
})
.
catch
((
err
)
=>
{
error
=
err
;
console
.
log
(
err
);
return
null
;
});
if
(
error
)
{
throw
error
;
}
return
res
;
};
src/lib/components/chat/SettingsModal.svelte
View file @
d5dc36b2
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
import { splitStream, getGravatarURL } from '$lib/utils';
import { splitStream, getGravatarURL } from '$lib/utils';
import { getOllamaVersion } from '$lib/apis/ollama';
import { getOllamaVersion } from '$lib/apis/ollama';
import { createNewChat, getAllChats, getChatList } from '$lib/apis/chats';
import { createNewChat,
deleteAllChats,
getAllChats, getChatList } from '$lib/apis/chats';
import {
import {
WEB_UI_VERSION,
WEB_UI_VERSION,
OLLAMA_API_BASE_URL,
OLLAMA_API_BASE_URL,
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
import Advanced from './Settings/Advanced.svelte';
import Advanced from './Settings/Advanced.svelte';
import Modal from '../common/Modal.svelte';
import Modal from '../common/Modal.svelte';
import { updateUserPassword } from '$lib/apis/auths';
import { updateUserPassword } from '$lib/apis/auths';
import { goto } from '$app/navigation';
export let show = false;
export let show = false;
...
@@ -83,7 +84,7 @@
...
@@ -83,7 +84,7 @@
// Chats
// Chats
let importFiles;
let importFiles;
let showDelete
History
Confirm = false;
let showDeleteConfirm = false;
const importChats = async (_chats) => {
const importChats = async (_chats) => {
for (const chat of _chats) {
for (const chat of _chats) {
...
@@ -114,6 +115,12 @@
...
@@ -114,6 +115,12 @@
reader.readAsText(importFiles[0]);
reader.readAsText(importFiles[0]);
}
}
const deleteChats = async () => {
await goto('/');
await deleteAllChats(localStorage.token);
await chats.set(await getChatList(localStorage.token));
};
// Auth
// Auth
let authEnabled = false;
let authEnabled = false;
let authType = 'Basic';
let authType = 'Basic';
...
@@ -1618,147 +1625,154 @@
...
@@ -1618,147 +1625,154 @@
</form>
</form>
{:else if selectedTab === 'chats'}
{:else if selectedTab === 'chats'}
<div class="flex flex-col h-full justify-between space-y-3 text-sm">
<div class="flex flex-col h-full justify-between space-y-3 text-sm">
<div class="flex flex-col">
<div class=" space-y-2">
<input
<div class="flex flex-col">
id="chat-import-input"
<input
bind:files={importFiles}
id="chat-import-input"
type="file"
bind:files={importFiles}
accept=".json"
type="file"
hidden
accept=".json"
/>
hidden
<button
/>
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
<button
on:click={() => {
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
document.getElementById('chat-import-input').click();
on:click={() => {
}}
document.getElementById('chat-import-input').click();
>
}}
<div class=" self-center mr-3">
>
<svg
<div class=" self-center mr-3">
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 9.5a.75.75 0 0 1-.75-.75V8.06l-.72.72a.75.75 0 0 1-1.06-1.06l2-2a.75.75 0 0 1 1.06 0l2 2a.75.75 0 1 1-1.06 1.06l-.72-.72v2.69a.75.75 0 0 1-.75.75Z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center text-sm font-medium">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"
on:click={() => {
exportChats();
}}
>
<div class=" self-center mr-3">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 3.5a.75.75 0 0 1 .75.75v2.69l.72-.72a.75.75 0 1 1 1.06 1.06l-2 2a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 0 1 1.06-1.06l.72.72V6.25A.75.75 0 0 1 8 5.5Z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center text-sm font-medium">Export Chats</div>
</button>
</div>
<!-- {#if showDeleteHistoryConfirm}
<div
class="flex justify-between rounded-md items-center py-3 px-3.5 w-full transition"
>
<div class="flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-5 h-5 mr-3"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
/>
</svg>
<span>Are you sure?</span>
</div>
<div class="flex space-x-1.5 items-center">
<button
class="hover:text-white transition"
on:click={() => {
deleteChatHistory();
showDeleteHistoryConfirm = false;
}}
>
<svg
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0
20 20
"
viewBox="0 0
16 16
"
fill="currentColor"
fill="currentColor"
class="w-4 h-4"
class="w-4 h-4"
>
>
<path
<path
fill-rule="evenodd"
fill-rule="evenodd"
d="M
16.704 4.153a.75.75 0 01.143 1.052l-8 10
.5a.75.75 0 01-
1.127.075l-4.5-4.5
a.75.75 0 0
1
1.06-1.06l
3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z
"
d="M
4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 9
.5a.75.75 0 0
1-
.75-.75V8.06l-.72.72
a.75.75 0 0
1-
1.06-1.06l
2-2a.75.75 0 0 1 1.06 0l2 2a.75.75 0 1 1-1.06 1.06l-.72-.72v2.69a.75.75 0 0 1-.75.75Z
"
clip-rule="evenodd"
clip-rule="evenodd"
/>
/>
</svg>
</svg>
</button>
</div>
<button
<div class=" self-center text-sm font-medium">Import Chats</div>
class="hover:text-white transition"
</button>
on:click={() => {
<button
showDeleteHistoryConfirm = false;
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
}}
on:click={() => {
>
exportChats();
}}
>
<div class=" self-center mr-3">
<svg
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0
20 20
"
viewBox="0 0
16 16
"
fill="currentColor"
fill="currentColor"
class="w-4 h-4"
class="w-4 h-4"
>
>
<path
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 3.5a.75.75 0 0 1 .75.75v2.69l.72-.72a.75.75 0 1 1 1.06 1.06l-2 2a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 0 1 1.06-1.06l.72.72V6.25A.75.75 0 0 1 8 5.5Z"
clip-rule="evenodd"
/>
/>
</svg>
</svg>
</button>
</div>
</div>
<div class=" self-center text-sm font-medium">Export Chats</div>
</button>
</div>
</div>
{:else}
<button
<hr class=" dark:border-gray-700" />
class=" flex rounded-md py-3 px-3.5 w-full hover:bg-gray-900 transition"
on:click={() => {
{#if showDeleteConfirm}
showDeleteHistoryConfirm = true;
<div
}}
class="flex justify-between rounded-md items-center py-2 px-3.5 w-full transition"
>
>
<div class="mr-3">
<div class="flex items-center space-x-3">
<svg
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 16 16"
viewBox="0 0 24 24"
fill="currentColor"
stroke-width="1.5"
class="w-4 h-4"
stroke="currentColor"
>
class="w-5 h-5"
<path
>
d="M2 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3Z"
<path
/>
stroke-linecap="round"
<path
stroke-linejoin="round"
fill-rule="evenodd"
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
d="M13 6H3v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6ZM5.72 7.47a.75.75 0 0 1 1.06 0L8 8.69l1.22-1.22a.75.75 0 1 1 1.06 1.06L9.06 9.75l1.22 1.22a.75.75 0 1 1-1.06 1.06L8 10.81l-1.22 1.22a.75.75 0 0 1-1.06-1.06l1.22-1.22-1.22-1.22a.75.75 0 0 1 0-1.06Z"
/>
clip-rule="evenodd"
</svg>
/>
</svg>
<span>Are you sure?</span>
</div>
<div class="flex space-x-1.5 items-center">
<button
class="hover:text-white transition"
on:click={() => {
deleteChats();
showDeleteConfirm = false;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
clip-rule="evenodd"
/>
</svg>
</button>
<button
class="hover:text-white transition"
on:click={() => {
showDeleteConfirm = false;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
/>
</svg>
</button>
</div>
</div>
</div>
<span>Clear conversations</span>
{:else}
</button>
<button
{/if} -->
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
on:click={() => {
showDeleteConfirm = true;
}}
>
<div class=" self-center mr-3">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M2 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3Z"
/>
<path
fill-rule="evenodd"
d="M13 6H3v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6ZM5.72 7.47a.75.75 0 0 1 1.06 0L8 8.69l1.22-1.22a.75.75 0 1 1 1.06 1.06L9.06 9.75l1.22 1.22a.75.75 0 1 1-1.06 1.06L8 10.81l-1.22 1.22a.75.75 0 0 1-1.06-1.06l1.22-1.22-1.22-1.22a.75.75 0 0 1 0-1.06Z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center text-sm font-medium">Delete All Chats</div>
</button>
{/if}
</div>
</div>
</div>
{:else if selectedTab === 'auth'}
{:else if selectedTab === 'auth'}
<form
<form
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment