mirror of https://github.com/go-gitea/gitea
Commit
This commit is contained in:
parent
edf98a2dc3
commit
1363205f29
|
@ -130,6 +130,8 @@ const (
|
|||
CommentTypePRScheduledToAutoMerge
|
||||
// 35 pr was un scheduled to auto merge when checks succeed
|
||||
CommentTypePRUnScheduledToAutoMerge
|
||||
// 36 Change plan time
|
||||
CommentTypeChangePlanTime
|
||||
)
|
||||
|
||||
var commentStrings = []string{
|
||||
|
@ -144,6 +146,7 @@ var commentStrings = []string{
|
|||
"milestone",
|
||||
"assignees",
|
||||
"change_title",
|
||||
"change_plan_time",
|
||||
"delete_branch",
|
||||
"start_tracking",
|
||||
"stop_tracking",
|
||||
|
@ -301,6 +304,9 @@ type Comment struct {
|
|||
NewCommit string `xorm:"-"`
|
||||
CommitsNum int64 `xorm:"-"`
|
||||
IsForcePush bool `xorm:"-"`
|
||||
|
||||
PlanTimeHours int
|
||||
PlanTimeMinutes int
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -819,6 +825,8 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
|
|||
RefIsPull: opts.RefIsPull,
|
||||
IsForcePush: opts.IsForcePush,
|
||||
Invalidated: opts.Invalidated,
|
||||
PlanTimeHours: opts.PlanTimeHours,
|
||||
PlanTimeMinutes: opts.PlanTimeMinutes,
|
||||
}
|
||||
if _, err = e.Insert(comment); err != nil {
|
||||
return nil, err
|
||||
|
@ -990,6 +998,8 @@ type CreateCommentOptions struct {
|
|||
RefIsPull bool
|
||||
IsForcePush bool
|
||||
Invalidated bool
|
||||
PlanTimeHours int
|
||||
PlanTimeMinutes int
|
||||
}
|
||||
|
||||
// GetCommentByID returns the comment by given ID.
|
||||
|
|
|
@ -146,6 +146,10 @@ type Issue struct {
|
|||
|
||||
// For view issue page.
|
||||
ShowRole RoleDescriptor `xorm:"-"`
|
||||
|
||||
// Plan time
|
||||
PlanTimeHours int
|
||||
PlanTimeMinutes int
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -774,6 +778,37 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err
|
|||
return committer.Commit()
|
||||
}
|
||||
|
||||
// ChangeIssuePlanTime changes the plan time of this issue, as the given user.
|
||||
func ChangeIssuePlanTime(issue *Issue, doer *user_model.User, planTimeHours int, planTimeMinutes int) (err error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, PlanTimeHours: planTimeHours, PlanTimeMinutes: planTimeMinutes}, "plan_time_hours", "plan_time_minutes"); err != nil {
|
||||
return fmt.Errorf("updateIssueCols: %w", err)
|
||||
}
|
||||
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
return fmt.Errorf("loadRepo: %w", err)
|
||||
}
|
||||
|
||||
opts := &CreateCommentOptions{
|
||||
Type: CommentTypeChangePlanTime,
|
||||
Doer: doer,
|
||||
Repo: issue.Repo,
|
||||
Issue: issue,
|
||||
PlanTimeHours: planTimeHours,
|
||||
PlanTimeMinutes: planTimeMinutes,
|
||||
}
|
||||
if _, err = CreateComment(ctx, opts); err != nil {
|
||||
return fmt.Errorf("createComment: %w", err)
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
// ChangeIssueRef changes the branch of this issue, as the given user.
|
||||
func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
|
|
|
@ -54,6 +54,8 @@ type Issue struct {
|
|||
Attachments []*Attachment `json:"assets"`
|
||||
Labels []*Label `json:"labels"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
PlanTimeHours int64 `json:"plan_time_hours"`
|
||||
PlanTimeMinutes int64 `json:"plan_time_minutes"`
|
||||
// deprecated
|
||||
Assignee *User `json:"assignee"`
|
||||
Assignees []*User `json:"assignees"`
|
||||
|
@ -106,8 +108,10 @@ type EditIssueOption struct {
|
|||
Milestone *int64 `json:"milestone"`
|
||||
State *string `json:"state"`
|
||||
// swagger:strfmt date-time
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
PlanTimeHours int `json:"plan_time_hours"`
|
||||
PlanTimeMinutes int `json:"plan_time_minutes"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
}
|
||||
|
||||
// EditDeadlineOption options for creating a deadline
|
||||
|
|
|
@ -1301,6 +1301,9 @@ issues.add_assignee_at = `was assigned by <b>%s</b> %s`
|
|||
issues.remove_assignee_at = `was unassigned by <b>%s</b> %s`
|
||||
issues.remove_self_assignment = `removed their assignment %s`
|
||||
issues.change_title_at = `changed title from <b><strike>%s</strike></b> to <b>%s</b> %s`
|
||||
issues.tracker_plan_time = `Time plan`
|
||||
issues.change_plan_time_at = `changed plan time to <b>%d hour %d minutes</b> %s`
|
||||
issues.remove_plan_time = `removed plan time %s`
|
||||
issues.change_ref_at = `changed reference from <b><strike>%s</strike></b> to <b>%s</b> %s`
|
||||
issues.remove_ref_at = `removed reference <b>%s</b> %s`
|
||||
issues.add_ref_at = `added reference <b>%s</b> %s`
|
||||
|
|
|
@ -1216,6 +1216,9 @@ issues.add_assignee_at=`был(а) назначен(а) <b>%s</b> %s`
|
|||
issues.remove_assignee_at=`был снят с назначения <b>%s</b> %s`
|
||||
issues.remove_self_assignment=`убрал(а) их назначение %s`
|
||||
issues.change_title_at=`изменил(а) заголовок с <b><strike>%s</strike></b> на <b>%s</b> %s`
|
||||
issues.tracker_plan_time = `Время план`
|
||||
issues.change_plan_time_at=`изменил(а) время план на <b>%d час(ов) %d минут</b> %s`
|
||||
issues.remove_plan_time = `убрал(а) время план %s`
|
||||
issues.change_ref_at=`изменил(а) ссылку с <b><strike>%s</strike></b> на <b>%s</b> %s`
|
||||
issues.remove_ref_at=`убрал(а) ссылку <b>%s</b> %s`
|
||||
issues.add_ref_at=`добавил(а) ссылку <b>%s</b> %s`
|
||||
|
|
|
@ -574,7 +574,7 @@ delete_email=Видалити
|
|||
email_deletion=Видалити адресу електронної пошти
|
||||
email_deletion_desc=Електронна адреса та пов'язана з нею інформація буде видалена з вашого облікового запису. Git коміти, здійснені через цю електронну адресу, залишиться без змін. Продовжити?
|
||||
email_deletion_success=Адресу електронної пошти було видалено.
|
||||
theme_update_success=Тему оновлено.
|
||||
theme_update_success=Тему оновлено.
|
||||
theme_update_error=Вибрана тема не існує.
|
||||
openid_deletion=Видалити адресу OpenID
|
||||
openid_deletion_desc=Видалення цієї OpenID-адреси з вашого облікового запису забороняє вам входити з ним. Продовжити?
|
||||
|
@ -1160,6 +1160,9 @@ issues.add_assignee_at=`був призначений <b>%s</b> %s`
|
|||
issues.remove_assignee_at=`був знятий з призначення <b>%s</b> %s`
|
||||
issues.remove_self_assignment=`видалено призначення %s`
|
||||
issues.change_title_at=`змінився заголовок з <b><strike>%s</strike></b> на <b>%s</b> %s`
|
||||
issues.tracker_plan_time = `Час план`
|
||||
issues.change_plan_time_at=`змінив час план на <b>%d годин %d хвилин</b> %s`
|
||||
issues.remove_plan_time = `видалив час план %s`
|
||||
issues.change_ref_at=`змінив посилання з <b><strike>%s</strike></b> на <b>%s</b> %s`
|
||||
issues.remove_ref_at=`видалив посилання <b>%s</b> %s`
|
||||
issues.add_ref_at=`додав посилання <b>%s</b> %s`
|
||||
|
|
|
@ -1970,6 +1970,32 @@ func UpdateIssueTitle(ctx *context.Context) {
|
|||
})
|
||||
}
|
||||
|
||||
// UpdateIssuePlanTime change issue's title
|
||||
func UpdateIssuePlanTime(ctx *context.Context) {
|
||||
issue := GetActionIssue(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
planTimeHours := ctx.FormInt("plan_time_hours")
|
||||
planTimeMinutes := ctx.FormInt("plan_time_minutes")
|
||||
|
||||
if err := issue_service.ChangePlanTime(issue, ctx.Doer, planTimeHours, planTimeMinutes); err != nil {
|
||||
ctx.ServerError("ChangePlanTime", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"plan_time_hours": issue.PlanTimeHours,
|
||||
"plan_time_minutes": issue.PlanTimeMinutes,
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateIssueRef change issue's ref (branch)
|
||||
func UpdateIssueRef(ctx *context.Context) {
|
||||
issue := GetActionIssue(ctx)
|
||||
|
|
|
@ -1069,6 +1069,7 @@ func RegisterRoutes(m *web.Route) {
|
|||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
m.Group("/{index}", func() {
|
||||
m.Post("/plan_time", repo.UpdateIssuePlanTime)
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
m.Post("/content", repo.UpdateIssueContent)
|
||||
m.Post("/deadline", web.Bind(structs.EditDeadlineOption{}), repo.UpdateIssueDeadline)
|
||||
|
|
|
@ -61,6 +61,21 @@ func ChangeTitle(issue *issues_model.Issue, doer *user_model.User, title string)
|
|||
return nil
|
||||
}
|
||||
|
||||
// ChangeTitle changes the title of this issue, as the given user.
|
||||
func ChangePlanTime(issue *issues_model.Issue, doer *user_model.User, planTimeHours int, planTimeMinutes int) (err error) {
|
||||
//oldTitle := issue.Title
|
||||
issue.PlanTimeHours = planTimeHours
|
||||
issue.PlanTimeMinutes = planTimeMinutes
|
||||
|
||||
if err = issues_model.ChangeIssuePlanTime(issue, doer, planTimeHours, planTimeMinutes); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//notification.NotifyIssueChangeTitle(db.DefaultContext, doer, issue, oldTitle)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeIssueRef changes the branch of this issue, as the given user.
|
||||
func ChangeIssueRef(issue *issues_model.Issue, doer *user_model.User, ref string) error {
|
||||
oldRef := issue.Ref
|
||||
|
|
|
@ -793,6 +793,19 @@
|
|||
{{else}}{{$.locale.Tr "repo.pulls.auto_merge_canceled_schedule_comment" $createdStr | Safe}}{{end}}
|
||||
</span>
|
||||
</div>
|
||||
{{else if eq .Type 1001}}
|
||||
<div class="timeline-item event" id="{{.HashTag}}">
|
||||
<span class="badge">{{svg "octicon-pencil"}}</span>
|
||||
{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}}
|
||||
<span class="text grey muted-links">
|
||||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{if and (eq .PlanTimeHours 0) (eq .PlanTimeMinutes 0)}}
|
||||
{{$.locale.Tr "repo.issues.remove_plan_time" $createdStr | Safe}}
|
||||
{{else}}
|
||||
{{$.locale.Tr "repo.issues.change_plan_time_at" (.PlanTimeHours) (.PlanTimeMinutes) $createdStr | Safe}}
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -358,6 +358,21 @@
|
|||
{{end}}
|
||||
{{if .Repository.IsTimetrackerEnabled $.Context}}
|
||||
{{if and .CanUseTimetracker (not .Repository.IsArchived)}}
|
||||
<div class="ui divider"></div>
|
||||
<div>
|
||||
<span class="text"><strong>{{.locale.Tr "repo.issues.tracker_plan_time"}}</strong></span>
|
||||
|
||||
<form method="POST" id="set_plan_time_form" class="gt-mt-3" action="{{.Issue.Link}}/plan_time">
|
||||
{{$.CsrfTokenHtml}}
|
||||
<div class="ui action input fluid">
|
||||
<input placeholder='{{.locale.Tr "repo.issues.add_time_hours"}}' type="number" min="0" value="{{ ($.Issue.PlanTimeHours) }}" name="plan_time_hours">
|
||||
<input placeholder='{{.locale.Tr "repo.issues.add_time_minutes"}}' type="number" min="0" max="59" value="{{ ($.Issue.PlanTimeMinutes) }}" name="plan_time_minutes" class="ui compact">
|
||||
</div>
|
||||
<button class="ui fluid button green tooltip issue-add-time gt-mt-3">
|
||||
{{.locale.Tr "repo.issues.save"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui timetrack">
|
||||
<span class="text"><strong>{{.locale.Tr "repo.issues.tracker"}}</strong></span>
|
||||
|
|
|
@ -639,6 +639,27 @@ export function initRepoIssueTitleEdit() {
|
|||
});
|
||||
}
|
||||
|
||||
export function initRepoIssuePlanTimeEdit() {
|
||||
$('#set_plan_time_form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const planTimeHours = $(this).find('[name=plan_time_hours]').val();
|
||||
const planTimeMinutes = $(this).find('[name=plan_time_minutes]').val();
|
||||
|
||||
$.post($(this).attr('action'), {
|
||||
_csrf: csrfToken,
|
||||
plan_time_hours: planTimeHours,
|
||||
plan_time_minutes: planTimeMinutes,
|
||||
}).done((data) => {
|
||||
console.log('ok')
|
||||
}).always(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
export function initRepoIssueBranchSelect() {
|
||||
const changeBranchSelect = function () {
|
||||
const selectionTextField = $('#pull-target-branch');
|
||||
|
|
|
@ -4,7 +4,7 @@ import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
|
|||
import {initEasyMDEImagePaste} from './comp/ImagePaste.js';
|
||||
import {
|
||||
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
|
||||
initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssueReferenceIssue,
|
||||
initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssuePlanTimeEdit, initRepoIssueReferenceIssue,
|
||||
initRepoIssueStatusButton, initRepoIssueTitleEdit, initRepoIssueWipToggle,
|
||||
initRepoPullRequestUpdate, updateIssuesMeta,
|
||||
} from './repo-issue.js';
|
||||
|
@ -562,6 +562,7 @@ export function initRepository() {
|
|||
initRepoIssueTitleEdit();
|
||||
initRepoIssueWipToggle();
|
||||
initRepoIssueComments();
|
||||
initRepoIssuePlanTimeEdit();
|
||||
|
||||
initRepoDiffConversationNav();
|
||||
initRepoIssueReferenceIssue();
|
||||
|
|
Loading…
Reference in New Issue