Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/test/browser/componentFixtures/chat/chatQuestionCarousel.fixture.ts
13405 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 { IMarkdownRendererService, MarkdownRendererService } from '../../../../../platform/markdown/browser/markdownRenderer.js';
8
import { IChatQuestion, IChatQuestionCarousel } from '../../../../contrib/chat/common/chatService/chatService.js';
9
import { ChatQuestionCarouselPart, IChatQuestionCarouselOptions } from '../../../../contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.js';
10
import { IChatContentPartRenderContext, InlineTextModelCollection } from '../../../../contrib/chat/browser/widget/chatContentParts/chatContentParts.js';
11
import { ComponentFixtureContext, createEditorServices, defineComponentFixture, defineThemedFixtureGroup } from '../fixtureUtils.js';
12
import { mock, upcastPartial } from '../../../../../base/test/common/mock.js';
13
import { Event } from '../../../../../base/common/event.js';
14
import { observableValue } from '../../../../../base/common/observable.js';
15
import { IChatRequestViewModel } from '../../../../contrib/chat/common/model/chatViewModel.js';
16
import '../../../../contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css';
17
18
function createCarousel(questions: IChatQuestion[], allowSkip: boolean = true): IChatQuestionCarousel {
19
return {
20
questions,
21
allowSkip,
22
kind: 'questionCarousel',
23
};
24
}
25
26
function createMockContext(): IChatContentPartRenderContext {
27
return {
28
element: new class extends mock<IChatRequestViewModel>() { }(),
29
inlineTextModels: upcastPartial<InlineTextModelCollection>({}),
30
elementIndex: 0,
31
container: document.createElement('div'),
32
content: [],
33
contentIndex: 0,
34
editorPool: undefined!,
35
codeBlockStartIndex: 0,
36
treeStartIndex: 0,
37
diffEditorPool: undefined!,
38
currentWidth: observableValue('currentWidth', 400),
39
onDidChangeVisibility: Event.None,
40
};
41
}
42
43
function createOptions(): IChatQuestionCarouselOptions {
44
return {
45
onSubmit: () => { },
46
shouldAutoFocus: false,
47
};
48
}
49
50
function renderCarousel(context: ComponentFixtureContext, carousel: IChatQuestionCarousel): void {
51
const { container, disposableStore } = context;
52
53
const instantiationService = createEditorServices(disposableStore, {
54
additionalServices: (reg) => {
55
reg.define(IMarkdownRendererService, MarkdownRendererService);
56
},
57
});
58
59
const part = disposableStore.add(
60
instantiationService.createInstance(
61
ChatQuestionCarouselPart,
62
carousel,
63
createMockContext(),
64
createOptions(),
65
)
66
);
67
68
container.style.width = '400px';
69
container.style.padding = '8px';
70
container.classList.add('interactive-session');
71
72
// The CSS uses `.interactive-session .interactive-input-part > .chat-question-carousel-widget-container`
73
// for most layout rules, so we need those wrapper elements.
74
const inputPart = dom.$('.interactive-input-part');
75
const widgetContainer = dom.$('.chat-question-carousel-widget-container');
76
inputPart.appendChild(widgetContainer);
77
container.appendChild(inputPart);
78
79
widgetContainer.appendChild(part.domNode);
80
}
81
82
// ============================================================================
83
// Sample questions
84
// ============================================================================
85
86
const textQuestion: IChatQuestion = {
87
id: 'project-name',
88
type: 'text',
89
title: 'Project name',
90
message: 'What is the name of your project?',
91
defaultValue: 'my-project',
92
};
93
94
const singleSelectQuestion: IChatQuestion = {
95
id: 'language',
96
type: 'singleSelect',
97
title: 'Language',
98
message: 'Which language do you want to use?',
99
options: [
100
{ id: 'ts', label: 'TypeScript - Strongly typed JavaScript', value: 'typescript' },
101
{ id: 'js', label: 'JavaScript - Dynamic scripting language', value: 'javascript' },
102
{ id: 'py', label: 'Python - General purpose language', value: 'python' },
103
{ id: 'rs', label: 'Rust - Systems programming', value: 'rust' },
104
],
105
defaultValue: 'ts',
106
};
107
108
const multiSelectQuestion: IChatQuestion = {
109
id: 'features',
110
type: 'multiSelect',
111
title: 'Features',
112
message: 'Which features should be enabled?',
113
options: [
114
{ id: 'lint', label: 'Linting', value: 'linting' },
115
{ id: 'fmt', label: 'Formatting', value: 'formatting' },
116
{ id: 'test', label: 'Testing', value: 'testing' },
117
{ id: 'ci', label: 'CI/CD Pipeline', value: 'ci' },
118
],
119
defaultValue: ['lint', 'fmt'],
120
};
121
122
// ============================================================================
123
// Fixtures
124
// ============================================================================
125
126
export default defineThemedFixtureGroup({ path: 'chat/' }, {
127
SingleTextQuestion: defineComponentFixture({
128
labels: { kind: 'screenshot' },
129
render: (context) => renderCarousel(context, createCarousel([textQuestion])),
130
}),
131
132
SingleSelectQuestion: defineComponentFixture({
133
labels: { kind: 'screenshot' },
134
render: (context) => renderCarousel(context, createCarousel([singleSelectQuestion])),
135
}),
136
137
MultiSelectQuestion: defineComponentFixture({
138
labels: { kind: 'screenshot' },
139
render: (context) => renderCarousel(context, createCarousel([multiSelectQuestion])),
140
}),
141
142
MultipleQuestions: defineComponentFixture({
143
labels: { kind: 'screenshot' },
144
render: (context) => renderCarousel(context, createCarousel([
145
textQuestion,
146
singleSelectQuestion,
147
multiSelectQuestion,
148
])),
149
}),
150
151
NoSkip: defineComponentFixture({
152
labels: { kind: 'screenshot' },
153
render: (context) => renderCarousel(context, createCarousel([singleSelectQuestion], false)),
154
}),
155
156
SubmittedSummary: defineComponentFixture({
157
labels: { kind: 'screenshot' },
158
render: (context) => {
159
const carousel = createCarousel([textQuestion, singleSelectQuestion, multiSelectQuestion]);
160
carousel.isUsed = true;
161
carousel.data = {
162
'project-name': 'my-app',
163
'language': { selectedValue: 'typescript', freeformValue: undefined },
164
'features': { selectedValues: ['linting', 'formatting'], freeformValue: undefined },
165
};
166
renderCarousel(context, carousel);
167
},
168
}),
169
170
SkippedSummary: defineComponentFixture({
171
labels: { kind: 'screenshot' },
172
render: (context) => {
173
const carousel = createCarousel([textQuestion, singleSelectQuestion]);
174
carousel.isUsed = true;
175
carousel.data = {};
176
renderCarousel(context, carousel);
177
},
178
}),
179
});
180
181