@@ -64,12 +64,22 @@ export function ContextSelector({
6464 )
6565 : courses ;
6666
67- const hasWorkspaceExercise = exercises . some ( ex => ex . isWorkspace ) ;
67+ const workspaceExercise = exercises . find ( ex => ex . isWorkspace ) ;
68+ const workspaceCourse = workspaceExercise ?. courseId
69+ ? courses . find ( c => c . id === workspaceExercise . courseId )
70+ : undefined ;
71+
6872 const isInWorkspaceContext = context ?. source === 'workspace-detected' ;
73+ const isInWorkspaceCourseContext = ! ! workspaceCourse
74+ && context ?. type === 'course'
75+ && context . id === workspaceCourse . id ;
6976 const canCreateNewSession = sessions . length > 0 && sessions . some ( s => s . messageCount > 0 ) ;
7077 const activeSession = context ? sessions . find ( s => s . id === activeSessionId ) : undefined ;
7178 const messageCount = activeSession ?. messageCount || 0 ;
72- const showSessionsSection = context !== null && q . length === 0 ;
79+
80+ const showShortcuts = q . length === 0 ;
81+ const showConversationsSection = context !== null && q . length === 0 ;
82+ const showWorkspaceShortcuts = showShortcuts && ( workspaceExercise || workspaceCourse ) ;
7383
7484 const toggleDropdown = ( ) => {
7585 setIsOpen ( ! isOpen ) ;
@@ -171,60 +181,66 @@ export function ContextSelector({
171181 </ div >
172182
173183 < div className = { styles . dropdownContent } >
174- { showSessionsSection && (
184+ { showConversationsSection && (
175185 < div className = { styles . section } >
176- < div className = { styles . sectionHeader } > Sessions</ div >
177- { sessions . map ( session => (
178- < button
179- key = { session . id }
180- className = { clsx ( styles . sessionItem , {
181- [ styles . sessionItemActive ] :
182- session . id === activeSessionId ,
183- } ) }
184- onClick = { ( ) => handleSelectSession ( session . id ) }
185- >
186- < svg
187- width = "14"
188- height = "14"
189- viewBox = "0 0 24 24"
190- fill = "none"
191- className = { styles . sessionIcon }
192- >
193- < path
194- d = "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
195- stroke = "currentColor"
196- strokeWidth = "2"
197- strokeLinecap = "round"
198- strokeLinejoin = "round"
199- />
200- </ svg >
201- < div className = { styles . sessionContent } >
202- < span className = { styles . sessionPreview } >
203- { session . title || session . preview }
204- </ span >
205- < span className = { styles . sessionMeta } >
206- { session . messageCount } messages · { formatRelativeTime ( session . lastActivity ) }
207- </ span >
186+ { sessions . length > 0 && (
187+ < >
188+ < div className = { styles . sectionHeader } > Conversations</ div >
189+ < div className = { styles . sessionsScroll } >
190+ { sessions . map ( session => (
191+ < button
192+ key = { session . id }
193+ className = { clsx ( styles . sessionItem , {
194+ [ styles . sessionItemActive ] :
195+ session . id === activeSessionId ,
196+ } ) }
197+ onClick = { ( ) => handleSelectSession ( session . id ) }
198+ >
199+ < svg
200+ width = "14"
201+ height = "14"
202+ viewBox = "0 0 24 24"
203+ fill = "none"
204+ className = { styles . sessionIcon }
205+ >
206+ < path
207+ d = "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
208+ stroke = "currentColor"
209+ strokeWidth = "2"
210+ strokeLinecap = "round"
211+ strokeLinejoin = "round"
212+ />
213+ </ svg >
214+ < div className = { styles . sessionContent } >
215+ < span className = { styles . sessionPreview } >
216+ { session . title || session . preview }
217+ </ span >
218+ < span className = { styles . sessionMeta } >
219+ { session . messageCount } messages · { formatRelativeTime ( session . lastActivity ) }
220+ </ span >
221+ </ div >
222+ { session . id === activeSessionId && (
223+ < svg
224+ width = "16"
225+ height = "16"
226+ viewBox = "0 0 24 24"
227+ fill = "none"
228+ className = { styles . checkIcon }
229+ >
230+ < polyline
231+ points = "20 6 9 17 4 12"
232+ stroke = "currentColor"
233+ strokeWidth = "2"
234+ strokeLinecap = "round"
235+ strokeLinejoin = "round"
236+ />
237+ </ svg >
238+ ) }
239+ </ button >
240+ ) ) }
208241 </ div >
209- { session . id === activeSessionId && (
210- < svg
211- width = "16"
212- height = "16"
213- viewBox = "0 0 24 24"
214- fill = "none"
215- className = { styles . checkIcon }
216- >
217- < polyline
218- points = "20 6 9 17 4 12"
219- stroke = "currentColor"
220- strokeWidth = "2"
221- strokeLinecap = "round"
222- strokeLinejoin = "round"
223- />
224- </ svg >
225- ) }
226- </ button >
227- ) ) }
242+ </ >
243+ ) }
228244 < div className = { styles . actions } >
229245 < button
230246 className = { styles . actionButton }
@@ -242,7 +258,14 @@ export function ContextSelector({
242258 New Conversation
243259 </ span >
244260 </ button >
245- { hasWorkspaceExercise && (
261+ </ div >
262+ </ div >
263+ ) }
264+
265+ { showWorkspaceShortcuts && (
266+ < div className = { styles . section } >
267+ < div className = { styles . actions } >
268+ { workspaceExercise && (
246269 < button
247270 className = { styles . actionButton }
248271 disabled = { isInWorkspaceContext }
@@ -253,7 +276,33 @@ export function ContextSelector({
253276 >
254277 < span className = { styles . actionButtonContent } >
255278 < FolderGit2 size = { 14 } />
256- { isInWorkspaceContext ? 'Workspace Exercise (Active)' : 'Chat about Workspace Exercise' }
279+ { isInWorkspaceContext
280+ ? `Workspace Exercise (Active): ${ workspaceExercise . title } `
281+ : `Chat about Workspace Exercise: ${ workspaceExercise . title } ` }
282+ </ span >
283+ </ button >
284+ ) }
285+ { workspaceCourse && (
286+ < button
287+ className = { styles . actionButton }
288+ disabled = { isInWorkspaceCourseContext }
289+ onClick = { ( ) => {
290+ handleSelectContext (
291+ 'course' ,
292+ workspaceCourse . id ,
293+ workspaceCourse . title ,
294+ workspaceCourse . shortName
295+ ) ;
296+ } }
297+ >
298+ < span className = { styles . actionButtonContent } >
299+ < svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" >
300+ < path d = "M22 10v6M2 10l10-5 10 5-10 5z" />
301+ < path d = "M6 12v5c3 3 9 3 12 0v-5" />
302+ </ svg >
303+ { isInWorkspaceCourseContext
304+ ? `Workspace Course (Active): ${ workspaceCourse . title } `
305+ : `Chat about Workspace Course: ${ workspaceCourse . title } ` }
257306 </ span >
258307 </ button >
259308 ) }
@@ -264,57 +313,61 @@ export function ContextSelector({
264313 { filteredExercises . length > 0 && (
265314 < div className = { styles . section } >
266315 < div className = { styles . sectionHeader } > Exercises</ div >
267- { filteredExercises . map ( ( exercise ) => {
268- const courseTag = exercise . courseId ? courseShortById . get ( exercise . courseId ) : undefined ;
269- return (
316+ < div className = { styles . itemsScroll } >
317+ { filteredExercises . map ( ( exercise ) => {
318+ const courseTag = exercise . courseId ? courseShortById . get ( exercise . courseId ) : undefined ;
319+ return (
320+ < button
321+ key = { exercise . id }
322+ className = { styles . contextItem }
323+ onClick = { ( ) =>
324+ handleSelectContext (
325+ 'exercise' ,
326+ exercise . id ,
327+ exercise . title ,
328+ exercise . shortName
329+ )
330+ }
331+ >
332+ { exercise . isWorkspace && (
333+ < FolderGit2 size = { 14 } className = { styles . itemIcon } />
334+ ) }
335+ < span className = { styles . itemText } >
336+ { exercise . title }
337+ </ span >
338+ { courseTag && (
339+ < span className = { styles . itemTag } > { courseTag } </ span >
340+ ) }
341+ </ button >
342+ ) ;
343+ } ) }
344+ </ div >
345+ </ div >
346+ ) }
347+
348+ { filteredCourses . length > 0 && (
349+ < div className = { styles . section } >
350+ < div className = { styles . sectionHeader } > Courses</ div >
351+ < div className = { styles . itemsScroll } >
352+ { filteredCourses . map ( ( course ) => (
270353 < button
271- key = { exercise . id }
354+ key = { course . id }
272355 className = { styles . contextItem }
273356 onClick = { ( ) =>
274357 handleSelectContext (
275- 'exercise ' ,
276- exercise . id ,
277- exercise . title ,
278- exercise . shortName
358+ 'course ' ,
359+ course . id ,
360+ course . title ,
361+ course . shortName
279362 )
280363 }
281364 >
282- { exercise . isWorkspace && (
283- < FolderGit2 size = { 14 } className = { styles . itemIcon } />
284- ) }
285365 < span className = { styles . itemText } >
286- { exercise . title }
366+ { course . title }
287367 </ span >
288- { courseTag && (
289- < span className = { styles . itemTag } > { courseTag } </ span >
290- ) }
291368 </ button >
292- ) ;
293- } ) }
294- </ div >
295- ) }
296-
297- { filteredCourses . length > 0 && (
298- < div className = { styles . section } >
299- < div className = { styles . sectionHeader } > Courses</ div >
300- { filteredCourses . map ( ( course ) => (
301- < button
302- key = { course . id }
303- className = { styles . contextItem }
304- onClick = { ( ) =>
305- handleSelectContext (
306- 'course' ,
307- course . id ,
308- course . title ,
309- course . shortName
310- )
311- }
312- >
313- < span className = { styles . itemText } >
314- { course . title }
315- </ span >
316- </ button >
317- ) ) }
369+ ) ) }
370+ </ div >
318371 </ div >
319372 ) }
320373
0 commit comments