]> source.dussan.org Git - gitea.git/commitdiff
Heatmap days clickable (#13935)
authorgordon-- <gordon_vdlg@gmx.de>
Sat, 20 Feb 2021 22:08:58 +0000 (23:08 +0100)
committerGitHub <noreply@github.com>
Sat, 20 Feb 2021 22:08:58 +0000 (17:08 -0500)
* Heatmap days clickable

* Error handling

* Unselect filter

* better dayclick handler

* made linter happy

* clickable heatmap for profiles

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
models/action.go
routers/user/home.go
routers/user/profile.go
web_src/js/components/ActivityHeatmap.vue

index e8a1336566e15f4d25e0891fee7be0bc4bf332b5..47d056ae3a554b41085b13d2fa66abf163d8b812 100644 (file)
@@ -289,12 +289,13 @@ func (a *Action) GetIssueContent() string {
 
 // GetFeedsOptions options for retrieving feeds
 type GetFeedsOptions struct {
-       RequestedUser   *User // the user we want activity for
-       RequestedTeam   *Team // the team we want activity for
-       Actor           *User // the user viewing the activity
-       IncludePrivate  bool  // include private actions
-       OnlyPerformedBy bool  // only actions performed by requested user
-       IncludeDeleted  bool  // include deleted actions
+       RequestedUser   *User  // the user we want activity for
+       RequestedTeam   *Team  // the team we want activity for
+       Actor           *User  // the user viewing the activity
+       IncludePrivate  bool   // include private actions
+       OnlyPerformedBy bool   // only actions performed by requested user
+       IncludeDeleted  bool   // include deleted actions
+       Date            string // the day we want activity for: YYYY-MM-DD
 }
 
 // GetFeeds returns actions according to the provided options
@@ -380,5 +381,17 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
                cond = cond.And(builder.Eq{"is_deleted": false})
        }
 
+       if opts.Date != "" {
+               dateLow, err := time.Parse("2006-01-02", opts.Date)
+               if err != nil {
+                       log.Warn("Unable to parse %s, filter not applied: %v", opts.Date, err)
+               } else {
+                       dateHigh := dateLow.Add(86399000000000) // 23h59m59s
+
+                       cond = cond.And(builder.Gte{"created_unix": dateLow.Unix()})
+                       cond = cond.And(builder.Lte{"created_unix": dateHigh.Unix()})
+               }
+       }
+
        return cond, nil
 }
index a8a8a5f3d750377dcbf00813bc10b358c6bb7bf2..a8020b64e0486b94b2f2885e0fd61888d86a46ed 100644 (file)
@@ -156,6 +156,7 @@ func Dashboard(ctx *context.Context) {
                IncludePrivate:  true,
                OnlyPerformedBy: false,
                IncludeDeleted:  false,
+               Date:            ctx.Query("date"),
        })
 
        if ctx.Written() {
index e19407baa78cf4486e6c937d5858343183442cbd..5dfee07d7622f48afe0eb17e4acaa43a8d5e011d 100644 (file)
@@ -202,6 +202,7 @@ func Profile(ctx *context.Context) {
                        IncludePrivate:  showPrivate,
                        OnlyPerformedBy: true,
                        IncludeDeleted:  false,
+                       Date:            ctx.Query("date"),
                })
                if ctx.Written() {
                        return
index 7eb129d1397bd4005a90d3f32ea819f715106ae7..63e38ea69e1e5fc70da2a50513c740146d42e3f5 100644 (file)
@@ -10,6 +10,7 @@
       :end-date="endDate"
       :values="values"
       :range-color="colorRange"
+      @day-click="handleDayClick($event)"
     />
   </div>
 </template>
@@ -48,7 +49,25 @@ export default {
       }
       return s;
     }
-  }
+  },
+  methods: {
+    handleDayClick(e) {
+      // Reset filter if same date is clicked
+      const params = new URLSearchParams(document.location.search);
+      const queryDate = params.get('date');
+      // Timezone has to be stripped because toISOString() converts to UTC
+      const clickedDate = new Date(e.date - (e.date.getTimezoneOffset() * 60000)).toISOString().substring(0, 10);
+
+      if (queryDate && queryDate === clickedDate) {
+        params.delete('date');
+      } else {
+        params.set('date', clickedDate);
+      }
+
+      const newSearch = params.toString();
+      window.location.search = newSearch.length ? `?${newSearch}` : '';
+    }
+  },
 };
 </script>
 <style scoped/>