This commit is contained in:
stuzer05 2023-02-24 12:06:12 +02:00
parent edf98a2dc3
commit 1363205f29
13 changed files with 154 additions and 4 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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`

View File

@ -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`

View File

@ -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`

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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}}

View File

@ -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>

View File

@ -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');

View File

@ -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();