Skip to content

Commit

Permalink
Issue due date api (go-gitea#3890)
Browse files Browse the repository at this point in the history
* Implemented basic api endpoint to manage deadlines

* Fixed checking for permissions

* Updating a deadline from the ui is now entirely done via the api

* cleanup

* Cosmetics

* fixed lint + fmt

* Added swagger model definition for deadline response

* Updated gitea-sdk

* Updated gitea-sdk

* More cleanup

* Generate swagger json

* Merge branch 'master' of https://github.com/go-gitea/gitea into issue-due-date-api

# Conflicts:
#	public/swagger.v1.json

* Fixed permission to update a deadline via api

* Re-added form to change a deadline

* Added client-side validation + not ignore error messages from the api

* Added locale for error message

* Merge branch 'master' of https://github.com/go-gitea/gitea

# Conflicts:
#	models/issue_comment.go

* Proper date validation

* Fixed indention

* moved css to css file

* added documentation for error codes

* after merge cleanup

* Added swagger description

* DO NOTHING BUT TRIGGER THAT F*CKIN CI SO IT PICKS UP THE LATEST COMMIT AS IT SHOULD

* DO NOTHING BUT TRIGGER THAT F*CKIN CI SO IT PICKS UP THE LATEST COMMIT AS IT SHOULD

* regenerated stylesheets
  • Loading branch information
kolaente authored and jonasfranz committed Jul 16, 2018
1 parent 55d9ddf commit ef6813a
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 90 deletions.
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ issues.due_date_added = "added the due date %s %s"
issues.due_date_modified = "modified the due date to %s from %s %s"
issues.due_date_remove = "removed the due date %s %s"
issues.due_date_overdue = "Overdue"
issues.due_date_invalid = "The due date is invalid or out of range. Please use the format yyyy-mm-dd."

pulls.desc = Enable merge requests and code reviews.
pulls.new = New Pull Request
Expand Down
2 changes: 1 addition & 1 deletion public/css/index.css

Large diffs are not rendered by default.

44 changes: 37 additions & 7 deletions public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2447,14 +2447,44 @@ function initTopicbar() {
}
});
}
function toggleDuedateForm() {
$('#add_deadline_form').fadeToggle(150);
function toggleDeadlineForm() {
$('#deadlineForm').fadeToggle(150);
}

function deleteDueDate(url) {
$.post(url, {
'_csrf': csrf,
},function( data ) {
window.location.reload();
function setDeadline() {
var deadline = $('#deadlineDate').val();
updateDeadline(deadline);
}

function updateDeadline(deadlineString) {
$('#deadline-err-invalid-date').hide();
$('#deadline-loader').addClass('loading');

var realDeadline = null;
if (deadlineString !== '') {

var newDate = Date.parse(deadlineString)

if (isNaN(newDate)) {
$('#deadline-loader').removeClass('loading');
$('#deadline-err-invalid-date').show();
return false;
}
realDeadline = new Date(newDate);
}

$.ajax($('#update-issue-deadline-form').attr('action') + '/deadline', {
data: JSON.stringify({
'due_date': realDeadline,
}),
contentType: 'application/json',
type: 'POST',
success: function () {
window.location.reload();
},
error: function () {
$('#deadline-loader').removeClass('loading');
$('#deadline-err-invalid-date').show();
}
});
}
7 changes: 7 additions & 0 deletions public/less/_repository.less
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@
}
}
}

#deadlineForm input{
width: 12.8rem;
border-radius: 4px 0 0 4px;
border-right: 0;
white-space: nowrap;
}
}
.header-wrapper {
background-color: #FAFAFA;
Expand Down
95 changes: 95 additions & 0 deletions public/swagger.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,68 @@
}
}
},
"/repos/{owner}/{repo}/issues/{index}/deadline": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"issue"
],
"summary": "Set an issue deadline. If set to null, the deadline is deleted.",
"operationId": "issueEditIssueDeadline",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "index of the issue to create or update a deadline on",
"name": "index",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/EditDeadlineOption"
}
}
],
"responses": {
"201": {
"$ref": "#/responses/IssueDeadline"
},
"403": {
"description": "Not repo writer",
"schema": {
"$ref": "#/responses/forbidden"
}
},
"404": {
"description": "Issue not found",
"schema": {
"$ref": "#/responses/empty"
}
}
}
}
},
"/repos/{owner}/{repo}/issues/{index}/labels": {
"get": {
"produces": [
Expand Down Expand Up @@ -6145,6 +6207,21 @@
},
"x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
},
"EditDeadlineOption": {
"description": "EditDeadlineOption options for creating a deadline",
"type": "object",
"required": [
"due_date"
],
"properties": {
"due_date": {
"type": "string",
"format": "date-time",
"x-go-name": "Deadline"
}
},
"x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
},
"EditHookOption": {
"description": "EditHookOption options when modify one hook",
"type": "object",
Expand Down Expand Up @@ -6635,6 +6712,18 @@
},
"x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
},
"IssueDeadline": {
"description": "IssueDeadline represents an issue deadline",
"type": "object",
"properties": {
"due_date": {
"type": "string",
"format": "date-time",
"x-go-name": "Deadline"
}
},
"x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
},
"IssueLabelsOption": {
"description": "IssueLabelsOption a collection of labels",
"type": "object",
Expand Down Expand Up @@ -7635,6 +7724,12 @@
"$ref": "#/definitions/Issue"
}
},
"IssueDeadline": {
"description": "IssueDeadline",
"schema": {
"$ref": "#/definitions/IssueDeadline"
}
},
"IssueList": {
"description": "IssueList",
"schema": {
Expand Down
2 changes: 2 additions & 0 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Combo("").Get(repo.ListTrackedTimes).
Post(reqToken(), bind(api.AddTimeOption{}), repo.AddTime)
})

m.Combo("/deadline").Post(reqToken(), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline)
})
}, mustEnableIssues)
m.Group("/labels", func() {
Expand Down
71 changes: 70 additions & 1 deletion routers/api/v1/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {

// Update the deadline
var deadlineUnix util.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() {
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.IsWriter() {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
}

Expand Down Expand Up @@ -338,3 +338,72 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
}
ctx.JSON(201, issue.APIFormat())
}

// UpdateIssueDeadline updates an issue deadline
func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/deadline issue issueEditIssueDeadline
// ---
// summary: Set an issue deadline. If set to null, the deadline is deleted.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: index
// in: path
// description: index of the issue to create or update a deadline on
// type: integer
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/EditDeadlineOption"
// responses:
// "201":
// "$ref": "#/responses/IssueDeadline"
// "403":
// description: Not repo writer
// schema:
// "$ref": "#/responses/forbidden"
// "404":
// description: Issue not found
// schema:
// "$ref": "#/responses/empty"

issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
if models.IsErrIssueNotExist(err) {
ctx.Status(404)
} else {
ctx.Error(500, "GetIssueByIndex", err)
}
return
}

if !ctx.Repo.IsWriter() {
ctx.Status(403)
return
}

var deadlineUnix util.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
}

if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
ctx.Error(500, "UpdateIssueDeadline", err)
return
}

ctx.JSON(201, api.IssueDeadline{Deadline: form.Deadline})
}
7 changes: 7 additions & 0 deletions routers/api/v1/swagger/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,10 @@ type swaggerResponseTrackedTimeList struct {
// in:body
Body []api.TrackedTime `json:"body"`
}

// IssueDeadline
// swagger:response IssueDeadline
type swaggerIssueDeadline struct {
// in:body
Body api.IssueDeadline `json:"body"`
}
2 changes: 2 additions & 0 deletions routers/api/v1/swagger/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type swaggerParameterBodies struct {
CreateIssueOption api.CreateIssueOption
// in:body
EditIssueOption api.EditIssueOption
// in:body
EditDeadlineOption api.EditDeadlineOption

// in:body
CreateIssueCommentOption api.CreateIssueCommentOption
Expand Down
48 changes: 0 additions & 48 deletions routers/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1490,51 +1490,3 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) {
"html": html,
})
}

// UpdateDeadline adds or updates a deadline
func UpdateDeadline(ctx *context.Context, form auth.DeadlineForm) {
issue := GetActionIssue(ctx)
if ctx.Written() {
return
}

if ctx.HasError() {
ctx.ServerError("ChangeIssueDeadline", errors.New(ctx.GetErrMsg()))
return
}

// Make unix of deadline string
deadline, err := time.ParseInLocation("2006-01-02", form.DateString, time.Local)
if err != nil {
ctx.Flash.Error(ctx.Tr("repo.issues.invalid_due_date_format"))
ctx.Redirect(fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, issue.Index))
return
}

if err = models.UpdateIssueDeadline(issue, util.TimeStamp(deadline.Unix()), ctx.User); err != nil {
ctx.Flash.Error(ctx.Tr("repo.issues.error_modifying_due_date"))
}

ctx.Redirect(fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, issue.Index))
return
}

// RemoveDeadline removes a deadline
func RemoveDeadline(ctx *context.Context) {
issue := GetActionIssue(ctx)
if ctx.Written() {
return
}

if ctx.HasError() {
ctx.ServerError("RemoveIssueDeadline", errors.New(ctx.GetErrMsg()))
return
}

if err := models.UpdateIssueDeadline(issue, 0, ctx.User); err != nil {
ctx.Flash.Error(ctx.Tr("repo.issues.error_removing_due_date"))
}

ctx.Redirect(fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, issue.Index))
return
}
2 changes: 0 additions & 2 deletions routers/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,6 @@ func RegisterRoutes(m *macaron.Macaron) {
})
})
m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction)
m.Post("/deadline/update", reqRepoWriter, bindIgnErr(auth.DeadlineForm{}), repo.UpdateDeadline)
m.Post("/deadline/delete", reqRepoWriter, repo.RemoveDeadline)
})

m.Post("/labels", reqRepoWriter, repo.UpdateIssueLabel)
Expand Down
Loading

0 comments on commit ef6813a

Please sign in to comment.