Skip to content

Commit 724eea7

Browse files
authored
Merge pull request microsoft#258909 from microsoft/osortega/chat-session-empty-message
Chat sessions empty message
2 parents b234a54 + 4c63eb1 commit 724eea7

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

src/vs/workbench/contrib/chat/browser/chatSessions.ts

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { FuzzyScore } from '../../../../base/common/filters.js';
3434
import { ResourceLabels, IResourceLabel } from '../../../browser/labels.js';
3535
import { ActionBar } from '../../../../base/browser/ui/actionbar/actionbar.js';
3636
import { Disposable } from '../../../../base/common/lifecycle.js';
37-
import { append, $, getActiveWindow } from '../../../../base/browser/dom.js';
37+
import { append, $, getActiveWindow, clearNode } from '../../../../base/browser/dom.js';
3838
import { URI } from '../../../../base/common/uri.js';
3939
import { IEditorGroupsService, IEditorGroup } from '../../../services/editor/common/editorGroupsService.js';
4040
import { GroupModelChangeKind } from '../../../common/editor.js';
@@ -673,6 +673,7 @@ class SessionsViewPane extends ViewPane {
673673
private treeContainer?: HTMLElement;
674674
private dataSource?: SessionsDataSource;
675675
private labels?: ResourceLabels;
676+
private messageElement?: HTMLElement;
676677

677678
constructor(
678679
private readonly provider: IChatSessionItemProvider,
@@ -690,6 +691,7 @@ class SessionsViewPane extends ViewPane {
690691
@IViewsService private readonly viewsService: IViewsService,
691692
@ILogService private readonly logService: ILogService,
692693
@IProgressService private readonly progressService: IProgressService,
694+
@IChatSessionsService private readonly chatSessionsService: IChatSessionsService,
693695
) {
694696
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService);
695697

@@ -713,6 +715,84 @@ class SessionsViewPane extends ViewPane {
713715
}
714716
}
715717

718+
private getProviderDisplayName(): string {
719+
const contributions = this.chatSessionsService.getChatSessionContributions();
720+
const contribution = contributions.find(c => c.type === this.provider.chatSessionType);
721+
if (contribution) {
722+
return contribution.displayName;
723+
}
724+
return '';
725+
}
726+
727+
private showEmptyMessage(): void {
728+
if (!this.messageElement) {
729+
return;
730+
}
731+
732+
// Only show message for non-local providers
733+
if (this.provider.chatSessionType === 'local') {
734+
this.hideMessage();
735+
return;
736+
}
737+
738+
const providerName = this.getProviderDisplayName();
739+
if (!providerName) {
740+
return;
741+
}
742+
743+
const messageText = nls.localize('chatSessions.noResults', "No sessions found from {0}", providerName);
744+
745+
// Clear the message element using DOM utility
746+
clearNode(this.messageElement);
747+
748+
const messageContainer = append(this.messageElement, $('.no-sessions-message'));
749+
750+
append(messageContainer, $('.codicon.codicon-info'));
751+
const textElement = append(messageContainer, $('span'));
752+
textElement.textContent = messageText;
753+
754+
// Show the message element
755+
this.messageElement.style.display = 'block';
756+
757+
// Hide the tree
758+
if (this.treeContainer) {
759+
this.treeContainer.style.display = 'none';
760+
}
761+
}
762+
763+
private hideMessage(): void {
764+
if (this.messageElement) {
765+
this.messageElement.style.display = 'none';
766+
}
767+
768+
// Show the tree
769+
if (this.treeContainer) {
770+
this.treeContainer.style.display = 'block';
771+
}
772+
}
773+
774+
/**
775+
* Updates the empty state message based on current tree data.
776+
* Uses the tree's existing data to avoid redundant provider calls.
777+
*/
778+
private updateEmptyStateMessage(): void {
779+
try {
780+
// Check if the tree has the provider node and get its children count
781+
if (this.tree?.hasNode(this.provider)) {
782+
const providerNode = this.tree.getNode(this.provider);
783+
const childCount = providerNode.children?.length || 0;
784+
785+
if (childCount === 0) {
786+
this.showEmptyMessage();
787+
} else {
788+
this.hideMessage();
789+
}
790+
}
791+
} catch (error) {
792+
this.logService.error('Error checking tree data for empty state:', error);
793+
}
794+
}
795+
716796
/**
717797
* Refreshes the tree data with progress indication.
718798
* Shows a progress indicator while the tree updates its children from the provider.
@@ -732,6 +812,9 @@ class SessionsViewPane extends ViewPane {
732812
await this.tree!.updateChildren(this.provider);
733813
}
734814
);
815+
816+
// Check for empty state after refresh using tree data
817+
this.updateEmptyStateMessage();
735818
} catch (error) {
736819
// Log error but don't throw to avoid breaking the UI
737820
this.logService.error('Error refreshing chat sessions tree:', error);
@@ -757,6 +840,9 @@ class SessionsViewPane extends ViewPane {
757840
await this.tree!.setInput(this.provider);
758841
}
759842
);
843+
844+
// Check for empty state after loading using tree data
845+
this.updateEmptyStateMessage();
760846
} catch (error) {
761847
// Log error but don't throw to avoid breaking the UI
762848
this.logService.error('Error loading chat sessions data:', error);
@@ -766,6 +852,10 @@ class SessionsViewPane extends ViewPane {
766852
protected override renderBody(container: HTMLElement): void {
767853
super.renderBody(container);
768854

855+
// Create message element for empty state
856+
this.messageElement = append(container, $('.chat-sessions-message'));
857+
this.messageElement.style.display = 'none';
858+
769859
this.treeContainer = append(container, $('.chat-sessions-tree.show-file-icons'));
770860
this.treeContainer.classList.add('file-icon-themable-tree');
771861

@@ -807,6 +897,7 @@ class SessionsViewPane extends ViewPane {
807897
// Handle double-click and keyboard selection to open editors
808898
this._register(this.tree.onDidOpen(async e => {
809899
const element = e.element as IChatSessionItem & { provider: IChatSessionItemProvider };
900+
810901
if (element && this.isLocalChatSessionItem(element)) {
811902
if (element.sessionType === 'editor' && element.editor && element.group) {
812903
// Open the chat editor

src/vs/workbench/contrib/chat/browser/media/chatSessions.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,22 @@
2121
margin-right: 4px;
2222
margin-left: 4px;
2323
}
24+
25+
/* Style for empty state message */
26+
.chat-sessions-message {
27+
padding: 20px;
28+
text-align: center;
29+
color: var(--vscode-descriptionForeground);
30+
}
31+
32+
.chat-sessions-message .no-sessions-message {
33+
display: flex;
34+
align-items: center;
35+
justify-content: center;
36+
gap: 8px;
37+
font-style: italic;
38+
}
39+
40+
.chat-sessions-message .no-sessions-message .codicon {
41+
opacity: 0.7;
42+
}

0 commit comments

Comments
 (0)