mirror of
https://github.com/open-webui/open-webui
synced 2025-04-22 07:18:29 +00:00
feat: valves
This commit is contained in:
parent
3a629ffe00
commit
627705a347
@ -127,8 +127,8 @@ async def get_function_valves_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
function = Functions.get_function_by_id(id)
|
function = Functions.get_function_by_id(id)
|
||||||
if function:
|
if function:
|
||||||
try:
|
try:
|
||||||
valves = Functions.get_function_valves_by_id(id)
|
function_valves = Functions.get_function_valves_by_id(id)
|
||||||
return valves
|
return function_valves.valves
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
@ -142,20 +142,60 @@ async def get_function_valves_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# UpdateToolValves
|
# GetFunctionValvesSpec
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
|
||||||
|
async def get_function_valves_spec_by_id(
|
||||||
|
request: Request, id: str, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
|
function = Functions.get_function_by_id(id)
|
||||||
|
if function:
|
||||||
|
if id in request.app.state.FUNCTIONS:
|
||||||
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
|
else:
|
||||||
|
function_module, function_type = load_function_module_by_id(id)
|
||||||
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
|
if hasattr(function_module, "Valves"):
|
||||||
|
Valves = function_module.Valves
|
||||||
|
return Valves.schema()
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# UpdateFunctionValves
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
||||||
async def update_toolkit_valves_by_id(
|
async def update_function_valves_by_id(
|
||||||
id: str, form_data: dict, user=Depends(get_admin_user)
|
request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
|
||||||
):
|
):
|
||||||
function = Functions.get_function_by_id(id)
|
function = Functions.get_function_by_id(id)
|
||||||
if function:
|
if function:
|
||||||
|
|
||||||
|
if id in request.app.state.FUNCTIONS:
|
||||||
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
|
else:
|
||||||
|
function_module, function_type = load_function_module_by_id(id)
|
||||||
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
|
if hasattr(function_module, "Valves"):
|
||||||
|
Valves = function_module.Valves
|
||||||
|
|
||||||
try:
|
try:
|
||||||
valves = Functions.update_function_valves_by_id(id, form_data)
|
valves = Valves(**form_data)
|
||||||
return valves
|
Functions.update_function_valves_by_id(id, valves.model_dump())
|
||||||
|
return valves.model_dump()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||||
@ -166,6 +206,12 @@ async def update_toolkit_valves_by_id(
|
|||||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# FunctionUserValves
|
# FunctionUserValves
|
||||||
|
@ -133,8 +133,8 @@ async def get_toolkit_valves_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
toolkit = Tools.get_tool_by_id(id)
|
toolkit = Tools.get_tool_by_id(id)
|
||||||
if toolkit:
|
if toolkit:
|
||||||
try:
|
try:
|
||||||
valves = Tools.get_tool_valves_by_id(id)
|
tool_valves = Tools.get_tool_valves_by_id(id)
|
||||||
return valves
|
return tool_valves.valves
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
@ -147,6 +147,34 @@ async def get_toolkit_valves_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# GetToolValvesSpec
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
|
||||||
|
async def get_toolkit_valves_spec_by_id(
|
||||||
|
request: Request, id: str, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
|
toolkit = Tools.get_tool_by_id(id)
|
||||||
|
if toolkit:
|
||||||
|
if id in request.app.state.TOOLS:
|
||||||
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
|
else:
|
||||||
|
toolkit_module = load_toolkit_module_by_id(id)
|
||||||
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
|
if hasattr(toolkit_module, "UserValves"):
|
||||||
|
UserValves = toolkit_module.UserValves
|
||||||
|
return UserValves.schema()
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# UpdateToolValves
|
# UpdateToolValves
|
||||||
############################
|
############################
|
||||||
@ -154,14 +182,25 @@ async def get_toolkit_valves_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
|
|
||||||
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
||||||
async def update_toolkit_valves_by_id(
|
async def update_toolkit_valves_by_id(
|
||||||
id: str, form_data: dict, user=Depends(get_admin_user)
|
request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
|
||||||
):
|
):
|
||||||
toolkit = Tools.get_tool_by_id(id)
|
toolkit = Tools.get_tool_by_id(id)
|
||||||
if toolkit:
|
if toolkit:
|
||||||
|
if id in request.app.state.TOOLS:
|
||||||
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
|
else:
|
||||||
|
toolkit_module = load_toolkit_module_by_id(id)
|
||||||
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
|
if hasattr(toolkit_module, "Valves"):
|
||||||
|
Valves = toolkit_module.Valves
|
||||||
|
|
||||||
try:
|
try:
|
||||||
valves = Tools.update_tool_valves_by_id(id, form_data)
|
valves = Valves(**form_data)
|
||||||
return valves
|
Tools.update_tool_valves_by_id(id, valves.model_dump())
|
||||||
|
return valves.model_dump()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||||
@ -172,6 +211,12 @@ async def update_toolkit_valves_by_id(
|
|||||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# ToolUserValves
|
# ToolUserValves
|
||||||
|
@ -256,6 +256,38 @@ export const getFunctionValvesById = async (token: string, id: string) => {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getFunctionValvesSpecById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/spec`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const updateFunctionValvesById = async (token: string, id: string, valves: object) => {
|
export const updateFunctionValvesById = async (token: string, id: string, valves: object) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
@ -192,6 +192,105 @@ export const deleteToolById = async (token: string, id: string) => {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getToolValvesById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getToolValvesSpecById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/spec`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateToolValvesById = async (token: string, id: string, valves: object) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/update`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
...valves
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const getUserValvesById = async (token: string, id: string) => {
|
export const getUserValvesById = async (token: string, id: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
import FunctionMenu from './Functions/FunctionMenu.svelte';
|
import FunctionMenu from './Functions/FunctionMenu.svelte';
|
||||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||||
import Switch from '../common/Switch.svelte';
|
import Switch from '../common/Switch.svelte';
|
||||||
|
import ValvesModal from './ValvesModal.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -33,6 +34,9 @@
|
|||||||
let showConfirm = false;
|
let showConfirm = false;
|
||||||
let query = '';
|
let query = '';
|
||||||
|
|
||||||
|
let showValvesModal = false;
|
||||||
|
let selectedFunction = null;
|
||||||
|
|
||||||
const shareHandler = async (tool) => {
|
const shareHandler = async (tool) => {
|
||||||
console.log(tool);
|
console.log(tool);
|
||||||
};
|
};
|
||||||
@ -175,6 +179,10 @@
|
|||||||
<button
|
<button
|
||||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||||
type="button"
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
selectedFunction = func;
|
||||||
|
showValvesModal = true;
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -352,6 +360,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ValvesModal bind:show={showValvesModal} type="function" id={selectedFunction?.id ?? null} />
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:show={showConfirm}
|
bind:show={showConfirm}
|
||||||
on:confirm={() => {
|
on:confirm={() => {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
import ConfirmDialog from '../common/ConfirmDialog.svelte';
|
import ConfirmDialog from '../common/ConfirmDialog.svelte';
|
||||||
import ToolMenu from './Tools/ToolMenu.svelte';
|
import ToolMenu from './Tools/ToolMenu.svelte';
|
||||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||||
|
import ValvesModal from './ValvesModal.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -29,6 +30,9 @@
|
|||||||
let showConfirm = false;
|
let showConfirm = false;
|
||||||
let query = '';
|
let query = '';
|
||||||
|
|
||||||
|
let showValvesModal = false;
|
||||||
|
let selectedTool = null;
|
||||||
|
|
||||||
const shareHandler = async (tool) => {
|
const shareHandler = async (tool) => {
|
||||||
console.log(tool);
|
console.log(tool);
|
||||||
};
|
};
|
||||||
@ -169,6 +173,10 @@
|
|||||||
<button
|
<button
|
||||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||||
type="button"
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
selectedTool = tool;
|
||||||
|
showValvesModal = true;
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -336,6 +344,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ValvesModal bind:show={showValvesModal} type="tool" id={selectedTool?.id ?? null} />
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:show={showConfirm}
|
bind:show={showConfirm}
|
||||||
on:confirm={() => {
|
on:confirm={() => {
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
import { addUser } from '$lib/apis/auths';
|
import { addUser } from '$lib/apis/auths';
|
||||||
|
|
||||||
import Modal from '../common/Modal.svelte';
|
import Modal from '../common/Modal.svelte';
|
||||||
|
import {
|
||||||
|
getFunctionValvesById,
|
||||||
|
getFunctionValvesSpecById,
|
||||||
|
updateFunctionValvesById
|
||||||
|
} from '$lib/apis/functions';
|
||||||
|
import { getToolValvesById, getToolValvesSpecById, updateToolValvesById } from '$lib/apis/tools';
|
||||||
|
import Spinner from '../common/Spinner.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
@ -14,21 +21,57 @@
|
|||||||
export let type = 'tool';
|
export let type = 'tool';
|
||||||
export let id = null;
|
export let id = null;
|
||||||
|
|
||||||
|
let saving = false;
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
let _user = {
|
let valvesSpec = null;
|
||||||
name: '',
|
let valves = {};
|
||||||
email: '',
|
|
||||||
password: '',
|
|
||||||
role: 'user'
|
|
||||||
};
|
|
||||||
|
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
const stopLoading = () => {
|
saving = true;
|
||||||
dispatch('save');
|
|
||||||
|
let res = null;
|
||||||
|
|
||||||
|
if (type === 'tool') {
|
||||||
|
res = await updateToolValvesById(localStorage.token, id, valves).catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
});
|
||||||
|
} else if (type === 'function') {
|
||||||
|
res = await updateFunctionValvesById(localStorage.token, id, valves).catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
toast.success('Valves updated successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
saving = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const initHandler = async () => {
|
||||||
|
loading = true;
|
||||||
|
valves = {};
|
||||||
|
valvesSpec = null;
|
||||||
|
|
||||||
|
if (type === 'tool') {
|
||||||
|
valves = await getToolValvesById(localStorage.token, id);
|
||||||
|
valvesSpec = await getToolValvesSpecById(localStorage.token, id);
|
||||||
|
} else if (type === 'function') {
|
||||||
|
valves = await getFunctionValvesById(localStorage.token, id);
|
||||||
|
valvesSpec = await getFunctionValvesSpecById(localStorage.token, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valves) {
|
||||||
|
valves = {};
|
||||||
|
}
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
$: if (show) {
|
||||||
|
initHandler();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal size="sm" bind:show>
|
<Modal size="sm" bind:show>
|
||||||
@ -63,81 +106,81 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="px-1">
|
<div class="px-1">
|
||||||
<div class="flex flex-col w-full">
|
{#if !loading}
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Role')}</div>
|
{#if valvesSpec}
|
||||||
|
{#each Object.keys(valvesSpec.properties) as property, idx}
|
||||||
|
<div class=" py-0.5 w-full justify-between">
|
||||||
|
<div class="flex w-full justify-between">
|
||||||
|
<div class=" self-center text-xs font-medium">
|
||||||
|
{valvesSpec.properties[property].title}
|
||||||
|
|
||||||
<div class="flex-1">
|
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||||
<select
|
<span class=" text-gray-500">*required</span>
|
||||||
class="w-full capitalize rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 disabled:text-gray-500 dark:disabled:text-gray-500 outline-none"
|
{/if}
|
||||||
bind:value={_user.role}
|
</div>
|
||||||
placeholder={$i18n.t('Enter Your Role')}
|
|
||||||
required
|
<button
|
||||||
|
class="p-1 px-3 text-xs flex rounded transition"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
valves[property] = (valves[property] ?? null) === null ? '' : null;
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<option value="pending"> {$i18n.t('pending')} </option>
|
{#if (valves[property] ?? null) === null}
|
||||||
<option value="user"> {$i18n.t('user')} </option>
|
<span class="ml-2 self-center">
|
||||||
<option value="admin"> {$i18n.t('admin')} </option>
|
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||||
</select>
|
{$i18n.t('None')}
|
||||||
</div>
|
{:else}
|
||||||
|
{$i18n.t('Default')}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{:else}
|
||||||
|
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col w-full mt-2">
|
{#if (valves[property] ?? null) !== null}
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Name')}</div>
|
<div class="flex mt-0.5 mb-1.5 space-x-2">
|
||||||
|
<div class=" flex-1">
|
||||||
<div class="flex-1">
|
|
||||||
<input
|
<input
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 disabled:text-gray-500 dark:disabled:text-gray-500 outline-none"
|
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={_user.name}
|
placeholder={valvesSpec.properties[property].title}
|
||||||
placeholder={$i18n.t('Enter Your Full Name')}
|
bind:value={valves[property]}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
required
|
required={(valvesSpec?.required ?? []).includes(property)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<hr class=" dark:border-gray-800 my-3 w-full" />
|
{#if (valvesSpec.properties[property]?.description ?? null) !== null}
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
<div class="flex flex-col w-full">
|
{valvesSpec.properties[property].description}
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div>
|
|
||||||
|
|
||||||
<div class="flex-1">
|
|
||||||
<input
|
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 disabled:text-gray-500 dark:disabled:text-gray-500 outline-none"
|
|
||||||
type="email"
|
|
||||||
bind:value={_user.email}
|
|
||||||
placeholder={$i18n.t('Enter Your Email')}
|
|
||||||
autocomplete="off"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-col w-full mt-2">
|
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Password')}</div>
|
|
||||||
|
|
||||||
<div class="flex-1">
|
|
||||||
<input
|
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 disabled:text-gray-500 dark:disabled:text-gray-500 outline-none"
|
|
||||||
type="password"
|
|
||||||
bind:value={_user.password}
|
|
||||||
placeholder={$i18n.t('Enter Your Password')}
|
|
||||||
autocomplete="off"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
<div>No valves</div>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<Spinner className="size-5" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end pt-3 text-sm font-medium">
|
<div class="flex justify-end pt-3 text-sm font-medium">
|
||||||
<button
|
<button
|
||||||
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg flex flex-row space-x-1 items-center {loading
|
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg flex flex-row space-x-1 items-center {saving
|
||||||
? ' cursor-not-allowed'
|
? ' cursor-not-allowed'
|
||||||
: ''}"
|
: ''}"
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={loading}
|
disabled={saving}
|
||||||
>
|
>
|
||||||
{$i18n.t('Submit')}
|
{$i18n.t('Save')}
|
||||||
|
|
||||||
{#if loading}
|
{#if saving}
|
||||||
<div class="ml-2 self-center">
|
<div class="ml-2 self-center">
|
||||||
<svg
|
<svg
|
||||||
class=" w-4 h-4"
|
class=" w-4 h-4"
|
||||||
|
Loading…
Reference in New Issue
Block a user