Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions assets/javascripts/discourse/components/ai-bot-header-icon.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import Component from "@glimmer/component";
import { action } from "@ember/object";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { defaultHomepage } from "discourse/lib/utilities";
import { i18n } from "discourse-i18n";
import { composeAiBotMessage } from "../lib/ai-bot-helper";
import { AI_CONVERSATIONS_PANEL } from "../services/ai-conversations-sidebar-manager";

export default class AiBotHeaderIcon extends Component {
@service currentUser;
@service siteSettings;
@service composer;
@service currentUser;
@service router;
@service sidebarState;
@service siteSettings;

get bots() {
const availableBots = this.currentUser.ai_enabled_chat_bots
Expand All @@ -23,20 +26,39 @@ export default class AiBotHeaderIcon extends Component {
return this.bots.length > 0 && this.siteSettings.ai_bot_add_to_header;
}

get icon() {
if (this.clickShouldRouteOutOfConversations) {
return "shuffle";
}
return "robot";
}

get clickShouldRouteOutOfConversations() {
return (
this.siteSettings.ai_enable_experimental_bot_ux &&
this.sidebarState.currentPanel?.key === AI_CONVERSATIONS_PANEL
);
}

@action
compose() {
onClick() {
if (this.clickShouldRouteOutOfConversations) {
return this.router.transitionTo(`discovery.${defaultHomepage()}`);
}

if (this.siteSettings.ai_enable_experimental_bot_ux) {
return this.router.transitionTo("discourse-ai-bot-conversations");
}

composeAiBotMessage(this.bots[0], this.composer);
}

<template>
{{#if this.showHeaderButton}}
<li>
<DButton
@action={{this.compose}}
@icon="robot"
@action={{this.onClick}}
@icon={{this.icon}}
title={{i18n "discourse_ai.ai_bot.shortcut_title"}}
class="ai-bot-button icon btn-flat"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ export default class AiConversationsSidebarManager extends Service {
@tracked newTopicForceSidebar = false;

forceCustomSidebar() {
// Set the panel to your custom panel
// Return early if we already have the correct panel, so we don't
// re-render it.
if (this.sidebarState.currentPanel?.key === AI_CONVERSATIONS_PANEL) {
return;
}

this.sidebarState.setPanel(AI_CONVERSATIONS_PANEL);

// Use separated mode to ensure independence from hamburger menu
Expand Down
35 changes: 27 additions & 8 deletions spec/system/ai_bot/homepage_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
let(:topic_page) { PageObjects::Pages::Topic.new }
let(:composer) { PageObjects::Components::Composer.new }
let(:ai_pm_homepage) { PageObjects::Components::AiPmHomepage.new }
let(:header) { PageObjects::Pages::DiscourseAi::Header.new }
let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
let(:header_dropdown) { PageObjects::Components::NavigationMenu::HeaderDropdown.new }
let(:dialog) { PageObjects::Components::Dialog.new }
Expand Down Expand Up @@ -92,14 +93,14 @@
context "when `ai_enable_experimental_bot_ux` is enabled" do
it "renders landing page on bot click" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button
expect(ai_pm_homepage).to have_homepage
expect(sidebar).to be_visible
end

it "displays error when message is too short" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button

ai_pm_homepage.input.fill_in(with: "a")
ai_pm_homepage.submit
Expand All @@ -111,15 +112,15 @@
it "renders sidebar even when navigation menu is set to header" do
SiteSetting.navigation_menu = "header dropdown"
visit "/"
find(".ai-bot-button").click
header.click_bot_button
expect(ai_pm_homepage).to have_homepage
expect(sidebar).to be_visible
expect(header_dropdown).to be_visible
end

it "hides default content in the sidebar" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button

expect(ai_pm_homepage).to have_homepage
expect(sidebar).to have_no_tags_section
Expand All @@ -132,7 +133,7 @@

it "shows the bot conversation in the sidebar" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button

expect(ai_pm_homepage).to have_homepage
expect(sidebar).to have_section("ai-conversations-history")
Expand All @@ -142,7 +143,7 @@

it "navigates to the bot conversation when clicked" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button

expect(ai_pm_homepage).to have_homepage
sidebar.find(
Expand All @@ -151,6 +152,24 @@
expect(topic_page).to have_topic_title(pm.title)
end

it "displays the shuffle icon when on homepage or bot PM" do
visit "/"
expect(header).to have_icon_in_bot_button(icon: "robot")
header.click_bot_button

expect(header).to have_icon_in_bot_button(icon: "shuffle")

# Go to a PM and assert that the icon is still shuffle
sidebar.find(
".sidebar-section[data-section-name='ai-conversations-history'] a.sidebar-section-link",
).click
expect(header).to have_icon_in_bot_button(icon: "shuffle")

# Go back home and assert that the icon is now robot again
header.click_bot_button
expect(header).to have_icon_in_bot_button(icon: "robot")
end

it "displays sidebar and 'new question' on the topic page" do
topic_page.visit_topic(pm)
expect(sidebar).to be_visible
Expand Down Expand Up @@ -193,7 +212,7 @@
sign_in(user_2)

visit "/"
find(".ai-bot-button").click
header.click_bot_button
expect(ai_pm_homepage).to have_homepage
expect(sidebar).to have_no_section_link(pm.title)
end
Expand All @@ -204,7 +223,7 @@

it "opens composer on bot click" do
visit "/"
find(".ai-bot-button").click
header.click_bot_button

expect(ai_pm_homepage).to have_no_homepage
expect(composer).to be_opened
Expand Down
17 changes: 17 additions & 0 deletions spec/system/page_objects/pages/discourse_ai/header.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module PageObjects
module Pages
module DiscourseAi
class Header < ::PageObjects::Pages::Header
def click_bot_button
find(".ai-bot-button").click
end

def has_icon_in_bot_button?(icon:)
page.has_css?(".ai-bot-button .d-icon-#{icon}")
end
end
end
end
end