33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import './media/chatSessions.css' ;
6+ import { $ , append , clearNode , getActiveWindow } from '../../../../base/browser/dom.js' ;
7+ import { ActionBar } from '../../../../base/browser/ui/actionbar/actionbar.js' ;
8+ import { IListVirtualDelegate } from '../../../../base/browser/ui/list/list.js' ;
9+ import { IAsyncDataSource , ITreeNode , ITreeRenderer } from '../../../../base/browser/ui/tree/tree.js' ;
10+ import { coalesce } from '../../../../base/common/arrays.js' ;
11+ import { CancellationToken } from '../../../../base/common/cancellation.js' ;
12+ import { Codicon } from '../../../../base/common/codicons.js' ;
13+ import { Emitter , Event } from '../../../../base/common/event.js' ;
14+ import { FuzzyScore } from '../../../../base/common/filters.js' ;
15+ import { Disposable , DisposableStore } from '../../../../base/common/lifecycle.js' ;
16+ import { MarshalledId } from '../../../../base/common/marshallingIds.js' ;
17+ import { ThemeIcon } from '../../../../base/common/themables.js' ;
18+ import { URI } from '../../../../base/common/uri.js' ;
719import * as nls from '../../../../nls.js' ;
20+ import { getActionBarActions } from '../../../../platform/actions/browser/menuEntryActionViewItem.js' ;
21+ import { IMenuService , MenuId , MenuRegistry } from '../../../../platform/actions/common/actions.js' ;
822import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js' ;
23+ import { ContextKeyExpr , IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js' ;
924import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js' ;
25+ import { IHoverService } from '../../../../platform/hover/browser/hover.js' ;
1026import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js' ;
1127import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js' ;
28+ import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js' ;
29+ import { WorkbenchAsyncDataTree } from '../../../../platform/list/browser/listService.js' ;
1230import { ILogService } from '../../../../platform/log/common/log.js' ;
31+ import { IOpenerService } from '../../../../platform/opener/common/opener.js' ;
1332import { IProgressService } from '../../../../platform/progress/common/progress.js' ;
1433import { Registry } from '../../../../platform/registry/common/platform.js' ;
1534import { IStorageService } from '../../../../platform/storage/common/storage.js' ;
1635import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js' ;
36+ import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js' ;
1737import { IThemeService } from '../../../../platform/theme/common/themeService.js' ;
1838import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js' ;
19- import { IContextKeyService , ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js' ;
20- import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js' ;
21- import { IOpenerService } from '../../../../platform/opener/common/opener.js' ;
22- import { IHoverService } from '../../../../platform/hover/browser/hover.js' ;
23- import { IMenuService , MenuId , MenuRegistry } from '../../../../platform/actions/common/actions.js' ;
24- import { getActionBarActions } from '../../../../platform/actions/browser/menuEntryActionViewItem.js' ;
25- import { Disposable , DisposableStore } from '../../../../base/common/lifecycle.js' ;
39+ import { fillEditorsDragData } from '../../../browser/dnd.js' ;
40+ import { IResourceLabel , ResourceLabels } from '../../../browser/labels.js' ;
41+ import { IViewPaneOptions , ViewPane } from '../../../browser/parts/views/viewPane.js' ;
2642import { ViewPaneContainer } from '../../../browser/parts/views/viewPaneContainer.js' ;
27- import { MarshalledId } from '../../../../base/common/marshallingIds.js' ;
28- import { ViewPane , IViewPaneOptions } from '../../../browser/parts/views/viewPane.js' ;
29- import { Extensions , IViewContainersRegistry , IViewDescriptorService , ViewContainerLocation , IViewsRegistry , IViewDescriptor } from '../../../common/views.js' ;
43+ import { IWorkbenchContribution } from '../../../common/contributions.js' ;
44+ import { GroupModelChangeKind } from '../../../common/editor.js' ;
45+ import { EditorInput } from '../../../common/editor/editorInput.js' ;
46+ import { Extensions , IViewContainersRegistry , IViewDescriptor , IViewDescriptorService , IViewsRegistry , ViewContainerLocation } from '../../../common/views.js' ;
47+ import { IEditorGroup , IEditorGroupsService } from '../../../services/editor/common/editorGroupsService.js' ;
48+ import { IEditorService } from '../../../services/editor/common/editorService.js' ;
3049import { IExtensionService } from '../../../services/extensions/common/extensions.js' ;
3150import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js' ;
32- import { WorkbenchAsyncDataTree } from '../../../../platform/list/browser/listService.js' ;
33- import { IChatSessionItem , IChatSessionItemProvider , IChatSessionsExtensionPoint , IChatSessionsService } from '../common/chatSessionsService.js' ;
51+ import { IViewsService } from '../../../services/views/common/viewsService.js' ;
3452import { ChatContextKeys } from '../common/chatContextKeys.js' ;
35- import { IAsyncDataSource , ITreeRenderer , ITreeNode } from '../../../../base/browser/ui/tree/tree.js' ;
36- import { IListVirtualDelegate } from '../../../../base/browser/ui/list/list.js' ;
37- import { CancellationToken } from '../../../../base/common/cancellation.js' ;
38- import { FuzzyScore } from '../../../../base/common/filters.js' ;
39- import { ResourceLabels , IResourceLabel } from '../../../browser/labels.js' ;
40- import { ActionBar } from '../../../../base/browser/ui/actionbar/actionbar.js' ;
41- import { append , $ , getActiveWindow , clearNode } from '../../../../base/browser/dom.js' ;
42- import { URI } from '../../../../base/common/uri.js' ;
43- import { IEditorGroupsService , IEditorGroup } from '../../../services/editor/common/editorGroupsService.js' ;
44- import { GroupModelChangeKind } from '../../../common/editor.js' ;
45- import { Emitter , Event } from '../../../../base/common/event.js' ;
46- import { Codicon } from '../../../../base/common/codicons.js' ;
47- import { IEditorService } from '../../../services/editor/common/editorService.js' ;
48- import { EditorInput } from '../../../common/editor/editorInput.js' ;
49- import { ChatEditorInput } from './chatEditorInput.js' ;
50- import { IChatWidgetService , IChatWidget } from './chat.js' ;
53+ import { IChatSessionItem , IChatSessionItemProvider , IChatSessionsExtensionPoint , IChatSessionsService } from '../common/chatSessionsService.js' ;
54+ import { ChatSessionUri } from '../common/chatUri.js' ;
5155import { ChatAgentLocation , ChatConfiguration } from '../common/constants.js' ;
52- import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js' ;
53- import { IWorkbenchContribution } from '../../../common/contributions.js' ;
54- import { IViewsService } from '../../../services/views/common/viewsService.js' ;
55- import { ThemeIcon } from '../../../../base/common/themables.js' ;
56+ import { IChatWidget , IChatWidgetService } from './chat.js' ;
5657import { IChatEditorOptions } from './chatEditor.js' ;
57- import { ChatSessionUri } from '../common/chatUri .js' ;
58- import { coalesce } from '../../../../base/common/arrays.js ';
58+ import { ChatEditorInput } from './chatEditorInput .js' ;
59+ import './media/chatSessions.css ';
5960
6061export const VIEWLET_ID = 'workbench.view.chat.sessions' ;
6162
63+ type ChatSessionItemWithProvider = IChatSessionItem & {
64+ readonly provider : IChatSessionItemProvider ;
65+ } ;
66+
6267// Helper function to create context overlay for session items
6368function getSessionItemContextOverlay ( session : IChatSessionItem , provider ?: IChatSessionItemProvider ) : [ string , any ] [ ] {
6469 const overlay : [ string , any ] [ ] = [ ] ;
@@ -517,18 +522,19 @@ class ChatSessionsViewPaneContainer extends ViewPaneContainer {
517522 }
518523}
519524
525+
520526// Chat sessions item data source for the tree
521- class SessionsDataSource implements IAsyncDataSource < IChatSessionItemProvider , IChatSessionItem > {
527+ class SessionsDataSource implements IAsyncDataSource < IChatSessionItemProvider , ChatSessionItemWithProvider > {
522528 constructor (
523529 private readonly provider : IChatSessionItemProvider
524530 ) { }
525531
526- hasChildren ( element : IChatSessionItemProvider | IChatSessionItem ) : boolean {
532+ hasChildren ( element : IChatSessionItemProvider | ChatSessionItemWithProvider ) : boolean {
527533 // Only the provider (root) has children
528534 return element === this . provider ;
529535 }
530536
531- async getChildren ( element : IChatSessionItemProvider | IChatSessionItem ) : Promise < IChatSessionItem [ ] > {
537+ async getChildren ( element : IChatSessionItemProvider | ChatSessionItemWithProvider ) : Promise < ChatSessionItemWithProvider [ ] > {
532538 if ( element === this . provider ) {
533539 try {
534540 const items = await this . provider . provideChatSessionItems ( CancellationToken . None ) ;
@@ -645,7 +651,7 @@ class SessionsRenderer extends Disposable implements ITreeRenderer<IChatSessionI
645651
646652 renderElement ( element : ITreeNode < IChatSessionItem , FuzzyScore > , index : number , templateData : ISessionTemplateData ) : void {
647653 const session = element . element ;
648- const sessionWithProvider = session as IChatSessionItem & { provider : IChatSessionItemProvider } ;
654+ const sessionWithProvider = session as ChatSessionItemWithProvider ;
649655
650656 // Clear previous element disposables
651657 templateData . elementDisposable . clear ( ) ;
@@ -736,7 +742,7 @@ class SessionsRenderer extends Disposable implements ITreeRenderer<IChatSessionI
736742
737743// Sessions view pane for a specific provider
738744class SessionsViewPane extends ViewPane {
739- private tree ?: WorkbenchAsyncDataTree < IChatSessionItemProvider , IChatSessionItem , FuzzyScore > ;
745+ private tree ?: WorkbenchAsyncDataTree < IChatSessionItemProvider , ChatSessionItemWithProvider , FuzzyScore > ;
740746 private treeContainer ?: HTMLElement ;
741747 private dataSource ?: SessionsDataSource ;
742748 private labels ?: ResourceLabels ;
@@ -935,14 +941,41 @@ class SessionsViewPane extends ViewPane {
935941 const renderer = this . instantiationService . createInstance ( SessionsRenderer , this . labels ) ;
936942 this . _register ( renderer ) ;
937943
944+ const getResourceForElement = ( element : ChatSessionItemWithProvider ) : URI => {
945+ return ChatSessionUri . forSession ( element . provider . chatSessionType , element . id ) ;
946+ } ;
947+
938948 this . tree = this . instantiationService . createInstance (
939- WorkbenchAsyncDataTree ,
949+ WorkbenchAsyncDataTree < IChatSessionItemProvider , ChatSessionItemWithProvider , FuzzyScore > ,
940950 'SessionsTree' ,
941951 this . treeContainer ,
942952 delegate ,
943953 [ renderer ] ,
944954 this . dataSource ,
945955 {
956+ dnd : {
957+ onDragStart : ( data , originalEvent ) => {
958+ try {
959+ const elements = data . getData ( ) as ChatSessionItemWithProvider [ ] ;
960+ const uris = coalesce ( elements . map ( getResourceForElement ) ) ;
961+ this . instantiationService . invokeFunction ( accessor => fillEditorsDragData ( accessor , uris , originalEvent ) ) ;
962+ } catch {
963+ // noop
964+ }
965+ } ,
966+ getDragURI : ( element ) => {
967+ return getResourceForElement ( element ) . toString ( ) ;
968+ } ,
969+ getDragLabel : ( elements ) => {
970+ if ( elements . length === 1 ) {
971+ return elements [ 0 ] . label ;
972+ }
973+ return nls . localize ( 'chatSessions.dragLabel' , "{0} chat sessions" , elements . length ) ;
974+ } ,
975+ drop : ( ) => { } ,
976+ onDragOver : ( ) => false ,
977+ dispose : ( ) => { } ,
978+ } ,
946979 horizontalScrolling : false ,
947980 setRowLineHeight : false ,
948981 transformOptimization : false ,
@@ -956,14 +989,14 @@ class SessionsViewPane extends ViewPane {
956989 hideTwistiesOfChildlessElements : true ,
957990 allowNonCollapsibleParents : true // Allow nodes to be non-collapsible even if they have children
958991 }
959- ) as WorkbenchAsyncDataTree < IChatSessionItemProvider , IChatSessionItem , FuzzyScore > ;
992+ ) ;
960993
961994 this . logService . debug ( 'Tree created with hideTwistiesOfChildlessElements: true' ) ;
962995 this . _register ( this . tree ) ;
963996
964997 // Handle double-click and keyboard selection to open editors
965998 this . _register ( this . tree . onDidOpen ( async e => {
966- const element = e . element as IChatSessionItem & { provider : IChatSessionItemProvider } ;
999+ const element = e . element as ChatSessionItemWithProvider ;
9671000
9681001 if ( element && this . isLocalChatSessionItem ( element ) ) {
9691002 if ( element . sessionType === 'editor' && element . editor && element . group ) {
0 commit comments