1- import React , { useState } from "react"
2- import { Plus , Globe , Folder , Settings } from "lucide-react"
1+ import React from "react"
2+ import { Globe , Folder , Settings } from "lucide-react"
33
44import type { Command } from "@roo/ExtensionMessage"
55
66import { useAppTranslation } from "@/i18n/TranslationContext"
77import { useExtensionState } from "@/context/ExtensionStateContext"
8- import {
9- AlertDialog ,
10- AlertDialogAction ,
11- AlertDialogCancel ,
12- AlertDialogContent ,
13- AlertDialogDescription ,
14- AlertDialogFooter ,
15- AlertDialogHeader ,
16- AlertDialogTitle ,
17- Button ,
18- } from "@/components/ui"
8+ import { Button , StandardTooltip } from "@/components/ui"
199import { vscode } from "@/utils/vscode"
2010
21- import { SlashCommandItem } from "./SlashCommandItem "
11+ import { SlashCommandItemSimple } from "./SlashCommandItemSimple "
2212
2313interface SlashCommandsListProps {
2414 commands : Command [ ]
2515 onRefresh : ( ) => void
2616}
2717
28- export const SlashCommandsList : React . FC < SlashCommandsListProps > = ( { commands, onRefresh } ) => {
18+ export const SlashCommandsList : React . FC < SlashCommandsListProps > = ( { commands } ) => {
2919 const { t } = useAppTranslation ( )
3020 const { cwd } = useExtensionState ( )
31- const [ deleteDialogOpen , setDeleteDialogOpen ] = useState ( false )
32- const [ commandToDelete , setCommandToDelete ] = useState < Command | null > ( null )
33- const [ globalNewName , setGlobalNewName ] = useState ( "" )
34- const [ workspaceNewName , setWorkspaceNewName ] = useState ( "" )
3521
3622 // Check if we're in a workspace/project
3723 const hasWorkspace = Boolean ( cwd )
3824
39- const handleDeleteClick = ( command : Command ) => {
40- setCommandToDelete ( command )
41- setDeleteDialogOpen ( true )
42- }
43-
44- const handleDeleteConfirm = ( ) => {
45- if ( commandToDelete ) {
46- vscode . postMessage ( {
47- type : "deleteCommand" ,
48- text : commandToDelete . name ,
49- values : { source : commandToDelete . source } ,
50- } )
51- setDeleteDialogOpen ( false )
52- setCommandToDelete ( null )
53- // Refresh the commands list after deletion
54- setTimeout ( onRefresh , 100 )
55- }
56- }
57-
58- const handleDeleteCancel = ( ) => {
59- setDeleteDialogOpen ( false )
60- setCommandToDelete ( null )
61- }
62-
63- const handleCreateCommand = ( source : "global" | "project" , name : string ) => {
64- if ( ! name . trim ( ) ) return
65-
66- // Append .md if not already present
67- const fileName = name . trim ( ) . endsWith ( ".md" ) ? name . trim ( ) : `${ name . trim ( ) } .md`
68-
25+ const handleOpenSettings = ( ) => {
26+ // Send message to open settings with the slashCommands tab
6927 vscode . postMessage ( {
70- type : "createCommand " ,
71- text : fileName ,
72- values : { source } ,
28+ type : "switchTab " ,
29+ tab : "settings" ,
30+ values : { section : "slashCommands" } ,
7331 } )
74-
75- // Clear the input and refresh
76- if ( source === "global" ) {
77- setGlobalNewName ( "" )
78- } else {
79- setWorkspaceNewName ( "" )
80- }
81- setTimeout ( onRefresh , 500 )
8232 }
8333
8434 const handleCommandClick = ( command : Command ) => {
@@ -96,6 +46,22 @@ export const SlashCommandsList: React.FC<SlashCommandsListProps> = ({ commands,
9646
9747 return (
9848 < >
49+ { /* Header with settings button */ }
50+ < div className = "flex items-center justify-between px-3 py-2 border-b border-vscode-dropdown-border" >
51+ < span className = "text-xs font-medium text-vscode-descriptionForeground" >
52+ { t ( "chat:slashCommands.title" ) }
53+ </ span >
54+ < StandardTooltip content = { t ( "chat:slashCommands.manageCommands" ) } >
55+ < Button
56+ variant = "ghost"
57+ size = "icon"
58+ onClick = { handleOpenSettings }
59+ className = "h-6 w-6 p-0 opacity-60 hover:opacity-100" >
60+ < Settings className = "w-3.5 h-3.5" />
61+ </ Button >
62+ </ StandardTooltip >
63+ </ div >
64+
9965 { /* Commands list */ }
10066 < div className = "max-h-[300px] overflow-y-auto" >
10167 < div className = "py-1" >
@@ -105,37 +71,12 @@ export const SlashCommandsList: React.FC<SlashCommandsListProps> = ({ commands,
10571 { t ( "chat:slashCommands.globalCommands" ) }
10672 </ div >
10773 { globalCommands . map ( ( command ) => (
108- < SlashCommandItem
74+ < SlashCommandItemSimple
10975 key = { `global-${ command . name } ` }
11076 command = { command }
111- onDelete = { handleDeleteClick }
11277 onClick = { handleCommandClick }
11378 />
11479 ) ) }
115- { /* New global command input */ }
116- < div className = "px-4 py-2 flex items-center gap-2 hover:bg-vscode-list-hoverBackground" >
117- < input
118- type = "text"
119- value = { globalNewName }
120- onChange = { ( e ) => setGlobalNewName ( e . target . value ) }
121- placeholder = { t ( "chat:slashCommands.newGlobalCommandPlaceholder" ) }
122- className = "flex-1 bg-transparent text-vscode-input-foreground placeholder-vscode-input-placeholderForeground border-none outline-none focus:outline-0 text-sm"
123- tabIndex = { - 1 }
124- onKeyDown = { ( e ) => {
125- if ( e . key === "Enter" ) {
126- handleCreateCommand ( "global" , globalNewName )
127- }
128- } }
129- />
130- < Button
131- variant = "ghost"
132- size = "icon"
133- onClick = { ( ) => handleCreateCommand ( "global" , globalNewName ) }
134- disabled = { ! globalNewName . trim ( ) }
135- className = "size-6 flex items-center justify-center opacity-60 hover:opacity-100" >
136- < Plus className = "w-4 h-4" />
137- </ Button >
138- </ div >
13980
14081 { /* Workspace Commands Section - Only show if in a workspace */ }
14182 { hasWorkspace && (
@@ -145,37 +86,12 @@ export const SlashCommandsList: React.FC<SlashCommandsListProps> = ({ commands,
14586 { t ( "chat:slashCommands.workspaceCommands" ) }
14687 </ div >
14788 { projectCommands . map ( ( command ) => (
148- < SlashCommandItem
89+ < SlashCommandItemSimple
14990 key = { `project-${ command . name } ` }
15091 command = { command }
151- onDelete = { handleDeleteClick }
15292 onClick = { handleCommandClick }
15393 />
15494 ) ) }
155- { /* New workspace command input */ }
156- < div className = "px-4 py-2 flex items-center gap-2 hover:bg-vscode-list-hoverBackground" >
157- < input
158- type = "text"
159- value = { workspaceNewName }
160- onChange = { ( e ) => setWorkspaceNewName ( e . target . value ) }
161- placeholder = { t ( "chat:slashCommands.newWorkspaceCommandPlaceholder" ) }
162- className = "flex-1 bg-transparent text-vscode-input-foreground placeholder-vscode-input-placeholderForeground border-none outline-none focus:outline-0 text-sm"
163- tabIndex = { - 1 }
164- onKeyDown = { ( e ) => {
165- if ( e . key === "Enter" ) {
166- handleCreateCommand ( "project" , workspaceNewName )
167- }
168- } }
169- />
170- < Button
171- variant = "ghost"
172- size = "icon"
173- onClick = { ( ) => handleCreateCommand ( "project" , workspaceNewName ) }
174- disabled = { ! workspaceNewName . trim ( ) }
175- className = "size-6 flex items-center justify-center opacity-60 hover:opacity-100" >
176- < Plus className = "w-4 h-4" />
177- </ Button >
178- </ div >
17995 </ >
18096 ) }
18197
@@ -187,36 +103,16 @@ export const SlashCommandsList: React.FC<SlashCommandsListProps> = ({ commands,
187103 { t ( "chat:slashCommands.builtInCommands" ) }
188104 </ div >
189105 { builtInCommands . map ( ( command ) => (
190- < SlashCommandItem
106+ < SlashCommandItemSimple
191107 key = { `built-in-${ command . name } ` }
192108 command = { command }
193- onDelete = { handleDeleteClick }
194109 onClick = { handleCommandClick }
195110 />
196111 ) ) }
197112 </ >
198113 ) }
199114 </ div >
200115 </ div >
201-
202- < AlertDialog open = { deleteDialogOpen } onOpenChange = { setDeleteDialogOpen } >
203- < AlertDialogContent >
204- < AlertDialogHeader >
205- < AlertDialogTitle > { t ( "chat:slashCommands.deleteDialog.title" ) } </ AlertDialogTitle >
206- < AlertDialogDescription >
207- { t ( "chat:slashCommands.deleteDialog.description" , { name : commandToDelete ?. name } ) }
208- </ AlertDialogDescription >
209- </ AlertDialogHeader >
210- < AlertDialogFooter >
211- < AlertDialogCancel onClick = { handleDeleteCancel } >
212- { t ( "chat:slashCommands.deleteDialog.cancel" ) }
213- </ AlertDialogCancel >
214- < AlertDialogAction onClick = { handleDeleteConfirm } >
215- { t ( "chat:slashCommands.deleteDialog.confirm" ) }
216- </ AlertDialogAction >
217- </ AlertDialogFooter >
218- </ AlertDialogContent >
219- </ AlertDialog >
220116 </ >
221117 )
222118}
0 commit comments