forked from forgejo/forgejo
times Add filters (#9373)
(extend #9200) * add query param for GET functions (created Bevore & after) * add test * generalize func GetQueryBeforeSince Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
f8dcc5f9f8
commit
14a9687444
6 changed files with 234 additions and 32 deletions
|
@ -5,12 +5,15 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
)
|
||||
|
||||
// ListTrackedTimes list all the tracked times of an issue
|
||||
|
@ -37,6 +40,16 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
|||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: since
|
||||
// in: query
|
||||
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// - name: before
|
||||
// in: query
|
||||
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/TrackedTimeList"
|
||||
|
@ -62,6 +75,11 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
|||
IssueID: issue.ID,
|
||||
}
|
||||
|
||||
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin {
|
||||
opts.UserID = ctx.User.ID
|
||||
}
|
||||
|
@ -141,7 +159,7 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) {
|
|||
//allow only RepoAdmin, Admin and User to add time
|
||||
user, err = models.GetUserByName(form.User)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetUserByName", err)
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,33 +213,33 @@ func ResetIssueTime(ctx *context.APIContext) {
|
|||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/error"
|
||||
// "$ref": "#/responses/forbidden"
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(500, "GetIssueByIndex", err)
|
||||
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanUseTimetracker(issue, ctx.User) {
|
||||
if !ctx.Repo.Repository.IsTimetrackerEnabled() {
|
||||
ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"})
|
||||
ctx.JSON(http.StatusBadRequest, struct{ Message string }{Message: "time tracking disabled"})
|
||||
return
|
||||
}
|
||||
ctx.Status(403)
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
err = models.DeleteIssueUserTimes(issue, ctx.User)
|
||||
if err != nil {
|
||||
if models.IsErrNotExist(err) {
|
||||
ctx.Error(404, "DeleteIssueUserTimes", err)
|
||||
ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err)
|
||||
} else {
|
||||
ctx.Error(500, "DeleteIssueUserTimes", err)
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteIssueUserTimes", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -266,52 +284,53 @@ func DeleteTime(ctx *context.APIContext) {
|
|||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/error"
|
||||
// "$ref": "#/responses/forbidden"
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(500, "GetIssueByIndex", err)
|
||||
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanUseTimetracker(issue, ctx.User) {
|
||||
if !ctx.Repo.Repository.IsTimetrackerEnabled() {
|
||||
ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"})
|
||||
ctx.JSON(http.StatusBadRequest, struct{ Message string }{Message: "time tracking disabled"})
|
||||
return
|
||||
}
|
||||
ctx.Status(403)
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
time, err := models.GetTrackedTimeByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetTrackedTimeByID", err)
|
||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimeByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.User.IsAdmin && time.UserID != ctx.User.ID {
|
||||
//Only Admin and User itself can delete their time
|
||||
ctx.Status(403)
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
err = models.DeleteTime(time)
|
||||
if err != nil {
|
||||
ctx.Error(500, "DeleteTime", err)
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteTime", err)
|
||||
return
|
||||
}
|
||||
ctx.Status(204)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// ListTrackedTimesByUser lists all tracked times of the user
|
||||
func ListTrackedTimesByUser(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/times/{user} user userTrackedTimes
|
||||
// swagger:operation GET /repos/{owner}/{repo}/times/{user} repository userTrackedTimes
|
||||
// ---
|
||||
// summary: List a user's tracked times in a repo
|
||||
// deprecated: true
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
|
@ -335,6 +354,8 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/TrackedTimeList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
|
||||
if !ctx.Repo.Repository.IsTimetrackerEnabled() {
|
||||
ctx.Error(http.StatusBadRequest, "", "time tracking disabled")
|
||||
|
@ -353,9 +374,23 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
|
|||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{
|
||||
|
||||
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin && ctx.User.ID != user.ID {
|
||||
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights"))
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin && ctx.User.ID != user.ID {
|
||||
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights"))
|
||||
return
|
||||
}
|
||||
|
||||
opts := models.FindTrackedTimesOptions{
|
||||
UserID: user.ID,
|
||||
RepositoryID: ctx.Repo.Repository.ID})
|
||||
RepositoryID: ctx.Repo.Repository.ID,
|
||||
}
|
||||
|
||||
trackedTimes, err := models.GetTrackedTimes(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err)
|
||||
return
|
||||
|
@ -385,11 +420,27 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
|
|||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: user
|
||||
// in: query
|
||||
// description: optional filter by user
|
||||
// type: string
|
||||
// - name: since
|
||||
// in: query
|
||||
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// - name: before
|
||||
// in: query
|
||||
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/TrackedTimeList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
|
||||
if !ctx.Repo.Repository.IsTimetrackerEnabled() {
|
||||
ctx.Error(http.StatusBadRequest, "", "time tracking disabled")
|
||||
|
@ -400,8 +451,30 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
|
|||
RepositoryID: ctx.Repo.Repository.ID,
|
||||
}
|
||||
|
||||
// Filters
|
||||
qUser := strings.Trim(ctx.Query("user"), " ")
|
||||
if qUser != "" {
|
||||
user, err := models.GetUserByName(qUser)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
|
||||
return
|
||||
}
|
||||
opts.UserID = user.ID
|
||||
}
|
||||
|
||||
var err error
|
||||
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin {
|
||||
opts.UserID = ctx.User.ID
|
||||
if opts.UserID == 0 {
|
||||
opts.UserID = ctx.User.ID
|
||||
} else {
|
||||
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
trackedTimes, err := models.GetTrackedTimes(opts)
|
||||
|
@ -423,18 +496,39 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
|
|||
// summary: List the current user's tracked times
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: since
|
||||
// in: query
|
||||
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// - name: before
|
||||
// in: query
|
||||
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format
|
||||
// type: string
|
||||
// format: date-time
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/TrackedTimeList"
|
||||
|
||||
trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{UserID: ctx.User.ID})
|
||||
opts := models.FindTrackedTimesOptions{UserID: ctx.User.ID}
|
||||
|
||||
var err error
|
||||
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
trackedTimes, err := models.GetTrackedTimes(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = trackedTimes.LoadAttributes(); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, trackedTimes.APIFormat())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue