feat: csv user import frontend

This commit is contained in:
Timothy J. Baek 2024-05-01 19:02:25 -07:00
parent e5703a588f
commit bd3b5f1edb
4 changed files with 188 additions and 54 deletions

View file

@ -1,12 +1,14 @@
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
############################

View file

@ -0,0 +1 @@
Name,Email,Password,Role
1 Name Email Password Role

View file

@ -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">

View file

@ -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