Path: blob/main/src/vs/workbench/contrib/comments/browser/commentFormActions.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 { Button, ButtonWithDropdown } from '../../../../base/browser/ui/button/button.js';6import { ActionRunner, IAction } from '../../../../base/common/actions.js';7import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';8import { IMenu, SubmenuItemAction } from '../../../../platform/actions/common/actions.js';9import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';10import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';11import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';12import { defaultButtonStyles } from '../../../../platform/theme/browser/defaultStyles.js';13import { CommentCommandId } from '../common/commentCommandIds.js';1415export class CommentFormActions implements IDisposable {16private _buttonElements: HTMLElement[] = [];17private readonly _toDispose = new DisposableStore();18private _actions: IAction[] = [];1920constructor(21private readonly keybindingService: IKeybindingService,22private readonly contextKeyService: IContextKeyService,23private readonly contextMenuService: IContextMenuService,24private container: HTMLElement,25private actionHandler: (action: IAction) => void,26private readonly maxActions?: number,27private readonly supportDropdowns?: boolean,28) { }2930setActions(menu: IMenu, hasOnlySecondaryActions: boolean = false) {31this._toDispose.clear();3233this._buttonElements.forEach(b => b.remove());34this._buttonElements = [];3536const groups = menu.getActions({ shouldForwardArgs: true });37let isPrimary: boolean = !hasOnlySecondaryActions;38for (const group of groups) {39const [, actions] = group;4041this._actions = actions;42for (const current of actions) {43const dropDownActions = this.supportDropdowns && current instanceof SubmenuItemAction ? current.actions : [];44const action = dropDownActions.length ? dropDownActions[0] : current;45let keybinding = this.keybindingService.lookupKeybinding(action.id, this.contextKeyService)?.getLabel();46if (!keybinding && isPrimary) {47keybinding = this.keybindingService.lookupKeybinding(CommentCommandId.Submit, this.contextKeyService)?.getLabel();48}49const title = keybinding ? `${action.label} (${keybinding})` : action.label;50const actionHandler = this.actionHandler;51const button = dropDownActions.length ? new ButtonWithDropdown(this.container, {52contextMenuProvider: this.contextMenuService,53actions: dropDownActions,54actionRunner: this._toDispose.add(new class extends ActionRunner {55protected override async runAction(action: IAction, context?: unknown): Promise<void> {56return actionHandler(action);57}58}),59secondary: !isPrimary,60title,61addPrimaryActionToDropdown: false,62...defaultButtonStyles63}) : new Button(this.container, { secondary: !isPrimary, title, ...defaultButtonStyles });6465isPrimary = false;66this._buttonElements.push(button.element);6768this._toDispose.add(button);69this._toDispose.add(button.onDidClick(() => this.actionHandler(action)));7071button.enabled = action.enabled;72button.label = action.label;73if ((this.maxActions !== undefined) && (this._buttonElements.length >= this.maxActions)) {74console.warn(`An extension has contributed more than the allowable number of actions to a comments menu.`);75return;76}77}78}79}8081triggerDefaultAction() {82if (this._actions.length) {83const lastAction = this._actions[0];8485if (lastAction.enabled) {86return this.actionHandler(lastAction);87}88}89}9091dispose() {92this._toDispose.dispose();93}94}959697