diff --git a/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 index 12ac1798dc5..911d858ba9c 100644 --- a/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 +++ b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 @@ -101,7 +101,6 @@ export default Component.extend({ moment(tooltipItem[0].xLabel, "YYYY-MM-DD").format("LL") } }, - legend: { display: false }, layout: { padding: { left: 0, diff --git a/app/models/report.rb b/app/models/report.rb index 7eac9ffd2fc..de17d8346f3 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -380,3 +380,4 @@ require_relative "reports/time_to_first_response" require_relative "reports/topics_with_no_response" require_relative "reports/emails" require_relative "reports/web_crawlers" +require_relative "reports/trust_level_growth" diff --git a/app/models/reports/trust_level_growth.rb b/app/models/reports/trust_level_growth.rb new file mode 100644 index 00000000000..091d37f3306 --- /dev/null +++ b/app/models/reports/trust_level_growth.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +Report.add_report("trust_level_growth") do |report| + report.modes = [:stacked_chart] + + filters = %w[ + tl1_reached + tl2_reached + tl3_reached + tl4_reached + ] + + sql = <<~SQL + SELECT + date(created_at), + ( + count(*) filter (WHERE previous_value::integer < 1 AND new_value = '1') + ) as tl1_reached, + ( + count(*) filter (WHERE previous_value::integer < 2 AND new_value = '2') + ) as tl2_reached, + ( + count(*) filter (WHERE previous_value::integer < 3 AND new_value = '3') + ) as tl3_reached, + ( + count(*) filter (WHERE previous_value::integer < 4 AND new_value = '4') + ) as tl4_reached + FROM user_histories + WHERE ( + created_at >= '#{report.start_date}' + AND created_at <= '#{report.end_date}' + ) + AND ( + action = #{UserHistory.actions[:change_trust_level]} + OR action = #{UserHistory.actions[:auto_trust_level_change]} + ) + GROUP BY date(created_at) + LIMIT #{report.limit || 250} + SQL + + data = Hash[ filters.collect { |x| [x, []] } ] + + builder = DB.build(sql) + builder.query.each do |row| + filters.each do |filter| + data[filter] << { + x: row.date.strftime("%Y-%m-%d"), + y: row.instance_variable_get("@#{filter}") + } + end + end + + tertiary = ColorScheme.hex_for_name('tertiary') || '0088cc' + quaternary = ColorScheme.hex_for_name('quaternary') || 'e45735' + + requests = filters.map do |filter| + color = report.rgba_color(quaternary) + + if filter == "tl1_reached" + color = report.lighten_color(tertiary, 0.25) + end + if filter == "tl2_reached" + color = report.rgba_color(tertiary) + end + if filter == "tl3_reached" + color = report.lighten_color(quaternary, 0.25) + end + + { + req: filter, + label: I18n.t("reports.trust_level_growth.xaxis.#{filter}"), + color: color, + data: data[filter] + } + end + + report.data = requests +end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 3a35fd6933e..ff8c37b8624 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1105,6 +1105,15 @@ en: xaxis: "Day" yaxis: "Number of new contributors" description: "Number of users who made their first post during this period." + trust_level_growth: + title: "Trust Level growth" + xaxis: + tl1_reached: "Reached TL1" + tl2_reached: "Reached TL2" + tl3_reached: "Reached TL3" + tl4_reached: "Reached TL4" + yaxis: "Day" + description: "Number of users who increased their Trust Level during this period." consolidated_page_views: title: "Consolidated Pageviews" xaxis: diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index fb92e584a95..12924fd82e1 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -1193,4 +1193,43 @@ describe Report do end end end + + describe "trust_level_growth" do + before do + freeze_time(Time.now.at_midnight) + Theme.clear_default! + end + + let(:reports) { Report.find('trust_level_growth') } + + context "with no data" do + it "works" do + reports.data.each do |report| + expect(report[:data]).to be_empty + end + end + end + + context "with data" do + fab!(:gwen) { Fabricate(:user) } + fab!(:martin) { Fabricate(:user) } + + before do + UserHistory.create(action: UserHistory.actions[:auto_trust_level_change], target_user_id: gwen.id, new_value: TrustLevel[2], previous_value: 1) + UserHistory.create(action: UserHistory.actions[:change_trust_level], target_user_id: martin.id, new_value: TrustLevel[4], previous_value: 0) + end + + it "works" do + tl1_reached = reports.data.find { |r| r[:req] == "tl1_reached" } + tl2_reached = reports.data.find { |r| r[:req] == "tl2_reached" } + tl3_reached = reports.data.find { |r| r[:req] == "tl3_reached" } + tl4_reached = reports.data.find { |r| r[:req] == "tl4_reached" } + + expect(tl1_reached[:data][0][:y]).to eql(0) + expect(tl2_reached[:data][0][:y]).to eql(1) + expect(tl3_reached[:data][0][:y]).to eql(0) + expect(tl4_reached[:data][0][:y]).to eql(1) + end + end + end end