mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 16:56:23 +08:00

This commit converts the `AdminReport` component, which is quite high complexity, to gjs. After this initial round, ideally this component would be broken up into smaller components because it is getting quite big now. Also in this commit: * Add an option to display the report description in a tooltip, which was the main way the description was shown until recently. We want to use this on the dashboard view mostly. * Move admin report "mode" definitions to the server-side Report model, inside a `Report::MODES` constant, collecting the modes defined in various places in the UI into one place * Refactor report code to refer to mode definitions * Add a `REPORT_MODES` constant in JS via javascript.rake and refactor JS to refer to the modes * Delete old admin report components that are no longer used (trust-level-counts, counts, per-day-counts) which were replaced by admin-report-counters a while ago * Add a new `registerReportModeComponent` plugin API, some plugins introduce their own modes (like AI's `emotion`) and components and we need a way to render them
190 lines
5.3 KiB
Ruby
190 lines
5.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Reports::FlagsStatus
|
|
extend ActiveSupport::Concern
|
|
|
|
class_methods do
|
|
def report_flags_status(report)
|
|
report.modes = [Report::MODES[:table]]
|
|
|
|
report.labels = [
|
|
{
|
|
type: :post,
|
|
properties: {
|
|
topic_id: :topic_id,
|
|
number: :post_number,
|
|
truncated_raw: :post_type,
|
|
},
|
|
title: I18n.t("reports.flags_status.labels.flag"),
|
|
},
|
|
{
|
|
type: :user,
|
|
properties: {
|
|
username: :staff_username,
|
|
id: :staff_id,
|
|
avatar: :staff_avatar_template,
|
|
},
|
|
title: I18n.t("reports.flags_status.labels.assigned"),
|
|
},
|
|
{
|
|
type: :user,
|
|
properties: {
|
|
username: :poster_username,
|
|
id: :poster_id,
|
|
avatar: :poster_avatar_template,
|
|
},
|
|
title: I18n.t("reports.flags_status.labels.poster"),
|
|
},
|
|
{
|
|
type: :user,
|
|
properties: {
|
|
username: :flagger_username,
|
|
id: :flagger_id,
|
|
avatar: :flagger_avatar_template,
|
|
},
|
|
title: I18n.t("reports.flags_status.labels.flagger"),
|
|
},
|
|
{
|
|
type: :seconds,
|
|
property: :response_time,
|
|
title: I18n.t("reports.flags_status.labels.time_to_resolution"),
|
|
},
|
|
]
|
|
|
|
report.data = []
|
|
|
|
flag_types = PostActionType.flag_types
|
|
|
|
sql = <<~SQL
|
|
WITH period_actions AS (
|
|
SELECT id,
|
|
post_action_type_id,
|
|
created_at,
|
|
agreed_at,
|
|
disagreed_at,
|
|
deferred_at,
|
|
agreed_by_id,
|
|
disagreed_by_id,
|
|
deferred_by_id,
|
|
post_id,
|
|
user_id,
|
|
COALESCE(disagreed_at, agreed_at, deferred_at) AS responded_at
|
|
FROM post_actions
|
|
WHERE post_action_type_id IN (#{flag_types.values.join(",")})
|
|
AND created_at >= '#{report.start_date}'
|
|
AND created_at <= '#{report.end_date}'
|
|
ORDER BY created_at DESC
|
|
),
|
|
poster_data AS (
|
|
SELECT pa.id,
|
|
p.user_id AS poster_id,
|
|
p.topic_id as topic_id,
|
|
p.post_number as post_number,
|
|
u.username_lower AS poster_username,
|
|
u.uploaded_avatar_id AS poster_avatar_id
|
|
FROM period_actions pa
|
|
JOIN posts p
|
|
ON p.id = pa.post_id
|
|
JOIN users u
|
|
ON u.id = p.user_id
|
|
),
|
|
flagger_data AS (
|
|
SELECT pa.id,
|
|
u.id AS flagger_id,
|
|
u.username_lower AS flagger_username,
|
|
u.uploaded_avatar_id AS flagger_avatar_id
|
|
FROM period_actions pa
|
|
JOIN users u
|
|
ON u.id = pa.user_id
|
|
),
|
|
staff_data AS (
|
|
SELECT pa.id,
|
|
u.id AS staff_id,
|
|
u.username_lower AS staff_username,
|
|
u.uploaded_avatar_id AS staff_avatar_id
|
|
FROM period_actions pa
|
|
JOIN users u
|
|
ON u.id = COALESCE(pa.agreed_by_id, pa.disagreed_by_id, pa.deferred_by_id)
|
|
)
|
|
SELECT
|
|
sd.staff_username,
|
|
sd.staff_id,
|
|
sd.staff_avatar_id,
|
|
pd.poster_username,
|
|
pd.poster_id,
|
|
pd.poster_avatar_id,
|
|
pd.post_number,
|
|
pd.topic_id,
|
|
fd.flagger_username,
|
|
fd.flagger_id,
|
|
fd.flagger_avatar_id,
|
|
pa.post_action_type_id,
|
|
pa.created_at,
|
|
pa.agreed_at,
|
|
pa.disagreed_at,
|
|
pa.deferred_at,
|
|
pa.agreed_by_id,
|
|
pa.disagreed_by_id,
|
|
pa.deferred_by_id,
|
|
COALESCE(pa.disagreed_at, pa.agreed_at, pa.deferred_at) AS responded_at
|
|
FROM period_actions pa
|
|
FULL OUTER JOIN staff_data sd
|
|
ON sd.id = pa.id
|
|
FULL OUTER JOIN flagger_data fd
|
|
ON fd.id = pa.id
|
|
FULL OUTER JOIN poster_data pd
|
|
ON pd.id = pa.id
|
|
SQL
|
|
|
|
DB
|
|
.query(sql)
|
|
.each do |row|
|
|
data = {}
|
|
|
|
data[:post_type] = flag_types.key(row.post_action_type_id).to_s
|
|
data[:post_number] = row.post_number
|
|
data[:topic_id] = row.topic_id
|
|
|
|
if row.staff_id
|
|
data[:staff_username] = row.staff_username
|
|
data[:staff_id] = row.staff_id
|
|
data[:staff_avatar_template] = User.avatar_template(
|
|
row.staff_username,
|
|
row.staff_avatar_id,
|
|
)
|
|
end
|
|
|
|
if row.poster_id
|
|
data[:poster_username] = row.poster_username
|
|
data[:poster_id] = row.poster_id
|
|
data[:poster_avatar_template] = User.avatar_template(
|
|
row.poster_username,
|
|
row.poster_avatar_id,
|
|
)
|
|
end
|
|
|
|
if row.flagger_id
|
|
data[:flagger_id] = row.flagger_id
|
|
data[:flagger_username] = row.flagger_username
|
|
data[:flagger_avatar_template] = User.avatar_template(
|
|
row.flagger_username,
|
|
row.flagger_avatar_id,
|
|
)
|
|
end
|
|
|
|
if row.agreed_by_id
|
|
data[:resolution] = I18n.t("reports.flags_status.values.agreed")
|
|
elsif row.disagreed_by_id
|
|
data[:resolution] = I18n.t("reports.flags_status.values.disagreed")
|
|
elsif row.deferred_by_id
|
|
data[:resolution] = I18n.t("reports.flags_status.values.deferred")
|
|
else
|
|
data[:resolution] = I18n.t("reports.flags_status.values.no_action")
|
|
end
|
|
data[:response_time] = row.responded_at ? row.responded_at - row.created_at : nil
|
|
report.data << data
|
|
end
|
|
end
|
|
end
|
|
end
|