Skip to content

Commit 5f04425

Browse files
authored
Add support for help link and allow customization of command and labels used in remote start entry (microsoft#181926)
Add support for help link and allow customization of command and labels used in remote start entry
1 parent 4660545 commit 5f04425

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

src/vs/base/common/product.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,24 @@ export interface IRemoteExtensionTip {
252252
friendlyName: string;
253253
extensionId: string;
254254
supportedPlatforms?: PlatformName[];
255-
showInStartEntry?: boolean;
255+
startEntry?: {
256+
helpLink: string;
257+
startConnectLabel: string;
258+
startCommand: string;
259+
priority: number;
260+
};
256261
}
257262

258263
export interface IVirtualWorkspaceExtensionTip {
259264
friendlyName: string;
260265
extensionId: string;
261266
supportedPlatforms?: PlatformName[];
262-
showInStartEntry?: boolean;
267+
startEntry: {
268+
helpLink: string;
269+
startConnectLabel: string;
270+
startCommand: string;
271+
priority: number;
272+
};
263273
}
264274

265275
export interface ISurveyData {

src/vs/workbench/contrib/remote/browser/remoteStartEntry.ts

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
77
import { Disposable } from 'vs/base/common/lifecycle';
88
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
99
import { ICommandService } from 'vs/platform/commands/common/commands';
10-
import { QuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
10+
import { QuickPickItem, IQuickInputService, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
1111
import { once } from 'vs/base/common/functional';
1212
import { IProductService } from 'vs/platform/product/common/productService';
1313
import { Action2, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions';
@@ -22,6 +22,10 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2222
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
2323
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
2424
import { IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
25+
import { ThemeIcon } from 'vs/base/common/themables';
26+
import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
27+
import { IOpenerService } from 'vs/platform/opener/common/opener';
28+
import { URI } from 'vs/base/common/uri';
2529

2630
const STATUSBAR_REMOTEINDICATOR_CONTRIBUTION = 'statusBar/remoteIndicator';
2731

@@ -49,6 +53,10 @@ interface RemoteExtensionMetadata {
4953
installed: boolean;
5054
dependencies: string[];
5155
isPlatformCompatible: boolean;
56+
helpLink: string;
57+
startConnectLabel: string;
58+
startCommand: string;
59+
priority: number;
5260
}
5361

5462
export class RemoteStartEntry extends Disposable implements IWorkbenchContribution {
@@ -66,16 +74,29 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
6674
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService,
6775
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
6876
@ITelemetryService private readonly telemetryService: ITelemetryService,
69-
@IContextKeyService private readonly contextKeyService: IContextKeyService) {
77+
@IContextKeyService private readonly contextKeyService: IContextKeyService,
78+
@IOpenerService private readonly openerService: IOpenerService) {
7079

7180
super();
7281
const enable = this.extensionGalleryService.isEnabled() && (this.productService.remoteExtensionTips ?? false) && this.productService.quality !== 'stable';
7382
registerConfiguration(enable);
7483
const remoteExtensionTips = { ...this.productService.remoteExtensionTips, ...this.productService.virtualWorkspaceExtensionTips };
75-
this.remoteExtensionMetadata = Object.values(remoteExtensionTips).filter(value => value.showInStartEntry === true).map(value => {
76-
return { id: value.extensionId, installed: false, friendlyName: value.friendlyName, remoteCommands: [], isPlatformCompatible: false, dependencies: [] };
84+
this.remoteExtensionMetadata = Object.values(remoteExtensionTips).filter(value => value.startEntry !== undefined).map(value => {
85+
return {
86+
id: value.extensionId,
87+
installed: false,
88+
friendlyName: value.friendlyName,
89+
remoteCommands: [],
90+
isPlatformCompatible: false,
91+
dependencies: [],
92+
helpLink: value.startEntry?.helpLink ?? '',
93+
startConnectLabel: value.startEntry?.startConnectLabel ?? '',
94+
startCommand: value.startEntry?.startCommand ?? '',
95+
priority: value.startEntry?.priority ?? 10
96+
};
7797
});
7898

99+
this.remoteExtensionMetadata.sort((ext1, ext2) => ext1.priority - ext2.priority);
79100
this.registerActions();
80101
this.registerListeners();
81102
}
@@ -220,8 +241,12 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
220241
}
221242
}
222243
else if (!metadata.installed && metadata.isPlatformCompatible) {
223-
const label = nls.localize('remote.startActions.connectTo', 'Connect to {0}... ', metadata.friendlyName);
224-
notInstalledItems.push({ type: 'item', id: metadata.id, label: label });
244+
const label = metadata.startConnectLabel;
245+
const buttons: IQuickInputButton[] = [{
246+
iconClass: ThemeIcon.asClassName(infoIcon),
247+
tooltip: nls.localize('remote.startActions.help', "Learn More")
248+
}];
249+
notInstalledItems.push({ type: 'item', id: metadata.id, label: label, buttons: buttons });
225250
}
226251
}
227252

@@ -232,7 +257,7 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
232257
};
233258

234259
const quickPick = this.quickInputService.createQuickPick();
235-
quickPick.placeholder = nls.localize('remote.startActions.quickPickPlaceholder', 'Select an option to connect to a Remote Window');
260+
quickPick.placeholder = nls.localize('remote.startActions.quickPickPlaceholder', 'Select an option to connect');
236261
quickPick.items = await computeItems();
237262
quickPick.sortByLabel = false;
238263
quickPick.canSelectMany = false;
@@ -258,11 +283,10 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
258283
});
259284

260285
this.telemetryService.publicLog2<RemoteStartActionEvent, RemoteStartActionClassification>('remoteStartList.ActionExecuted', { command: 'workbench.extensions.installExtension', remoteExtensionId: selectedItem });
261-
const commands = await this.getRemoteCommands(selectedItem);
262-
263-
await this.extensionService.activateByEvent(`onCommand:${commands[0]}`);
264286

265-
const command = commands[0].command;
287+
const commands = await this.getRemoteCommands(selectedItem);
288+
const command = (commands.find(value => value.command === remoteExtension.startCommand) ?? commands[0]).command;
289+
await this.extensionService.activateByEvent(`onCommand:${command}`);
266290
this.commandService.executeCommand(command);
267291

268292
this.telemetryService.publicLog2<RemoteStartActionEvent, RemoteStartActionClassification>('remoteStartList.ActionExecuted', { command: command, remoteExtensionId: selectedItem });
@@ -274,6 +298,12 @@ export class RemoteStartEntry extends Disposable implements IWorkbenchContributi
274298
quickPick.dispose();
275299
}
276300
});
301+
once(quickPick.onDidTriggerItemButton)(async (e) => {
302+
const remoteExtension = this.remoteExtensionMetadata.find(value => ExtensionIdentifier.equals(value.id, e.item.id));
303+
if (remoteExtension) {
304+
await this.openerService.open(URI.parse(remoteExtension.helpLink));
305+
}
306+
});
277307
quickPick.onDidHide(() => quickPick.dispose());
278308
quickPick.show();
279309
}

0 commit comments

Comments
 (0)