From 64f3f898a3526b276b3b06f88834f6cef3239b88 Mon Sep 17 00:00:00 2001 From: Keegan George Date: Tue, 25 Mar 2025 12:46:17 -0700 Subject: [PATCH 1/4] UX: Convert sentiment analysis overview to horizontal bars --- .../admin-report-sentiment-analysis.gjs | 101 +++++++++++++----- .../ai-sentiment-horizontal-bar.gjs | 30 ++++++ .../modules/sentiment/common/dashboard.scss | 55 +++++++++- config/locales/client.en.yml | 6 ++ 4 files changed, 164 insertions(+), 28 deletions(-) create mode 100644 assets/javascripts/discourse/components/ai-sentiment-horizontal-bar.gjs diff --git a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs index 62a18dfd3..c77afe0cc 100644 --- a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs +++ b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs @@ -1,12 +1,13 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; -import { fn, hash } from "@ember/helper"; +import { concat, fn, hash } from "@ember/helper"; import { on } from "@ember/modifier"; import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import { service } from "@ember/service"; +import { htmlSafe } from "@ember/template"; import { modifier } from "ember-modifier"; -import { and } from "truth-helpers"; +import { and, gt } from "truth-helpers"; import DButton from "discourse/components/d-button"; import HorizontalOverflowNav from "discourse/components/horizontal-overflow-nav"; import PostList from "discourse/components/post-list"; @@ -23,6 +24,7 @@ import closeOnClickOutside from "discourse/modifiers/close-on-click-outside"; import { i18n } from "discourse-i18n"; import DTooltip from "float-kit/components/d-tooltip"; import DoughnutChart from "discourse/plugins/discourse-ai/discourse/components/doughnut-chart"; +import AiSentimentHorizontalBar from "../components/ai-sentiment-horizontal-bar"; export default class AdminReportSentimentAnalysis extends Component { @service router; @@ -82,6 +84,15 @@ export default class AdminReportSentimentAnalysis extends Component { } } + get groupingType() { + const dataSample = this.args.model.data[0]; + const localePrefix = + "discourse_ai.sentiments.sentiment_analysis.group_types"; + return dataSample.category_name + ? i18n(`${localePrefix}.category`) + : i18n(`${localePrefix}.tag`); + } + get colors() { return ["#2ecc71", "#95a5a6", "#e74c3c"]; } @@ -107,7 +118,17 @@ export default class AdminReportSentimentAnalysis extends Component { this.calculateNeutralScore(data), data.negative_count, ], + score_map: { + positive: data.positive_count, + neutral: this.calculateNeutralScore(data), + negative: data.negative_count, + }, total_score: data.total_count, + widths: { + positive: (data.positive_count / data.total_count) * 100, + neutral: (this.calculateNeutralScore(data) / data.total_count) * 100, + negative: (data.negative_count / data.total_count) * 100, + }, }; }); } @@ -302,29 +323,59 @@ export default class AdminReportSentimentAnalysis extends Component { {{#unless this.showingSelectedChart}}
- {{#each this.transformedData as |data|}} -
- -
- {{/each}} + + {{log @model.data}} + + + + + + + + {{#each this.transformedData as |data|}} + + + {{log data}} + + + + + {{/each}} + +
{{this.groupingType}}{{i18n + "discourse_ai.sentiments.sentiment_analysis.table.total_count" + }}{{i18n + "discourse_ai.sentiments.sentiment_analysis.table.sentiment" + }}
{{data.title}}{{data.total_score}} + + + +
{{/unless}} diff --git a/assets/javascripts/discourse/components/ai-sentiment-horizontal-bar.gjs b/assets/javascripts/discourse/components/ai-sentiment-horizontal-bar.gjs new file mode 100644 index 000000000..ae8cd50b2 --- /dev/null +++ b/assets/javascripts/discourse/components/ai-sentiment-horizontal-bar.gjs @@ -0,0 +1,30 @@ +import { concat } from "@ember/helper"; +import { htmlSafe } from "@ember/template"; +import { gt } from "truth-helpers"; +import { i18n } from "discourse-i18n"; +import DTooltip from "float-kit/components/d-tooltip"; + +const AiSentimentHorizontalBar = ; + +export default AiSentimentHorizontalBar; diff --git a/assets/stylesheets/modules/sentiment/common/dashboard.scss b/assets/stylesheets/modules/sentiment/common/dashboard.scss index 0ae79ddeb..6d65403f6 100644 --- a/assets/stylesheets/modules/sentiment/common/dashboard.scss +++ b/assets/stylesheets/modules/sentiment/common/dashboard.scss @@ -82,9 +82,7 @@ &__chart-wrapper { height: fit-content; position: relative; - transition: - transform 0.25s ease, - box-shadow 0.25s ease; + transition: transform 0.25s ease, box-shadow 0.25s ease; border-radius: var(--d-border-radius); .doughnut-chart-title { @@ -248,3 +246,54 @@ display: none; } } + +.sentiment-analysis-table { + margin: 1rem; + + &__total-score { + font-weight: bold; + font-size: var(--font-up-1); + } + + &__row { + cursor: pointer; + } +} + +.sentiment-horizontal-bar { + display: flex; + + &__count { + font-weight: bold; + font-size: var(--font-down-1); + color: var(--secondary); + } + + &__positive, + &__neutral, + &__negative { + display: flex; + flex-flow: column nowrap; + justify-content: flex-end; + align-items: center; + padding: 0.75rem; + border-left: 2px solid var(--secondary); + border-right: 2px solid var(--secondary); + } + + &__positive { + background: rgb(var(--d-sentiment-report-positive-rgb)); + border-top-left-radius: var(--d-border-radius); + border-bottom-left-radius: var(--d-border-radius); + } + + &__negative { + background: rgb(var(--d-sentiment-report-negative-rgb)); + } + + &__neutral { + background: rgb(var(--d-sentiment-report-neutral-rgb)); + border-top-right-radius: var(--d-border-radius); + border-bottom-right-radius: var(--d-border-radius); + } +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 5f4c7295c..a7105cc9a 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -700,6 +700,12 @@ en: positive: "Positive" neutral: "Neutral" negative: "Negative" + group_types: + category: "Category" + tag: "Tag" + table: + sentiment: "Sentiment" + total_count: "Total" summarization: chat: From 157357f472d7594576540ef17b52913ac4267b80 Mon Sep 17 00:00:00 2001 From: Keegan George Date: Tue, 25 Mar 2025 12:51:05 -0700 Subject: [PATCH 2/4] FIX: linting and remove log --- .../components/admin-report-sentiment-analysis.gjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs index c77afe0cc..3e955b0d1 100644 --- a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs +++ b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs @@ -1,13 +1,12 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; -import { concat, fn, hash } from "@ember/helper"; +import { fn, hash } from "@ember/helper"; import { on } from "@ember/modifier"; import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import { service } from "@ember/service"; -import { htmlSafe } from "@ember/template"; import { modifier } from "ember-modifier"; -import { and, gt } from "truth-helpers"; +import { and } from "truth-helpers"; import DButton from "discourse/components/d-button"; import HorizontalOverflowNav from "discourse/components/horizontal-overflow-nav"; import PostList from "discourse/components/post-list"; @@ -324,7 +323,6 @@ export default class AdminReportSentimentAnalysis extends Component { {{#unless this.showingSelectedChart}}
- {{log @model.data}}
{{this.groupingType}} {{i18n From 8d90949f41744ef1f33a754892b0bb2f79bb9c4b Mon Sep 17 00:00:00 2001 From: Keegan George Date: Tue, 25 Mar 2025 12:51:51 -0700 Subject: [PATCH 3/4] FIX: trailing log --- .../discourse/components/admin-report-sentiment-analysis.gjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs index 3e955b0d1..154d07305 100644 --- a/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs +++ b/assets/javascripts/discourse/components/admin-report-sentiment-analysis.gjs @@ -347,8 +347,6 @@ export default class AdminReportSentimentAnalysis extends Component { ) }} > - - {{log data}} {{data.title}} Date: Tue, 25 Mar 2025 12:59:01 -0700 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=92=84Prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/stylesheets/modules/sentiment/common/dashboard.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/stylesheets/modules/sentiment/common/dashboard.scss b/assets/stylesheets/modules/sentiment/common/dashboard.scss index 6d65403f6..4fd9d412d 100644 --- a/assets/stylesheets/modules/sentiment/common/dashboard.scss +++ b/assets/stylesheets/modules/sentiment/common/dashboard.scss @@ -82,7 +82,9 @@ &__chart-wrapper { height: fit-content; position: relative; - transition: transform 0.25s ease, box-shadow 0.25s ease; + transition: + transform 0.25s ease, + box-shadow 0.25s ease; border-radius: var(--d-border-radius); .doughnut-chart-title {