diff --git a/src/lib/components/common/CodeEditor.svelte b/src/lib/components/common/CodeEditor.svelte index c83ee991ea..f53d504d44 100644 --- a/src/lib/components/common/CodeEditor.svelte +++ b/src/lib/components/common/CodeEditor.svelte @@ -318,4 +318,4 @@ print("${endTag}") }); -
+
diff --git a/src/lib/components/workspace/Prompts.svelte b/src/lib/components/workspace/Prompts.svelte index e08d9b3c62..c075ec7a62 100644 --- a/src/lib/components/workspace/Prompts.svelte +++ b/src/lib/components/workspace/Prompts.svelte @@ -5,6 +5,8 @@ import { goto } from '$app/navigation'; import { onMount, getContext, tick, onDestroy } from 'svelte'; + import type { Writable } from 'svelte/store'; + import type { i18n as i18nType } from 'i18next'; import { WEBUI_NAME, config, user, workspaceActions } from '$lib/stores'; import { @@ -35,9 +37,20 @@ import Switch from '../common/Switch.svelte'; import Pagination from '../common/Pagination.svelte'; + type PromptDraft = { + id?: string; + name: string; + command: string; + content: string; + tags: string[]; + access_grants: any[]; + commit_message?: string; + is_production?: boolean; + }; + let shiftKey = false; - const i18n = getContext('i18n'); + const i18n = getContext>('i18n'); let promptsImportInputElement: HTMLInputElement; let loaded = false; @@ -52,6 +65,7 @@ let showDeleteConfirm = false; let showCreateModal = false; + let createPrompt: PromptDraft | null = null; let deletePrompt = null; let tagsContainerElement: HTMLDivElement; @@ -67,6 +81,7 @@ id: 'prompts-new', label: $i18n.t('Create'), onClick: () => { + createPrompt = null; showCreateModal = true; } }, @@ -160,7 +175,20 @@ ); }; - const createPromptHandler = async (prompt) => { + const toPromptDraft = (prompt: any): PromptDraft => ({ + name: prompt.name || prompt.title || 'Prompt', + command: prompt.command || '', + content: prompt.content || '', + tags: prompt.tags || [], + access_grants: prompt.access_grants !== undefined ? prompt.access_grants : [] + }); + + const openCreateModal = (prompt: PromptDraft | null = null) => { + createPrompt = prompt; + showCreateModal = true; + }; + + const createPromptHandler = async (prompt: PromptDraft) => { const res = await createNewPrompt(localStorage.token, prompt).catch((error) => { toast.error(`${error}`); return null; @@ -169,6 +197,7 @@ if (res) { toast.success($i18n.t('Prompt created successfully')); showCreateModal = false; + createPrompt = null; page = 1; await getPromptList(); } @@ -183,8 +212,7 @@ : clonedPrompt.command; clonedPrompt.command = slugify(`${baseCommand} clone`); - sessionStorage.prompt = JSON.stringify(clonedPrompt); - goto('/workspace/prompts/create'); + openCreateModal(toPromptDraft(clonedPrompt)); }; const exportHandler = async (prompt) => { @@ -224,13 +252,37 @@ viewOption = localStorage?.workspaceViewOption || ''; loaded = true; - const onKeyDown = (event) => { + const onMessage = async (event: MessageEvent) => { + if ( + !['https://openwebui.com', 'https://www.openwebui.com', 'http://localhost:9999'].includes( + event.origin + ) + ) { + return; + } + + openCreateModal(toPromptDraft(JSON.parse(event.data))); + }; + + window.addEventListener('message', onMessage); + + if (window.opener ?? false) { + window.opener.postMessage('loaded', '*'); + } + + if (sessionStorage.prompt) { + const prompt = JSON.parse(sessionStorage.prompt); + sessionStorage.removeItem('prompt'); + openCreateModal(toPromptDraft(prompt)); + } + + const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Shift') { shiftKey = true; } }; - const onKeyUp = (event) => { + const onKeyUp = (event: KeyboardEvent) => { if (event.key === 'Shift') { shiftKey = false; } @@ -246,6 +298,7 @@ return () => { clearTimeout(searchDebounceTimer); + window.removeEventListener('message', onMessage); window.removeEventListener('keydown', onKeyDown); window.removeEventListener('keyup', onKeyUp); window.removeEventListener('blur', onBlur); @@ -277,13 +330,18 @@ - { - showCreateModal = false; - }} - /> + {#key createPrompt} + { + showCreateModal = false; + createPrompt = null; + }} + /> + {/key} import { onMount, tick, getContext } from 'svelte'; + import type { Writable } from 'svelte/store'; + import type { i18n as i18nType } from 'i18next'; import Textarea from '$lib/components/common/Textarea.svelte'; import { toast } from 'svelte-sonner'; @@ -31,13 +33,13 @@ export let onSubmit: Function; export let edit = false; - export let prompt = null; + export let prompt: any = null; export let clone = false; export let disabled = false; export let modal = false; export let onCancel: Function = () => {}; - const i18n = getContext('i18n'); + const i18n = getContext>('i18n'); let loading = false; let showEditModal = false; diff --git a/src/routes/(app)/admin/+layout.svelte b/src/routes/(app)/admin/+layout.svelte index 5343d6be43..d18e68bc1c 100644 --- a/src/routes/(app)/admin/+layout.svelte +++ b/src/routes/(app)/admin/+layout.svelte @@ -33,7 +33,7 @@ {#if loaded}
@@ -117,7 +117,7 @@
-
+
diff --git a/src/routes/(app)/workspace/+layout.svelte b/src/routes/(app)/workspace/+layout.svelte index 4ec43958e0..3320ec1bae 100644 --- a/src/routes/(app)/workspace/+layout.svelte +++ b/src/routes/(app)/workspace/+layout.svelte @@ -111,9 +111,9 @@ {#if loaded}
-
+