From b13ea401d2ec5d4945a640c07c241b9363a9c80c Mon Sep 17 00:00:00 2001 From: Katya Sarmiento <5871075+Kitkatnik@users.noreply.github.com> Date: Fri, 1 May 2026 12:19:24 -0400 Subject: [PATCH] =?UTF-8?q?Annual=20Report:=20polish=20=E2=80=94=20chart?= =?UTF-8?q?=20alignment,=20sort,=20version=20grouping,=20freshness,=20nav?= =?UTF-8?q?=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bar charts (§3 Proficiency, §1 First Ruby) now share fixed column widths so they line up regardless of label or value text. - §2 Sentiment and §3 Persona render highest→lowest by percentage. - Sentimental Ruby versions normalize to MAJOR.MINOR before tallying so 3.4 / 3.4.0 / 3.4.6 / 3.4.9 group together. - Submitting an application busts the /report cache via after_update_commit, so totals reflect new submissions immediately instead of waiting up to an hour. - Adds "Annual Report" link back to the top navbar (logged-in and logged-out, desktop and mobile). --- app/assets/stylesheets/application.css | 3 ++- app/models/embassy_application.rb | 5 +++++ app/services/annual_report.rb | 7 ++++--- app/views/report/index.html.erb | 4 ++-- app/views/shared/_navbar.html.erb | 4 ++++ 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index ef8af6a..ae6c6e3 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -3589,7 +3589,7 @@ hr { .report-bar-row { display: grid; - grid-template-columns: minmax(8rem, 1fr) 2fr auto; + grid-template-columns: 11rem 1fr 5.5rem; gap: 1rem; align-items: center; } @@ -3624,6 +3624,7 @@ hr { color: #0C2866; font-size: 0.9375rem; white-space: nowrap; + text-align: right; } .report-bar-row__count { diff --git a/app/models/embassy_application.rb b/app/models/embassy_application.rb index 951c40b..ddc3869 100644 --- a/app/models/embassy_application.rb +++ b/app/models/embassy_application.rb @@ -11,6 +11,7 @@ class EmbassyApplication < ApplicationRecord validate :required_questions_answered, on: :submit before_validation :assign_serial, on: :create + after_update_commit :bust_annual_report_cache, if: :saved_change_to_state? def to_param = serial @@ -38,6 +39,10 @@ def assign_serial self.serial ||= EmbassyApplicationSerialGenerator.next end + def bust_annual_report_cache + Rails.cache.delete("annual_report:v1") if submitted? + end + def required_questions_answered answers_by_qid = embassy_application_answers.includes(:question).index_by(&:question_id) diff --git a/app/services/annual_report.rb b/app/services/annual_report.rb index 4fe5ccf..e2a108b 100644 --- a/app/services/annual_report.rb +++ b/app/services/annual_report.rb @@ -101,9 +101,10 @@ def self.other_language_stat(question) def self.sentimental_version_stat(question) raw = submitted_answers_for(question).pluck(:value_text).compact.reject(&:blank?) cleaned = raw.reject { |v| REFUSAL_PHRASES.any? { |p| v.downcase.include?(p) } } - versions = cleaned.filter_map { |v| v[/\d+(?:\.\d+){0,2}/] } - counts = versions.tally.sort_by { |_, c| -c }.first(5).to_h - parseable = versions.filter_map { |v| Gem::Version.new(v) rescue nil }.sort + raw_versions = cleaned.filter_map { |v| v[/\d+(?:\.\d+){0,2}/] } + normalized = raw_versions.map { |v| v.split(".").first(2).join(".") } + counts = normalized.tally.sort_by { |_, c| -c }.first(5).to_h + parseable = raw_versions.filter_map { |v| Gem::Version.new(v) rescue nil }.sort Stat.new( question: question, total_respondents: raw.count, diff --git a/app/views/report/index.html.erb b/app/views/report/index.html.erb index 1dfc63f..cdb9b5a 100644 --- a/app/views/report/index.html.erb +++ b/app/views/report/index.html.erb @@ -168,7 +168,7 @@
<%= s.total_respondents %> diplomats declared one or more sentiments. Percentages reflect share of diplomats who selected each.
<%= s.total_respondents %> diplomats claimed one or more identities.