Path: blob/main/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationGroupHeaderRenderer.ts
13406 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 * as DOM from '../../../../../base/browser/dom.js';6import { DisposableStore } from '../../../../../base/common/lifecycle.js';7import { Codicon } from '../../../../../base/common/codicons.js';8import { ThemeIcon } from '../../../../../base/common/themables.js';9import { IListRenderer } from '../../../../../base/browser/ui/list/list.js';10import { IHoverService } from '../../../../../platform/hover/browser/hover.js';1112const $ = DOM.$;1314export const CUSTOMIZATION_GROUP_HEADER_HEIGHT = 36;15export const CUSTOMIZATION_GROUP_HEADER_HEIGHT_WITH_SEPARATOR = 40;1617/**18* Common shape for a collapsible group header entry used in the19* MCP-server and plugin list widgets.20*/21export interface ICustomizationGroupHeaderEntry {22readonly type: 'group-header';23readonly id: string;24readonly label: string;25readonly icon: ThemeIcon;26readonly count: number;27readonly isFirst: boolean;28readonly description: string;29collapsed: boolean;30}3132interface ICustomizationGroupHeaderTemplateData {33readonly container: HTMLElement;34readonly chevron: HTMLElement;35readonly icon: HTMLElement;36readonly label: HTMLElement;37readonly count: HTMLElement;38readonly infoIcon: HTMLElement;39readonly disposables: DisposableStore;40readonly elementDisposables: DisposableStore;41}4243/**44* Shared renderer for collapsible group headers in the AI Customization45* list widgets (MCP servers, plugins, etc.).46*/47export class CustomizationGroupHeaderRenderer<T extends ICustomizationGroupHeaderEntry> implements IListRenderer<T, ICustomizationGroupHeaderTemplateData> {4849constructor(50readonly templateId: string,51private readonly hoverService: IHoverService,52) { }5354renderTemplate(container: HTMLElement): ICustomizationGroupHeaderTemplateData {55const disposables = new DisposableStore();56const elementDisposables = new DisposableStore();57container.classList.add('ai-customization-group-header');5859const chevron = DOM.append(container, $('.group-chevron'));60const icon = DOM.append(container, $('.group-icon'));61const labelGroup = DOM.append(container, $('.group-label-group'));62const label = DOM.append(labelGroup, $('.group-label'));63const infoIcon = DOM.append(labelGroup, $('.group-info'));64infoIcon.classList.add(...ThemeIcon.asClassNameArray(Codicon.info));65const count = DOM.append(container, $('.group-count'));6667return { container, chevron, icon, label, count, infoIcon, disposables, elementDisposables };68}6970renderElement(element: T, _index: number, templateData: ICustomizationGroupHeaderTemplateData): void {71templateData.elementDisposables.clear();7273templateData.chevron.className = 'group-chevron';74templateData.chevron.classList.add(...ThemeIcon.asClassNameArray(element.collapsed ? Codicon.chevronRight : Codicon.chevronDown));7576templateData.icon.className = 'group-icon';77templateData.icon.classList.add(...ThemeIcon.asClassNameArray(element.icon));7879templateData.label.textContent = element.label;80templateData.count.textContent = `${element.count}`;8182templateData.elementDisposables.add(this.hoverService.setupDelayedHover(templateData.infoIcon, () => ({83content: element.description,84appearance: {85compact: true,86skipFadeInAnimation: true,87}88})));8990templateData.container.classList.toggle('collapsed', element.collapsed);91templateData.container.classList.toggle('has-previous-group', !element.isFirst);92}9394disposeTemplate(templateData: ICustomizationGroupHeaderTemplateData): void {95templateData.elementDisposables.dispose();96templateData.disposables.dispose();97}98}99100101