From 3800728d52a610ddf9444af3042ea40bfc21dc55 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 2 May 2025 13:46:22 +1000 Subject: [PATCH] FIX: clear uploads after successfully posting new PM (#1307) This PR addresses a bug where uploads weren't being cleared after successfully posting a new private message in the AI bot conversations interface. Here's what the changes do: ## Main Fix: - Makes the `prepareAndSubmitToBot()` method async and adds proper error handling - Adds `this.uploads.clear()` after successful submission to clear all uploads - Adds a test to verify that the "New Question" button properly resets the UI with no uploads ## Additional Improvements: 1. **Dynamic Character Length Validation**: - Uses `siteSettings.min_personal_message_post_length` instead of hardcoded 10 characters - Updates the error message to show the dynamic character count - Adds proper pluralization in the localization file for the error message 2. **Bug Fixes**: - Adds null checks with optional chaining (`link?.topic?.id`) in the sidebar code to prevent potential errors 3. **Code Organization**: - Moves error handling from the service to the controller for better separation of concerns --- .../controllers/discourse-ai-bot-conversations.js | 10 ++++++++-- .../services/ai-bot-conversations-hidden-submit.js | 12 +++++++----- .../initializers/ai-conversations-sidebar.js | 2 +- config/locales/client.en.yml | 4 +++- spec/system/ai_bot/homepage_spec.rb | 4 ++++ .../system/page_objects/components/ai_pm_homepage.rb | 6 +++++- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/assets/javascripts/discourse/controllers/discourse-ai-bot-conversations.js b/assets/javascripts/discourse/controllers/discourse-ai-bot-conversations.js index 2048890b..167cfbc0 100644 --- a/assets/javascripts/discourse/controllers/discourse-ai-bot-conversations.js +++ b/assets/javascripts/discourse/controllers/discourse-ai-bot-conversations.js @@ -3,6 +3,7 @@ import Controller from "@ember/controller"; import { action } from "@ember/object"; import { getOwner } from "@ember/owner"; import { service } from "@ember/service"; +import { popupAjaxError } from "discourse/lib/ajax-error"; import UppyUpload from "discourse/lib/uppy/uppy-upload"; import UppyMediaOptimization from "discourse/lib/uppy-media-optimization-plugin"; import { clipboardHelpers } from "discourse/lib/utilities"; @@ -172,10 +173,15 @@ export default class DiscourseAiBotConversations extends Controller { } @action - prepareAndSubmitToBot() { + async prepareAndSubmitToBot() { // Pass uploads to the service before submitting this.aiBotConversationsHiddenSubmit.uploads = this.uploads; - this.aiBotConversationsHiddenSubmit.submitToBot(); + try { + await this.aiBotConversationsHiddenSubmit.submitToBot(); + this.uploads.clear(); + } catch (error) { + popupAjaxError(error); + } } _autoExpandTextarea() { diff --git a/assets/javascripts/discourse/services/ai-bot-conversations-hidden-submit.js b/assets/javascripts/discourse/services/ai-bot-conversations-hidden-submit.js index 4eb6fa90..1749ba98 100644 --- a/assets/javascripts/discourse/services/ai-bot-conversations-hidden-submit.js +++ b/assets/javascripts/discourse/services/ai-bot-conversations-hidden-submit.js @@ -3,7 +3,6 @@ import { next } from "@ember/runloop"; import Service, { service } from "@ember/service"; import { tracked } from "@ember-compat/tracked-built-ins"; import { ajax } from "discourse/lib/ajax"; -import { popupAjaxError } from "discourse/lib/ajax-error"; import { getUploadMarkdown } from "discourse/lib/uploads"; import { i18n } from "discourse-i18n"; @@ -13,6 +12,7 @@ export default class AiBotConversationsHiddenSubmit extends Service { @service composer; @service dialog; @service router; + @service siteSettings; @tracked loading = false; @@ -33,10 +33,14 @@ export default class AiBotConversationsHiddenSubmit extends Service { @action async submitToBot() { - if (this.inputValue.length < 10) { + if ( + this.inputValue.length < + this.siteSettings.min_personal_message_post_length + ) { return this.dialog.alert({ message: i18n( - "discourse_ai.ai_bot.conversations.min_input_length_message" + "discourse_ai.ai_bot.conversations.min_input_length_message", + { count: this.siteSettings.min_personal_message_post_length } ), didConfirm: () => this.focusInput(), didCancel: () => this.focusInput(), @@ -89,8 +93,6 @@ export default class AiBotConversationsHiddenSubmit extends Service { }); this.router.transitionTo(response.post_url); - } catch (e) { - popupAjaxError(e); } finally { this.loading = false; } diff --git a/assets/javascripts/initializers/ai-conversations-sidebar.js b/assets/javascripts/initializers/ai-conversations-sidebar.js index 895468cd..764af7a5 100644 --- a/assets/javascripts/initializers/ai-conversations-sidebar.js +++ b/assets/javascripts/initializers/ai-conversations-sidebar.js @@ -319,7 +319,7 @@ export default { // force Glimmer to re-render that one link this.links = this.links.map((link) => - link.topic.id === topic.id + link?.topic?.id === topic.id ? new AiConversationLink(topic) : link ); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d153800c..3a4fb037 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -726,7 +726,9 @@ en: disclaimer: "Generative AI can make mistakes. Verify important information." placeholder: "Ask a question..." new: "New Question" - min_input_length_message: "Message must be longer than 10 characters" + min_input_length_message: + one: "Message must be 1 character or longer" + other: "Message must be %{count} characters or longer" messages_sidebar_title: "Conversations" today: "Today" last_7_days: "Last 7 days" diff --git a/spec/system/ai_bot/homepage_spec.rb b/spec/system/ai_bot/homepage_spec.rb index c0500c1d..f6cd2e16 100644 --- a/spec/system/ai_bot/homepage_spec.rb +++ b/spec/system/ai_bot/homepage_spec.rb @@ -131,6 +131,10 @@ RSpec.describe "AI Bot - Homepage", type: :system do expect(topic_page).to have_content("Here are two image attachments") expect(page).to have_css(".cooked img", count: 2) end + + find(".ai-new-question-button").click + expect(ai_pm_homepage).to have_homepage + expect(page).to have_no_css(".ai-bot-upload") end it "allows removing an upload before submission" do diff --git a/spec/system/page_objects/components/ai_pm_homepage.rb b/spec/system/page_objects/components/ai_pm_homepage.rb index f850ebcd..69b93af3 100644 --- a/spec/system/page_objects/components/ai_pm_homepage.rb +++ b/spec/system/page_objects/components/ai_pm_homepage.rb @@ -20,7 +20,11 @@ module PageObjects def has_too_short_dialog? page.find( ".dialog-content", - text: I18n.t("js.discourse_ai.ai_bot.conversations.min_input_length_message"), + text: + I18n.t( + "js.discourse_ai.ai_bot.conversations.min_input_length_message", + count: SiteSetting.min_personal_message_post_length, + ), ) end