mirror of
https://github.com/go-gitea/gitea.git
synced 2025-02-03 09:31:40 +01:00
34692a20b1
Dear Gitea team, first of all, thanks for the great work you're doing with this project. I'm planning to introduce Gitea at a client site, and noticed that while there is time recording, there are no project-manager-friendly reports to actually make use of that data, as were also mentioned by others in #4870 #8684 and #13531. Since I had a little time last weekend, I had put together something that I hope to be a useful contribution to this great project (while of course useful for me too). This PR adds a new "Worktime" tab to the Organisation level. There is a date range selector (by default set to the current month), and there are three possible views: - by repository, - by milestone, and - by team member. Happy to receive any feedback! There are several possible future improvements of course (predefined date ranges, charts, a member time sheet, matrix of repos/members, etc) but I hope that even in this relatively simple state this would be useful to lots of people. <img width="1161" alt="Screen Shot 2022-05-25 at 22 12 58" src="https://user-images.githubusercontent.com/118010/170366976-af00c7af-c4f3-4117-86d7-00356d6797a5.png"> Keep up the good work! Kristof --------- Co-authored-by: user <user@kk-git1> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package org
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"code.gitea.io/gitea/models/organization"
|
|
"code.gitea.io/gitea/modules/templates"
|
|
"code.gitea.io/gitea/services/context"
|
|
)
|
|
|
|
const tplByRepos templates.TplName = "org/worktime"
|
|
|
|
// parseOrgTimes contains functionality that is required in all these functions,
|
|
// like parsing the date from the request, setting default dates, etc.
|
|
func parseOrgTimes(ctx *context.Context) (unixFrom, unixTo int64) {
|
|
rangeFrom := ctx.FormString("from")
|
|
rangeTo := ctx.FormString("to")
|
|
if rangeFrom == "" {
|
|
rangeFrom = time.Now().Format("2006-01") + "-01" // defaults to start of current month
|
|
}
|
|
if rangeTo == "" {
|
|
rangeTo = time.Now().Format("2006-01-02") // defaults to today
|
|
}
|
|
|
|
ctx.Data["RangeFrom"] = rangeFrom
|
|
ctx.Data["RangeTo"] = rangeTo
|
|
|
|
timeFrom, err := time.Parse("2006-01-02", rangeFrom)
|
|
if err != nil {
|
|
ctx.ServerError("time.Parse", err)
|
|
}
|
|
timeTo, err := time.Parse("2006-01-02", rangeTo)
|
|
if err != nil {
|
|
ctx.ServerError("time.Parse", err)
|
|
}
|
|
unixFrom = timeFrom.Unix()
|
|
unixTo = timeTo.Add(1440*time.Minute - 1*time.Second).Unix() // humans expect that we include the ending day too
|
|
return unixFrom, unixTo
|
|
}
|
|
|
|
func Worktime(ctx *context.Context) {
|
|
ctx.Data["PageIsOrgTimes"] = true
|
|
|
|
unixFrom, unixTo := parseOrgTimes(ctx)
|
|
if ctx.Written() {
|
|
return
|
|
}
|
|
|
|
worktimeBy := ctx.FormString("by")
|
|
ctx.Data["WorktimeBy"] = worktimeBy
|
|
|
|
var worktimeSumResult any
|
|
var err error
|
|
if worktimeBy == "milestones" {
|
|
worktimeSumResult, err = organization.GetWorktimeByMilestones(ctx.Org.Organization, unixFrom, unixTo)
|
|
ctx.Data["WorktimeByMilestones"] = true
|
|
} else if worktimeBy == "members" {
|
|
worktimeSumResult, err = organization.GetWorktimeByMembers(ctx.Org.Organization, unixFrom, unixTo)
|
|
ctx.Data["WorktimeByMembers"] = true
|
|
} else /* by repos */ {
|
|
worktimeSumResult, err = organization.GetWorktimeByRepos(ctx.Org.Organization, unixFrom, unixTo)
|
|
ctx.Data["WorktimeByRepos"] = true
|
|
}
|
|
if err != nil {
|
|
ctx.ServerError("GetWorktime", err)
|
|
return
|
|
}
|
|
ctx.Data["WorktimeSumResult"] = worktimeSumResult
|
|
ctx.HTML(http.StatusOK, tplByRepos)
|
|
}
|