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