Commit ·
1023c33
1
Parent(s): 4837c9c
Simplify rename assistant UI - replace inline editing with clean dialog
Browse files- frontend/src/pages/Playground.tsx +100 -74
- static/assets/index-cfecd2e3.js +0 -0
- static/assets/index-cfecd2e3.js.map +0 -0
- static/index.html +1 -1
frontend/src/pages/Playground.tsx
CHANGED
|
@@ -98,12 +98,14 @@ export function Playground() {
|
|
| 98 |
// Saved assistants state
|
| 99 |
const [savedAssistants, setSavedAssistants] = useState<any[]>([])
|
| 100 |
const [selectedAssistant, setSelectedAssistant] = useState<{id: string, name: string, type: 'user'|'template'|'new', originalTemplate?: string} | null>(null)
|
| 101 |
-
const [isRenaming, setIsRenaming] = useState(false)
|
| 102 |
-
const [tempAssistantName, setTempAssistantName] = useState('')
|
| 103 |
|
| 104 |
// Save assistant dialog state
|
| 105 |
const [showSaveDialog, setShowSaveDialog] = useState(false)
|
| 106 |
const [saveAssistantName, setSaveAssistantName] = useState('')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
// Load saved assistants
|
| 109 |
const loadSavedAssistants = () => {
|
|
@@ -228,7 +230,6 @@ export function Playground() {
|
|
| 228 |
name: 'New Assistant',
|
| 229 |
type: 'new'
|
| 230 |
})
|
| 231 |
-
setTempAssistantName('New Assistant')
|
| 232 |
}
|
| 233 |
|
| 234 |
// Clear current assistant
|
|
@@ -236,27 +237,45 @@ export function Playground() {
|
|
| 236 |
setSelectedAssistant(null)
|
| 237 |
}
|
| 238 |
|
| 239 |
-
//
|
| 240 |
-
const
|
| 241 |
if (selectedAssistant) {
|
| 242 |
-
|
| 243 |
-
|
| 244 |
}
|
| 245 |
}
|
| 246 |
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
|
|
|
| 254 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
}
|
| 256 |
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
|
|
|
| 260 |
}
|
| 261 |
|
| 262 |
// Convert template to new assistant when settings change
|
|
@@ -625,12 +644,7 @@ export function Playground() {
|
|
| 625 |
selectedAssistant={selectedAssistant}
|
| 626 |
createNewAssistant={createNewAssistant}
|
| 627 |
clearCurrentAssistant={clearCurrentAssistant}
|
| 628 |
-
|
| 629 |
-
tempAssistantName={tempAssistantName}
|
| 630 |
-
setTempAssistantName={setTempAssistantName}
|
| 631 |
-
startRenaming={startRenaming}
|
| 632 |
-
confirmRename={confirmRename}
|
| 633 |
-
cancelRename={cancelRename}
|
| 634 |
systemPrompt={systemPrompt}
|
| 635 |
/>
|
| 636 |
</div>
|
|
@@ -748,6 +762,56 @@ export function Playground() {
|
|
| 748 |
</AlertDialogFooter>
|
| 749 |
</AlertDialogContent>
|
| 750 |
</AlertDialog>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 751 |
</div>
|
| 752 |
)
|
| 753 |
}
|
|
@@ -913,12 +977,7 @@ function AssistantSelector({
|
|
| 913 |
selectedAssistant,
|
| 914 |
createNewAssistant,
|
| 915 |
clearCurrentAssistant,
|
| 916 |
-
|
| 917 |
-
tempAssistantName,
|
| 918 |
-
setTempAssistantName,
|
| 919 |
-
startRenaming,
|
| 920 |
-
confirmRename,
|
| 921 |
-
cancelRename,
|
| 922 |
systemPrompt
|
| 923 |
}: {
|
| 924 |
savedAssistants: any[]
|
|
@@ -930,12 +989,7 @@ function AssistantSelector({
|
|
| 930 |
selectedAssistant: {id: string, name: string, type: 'user'|'template'|'new', originalTemplate?: string} | null
|
| 931 |
createNewAssistant: () => void
|
| 932 |
clearCurrentAssistant: () => void
|
| 933 |
-
|
| 934 |
-
tempAssistantName: string
|
| 935 |
-
setTempAssistantName: (name: string) => void
|
| 936 |
-
startRenaming: () => void
|
| 937 |
-
confirmRename: () => void
|
| 938 |
-
cancelRename: () => void
|
| 939 |
systemPrompt: string
|
| 940 |
}) {
|
| 941 |
const handleAssistantSelect = (value: string) => {
|
|
@@ -1087,46 +1141,18 @@ function AssistantSelector({
|
|
| 1087 |
</Select>
|
| 1088 |
</div>
|
| 1089 |
|
| 1090 |
-
{/* Rename Assistant
|
| 1091 |
{selectedAssistant && selectedAssistant.type !== 'template' && (
|
| 1092 |
-
<
|
| 1093 |
-
{
|
| 1094 |
-
|
| 1095 |
-
|
| 1096 |
-
|
| 1097 |
-
|
| 1098 |
-
|
| 1099 |
-
|
| 1100 |
-
|
| 1101 |
-
|
| 1102 |
-
placeholder="Enter assistant name..."
|
| 1103 |
-
autoFocus
|
| 1104 |
-
onKeyDown={(e) => {
|
| 1105 |
-
if (e.key === 'Enter') confirmRename()
|
| 1106 |
-
if (e.key === 'Escape') cancelRename()
|
| 1107 |
-
}}
|
| 1108 |
-
/>
|
| 1109 |
-
<Button size="sm" onClick={confirmRename} disabled={!tempAssistantName.trim()}>
|
| 1110 |
-
✓
|
| 1111 |
-
</Button>
|
| 1112 |
-
<Button size="sm" variant="ghost" onClick={cancelRename}>
|
| 1113 |
-
✗
|
| 1114 |
-
</Button>
|
| 1115 |
-
</div>
|
| 1116 |
-
</div>
|
| 1117 |
-
) : (
|
| 1118 |
-
<Button
|
| 1119 |
-
onClick={startRenaming}
|
| 1120 |
-
size="sm"
|
| 1121 |
-
variant="ghost"
|
| 1122 |
-
className="w-full justify-start"
|
| 1123 |
-
disabled={isLoading}
|
| 1124 |
-
>
|
| 1125 |
-
<Settings className="h-4 w-4 mr-2" />
|
| 1126 |
-
Rename "{selectedAssistant.name}"
|
| 1127 |
-
</Button>
|
| 1128 |
-
)}
|
| 1129 |
-
</>
|
| 1130 |
)}
|
| 1131 |
|
| 1132 |
{/* Save Current Configuration */}
|
|
|
|
| 98 |
// Saved assistants state
|
| 99 |
const [savedAssistants, setSavedAssistants] = useState<any[]>([])
|
| 100 |
const [selectedAssistant, setSelectedAssistant] = useState<{id: string, name: string, type: 'user'|'template'|'new', originalTemplate?: string} | null>(null)
|
|
|
|
|
|
|
| 101 |
|
| 102 |
// Save assistant dialog state
|
| 103 |
const [showSaveDialog, setShowSaveDialog] = useState(false)
|
| 104 |
const [saveAssistantName, setSaveAssistantName] = useState('')
|
| 105 |
+
|
| 106 |
+
// Rename assistant dialog state
|
| 107 |
+
const [showRenameDialog, setShowRenameDialog] = useState(false)
|
| 108 |
+
const [renameAssistantName, setRenameAssistantName] = useState('')
|
| 109 |
|
| 110 |
// Load saved assistants
|
| 111 |
const loadSavedAssistants = () => {
|
|
|
|
| 230 |
name: 'New Assistant',
|
| 231 |
type: 'new'
|
| 232 |
})
|
|
|
|
| 233 |
}
|
| 234 |
|
| 235 |
// Clear current assistant
|
|
|
|
| 237 |
setSelectedAssistant(null)
|
| 238 |
}
|
| 239 |
|
| 240 |
+
// Open rename assistant dialog
|
| 241 |
+
const openRenameDialog = () => {
|
| 242 |
if (selectedAssistant) {
|
| 243 |
+
setRenameAssistantName(selectedAssistant.name)
|
| 244 |
+
setShowRenameDialog(true)
|
| 245 |
}
|
| 246 |
}
|
| 247 |
|
| 248 |
+
// Confirm rename assistant
|
| 249 |
+
const confirmRenameAssistant = () => {
|
| 250 |
+
if (!selectedAssistant || !renameAssistantName.trim()) return
|
| 251 |
+
|
| 252 |
+
// Update selectedAssistant state
|
| 253 |
+
const updatedAssistant = {
|
| 254 |
+
...selectedAssistant,
|
| 255 |
+
name: renameAssistantName.trim()
|
| 256 |
}
|
| 257 |
+
setSelectedAssistant(updatedAssistant)
|
| 258 |
+
|
| 259 |
+
// If it's a saved user assistant, update localStorage
|
| 260 |
+
if (selectedAssistant.type === 'user') {
|
| 261 |
+
const updatedAssistants = savedAssistants.map(assistant =>
|
| 262 |
+
assistant.id === selectedAssistant.id
|
| 263 |
+
? { ...assistant, name: renameAssistantName.trim() }
|
| 264 |
+
: assistant
|
| 265 |
+
)
|
| 266 |
+
setSavedAssistants(updatedAssistants)
|
| 267 |
+
localStorage.setItem('savedAssistants', JSON.stringify(updatedAssistants))
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
// Close dialog
|
| 271 |
+
setShowRenameDialog(false)
|
| 272 |
+
setRenameAssistantName('')
|
| 273 |
}
|
| 274 |
|
| 275 |
+
// Cancel rename dialog
|
| 276 |
+
const cancelRenameDialog = () => {
|
| 277 |
+
setShowRenameDialog(false)
|
| 278 |
+
setRenameAssistantName('')
|
| 279 |
}
|
| 280 |
|
| 281 |
// Convert template to new assistant when settings change
|
|
|
|
| 644 |
selectedAssistant={selectedAssistant}
|
| 645 |
createNewAssistant={createNewAssistant}
|
| 646 |
clearCurrentAssistant={clearCurrentAssistant}
|
| 647 |
+
openRenameDialog={openRenameDialog}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
systemPrompt={systemPrompt}
|
| 649 |
/>
|
| 650 |
</div>
|
|
|
|
| 762 |
</AlertDialogFooter>
|
| 763 |
</AlertDialogContent>
|
| 764 |
</AlertDialog>
|
| 765 |
+
|
| 766 |
+
{/* Rename Assistant Dialog */}
|
| 767 |
+
<AlertDialog open={showRenameDialog} onOpenChange={setShowRenameDialog}>
|
| 768 |
+
<AlertDialogContent>
|
| 769 |
+
<AlertDialogHeader>
|
| 770 |
+
<AlertDialogTitle>Rename Assistant</AlertDialogTitle>
|
| 771 |
+
<AlertDialogDescription>
|
| 772 |
+
Enter a new name for "{selectedAssistant?.name}".
|
| 773 |
+
</AlertDialogDescription>
|
| 774 |
+
</AlertDialogHeader>
|
| 775 |
+
<div className="py-4">
|
| 776 |
+
<Label htmlFor="rename-assistant-name" className="text-sm font-medium">
|
| 777 |
+
Assistant Name
|
| 778 |
+
</Label>
|
| 779 |
+
<input
|
| 780 |
+
id="rename-assistant-name"
|
| 781 |
+
type="text"
|
| 782 |
+
value={renameAssistantName}
|
| 783 |
+
onChange={(e) => setRenameAssistantName(e.target.value)}
|
| 784 |
+
className="mt-2 w-full px-3 py-2 text-sm border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring"
|
| 785 |
+
placeholder="Enter new assistant name..."
|
| 786 |
+
maxLength={100}
|
| 787 |
+
autoFocus
|
| 788 |
+
onKeyDown={(e) => {
|
| 789 |
+
if (e.key === 'Enter' && renameAssistantName.trim()) {
|
| 790 |
+
confirmRenameAssistant()
|
| 791 |
+
}
|
| 792 |
+
if (e.key === 'Escape') {
|
| 793 |
+
cancelRenameDialog()
|
| 794 |
+
}
|
| 795 |
+
}}
|
| 796 |
+
/>
|
| 797 |
+
<div className="mt-1 text-xs text-muted-foreground">
|
| 798 |
+
{renameAssistantName.length}/100 characters
|
| 799 |
+
</div>
|
| 800 |
+
</div>
|
| 801 |
+
<AlertDialogFooter>
|
| 802 |
+
<AlertDialogCancel onClick={cancelRenameDialog}>
|
| 803 |
+
Cancel
|
| 804 |
+
</AlertDialogCancel>
|
| 805 |
+
<AlertDialogAction
|
| 806 |
+
onClick={confirmRenameAssistant}
|
| 807 |
+
disabled={!renameAssistantName.trim()}
|
| 808 |
+
>
|
| 809 |
+
<Settings className="h-4 w-4 mr-2" />
|
| 810 |
+
Rename
|
| 811 |
+
</AlertDialogAction>
|
| 812 |
+
</AlertDialogFooter>
|
| 813 |
+
</AlertDialogContent>
|
| 814 |
+
</AlertDialog>
|
| 815 |
</div>
|
| 816 |
)
|
| 817 |
}
|
|
|
|
| 977 |
selectedAssistant,
|
| 978 |
createNewAssistant,
|
| 979 |
clearCurrentAssistant,
|
| 980 |
+
openRenameDialog,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 981 |
systemPrompt
|
| 982 |
}: {
|
| 983 |
savedAssistants: any[]
|
|
|
|
| 989 |
selectedAssistant: {id: string, name: string, type: 'user'|'template'|'new', originalTemplate?: string} | null
|
| 990 |
createNewAssistant: () => void
|
| 991 |
clearCurrentAssistant: () => void
|
| 992 |
+
openRenameDialog: () => void
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 993 |
systemPrompt: string
|
| 994 |
}) {
|
| 995 |
const handleAssistantSelect = (value: string) => {
|
|
|
|
| 1141 |
</Select>
|
| 1142 |
</div>
|
| 1143 |
|
| 1144 |
+
{/* Rename Assistant */}
|
| 1145 |
{selectedAssistant && selectedAssistant.type !== 'template' && (
|
| 1146 |
+
<Button
|
| 1147 |
+
onClick={openRenameDialog}
|
| 1148 |
+
size="sm"
|
| 1149 |
+
variant="ghost"
|
| 1150 |
+
className="w-full justify-start"
|
| 1151 |
+
disabled={isLoading}
|
| 1152 |
+
>
|
| 1153 |
+
<Settings className="h-4 w-4 mr-2" />
|
| 1154 |
+
Rename
|
| 1155 |
+
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1156 |
)}
|
| 1157 |
|
| 1158 |
{/* Save Current Configuration */}
|
static/assets/index-cfecd2e3.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/assets/index-cfecd2e3.js.map
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
-
<script type="module" crossorigin src="/assets/index-
|
| 9 |
<link rel="stylesheet" href="/assets/index-b386becc.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
|
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
+
<script type="module" crossorigin src="/assets/index-cfecd2e3.js"></script>
|
| 9 |
<link rel="stylesheet" href="/assets/index-b386becc.css">
|
| 10 |
</head>
|
| 11 |
<body>
|