Skip to content

Develop - #665

Merged
tiberiuichim merged 18 commits into
masterfrom
develop
Sep 4, 2026
Merged

Develop#665
tiberiuichim merged 18 commits into
masterfrom
develop

Conversation

@tiberiuichim

Copy link
Copy Markdown
Member

No description provided.

tiberiuichim and others added 18 commits August 21, 2026 13:52
Register a 'catalogue' presentation variation on the AI Chatbot block
(@eeacms/volto-eea-chatbot), following the cross-addon variation push
pattern used by the TabsBlock 'spotlight' variation.

Rough first iteration of the presentation:
- reuses the chatbot core (useChatController, markdown components,
  AutoResizeTextarea, EmptyState)
- streamed answer rendered inline, no Sources tab
- cited documents rendered below the answer as document cards in the
  style of the Navigator catalogue cards (Onyx-provided metadata only
  for now; Plone REST enrichment with full catalogue metadata comes
  in a follow-up)

Block fields are read from top-level props (ChatBlockView renders
<Presentation persona=... {...blockData} />), matching the classic
ChatWindow contract.
…nt cards

Fixes:
- Block fields (onyxVersion, qgenAsistantId, enableQgen, placeholder,
  starter prompts, ...) are read from top-level props, matching the
  <Presentation persona=... {...blockData} /> contract of the classic
  ChatWindow. Previously a non-existent 'data' prop was read, silently
  dropping onyxVersion and falling back to the v2 API.
- Assistant messages now render through the chatbot core's
  RendererComponent (as AIMessage does), so the answer streams with the
  typewriter reveal, blinking cursor and citations; a BlinkingDot shows
  while the assistant is working (search-tool phase). Message keys
  switched to the stable nodeId.

Features (document cards):
- Inline ![[doc: Title]] markers in the answer text are converted by a
  remark plugin (docCards.js) into cca-doc-card elements, rendered as
  document cards via extraMarkdownComponents (new pass-through props on
  the chatbot's MessageTextRenderer/RendererComponent).
- DocumentCard extracted to its own module; the 'Relevant documents'
  grid and the inline cards both use EnhancedDocCard, which upgrades
  from the basic Onyx-fields card to the full Navigator catalogue card
  once the document is fetched.
- useCatalogueDoc: fetches a document from the globalsearch ES index by
  URL (_id) via searchlib's fetchResult (GET /_es/globalsearch/_doc/{id}
  passthrough, whitelisted in the volto-searchlib middleware), appConfig
  from the searchlib registry (settings.searchlib.searchui), with a
  module-level cache per URL.
- Extract Navigator catalogue card CSS into a shared mixin and apply it in
  the chat (.catalogue-chat .catalogue-chat-navigator-card), not only in
  the searchlib results page — the card was rendering unstyled in chat.
- docCards: match ![[doc: ...]] markers in any text node (own line, list
  items, mid-sentence), not only whole paragraphs.
- Hide the "Relevant documents" grid (inline cards replace it; kept for
  easy restore) and drop the temporary RAW MESSAGE debug log.
Restore the full classic chatbot functionality (Thinking/tools accordion,
styled New-chat button, streaming placeholder, quality check, related
questions, feedback) by reusing the classic ChatWindow instead of the
hand-rolled view. The catalogue variation now only:

- passes hideSourcesTab (classic Sources tab/sidebar/inline list hidden;
  the inline catalogue cards are the document UI), and
- injects the ![[doc: ...]] remark plugin + a stable cca-doc-card component
  (CcaDocCard) that reads the owning message from ChatMessageContext and
  renders the inline Navigator-style catalogue cards.

CatalogueChatView is now a thin wrapper; removed the now-unused view
subcomponents and their CSS. Doc-card CSS in navigator.less no longer needs
the .catalogue-chat parent.
The core MessageTextRenderer re-renders the whole markdown tree on every
streaming tick, which was re-rendering every (potentially heavy) catalogue
card tens of times a second.

- Memoize DocumentCard/EnhancedDocCard with a field-based comparator (the
  inline card rebuilds its `source` object each render, so plain `===` would
  never memoize). Cards now only re-render when their own data changes; the
  one-time basic->full upgrade is still driven by internal state.
- useCatalogueDoc: keep a resolved-value cache and initialize/short-circuit
  from it, so an already-known doc renders the full card immediately instead
  of flashing the basic card first (repeat doc, remount, same URL twice).
The `.catalogue-compare` label (checkbox + "Compare" text) is only made into
a centered inline-flex inside `.searchapp-navigatorCatalogueSearch`. The chat
catalogue card lives under `.catalogue-chat-navigator-card`, not that
ancestor, so the label fell back to default inline flow and the Semantic UI
checkbox's default spacing pushed the "Compare" text out of line with the
box. Extend the selector to cover the chat card wrapper.
Import the chat module namespace instead of the ChatMessageContext named
export so the app still compiles when an environment resolves a
pre-4.1.0 @eeacms/volto-eea-chatbot; CcaDocCard then falls back to the
basic metadata card (no document matching).
Covers the remark doc-marker plugin, the document cards (basic, enhanced,
inline, context-based CcaDocCard), the catalogue ES lookup hook (fetch,
cache, error paths) and the variation registration / ChatWindow wrapper,
restoring the SonarQube coverage gate after the new code landed.
- Use Navigator catalogue card structure and components in base DocumentCard
- Add cleanDocumentTitle and resilient matchesDocumentTitle for pipeline titles
- Add normalizeCatalogueUrl in useCatalogueDoc for Elasticsearch URL matching
- Compact inline card bottom margin in catalogue-chat.less
- Add unit tests for title cleaning, view button, and URL normalization
feat: Chatbot 'catalogue' presentation variation (cards & suggested next steps)
@tiberiuichim
tiberiuichim merged commit 27e679f into master Sep 4, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant