Path: blob/main/src/vs/workbench/contrib/issue/browser/issueQuickAccess.ts
3296 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 { PickerQuickAccessProvider, IPickerQuickAccessItem, FastAndSlowPicks, Picks, TriggerAction } from '../../../../platform/quickinput/browser/pickerQuickAccess.js';6import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';7import { IMenuService, MenuId, MenuItemAction, SubmenuItemAction } from '../../../../platform/actions/common/actions.js';8import { matchesFuzzy } from '../../../../base/common/filters.js';9import { IQuickPickSeparator } from '../../../../platform/quickinput/common/quickInput.js';10import { localize } from '../../../../nls.js';11import { ICommandService } from '../../../../platform/commands/common/commands.js';12import { IExtensionService } from '../../../services/extensions/common/extensions.js';13import { IExtensionDescription } from '../../../../platform/extensions/common/extensions.js';14import { ThemeIcon } from '../../../../base/common/themables.js';15import { Codicon } from '../../../../base/common/codicons.js';16import { IssueSource } from '../common/issue.js';17import { IProductService } from '../../../../platform/product/common/productService.js';1819export class IssueQuickAccess extends PickerQuickAccessProvider<IPickerQuickAccessItem> {2021static PREFIX = 'issue ';2223constructor(24@IMenuService private readonly menuService: IMenuService,25@IContextKeyService private readonly contextKeyService: IContextKeyService,26@ICommandService private readonly commandService: ICommandService,27@IExtensionService private readonly extensionService: IExtensionService,28@IProductService private readonly productService: IProductService29) {30super(IssueQuickAccess.PREFIX, { canAcceptInBackground: true });31}3233protected override _getPicks(filter: string): Picks<IPickerQuickAccessItem> | FastAndSlowPicks<IPickerQuickAccessItem> | Promise<Picks<IPickerQuickAccessItem> | FastAndSlowPicks<IPickerQuickAccessItem>> | null {34const issuePicksConst = new Array<IPickerQuickAccessItem | IQuickPickSeparator>();35const issuePicksParts = new Array<IPickerQuickAccessItem | IQuickPickSeparator>();36const extensionIdSet = new Set<string>();3738// Add default items39const productLabel = this.productService.nameLong;40const marketPlaceLabel = localize("reportExtensionMarketplace", "Extension Marketplace");41const productFilter = matchesFuzzy(filter, productLabel, true);42const marketPlaceFilter = matchesFuzzy(filter, marketPlaceLabel, true);4344// Add product pick if product filter matches45if (productFilter) {46issuePicksConst.push({47label: productLabel,48ariaLabel: productLabel,49highlights: { label: productFilter },50accept: () => this.commandService.executeCommand('workbench.action.openIssueReporter', { issueSource: IssueSource.VSCode })51});52}5354// Add marketplace pick if marketplace filter matches55if (marketPlaceFilter) {56issuePicksConst.push({57label: marketPlaceLabel,58ariaLabel: marketPlaceLabel,59highlights: { label: marketPlaceFilter },60accept: () => this.commandService.executeCommand('workbench.action.openIssueReporter', { issueSource: IssueSource.Marketplace })61});62}6364issuePicksConst.push({ type: 'separator', label: localize('extensions', "Extensions") });656667// gets menu actions from contributed68const actions = this.menuService.getMenuActions(MenuId.IssueReporter, this.contextKeyService, { renderShortTitle: true }).flatMap(entry => entry[1]);6970// create picks from contributed menu71actions.forEach(action => {72if ('source' in action.item && action.item.source) {73extensionIdSet.add(action.item.source.id);74}7576const pick = this._createPick(filter, action);77if (pick) {78issuePicksParts.push(pick);79}80});818283// create picks from extensions84this.extensionService.extensions.forEach(extension => {85if (!extension.isBuiltin) {86const pick = this._createPick(filter, undefined, extension);87const id = extension.identifier.value;88if (pick && !extensionIdSet.has(id)) {89issuePicksParts.push(pick);90}91extensionIdSet.add(id);92}93});9495issuePicksParts.sort((a, b) => {96const aLabel = a.label ?? '';97const bLabel = b.label ?? '';98return aLabel.localeCompare(bLabel);99});100101return [...issuePicksConst, ...issuePicksParts];102}103104private _createPick(filter: string, action?: MenuItemAction | SubmenuItemAction | undefined, extension?: IExtensionDescription): IPickerQuickAccessItem | undefined {105const buttons = [{106iconClass: ThemeIcon.asClassName(Codicon.info),107tooltip: localize('contributedIssuePage', "Open Extension Page")108}];109110let label: string;111let trigger: () => TriggerAction;112let accept: () => void;113if (action && 'source' in action.item && action.item.source) {114label = action.item.source?.title;115trigger = () => {116if ('source' in action.item && action.item.source) {117this.commandService.executeCommand('extension.open', action.item.source.id);118}119return TriggerAction.CLOSE_PICKER;120};121accept = () => {122action.run();123};124125} else if (extension) {126label = extension.displayName ?? extension.name;127trigger = () => {128this.commandService.executeCommand('extension.open', extension.identifier.value);129return TriggerAction.CLOSE_PICKER;130};131accept = () => {132this.commandService.executeCommand('workbench.action.openIssueReporter', extension.identifier.value);133};134135} else {136return undefined;137}138139const highlights = matchesFuzzy(filter, label, true);140if (highlights) {141return {142label,143highlights: { label: highlights },144buttons,145trigger,146accept147};148}149return undefined;150}151}152153154