From d44c2d3f5aeab25a9405896f48a36082cee5d8ac Mon Sep 17 00:00:00 2001
From: firecoperana <xuqiaowei1124@gmail.com>
Date: Sun, 20 Jul 2025 05:33:55 -0500
Subject: Webui: New Features for Conversations, Settings, and Chat Messages
 (#618)

* Webui: add Rename/Upload conversation in header and sidebar

webui: don't change modified date when renaming conversation

* webui: add a preset feature to the settings #14649

* webui: Add editing assistant messages #13522

Webui: keep the following message while editing assistance response.

webui: change icon to edit message

* webui: DB import and export #14347

* webui: Wrap long numbers instead of infinite horizontal scroll (#14062)
fix sidebar being covered by main content #14082

---------

Co-authored-by: firecoperana <firecoperana>
---
 examples/server/webui/src/components/Header.tsx | 86 +++++++++++++++++++++++--
 1 file changed, 80 insertions(+), 6 deletions(-)

(limited to 'examples/server/webui/src/components/Header.tsx')

diff --git a/examples/server/webui/src/components/Header.tsx b/examples/server/webui/src/components/Header.tsx
index 84fea191..601fb960 100644
--- a/examples/server/webui/src/components/Header.tsx
+++ b/examples/server/webui/src/components/Header.tsx
@@ -5,6 +5,14 @@ import { classNames } from '../utils/misc';
 import daisyuiThemes from 'daisyui/theme/object';
 import { THEMES } from '../Config';
 import { useNavigate } from 'react-router';
+import toast from 'react-hot-toast';
+import { useModals } from './ModalProvider';
+import {
+  ArrowUpTrayIcon,
+  ArrowDownTrayIcon,
+  PencilIcon,
+  TrashIcon,
+} from '@heroicons/react/24/outline';
 
 export default function Header() {
   const navigate = useNavigate();
@@ -24,9 +32,11 @@ export default function Header() {
     );
   }, [selectedTheme]);
 
+  const {showPrompt } = useModals();
   const { isGenerating, viewingChat } = useAppContext();
   const isCurrConvGenerating = isGenerating(viewingChat?.conv.id ?? '');
 
+  // remove conversation
   const removeConversation = () => {
     if (isCurrConvGenerating || !viewingChat) return;
     const convId = viewingChat?.conv.id;
@@ -35,6 +45,37 @@ export default function Header() {
       navigate('/');
     }
   };
+  
+  // rename conversation 
+  async function renameConversation() {  
+	if (isGenerating(viewingChat?.conv.id ?? '')) {
+	  toast.error(
+		'Cannot rename conversation while generating'
+	  );
+	  return;
+	}
+	const newName = await showPrompt(
+	  'Enter new name for the conversation',
+	  viewingChat?.conv.name
+	);
+	if (newName && newName.trim().length > 0) {
+	  StorageUtils.updateConversationName(viewingChat?.conv.id ?? '', newName);
+	}
+    //const importedConv = await StorageUtils.updateConversationName();
+  //if (importedConv) {
+    //console.log('Successfully imported:', importedConv.name);
+    // Refresh UI or navigate to conversation
+  //}
+  };
+  
+  // at the top of your file, alongside ConversationExport:
+  async function importConversation() {  
+    const importedConv = await StorageUtils.importConversationFromFile();
+  if (importedConv) {
+    console.log('Successfully imported:', importedConv.name);
+    // Refresh UI or navigate to conversation
+  }
+  };
 
   const downloadConversation = () => {
     if (isCurrConvGenerating || !viewingChat) return;
@@ -99,12 +140,45 @@ export default function Header() {
               tabIndex={0}
               className="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow"
             >
-              <li onClick={downloadConversation}>
-                <a>Download</a>
-              </li>
-              <li className="text-error" onClick={removeConversation}>
-                <a>Delete</a>
-              </li>
+              {/* Always show Upload when viewingChat is false */}
+              {!viewingChat && (
+                <li onClick={importConversation}>
+                  <a>
+				  <ArrowUpTrayIcon className="w-4 h-4" />
+				  Upload
+				  </a>
+                </li>
+              )}
+
+              {/* Show all three when viewingChat is true */}
+              {viewingChat && (
+                <>
+                  <li onClick={importConversation}>
+                    <a>				  
+					<ArrowUpTrayIcon className="w-4 h-4" />
+					Upload
+					</a>
+                  </li>
+				  <li onClick={renameConversation} tabIndex={0}>
+					<a>
+					  <PencilIcon className="w-4 h-4" />
+					  Rename
+					</a>
+				  </li>
+                  <li onClick={downloadConversation}>
+                    <a>
+					<ArrowDownTrayIcon className="w-4 h-4" />
+					Download
+					</a>
+                  </li>
+                  <li className="text-error" onClick={removeConversation}>
+                    <a>
+					<TrashIcon className="w-4 h-4" />
+					Delete
+					</a>
+                  </li>
+                </>
+              )}
             </ul>
           </div>
         )}
-- 
cgit v1.2.3

