UNPKG

@progress/kendo-angular-conversational-ui

Version:

Kendo UI for Angular Conversational UI components

387 lines (384 loc) 17.4 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, ContentChild, ContentChildren, EventEmitter, HostBinding, Input, NgZone, Output, QueryList } from "@angular/core"; import { NgFor, NgIf, NgTemplateOutlet } from "@angular/common"; import { Subscription } from "rxjs"; import { sparklesIcon, commentIcon } from "@progress/kendo-svg-icons"; import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n'; import { validatePackage } from "@progress/kendo-licensing"; import { ButtonComponent } from "@progress/kendo-angular-buttons"; import { BaseView } from "./views/base-view"; import { packageMetadata } from "../package-metadata"; import { AIPromptService } from "./common/aiprompt.service"; import { AIPromptToolbarActionsDirective } from "./templates/toolbar-actions.template"; import { ToolbarNavigationService } from "./common/toolbar-navigation.service"; import { AIPromptToolbarFocusableDirective } from "./common/toolbar-focusable.directive"; import { LocalizedMessagesDirective } from "./localization/localized-messages.directive"; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-l10n"; import * as i2 from "./common/aiprompt.service"; import * as i3 from "./common/toolbar-navigation.service"; /** * Represents the [Kendo UI AIPrompt component for Angular](slug:overview_aiprompt). * * @example * ```html * <kendo-aiprompt * [promptCommands]="commands" * [promptSuggestions]="suggestions" * [promptOutputs]="outputs" * [showOutputRating]="true" * (promptRequest)="onPromptRequest($event)"> * </kendo-aiprompt> * ``` * * @remarks * Supported children components are: {@link AIPromptCustomMessagesComponent}, {@link CustomViewComponent}, {@link CommandViewComponent}, {@link PromptViewComponent}, {@link OutputViewComponent}. */ export class AIPromptComponent { localization; service; navigationService; ngZone; hostClasses = true; get dirAttr() { return this.direction; } constructor(localization, service, navigationService, ngZone) { this.localization = localization; this.service = service; this.navigationService = navigationService; this.ngZone = ngZone; validatePackage(packageMetadata); this.direction = localization.rtl ? 'rtl' : 'ltr'; this.subs.add(localization.changes.subscribe(({ rtl }) => { this.direction = rtl ? 'rtl' : 'ltr'; })); } /** * @hidden */ views; /** * @hidden */ toolbarActionsTemplate; /** * The active view index of the AIPrompt component. */ set activeView(idx) { if (this._activeView !== idx) { this._activeView = idx; this.service.promptValue && (this.service.promptValue = ''); } } get activeView() { return this._activeView; } /** * Sets the collection of commands to render in the **Command** view. */ set promptCommands(value) { this.service.promptCommands = value; } /** * Sets the collection of suggestions to render in the **Prompt** view. */ set promptSuggestions(value) { this.service.promptSuggestions = value; } /** * Sets the collection of generated prompt outputs to render in the **Output** view. */ set promptOutputs(value) { this.service.promptOutputs = value; } /** * Specifies if the rating buttons appear in each **Output** view card. * By default, the rating buttons do not appear. * @default false */ set showOutputRating(value) { this.service.showOutputRating = value; } /** * Fires when the `activeView` property is updated. * Use this event for two-way binding of the `activeView` property. */ activeViewChange = new EventEmitter(); /** * Fires when the user clicks the **Generate** button in the **Prompt** view or the **Retry** button in the **Output** view. * Use the event's `isRetry` field to determine the source element. */ promptRequest = new EventEmitter(); /** * Fires when the user clicks a **Command** view command. * The event data contains the selected command. */ commandExecute = new EventEmitter(); /** * Fires when the user clicks a **Copy** button in any **Output** view card. */ outputCopy = new EventEmitter(); /** * Fires when the user clicks a rating button in any **Output** view card. */ outputRatingChange = new EventEmitter(); ngAfterViewInit() { this.ngZone.runOutsideAngular(() => { this.service.aiPrompt = this; this.subs.add(this.service.requestEvent.subscribe(ev => this.promptRequest.emit(ev))); this.subs.add(this.service.executeEvent.subscribe(ev => this.commandExecute.emit(ev))); this.subs.add(this.service.outputCopyEvent.subscribe(ev => this.outputCopy.emit(ev))); this.subs.add(this.service.outputRatingChangeEvent.subscribe(ev => this.outputRatingChange.emit(ev))); }); } ngOnDestroy() { this.subs.unsubscribe(); } /** * Focuses the first focusable element in the AIPrompt component. */ focus() { this.navigationService.focusFirst(); } subs = new Subscription(); /** * @hidden */ get selectedView() { return this.viewsArray[this.activeView]; } /** * @hidden */ sparklesIcon = sparklesIcon; /** * @hidden */ outputIcon = commentIcon; /** * @hidden */ get viewsArray() { return this.views?.toArray(); } direction; _activeView = 0; /** * @hidden */ viewChange(idx) { if (idx !== this.activeView) { this.activeView = idx; this.activeViewChange.emit(idx); } } /** * @hidden */ messageFor(text) { return this.localization.get(text); } /** * @hidden */ get viewTemplate() { return this.selectedView?.viewType === 'custom' ? this.selectedView?.viewTemplate : this.selectedView?.template; } /** * @hidden */ handleGenerateOutput() { const value = this.service.promptValue; const eventArgs = { prompt: value, sender: this, isRetry: false }; this.promptRequest.emit(eventArgs); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1.LocalizationService }, { token: i2.AIPromptService }, { token: i3.ToolbarNavigationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AIPromptComponent, isStandalone: true, selector: "kendo-aiprompt", inputs: { activeView: "activeView", promptCommands: "promptCommands", promptSuggestions: "promptSuggestions", promptOutputs: "promptOutputs", showOutputRating: "showOutputRating" }, outputs: { activeViewChange: "activeViewChange", promptRequest: "promptRequest", commandExecute: "commandExecute", outputCopy: "outputCopy", outputRatingChange: "outputRatingChange" }, host: { properties: { "class.k-prompt": "this.hostClasses", "attr.dir": "this.dirAttr" } }, providers: [ LocalizationService, AIPromptService, ToolbarNavigationService, { provide: L10N_PREFIX, useValue: 'kendo.aiprompt' } ], queries: [{ propertyName: "toolbarActionsTemplate", first: true, predicate: AIPromptToolbarActionsDirective, descendants: true }, { propertyName: "views", predicate: BaseView }], exportAs: ["kendoAIPrompt"], ngImport: i0, template: ` <ng-container kendoAIPromptLocalizedMessages i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view." promptView="Ask AI" i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view." outputView="Output" i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view." generateOutput="Generate" i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area." promptPlaceholder="Ask or generate content with AI" i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card." copyOutput="Copy" i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card." retryGeneration="Retry" i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card." outputTitle="Generated with AI" i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card." outputRetryTitle="Generated with AI" i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button." promptSuggestions="Prompt suggestions"> </ng-container> <div class="k-prompt-header"> <div class="k-toolbar-flat k-toolbar k-toolbar-md" role="toolbar"> <button *ngFor="let view of viewsArray; let idx = index" kendoButton kendoAIPromptToolbarFocusable type="button" fillMode="flat" rounded="full" themeColor="primary" [svgIcon]="view.svgIcon" [icon]="view.icon" [selected]="idx === activeView" (click)="viewChange(idx)"> {{view.buttonText}} </button> <ng-template *ngIf="toolbarActionsTemplate" [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef"> </ng-template> </div> </div> <div class="k-prompt-content"> <div class="k-prompt-view"> <ng-container *ngTemplateOutlet="viewTemplate"> </ng-container> </div> </div> <div class="k-prompt-footer" *ngIf="selectedView?.viewType === 'prompt'"> <div class="k-actions k-actions-start k-actions-horizontal k-prompt-actions"> <button kendoButton type="button" themeColor="primary" rounded="full" [svgIcon]="sparklesIcon" icon="sparkles" (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button> </div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoAIPromptLocalizedMessages]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: AIPromptToolbarFocusableDirective, selector: "[kendoAIPromptToolbarFocusable]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, decorators: [{ type: Component, args: [{ exportAs: 'kendoAIPrompt', selector: 'kendo-aiprompt', providers: [ LocalizationService, AIPromptService, ToolbarNavigationService, { provide: L10N_PREFIX, useValue: 'kendo.aiprompt' } ], template: ` <ng-container kendoAIPromptLocalizedMessages i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view." promptView="Ask AI" i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view." outputView="Output" i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view." generateOutput="Generate" i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area." promptPlaceholder="Ask or generate content with AI" i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card." copyOutput="Copy" i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card." retryGeneration="Retry" i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card." outputTitle="Generated with AI" i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card." outputRetryTitle="Generated with AI" i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button." promptSuggestions="Prompt suggestions"> </ng-container> <div class="k-prompt-header"> <div class="k-toolbar-flat k-toolbar k-toolbar-md" role="toolbar"> <button *ngFor="let view of viewsArray; let idx = index" kendoButton kendoAIPromptToolbarFocusable type="button" fillMode="flat" rounded="full" themeColor="primary" [svgIcon]="view.svgIcon" [icon]="view.icon" [selected]="idx === activeView" (click)="viewChange(idx)"> {{view.buttonText}} </button> <ng-template *ngIf="toolbarActionsTemplate" [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef"> </ng-template> </div> </div> <div class="k-prompt-content"> <div class="k-prompt-view"> <ng-container *ngTemplateOutlet="viewTemplate"> </ng-container> </div> </div> <div class="k-prompt-footer" *ngIf="selectedView?.viewType === 'prompt'"> <div class="k-actions k-actions-start k-actions-horizontal k-prompt-actions"> <button kendoButton type="button" themeColor="primary" rounded="full" [svgIcon]="sparklesIcon" icon="sparkles" (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button> </div> </div> `, standalone: true, imports: [LocalizedMessagesDirective, NgFor, ButtonComponent, AIPromptToolbarFocusableDirective, NgIf, NgTemplateOutlet] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.AIPromptService }, { type: i3.ToolbarNavigationService }, { type: i0.NgZone }]; }, propDecorators: { hostClasses: [{ type: HostBinding, args: ['class.k-prompt'] }], dirAttr: [{ type: HostBinding, args: ['attr.dir'] }], views: [{ type: ContentChildren, args: [BaseView] }], toolbarActionsTemplate: [{ type: ContentChild, args: [AIPromptToolbarActionsDirective] }], activeView: [{ type: Input }], promptCommands: [{ type: Input }], promptSuggestions: [{ type: Input }], promptOutputs: [{ type: Input }], showOutputRating: [{ type: Input }], activeViewChange: [{ type: Output }], promptRequest: [{ type: Output }], commandExecute: [{ type: Output }], outputCopy: [{ type: Output }], outputRatingChange: [{ type: Output }] } });