diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py index 3ab7a496a..80b7856f0 100644 --- a/backend/open_webui/models/prompts.py +++ b/backend/open_webui/models/prompts.py @@ -259,7 +259,6 @@ class PromptsTable: # Join with User table for user filtering and sorting query = db.query(Prompt, User).outerjoin(User, User.id == Prompt.user_id) - query = query.filter(Prompt.is_active == True) if filter: query_key = filter.get("query") @@ -562,43 +561,24 @@ class PromptsTable: except Exception: return None - def delete_prompt_by_command( - self, command: str, db: Optional[Session] = None - ) -> bool: - """Soft delete a prompt by setting is_active to False.""" - try: - with get_db_context(db) as db: - prompt = db.query(Prompt).filter_by(command=command).first() - if prompt: - PromptHistories.delete_history_by_prompt_id(prompt.id, db=db) - AccessGrants.revoke_all_access("prompt", prompt.id, db=db) - - prompt.is_active = False - prompt.updated_at = int(time.time()) - db.commit() - return True - return False - except Exception: - return False - - def delete_prompt_by_id(self, prompt_id: str, db: Optional[Session] = None) -> bool: - """Soft delete a prompt by setting is_active to False.""" + def toggle_prompt_active( + self, prompt_id: str, db: Optional[Session] = None + ) -> Optional[PromptModel]: + """Toggle the is_active flag on a prompt.""" try: with get_db_context(db) as db: prompt = db.query(Prompt).filter_by(id=prompt_id).first() if prompt: - PromptHistories.delete_history_by_prompt_id(prompt.id, db=db) - AccessGrants.revoke_all_access("prompt", prompt.id, db=db) - - prompt.is_active = False + prompt.is_active = not prompt.is_active prompt.updated_at = int(time.time()) db.commit() - return True - return False + db.refresh(prompt) + return self._to_prompt_model(prompt, db=db) + return None except Exception: - return False + return None - def hard_delete_prompt_by_command( + def delete_prompt_by_command( self, command: str, db: Optional[Session] = None ) -> bool: """Permanently delete a prompt and its history.""" @@ -609,8 +589,23 @@ class PromptsTable: PromptHistories.delete_history_by_prompt_id(prompt.id, db=db) AccessGrants.revoke_all_access("prompt", prompt.id, db=db) - # Delete prompt - db.query(Prompt).filter_by(command=command).delete() + db.delete(prompt) + db.commit() + return True + return False + except Exception: + return False + + def delete_prompt_by_id(self, prompt_id: str, db: Optional[Session] = None) -> bool: + """Permanently delete a prompt and its history.""" + try: + with get_db_context(db) as db: + prompt = db.query(Prompt).filter_by(id=prompt_id).first() + if prompt: + PromptHistories.delete_history_by_prompt_id(prompt.id, db=db) + AccessGrants.revoke_all_access("prompt", prompt.id, db=db) + + db.delete(prompt) db.commit() return True return False diff --git a/backend/open_webui/routers/prompts.py b/backend/open_webui/routers/prompts.py index 249157895..9653571fb 100644 --- a/backend/open_webui/routers/prompts.py +++ b/backend/open_webui/routers/prompts.py @@ -497,6 +497,48 @@ async def update_prompt_access_by_id( return Prompts.get_prompt_by_id(prompt_id, db=db) +############################ +# TogglePromptActiveById +############################ + + +@router.post("/id/{prompt_id}/toggle", response_model=Optional[PromptModel]) +async def toggle_prompt_active( + prompt_id: str, user=Depends(get_verified_user), db: Session = Depends(get_session) +): + prompt = Prompts.get_prompt_by_id(prompt_id, db=db) + + if not prompt: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + prompt.user_id != user.id + and not AccessGrants.has_access( + user_id=user.id, + resource_type="prompt", + resource_id=prompt.id, + permission="write", + db=db, + ) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + result = Prompts.toggle_prompt_active(prompt.id, db=db) + if result: + return result + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + ############################ # DeletePromptById ############################ diff --git a/src/lib/apis/prompts/index.ts b/src/lib/apis/prompts/index.ts index 1fd311c76..5db7dc354 100644 --- a/src/lib/apis/prompts/index.ts +++ b/src/lib/apis/prompts/index.ts @@ -395,6 +395,34 @@ export const setProductionPromptVersion = async ( return res; }; +export const togglePromptById = async (token: string, promptId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/id/${promptId}/toggle`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.error(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const deletePromptById = async (token: string, promptId: string) => { let error = null; diff --git a/src/lib/components/workspace/Prompts.svelte b/src/lib/components/workspace/Prompts.svelte index 4e99651f8..726571d8a 100644 --- a/src/lib/components/workspace/Prompts.svelte +++ b/src/lib/components/workspace/Prompts.svelte @@ -10,6 +10,7 @@ import { createNewPrompt, deletePromptById, + togglePromptById, getPrompts, getPromptItems, getPromptTags @@ -31,6 +32,7 @@ import ViewSelector from './common/ViewSelector.svelte'; import TagSelector from './common/TagSelector.svelte'; import Badge from '$lib/components/common/Badge.svelte'; + import Switch from '../common/Switch.svelte'; import Pagination from '../common/Pagination.svelte'; let shiftKey = false; @@ -398,6 +400,9 @@
/{prompt.command}
+ {#if prompt.is_active === false} + + {/if} {#if !prompt.write_access} @@ -484,6 +489,17 @@ + + {/if}