Issue #3499451: Restore toolbar chatbot state idempotently so a dialog re-attach cannot close it
Closes #3499451.
Refactored onto 1.x per the review on !1277 (which targeted 1.2.x). Same fork branch, retargeted to the default development branch; original approach by joshua1234511.
Scope (after the investigation in the issue)
The issue collected two different problems. Ahmad-Khader's investigation (issue comment, Jul 19) separated them:
- Klaro re-hide -- the symptom most reporters hit ("Yes (this time)" consent lost when any AJAX dialog re-attaches behaviors). That is a bug in the klaro module's klaro.drupal.js, not in the chatbot, and is now tracked in https://www.drupal.org/project/klaro/issues/3613540. This MR does not and cannot fix it.
- The chatbot's own toggle/state-restore bug -- the blind toggleChatbot() flipping an already-open chatbot closed when the toolbar button is processed a second time (dialog re-attach, classic toolbar double-processing). That is what this MR fixes, and it reproduces without Klaro installed.
Problem
The toolbar chatbot closes itself and cannot be reopened without a page reload when a CKEditor or Media Library dialog is used while the chatbot is open.
Root cause
attach() restores a saved-open chatbot by calling the blind toggleChatbot(), which does classList.toggle('ai-chatbot-opened'). When a dialog re-attaches behaviors and the toolbar button is re-rendered, once() processes the new button and the blind toggle flips an already-open chatbot closed. The close persists to localStorage, so the next restore reopens then a later re-attach closes it again, and the user cannot recover without reloading.
Fix
Replace the restore and toggle with an idempotent setChatbotOpen(open) that sets the body class to match the requested state instead of flipping it. Restoring an already-open chatbot on re-attach is now a no-op. Single file: modules/ai_chatbot/js/toolbar-chatbot.js.
Testing steps
- Install and enable the toolbar chatbot; place the AI chatbot in the toolbar and open it (body gets
ai-chatbot-opened). - Edit a node with a CKEditor field, click Insert Media to open the Media Library dialog.
- Confirm the chatbot stays open while the dialog opens and closes (before this fix it closed and could not be reopened).
- Insert the media, confirm the chatbot is still open and usable.
- Toggle the chatbot closed and open again via the toolbar button and the close button; confirm both work.
- Reload the page with the chatbot open; confirm it restores open and can still be toggled.
Automated check
A DOM-stub harness that loads the real behavior and simulates the dialog re-attach (a fresh .button--ai-chatbot processed by once() a second time) confirms the difference: on the pre-fix code the body loses ai-chatbot-opened after the re-attach (reproduces the bug); with this fix it stays open.
Notes
1.2.x has diverged from 1.x (parallel branches), and the same bug is present there under the Drupal.ai.chatbotExpanded localStorage key. A separate backport can carry the same idempotent fix to 1.2.x if that branch is still maintained.
AI usage
AI assisted: root-cause analysis, the fix, and the verification harness were produced with AI assistance and reviewed before pushing.