mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-03-06 09:20:14 +00:00
Revert "DEV: Updates to sentiment analysis reports (#1161)"
This reverts commit 8863cf0c86140065978d33ee9dca421fc8670fb5. The conditionals added around the report registrations are incompatible with multisite environment and skip_db=true
This commit is contained in:
parent
e255c7a8f0
commit
86bdc7b517
@ -37,7 +37,7 @@ module DiscourseAi
|
||||
SELECT
|
||||
p.id AS post_id,
|
||||
p.topic_id,
|
||||
t.fancy_title AS topic_title,
|
||||
t.title AS topic_title,
|
||||
p.cooked as post_cooked,
|
||||
p.user_id,
|
||||
p.post_number,
|
||||
|
@ -2,10 +2,6 @@
|
||||
|
||||
class ClassificationResult < ActiveRecord::Base
|
||||
belongs_to :target, polymorphic: true
|
||||
|
||||
def self.has_sentiment_classification?
|
||||
where(classification_type: "sentiment").exists?
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
@ -3,36 +3,26 @@ import { tracked } from "@glimmer/tracking";
|
||||
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 { modifier } from "ember-modifier";
|
||||
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";
|
||||
import dIcon from "discourse/helpers/d-icon";
|
||||
import replaceEmoji from "discourse/helpers/replace-emoji";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { getAbsoluteURL } from "discourse/lib/get-url";
|
||||
import discourseLater from "discourse/lib/later";
|
||||
import { clipboardCopy } from "discourse/lib/utilities";
|
||||
import Post from "discourse/models/post";
|
||||
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";
|
||||
|
||||
export default class AdminReportSentimentAnalysis extends Component {
|
||||
@service router;
|
||||
|
||||
@tracked selectedChart = null;
|
||||
@tracked posts = [];
|
||||
@tracked posts = null;
|
||||
@tracked hasMorePosts = false;
|
||||
@tracked nextOffset = 0;
|
||||
@tracked showingSelectedChart = false;
|
||||
@tracked activeFilter = "all";
|
||||
@tracked shareIcon = "link";
|
||||
|
||||
setActiveFilter = modifier((element) => {
|
||||
this.clearActiveFilters(element);
|
||||
@ -81,6 +71,32 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
doughnutTitle(data) {
|
||||
const MAX_TITLE_LENGTH = 18;
|
||||
const title = data?.title || "";
|
||||
const score = data?.total_score ? ` (${data.total_score})` : "";
|
||||
|
||||
if (title.length + score.length > MAX_TITLE_LENGTH) {
|
||||
return (
|
||||
title.substring(0, MAX_TITLE_LENGTH - score.length) + "..." + score
|
||||
);
|
||||
}
|
||||
|
||||
return title + score;
|
||||
}
|
||||
|
||||
async postRequest() {
|
||||
return await ajax("/discourse-ai/sentiment/posts", {
|
||||
data: {
|
||||
group_by: this.currentGroupFilter,
|
||||
group_value: this.selectedChart?.title,
|
||||
start_date: this.args.model.start_date,
|
||||
end_date: this.args.model.end_date,
|
||||
offset: this.nextOffset,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
get colors() {
|
||||
return ["#2ecc71", "#95a5a6", "#e74c3c"];
|
||||
}
|
||||
@ -117,11 +133,10 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
}
|
||||
|
||||
return this.posts.filter((post) => {
|
||||
post.topic_title = replaceEmoji(post.topic_title);
|
||||
|
||||
if (this.activeFilter === "all") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return post.sentiment === this.activeFilter;
|
||||
});
|
||||
}
|
||||
@ -171,42 +186,6 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
];
|
||||
}
|
||||
|
||||
async postRequest() {
|
||||
return await ajax("/discourse-ai/sentiment/posts", {
|
||||
data: {
|
||||
group_by: this.currentGroupFilter,
|
||||
group_value: this.selectedChart?.title,
|
||||
start_date: this.args.model.start_date,
|
||||
end_date: this.args.model.end_date,
|
||||
offset: this.nextOffset,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async openToChart() {
|
||||
const queryParams = this.router.currentRoute.queryParams;
|
||||
if (queryParams.selectedChart) {
|
||||
this.selectedChart = this.transformedData.find(
|
||||
(data) => data.title === queryParams.selectedChart
|
||||
);
|
||||
|
||||
if (!this.selectedChart) {
|
||||
return;
|
||||
}
|
||||
this.showingSelectedChart = true;
|
||||
|
||||
try {
|
||||
const response = await this.postRequest();
|
||||
this.posts = response.posts.map((post) => Post.create(post));
|
||||
this.hasMorePosts = response.has_more;
|
||||
this.nextOffset = response.next_offset;
|
||||
} catch (e) {
|
||||
popupAjaxError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
async showDetails(data) {
|
||||
if (this.selectedChart === data) {
|
||||
@ -214,14 +193,6 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentQueryParams = this.router.currentRoute.queryParams;
|
||||
this.router.transitionTo(this.router.currentRoute.name, {
|
||||
queryParams: {
|
||||
...currentQueryParams,
|
||||
selectedChart: data.title,
|
||||
},
|
||||
});
|
||||
|
||||
this.selectedChart = data;
|
||||
this.showingSelectedChart = true;
|
||||
|
||||
@ -246,10 +217,7 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
|
||||
this.hasMorePosts = response.has_more;
|
||||
this.nextOffset = response.next_offset;
|
||||
|
||||
const mappedPosts = response.posts.map((post) => Post.create(post));
|
||||
this.posts.pushObjects(mappedPosts);
|
||||
return mappedPosts;
|
||||
return response.posts.map((post) => Post.create(post));
|
||||
} catch (e) {
|
||||
popupAjaxError(e);
|
||||
}
|
||||
@ -260,35 +228,9 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
this.showingSelectedChart = false;
|
||||
this.selectedChart = null;
|
||||
this.activeFilter = "all";
|
||||
this.posts = [];
|
||||
|
||||
const currentQueryParams = this.router.currentRoute.queryParams;
|
||||
this.router.transitionTo(this.router.currentRoute.name, {
|
||||
queryParams: {
|
||||
...currentQueryParams,
|
||||
selectedChart: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
shareChart() {
|
||||
const url = this.router.currentURL;
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
clipboardCopy(getAbsoluteURL(url));
|
||||
this.shareIcon = "check";
|
||||
|
||||
discourseLater(() => {
|
||||
this.shareIcon = "link";
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
<template>
|
||||
<span {{didInsert this.openToChart}}></span>
|
||||
|
||||
{{#unless this.showingSelectedChart}}
|
||||
<div class="admin-report-sentiment-analysis">
|
||||
{{#each this.transformedData as |data|}}
|
||||
@ -310,7 +252,6 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
@data={{data.scores}}
|
||||
@totalScore={{data.total_score}}
|
||||
@doughnutTitle={{data.title}}
|
||||
@displayLegend={{true}}
|
||||
/>
|
||||
</div>
|
||||
{{/each}}
|
||||
@ -319,23 +260,12 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
|
||||
{{#if (and this.selectedChart this.showingSelectedChart)}}
|
||||
<div class="admin-report-sentiment-analysis__selected-chart">
|
||||
<div class="admin-report-sentiment-analysis__selected-chart-actions">
|
||||
<DButton
|
||||
@label="back_button"
|
||||
@icon="chevron-left"
|
||||
class="btn-flat"
|
||||
@action={{this.backToAllCharts}}
|
||||
/>
|
||||
|
||||
<DTooltip
|
||||
class="share btn-flat"
|
||||
@icon={{this.shareIcon}}
|
||||
{{on "click" this.shareChart}}
|
||||
@content={{i18n
|
||||
"discourse_ai.sentiments.sentiment_analysis.share_chart"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<DButton
|
||||
@label="back_button"
|
||||
@icon="chevron-left"
|
||||
class="btn-flat"
|
||||
@action={{this.backToAllCharts}}
|
||||
/>
|
||||
|
||||
<DoughnutChart
|
||||
@labels={{@model.labels}}
|
||||
@ -343,9 +273,7 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
@data={{this.selectedChart.scores}}
|
||||
@totalScore={{this.selectedChart.total_score}}
|
||||
@doughnutTitle={{this.selectedChart.title}}
|
||||
@displayLegend={{true}}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="admin-report-sentiment-analysis-details">
|
||||
<HorizontalOverflowNav
|
||||
|
@ -1,10 +1,7 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import Chart from "admin/components/chart";
|
||||
|
||||
export default class DoughnutChart extends Component {
|
||||
@tracked canvasSize = null;
|
||||
|
||||
get config() {
|
||||
const totalScore = this.args.totalScore || "";
|
||||
|
||||
@ -16,18 +13,14 @@ export default class DoughnutChart extends Component {
|
||||
{
|
||||
data: this.args.data,
|
||||
backgroundColor: this.args.colors,
|
||||
cutout: "50%",
|
||||
radius: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: this.args.displayLegend || false,
|
||||
position: "bottom",
|
||||
position: this.args.legendPosition || "bottom",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -22,13 +22,6 @@ export default {
|
||||
"sentiment_analysis",
|
||||
AdminReportSentimentAnalysis
|
||||
);
|
||||
|
||||
api.registerValueTransformer(
|
||||
"admin-reports-show-query-params",
|
||||
({ value }) => {
|
||||
return [...value, "selectedChart"];
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -1,27 +1,21 @@
|
||||
import { apiInitializer } from "discourse/lib/api";
|
||||
|
||||
export default apiInitializer("1.15.0", (api) => {
|
||||
const currentUser = api.getCurrentUser();
|
||||
const settings = api.container.lookup("service:site-settings");
|
||||
|
||||
if (
|
||||
!currentUser ||
|
||||
!currentUser.admin ||
|
||||
!currentUser.can_see_sentiment_reports
|
||||
) {
|
||||
return;
|
||||
if (settings.ai_sentiment_enabled) {
|
||||
api.addAdminSidebarSectionLink("reports", {
|
||||
name: "sentiment_overview",
|
||||
route: "admin.dashboardSentiment",
|
||||
label: "discourse_ai.sentiments.sidebar.overview",
|
||||
icon: "chart-column",
|
||||
});
|
||||
api.addAdminSidebarSectionLink("reports", {
|
||||
name: "sentiment_analysis",
|
||||
route: "adminReports.show",
|
||||
routeModels: ["sentiment_analysis"],
|
||||
label: "discourse_ai.sentiments.sidebar.analysis",
|
||||
icon: "chart-pie",
|
||||
});
|
||||
}
|
||||
|
||||
api.addAdminSidebarSectionLink("reports", {
|
||||
name: "sentiment_overview",
|
||||
route: "admin.dashboardSentiment",
|
||||
label: "discourse_ai.sentiments.sidebar.overview",
|
||||
icon: "chart-column",
|
||||
});
|
||||
api.addAdminSidebarSectionLink("reports", {
|
||||
name: "sentiment_analysis",
|
||||
route: "adminReports.show",
|
||||
routeModels: ["sentiment_analysis"],
|
||||
label: "discourse_ai.sentiments.sidebar.analysis",
|
||||
icon: "chart-pie",
|
||||
});
|
||||
});
|
||||
|
@ -39,12 +39,13 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
// Hides tag selector when showing subcategories selector
|
||||
.control:nth-of-type(6):nth-last-of-type(3) {
|
||||
display: none;
|
||||
.control:nth-of-type(n + 6) {
|
||||
flex-basis: 49%;
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.control:has(.export-csv-btn) {
|
||||
// Hides tag selector when showing subcategories selector
|
||||
.control:nth-of-type(6):nth-last-of-type(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@ -54,6 +55,7 @@
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
order: 2;
|
||||
gap: 1rem;
|
||||
align-items: flex-start;
|
||||
max-height: 100vh;
|
||||
}
|
||||
@ -63,31 +65,30 @@
|
||||
@include report-container-box();
|
||||
flex: 2;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-flow: row wrap;
|
||||
gap: 3rem;
|
||||
|
||||
.admin-report-doughnut {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
&__chart-wrapper {
|
||||
height: fit-content;
|
||||
position: relative;
|
||||
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
||||
border-radius: var(--d-border-radius);
|
||||
|
||||
width: auto;
|
||||
.doughnut-chart-title {
|
||||
@include ellipsis;
|
||||
margin: 0 auto;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
max-width: 300px;
|
||||
}
|
||||
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
||||
border-radius: var(--d-border-radius);
|
||||
|
||||
&:hover {
|
||||
box-shadow: var(--shadow-card);
|
||||
transform: translateY(-1rem);
|
||||
box-shadow: var(--shadow-card);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@ -101,23 +102,11 @@
|
||||
font-size: var(--font-up-2);
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 0.3rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__selected-chart-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 0.35rem;
|
||||
border-bottom: 1px solid var(--primary-low);
|
||||
|
||||
.share {
|
||||
margin-left: auto;
|
||||
|
||||
.d-icon-check {
|
||||
color: var(--success);
|
||||
}
|
||||
padding-bottom: 1rem;
|
||||
border-top: 1px solid var(--primary-low);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,12 +121,11 @@
|
||||
@include report-container-box();
|
||||
flex: 1 1 300px;
|
||||
min-width: 300px;
|
||||
margin-left: 1rem;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
padding-top: 0;
|
||||
|
||||
&__filters {
|
||||
border-bottom: 1px solid var(--primary-low);
|
||||
@ -212,13 +200,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-reports.admin-contents .sentiment-analysis {
|
||||
.horizontal-overflow-nav {
|
||||
background: var(--secondary);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding-top: 1rem;
|
||||
z-index: z("header");
|
||||
}
|
||||
}
|
||||
|
@ -678,7 +678,6 @@ en:
|
||||
overview: "Sentiment overview"
|
||||
analysis: "Sentiment analysis"
|
||||
sentiment_analysis:
|
||||
share_chart: "Copy link to chart"
|
||||
filter_types:
|
||||
all: "All"
|
||||
positive: "Positive"
|
||||
|
@ -14,17 +14,10 @@ module DiscourseAi
|
||||
plugin.on(:post_created, &sentiment_analysis_cb)
|
||||
plugin.on(:post_edited, &sentiment_analysis_cb)
|
||||
|
||||
plugin.add_to_serializer(:current_user, :can_see_sentiment_reports) do
|
||||
ClassificationResult.has_sentiment_classification? && SiteSetting.ai_sentiment_enabled
|
||||
end
|
||||
|
||||
if Rails.env.test? ||
|
||||
ClassificationResult.has_sentiment_classification? && SiteSetting.ai_sentiment_enabled
|
||||
EmotionFilterOrder.register!(plugin)
|
||||
EmotionDashboardReport.register!(plugin)
|
||||
SentimentDashboardReport.register!(plugin)
|
||||
SentimentAnalysisReport.register!(plugin)
|
||||
end
|
||||
EmotionFilterOrder.register!(plugin)
|
||||
EmotionDashboardReport.register!(plugin)
|
||||
SentimentDashboardReport.register!(plugin)
|
||||
SentimentAnalysisReport.register!(plugin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user