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
bd3b5f1e
Commit
bd3b5f1e
authored
May 01, 2024
by
Timothy J. Baek
Browse files
feat: csv user import frontend
parent
e5703a58
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
196 additions
and
62 deletions
+196
-62
backend/apps/web/routers/auths.py
backend/apps/web/routers/auths.py
+74
-2
backend/static/user-import.csv
backend/static/user-import.csv
+1
-0
src/lib/components/admin/AddUserModal.svelte
src/lib/components/admin/AddUserModal.svelte
+120
-59
src/routes/(app)/+layout.svelte
src/routes/(app)/+layout.svelte
+1
-1
No files found.
backend/apps/web/routers/auths.py
View file @
bd3b5f1e
import
logging
from
fastapi
import
Request
from
fastapi
import
Request
,
UploadFile
,
File
from
fastapi
import
Depends
,
HTTPException
,
status
from
fastapi
import
APIRouter
from
pydantic
import
BaseModel
import
re
import
uuid
import
csv
from
apps.web.models.auths
import
(
SigninForm
,
...
...
@@ -212,7 +214,7 @@ async def signup(request: Request, form_data: SignupForm):
@
router
.
post
(
"/add"
,
response_model
=
SigninResponse
)
async
def
signup
(
form_data
:
AddUserForm
,
user
=
Depends
(
get_admin_user
)):
async
def
add_user
(
form_data
:
AddUserForm
,
user
=
Depends
(
get_admin_user
)):
if
not
validate_email_format
(
form_data
.
email
.
lower
()):
raise
HTTPException
(
...
...
@@ -251,6 +253,76 @@ async def signup(form_data: AddUserForm, user=Depends(get_admin_user)):
raise
HTTPException
(
500
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
err
))
@
router
.
post
(
"/add/import"
,
response_model
=
SigninResponse
)
async
def
add_user_csv_import
(
file
:
UploadFile
=
File
(...),
user
=
Depends
(
get_admin_user
)
):
try
:
# Check if the file is a CSV file
if
file
.
filename
.
endswith
(
".csv"
):
# Read the contents of the CSV file
contents
=
await
file
.
read
()
# Decode the contents from bytes to string
decoded_content
=
contents
.
decode
(
"utf-8"
)
# Split the CSV content into lines
csv_lines
=
decoded_content
.
split
(
"
\n
"
)
# Parse CSV
csv_data
=
[]
csv_reader
=
csv
.
reader
(
csv_lines
)
for
row
in
csv_reader
:
csv_data
.
append
(
row
)
# Print the CSV data
for
row
in
csv_data
:
print
(
row
)
return
{
"message"
:
"CSV file uploaded successfully."
}
else
:
raise
"File must be a CSV."
except
Exception
as
err
:
raise
HTTPException
(
500
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
err
))
# if not validate_email_format(form_data.email.lower()):
# raise HTTPException(
# status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT
# )
# if Users.get_user_by_email(form_data.email.lower()):
# raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
# try:
# print(form_data)
# hashed = get_password_hash(form_data.password)
# user = Auths.insert_new_auth(
# form_data.email.lower(),
# hashed,
# form_data.name,
# form_data.profile_image_url,
# form_data.role,
# )
# if user:
# token = create_token(data={"id": user.id})
# return {
# "token": token,
# "token_type": "Bearer",
# "id": user.id,
# "email": user.email,
# "name": user.name,
# "role": user.role,
# "profile_image_url": user.profile_image_url,
# }
# else:
# raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
# except Exception as err:
# raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))
############################
# ToggleSignUp
############################
...
...
backend/static/user-import.csv
0 → 100644
View file @
bd3b5f1e
Name,Email,Password,Role
src/lib/components/admin/AddUserModal.svelte
View file @
bd3b5f1e
...
...
@@ -5,12 +5,16 @@
import { addUser } from '$lib/apis/auths';
import Modal from '../common/Modal.svelte';
import { WEBUI_BASE_URL } from '$lib/constants';
const i18n = getContext('i18n');
const dispatch = createEventDispatcher();
export let show = false;
let tab = '';
let inputFiles;
let _user = {
name: '',
email: '',
...
...
@@ -76,7 +80,25 @@
submitHandler();
}}
>
<div class=" ">
<div class="flex text-center text-sm font-medium rounded-xl bg-transparent/10 p-1 mb-2">
<button
class="w-full rounded-lg p-1.5 {tab === '' ? 'bg-gray-50 dark:bg-gray-850' : ''}"
type="button"
on:click={() => {
tab = '';
}}>Form</button
>
<button
class="w-full rounded-lg p-1 {tab === 'import' ? 'bg-gray-50 dark:bg-gray-850' : ''}"
type="button"
on:click={() => {
tab = 'import';
}}>CSV Import</button
>
</div>
<div class="px-1">
{#if tab === ''}
<div class="flex flex-col w-full">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Role')}</div>
...
...
@@ -139,6 +161,45 @@
/>
</div>
</div>
{:else if tab === 'import'}
<div>
<div class="mb-3 w-full">
<input
id="upload-user-csv-input"
hidden
bind:files={inputFiles}
type="file"
accept=".csv"
/>
<button
class="w-full text-sm font-medium py-3 bg-transparent hover:bg-gray-100 border border-dashed dark:border-gray-800 dark:hover:bg-gray-850 text-center rounded-xl"
type="button"
on:click={() => {
document.getElementById('upload-user-csv-input')?.click();
}}
>
{#if inputFiles}
{inputFiles.length > 0 ? `${inputFiles.length}` : ''} document(s) selected.
{:else}
{$i18n.t('Click here to select a csv file.')}
{/if}
</button>
</div>
<div class=" text-xs text-gray-500">
ⓘ {$i18n.t(
'Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.'
)}
<a
class="underline dark:text-gray-200"
href="{WEBUI_BASE_URL}/static/user-import.csv"
>
Click here to download user import template file.
</a>
</div>
</div>
{/if}
</div>
<div class="flex justify-end pt-3 text-sm font-medium">
...
...
src/routes/(app)/+layout.svelte
View file @
bd3b5f1e
...
...
@@ -154,7 +154,7 @@
if (isCtrlPressed && event.key === '.') {
event.preventDefault();
console.log('openSettings');
document.getElementById('open-settings-button')?.click(
);
showSettings.set(!$showSettings
);
}
// Check if Ctrl + / is pressed
...
...
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