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
35 changes: 35 additions & 0 deletions assets/javascripts/discourse/components/admin-report-emotion.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div class="cell title">
{{#if this.model.icon}}
{{d-icon this.model.icon}}
{{/if}}
<a href="{{this.filterURL}}{{this.model.type}}">{{this.model.title}}</a>
</div>

<div class="cell value today-count">{{number this.model.todayCount}}</div>

<div
class="cell value yesterday-count {{this.model.yesterdayTrend}}"
title={{this.model.yesterdayCountTitle}}
>
{{number this.model.yesterdayCount}}
{{d-icon this.model.yesterdayTrendIcon}}
</div>

<div
class="cell value sevendays-count {{this.model.sevenDaysTrend}}"
title={{this.model.sevenDaysCountTitle}}
>
{{number this.model.lastSevenDaysCount}}
{{d-icon this.model.sevenDaysTrendIcon}}
</div>

<div
class="cell value thirty-days-count {{this.model.thirtyDaysTrend}}"
title={{this.model.thirtyDaysCountTitle}}
>
{{number this.model.lastThirtyDaysCount}}

{{#if this.model.canDisplayTrendIcon}}
{{d-icon this.model.thirtyDaysTrendIcon}}
{{/if}}
</div>
12 changes: 12 additions & 0 deletions assets/javascripts/discourse/components/admin-report-emotion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Component from "@ember/component";
import { attributeBindings, classNames } from "@ember-decorators/component";
import getURL from "discourse-common/lib/get-url";

@classNames("admin-report-counters")
@attributeBindings("model.description:title")
export default class AdminReportEmotion extends Component {
get filterURL() {
let aMonthAgo = moment().subtract(1, "month").format("YYYY-MM-DD");
return getURL(`/filter?q=activity-after%3A${aMonthAgo}%20order%3A`);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
import { computed } from "@ember/object";
import AdminDashboardTabController from "admin/controllers/admin-dashboard-tab";

export default class AdminDashboardSentiment extends AdminDashboardTabController {
@computed("startDate", "endDate")
get filters() {
return { startDate: this.startDate, endDate: this.endDate };
get emotions() {
const emotions = [
"admiration",
"amusement",
"anger",
"annoyance",
"approval",
"caring",
"confusion",
"curiosity",
"desire",
"disappointment",
"disapproval",
"disgust",
"embarrassment",
"excitement",
"fear",
"gratitude",
"grief",
"joy",
"love",
"nervousness",
"neutral",
"optimism",
"pride",
"realization",
"relief",
"remorse",
"sadness",
"surprise",
];
return emotions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,43 @@
@filters={{this.filters}}
@showHeader={{true}}
/>

<AdminReport
@dataSourceName="post_emotion"
@filters={{this.filters}}
@showHeader={{true}}
/>
<div class="admin-report activity-metrics">
<div class="header">
<ul class="breadcrumb">
<li class="item report">
<LinkTo @route="adminReports" class="report-url">
{{i18n "admin.dashboard.emotion"}}
</LinkTo>
</li>
</ul>
</div>
<div class="report-body">
<div class="counters-list">
<div class="counters-header">
<div class="counters-cell"></div>
<div class="counters-cell">{{i18n
"admin.dashboard.reports.today"
}}</div>
<div class="counters-cell">{{i18n
"admin.dashboard.reports.yesterday"
}}</div>
<div class="counters-cell">{{i18n
"admin.dashboard.reports.last_7_days"
}}</div>
<div class="counters-cell">{{i18n
"admin.dashboard.reports.last_30_days"
}}</div>
</div>
{{#each this.emotions as |metric|}}
<AdminReport
@showHeader={{false}}
@forcedModes="emotion"
@dataSourceName="emotion_{{metric}}"
/>
{{/each}}
</div>
</div>
</div>
</div>
</div>
</div>
3 changes: 3 additions & 0 deletions assets/stylesheets/modules/sentiment/common/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
grid-template-columns: repeat(12, 1fr);
grid-column-gap: 1em;
grid-row-gap: 1em;
.admin-report {
grid-column: span 12;
}
}
}
8 changes: 0 additions & 8 deletions assets/stylesheets/modules/sentiment/desktop/dashboard.scss

This file was deleted.

10 changes: 0 additions & 10 deletions assets/stylesheets/modules/sentiment/mobile/dashboard.scss

This file was deleted.

2 changes: 2 additions & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ en:
site_settings:
categories:
discourse_ai: "Discourse AI"
dashboard:
emotion: "Emotion"
js:
discourse_automation:
scriptables:
Expand Down
67 changes: 59 additions & 8 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ en:
ai_embeddings_semantic_related_include_closed_topics: "Include closed topics in semantic search results"
ai_embeddings_semantic_search_hyde_model: "Model used to expand keywords to get better results during a semantic search"
ai_embeddings_per_post_enabled: Generate embeddings for each post

ai_summarization_enabled: "Enable the topic summarization module."
ai_summarization_model: "Model to use for summarization."
ai_custom_summarization_allowed_groups: "Groups allowed to use create new summaries."
ai_pm_summarization_allowed_groups: "Groups allowed to create and view summaries in PMs."
ai_summarize_max_hot_topics_gists_per_batch: "After updating topics in the hot list, we'll generate brief summaries of the first N ones. (Disabled when 0)"
ai_hot_topic_gists_allowed_groups: "Groups allowed to see gists in the hot topics list."
ai_hot_topic_gists_allowed_groups: "Groups allowed to see gists in the hot topics list."
ai_summary_backfill_maximum_topics_per_hour: "Number of topic summaries to backfill per hour."

ai_bot_enabled: "Enable the AI Bot module."
Expand All @@ -111,14 +111,65 @@ en:
reports:
overall_sentiment:
title: "Overall sentiment"
description: "The chart compares the number of posts classified as either positive or negative. These are calculated when positive or negative scores > the set threshold score. This means neutral posts are not shown. Private messages (PMs) are also excluded. Classified with \"cardiffnlp/twitter-roberta-base-sentiment-latest\""
description: 'The chart compares the number of posts classified as either positive or negative. These are calculated when positive or negative scores > the set threshold score. This means neutral posts are not shown. Private messages (PMs) are also excluded. Classified with "cardiffnlp/twitter-roberta-base-sentiment-latest"'
xaxis: "Positive(%)"
yaxis: "Date"
post_emotion:
title: "Post emotion"
description: "Number of posts classified with one of the following emotions, grouped by poster's trust level. Posts that are not positive or negative and considered neutral, are not shown. Private messages (PMs) are also excluded. Classified with \"j-hartmann/emotion-english-roberta-large\""
xaxis:
yaxis:
emotion_admiration:
title: Admiration
emotion_amusement:
title: Amusement
emotion_anger:
title: Anger
emotion_annoyance:
title: Annoyance
emotion_approval:
title: Approval
emotion_caring:
title: Caring
emotion_confusion:
title: Confusion
emotion_curiosity:
title: Curiosity
emotion_desire:
title: Desire
emotion_disappointment:
title: Disappointment
emotion_disapproval:
title: Disapproval
emotion_disgust:
title: Disgust
emotion_embarrassment:
title: Embarrassment
emotion_excitement:
title: Excitement
emotion_fear:
title: Fear
emotion_gratitude:
title: Gratitude
emotion_grief:
title: Grief
emotion_joy:
title: Joy
emotion_love:
title: Love
emotion_nervousness:
title: Nervousness
emotion_neutral:
title: Neutral
emotion_optimism:
title: Optimism
emotion_pride:
title: Pride
emotion_realization:
title: Realization
emotion_relief:
title: Relief
emotion_remorse:
title: Remorse
emotion_sadness:
title: Sadness
emotion_surprise:
title: Surprise

discourse_ai:
unknown_model: "Unknown AI model"
Expand Down
47 changes: 47 additions & 0 deletions lib/sentiment/emotion_dashboard_report.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module DiscourseAi
module Sentiment
class EmotionDashboardReport
def self.register!(plugin)
Emotions::LIST.each do |emotion|
plugin.add_report("emotion_#{emotion}") do |report|
query_results = DiscourseAi::Sentiment::EmotionDashboardReport.fetch_data
report.data = query_results.pop(30).map { |row| { x: row.day, y: row.send(emotion) } }
report.prev30Days =
query_results.take(30).map { |row| { x: row.day, y: row.send(emotion) } }
end
end

def self.fetch_data
DB.query(<<~SQL, end: Time.now.tomorrow.midnight, start: 60.days.ago.midnight)
SELECT
posts.created_at::DATE AS day,
#{
DiscourseAi::Sentiment::Emotions::LIST
.map do |emotion|
"COUNT(*) FILTER (WHERE (classification_results.classification::jsonb->'#{emotion}')::float > 0.1) AS #{emotion}"
end
.join(",\n ")
}
FROM
classification_results
INNER JOIN
posts ON posts.id = classification_results.target_id AND
posts.deleted_at IS NULL AND
posts.created_at BETWEEN :start AND :end
INNER JOIN
topics ON topics.id = posts.topic_id AND
topics.archetype = 'regular' AND
topics.deleted_at IS NULL
WHERE
classification_results.target_type = 'Post' AND
classification_results.model_used = 'SamLowe/roberta-base-go_emotions'
GROUP BY 1
ORDER BY 1 ASC
SQL
end
end
end
end
end
33 changes: 1 addition & 32 deletions lib/sentiment/emotion_filter_order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,7 @@ module DiscourseAi
module Sentiment
class EmotionFilterOrder
def self.register!(plugin)
emotions = %w[
admiration
amusement
anger
annoyance
approval
caring
confusion
curiosity
desire
disappointment
disapproval
disgust
embarrassment
excitement
fear
gratitude
grief
joy
love
nervousness
neutral
optimism
pride
realization
relief
remorse
sadness
surprise
]

emotions.each do |emotion|
Emotions::LIST.each do |emotion|
filter_order_emotion = ->(scope, order_direction) do
emotion_clause = <<~SQL
SUM(
Expand Down
38 changes: 38 additions & 0 deletions lib/sentiment/emotions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

module DiscourseAi
module Sentiment
class Emotions
LIST = %w[
admiration
amusement
anger
annoyance
approval
caring
confusion
curiosity
desire
disappointment
disapproval
disgust
embarrassment
excitement
fear
gratitude
grief
joy
love
nervousness
neutral
optimism
pride
realization
relief
remorse
sadness
surprise
]
end
end
end
Loading