]> git.openstreetmap.org Git - rails.git/commitdiff
Add links to days in user history from heatmap
authorAnton Khorev <tony29@yandex.ru>
Sat, 15 Mar 2025 22:34:36 +0000 (01:34 +0300)
committerAnton Khorev <tony29@yandex.ru>
Sat, 15 Mar 2025 23:22:51 +0000 (02:22 +0300)
app/assets/javascripts/heatmap.js
app/controllers/users_controller.rb
app/views/users/show.html.erb
test/controllers/users_controller_test.rb

index 058f71cfe4b88c05e8f23c27af657ce9ec550b90..b96a47a2208ac3e0797b31bc863f33782358bb32 100644 (file)
@@ -12,6 +12,7 @@ document.addEventListener("DOMContentLoaded", () => {
   }
 
   const heatmapData = heatmapElement.dataset.heatmap ? JSON.parse(heatmapElement.dataset.heatmap) : [];
+  const displayName = heatmapElement.dataset.displayName;
   const colorScheme = document.documentElement.getAttribute("data-bs-theme") ?? "auto";
   const rangeColors = ["#14432a", "#166b34", "#37a446", "#4dd05a"];
   const startDate = new Date(Date.now() - (365 * 24 * 60 * 60 * 1000));
@@ -68,6 +69,16 @@ document.addEventListener("DOMContentLoaded", () => {
         text: (date, value) => getTooltipText(date, value)
       }]
     ]);
+
+    cal.on("click", (_event, timestamp) => {
+      if (!displayName) return;
+      for (const { date, max_id } of heatmapData) {
+        if (!max_id) continue;
+        if (timestamp !== Date.parse(date)) continue;
+        const params = new URLSearchParams([["before", max_id + 1]]);
+        location = `/user/${encodeURIComponent(displayName)}/history?${params}`;
+      }
+    });
   }
 
   function getTooltipText(date, value) {
index c6e2298ab330685bbe37c20174a674bd929f0442..2ea2ea36f3006f4566e46830646904c529a88391 100644 (file)
@@ -24,7 +24,7 @@ class UsersController < ApplicationController
     if @user && (@user.visible? || current_user&.administrator?)
       @title = @user.display_name
 
-      @heatmap_data = Rails.cache.fetch("heatmap_data_user_#{@user.id}", :expires_in => 1.day) do
+      @heatmap_data = Rails.cache.fetch("heatmap_data_with_ids_user_#{@user.id}", :expires_in => 1.day) do
         one_year_ago = 1.year.ago.beginning_of_day
         today = Time.zone.now.end_of_day
 
@@ -33,12 +33,13 @@ class UsersController < ApplicationController
           .where(:created_at => one_year_ago..today)
           .where(:num_changes => 1..)
           .group("date_trunc('day', created_at)")
-          .select("date_trunc('day', created_at) AS date, SUM(num_changes) AS total_changes")
+          .select("date_trunc('day', created_at) AS date, SUM(num_changes) AS total_changes, MAX(id) AS max_id")
           .order("date")
           .map do |changeset|
             {
               :date => changeset.date.to_date.to_s,
-              :total_changes => changeset.total_changes.to_i
+              :total_changes => changeset.total_changes.to_i,
+              :max_id => changeset.max_id
             }
           end
       end
index e9f364523dd6c863d8b20719bf95166fa6c055ad..5ee0c190081ba4ebad035c5f6ec9f235d6e6d55f 100644 (file)
         </ul>
         <!-- Heatmap -->
         <div id="cal-heatmap" class="ms-2"
-          data-heatmap="<%= @heatmap_data.to_json %>">
+          data-heatmap="<%= @heatmap_data.to_json %>" data-display-name="<%= @user.display_name %>">
         </div>
       </div>
     </div>
index a4326cf5cfe2845873349f8583cb1c5fe738191f..5066faec3097377b794233d20087e87ab9ad4cbd 100644 (file)
@@ -364,7 +364,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
     assert_equal 1, first_response_data.size, "Expected one entry in the heatmap data"
 
     # Inspect cache after the first request
-    cached_data = Rails.cache.read("heatmap_data_user_#{user.id}")
+    cached_data = Rails.cache.read("heatmap_data_with_ids_user_#{user.id}")
     assert_equal first_response_data, cached_data, "Expected the cache to contain the first response data"
 
     # Add a new changeset to the database
@@ -408,16 +408,17 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
 
     # Test user with changesets
     user_with_changesets = create(:user)
-    create(:changeset, :user => user_with_changesets, :created_at => 3.months.ago.beginning_of_day, :num_changes => 42)
-    create(:changeset, :user => user_with_changesets, :created_at => 4.months.ago.beginning_of_day, :num_changes => 39)
+    changeset39 = create(:changeset, :user => user_with_changesets, :created_at => 4.months.ago.beginning_of_day, :num_changes => 39)
+    _changeset5 = create(:changeset, :user => user_with_changesets, :created_at => 3.months.ago.beginning_of_day, :num_changes => 5)
+    changeset11 = create(:changeset, :user => user_with_changesets, :created_at => 3.months.ago.beginning_of_day, :num_changes => 11)
     get user_path(user_with_changesets)
     assert_response :success
     assert_select "div#cal-heatmap[data-heatmap]" do |elements|
       # Check the data-heatmap attribute is present and contains expected JSON
       heatmap_data = JSON.parse(elements.first["data-heatmap"])
       expected_data = [
-        { "date" => 4.months.ago.to_date.to_s, "total_changes" => 39 },
-        { "date" => 3.months.ago.to_date.to_s, "total_changes" => 42 }
+        { "date" => 4.months.ago.to_date.to_s, "total_changes" => 39, "max_id" => changeset39.id },
+        { "date" => 3.months.ago.to_date.to_s, "total_changes" => 16, "max_id" => changeset11.id }
       ]
       assert_equal expected_data, heatmap_data
     end