Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit bb32d0d

Browse files
authored
FEATURE: Add ability to disable search discoveries (#1177)
This update adds the ability to disable search discoveries. This can be done through a tooltip when search discoveries are shown. It can also be done in the AI user preferences, which has also been updated to accommodate more than just the one image caption setting.
1 parent 339251a commit bb32d0d

File tree

15 files changed

+245
-85
lines changed

15 files changed

+245
-85
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import Component from "@glimmer/component";
2+
import { service } from "@ember/service";
3+
import DButton from "discourse/components/d-button";
4+
import icon from "discourse/helpers/d-icon";
5+
import { i18n } from "discourse-i18n";
6+
import DTooltip from "float-kit/components/d-tooltip";
7+
8+
export default class AiSearchDiscoveriesTooltip extends Component {
9+
@service discobotDiscoveries;
10+
11+
<template>
12+
<span class="ai-search-discoveries-tooltip">
13+
<DTooltip @placement="top-end" @interactive={{true}}>
14+
<:trigger>
15+
{{icon "circle-info"}}
16+
</:trigger>
17+
<:content>
18+
<div class="ai-search-discoveries-tooltip__content">
19+
<div class="ai-search-discoveries-tooltip__header">
20+
{{i18n "discourse_ai.discobot_discoveries.tooltip.header"}}
21+
</div>
22+
23+
<div class="ai-search-discoveries-tooltip__description">
24+
{{#if this.discobotDiscoveries.modelUsed}}
25+
{{i18n
26+
"discourse_ai.discobot_discoveries.tooltip.content"
27+
model=this.discobotDiscoveries.modelUsed
28+
}}
29+
{{/if}}
30+
</div>
31+
32+
<div class="ai-search-discoveries-tooltip__actions">
33+
<DButton
34+
class="btn-transparent btn-primary"
35+
@label="discourse_ai.discobot_discoveries.tooltip.actions.info"
36+
@href="https://meta.discourse.org/t/conversational-ai-search-coming-to-discourse-ai/355939"
37+
/>
38+
<DButton
39+
class="btn-transparent btn-danger"
40+
@label="discourse_ai.discobot_discoveries.tooltip.actions.disable"
41+
@action={{this.discobotDiscoveries.disableDiscoveries}}
42+
/>
43+
</div>
44+
</div>
45+
</:content>
46+
</DTooltip>
47+
</span>
48+
</template>
49+
}

assets/javascripts/discourse/connectors/full-page-search-below-search-header/ai-full-page-discobot-discoveries.gjs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import Component from "@glimmer/component";
22
import { service } from "@ember/service";
33
import icon from "discourse/helpers/d-icon";
44
import { i18n } from "discourse-i18n";
5-
import DTooltip from "float-kit/components/d-tooltip";
65
import AiSearchDiscoveries from "../../components/ai-search-discoveries";
6+
import AiSearchDiscoveriesTooltip from "../../components/ai-search-discoveries-tooltip";
77

88
export default class AiFullPageDiscobotDiscoveries extends Component {
99
static shouldRender(_args, { siteSettings, currentUser }) {
1010
return (
1111
siteSettings.ai_bot_discover_persona &&
12-
currentUser?.can_use_ai_bot_discover_persona
12+
currentUser?.can_use_ai_bot_discover_persona &&
13+
currentUser?.user_option?.ai_search_discoveries
1314
);
1415
}
1516

@@ -29,29 +30,7 @@ export default class AiFullPageDiscobotDiscoveries extends Component {
2930
{{i18n "discourse_ai.discobot_discoveries.main_title"}}
3031
</span>
3132

32-
<span class="ai-search-discoveries-tooltip">
33-
<DTooltip @placement="top-end">
34-
<:trigger>
35-
{{icon "circle-info"}}
36-
</:trigger>
37-
<:content>
38-
<div class="ai-search-discoveries-tooltip__content">
39-
<div class="ai-search-discoveries-tooltip__header">
40-
{{i18n "discourse_ai.discobot_discoveries.tooltip.header"}}
41-
</div>
42-
43-
<div class="ai-search-discoveries-tooltip__content">
44-
{{#if this.discobotDiscoveries.modelUsed}}
45-
{{i18n
46-
"discourse_ai.discobot_discoveries.tooltip.content"
47-
model=this.discobotDiscoveries.modelUsed
48-
}}
49-
{{/if}}
50-
</div>
51-
</div>
52-
</:content>
53-
</DTooltip>
54-
</span>
33+
<AiSearchDiscoveriesTooltip />
5534
</h3>
5635
<div class="full-page-discoveries">
5736
<AiSearchDiscoveries @searchTerm={{@outletArgs.search}} />

assets/javascripts/discourse/connectors/search-menu-results-type-top/ai-discobot-discoveries.gjs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import Component from "@glimmer/component";
22
import { service } from "@ember/service";
33
import icon from "discourse/helpers/d-icon";
44
import { i18n } from "discourse-i18n";
5-
import DTooltip from "float-kit/components/d-tooltip";
65
import AiSearchDiscoveries from "../../components/ai-search-discoveries";
6+
import AiSearchDiscoveriesTooltip from "../../components/ai-search-discoveries-tooltip";
77

88
export default class AiDiscobotDiscoveries extends Component {
99
static shouldRender(args, { siteSettings, currentUser }) {
1010
return (
1111
args.resultType.type === "topic" &&
1212
siteSettings.ai_bot_discover_persona &&
13-
currentUser?.can_use_ai_bot_discover_persona
13+
currentUser?.can_use_ai_bot_discover_persona &&
14+
currentUser?.user_option?.ai_search_discoveries
1415
);
1516
}
1617

@@ -24,29 +25,7 @@ export default class AiDiscobotDiscoveries extends Component {
2425
{{i18n "discourse_ai.discobot_discoveries.main_title"}}
2526
</span>
2627

27-
<span class="ai-search-discoveries-tooltip">
28-
<DTooltip @placement="top-end">
29-
<:trigger>
30-
{{icon "circle-info"}}
31-
</:trigger>
32-
<:content>
33-
<div class="ai-search-discoveries-tooltip__content">
34-
<div class="ai-search-discoveries-tooltip__header">
35-
{{i18n "discourse_ai.discobot_discoveries.tooltip.header"}}
36-
</div>
37-
38-
<div class="ai-search-discoveries-tooltip__content">
39-
{{#if this.discobotDiscoveries.modelUsed}}
40-
{{i18n
41-
"discourse_ai.discobot_discoveries.tooltip.content"
42-
model=this.discobotDiscoveries.modelUsed
43-
}}
44-
{{/if}}
45-
</div>
46-
</div>
47-
</:content>
48-
</DTooltip>
49-
</span>
28+
<AiSearchDiscoveriesTooltip />
5029
</h3>
5130

5231
<AiSearchDiscoveries @discoveryPreviewLength={{50}} />

assets/javascripts/discourse/controllers/preferences-ai.js

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,62 @@ import { service } from "@ember/service";
55
import { popupAjaxError } from "discourse/lib/ajax-error";
66
import { isTesting } from "discourse/lib/environment";
77

8-
const AI_ATTRS = ["auto_image_caption"];
9-
108
export default class PreferencesAiController extends Controller {
119
@service siteSettings;
1210
@tracked saved = false;
1311

14-
get showAutoImageCaptionSetting() {
15-
const aiHelperEnabledFeatures =
16-
this.siteSettings.ai_helper_enabled_features.split("|");
12+
get booleanSettings() {
13+
return [
14+
{
15+
key: "auto_image_caption",
16+
label: "discourse_ai.ai_helper.image_caption.automatic_caption_setting",
17+
settingName: "auto-image-caption",
18+
checked: this.model.user_option.auto_image_caption,
19+
isIncluded: (() => {
20+
const aiHelperEnabledFeatures =
21+
this.siteSettings.ai_helper_enabled_features.split("|");
22+
23+
return (
24+
this.model?.user_allowed_ai_auto_image_captions &&
25+
aiHelperEnabledFeatures.includes("image_caption") &&
26+
this.siteSettings.ai_helper_enabled
27+
);
28+
})(),
29+
},
30+
{
31+
key: "ai_search_discoveries",
32+
label: "discourse_ai.discobot_discoveries.user_setting",
33+
settingName: "ai-search-discoveries",
34+
checked: this.model.user_option.ai_search_discoveries,
35+
isIncluded: (() => {
36+
return (
37+
this.siteSettings.ai_bot_discover_persona &&
38+
this.model?.can_use_ai_bot_discover_persona &&
39+
this.siteSettings.ai_bot_enabled
40+
);
41+
})(),
42+
},
43+
];
44+
}
45+
46+
get userSettingAttributes() {
47+
const attrs = [];
48+
49+
this.booleanSettings.forEach((setting) => {
50+
if (setting.isIncluded) {
51+
attrs.push(setting.key);
52+
}
53+
});
1754

18-
return (
19-
this.model?.user_allowed_ai_auto_image_captions &&
20-
aiHelperEnabledFeatures.includes("image_caption") &&
21-
this.siteSettings.ai_helper_enabled
22-
);
55+
return attrs;
2356
}
2457

2558
@action
2659
save() {
2760
this.saved = false;
2861

2962
return this.model
30-
.save(AI_ATTRS)
63+
.save(this.userSettingAttributes)
3164
.then(() => {
3265
this.saved = true;
3366
if (!isTesting()) {

assets/javascripts/discourse/services/discobot-discoveries.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { tracked } from "@glimmer/tracking";
2-
import Service from "@ember/service";
2+
import { action } from "@ember/object";
3+
import Service, { service } from "@ember/service";
34

45
export default class DiscobotDiscoveries extends Service {
56
// We use this to retain state after search menu gets closed.
67
// Similar to discourse/discourse#25504
8+
@service currentUser;
9+
710
@tracked discovery = "";
811
@tracked lastQuery = "";
912
@tracked discoveryTimedOut = false;
@@ -14,4 +17,11 @@ export default class DiscobotDiscoveries extends Service {
1417
this.discoveryTimedOut = false;
1518
this.modelUsed = "";
1619
}
20+
21+
@action
22+
async disableDiscoveries() {
23+
this.currentUser.user_option.ai_search_discoveries = false;
24+
await this.currentUser.save(["ai_search_discoveries"]);
25+
location.reload();
26+
}
1727
}
Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
1-
{{!
2-
Later when we have more preferences,
3-
move the conditional (showAutoImageCaptionSetting)
4-
to be only around the auto-image-caption preference.
5-
}}
6-
{{#if this.showAutoImageCaptionSetting}}
7-
<label class="control-label">{{i18n "discourse_ai.title"}}</label>
1+
<div class="ai-user-preferences">
2+
<legend class="control-label">{{i18n "discourse_ai.title"}}</legend>
83

9-
<div class="control-group ai-setting">
10-
<PreferenceCheckbox
11-
@labelKey="discourse_ai.ai_helper.image_caption.automatic_caption_setting"
12-
@checked={{this.model.user_option.auto_image_caption}}
13-
data-setting-name="auto-image-caption"
14-
class="pref-auto-image-caption"
15-
/>
16-
</div>
4+
{{#each this.booleanSettings as |setting|}}
5+
{{#if setting.isIncluded}}
6+
<div class="control-group ai-setting">
7+
<PreferenceCheckbox
8+
@labelKey={{setting.label}}
9+
@checked={{get this.model.user_option setting.key}}
10+
data-setting-name={{setting.settingName}}
11+
class="pref-{{setting.settingName}}"
12+
/>
13+
</div>
14+
{{/if}}
15+
{{/each}}
16+
17+
{{#if (eq this.userSettingAttributes.length 0)}}
18+
{{i18n "discourse_ai.user_preferences.empty"}}
19+
{{/if}}
1720

18-
<SaveControls
19-
@id="user_ai_preference_save"
20-
@model={{this.model}}
21-
@action={{this.save}}
22-
@saved={{this.saved}}
23-
/>
24-
{{/if}}
21+
{{#unless (eq this.userSettingAttributes.length 0)}}
22+
<SaveControls
23+
@id="user_ai_preference_save"
24+
@model={{this.model}}
25+
@action={{this.save}}
26+
@saved={{this.saved}}
27+
/>
28+
{{/unless}}
29+
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { apiInitializer } from "discourse/lib/api";
2+
3+
export default apiInitializer((api) => {
4+
const currentUser = api.getCurrentUser();
5+
const settings = api.container.lookup("service:site-settings");
6+
7+
if (
8+
!settings.ai_bot_enabled ||
9+
!currentUser?.can_use_ai_bot_discover_persona
10+
) {
11+
return;
12+
}
13+
14+
api.addSaveableUserOptionField("ai_search_discoveries");
15+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.user-preferences .ai-user-preferences {
2+
legend {
3+
margin-bottom: 1rem;
4+
}
5+
6+
.control-group {
7+
margin-bottom: 0;
8+
}
9+
10+
.save-button {
11+
margin-top: 2rem;
12+
}
13+
}

assets/stylesheets/modules/ai-bot/common/ai-discobot-discoveries.scss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,26 @@
6363
}
6464

6565
.ai-search-discoveries-tooltip {
66+
&__content {
67+
padding: 0.5rem;
68+
}
69+
6670
&__header {
6771
font-weight: bold;
6872
margin-bottom: 0.5em;
6973
}
7074

75+
&__actions {
76+
display: flex;
77+
justify-content: space-between;
78+
gap: 1rem;
79+
margin-top: 1rem;
80+
81+
.btn {
82+
padding: 0;
83+
}
84+
}
85+
7186
.fk-d-tooltip__trigger {
7287
vertical-align: middle;
7388
}

config/locales/client.en.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ en:
9999
label: "Tool"
100100
description: "Tool to use for triage (tool must have no parameters defined)"
101101

102-
103102
llm_persona_triage:
104103
fields:
105104
persona:
@@ -714,9 +713,16 @@ en:
714713
tell_me_more: "Tell me more..."
715714
collapse: "Collapse"
716715
timed_out: "Discobot couldn't find any discoveries. Something went wrong."
716+
user_setting: "Enable search discoveries"
717717
tooltip:
718718
header: "AI powered search"
719719
content: "Natural language search powered by %{model}"
720+
actions:
721+
info: "How does it work?"
722+
disable: "Disable"
723+
724+
user_preferences:
725+
empty: "There are no relevant settings available at this time"
720726
review:
721727
types:
722728
reviewable_ai_post:

0 commit comments

Comments
 (0)