Package io.jmix.aitoolsflowui.view.chat
Class AiChatFragment
java.lang.Object
com.vaadin.flow.component.Component
com.vaadin.flow.component.Composite<com.vaadin.flow.component.orderedlayout.VerticalLayout>
io.jmix.flowui.fragment.Fragment<com.vaadin.flow.component.orderedlayout.VerticalLayout>
io.jmix.aitoolsflowui.view.chat.AiChatFragment
- All Implemented Interfaces:
com.vaadin.flow.component.AttachNotifier,com.vaadin.flow.component.DetachNotifier,com.vaadin.flow.component.HasElement,com.vaadin.flow.component.HasStyle,FacetOwner,FragmentOwner,Serializable
public class AiChatFragment
extends Fragment<com.vaadin.flow.component.orderedlayout.VerticalLayout>
Encapsulates the "AI chat panel" UI — title row, message timeline, thinking
indicator and the
AiChatInputFragment composer — for an AiConversation.
Designed to be embedded into any host view (the standard detail view, a
side dialog, a chat hub view, custom layouts).
Ownership. The host supplies the conversation to display via
setConversation(AiConversation) or setConversationId(UUID);
the fragment loads that conversation's AiChatMessages itself — it does
not rely on the messages collection being pre-fetched by the host —
and reads/writes directly through DataManager.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class io.jmix.flowui.fragment.Fragment
Fragment.ReadyEvent -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected @Nullable TimelineItemprotected @Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> protected AssistantResponseTaskCoordinatorprotected booleanprotected AiChatServiceprotected booleanprotected com.vaadin.flow.component.orderedlayout.VerticalLayoutprotected AiChatInputFragmentprotected @Nullable AiConversationprotected AiConversationServiceprotected com.vaadin.flow.component.html.H3protected DataManagerprotected Dialogsprotected JmixButtonprotected MessageBundleprotected AiChatMessageServiceprotected Notificationsprotected booleanprotected TimelineItemFactoryprotected CollectionContainer<TimelineItem> protected JmixVirtualList<TimelineItem> protected TimeSourceFields inherited from class io.jmix.flowui.fragment.Fragment
fragmentActions, fragmentData, fragmentFacets, parentController, uiComponents -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected voidappendThinkingStatusUpdate(@Nullable AiToolStatusUpdate statusUpdate) protected voidprotected TimelineItemStatuscreateTimelineStatus(AiToolStatusUpdate statusUpdate) protected AiChatMessagecreateTransientAssistantMessage(String content) voidMoves keyboard focus to the message composer.protected void@Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> Returns the custom assistant avatar icon supplier, if one was set.protected voidhandleAssistantResponseDone(@Nullable AiChatMessage finalMessage) booleanWhether an assistant response is currently being generated for the bound conversation.protected @Nullable AiConversationloadConversation(UUID conversationId) protected Collection<AiChatMessage> Loads all messages of the bound conversation, oldest first.protected voidmarkFreshAssistantItem(UUID assistantMessageId) Locates the assistant item that just landed in the container after the post-LLM reload and stamps it with the "fresh" flag, triggering a single-row re-render viaCollectionContainer.replaceItem(E).voidonEditConversationTitleBtnClick(com.vaadin.flow.component.ClickEvent<JmixButton> event) voidonReady(Fragment.ReadyEvent event) protected voidprotected voidprocessUserMessage(AiChatMessage savedUserMessage) protected voidprotected voidprotected voidprotected voidprotected voidScrolls the timeline to the latest row, forcing the move regardless of where the user is currently looking.protected voidscrollToBottom(boolean force) Scrolls the timeline to the latest row.voidsendMessage(@Nullable String userMessage) Programmatic entry point to send a user message: persists it, appends it to the timeline, shows the thinking indicator, disables the composer and runs the assistant.voidsetAiAvatarIconSupplier(@Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> avatarIconSupplier) Sets a supplier of the avatar icon shown next to assistant messages, letting the host override the default add-on icon.voidsetConversation(@Nullable AiConversation conversation) Binds the fragment to a conversation.voidsetConversationId(@Nullable UUID conversationId) Binds the fragment to a conversation by id.voidsetMessageInputEnabled(boolean enabled) Enables or disables the message composer.voidsetReadOnly(boolean readOnly) Hides the composer and the title-edit button.protected voidprotected voidprotected voidMethods inherited from class io.jmix.flowui.fragment.Fragment
addReadyListener, findInnerComponent, getFragmentActions, getFragmentData, getFragmentFacets, getInnerComponent, getParentController, initContent, onAttach, onDetach, setFragmentActions, setFragmentData, setFragmentFacets, setParentController, setUiComponentsMethods inherited from class com.vaadin.flow.component.Composite
getChildren, getContent, getElementMethods inherited from class com.vaadin.flow.component.Component
addListener, bindVisible, findAncestor, fireEvent, from, get, getEventBus, getId, getListeners, getLocale, getParent, getTestId, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setTestId, setVisibleMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.vaadin.flow.component.AttachNotifier
addAttachListenerMethods inherited from interface com.vaadin.flow.component.DetachNotifier
addDetachListenerMethods inherited from interface io.jmix.flowui.facet.FacetOwner
getIdMethods inherited from interface com.vaadin.flow.component.HasStyle
addClassName, addClassNames, bindClassName, bindClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassName
-
Field Details
-
dataManager
-
timeSource
-
dialogs
-
notifications
-
messageService
-
conversationService
-
assistantResponseTaskCoordinator
-
timelineItemFactory
-
chatService
-
messageBundle
-
conversationTitle
-
editConversationTitleBtn
-
composerContainer
-
timelineList
-
timelineItemsDc
-
composerFragment
-
conversation
-
activeThinkingItem
-
awaitingResponse
protected boolean awaitingResponse -
readOnly
protected boolean readOnly -
aiAvatarIconSupplier
protected @Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> aiAvatarIconSupplier
-
-
Constructor Details
-
AiChatFragment
public AiChatFragment()
-
-
Method Details
-
setConversation
Binds the fragment to a conversation.- Parameters:
conversation- conversation to bind
-
setConversationId
Binds the fragment to a conversation by id. Anullid (or an id that no longer resolves) clears the fragment.- Parameters:
conversationId- conversation id to set
-
setAiAvatarIconSupplier
public void setAiAvatarIconSupplier(@Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> avatarIconSupplier) Sets a supplier of the avatar icon shown next to assistant messages, letting the host override the default add-on icon. The supplier must return a fresh component on every call.- Parameters:
avatarIconSupplier- supplier of the assistant avatar icon, ornullto use the default
-
getAiAvatarIconSupplier
public @Nullable com.vaadin.flow.function.SerializableSupplier<com.vaadin.flow.component.Component> getAiAvatarIconSupplier()Returns the custom assistant avatar icon supplier, if one was set.- Returns:
- the avatar icon supplier, or
nullwhen the default icon is used
-
setReadOnly
public void setReadOnly(boolean readOnly) Hides the composer and the title-edit button.- Parameters:
readOnly-trueto hide the composer and the title-edit button
-
focusMessageInput
public void focusMessageInput()Moves keyboard focus to the message composer. No-op if the composer is currently disabled (e.g. while the assistant is still generating a response). -
setMessageInputEnabled
public void setMessageInputEnabled(boolean enabled) Enables or disables the message composer. The fragment disables it automatically while an assistant response is in flight and re-enables it on completion; hosts can call this for additional read-only states.- Parameters:
enabled-trueto enable the composer,falseto disable it
-
onEditConversationTitleBtnClick
@Subscribe(id="editConversationTitleBtn", subject="clickListener") public void onEditConversationTitleBtnClick(com.vaadin.flow.component.ClickEvent<JmixButton> event) -
isAwaitingResponse
public boolean isAwaitingResponse()Whether an assistant response is currently being generated for the bound conversation. Hosts can use this to warn the user before closing — the background task is scoped to the host view and is cancelled (losing the answer) when the view detaches.- Returns:
truewhile an assistant response is being generated
-
sendMessage
Programmatic entry point to send a user message: persists it, appends it to the timeline, shows the thinking indicator, disables the composer and runs the assistant. Used by the composer's submit handler and by hosts that start a conversation with an initial prompt (the chat-hub flow).- Parameters:
userMessage- message text to send; anullor blank value is ignored
-
onReady
-
processUserMessage
-
handleAssistantResponseDone
-
markFreshAssistantItem
Locates the assistant item that just landed in the container after the post-LLM reload and stamps it with the "fresh" flag, triggering a single-row re-render viaCollectionContainer.replaceItem(E).- Parameters:
assistantMessageId- id of the assistant message to mark as fresh
-
showAssistantProcessingError
protected void showAssistantProcessingError() -
showThinkingIndicator
protected void showThinkingIndicator() -
removeThinkingIndicator
protected void removeThinkingIndicator() -
appendThinkingStatusUpdate
-
refreshAll
protected void refreshAll() -
loadMessages
Loads all messages of the bound conversation, oldest first. Empty when no conversation is bound or it has not been persisted yet.- Returns:
- the bound conversation's messages, oldest first; empty if none
-
forceMessageInputFocus
protected void forceMessageInputFocus() -
refreshComposerVisibility
protected void refreshComposerVisibility() -
appendTimelineItem
-
refreshTimelineItem
-
scrollToBottom
protected void scrollToBottom()Scrolls the timeline to the latest row, forcing the move regardless of where the user is currently looking. Use for discrete, user-initiated events (opening a conversation, sending a message, the assistant's final answer) where the bottom must be shown. -
scrollToBottom
protected void scrollToBottom(boolean force) Scrolls the timeline to the latest row.- Parameters:
force- whentrue, always scrolls to the bottom and resets the "stick to bottom" intent. Whenfalse, scrolls only if the user is already at (or near) the bottom — used for streaming status updates so a user who scrolled up to read is not yanked back down on every minor update.
-
createTransientAssistantMessage
-
createTimelineStatus
-
loadConversation
-
openTitleEditDialog
protected void openTitleEditDialog()
-