UX: Empty state for AI conversations sidebar & btn changes (#1297)

This commit adds an empty state when the user doesn't have any PM history. It ALSO retains the new conversation button in the sidebar so it no longer jumps. The button is disabled, icon, and text are all updated.
This commit is contained in:
Mark VanLandingham 2025-04-30 11:33:41 -05:00 committed by GitHub
parent 81a664b3da
commit 1e32416eaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 44 additions and 12 deletions

View File

@ -0,0 +1,7 @@
import { i18n } from "discourse-i18n";
<template>
<div class="ai-bot-sidebar-empty-state">
{{i18n "discourse_ai.ai_bot.sidebar_empty"}}
</div>
</template>

View File

@ -9,15 +9,14 @@ export default class AiBotSidebarNewConversation extends Component {
@service sidebarState; @service sidebarState;
get shouldRender() { get shouldRender() {
return ( return this.sidebarState.isCurrentPanel(AI_CONVERSATIONS_PANEL);
this.router.currentRouteName !== "discourse-ai-bot-conversations" &&
this.sidebarState.isCurrentPanel(AI_CONVERSATIONS_PANEL)
);
} }
@action @action
routeTo() { routeTo() {
this.router.transitionTo("/discourse-ai/ai-bot/conversations"); if (this.router.currentRouteName !== "discourse-ai-bot-conversations") {
this.router.transitionTo("/discourse-ai/ai-bot/conversations");
}
this.args.outletArgs?.toggleNavigationMenu?.(); this.args.outletArgs?.toggleNavigationMenu?.();
} }

View File

@ -31,6 +31,7 @@ export default RouteTemplate(
{{on "input" @controller.updateInputValue}} {{on "input" @controller.updateInputValue}}
{{on "keydown" @controller.handleKeyDown}} {{on "keydown" @controller.handleKeyDown}}
id="ai-bot-conversations-input" id="ai-bot-conversations-input"
autofocus="true"
placeholder={{i18n "discourse_ai.ai_bot.conversations.placeholder"}} placeholder={{i18n "discourse_ai.ai_bot.conversations.placeholder"}}
minlength="10" minlength="10"
disabled={{@controller.loading}} disabled={{@controller.loading}}

View File

@ -6,6 +6,7 @@ import { bind } from "discourse/lib/decorators";
import { autoUpdatingRelativeAge } from "discourse/lib/formatter"; import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
import { withPluginApi } from "discourse/lib/plugin-api"; import { withPluginApi } from "discourse/lib/plugin-api";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import AiBotSidebarEmptyState from "../discourse/components/ai-bot-sidebar-empty-state";
import AiBotSidebarNewConversation from "../discourse/components/ai-bot-sidebar-new-conversation"; import AiBotSidebarNewConversation from "../discourse/components/ai-bot-sidebar-new-conversation";
import { AI_CONVERSATIONS_PANEL } from "../discourse/services/ai-conversations-sidebar-manager"; import { AI_CONVERSATIONS_PANEL } from "../discourse/services/ai-conversations-sidebar-manager";
@ -121,6 +122,10 @@ export default {
return "ai-conversations-history"; return "ai-conversations-history";
} }
get emptyStateComponent() {
return AiBotSidebarEmptyState;
}
get text() { get text() {
return i18n( return i18n(
"discourse_ai.ai_bot.conversations.messages_sidebar_title" "discourse_ai.ai_bot.conversations.messages_sidebar_title"

View File

@ -673,6 +673,7 @@ en:
share: "Copy AI conversation" share: "Copy AI conversation"
conversation_shared: "Conversation copied" conversation_shared: "Conversation copied"
debug_ai: "View raw AI request and response" debug_ai: "View raw AI request and response"
sidebar_empty: "Bot conversation history will appear here."
debug_ai_modal: debug_ai_modal:
title: "View AI interaction" title: "View AI interaction"
copy_request: "Copy request" copy_request: "Copy request"

View File

@ -149,7 +149,6 @@ RSpec.describe "AI Bot - Homepage", type: :system do
expect(sidebar).to have_section("ai-conversations-history") expect(sidebar).to have_section("ai-conversations-history")
expect(sidebar).to have_section_link("Today") expect(sidebar).to have_section_link("Today")
expect(sidebar).to have_section_link(pm.title) expect(sidebar).to have_section_link(pm.title)
expect(sidebar).to have_no_css("button.ai-new-question-button")
end end
it "displays last_7_days label in the sidebar" do it "displays last_7_days label in the sidebar" do
@ -204,16 +203,18 @@ RSpec.describe "AI Bot - Homepage", type: :system do
expect(header).to have_icon_in_bot_button(icon: "robot") expect(header).to have_icon_in_bot_button(icon: "robot")
end end
it "displays sidebar and 'new question' on the topic page" do it "displays 'new question' button on homepage and topic page" do
topic_page.visit_topic(pm) topic_page.visit_topic(pm)
expect(sidebar).to be_visible expect(ai_pm_homepage).to have_new_question_button
expect(sidebar).to have_css("button.ai-new-question-button")
ai_pm_homepage.visit
expect(ai_pm_homepage).to have_new_question_button
end end
it "redirect to the homepage when 'new question' is clicked" do it "redirect to the homepage when 'new question' is clicked" do
topic_page.visit_topic(pm) topic_page.visit_topic(pm)
expect(sidebar).to be_visible expect(sidebar).to be_visible
sidebar.find("button.ai-new-question-button").click ai_pm_homepage.click_new_question_button
expect(ai_pm_homepage).to have_homepage expect(ai_pm_homepage).to have_homepage
end end
@ -232,6 +233,7 @@ RSpec.describe "AI Bot - Homepage", type: :system do
Fabricate(:post, topic: pm, user: user_2, post_number: 4) Fabricate(:post, topic: pm, user: user_2, post_number: 4)
Fabricate(:topic_allowed_user, topic: pm, user: user_2) Fabricate(:topic_allowed_user, topic: pm, user: user_2)
sign_in(user_2) sign_in(user_2)
topic_page.visit_topic(pm) topic_page.visit_topic(pm)
expect(sidebar).to be_visible expect(sidebar).to be_visible
@ -244,13 +246,18 @@ RSpec.describe "AI Bot - Homepage", type: :system do
Fabricate(:post, topic: pm, user: user_2, post_number: 4) Fabricate(:post, topic: pm, user: user_2, post_number: 4)
Fabricate(:topic_allowed_user, topic: pm, user: user_2) Fabricate(:topic_allowed_user, topic: pm, user: user_2)
sign_in(user_2) sign_in(user_2)
visit "/" visit "/"
header.click_bot_button header.click_bot_button
expect(ai_pm_homepage).to have_homepage expect(ai_pm_homepage).to have_homepage
expect(sidebar).to have_no_section_link(pm.title) expect(sidebar).to have_no_section_link(pm.title)
end end
it "renders empty state in sidebar with no bot PM history" do
sign_in(user_2)
ai_pm_homepage.visit
expect(ai_pm_homepage).to have_empty_state
end
it "Allows choosing persona and LLM" do it "Allows choosing persona and LLM" do
ai_pm_homepage.visit ai_pm_homepage.visit
@ -325,7 +332,7 @@ RSpec.describe "AI Bot - Homepage", type: :system do
it "displays the new question button in the menu when viewing a PM" do it "displays the new question button in the menu when viewing a PM" do
ai_pm_homepage.visit ai_pm_homepage.visit
header_dropdown.open header_dropdown.open
expect(ai_pm_homepage).to have_no_new_question_button expect(ai_pm_homepage).to have_new_question_button
topic_page.visit_topic(pm) topic_page.visit_topic(pm)
header_dropdown.open header_dropdown.open

View File

@ -36,10 +36,22 @@ module PageObjects
page.has_no_css?(".ai-new-question-button") page.has_no_css?(".ai-new-question-button")
end end
def has_new_question_button?
sidebar = PageObjects::Components::NavigationMenu::Sidebar.new
sidebar.has_css?(
"button.ai-new-question-button",
text: I18n.t("js.discourse_ai.ai_bot.conversations.new"),
)
end
def click_new_question_button def click_new_question_button
page.find(".ai-new-question-button").click page.find(".ai-new-question-button").click
end end
def has_empty_state?
page.has_css?(".ai-bot-sidebar-empty-state")
end
def click_fist_sidebar_conversation def click_fist_sidebar_conversation
page.find( page.find(
".sidebar-section[data-section-name='ai-conversations-history'] a.sidebar-section-link:not(.date-heading)", ".sidebar-section[data-section-name='ai-conversations-history'] a.sidebar-section-link:not(.date-heading)",