Path: blob/main/src/vs/sessions/contrib/chat/browser/scopedWorkspacePicker.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Codicon } from '../../../../base/common/codicons.js';6import { localize } from '../../../../nls.js';7import { IActionWidgetService } from '../../../../platform/actionWidget/browser/actionWidget.js';8import { ActionListItemKind, IActionListItem } from '../../../../platform/actionWidget/browser/actionList.js';9import { IMenuService } from '../../../../platform/actions/common/actions.js';10import { IRemoteAgentHostService } from '../../../../platform/agentHost/common/remoteAgentHostService.js';11import { ICommandService } from '../../../../platform/commands/common/commands.js';12import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';13import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';14import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js';15import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';16import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';17import { IStorageService } from '../../../../platform/storage/common/storage.js';18import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';19import { ISessionsProvidersService } from '../../../services/sessions/browser/sessionsProvidersService.js';20import { IAgentHostFilterService } from '../../remoteAgentHost/common/agentHostFilter.js';21import { IWorkspacePickerItem, IWorkspaceSelection, WorkspacePicker } from './sessionWorkspacePicker.js';22import { IWorkspacesService } from '../../../../platform/workspaces/common/workspaces.js';2324/**25* A simplified workspace picker that scopes its contents to the host26* currently selected in the agent host filter. It shows:27*28* 1. Recent workspaces for the selected host29* 2. A single "Select Folder..." entry that invokes the host's browse action30*31* Falls back to the Copilot local provider when no host is selected (e.g. on32* desktop, where the host filter UI is not surfaced).33*/34export class ScopedWorkspacePicker extends WorkspacePicker {3536constructor(37@IActionWidgetService actionWidgetService: IActionWidgetService,38@IStorageService storageService: IStorageService,39@IUriIdentityService uriIdentityService: IUriIdentityService,40@ISessionsProvidersService sessionsProvidersService: ISessionsProvidersService,41@IRemoteAgentHostService remoteAgentHostService: IRemoteAgentHostService,42@IConfigurationService configurationService: IConfigurationService,43@ICommandService commandService: ICommandService,44@IWorkspacesService workspacesService: IWorkspacesService,45@IMenuService menuService: IMenuService,46@IContextKeyService contextKeyService: IContextKeyService,47@IInstantiationService instantiationService: IInstantiationService,48@IFileDialogService fileDialogService: IFileDialogService,49@IQuickInputService quickInputService: IQuickInputService,50@IAgentHostFilterService private readonly _agentHostFilterService: IAgentHostFilterService,51) {52super(53actionWidgetService,54storageService,55uriIdentityService,56sessionsProvidersService,57remoteAgentHostService,58configurationService,59commandService,60workspacesService,61menuService,62contextKeyService,63instantiationService,64fileDialogService,65quickInputService,66);6768// When the scoped host changes, if the current selection no longer69// belongs to the selected host, reset it: prefer the most recent70// workspace for the new host, otherwise clear the selection.71this._register(this._agentHostFilterService.onDidChange(() => this._onScopedHostChanged()));72}7374protected override _showTabs(): boolean {75// Scoped picker is already filtered to a single host \u2014 the categorical76// tab bar would be redundant.77return false;78}7980private _onScopedHostChanged(): void {81const scopedProviderId = this._agentHostFilterService.selectedProviderId;82const current = this.selectedProject;83if (current && scopedProviderId !== undefined && current.providerId === scopedProviderId) {84this._onDidChangeSelection.fire();85return;86}8788const firstRecent = scopedProviderId !== undefined89? this._getRecentWorkspaces().find(w => w.providerId === scopedProviderId)90: undefined;91if (firstRecent) {92this.setSelectedWorkspace({ providerId: firstRecent.providerId, workspace: firstRecent.workspace });93return;94}9596this.clearSelection();97this._onDidSelectWorkspace.fire(undefined);98}99100protected override _buildItems(): IActionListItem<IWorkspacePickerItem>[] {101const items: IActionListItem<IWorkspacePickerItem>[] = [];102103const scopedProviderId = this._agentHostFilterService.selectedProviderId;104if (scopedProviderId === undefined) {105return [];106}107const provider = this.sessionsProvidersService.getProvider(scopedProviderId);108if (!provider) {109return items;110}111112// 1. Recent workspaces for the scoped provider113const recents = this._getRecentWorkspaces().filter(w => w.providerId === scopedProviderId);114for (const { workspace, providerId } of recents) {115const selection: IWorkspaceSelection = { providerId, workspace };116items.push({117kind: ActionListItemKind.Action,118label: workspace.label,119description: workspace.description,120group: { title: '', icon: workspace.icon },121item: { selection, checked: this._isSelectedWorkspace(selection) || undefined },122onRemove: () => this._removeRecentWorkspace(selection),123});124}125126// 2. "Select Folder..." — dispatches the scoped provider's first browse action127const allBrowseActions = this._getAllBrowseActions();128const browseIndex = allBrowseActions.findIndex(a => a.providerId === scopedProviderId);129if (browseIndex >= 0 && !this._isProviderUnavailable(scopedProviderId)) {130if (items.length > 0) {131items.push({ kind: ActionListItemKind.Separator, label: '' });132}133items.push({134kind: ActionListItemKind.Action,135label: localize('scopedWorkspacePicker.selectFolder', "Select Folder..."),136group: { title: '', icon: Codicon.folderOpened },137item: { browseActionIndex: browseIndex },138});139}140141return items;142}143}144145146