Path: blob/main/src/vs/sessions/contrib/remoteAgentHost/browser/remoteHostOptions.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 { localize } from '../../../../nls.js';6import { DisposableStore } from '../../../../base/common/lifecycle.js';7import { IRemoteAgentHostService, RemoteAgentHostConnectionStatus } from '../../../../platform/agentHost/common/remoteAgentHostService.js';8import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';9import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';10import { IQuickInputService, IQuickPickItem } from '../../../../platform/quickinput/common/quickInput.js';11import { IOutputService } from '../../../../workbench/services/output/common/output.js';12import { IPreferencesService } from '../../../../workbench/services/preferences/common/preferences.js';13import { IAgentHostSessionsProvider } from '../../../common/agentHostSessionsProvider.js';1415export function getStatusLabel(status: RemoteAgentHostConnectionStatus): string {16switch (status) {17case RemoteAgentHostConnectionStatus.Connected:18return localize('workspacePicker.statusOnline', "Online");19case RemoteAgentHostConnectionStatus.Connecting:20return localize('workspacePicker.statusConnecting', "Connecting");21case RemoteAgentHostConnectionStatus.Disconnected:22return localize('workspacePicker.statusOffline', "Offline");23}24}2526export function getStatusHover(status: RemoteAgentHostConnectionStatus, address?: string): string {27switch (status) {28case RemoteAgentHostConnectionStatus.Connected:29return address30? localize('workspacePicker.hoverConnectedAddr', "Remote agent host is connected and ready.\n\nAddress: {0}", address)31: localize('workspacePicker.hoverConnected', "Remote agent host is connected and ready.");32case RemoteAgentHostConnectionStatus.Connecting:33return address34? localize('workspacePicker.hoverConnectingAddr', "Attempting to connect to remote agent host...\n\nAddress: {0}", address)35: localize('workspacePicker.hoverConnecting', "Attempting to connect to remote agent host...");36case RemoteAgentHostConnectionStatus.Disconnected:37return address38? localize('workspacePicker.hoverDisconnectedAddr', "Remote agent host is disconnected.\n\nAddress: {0}", address)39: localize('workspacePicker.hoverDisconnected', "Remote agent host is disconnected.");40}41}4243export interface IShowRemoteHostOptionsOptions {44/** When true, show a Back button in the picker title bar. The promise resolves to `'back'` if pressed. */45readonly showBackButton?: boolean;46}4748/**49* Show the per-remote management options quickpick (Reconnect / Remove /50* Copy Address / Open Settings / Show Output) for the given provider.51*52* Used by both the Workspace Picker's Manage submenu and the F153* "Manage Remote Agent Hosts..." command, so both surfaces drive the54* same actions. Callers that don't have a {@link ServicesAccessor} should55* use `instantiationService.invokeFunction(accessor => showRemoteHostOptions(accessor, provider))`.56*57* Returns `'back'` if the user clicked the back button (only possible when58* `options.showBackButton` is true), otherwise `undefined`.59*/60export async function showRemoteHostOptions(accessor: ServicesAccessor, provider: IAgentHostSessionsProvider, options: IShowRemoteHostOptionsOptions = {}): Promise<'back' | undefined> {61const address = provider.remoteAddress;62if (!address) {63return undefined;64}6566const quickInputService = accessor.get(IQuickInputService);67const remoteAgentHostService = accessor.get(IRemoteAgentHostService);68const clipboardService = accessor.get(IClipboardService);69const preferencesService = accessor.get(IPreferencesService);70const outputService = accessor.get(IOutputService);7172const status = provider.connectionStatus?.get();73const isConnected = status === RemoteAgentHostConnectionStatus.Connected;7475type RemoteOptionPickItem = IQuickPickItem & { id: string };76const items: RemoteOptionPickItem[] = [];77if (!isConnected) {78items.push({ label: '$(debug-restart) ' + localize('workspacePicker.reconnect', "Reconnect"), id: 'reconnect' });79}80items.push(81{ label: '$(trash) ' + localize('workspacePicker.removeRemote', "Remove Remote"), id: 'remove' },82{ label: '$(copy) ' + localize('workspacePicker.copyAddress', "Copy Address"), id: 'copy' },83{ label: '$(settings-gear) ' + localize('workspacePicker.openSettings', "Open Settings"), id: 'settings' },84);85if (provider.outputChannelId) {86items.push({ label: '$(output) ' + localize('workspacePicker.showOutput', "Show Output"), id: 'output' });87}8889const result = await new Promise<'back' | RemoteOptionPickItem | undefined>((resolve) => {90const store = new DisposableStore();91const picker = store.add(quickInputService.createQuickPick<RemoteOptionPickItem>());92picker.placeholder = localize('workspacePicker.remoteOptionsTitle', "Options for {0}", provider.label);93picker.items = items;94if (options.showBackButton) {95picker.buttons = [quickInputService.backButton];96}97store.add(picker.onDidTriggerButton(button => {98if (button === quickInputService.backButton) {99resolve('back');100picker.hide();101}102}));103store.add(picker.onDidAccept(() => {104resolve(picker.selectedItems[0]);105picker.hide();106}));107store.add(picker.onDidHide(() => {108resolve(undefined);109store.dispose();110}));111picker.show();112});113114if (result === 'back') {115return 'back';116}117if (!result) {118return undefined;119}120121switch (result.id) {122case 'reconnect':123remoteAgentHostService.reconnect(address);124break;125case 'remove':126await remoteAgentHostService.removeRemoteAgentHost(address);127break;128case 'copy':129await clipboardService.writeText(address);130break;131case 'settings':132await preferencesService.openSettings({ query: 'chat.remoteAgentHosts' });133break;134case 'output':135if (provider.outputChannelId) {136outputService.showChannel(provider.outputChannelId, true);137}138break;139}140return undefined;141}142143144145