Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationGroupHeaderRenderer.ts
13406 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as DOM from '../../../../../base/browser/dom.js';
7
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
8
import { Codicon } from '../../../../../base/common/codicons.js';
9
import { ThemeIcon } from '../../../../../base/common/themables.js';
10
import { IListRenderer } from '../../../../../base/browser/ui/list/list.js';
11
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
12
13
const $ = DOM.$;
14
15
export const CUSTOMIZATION_GROUP_HEADER_HEIGHT = 36;
16
export const CUSTOMIZATION_GROUP_HEADER_HEIGHT_WITH_SEPARATOR = 40;
17
18
/**
19
* Common shape for a collapsible group header entry used in the
20
* MCP-server and plugin list widgets.
21
*/
22
export interface ICustomizationGroupHeaderEntry {
23
readonly type: 'group-header';
24
readonly id: string;
25
readonly label: string;
26
readonly icon: ThemeIcon;
27
readonly count: number;
28
readonly isFirst: boolean;
29
readonly description: string;
30
collapsed: boolean;
31
}
32
33
interface ICustomizationGroupHeaderTemplateData {
34
readonly container: HTMLElement;
35
readonly chevron: HTMLElement;
36
readonly icon: HTMLElement;
37
readonly label: HTMLElement;
38
readonly count: HTMLElement;
39
readonly infoIcon: HTMLElement;
40
readonly disposables: DisposableStore;
41
readonly elementDisposables: DisposableStore;
42
}
43
44
/**
45
* Shared renderer for collapsible group headers in the AI Customization
46
* list widgets (MCP servers, plugins, etc.).
47
*/
48
export class CustomizationGroupHeaderRenderer<T extends ICustomizationGroupHeaderEntry> implements IListRenderer<T, ICustomizationGroupHeaderTemplateData> {
49
50
constructor(
51
readonly templateId: string,
52
private readonly hoverService: IHoverService,
53
) { }
54
55
renderTemplate(container: HTMLElement): ICustomizationGroupHeaderTemplateData {
56
const disposables = new DisposableStore();
57
const elementDisposables = new DisposableStore();
58
container.classList.add('ai-customization-group-header');
59
60
const chevron = DOM.append(container, $('.group-chevron'));
61
const icon = DOM.append(container, $('.group-icon'));
62
const labelGroup = DOM.append(container, $('.group-label-group'));
63
const label = DOM.append(labelGroup, $('.group-label'));
64
const infoIcon = DOM.append(labelGroup, $('.group-info'));
65
infoIcon.classList.add(...ThemeIcon.asClassNameArray(Codicon.info));
66
const count = DOM.append(container, $('.group-count'));
67
68
return { container, chevron, icon, label, count, infoIcon, disposables, elementDisposables };
69
}
70
71
renderElement(element: T, _index: number, templateData: ICustomizationGroupHeaderTemplateData): void {
72
templateData.elementDisposables.clear();
73
74
templateData.chevron.className = 'group-chevron';
75
templateData.chevron.classList.add(...ThemeIcon.asClassNameArray(element.collapsed ? Codicon.chevronRight : Codicon.chevronDown));
76
77
templateData.icon.className = 'group-icon';
78
templateData.icon.classList.add(...ThemeIcon.asClassNameArray(element.icon));
79
80
templateData.label.textContent = element.label;
81
templateData.count.textContent = `${element.count}`;
82
83
templateData.elementDisposables.add(this.hoverService.setupDelayedHover(templateData.infoIcon, () => ({
84
content: element.description,
85
appearance: {
86
compact: true,
87
skipFadeInAnimation: true,
88
}
89
})));
90
91
templateData.container.classList.toggle('collapsed', element.collapsed);
92
templateData.container.classList.toggle('has-previous-group', !element.isFirst);
93
}
94
95
disposeTemplate(templateData: ICustomizationGroupHeaderTemplateData): void {
96
templateData.elementDisposables.dispose();
97
templateData.disposables.dispose();
98
}
99
}
100
101