11import React , { useEffect , useState } from "react" ;
2- import { ActionIcon , Drawer , Text , Box , Flex , Divider } from "@mantine/core" ;
3- import { IconClock , IconChevronDown } from "@tabler/icons-react" ;
2+ import {
3+ ActionIcon ,
4+ Drawer ,
5+ Text ,
6+ Box ,
7+ Flex ,
8+ Divider ,
9+ LoadingOverlay ,
10+ } from "@mantine/core" ;
11+ import {
12+ IconClock ,
13+ IconChevronDown ,
14+ IconPlus ,
15+ IconRefresh ,
16+ IconTrash ,
17+ } from "@tabler/icons-react" ;
418import { useDisclosure } from "@mantine/hooks" ;
519import messageUtil from "@/util/MessageUtil" ;
620import dayjs from "dayjs" ;
21+ import { t } from "mobx-state-tree" ;
722
823export default function Topic ( { styleName } ) {
924 const [ drawerOpened , { open : openDrawer , close : closeDrawer } ] =
1025 useDisclosure ( false ) ;
11- const [ topicList , setTopicList ] = useState ( [ ] ) ;
26+ const [ loading , setLoading ] = useState ( false ) ;
27+ const [ topicList , setTopicList ] = useState < any > ( [ ] ) ;
1228
1329 useEffect ( ( ) => {
1430 messageUtil . sendMessage ( {
1531 command : "listTopics" ,
1632 } ) ;
1733 messageUtil . registerHandler ( "listTopics" , ( { list } : { list : any } ) => {
1834 setTopicList ( list ) ;
35+ setLoading ( false ) ;
1936 } ) ;
2037 } , [ ] ) ;
2138
@@ -27,12 +44,49 @@ export default function Topic({ styleName }) {
2744 } ) ;
2845 } ;
2946
47+ const refreshTopicList = ( ) => {
48+ setLoading ( true ) ;
49+ messageUtil . sendMessage ( {
50+ command : "listTopics" ,
51+ } ) ;
52+ } ;
53+
54+ const setNewTopic = ( ) => {
55+ messageUtil . sendMessage ( {
56+ command : "setNewTopic" ,
57+ } ) ;
58+ closeDrawer ( ) ;
59+ } ;
60+
61+ const deleteTopic = ( topicHash : string ) => {
62+ const newTopicList = topicList . filter (
63+ ( topic ) => topic . root_prompt . hash !== topicHash
64+ ) ;
65+ setTopicList ( newTopicList ) ;
66+ messageUtil . sendMessage ( {
67+ command : "deleteTopic" ,
68+ topicHash : topicHash ,
69+ } ) ;
70+ } ;
71+
3072 return (
3173 < >
3274 < Drawer
3375 opened = { drawerOpened }
3476 position = "bottom"
35- title = "Devchat Topic"
77+ title = {
78+ < Flex justify = "space-between" >
79+ < Text > Devchat Topic</ Text >
80+ < Flex >
81+ < ActionIcon onClick = { setNewTopic } >
82+ < IconPlus size = "1rem" />
83+ </ ActionIcon >
84+ < ActionIcon onClick = { refreshTopicList } >
85+ < IconRefresh size = "1rem" />
86+ </ ActionIcon >
87+ </ Flex >
88+ </ Flex >
89+ }
3690 onClose = { closeDrawer }
3791 overlayProps = { { opacity : 0.5 , blur : 4 } }
3892 closeButtonProps = { { children : < IconChevronDown size = "1rem" /> } }
@@ -46,57 +100,81 @@ export default function Topic({ styleName }) {
46100 background : "var(--vscode-sideBar-background)" ,
47101 color : "var(--vscode-editor-foreground)" ,
48102 } ,
103+ title : {
104+ flex : 1 ,
105+ } ,
49106 } }
50107 >
51108 { topicList . map ( ( item : any , index ) => (
52- < Box
53- sx = { {
54- cursor : "pointer" ,
55- } }
56- onClick = { ( ) => showTopic ( item ?. root_prompt ) }
57- >
58- < Flex justify = "space-between" gap = "sm" >
59- < Text
60- fz = "sm"
61- fw = { 700 }
109+ < Box >
110+ < Flex sx = { { width : "100%" } } gap = "sm" >
111+ < Box
62112 sx = { {
63- whiteSpace : "nowrap" ,
64- overflow : "hidden" ,
65- textOverflow : "ellipsis" ,
113+ cursor : "pointer" ,
66114 flex : 1 ,
67- } }
68- >
69- { item ?. root_prompt . title }
70- </ Text >
71- < Text
72- fz = "sm"
73- c = "dimmed"
74- sx = { {
75- whiteSpace : "nowrap" ,
76115 overflow : "hidden" ,
77- textOverflow : "ellipsis" ,
78116 } }
117+ onClick = { ( ) => showTopic ( item ?. root_prompt ) }
79118 >
80- { dayjs ( item ?. latest_time * 1000 ) . format ( "MM-DD HH:mm:ss" ) }
81- </ Text >
82- </ Flex >
119+ < Flex justify = "space-between" gap = "sm" >
120+ < Text
121+ fz = "sm"
122+ fw = { 700 }
123+ sx = { {
124+ whiteSpace : "nowrap" ,
125+ overflow : "hidden" ,
126+ textOverflow : "ellipsis" ,
127+ flex : 1 ,
128+ } }
129+ >
130+ { item ?. root_prompt . title }
131+ </ Text >
132+ < Text
133+ fz = "sm"
134+ c = "dimmed"
135+ sx = { {
136+ whiteSpace : "nowrap" ,
137+ overflow : "hidden" ,
138+ textOverflow : "ellipsis" ,
139+ } }
140+ >
141+ { dayjs ( item ?. latest_time * 1000 ) . format ( "MM-DD HH:mm:ss" ) }
142+ </ Text >
143+ </ Flex >
83144
84- < Text
85- c = "dimmed"
86- fz = "sm"
87- sx = { {
88- whiteSpace : "nowrap" ,
89- overflow : "hidden" ,
90- textOverflow : "ellipsis" ,
91- } }
92- >
93- { item ?. root_prompt . responses ?. [ 0 ] }
94- </ Text >
145+ < Text
146+ c = "dimmed"
147+ fz = "sm"
148+ sx = { {
149+ whiteSpace : "nowrap" ,
150+ overflow : "hidden" ,
151+ textOverflow : "ellipsis" ,
152+ } }
153+ >
154+ { item ?. root_prompt . responses ?. [ 0 ] }
155+ </ Text >
156+ </ Box >
157+ < Flex align = "center" >
158+ < ActionIcon
159+ onClick = { ( ) => {
160+ deleteTopic ( item ?. root_prompt . hash ) ;
161+ } }
162+ >
163+ < IconTrash size = "1rem" />
164+ </ ActionIcon >
165+ </ Flex >
166+ </ Flex >
95167 { index !== topicList . length - 1 && (
96168 < Divider variant = "solid" my = { 6 } opacity = "0.5" />
97169 ) }
98170 </ Box >
99171 ) ) }
172+ < LoadingOverlay
173+ visible = { loading }
174+ overlayBlur = { 3 }
175+ overlayOpacity = { 0 }
176+ keepMounted = { true }
177+ />
100178 </ Drawer >
101179 < ActionIcon
102180 className = { styleName }
0 commit comments