summaryrefslogtreecommitdiffstats
path: root/templates/repo/issue
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-10-11 10:27:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-10-11 10:27:00 +0000
commit65aa53fc52ff15efe54df4147564828d535837f8 (patch)
tree31c51dad04fdcca80e6d3043c8bd49d2f1a51f83 /templates/repo/issue
parentInitial commit. (diff)
downloadforgejo-upstream.tar.xz
forgejo-upstream.zip
Adding upstream version 8.0.3.HEADupstream/8.0.3upstreamdebian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'templates/repo/issue')
-rw-r--r--templates/repo/issue/card.tmpl78
-rw-r--r--templates/repo/issue/choose.tmpl59
-rw-r--r--templates/repo/issue/comment_tab.tmpl21
-rw-r--r--templates/repo/issue/fields/checkboxes.tmpl14
-rw-r--r--templates/repo/issue/fields/dropdown.tmpl17
-rw-r--r--templates/repo/issue/fields/header.tmpl6
-rw-r--r--templates/repo/issue/fields/input.tmpl4
-rw-r--r--templates/repo/issue/fields/markdown.tmpl3
-rw-r--r--templates/repo/issue/fields/textarea.tmpl24
-rw-r--r--templates/repo/issue/filter_actions.tmpl128
-rw-r--r--templates/repo/issue/filter_list.tmpl158
-rw-r--r--templates/repo/issue/filters.tmpl26
-rw-r--r--templates/repo/issue/label_precolors.tmpl22
-rw-r--r--templates/repo/issue/labels.tmpl22
-rw-r--r--templates/repo/issue/labels/edit_delete_label.tmpl72
-rw-r--r--templates/repo/issue/labels/label.tmpl7
-rw-r--r--templates/repo/issue/labels/label_archived.tmpl5
-rw-r--r--templates/repo/issue/labels/label_list.tmpl88
-rw-r--r--templates/repo/issue/labels/label_load_template.tmpl24
-rw-r--r--templates/repo/issue/labels/label_new.tmpl48
-rw-r--r--templates/repo/issue/labels/labels_selector_field.tmpl46
-rw-r--r--templates/repo/issue/labels/labels_sidebar.tmpl11
-rw-r--r--templates/repo/issue/list.tmpl55
-rw-r--r--templates/repo/issue/milestone/filter_list.tmpl15
-rw-r--r--templates/repo/issue/milestone/select_menu.tmpl38
-rw-r--r--templates/repo/issue/milestone_issues.tmpl65
-rw-r--r--templates/repo/issue/milestone_new.tmpl59
-rw-r--r--templates/repo/issue/milestones.tmpl110
-rw-r--r--templates/repo/issue/navbar.tmpl4
-rw-r--r--templates/repo/issue/new.tmpl8
-rw-r--r--templates/repo/issue/new_form.tmpl190
-rw-r--r--templates/repo/issue/openclose.tmpl16
-rw-r--r--templates/repo/issue/search.tmpl20
-rw-r--r--templates/repo/issue/view.tmpl12
-rw-r--r--templates/repo/issue/view_content.tmpl187
-rw-r--r--templates/repo/issue/view_content/add_reaction.tmpl12
-rw-r--r--templates/repo/issue/view_content/attachments.tmpl42
-rw-r--r--templates/repo/issue/view_content/comments.tmpl683
-rw-r--r--templates/repo/issue/view_content/comments_authorlink.tmpl11
-rw-r--r--templates/repo/issue/view_content/comments_delete_time.tmpl18
-rw-r--r--templates/repo/issue/view_content/context_menu.tmpl27
-rw-r--r--templates/repo/issue/view_content/conversation.tmpl137
-rw-r--r--templates/repo/issue/view_content/pull.tmpl396
-rw-r--r--templates/repo/issue/view_content/pull_merge_instruction.tmpl49
-rw-r--r--templates/repo/issue/view_content/reactions.tmpl17
-rw-r--r--templates/repo/issue/view_content/reference_issue_dialog.tmpl28
-rw-r--r--templates/repo/issue/view_content/show_role.tmpl15
-rw-r--r--templates/repo/issue/view_content/sidebar.tmpl66
-rw-r--r--templates/repo/issue/view_content/sidebar/actions.tmpl114
-rw-r--r--templates/repo/issue/view_content/sidebar/assignees.tmpl45
-rw-r--r--templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl59
-rw-r--r--templates/repo/issue/view_content/sidebar/dependencies.tmpl145
-rw-r--r--templates/repo/issue/view_content/sidebar/due_deadline.tmpl41
-rw-r--r--templates/repo/issue/view_content/sidebar/milestones.tmpl22
-rw-r--r--templates/repo/issue/view_content/sidebar/participants.tmpl8
-rw-r--r--templates/repo/issue/view_content/sidebar/projects.tmpl54
-rw-r--r--templates/repo/issue/view_content/sidebar/pull_maintainer_edits.tmpl10
-rw-r--r--templates/repo/issue/view_content/sidebar/pull_review.tmpl45
-rw-r--r--templates/repo/issue/view_content/sidebar/pull_reviewers.tmpl67
-rw-r--r--templates/repo/issue/view_content/sidebar/pull_wip.tmpl11
-rw-r--r--templates/repo/issue/view_content/sidebar/reference.tmpl7
-rw-r--r--templates/repo/issue/view_content/sidebar/timetracking.tmpl73
-rw-r--r--templates/repo/issue/view_content/sidebar/watch.tmpl6
-rw-r--r--templates/repo/issue/view_content/sidebar/watching.tmpl19
-rw-r--r--templates/repo/issue/view_content/update_branch_by_merge.tmpl37
-rw-r--r--templates/repo/issue/view_title.tmpl145
66 files changed, 4071 insertions, 0 deletions
diff --git a/templates/repo/issue/card.tmpl b/templates/repo/issue/card.tmpl
new file mode 100644
index 00000000..4c22c283
--- /dev/null
+++ b/templates/repo/issue/card.tmpl
@@ -0,0 +1,78 @@
+{{with .Issue}}
+ {{if eq $.Page.Project.CardType 1}}{{/* Images and Text*/}}
+ {{$attachments := index $.Page.issuesAttachmentMap .ID}}
+ {{if $attachments}}
+ <div class="card-attachment-images">
+ {{range $attachments}}
+ <img src="{{.DownloadURL}}" alt="{{.Name}}" />
+ {{end}}
+ </div>
+ {{end}}
+ {{end}}
+ <div class="content tw-w-full">
+ <div class="tw-flex tw-items-start tw-gap-[5px]">
+ <div class="issue-card-icon">
+ {{template "shared/issueicon" .}}
+ </div>
+ <a class="issue-card-title muted issue-title tw-break-anywhere" href="{{.Link}}">{{.Title | RenderEmoji ctx | RenderCodeBlock}}</a>
+ {{if and $.isPinnedIssueCard $.Page.IsRepoAdmin}}
+ <a role="button" class="issue-card-unpin muted tw-flex tw-items-center" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin_issue"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}">
+ {{svg "octicon-x" 16}}
+ </a>
+ {{end}}
+ </div>
+ <div class="meta">
+ <span class="text light grey muted-links">
+ {{if not $.Page.Repository}}{{.Repo.FullName}}{{end}}#{{.Index}}
+ {{$timeStr := TimeSinceUnix .GetLastEventTimestamp ctx.Locale}}
+ {{if .OriginalAuthor}}
+ {{ctx.Locale.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor}}
+ {{else if gt .Poster.ID 0}}
+ {{ctx.Locale.Tr .GetLastEventLabel $timeStr .Poster.HomeLink .Poster.GetDisplayName}}
+ {{else}}
+ {{ctx.Locale.Tr .GetLastEventLabelFake $timeStr .Poster.GetDisplayName}}
+ {{end}}
+ </span>
+ </div>
+ {{if .MilestoneID}}
+ <div class="meta tw-my-1">
+ <a class="milestone" href="{{.Repo.Link}}/milestone/{{.MilestoneID}}">
+ {{svg "octicon-milestone" 16 "tw-mr-1 tw-align-middle"}}
+ <span class="tw-align-middle">{{.Milestone.Name}}</span>
+ </a>
+ </div>
+ {{end}}
+ {{if $.Page.LinkedPRs}}
+ {{range index $.Page.LinkedPRs .ID}}
+ <div class="meta tw-my-1">
+ <a href="{{$.Issue.Repo.Link}}/pulls/{{.Index}}">
+ <span class="tw-m-0 text {{if .PullRequest.HasMerged}}purple{{else if .IsClosed}}red{{else}}green{{end}}">{{svg "octicon-git-merge" 16 "tw-mr-1 tw-align-middle"}}</span>
+ <span class="tw-align-middle">{{.Title}} <span class="text light grey">#{{.Index}}</span></span>
+ </a>
+ </div>
+ {{end}}
+ {{end}}
+ {{$tasks := .GetTasks}}
+ {{if gt $tasks 0}}
+ <div class="meta tw-my-1">
+ {{svg "octicon-checklist" 16 "tw-mr-1 tw-align-middle"}}
+ <span class="tw-align-middle">{{.GetTasksDone}} / {{$tasks}}</span>
+ </div>
+ {{end}}
+ </div>
+
+ {{if or .Labels .Assignees}}
+ <div class="issue-card-bottom">
+ <div class="labels-list">
+ {{range .Labels}}
+ <a target="_blank" href="{{$.Issue.Repo.Link}}/issues?labels={{.ID}}">{{RenderLabel ctx ctx.Locale .}}</a>
+ {{end}}
+ </div>
+ <div class="issue-card-assignees">
+ {{range .Assignees}}
+ <a target="_blank" href="{{.HomeLink}}" data-tooltip-content="{{ctx.Locale.Tr "repo.projects.column.assigned_to"}} {{.Name}}">{{ctx.AvatarUtils.Avatar . 28}}</a>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+{{end}}
diff --git a/templates/repo/issue/choose.tmpl b/templates/repo/issue/choose.tmpl
new file mode 100644
index 00000000..38cf9e48
--- /dev/null
+++ b/templates/repo/issue/choose.tmpl
@@ -0,0 +1,59 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository new issue">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+ <div class="issue-navbar">
+ {{template "repo/issue/navbar" .}}
+ </div>
+ <div class="divider"></div>
+ {{range .IssueTemplates}}
+ <div class="ui attached segment">
+ <div class="ui two column grid">
+ <div class="column left aligned">
+ <strong>{{.Name}}</strong>
+ <br>{{.About}}
+ </div>
+ <div class="column right aligned">
+ <a href="{{$.RepoLink}}/issues/new?template={{.FileName}}{{if $.milestone}}&milestone={{$.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui primary button">{{ctx.Locale.Tr "repo.issues.choose.get_started"}}</a>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ {{range .IssueConfig.ContactLinks}}
+ <div class="ui attached segment">
+ <div class="ui two column grid">
+ <div class="column left aligned">
+ <strong>{{.Name}}</strong>
+ <br>{{.About}}
+ </div>
+ <div class="column right aligned">
+ <a href="{{.URL}}" class="ui primary button">{{svg "octicon-link-external"}} {{ctx.Locale.Tr "repo.issues.choose.open_external_link"}}</a>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ {{if .IssueConfig.BlankIssuesEnabled}}
+ <div class="ui attached segment">
+ <div class="ui two column grid">
+ <div class="column left aligned">
+ <strong>{{ctx.Locale.Tr "repo.issues.choose.blank"}}</strong>
+ <br/>{{ctx.Locale.Tr "repo.issues.choose.blank_about"}}
+ </div>
+ <div class="column right aligned">
+ <a href="{{.RepoLink}}/issues/new?{{if .milestone}}&milestone={{.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui primary button">{{ctx.Locale.Tr "repo.issues.choose.get_started"}}</a>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ {{- if .IssueConfigError}}{{/* normal warning flash makes problems here*/}}
+ <div class="ui warning message">
+ <div class="text left">
+ <div>{{ctx.Locale.Tr "repo.issues.choose.invalid_config"}}</div>
+ <div>{{.IssueConfigError}}</div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/comment_tab.tmpl b/templates/repo/issue/comment_tab.tmpl
new file mode 100644
index 00000000..4197ea4f
--- /dev/null
+++ b/templates/repo/issue/comment_tab.tmpl
@@ -0,0 +1,21 @@
+{{$textareaContent := .BodyQuery}}
+{{if not $textareaContent}}{{$textareaContent = .IssueTemplate}}{{end}}
+{{if not $textareaContent}}{{$textareaContent = .PullRequestTemplate}}{{end}}
+{{if not $textareaContent}}{{$textareaContent = .content}}{{end}}
+
+<div class="field">
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewUrl" (print .Repository.Link "/markup")
+ "MarkdownPreviewContext" .RepoLink
+ "TextareaName" "content"
+ "TextareaContent" $textareaContent
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
+ "DropzoneParentContainer" "form, .ui.form"
+ )}}
+</div>
+
+{{if .IsAttachmentEnabled}}
+ <div class="field">
+ {{template "repo/upload" .}}
+ </div>
+{{end}}
diff --git a/templates/repo/issue/fields/checkboxes.tmpl b/templates/repo/issue/fields/checkboxes.tmpl
new file mode 100644
index 00000000..531f401f
--- /dev/null
+++ b/templates/repo/issue/fields/checkboxes.tmpl
@@ -0,0 +1,14 @@
+<div class="field {{if not .item.VisibleOnForm}}tw-hidden{{end}}">
+ {{template "repo/issue/fields/header" .}}
+ {{range $i, $opt := .item.Attributes.options}}
+ <div class="field inline">
+ <div class="ui checkbox tw-mr-0 {{if and ($opt.visible) (not (SliceUtils.Contains $opt.visible "form"))}}tw-hidden{{end}}">
+ <input type="checkbox" name="form-field-{{$.item.ID}}-{{$i}}" {{if $opt.required}}required{{end}}>
+ <label>{{RenderMarkdownToHtml $.context $opt.label}}</label>
+ </div>
+ {{if $opt.required}}
+ <label class="required"></label>
+ {{end}}
+ </div>
+ {{end}}
+</div>
diff --git a/templates/repo/issue/fields/dropdown.tmpl b/templates/repo/issue/fields/dropdown.tmpl
new file mode 100644
index 00000000..26505f58
--- /dev/null
+++ b/templates/repo/issue/fields/dropdown.tmpl
@@ -0,0 +1,17 @@
+<div class="field {{if not .item.VisibleOnForm}}tw-hidden{{end}}">
+ {{template "repo/issue/fields/header" .}}
+ {{/* FIXME: required validation */}}
+ <div class="ui fluid selection dropdown {{if .item.Attributes.multiple}}multiple clearable{{end}}">
+ <input type="hidden" name="form-field-{{.item.ID}}" value="{{.item.Attributes.default}}">
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ {{if not .item.Validations.required}}
+ {{svg "octicon-x" 14 "remove icon"}}
+ {{end}}
+ <div class="default text"></div>
+ <div class="menu">
+ {{range $i, $opt := .item.Attributes.options}}
+ <div class="item" data-value="{{$i}}">{{$opt}}</div>
+ {{end}}
+ </div>
+ </div>
+</div>
diff --git a/templates/repo/issue/fields/header.tmpl b/templates/repo/issue/fields/header.tmpl
new file mode 100644
index 00000000..6034fed5
--- /dev/null
+++ b/templates/repo/issue/fields/header.tmpl
@@ -0,0 +1,6 @@
+{{if .item.Attributes.label}}
+ <h3>{{.item.Attributes.label}}{{if .item.Validations.required}}<label class="required"></label>{{end}}</h3>
+{{end}}
+{{if .item.Attributes.description}}
+ <span class="help">{{RenderMarkdownToHtml .Context .item.Attributes.description}}</span>
+{{end}}
diff --git a/templates/repo/issue/fields/input.tmpl b/templates/repo/issue/fields/input.tmpl
new file mode 100644
index 00000000..039f9a9f
--- /dev/null
+++ b/templates/repo/issue/fields/input.tmpl
@@ -0,0 +1,4 @@
+<div class="field {{if not .item.VisibleOnForm}}tw-hidden{{end}}">
+ {{template "repo/issue/fields/header" .}}
+ <input type="{{if .item.Validations.is_number}}number{{else}}text{{end}}" name="form-field-{{.item.ID}}" placeholder="{{.item.Attributes.placeholder}}" value="{{.item.Attributes.value}}" {{if .item.Validations.required}}required{{end}} {{if .item.Validations.regex}}pattern="{{.item.Validations.regex}}" title="{{.item.Validations.regex}}"{{end}}>
+</div>
diff --git a/templates/repo/issue/fields/markdown.tmpl b/templates/repo/issue/fields/markdown.tmpl
new file mode 100644
index 00000000..934699ed
--- /dev/null
+++ b/templates/repo/issue/fields/markdown.tmpl
@@ -0,0 +1,3 @@
+<div class="field {{if not .item.VisibleOnForm}}tw-hidden{{end}}">
+ <div>{{RenderMarkdownToHtml .Context .item.Attributes.value}}</div>
+</div>
diff --git a/templates/repo/issue/fields/textarea.tmpl b/templates/repo/issue/fields/textarea.tmpl
new file mode 100644
index 00000000..3ad69e12
--- /dev/null
+++ b/templates/repo/issue/fields/textarea.tmpl
@@ -0,0 +1,24 @@
+{{$useMarkdownEditor := not .item.Attributes.render}}
+<div class="field {{if not .item.VisibleOnForm}}tw-hidden{{end}} {{if $useMarkdownEditor}}combo-editor-dropzone{{end}}">
+ {{template "repo/issue/fields/header" .}}
+
+ {{/* the real form element to provide the value */}}
+ <textarea class="form-field-real" name="form-field-{{.item.ID}}" placeholder="{{.item.Attributes.placeholder}}" {{if and .item.Validations.required}}required{{end}}>{{.item.Attributes.value}}</textarea>
+
+ {{if $useMarkdownEditor}}
+ {{template "shared/combomarkdowneditor" (dict
+ "ContainerClasses" "tw-hidden"
+ "MarkdownPreviewUrl" (print .root.RepoLink "/markup")
+ "MarkdownPreviewContext" .root.RepoLink
+ "TextareaContent" .item.Attributes.value
+ "TextareaPlaceholder" .item.Attributes.placeholder
+ "DropzoneParentContainer" ".combo-editor-dropzone"
+ )}}
+
+ {{if .root.IsAttachmentEnabled}}
+ <div class="tw-mt-4 form-field-dropzone tw-hidden">
+ {{template "repo/upload" .root}}
+ </div>
+ {{end}}
+ {{end}}
+</div>
diff --git a/templates/repo/issue/filter_actions.tmpl b/templates/repo/issue/filter_actions.tmpl
new file mode 100644
index 00000000..a341448b
--- /dev/null
+++ b/templates/repo/issue/filter_actions.tmpl
@@ -0,0 +1,128 @@
+<div class="ui secondary filter menu">
+ {{if not .Repository.IsArchived}}
+ <!-- Action Button -->
+ {{if .IsShowClosed}}
+ <button class="ui primary basic button issue-action" data-action="open" data-url="{{$.RepoLink}}/issues/status">{{ctx.Locale.Tr "repo.issues.action_open"}}</button>
+ {{else}}
+ <button class="ui red basic button issue-action" data-action="close" data-url="{{$.RepoLink}}/issues/status">{{ctx.Locale.Tr "repo.issues.action_close"}}</button>
+ {{end}}
+ {{if $.IsRepoAdmin}}
+ <button class="ui red button issue-action"
+ data-action="delete" data-url="{{$.RepoLink}}/issues/delete"
+ data-action-delete-confirm="{{ctx.Locale.Tr "confirm_delete_selected"}}"
+ >{{ctx.Locale.Tr "repo.issues.delete"}}</button>
+ {{end}}
+ <!-- Labels -->
+ <div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.action_label"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="item issue-action" data-action="clear" data-url="{{$.RepoLink}}/issues/labels">
+ {{ctx.Locale.Tr "repo.issues.new.clear_labels"}}
+ </div>
+ {{$previousExclusiveScope := "_no_scope"}}
+ {{range .Labels}}
+ {{$exclusiveScope := .ExclusiveScope}}
+ {{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
+ <div class="divider"></div>
+ {{end}}
+ {{$previousExclusiveScope = $exclusiveScope}}
+ <div class="item issue-action tw-flex tw-justify-between" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels">
+ {{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context ctx.Locale .}}
+ {{template "repo/issue/labels/label_archived" .}}
+ </div>
+ {{end}}
+ </div>
+ </div>
+
+ <!-- Milestone -->
+ <div class="ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.action_milestone"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/milestone">
+ {{ctx.Locale.Tr "repo.issues.action_milestone_no_select"}}
+ </div>
+ {{if .OpenMilestones}}
+ <div class="divider"></div>
+ <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div>
+ {{range .OpenMilestones}}
+ <div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/milestone">
+ {{.Name}}
+ </div>
+ {{end}}
+ {{end}}
+ {{if .ClosedMilestones}}
+ <div class="divider"></div>
+ <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}</div>
+ {{range .ClosedMilestones}}
+ <div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/milestone">
+ {{.Name}}
+ </div>
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+
+ <!-- Projects -->
+ <div class="ui{{if not (or .OpenProjects .ClosedProjects)}} disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.projects"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/projects">
+ {{ctx.Locale.Tr "repo.issues.new.clear_projects"}}
+ </div>
+ {{if .OpenProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.open_projects"}}
+ </div>
+ {{range .OpenProjects}}
+ <div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/projects">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </div>
+ {{end}}
+ {{end}}
+ {{if .ClosedProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.closed_projects"}}
+ </div>
+ {{range .ClosedProjects}}
+ <div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/projects">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </div>
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+
+ <!-- Assignees -->
+ <div class="ui {{if not .Assignees}}disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.action_assignee"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="item issue-action" data-action="clear" data-url="{{$.Link}}/assignee">
+ {{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}
+ </div>
+ <div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/assignee">
+ {{ctx.Locale.Tr "repo.issues.action_assignee_no_select"}}
+ </div>
+ {{range .Assignees}}
+ <div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/assignee">
+ {{ctx.AvatarUtils.Avatar . 20}} {{.GetDisplayName}}
+ </div>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+</div>
+
diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl
new file mode 100644
index 00000000..09f87b58
--- /dev/null
+++ b/templates/repo/issue/filter_list.tmpl
@@ -0,0 +1,158 @@
+<!-- Label -->
+{{template "shared/label_filter" .}}
+
+{{if not .Milestone}}
+<!-- Milestone -->
+<div class="list-header-milestone ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_milestone"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_milestone"}}">
+ </div>
+ <div class="divider"></div>
+ <a rel="nofollow" class="{{if not $.MilestoneID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=0&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_all"}}</a>
+ <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID -1}}active selected {{end}}{{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=-1&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_none"}}</a>
+ {{if .OpenMilestones}}
+ <div class="divider"></div>
+ <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div>
+ {{range .OpenMilestones}}
+ <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">
+ {{svg "octicon-milestone" 16 "mr-2"}}
+ {{.Name}}
+ </a>
+ {{end}}
+ {{end}}
+ {{if .ClosedMilestones}}
+ <div class="divider"></div>
+ <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}</div>
+ {{range .ClosedMilestones}}
+ <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">
+ {{svg "octicon-milestone" 16 "mr-2"}}
+ {{.Name}}
+ </a>
+ {{end}}
+ {{end}}
+ </div>
+</div>
+{{end}}
+
+<!-- Project -->
+<div class="list-header-project ui{{if not (or .OpenProjects .ClosedProjects)}} disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_project"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_project"}}">
+ </div>
+ <a rel="nofollow" class="{{if not .ProjectID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project=&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_all"}}</a>
+ <a rel="nofollow" class="{{if eq .ProjectID -1}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project=-1&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_none"}}</a>
+ {{if .OpenProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.open_projects"}}
+ </div>
+ {{range .OpenProjects}}
+ <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item tw-flex" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">
+ {{svg .IconName 18 "tw-mr-2 tw-shrink-0"}}<span class="gt-ellipsis">{{.Title}}</span>
+ </a>
+ {{end}}
+ {{end}}
+ {{if .ClosedProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.closed_projects"}}
+ </div>
+ {{range .ClosedProjects}}
+ <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </a>
+ {{end}}
+ {{end}}
+ </div>
+</div>
+
+<!-- Author -->
+<div class="list-header-author ui dropdown jump item user-remote-search" data-tooltip-content="{{ctx.Locale.Tr "repo.author_search_tooltip"}}"
+ data-search-url="{{if .Milestone}}{{$.RepoLink}}/issues/posters{{else}}{{$.Link}}/posters{{end}}"
+ data-selected-user-id="{{$.PosterID}}"
+ data-action-jump-url="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&fuzzy={{$.IsFuzzy}}&poster={user_id}{{if $.ShowArchivedLabels}}&archived=true{{end}}"
+>
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_poster"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_poster"}}">
+ </div>
+ <a class="item" data-value="0">{{ctx.Locale.Tr "repo.issues.filter_poster_no_select"}}</a>
+ </div>
+</div>
+
+<!-- Assignee -->
+<div class="list-header-assignee ui {{if not .Assignees}}disabled{{end}} dropdown jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_assignee"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignee"}}">
+ </div>
+ <a rel="nofollow" class="{{if not .AssigneeID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee=&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_select"}}</a>
+ <a rel="nofollow" class="{{if eq .AssigneeID -1}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee=-1&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a>
+ <div class="divider"></div>
+ {{range .Assignees}}
+ <a rel="nofollow" class="{{if eq $.AssigneeID .ID}}active selected{{end}} item tw-flex" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{.ID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">
+ {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}}
+ </a>
+ {{end}}
+ </div>
+</div>
+
+{{if .IsSigned}}
+ <!-- Type -->
+ <div class="list-header-type ui dropdown type jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_type"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <a rel="nofollow" class="{{if eq .ViewType "all"}}active {{end}}item" href="?q={{$.Keyword}}&type=all&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.all_issues"}}</a>
+ <a rel="nofollow" class="{{if eq .ViewType "assigned"}}active {{end}}item" href="?q={{$.Keyword}}&type=assigned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}}</a>
+ <a rel="nofollow" class="{{if eq .ViewType "created_by"}}active {{end}}item" href="?q={{$.Keyword}}&type=created_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}}</a>
+ {{if .PageIsPullList}}
+ <a rel="nofollow" class="{{if eq .ViewType "review_requested"}}active {{end}}item" href="?q={{$.Keyword}}&type=review_requested&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}}</a>
+ <a rel="nofollow" class="{{if eq .ViewType "reviewed_by"}}active {{end}}item" href="?q={{$.Keyword}}&type=reviewed_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}}</a>
+ {{end}}
+ <a rel="nofollow" class="{{if eq .ViewType "mentioned"}}active {{end}}item" href="?q={{$.Keyword}}&type=mentioned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}}</a>
+ </div>
+ </div>
+{{end}}
+
+<!-- Sort -->
+<div class="list-header-sort ui dropdown downward type jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_sort"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <a rel="nofollow" class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=latest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "oldest"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=oldest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a>
+ <a rel="nofollow" class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=farduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a>
+ </div>
+</div>
diff --git a/templates/repo/issue/filters.tmpl b/templates/repo/issue/filters.tmpl
new file mode 100644
index 00000000..06e7c1aa
--- /dev/null
+++ b/templates/repo/issue/filters.tmpl
@@ -0,0 +1,26 @@
+<div id="issue-filters" class="issue-list-toolbar">
+ <div class="issue-list-toolbar-left">
+ {{if and $.CanWriteIssuesOrPulls .Issues}}
+ <input type="checkbox" autocomplete="off" class="issue-checkbox-all tw-mr-4" title="{{ctx.Locale.Tr "repo.issues.action_check_all"}}">
+ {{end}}
+ {{template "repo/issue/openclose" .}}
+ <!-- Total Tracked Time -->
+ {{if .TotalTrackedTime}}
+ <div class="ui compact tiny secondary menu">
+ <span class="item" data-tooltip-content='{{ctx.Locale.Tr "tracked_time_summary"}}'>
+ {{svg "octicon-clock"}}
+ {{.TotalTrackedTime | Sec2Time}}
+ </span>
+ </div>
+ {{end}}
+ </div>
+ <div class="issue-list-toolbar-right">
+ <div class="ui secondary filter menu labels">
+ {{if .PageIsMilestones}}
+ {{template "repo/issue/milestone/filter_list" .}}
+ {{else}}
+ {{template "repo/issue/filter_list" .}}
+ {{end}}
+ </div>
+ </div>
+</div>
diff --git a/templates/repo/issue/label_precolors.tmpl b/templates/repo/issue/label_precolors.tmpl
new file mode 100644
index 00000000..80007662
--- /dev/null
+++ b/templates/repo/issue/label_precolors.tmpl
@@ -0,0 +1,22 @@
+<div class="precolors">
+ <div class="tw-flex">
+ <a class="color" style="background-color:#e11d21" data-color-hex="#e11d21"></a>
+ <a class="color" style="background-color:#eb6420" data-color-hex="#eb6420"></a>
+ <a class="color" style="background-color:#fbca04" data-color-hex="#fbca04"></a>
+ <a class="color" style="background-color:#009800" data-color-hex="#009800"></a>
+ <a class="color" style="background-color:#006b75" data-color-hex="#006b75"></a>
+ <a class="color" style="background-color:#207de5" data-color-hex="#207de5"></a>
+ <a class="color" style="background-color:#0052cc" data-color-hex="#0052cc"></a>
+ <a class="color" style="background-color:#5319e7" data-color-hex="#5319e7"></a>
+ </div>
+ <div class="tw-flex">
+ <a class="color" style="background-color:#f6c6c7" data-color-hex="#f6c6c7"></a>
+ <a class="color" style="background-color:#fad8c7" data-color-hex="#fad8c7"></a>
+ <a class="color" style="background-color:#fef2c0" data-color-hex="#fef2c0"></a>
+ <a class="color" style="background-color:#bfe5bf" data-color-hex="#bfe5bf"></a>
+ <a class="color" style="background-color:#bfdadc" data-color-hex="#bfdadc"></a>
+ <a class="color" style="background-color:#c7def8" data-color-hex="#c7def8"></a>
+ <a class="color" style="background-color:#bfd4f2" data-color-hex="#bfd4f2"></a>
+ <a class="color" style="background-color:#d4c5f9" data-color-hex="#d4c5f9"></a>
+ </div>
+</div>
diff --git a/templates/repo/issue/labels.tmpl b/templates/repo/issue/labels.tmpl
new file mode 100644
index 00000000..230777ef
--- /dev/null
+++ b/templates/repo/issue/labels.tmpl
@@ -0,0 +1,22 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository labels">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ <div class="issue-navbar tw-mb-4">
+ {{template "repo/issue/navbar" .}}
+ {{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
+ <button class="ui small primary new-label button">{{ctx.Locale.Tr "repo.issues.new_label"}}</button>
+ {{end}}
+ </div>
+ {{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
+ {{template "repo/issue/labels/label_new" .}}
+ {{end}}
+ {{template "base/alert" .}}
+ {{template "repo/issue/labels/label_list" .}}
+ </div>
+</div>
+
+{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
+ {{template "repo/issue/labels/edit_delete_label" .}}
+{{end}}
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/labels/edit_delete_label.tmpl b/templates/repo/issue/labels/edit_delete_label.tmpl
new file mode 100644
index 00000000..fcf69217
--- /dev/null
+++ b/templates/repo/issue/labels/edit_delete_label.tmpl
@@ -0,0 +1,72 @@
+<div class="ui g-modal-confirm delete modal">
+ <div class="header">
+ {{svg "octicon-trash"}}
+ {{ctx.Locale.Tr "repo.issues.label_deletion"}}
+ </div>
+ <div class="content">
+ <p>{{ctx.Locale.Tr "repo.issues.label_deletion_desc"}}</p>
+ </div>
+ {{template "base/modal_actions_confirm" .}}
+</div>
+
+<div class="ui small edit-label modal">
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.label_modify"}}
+ </div>
+ <div class="content">
+ <form class="ui edit-label form ignore-dirty" action="{{$.Link}}/edit" method="post">
+ {{.CsrfTokenHtml}}
+ <input id="label-modal-id" name="id" type="hidden">
+ <div class="required field">
+ <label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
+ <div class="ui small input">
+ <input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
+ </div>
+ </div>
+ <div class="field label-exclusive-input-field">
+ <div class="ui checkbox">
+ <input class="label-exclusive-input" name="exclusive" type="checkbox">
+ <label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
+ </div>
+ <br>
+ <small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
+ <div class="desc tw-ml-1 tw-mt-2 tw-hidden label-exclusive-warning">
+ {{svg "octicon-alert"}} {{ctx.Locale.Tr "repo.issues.label_exclusive_warning"}}
+ </div>
+ <br>
+ </div>
+ <div class="field label-is-archived-input-field">
+ <div class="ui checkbox">
+ <input class="label-is-archived-input" name="is_archived" type="checkbox">
+ <label>{{ctx.Locale.Tr "repo.issues.label_archive"}}</label>
+ </div>
+ <i class="tw-ml-1" data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}>
+ {{svg "octicon-info"}}
+ </i>
+ </div>
+ <div class="field">
+ <label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
+ <div class="ui small fluid input">
+ <input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
+ </div>
+ </div>
+ <div class="field color-field">
+ <label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
+ <div class="column js-color-picker-input">
+ <input name="color" value="#70c24a"placeholder="#c320f6" required maxlength="7">
+ {{template "repo/issue/label_precolors"}}
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="actions">
+ <button class="ui small basic cancel button">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "cancel"}}
+ </button>
+ <button class="ui primary small approve button">
+ {{svg "fontawesome-save"}}
+ {{ctx.Locale.Tr "save"}}
+ </button>
+ </div>
+</div>
diff --git a/templates/repo/issue/labels/label.tmpl b/templates/repo/issue/labels/label.tmpl
new file mode 100644
index 00000000..3651ba11
--- /dev/null
+++ b/templates/repo/issue/labels/label.tmpl
@@ -0,0 +1,7 @@
+<a
+ class="item {{if not .label.IsChecked}}tw-hidden{{end}}"
+ id="label_{{.label.ID}}"
+ href="{{.root.RepoLink}}/{{if or .root.IsPull .root.Issue.IsPull}}pulls{{else}}issues{{end}}?labels={{.label.ID}}"{{/* FIXME: use .root.Issue.Link or create .root.Link */}}
+>
+ {{- RenderLabel $.Context ctx.Locale .label -}}
+</a>
diff --git a/templates/repo/issue/labels/label_archived.tmpl b/templates/repo/issue/labels/label_archived.tmpl
new file mode 100644
index 00000000..feaf77e4
--- /dev/null
+++ b/templates/repo/issue/labels/label_archived.tmpl
@@ -0,0 +1,5 @@
+{{if .IsArchived}}
+ <span class="ui label basic small" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}">
+ {{ctx.Locale.Tr "archived"}}
+ </span>
+{{end}}
diff --git a/templates/repo/issue/labels/label_list.tmpl b/templates/repo/issue/labels/label_list.tmpl
new file mode 100644
index 00000000..8d7fc2c3
--- /dev/null
+++ b/templates/repo/issue/labels/label_list.tmpl
@@ -0,0 +1,88 @@
+<h4 class="ui top attached header">
+ {{ctx.Locale.Tr "repo.issues.label_count" .NumLabels}}
+ <div class="ui right">
+ <div class="ui secondary menu">
+ <!-- Sort -->
+ <div class="item ui jump dropdown tw-py-2">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_sort"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <a class="{{if or (eq .SortType "alphabetically") (not .SortType)}}active {{end}}item" href="?sort=alphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a>
+ <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="?sort=reversealphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a>
+ <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="?sort=leastissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a>
+ <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="?sort=mostissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a>
+ </div>
+ </div>
+ </div>
+ </div> <!-- filter menu -->
+</h4>
+
+<div class="ui attached segment">
+ {{if and (not $.PageIsOrgSettingsLabels) (or $.CanWriteIssues $.CanWritePulls) (eq .NumLabels 0) (not $.Repository.IsArchived)}}
+ {{template "repo/issue/labels/label_load_template" .}}
+ <div class="divider"></div>
+ {{else if and ($.PageIsOrgSettingsLabels) (eq .NumLabels 0)}}
+ {{template "repo/issue/labels/label_load_template" .}}
+ <div class="divider"></div>
+ {{end}}
+
+ <ul class="issue-label-list">
+ {{range .Labels}}
+ <li class="item">
+ <div class="label-title">
+ {{RenderLabel $.Context ctx.Locale .}}
+ {{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
+ </div>
+ <div class="label-issues">
+ {{if $.PageIsOrgSettingsLabels}}
+ <a class="open-issues" href="{{AppSubUrl}}/issues?labels={{.ID}}">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a>
+ {{else}}
+ <a class="open-issues" href="{{$.RepoLink}}/issues?labels={{.ID}}">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a>
+ {{end}}
+ </div>
+ <div class="label-operation tw-flex">
+ {{template "repo/issue/labels/label_archived" .}}
+ <div class="tw-flex tw-ml-auto">
+ {{if and (not $.PageIsOrgSettingsLabels) (not $.Repository.IsArchived) (or $.CanWriteIssues $.CanWritePulls)}}
+ <a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} {{if gt .ArchivedUnix 0}}data-is-archived{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{ctx.Locale.Tr "repo.issues.label_edit"}}</a>
+ <a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.issues.label_delete"}}</a>
+ {{else if $.PageIsOrgSettingsLabels}}
+ <a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} {{if gt .ArchivedUnix 0}}data-is-archived{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{ctx.Locale.Tr "repo.issues.label_edit"}}</a>
+ <a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.issues.label_delete"}}</a>
+ {{end}}
+ </div>
+ </div>
+ </li>
+ {{end}}
+
+ {{if and (not .PageIsOrgSettingsLabels) (.OrgLabels)}}
+ <li class="item">
+ <div class="ui grid middle aligned">
+ <div class="ten wide column">
+ {{ctx.Locale.Tr "repo.org_labels_desc"}}
+ {{if .IsOrganizationOwner}}
+ <a href="{{.OrganizationLink}}/settings/labels">({{ctx.Locale.Tr "repo.org_labels_desc_manage"}})</a>:
+ {{end}}
+ </div>
+ </div>
+ </li>
+
+ {{range .OrgLabels}}
+ <li class="item org-label">
+ <div class="label-title">
+ {{RenderLabel $.Context ctx.Locale .}}
+ {{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
+ </div>
+ <div class="label-issues">
+ <a class="open-issues" {{if .IsArchived}}data-is-archived{{end}} href="{{$.RepoLink}}/issues?labels={{.ID}}">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.label_open_issues" .NumOpenRepoIssues}}</a>
+ </div>
+ <div class="label-operation">
+ {{template "repo/issue/labels/label_archived" .}}
+ </div>
+ </li>
+ {{end}}
+ {{end}}
+ </ul>
+</div>
diff --git a/templates/repo/issue/labels/label_load_template.tmpl b/templates/repo/issue/labels/label_load_template.tmpl
new file mode 100644
index 00000000..02494300
--- /dev/null
+++ b/templates/repo/issue/labels/label_load_template.tmpl
@@ -0,0 +1,24 @@
+<div class="ui centered grid">
+ <div class="twelve wide computer column">
+ <div class="ui attached left aligned segment">
+ <p>{{ctx.Locale.Tr "repo.issues.label_templates.info"}}</p>
+ <br>
+ <form class="ui form center" action="{{.Link}}/initialize" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="field">
+ <div class="ui selection dropdown">
+ <input type="hidden" name="template_name" value="Default">
+ <div class="default text">{{ctx.Locale.Tr "repo.issues.label_templates.helper"}}</div>
+ <div class="menu">
+ {{range .LabelTemplateFiles}}
+ <div class="item" data-value="{{.DisplayName}}">{{.DisplayName}}<br><p>({{.Description}})</p></div>
+ {{end}}
+ </div>
+ {{svg "octicon-triangle-down" 18 "dropdown icon"}}
+ </div>
+ </div>
+ <button type="submit" class="ui primary button">{{ctx.Locale.Tr "repo.issues.label_templates.use"}}</button>
+ </form>
+ </div>
+ </div>
+</div>
diff --git a/templates/repo/issue/labels/label_new.tmpl b/templates/repo/issue/labels/label_new.tmpl
new file mode 100644
index 00000000..32fd8e76
--- /dev/null
+++ b/templates/repo/issue/labels/label_new.tmpl
@@ -0,0 +1,48 @@
+<div class="ui small new-label modal">
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new_label"}}
+ </div>
+ <div class="content">
+ <form class="ui new-label form ignore-dirty" action="{{$.Link}}/new" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required field">
+ <label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
+ <div class="ui small input">
+ <input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
+ </div>
+ </div>
+ <div class="field label-exclusive-input-field">
+ <div class="ui checkbox">
+ <input class="label-exclusive-input" name="exclusive" type="checkbox">
+ <label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
+ </div>
+ <br>
+ <small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
+ </div>
+ <div class="field">
+ <label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
+ <div class="ui small fluid input">
+ <input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
+ </div>
+ </div>
+ <div class="field color-field">
+ <label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
+ <div class="js-color-picker-input column">
+ <input name="color" value="#70c24a" placeholder="#c320f6" required maxlength="7">
+ {{template "repo/issue/label_precolors"}}
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div class="actions">
+ <button class="ui cancel button">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "cancel"}}
+ </button>
+ <button class="ui primary ok button">
+ {{svg "octicon-check"}}
+ {{ctx.Locale.Tr "repo.issues.create_label"}}
+ </button>
+ </div>
+</div>
diff --git a/templates/repo/issue/labels/labels_selector_field.tmpl b/templates/repo/issue/labels/labels_selector_field.tmpl
new file mode 100644
index 00000000..9e54e7a6
--- /dev/null
+++ b/templates/repo/issue/labels/labels_selector_field.tmpl
@@ -0,0 +1,46 @@
+<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-label dropdown">
+ <span class="text muted flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.labels"}}</strong>
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </span>
+ <div class="filter menu ugc-labels" {{if .Issue}}data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/labels"{{else}}data-id="#label_ids"{{end}}>
+ {{if or .Labels .OrgLabels}}
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input class="tw-w-auto" type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_labels"}}">
+ </div>
+ {{end}}
+ <a class="no-select item" href="#">{{ctx.Locale.Tr "repo.issues.new.clear_labels"}}</a>
+ {{if or .Labels .OrgLabels}}
+ {{$previousExclusiveScope := "_no_scope"}}
+ {{range .Labels}}
+ {{$exclusiveScope := .ExclusiveScope}}
+ {{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
+ <div class="divider"></div>
+ {{end}}
+ {{$previousExclusiveScope = $exclusiveScope}}
+ <a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context ctx.Locale .}}
+ {{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
+ <p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
+ </a>
+ {{end}}
+ <div class="divider"></div>
+ {{$previousExclusiveScope = "_no_scope"}}
+ {{range .OrgLabels}}
+ {{$exclusiveScope := .ExclusiveScope}}
+ {{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
+ <div class="divider"></div>
+ {{end}}
+ {{$previousExclusiveScope = $exclusiveScope}}
+ <a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context ctx.Locale .}}
+ {{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
+ <p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
+ </a>
+ {{end}}
+ {{else}}
+ <div class="disabled item">{{ctx.Locale.Tr "repo.issues.new.no_items"}}</div>
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/issue/labels/labels_sidebar.tmpl b/templates/repo/issue/labels/labels_sidebar.tmpl
new file mode 100644
index 00000000..81fc9709
--- /dev/null
+++ b/templates/repo/issue/labels/labels_sidebar.tmpl
@@ -0,0 +1,11 @@
+<div class="ui labels list">
+ <span class="no-select {{if .root.HasSelectedLabel}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_label"}}</span>
+ <span class="labels-list ugc-labels">
+ {{range .root.Labels}}
+ {{template "repo/issue/labels/label" dict "root" $.root "label" .}}
+ {{end}}
+ {{range .root.OrgLabels}}
+ {{template "repo/issue/labels/label" dict "root" $.root "label" .}}
+ {{end}}
+ </span>
+</div>
diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl
new file mode 100644
index 00000000..8c81bf02
--- /dev/null
+++ b/templates/repo/issue/list.tmpl
@@ -0,0 +1,55 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository issue-list">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+
+ {{if .PinnedIssues}}
+ <div id="issue-pins" {{if .IsRepoAdmin}}data-is-repo-admin{{end}}>
+ {{range .PinnedIssues}}
+ <div class="issue-card tw-break-anywhere {{if $.IsRepoAdmin}}tw-cursor-grab{{end}}" data-move-url="{{$.Link}}/move_pin" data-issue-id="{{.ID}}">
+ {{template "repo/issue/card" (dict "Issue" . "Page" $ "isPinnedIssueCard" true)}}
+ </div>
+ {{end}}
+ </div>
+ {{end}}
+
+ <div class="list-header list-header-issues">
+ {{template "repo/issue/navbar" .}}
+ {{template "repo/issue/search" .}}
+ {{if not .Repository.IsArchived}}
+ {{if .PageIsIssueList}}
+ <a class="ui small primary button issue-list-new" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
+ {{else}}
+ <a class="ui small primary button new-pr-button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.Repository.Link}}/compare/{{.Repository.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{ctx.Locale.Tr "repo.pulls.new"}}</a>
+ {{end}}
+ {{else}}
+ {{if not .PageIsIssueList}}
+ <a class="ui small primary small button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.PullRequestCtx.BaseRepo.Link}}/compare/{{.PullRequestCtx.BaseRepo.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{ctx.Locale.Tr "action.compare_commits_general"}}</a>
+ {{end}}
+ {{end}}
+ </div>
+
+ {{template "repo/issue/filters" .}}
+
+ <div id="issue-actions" class="issue-list-toolbar tw-hidden">
+ <div class="issue-list-toolbar-left">
+ {{template "repo/issue/openclose" .}}
+ <!-- Total Tracked Time -->
+ {{if .TotalTrackedTime}}
+ <div class="ui compact tiny secondary menu">
+ <span class="item" data-tooltip-content='{{ctx.Locale.Tr "tracked_time_summary"}}'>
+ {{svg "octicon-clock"}}
+ {{.TotalTrackedTime | Sec2Time}}
+ </span>
+ </div>
+ {{end}}
+ </div>
+ <div class="issue-list-toolbar-right">
+ {{template "repo/issue/filter_actions" .}}
+ </div>
+ </div>
+ {{template "shared/issuelist" dict "." . "listType" "repo"}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/milestone/filter_list.tmpl b/templates/repo/issue/milestone/filter_list.tmpl
new file mode 100644
index 00000000..ecfb95bb
--- /dev/null
+++ b/templates/repo/issue/milestone/filter_list.tmpl
@@ -0,0 +1,15 @@
+<!-- Sort -->
+<div class="list-header-sort ui dropdown type jump item">
+ <span class="text">
+ {{ctx.Locale.Tr "repo.issues.filter_sort"}}
+ </span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="?sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a>
+ <a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="?sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a>
+ <a class="{{if eq .SortType "leastcomplete"}}active {{end}}item" href="?sort=leastcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_complete"}}</a>
+ <a class="{{if eq .SortType "mostcomplete"}}active {{end}}item" href="?sort=mostcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_complete"}}</a>
+ <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="?sort=mostissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a>
+ <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="?sort=leastissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a>
+ </div>
+</div>
diff --git a/templates/repo/issue/milestone/select_menu.tmpl b/templates/repo/issue/milestone/select_menu.tmpl
new file mode 100644
index 00000000..9b0492ce
--- /dev/null
+++ b/templates/repo/issue/milestone/select_menu.tmpl
@@ -0,0 +1,38 @@
+{{if or .OpenMilestones .ClosedMilestones}}
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_milestones"}}">
+ </div>
+ <div class="divider"></div>
+{{end}}
+<div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
+{{if and (not .OpenMilestones) (not .ClosedMilestones)}}
+ <div class="disabled item">
+ {{ctx.Locale.Tr "repo.issues.new.no_items"}}
+ </div>
+{{else}}
+ {{if .OpenMilestones}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.open_milestone"}}
+ </div>
+ {{range .OpenMilestones}}
+ <a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
+ {{svg "octicon-milestone" 16 "tw-mr-1"}}
+ {{.Name}}
+ </a>
+ {{end}}
+ {{end}}
+ {{if .ClosedMilestones}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.closed_milestone"}}
+ </div>
+ {{range .ClosedMilestones}}
+ <a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
+ {{svg "octicon-milestone" 16 "tw-mr-1"}}
+ {{.Name}}
+ </a>
+ {{end}}
+ {{end}}
+{{end}}
diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl
new file mode 100644
index 00000000..e5dc8cb6
--- /dev/null
+++ b/templates/repo/issue/milestone_issues.tmpl
@@ -0,0 +1,65 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository milestone-issue-list">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+ <div class="tw-flex tw-items-center tw-justify-between">
+ <h1 class="tw-mb-2">{{.Milestone.Name}}</h1>
+ {{if not .Repository.IsArchived}}
+ <div class="tw-flex button-row">
+ {{if or .CanWriteIssues .CanWritePulls}}
+ {{if .Milestone.IsClosed}}
+ <a class="ui primary button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/open">{{ctx.Locale.Tr "repo.milestones.open"}}
+ </a>
+ {{else}}
+ <a class="ui red button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/close">{{ctx.Locale.Tr "repo.milestones.close"}}
+ </a>
+ {{end}}
+ <a class="ui button" href="{{.RepoLink}}/milestones/{{.MilestoneID}}/edit">{{ctx.Locale.Tr "repo.milestones.edit"}}</a>
+ {{end}}
+ <a class="ui primary button" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}?milestone={{.MilestoneID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
+ </div>
+ {{end}}
+ </div>
+ {{if .Milestone.RenderedContent}}
+ <div class="markup content tw-mb-4">
+ {{.Milestone.RenderedContent}}
+ </div>
+ {{end}}
+ <div class="tw-flex tw-flex-col tw-gap-2">
+ <progress class="milestone-progress-big" value="{{.Milestone.Completeness}}" max="100"></progress>
+ <div class="tw-flex tw-gap-4">
+ <div class="tw-flex tw-items-center">
+ {{$closedDate:= TimeSinceUnix .Milestone.ClosedDateUnix ctx.Locale}}
+ {{if .IsClosed}}
+ {{svg "octicon-clock"}} {{ctx.Locale.Tr "repo.milestones.closed" $closedDate}}
+ {{else}}
+
+ {{if .Milestone.DeadlineString}}
+ <span{{if .IsOverdue}} class="text red"{{end}}>
+ {{svg "octicon-calendar"}}
+ {{DateTime "short" .Milestone.DeadlineString}}
+ </span>
+ {{else}}
+ {{svg "octicon-calendar"}}
+ {{ctx.Locale.Tr "repo.milestones.no_due_date"}}
+ {{end}}
+ {{end}}
+ </div>
+ <div class="tw-mr-2">{{ctx.Locale.Tr "repo.milestones.completeness" .Milestone.Completeness}}</div>
+ {{if .TotalTrackedTime}}
+ <div data-tooltip-content='{{ctx.Locale.Tr "tracked_time_summary"}}'>
+ {{svg "octicon-clock"}}
+ {{.TotalTrackedTime | Sec2Time}}
+ </div>
+ {{end}}
+ </div>
+ </div>
+ <div class="divider"></div>
+
+ {{template "repo/issue/filters" .}}
+
+ {{template "shared/issuelist" dict "." . "listType" "milestone"}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/milestone_new.tmpl b/templates/repo/issue/milestone_new.tmpl
new file mode 100644
index 00000000..9f32df00
--- /dev/null
+++ b/templates/repo/issue/milestone_new.tmpl
@@ -0,0 +1,59 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository new milestone">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ <div class="issue-navbar">
+ {{template "repo/issue/navbar" .}}
+ {{if and (or .CanWriteIssues .CanWritePulls) .PageIsEditMilestone}}
+ <div class="ui right floated secondary menu">
+ <a class="ui primary button" href="{{$.RepoLink}}/milestones/new">{{ctx.Locale.Tr "repo.milestones.new"}}</a>
+ </div>
+ {{end}}
+ </div>
+ <div class="divider"></div>
+ <h2 class="ui dividing header">
+ {{if .PageIsEditMilestone}}
+ {{ctx.Locale.Tr "repo.milestones.edit"}}
+ <div class="sub header">{{ctx.Locale.Tr "repo.milestones.edit_subheader"}}</div>
+ {{else}}
+ {{ctx.Locale.Tr "repo.milestones.new"}}
+ <div class="sub header">{{ctx.Locale.Tr "repo.milestones.new_subheader"}}</div>
+ {{end}}
+ </h2>
+ {{template "base/alert" .}}
+ <form class="ui form" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="field {{if .Err_Title}}error{{end}}">
+ <label>{{ctx.Locale.Tr "repo.milestones.title"}}</label>
+ <input name="title" placeholder="{{ctx.Locale.Tr "repo.milestones.title"}}" value="{{.title}}" autofocus required maxlength="50">
+ </div>
+ <div class="field {{if .Err_Deadline}}error{{end}}">
+ <label>
+ {{ctx.Locale.Tr "repo.milestones.due_date"}}
+ <a id="clear-date">{{ctx.Locale.Tr "repo.milestones.clear"}}</a>
+ </label>
+ <input type="date" id="deadline" name="deadline" value="{{.deadline}}" placeholder="{{ctx.Locale.Tr "repo.issues.due_date_form"}}">
+ </div>
+ <div class="field">
+ <label>{{ctx.Locale.Tr "repo.milestones.desc"}}</label>
+ <textarea name="content">{{.content}}</textarea>
+ </div>
+ <div class="divider"></div>
+ <div class="tw-text-right">
+ {{if .PageIsEditMilestone}}
+ <a class="ui primary basic button" href="{{.RepoLink}}/milestones">
+ {{ctx.Locale.Tr "repo.milestones.cancel"}}
+ </a>
+ <button class="ui primary button">
+ {{ctx.Locale.Tr "repo.milestones.modify"}}
+ </button>
+ {{else}}
+ <button class="ui primary button">
+ {{ctx.Locale.Tr "repo.milestones.create"}}
+ </button>
+ {{end}}
+ </div>
+ </form>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/milestones.tmpl b/templates/repo/issue/milestones.tmpl
new file mode 100644
index 00000000..63a6f6b2
--- /dev/null
+++ b/templates/repo/issue/milestones.tmpl
@@ -0,0 +1,110 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository milestones">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+
+ <div class="list-header list-header-issues">
+ {{template "repo/issue/navbar" .}}
+ {{template "repo/issue/search" .}}
+ {{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
+ <div class="button-row">
+ <a class="ui small primary button" href="{{$.Link}}/new">{{ctx.Locale.Tr "repo.milestones.new"}}</a>
+ </div>
+ {{end}}
+ </div>
+
+ {{template "repo/issue/filters" .}}
+
+ <!-- milestone list -->
+ <div class="milestone-list">
+ {{range .Milestones}}
+ <li class="milestone-card">
+ <div class="milestone-header">
+ <h3 class="flex-text-block tw-m-0">
+ {{svg "octicon-milestone" 16}}
+ <a class="muted" href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a>
+ </h3>
+ <div class="tw-flex tw-items-center">
+ <span class="tw-mr-2">{{.Completeness}}%</span>
+ <progress value="{{.Completeness}}" max="100"></progress>
+ </div>
+ </div>
+ <div class="milestone-toolbar">
+ <div class="group">
+ <div class="flex-text-block">
+ {{svg "octicon-issue-opened" 14}}
+ {{ctx.Locale.PrettyNumber .NumOpenIssues}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}}
+ </div>
+ <div class="flex-text-block">
+ {{svg "octicon-check" 14}}
+ {{ctx.Locale.PrettyNumber .NumClosedIssues}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}}
+ </div>
+ {{if .TotalTrackedTime}}
+ <div class="flex-text-block">
+ {{svg "octicon-clock"}}
+ {{.TotalTrackedTime|Sec2Time}}
+ </div>
+ {{end}}
+ {{if .UpdatedUnix}}
+ <div class="flex-text-block">
+ {{svg "octicon-clock"}}
+ {{ctx.Locale.Tr "repo.milestones.update_ago" (TimeSinceUnix .UpdatedUnix ctx.Locale)}}
+ </div>
+ {{end}}
+ <div class="flex-text-block">
+ {{if .IsClosed}}
+ {{$closedDate:= TimeSinceUnix .ClosedDateUnix ctx.Locale}}
+ {{svg "octicon-clock" 14}}
+ {{ctx.Locale.Tr "repo.milestones.closed" $closedDate}}
+ {{else}}
+ {{if .DeadlineString}}
+ <span class="flex-text-inline {{if .IsOverdue}}text red{{end}}">
+ {{svg "octicon-calendar" 14}}
+ {{DateTime "short" .DeadlineString}}
+ </span>
+ {{else}}
+ {{svg "octicon-calendar" 14}}
+ {{ctx.Locale.Tr "repo.milestones.no_due_date"}}
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+ {{if and (or $.CanWriteIssues $.CanWritePulls) (not $.Repository.IsArchived)}}
+ <div class="group">
+ <a class="flex-text-inline" href="{{$.Link}}/{{.ID}}/edit">{{svg "octicon-pencil" 14}}{{ctx.Locale.Tr "repo.issues.label_edit"}}</a>
+ {{if .IsClosed}}
+ <a class="link-action flex-text-inline" href data-url="{{$.Link}}/{{.ID}}/open">{{svg "octicon-check" 14}}{{ctx.Locale.Tr "repo.milestones.open"}}</a>
+ {{else}}
+ <a class="link-action flex-text-inline" href data-url="{{$.Link}}/{{.ID}}/close">{{svg "octicon-x" 14}}{{ctx.Locale.Tr "repo.milestones.close"}}</a>
+ {{end}}
+ <a class="delete-button flex-text-inline" href="#" data-url="{{$.RepoLink}}/milestones/delete" data-id="{{.ID}}">{{svg "octicon-trash" 14}}{{ctx.Locale.Tr "repo.issues.label_delete"}}</a>
+ </div>
+ {{end}}
+ </div>
+ {{if .Content}}
+ <div class="markup content">
+ {{.RenderedContent}}
+ </div>
+ {{end}}
+ </li>
+ {{end}}
+
+ {{template "base/paginate" .}}
+ </div>
+ </div>
+</div>
+
+{{if or .CanWriteIssues .CanWritePulls}}
+ <div class="ui g-modal-confirm delete modal">
+ <div class="header">
+ {{svg "octicon-trash"}}
+ {{ctx.Locale.Tr "repo.milestones.deletion"}}
+ </div>
+ <div class="content">
+ <p>{{ctx.Locale.Tr "repo.milestones.deletion_desc"}}</p>
+ </div>
+ {{template "base/modal_actions_confirm" .}}
+ </div>
+{{end}}
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/navbar.tmpl b/templates/repo/issue/navbar.tmpl
new file mode 100644
index 00000000..30e42c77
--- /dev/null
+++ b/templates/repo/issue/navbar.tmpl
@@ -0,0 +1,4 @@
+<h2 class="ui compact small menu small-menu-items issue-list-navbar">
+ <a class="{{if .PageIsLabels}}active {{end}}item" href="{{.RepoLink}}/labels">{{ctx.Locale.Tr "repo.labels"}}</a>
+ <a class="{{if .PageIsMilestones}}active {{end}}item" href="{{.RepoLink}}/milestones">{{ctx.Locale.Tr "repo.milestones"}}</a>
+</h2>
diff --git a/templates/repo/issue/new.tmpl b/templates/repo/issue/new.tmpl
new file mode 100644
index 00000000..ccd45fde
--- /dev/null
+++ b/templates/repo/issue/new.tmpl
@@ -0,0 +1,8 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository new issue">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "repo/issue/new_form" .}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl
new file mode 100644
index 00000000..465cb44f
--- /dev/null
+++ b/templates/repo/issue/new_form.tmpl
@@ -0,0 +1,190 @@
+{{if .Flash}}
+{{template "base/alert" .}}
+{{end}}
+<form class="issue-content ui comment form form-fetch-action" id="new-issue" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="issue-content-left">
+ <div class="ui comments">
+ <div class="comment">
+ {{ctx.AvatarUtils.Avatar .SignedUser 40}}
+ <div class="ui segment content tw-my-0">
+ <div class="field">
+ <input name="title" class="js-autofocus-end" id="issue_title" placeholder="{{ctx.Locale.Tr "repo.milestones.title"}}" value="{{if .TitleQuery}}{{.TitleQuery}}{{else if .IssueTemplateTitle}}{{.IssueTemplateTitle}}{{else}}{{.title}}{{end}}" required maxlength="255" autocomplete="off">
+ {{if .PageIsComparePull}}
+ <div class="title_wip_desc" data-wip-prefixes="{{JsonUtils.EncodeToString .PullRequestWorkInProgressPrefixes}}">{{ctx.Locale.Tr "repo.pulls.title_wip_desc" (index .PullRequestWorkInProgressPrefixes 0)}}</div>
+ {{end}}
+ </div>
+ {{if .Fields}}
+ <input type="hidden" name="template-file" value="{{.TemplateFile}}">
+ {{range .Fields}}
+ {{if eq .Type "input"}}
+ {{template "repo/issue/fields/input" dict "Context" $.Context "item" .}}
+ {{else if eq .Type "markdown"}}
+ {{template "repo/issue/fields/markdown" dict "Context" $.Context "item" .}}
+ {{else if eq .Type "textarea"}}
+ {{template "repo/issue/fields/textarea" dict "Context" $.Context "item" . "root" $}}
+ {{else if eq .Type "dropdown"}}
+ {{template "repo/issue/fields/dropdown" dict "Context" $.Context "item" .}}
+ {{else if eq .Type "checkboxes"}}
+ {{template "repo/issue/fields/checkboxes" dict "Context" $.Context "item" .}}
+ {{end}}
+ {{end}}
+ {{else}}
+ {{template "repo/issue/comment_tab" .}}
+ {{end}}
+ <div class="text right">
+ <button class="ui primary button">
+ {{if .PageIsComparePull}}
+ {{ctx.Locale.Tr "repo.pulls.create"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.create"}}
+ {{end}}
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="issue-content-right ui segment">
+ {{template "repo/issue/view_content/sidebar/branch_selector_field" .}}
+
+ <input id="label_ids" name="label_ids" type="hidden" value="{{.label_ids}}">
+ {{template "repo/issue/labels/labels_selector_field" .}}
+ {{template "repo/issue/labels/labels_sidebar" dict "root" $}}
+
+ <div class="divider"></div>
+
+ <input id="milestone_id" name="milestone_id" type="hidden" value="{{.milestone_id}}">
+ <div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating jump select-milestone dropdown">
+ <span class="text flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.milestone"}}</strong>
+ {{if .HasIssuesOrPullsWritePermission}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </span>
+ <div class="menu">
+ {{template "repo/issue/milestone/select_menu" .}}
+ </div>
+ </div>
+ <div class="ui select-milestone list">
+ <span class="no-select item {{if .Milestone}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_milestone"}}</span>
+ <div class="selected">
+ {{if .Milestone}}
+ <a class="item muted sidebar-item-link" href="{{.RepoLink}}/issues?milestone={{.Milestone.ID}}">
+ {{svg "octicon-milestone" 18 "tw-mr-2"}}
+ {{.Milestone.Name}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+
+ {{if .IsProjectsEnabled}}
+ <div class="divider"></div>
+
+ <input id="project_id" name="project_id" type="hidden" value="{{.project_id}}">
+ <div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating jump select-project dropdown">
+ <span class="text flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.projects"}}</strong>
+ {{if .HasIssuesOrPullsWritePermission}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </span>
+ <div class="menu">
+ {{if or .OpenProjects .ClosedProjects}}
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_projects"}}">
+ </div>
+ {{end}}
+ <div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_projects"}}</div>
+ {{if and (not .OpenProjects) (not .ClosedProjects)}}
+ <div class="disabled item">
+ {{ctx.Locale.Tr "repo.issues.new.no_items"}}
+ </div>
+ {{else}}
+ {{if .OpenProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.open_projects"}}
+ </div>
+ {{range .OpenProjects}}
+ <a class="item muted sidebar-item-link" data-id="{{.ID}}" data-href="{{.Link ctx}}">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </a>
+ {{end}}
+ {{end}}
+ {{if .ClosedProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.closed_projects"}}
+ </div>
+ {{range .ClosedProjects}}
+ <a class="item muted sidebar-item-link" data-id="{{.ID}}" data-href="{{.Link ctx}}">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </a>
+ {{end}}
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+ <div class="ui select-project list">
+ <span class="no-select item {{if .Project}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_projects"}}</span>
+ <div class="selected">
+ {{if .Project}}
+ <a class="item muted sidebar-item-link" href="{{.Project.Link ctx}}">
+ {{svg .Project.IconName 18 "tw-mr-2"}}{{.Project.Title}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+ <div class="divider"></div>
+ <input id="assignee_ids" name="assignee_ids" type="hidden" value="{{.assignee_ids}}">
+ <div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating jump select-assignees dropdown">
+ <span class="text flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.assignees"}}</strong>
+ {{if .HasIssuesOrPullsWritePermission}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </span>
+ <div class="filter menu" data-id="#assignee_ids">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignees"}}">
+ </div>
+ <div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}</div>
+ {{range .Assignees}}
+ <a class="item muted" href="#" data-id="{{.ID}}" data-id-selector="#assignee_{{.ID}}">
+ <span class="octicon-check tw-invisible">{{svg "octicon-check"}}</span>
+ <span class="text">
+ {{ctx.AvatarUtils.Avatar . 28 "tw-mr-2"}}{{template "repo/search_name" .}}
+ </span>
+ </a>
+ {{end}}
+ </div>
+ </div>
+ <div class="ui assignees list">
+ <span class="no-select item {{if .HasSelectedLabel}}tw-hidden{{end}}">
+ {{ctx.Locale.Tr "repo.issues.new.no_assignees"}}
+ </span>
+ <div class="selected">
+ {{range .Assignees}}
+ <a class="item tw-p-1 muted tw-hidden" id="assignee_{{.ID}}" href="{{$.RepoLink}}/issues?assignee={{.ID}}">
+ {{ctx.AvatarUtils.Avatar . 28 "tw-mr-2 tw-align-middle"}}{{.GetDisplayName}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ {{if and .PageIsComparePull (not (eq .HeadRepo.FullName .BaseCompareRepo.FullName)) .CanWriteToHeadRepo}}
+ <div class="divider"></div>
+ <div class="inline field">
+ <div class="ui checkbox">
+ <label data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers_desc"}}"><strong>{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers"}}</strong></label>
+ <input name="allow_maintainer_edit" type="checkbox" {{if .AllowMaintainerEdit}}checked{{end}}>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ <input type="hidden" name="redirect_after_creation" value="{{.redirect_after_creation}}">
+</form>
diff --git a/templates/repo/issue/openclose.tmpl b/templates/repo/issue/openclose.tmpl
new file mode 100644
index 00000000..eb2d6e09
--- /dev/null
+++ b/templates/repo/issue/openclose.tmpl
@@ -0,0 +1,16 @@
+<div class="small-menu-items ui compact tiny menu">
+ <a class="{{if eq .State "open"}}active {{end}}item" href="{{if eq .State "open"}}{{.AllStatesLink}}{{else}}{{.OpenLink}}{{end}}">
+ {{if .PageIsMilestones}}
+ {{svg "octicon-milestone" 16 "tw-mr-2"}}
+ {{else if .PageIsPullList}}
+ {{svg "octicon-git-pull-request" 16 "tw-mr-2"}}
+ {{else}}
+ {{svg "octicon-issue-opened" 16 "tw-mr-2"}}
+ {{end}}
+ {{ctx.Locale.PrettyNumber .OpenCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}}
+ </a>
+ <a class="{{if eq .State "closed"}}active {{end}}item" href="{{if eq .State "closed"}}{{.AllStatesLink}}{{else}}{{.ClosedLink}}{{end}}">
+ {{svg "octicon-check" 16 "tw-mr-2"}}
+ {{ctx.Locale.PrettyNumber .ClosedCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}}
+ </a>
+</div>
diff --git a/templates/repo/issue/search.tmpl b/templates/repo/issue/search.tmpl
new file mode 100644
index 00000000..f1c0ea32
--- /dev/null
+++ b/templates/repo/issue/search.tmpl
@@ -0,0 +1,20 @@
+<form class="list-header-search ui form ignore-dirty issue-list-search">
+ <div class="ui small search fluid action input">
+ <input type="hidden" name="state" value="{{$.State}}">
+ {{if not .PageIsMilestones}}
+ <input type="hidden" name="type" value="{{$.ViewType}}">
+ <input type="hidden" name="labels" value="{{.SelectLabels}}">
+ <input type="hidden" name="milestone" value="{{$.MilestoneID}}">
+ <input type="hidden" name="project" value="{{$.ProjectID}}">
+ <input type="hidden" name="assignee" value="{{$.AssigneeID}}">
+ <input type="hidden" name="poster" value="{{$.PosterID}}">
+ {{end}}
+ {{if .PageIsPullList}}
+ {{template "shared/search/combo_fuzzy" dict "Value" .Keyword "IsFuzzy" .IsFuzzy "Placeholder" (ctx.Locale.Tr "search.pull_kind") "Tooltip" (ctx.Locale.Tr "explore.go_to")}}
+ {{else if .PageIsMilestones}}
+ {{template "shared/search/combo_fuzzy" dict "Value" .Keyword "IsFuzzy" .IsFuzzy "Placeholder" (ctx.Locale.Tr "search.milestone_kind") "Tooltip" (ctx.Locale.Tr "explore.go_to")}}
+ {{else}}
+ {{template "shared/search/combo_fuzzy" dict "Value" .Keyword "IsFuzzy" .IsFuzzy "Placeholder" (ctx.Locale.Tr "search.issue_kind") "Tooltip" (ctx.Locale.Tr "explore.go_to")}}
+ {{end}}
+ </div>
+</form>
diff --git a/templates/repo/issue/view.tmpl b/templates/repo/issue/view.tmpl
new file mode 100644
index 00000000..1ef9e735
--- /dev/null
+++ b/templates/repo/issue/view.tmpl
@@ -0,0 +1,12 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content repository view issue pull">
+ {{template "repo/header" .}}
+ <div class="ui container">
+ {{template "repo/issue/view_title" .}}
+ {{if .Issue.IsPull}}
+ {{template "repo/pulls/tab_menu" .}}
+ {{end}}
+ {{template "repo/issue/view_content" .}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl
new file mode 100644
index 00000000..543191e0
--- /dev/null
+++ b/templates/repo/issue/view_content.tmpl
@@ -0,0 +1,187 @@
+<div class="issue-content">
+ <!-- I know, there is probably a better way to do this (moved from sidebar.tmpl, original author: 6543 @ 2021-02-28) -->
+ <!-- Agree, there should be a better way, eg: introduce window.config.pageData (original author: wxiaoguang @ 2021-09-05) -->
+ <input type="hidden" id="repolink" value="{{$.RepoRelPath}}">
+ <input type="hidden" id="repoId" value="{{.Repository.ID}}">
+ <input type="hidden" id="issueIndex" value="{{.Issue.Index}}">
+ <input type="hidden" id="type" value="{{.IssueType}}">
+
+ {{$createdStr:= TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}
+ <div class="issue-content-left comment-list prevent-before-timeline">
+ <div class="ui timeline">
+ <div id="{{.Issue.HashTag}}" class="timeline-item comment first">
+ {{if .Issue.OriginalAuthor}}
+ <span class="timeline-avatar">
+ {{ctx.AvatarUtils.Avatar nil 40}}
+ </span>
+ {{else}}
+ <a class="timeline-avatar" {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>
+ {{ctx.AvatarUtils.Avatar .Issue.Poster 40}}
+ </a>
+ {{end}}
+ <div class="content comment-container">
+ <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between" role="heading" aria-level="3">
+ <div class="comment-header-left tw-flex tw-items-center">
+ {{if .Issue.OriginalAuthor}}
+ <span class="text black tw-font-semibold">
+ {{svg (MigrationIcon .Repository.GetOriginalURLHostname)}}
+ {{.Issue.OriginalAuthor}}
+ </span>
+ <span class="text grey muted-links">
+ {{ctx.Locale.Tr "repo.issues.commented_at" .Issue.HashTag $createdStr}}
+ </span>
+ <span class="text migrate">
+ {{if .Repository.OriginalURL}} ({{ctx.Locale.Tr "repo.migrated_from" .Repository.OriginalURL .Repository.GetOriginalURLHostname}}){{end}}
+ </span>
+ {{else}}
+ <a class="inline-timeline-avatar" href="{{.Issue.Poster.HomeLink}}">
+ {{ctx.AvatarUtils.Avatar .Issue.Poster 24}}
+ </a>
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Issue.Poster}}
+ {{ctx.Locale.Tr "repo.issues.commented_at" .Issue.HashTag $createdStr}}
+ </span>
+ {{end}}
+ </div>
+ <div class="comment-header-right actions tw-flex tw-items-center">
+ {{template "repo/issue/view_content/show_role" dict "ShowRole" .Issue.ShowRole "IgnorePoster" true "IsPull" .Issue.IsPull}}
+ {{if not $.Repository.IsArchived}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
+ {{end}}
+ {{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}}
+ </div>
+ </div>
+ <div class="ui attached segment comment-body" role="article">
+ <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission $.IsIssuePoster}}data-can-edit="true"{{end}}>
+ {{if .Issue.RenderedContent}}
+ {{.Issue.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ <div id="issue-{{.Issue.ID}}-raw" class="raw-content tw-hidden">{{.Issue.Content}}</div>
+ <div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/content" data-content-version="{{.Issue.ContentVersion}}" data-context="{{.RepoLink}}" data-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/attachments" data-view-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/view-attachments"></div>
+ {{if .Issue.Attachments}}
+ {{template "repo/issue/view_content/attachments" dict "Attachments" .Issue.Attachments "RenderedContent" .Issue.RenderedContent}}
+ {{end}}
+ </div>
+ {{$reactions := .Issue.Reactions.GroupByType}}
+ {{if $reactions}}
+ {{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}}
+ {{end}}
+ </div>
+ </div>
+
+ {{template "repo/issue/view_content/comments" .}}
+
+ {{if and .Issue.IsPull (not $.Repository.IsArchived)}}
+ {{template "repo/issue/view_content/pull".}}
+ {{end}}
+
+ {{if .IsSigned}}
+ {{if and (or .IsRepoAdmin .HasIssuesOrPullsWritePermission (not .Issue.IsLocked)) (not .Repository.IsArchived)}}
+ <div class="timeline-item comment form">
+ <a class="timeline-avatar" href="{{.SignedUser.HomeLink}}">
+ {{ctx.AvatarUtils.Avatar .SignedUser 40}}
+ </a>
+ <div class="content">
+ <form class="ui segment form form-fetch-action" id="comment-form" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/comments" method="post">
+ {{template "repo/issue/comment_tab" .}}
+ {{.CsrfTokenHtml}}
+ <div class="field footer">
+ <div class="text right">
+ {{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .DisableStatusChange)}}
+ {{if .Issue.IsClosed}}
+ <button id="status-button" class="ui primary basic button" data-status="{{ctx.Locale.Tr "repo.issues.reopen_issue"}}" data-status-and-comment="{{ctx.Locale.Tr "repo.issues.reopen_comment_issue"}}" name="status" value="reopen">
+ {{ctx.Locale.Tr "repo.issues.reopen_issue"}}
+ </button>
+ {{else}}
+ {{$closeTranslationKey := "repo.issues.close"}}
+ {{if .Issue.IsPull}}
+ {{$closeTranslationKey = "repo.pulls.close"}}
+ {{end}}
+ <button id="status-button" class="ui red basic button" data-status="{{ctx.Locale.Tr $closeTranslationKey}}" data-status-and-comment="{{ctx.Locale.Tr "repo.issues.close_comment_issue"}}" name="status" value="close">
+ {{ctx.Locale.Tr $closeTranslationKey}}
+ </button>
+ {{end}}
+ {{end}}
+ <button class="ui primary button">
+ {{ctx.Locale.Tr "repo.issues.create_comment"}}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ {{else if .Repository.IsArchived}}
+ <div class="ui warning message tw-text-center">
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.archive.pull.nocomment"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.archive.issue.nocomment"}}
+ {{end}}
+ </div>
+ {{end}}
+ {{else}} {{/* not .IsSigned */}}
+ {{if .Repository.IsArchived}}
+ <div class="ui warning message tw-text-center">
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.archive.pull.nocomment"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.archive.issue.nocomment"}}
+ {{end}}
+ </div>
+ {{else}}
+ <div class="ui warning message">
+ {{ctx.Locale.Tr "repo.issues.sign_in_require_desc" .SignInLink}}
+ </div>
+ {{end}}
+ {{end}}{{/* end if: .IsSigned */}}
+ </div>
+ </div>
+
+ {{template "repo/issue/view_content/sidebar" .}}
+</div>
+
+<template id="issue-comment-editor-template">
+ <div class="ui comment form">
+ <div class="field">
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewUrl" (print .Repository.Link "/markup")
+ "MarkdownPreviewContext" .RepoLink
+ "TextareaName" "content"
+ "DropzoneParentContainer" ".ui.form"
+ )}}
+ </div>
+
+ {{if .IsAttachmentEnabled}}
+ <div class="field">
+ {{template "repo/upload" .}}
+ </div>
+ {{end}}
+
+ <div class="field">
+ <div class="text right edit">
+ <button class="ui basic cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
+ <button class="ui primary save button">{{ctx.Locale.Tr "repo.issues.save"}}</button>
+ </div>
+ </div>
+ </div>
+</template>
+
+{{template "repo/issue/view_content/reference_issue_dialog" .}}
+
+<div class="tw-hidden" id="no-content">
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+</div>
+
+<div class="ui g-modal-confirm delete modal">
+ <div class="header">
+ {{svg "octicon-trash"}}
+ {{ctx.Locale.Tr "repo.branch.delete" .HeadTarget}}
+ </div>
+ <div class="content">
+ <p>{{ctx.Locale.Tr "repo.branch.delete_desc"}}</p>
+ </div>
+ {{template "base/modal_actions_confirm" .}}
+</div>
diff --git a/templates/repo/issue/view_content/add_reaction.tmpl b/templates/repo/issue/view_content/add_reaction.tmpl
new file mode 100644
index 00000000..37931f28
--- /dev/null
+++ b/templates/repo/issue/view_content/add_reaction.tmpl
@@ -0,0 +1,12 @@
+{{if .ctxData.IsSigned}}
+<div class="item action ui dropdown jump pointing top right select-reaction" data-action-url="{{.ActionURL}}">
+ <a class="add-reaction muted">
+ {{svg "octicon-smiley"}}
+ </a>
+ <div class="menu reactions-menu">
+ {{range $value := AllowedReactions}}
+ <a class="item reaction" data-tooltip-content="{{$value}}" aria-label="{{$value}}" data-reaction-content="{{$value}}">{{ReactionToEmoji $value}}</a>
+ {{end}}
+ </div>
+</div>
+{{end}}
diff --git a/templates/repo/issue/view_content/attachments.tmpl b/templates/repo/issue/view_content/attachments.tmpl
new file mode 100644
index 00000000..79085df3
--- /dev/null
+++ b/templates/repo/issue/view_content/attachments.tmpl
@@ -0,0 +1,42 @@
+<div class="dropzone-attachments">
+ {{if .Attachments}}
+ <div class="divider"></div>
+ {{end}}
+ {{$hasThumbnails := false}}
+ {{- range .Attachments -}}
+ <div class="tw-flex">
+ <div class="tw-flex-1 tw-p-2">
+ <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
+ {{if FilenameIsImage .Name}}
+ {{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}}
+ {{$hasThumbnails = true}}
+ {{end}}
+ {{svg "octicon-file"}}
+ {{else}}
+ {{svg "octicon-desktop-download"}}
+ {{end}}
+ <span><strong>{{.Name}}</strong></span>
+ </a>
+ </div>
+ <div class="tw-p-2 tw-flex tw-items-center">
+ <span class="ui text grey">{{.Size | ctx.Locale.TrSize}}</span>
+ </div>
+ </div>
+ {{end -}}
+
+ {{if $hasThumbnails}}
+ <div class="divider"></div>
+ <div class="ui small thumbnails">
+ {{- range .Attachments -}}
+ {{if FilenameIsImage .Name}}
+ {{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}}
+ <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
+ <img alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
+ </a>
+ {{end}}
+ {{end}}
+ {{end -}}
+ </div>
+ {{end}}
+
+</div>
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl
new file mode 100644
index 00000000..6d14d726
--- /dev/null
+++ b/templates/repo/issue/view_content/comments.tmpl
@@ -0,0 +1,683 @@
+{{template "base/alert"}}
+{{range .Issue.Comments}}
+ {{if call $.ShouldShowCommentType .Type}}
+ {{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
+
+ <!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF,
+ 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 8 = MILESTONE_CHANGE,
+ 9 = ASSIGNEES_CHANGE, 10 = TITLE_CHANGE, 11 = DELETE_BRANCH, 12 = START_TRACKING,
+ 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL, 16 = ADDED_DEADLINE, 17 = MODIFIED_DEADLINE,
+ 18 = REMOVED_DEADLINE, 19 = ADD_DEPENDENCY, 20 = REMOVE_DEPENDENCY, 21 = CODE,
+ 22 = REVIEW, 23 = ISSUE_LOCKED, 24 = ISSUE_UNLOCKED, 25 = TARGET_BRANCH_CHANGED,
+ 26 = DELETE_TIME_MANUAL, 27 = REVIEW_REQUEST, 28 = MERGE_PULL_REQUEST,
+ 29 = PULL_PUSH_EVENT, 30 = PROJECT_CHANGED, 31 = PROJECT_BOARD_CHANGED
+ 32 = DISMISSED_REVIEW, 33 = COMMENT_TYPE_CHANGE_ISSUE_REF, 34 = PR_SCHEDULE_TO_AUTO_MERGE,
+ 35 = CANCEL_SCHEDULED_AUTO_MERGE_PR, 36 = PIN_ISSUE, 37 = UNPIN_ISSUE -->
+ {{if eq .Type 0}}
+ <div class="timeline-item comment" id="{{.HashTag}}">
+ {{if .OriginalAuthor}}
+ <span class="timeline-avatar">
+ {{ctx.AvatarUtils.Avatar nil 40}}
+ </span>
+ {{else}}
+ <a class="timeline-avatar"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
+ {{ctx.AvatarUtils.Avatar .Poster 40}}
+ </a>
+ {{end}}
+ <div class="content comment-container">
+ <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between" role="heading" aria-level="3">
+ <div class="comment-header-left tw-flex tw-items-center">
+ {{if .OriginalAuthor}}
+ <span class="text black tw-font-semibold tw-mr-1">
+ {{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
+ {{.OriginalAuthor}}
+ </span>
+ <span class="text grey muted-links">
+ {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}} {{if $.Repository.OriginalURL}}
+ </span>
+ <span class="text migrate">
+ ({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}}){{end}}
+ </span>
+ {{else}}
+ {{if gt .Poster.ID 0}}
+ <a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
+ {{ctx.AvatarUtils.Avatar .Poster 24}}
+ </a>
+ {{end}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}}
+ </span>
+ {{end}}
+ </div>
+ <div class="comment-header-right actions tw-flex tw-items-center">
+ {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole "IsPull" .Issue.IsPull}}
+ {{if not $.Repository.IsArchived}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
+ {{end}}
+ {{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
+ </div>
+ </div>
+ <div class="ui attached segment comment-body" role="article">
+ <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
+ {{if .RenderedContent}}
+ {{.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ <div id="issuecomment-{{.ID}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
+ <div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
+ {{if .Attachments}}
+ {{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
+ {{end}}
+ </div>
+ {{$reactions := .Reactions.GroupByType}}
+ {{if $reactions}}
+ {{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
+ {{end}}
+ </div>
+ </div>
+ {{else if eq .Type 1}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge tw-bg-green tw-text-white">{{svg "octicon-dot-fill"}}</span>
+ {{if not .OriginalAuthor}}
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{end}}
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.pulls.reopened_at" .EventTag $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.reopened_at" .EventTag $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{else if eq .Type 2}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge tw-bg-red tw-text-white">{{svg "octicon-circle-slash"}}</span>
+ {{if not .OriginalAuthor}}
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{end}}
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.pulls.closed_at" .EventTag $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.closed_at" .EventTag $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{else if eq .Type 28}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge tw-bg-purple tw-text-white">{{svg "octicon-git-merge"}}</span>
+ {{if not .OriginalAuthor}}
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{end}}
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}}
+ {{if eq $.Issue.PullRequest.Status 3}}
+ {{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{else if eq .Type 3 5 6}}
+ {{$refFrom:= ""}}
+ {{if ne .RefRepoID .Issue.RepoID}}
+ {{$refFrom = ctx.Locale.Tr "repo.issues.ref_from" .RefRepo.FullName}}
+ {{end}}
+ {{$refTr := "repo.issues.ref_issue_from"}}
+ {{if .Issue.IsPull}}
+ {{$refTr = "repo.issues.ref_pull_from"}}
+ {{else if eq .RefAction 1}}
+ {{$refTr = "repo.issues.ref_closing_from"}}
+ {{else if eq .RefAction 2}}
+ {{$refTr = "repo.issues.ref_reopening_from"}}
+ {{end}}
+ {{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-bookmark"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{if eq .RefAction 3}}<del>{{end}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr $refTr .EventTag $createdStr (.RefCommentLink ctx) $refFrom}}
+ </span>
+ {{if eq .RefAction 3}}</del>{{end}}
+
+ <div class="detail flex-text-block">
+ <span class="text grey muted-links"><a href="{{.RefIssueLink ctx}}"><b>{{.RefIssueTitle ctx}}</b> {{.RefIssueIdent ctx}}</a></span>
+ </div>
+ </div>
+ {{else if eq .Type 4}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-bookmark"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.pulls.commit_ref_at" .EventTag $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.commit_ref_at" .EventTag $createdStr}}
+ {{end}}
+ </span>
+ <div class="detail flex-text-block">
+ {{svg "octicon-git-commit"}}
+ <span class="text grey muted-links">{{.Content | SanitizeHTML}}</span>
+ </div>
+ </div>
+ {{else if eq .Type 7}}
+ {{if or .AddedLabels .RemovedLabels}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-tag"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if and .AddedLabels (not .RemovedLabels)}}
+ {{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) $createdStr}}
+ {{else if and (not .AddedLabels) .RemovedLabels}}
+ {{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{end}}
+ {{else if eq .Type 8}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-milestone"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if gt .OldMilestoneID 0}}{{if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.change_milestone_at" .OldMilestone.Name .Milestone.Name $createdStr}}{{else}}{{ctx.Locale.Tr "repo.issues.remove_milestone_at" .OldMilestone.Name $createdStr}}{{end}}{{else if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.add_milestone_at" .Milestone.Name $createdStr}}{{end}}
+ </span>
+ </div>
+ {{else if and (eq .Type 9) (gt .AssigneeID 0)}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-person"}}</span>
+ {{if .RemovedAssignee}}
+ {{template "shared/user/avatarlink" dict "user" .Assignee}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Assignee}}
+ {{if eq .Poster.ID .Assignee.ID}}
+ {{ctx.Locale.Tr "repo.issues.remove_self_assignment" $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.remove_assignee_at" .Poster.GetDisplayName $createdStr}}
+ {{end}}
+ </span>
+ {{else}}
+ {{template "shared/user/avatarlink" dict "user" .Assignee}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Assignee}}
+ {{if eq .Poster.ID .AssigneeID}}
+ {{ctx.Locale.Tr "repo.issues.self_assign_at" $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.add_assignee_at" .Poster.GetDisplayName $createdStr}}
+ {{end}}
+ </span>
+ {{end}}
+ </div>
+ {{else if eq .Type 10}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-pencil"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.change_title_at" (.OldTitle|RenderEmoji $.Context) (.NewTitle|RenderEmoji $.Context) $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 11}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-git-branch"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.delete_branch_at" .OldRef $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 12}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.start_tracking_history" $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 13}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.stop_tracking_history" $createdStr}}
+ </span>
+ {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
+ <div class="detail flex-text-block">
+ {{svg "octicon-clock"}}
+ {{if .RenderedContent}}
+ {{/* compatibility with time comments made before v1.21 */}}
+ <span class="text grey muted-links">{{.RenderedContent}}</span>
+ {{else}}
+ <span class="text grey muted-links">{{.Content|Sec2Time}}</span>
+ {{end}}
+ </div>
+ </div>
+ {{else if eq .Type 14}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.add_time_history" $createdStr}}
+ </span>
+ {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
+ <div class="detail flex-text-block">
+ {{svg "octicon-clock"}}
+ {{if .RenderedContent}}
+ {{/* compatibility with time comments made before v1.21 */}}
+ <span class="text grey muted-links">{{.RenderedContent}}</span>
+ {{else}}
+ <span class="text grey muted-links">{{.Content|Sec2Time}}</span>
+ {{end}}
+ </div>
+ </div>
+ {{else if eq .Type 15}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.cancel_tracking_history" $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 16}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.due_date_added" (DateTime "long" .Content) $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 17}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{$parsedDeadline := StringUtils.Split .Content "|"}}
+ {{if eq (len $parsedDeadline) 2}}
+ {{$from := DateTime "long" (index $parsedDeadline 1)}}
+ {{$to := DateTime "long" (index $parsedDeadline 0)}}
+ {{ctx.Locale.Tr "repo.issues.due_date_modified" $to $from $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{else if eq .Type 18}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.due_date_remove" (DateTime "long" .Content) $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 19}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-package-dependents"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.dependency.added_dependency" $createdStr}}
+ </span>
+ {{if .DependentIssue}}
+ <div class="detail flex-text-block">
+ {{svg "octicon-plus"}}
+ <span class="text grey muted-links">
+ <a href="{{.DependentIssue.Link}}">
+ {{if eq .DependentIssue.RepoID .Issue.RepoID}}
+ #{{.DependentIssue.Index}} {{.DependentIssue.Title}}
+ {{else}}
+ {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}}
+ {{end}}
+ </a>
+ </span>
+ </div>
+ {{end}}
+ </div>
+ {{else if eq .Type 20}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-package-dependents"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.dependency.removed_dependency" $createdStr}}
+ </span>
+ {{if .DependentIssue}}
+ <div class="detail flex-text-block">
+ {{svg "octicon-trash"}}
+ <span class="text grey muted-links">
+ <a href="{{.DependentIssue.Link}}">
+ {{if eq .DependentIssue.RepoID .Issue.RepoID}}
+ #{{.DependentIssue.Index}} {{.DependentIssue.Title}}
+ {{else}}
+ {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}}
+ {{end}}
+ </a>
+ </span>
+ </div>
+ {{end}}
+ </div>
+ {{else if eq .Type 22}}
+ <div class="timeline-item-group" id="{{.HashTag}}">
+ <div class="timeline-item event">
+ {{if not .OriginalAuthor}}
+ {{/* Some timeline avatars need a offset to correctly align with their speech bubble.
+ The condition depends on whether the comment has contents/attachments or reviews */}}
+ <a class="timeline-avatar{{if or .Content .Attachments (and .Review .Review.CodeComments)}} timeline-avatar-offset{{end}}"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
+ {{ctx.AvatarUtils.Avatar .Poster 40}}
+ </a>
+ {{end}}
+ <span class="badge{{if eq .Review.Type 1}} tw-bg-green tw-text-white{{else if eq .Review.Type 3}} tw-bg-red tw-text-white{{end}}">{{svg (printf "octicon-%s" .Review.Type.Icon)}}</span>
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{if eq .Review.Type 1}}
+ {{ctx.Locale.Tr "repo.issues.review.approve" $createdStr}}
+ {{else if eq .Review.Type 2}}
+ {{ctx.Locale.Tr "repo.issues.review.comment" $createdStr}}
+ {{else if eq .Review.Type 3}}
+ {{ctx.Locale.Tr "repo.issues.review.reject" $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.comment" $createdStr}}
+ {{end}}
+ {{if .Review.Dismissed}}
+ <div class="ui small label">{{ctx.Locale.Tr "repo.issues.review.dismissed_label"}}</div>
+ {{end}}
+ </span>
+ </div>
+ {{if or .Content .Attachments}}
+ <div class="timeline-item comment">
+ <div class="content comment-container">
+ <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between">
+ <div class="comment-header-left tw-flex tw-items-center">
+ {{if gt .Poster.ID 0}}
+ <a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
+ {{ctx.AvatarUtils.Avatar .Poster 24}}
+ </a>
+ {{end}}
+ <span class="text grey muted-links">
+ {{if .OriginalAuthor}}
+ <span class="text black tw-font-semibold">
+ {{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
+ {{.OriginalAuthor}}
+ </span>
+ <span class="text grey muted-links"> {{if $.Repository.OriginalURL}}</span>
+ <span class="text migrate">({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}}){{end}}</span>
+ {{else}}
+ {{template "shared/user/authorlink" .Poster}}
+ {{end}}
+
+ {{ctx.Locale.Tr "repo.issues.review.left_comment"}}
+ </span>
+ </div>
+ <div class="comment-header-right actions tw-flex tw-items-center">
+ {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole "IsPull" .Issue.IsPull}}
+ {{if not $.Repository.IsArchived}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
+ {{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
+ {{end}}
+ </div>
+ </div>
+ <div class="ui attached segment comment-body">
+ <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
+ {{if .RenderedContent}}
+ {{.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ <div id="issuecomment-{{.ID}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
+ <div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
+ {{if .Attachments}}
+ {{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
+ {{end}}
+ </div>
+ {{$reactions := .Reactions.GroupByType}}
+ {{if $reactions}}
+ {{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+
+ {{if .Review.CodeComments}}
+ <div class="timeline-item event">
+ {{range $filename, $lines := .Review.CodeComments}}
+ {{range $line, $comms := $lines}}
+ {{template "repo/issue/view_content/conversation" dict "." $ "comments" $comms}}
+ {{end}}
+ {{end}}
+ </div>
+ {{end}}
+ </div>
+ {{else if eq .Type 23}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-lock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{if .Content}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.lock_with_reason" .Content $createdStr}}
+ </span>
+ {{else}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.lock_no_reason" $createdStr}}
+ </span>
+ {{end}}
+ </div>
+ {{else if eq .Type 24}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-key"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.unlock_comment" $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 25}}
+ <div class="timeline-item event">
+ <span class="badge">{{svg "octicon-git-branch"}}</span>
+ {{if not .OriginalAuthor}}
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{end}}
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{ctx.Locale.Tr "repo.pulls.change_target_branch_at" .OldRef .NewRef $createdStr}}
+ </span>
+ </div>
+ {{else if eq .Type 26}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-clock"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+
+ {{ctx.Locale.Tr "repo.issues.del_time_history" $createdStr}}
+ </span>
+ <div class="detail flex-text-block">
+ {{svg "octicon-clock"}}
+ {{if .RenderedContent}}
+ {{/* compatibility with time comments made before v1.21 */}}
+ <span class="text grey muted-links">{{.RenderedContent}}</span>
+ {{else}}
+ <span class="text grey muted-links">- {{.Content|Sec2Time}}</span>
+ {{end}}
+ </div>
+ </div>
+ {{else if eq .Type 27}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-eye"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if (gt .AssigneeID 0)}}
+ {{if .RemovedAssignee}}
+ {{if eq .PosterID .AssigneeID}}
+ {{ctx.Locale.Tr "repo.issues.review.remove_review_request_self" $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.remove_review_request" .Assignee.GetDisplayName $createdStr}}
+ {{end}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.add_review_request" .Assignee.GetDisplayName $createdStr}}
+ {{end}}
+ {{else}}
+ <!-- If the assigned team is deleted, just displaying "Ghost Team" in the comment -->
+ {{$teamName := "Ghost Team"}}
+ {{if .AssigneeTeam}}
+ {{$teamName = .AssigneeTeam.Name}}
+ {{end}}
+ {{if .RemovedAssignee}}
+ {{ctx.Locale.Tr "repo.issues.review.remove_review_request" $teamName $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.add_review_request" $teamName $createdStr}}
+ {{end}}
+ {{end}}
+ </span>
+ </div>
+ {{else if and (eq .Type 29) (or (gt .CommitsNum 0) .IsForcePush)}}
+ <!-- If PR is closed, the comments whose type is CommentTypePullRequestPush(29) after latestCloseCommentID won't be rendered. //-->
+ {{if and .Issue.IsClosed (gt .ID $.LatestCloseCommentID)}}
+ {{continue}}
+ {{end}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-repo-push"}}</span>
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if .IsForcePush}}
+ {{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr}}
+ {{else}}
+ {{ctx.Locale.TrN (len .Commits) "repo.issues.push_commit_1" "repo.issues.push_commits_n" (len .Commits) $createdStr}}
+ {{end}}
+ </span>
+ {{if and .IsForcePush $.Issue.PullRequest.BaseRepo.Name}}
+ <span class="tw-float-right comparebox">
+ <a href="{{$.Issue.PullRequest.BaseRepo.Link}}/compare/{{PathEscape .OldCommit}}..{{PathEscape .NewCommit}}" rel="nofollow" class="ui compare label">{{ctx.Locale.Tr "repo.issues.force_push_compare"}}</a>
+ </span>
+ {{end}}
+ </div>
+ {{if not .IsForcePush}}
+ {{template "repo/commits_list_small" dict "comment" . "root" $}}
+ {{end}}
+ {{else if eq .Type 30}}
+ {{if not $.UnitProjectsGlobalDisabled}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-project"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{$oldProjectDisplayHtml := "Unknown Project"}}
+ {{if .OldProject}}
+ {{$trKey := printf "projects.type-%d.display_name" .OldProject.Type}}
+ {{$oldProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey) .OldProject.Title}}
+ {{end}}
+ {{$newProjectDisplayHtml := "Unknown Project"}}
+ {{if .Project}}
+ {{$trKey := printf "projects.type-%d.display_name" .Project.Type}}
+ {{$newProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey) .Project.Title}}
+ {{end}}
+ {{if and (gt .OldProjectID 0) (gt .ProjectID 0)}}
+ {{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}}
+ {{else if gt .OldProjectID 0}}
+ {{ctx.Locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr}}
+ {{else if gt .ProjectID 0}}
+ {{ctx.Locale.Tr "repo.issues.add_project_at" $newProjectDisplayHtml $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{end}}
+ {{else if eq .Type 32}}
+ <div class="timeline-item-group">
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <a class="timeline-avatar"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
+ <img src="{{.Poster.AvatarLink $.Context}}" width="40" height="40">
+ </a>
+ <span class="badge grey">{{svg "octicon-x" 16}}</span>
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{$reviewerName := ""}}
+ {{if eq .Review.OriginalAuthor ""}}
+ {{$reviewerName = .Review.Reviewer.Name}}
+ {{else}}
+ {{$reviewerName = .Review.OriginalAuthor}}
+ {{end}}
+ <span class="dismissed-message">{{ctx.Locale.Tr "repo.issues.review.dismissed" $reviewerName $createdStr}}</span>
+ </span>
+ </div>
+ {{if .Content}}
+ <div class="timeline-item comment">
+ <div class="content">
+ <div class="ui top attached header comment-header-left tw-flex tw-items-center arrow-top">
+ {{if gt .Poster.ID 0}}
+ <a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
+ {{ctx.AvatarUtils.Avatar .Poster 24}}
+ </a>
+ {{end}}
+ <span class="text grey muted-links">
+ {{ctx.Locale.Tr "action.review_dismissed_reason"}}
+ </span>
+ </div>
+ <div class="ui attached segment">
+ <div class="render-content markup">
+ {{if .RenderedContent}}
+ {{.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ {{else if eq .Type 33}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-git-branch"}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if and .OldRef .NewRef}}
+ {{ctx.Locale.Tr "repo.issues.change_ref_at" .OldRef .NewRef $createdStr}}
+ {{else if .OldRef}}
+ {{ctx.Locale.Tr "repo.issues.remove_ref_at" .OldRef $createdStr}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.add_ref_at" .NewRef $createdStr}}
+ {{end}}
+ </span>
+ </div>
+ {{else if or (eq .Type 34) (eq .Type 35)}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-git-merge" 16}}</span>
+ <span class="text grey muted-links">
+ {{template "repo/issue/view_content/comments_authorlink" dict "ctxData" $ "comment" .}}
+ {{if eq .Type 34}}{{ctx.Locale.Tr "repo.pulls.auto_merge_newly_scheduled_comment" $createdStr}}
+ {{else}}{{ctx.Locale.Tr "repo.pulls.auto_merge_canceled_schedule_comment" $createdStr}}{{end}}
+ </span>
+ </div>
+ {{else if or (eq .Type 36) (eq .Type 37)}}
+ <div class="timeline-item event" id="{{.HashTag}}">
+ <span class="badge">{{svg "octicon-pin" 16}}</span>
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ <span class="text grey muted-links">
+ {{template "shared/user/authorlink" .Poster}}
+ {{if eq .Type 36}}{{ctx.Locale.Tr "repo.issues.pin_comment" $createdStr}}
+ {{else}}{{ctx.Locale.Tr "repo.issues.unpin_comment" $createdStr}}{{end}}
+ </span>
+ </div>
+ {{end}}
+ {{end}}
+{{end}}
diff --git a/templates/repo/issue/view_content/comments_authorlink.tmpl b/templates/repo/issue/view_content/comments_authorlink.tmpl
new file mode 100644
index 00000000..f652a0be
--- /dev/null
+++ b/templates/repo/issue/view_content/comments_authorlink.tmpl
@@ -0,0 +1,11 @@
+{{if .comment.OriginalAuthor}}
+ <span class="text black">
+ {{svg (MigrationIcon .ctxData.Repository.GetOriginalURLHostname)}}
+ {{.comment.OriginalAuthor}}
+ </span>
+ {{if .ctxData.Repository.OriginalURL}}
+ <span class="migrate">({{ctx.Locale.Tr "repo.migrated_from" .ctxData.Repository.OriginalURL .ctxData.Repository.GetOriginalURLHostname}})</span>
+ {{end}}
+{{else}}
+ {{template "shared/user/authorlink" .comment.Poster}}
+{{end}}
diff --git a/templates/repo/issue/view_content/comments_delete_time.tmpl b/templates/repo/issue/view_content/comments_delete_time.tmpl
new file mode 100644
index 00000000..2377e7c4
--- /dev/null
+++ b/templates/repo/issue/view_content/comments_delete_time.tmpl
@@ -0,0 +1,18 @@
+{{if and .comment.Time (.ctxData.Repository.IsTimetrackerEnabled ctx)}} {{/* compatibility with time comments made before v1.14 */}}
+ {{if (not .comment.Time.Deleted)}}
+ {{if (or .ctxData.IsAdmin (and .ctxData.IsSigned (eq .ctxData.SignedUserID .comment.PosterID)))}}
+ <span class="tw-float-right">
+ <div class="ui mini modal issue-delete-time-modal" data-id="{{.comment.Time.ID}}">
+ <form method="post" class="delete-time-form" action="{{.ctxData.RepoLink}}/issues/{{.ctxData.Issue.Index}}/times/{{.comment.TimeID}}/delete">
+ {{.ctxData.CsrfTokenHtml}}
+ </form>
+ <div class="header">{{ctx.Locale.Tr "repo.issues.del_time"}}</div>
+ {{template "base/modal_actions_confirm"}}
+ </div>
+ <button class="ui icon button compact mini issue-delete-time" data-id="{{.comment.Time.ID}}" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.del_time"}}">
+ {{svg "octicon-trash"}}
+ </button>
+ </span>
+ {{end}}
+ {{end}}
+{{end}}
diff --git a/templates/repo/issue/view_content/context_menu.tmpl b/templates/repo/issue/view_content/context_menu.tmpl
new file mode 100644
index 00000000..4afd73c3
--- /dev/null
+++ b/templates/repo/issue/view_content/context_menu.tmpl
@@ -0,0 +1,27 @@
+<div class="item action ui dropdown jump pointing top right context-dropdown">
+ <a class="context-menu muted">
+ {{svg "octicon-kebab-horizontal"}}
+ </a>
+ <div class="menu">
+ {{$referenceUrl := ""}}
+ {{if .issue}}
+ {{$referenceUrl = printf "%s#%s" .ctxData.Issue.Link .item.HashTag}}
+ {{else}}
+ {{$referenceUrl = printf "%s/files#%s" .ctxData.Issue.Link .item.HashTag}}
+ {{end}}
+ <div class="item context js-aria-clickable" data-clipboard-text-type="url" data-clipboard-text="{{$referenceUrl}}">{{ctx.Locale.Tr "repo.issues.context.copy_link"}}</div>
+ {{if and .ctxData.IsSigned (not .ctxData.Repository.IsArchived)}}
+ <div class="item context js-aria-clickable quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.HashTag}}-raw">{{ctx.Locale.Tr "repo.issues.context.quote_reply"}}</div>
+ {{if not .ctxData.UnitIssuesGlobalDisabled}}
+ <div class="item context js-aria-clickable reference-issue" data-target="{{.item.HashTag}}-raw" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-poster-username="{{.item.Poster.Name}}" data-reference="{{$referenceUrl}}">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</div>
+ {{end}}
+ {{if or .ctxData.Permission.IsAdmin .IsCommentPoster .ctxData.HasIssuesOrPullsWritePermission}}
+ <div class="divider"></div>
+ <div class="item context js-aria-clickable edit-content">{{ctx.Locale.Tr "repo.issues.context.edit"}}</div>
+ {{if .delete}}
+ <div class="item context js-aria-clickable delete-comment" data-comment-id={{.item.HashTag}} data-url="{{.ctxData.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{ctx.Locale.Tr "repo.issues.delete_comment_confirm"}}">{{ctx.Locale.Tr "repo.issues.context.delete"}}</div>
+ {{end}}
+ {{end}}
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/conversation.tmpl b/templates/repo/issue/view_content/conversation.tmpl
new file mode 100644
index 00000000..c788a611
--- /dev/null
+++ b/templates/repo/issue/view_content/conversation.tmpl
@@ -0,0 +1,137 @@
+{{$invalid := (index .comments 0).Invalidated}}
+{{$resolved := (index .comments 0).IsResolved}}
+{{$resolveDoer := (index .comments 0).ResolveDoer}}
+{{$isNotPending := (not (eq (index .comments 0).Review.Type 0))}}
+<div class="ui segments conversation-holder">
+ <div class="ui segment collapsible-comment-box tw-py-2 tw-flex tw-items-center tw-justify-between">
+ <div class="tw-flex tw-items-center">
+ <a href="{{(index .comments 0).CodeCommentLink ctx}}" class="file-comment tw-ml-2 tw-break-anywhere">{{(index .comments 0).TreePath}}</a>
+ {{if $invalid}}
+ <span class="ui label basic small tw-ml-2" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
+ {{ctx.Locale.Tr "repo.issues.review.outdated"}}
+ </span>
+ {{end}}
+ </div>
+ <div>
+ {{if or $invalid $resolved}}
+ <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if not $resolved}}tw-hidden {{end}}ui compact labeled button show-outdated tw-flex tw-items-center">
+ {{svg "octicon-unfold" 16 "tw-mr-2"}}
+ {{if $resolved}}
+ {{ctx.Locale.Tr "repo.issues.review.show_resolved"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.show_outdated"}}
+ {{end}}
+ </button>
+ <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if $resolved}}tw-hidden {{end}}ui compact labeled button hide-outdated tw-flex tw-items-center">
+ {{svg "octicon-fold" 16 "tw-mr-2"}}
+ {{if $resolved}}
+ {{ctx.Locale.Tr "repo.issues.review.hide_resolved"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.hide_outdated"}}
+ {{end}}
+ </button>
+ {{end}}
+ </div>
+ </div>
+ {{$diff := (CommentMustAsDiff ctx (index .comments 0))}}
+ {{if $diff}}
+ {{$file := (index $diff.Files 0)}}
+ <div id="code-preview-{{(index .comments 0).ID}}" class="ui table segment{{if $resolved}} tw-hidden{{end}}">
+ <div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}">
+ <div class="file-body file-code code-view code-diff code-diff-unified unicode-escaped">
+ <table>
+ <tbody>
+ {{template "repo/diff/section_unified" dict "file" $file "root" $}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ <div id="code-comments-{{(index .comments 0).ID}}" class="comment-code-cloud ui segment{{if $resolved}} tw-hidden{{end}}">
+ <div class="ui comments tw-mb-0">
+ {{range .comments}}
+ {{$createdSubStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
+ <div class="comment code-comment tw-pb-4" id="{{.HashTag}}">
+ <div class="content">
+ <div class="header comment-header">
+ <div class="comment-header-left tw-flex tw-items-center">
+ {{if not .OriginalAuthor}}
+ <a class="avatar">
+ {{ctx.AvatarUtils.Avatar .Poster 20}}
+ </a>
+ {{end}}
+ <span class="text grey muted-links">
+ {{if .OriginalAuthor}}
+ <span class="text black">
+ {{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
+ {{.OriginalAuthor}}
+ </span>
+ {{if $.Repository.OriginalURL}}
+ <span class="migrate">({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}})</span>
+ {{end}}
+ {{else}}
+ {{template "shared/user/authorlink" .Poster}}
+ {{end}}
+ {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdSubStr}}
+ </span>
+ </div>
+ <div class="comment-header-right actions tw-flex tw-items-center">
+ {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole "IsPull" $.Issue.IsPull}}
+ {{if not $.Repository.IsArchived}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
+ {{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
+ {{end}}
+ </div>
+ </div>
+ <div class="text comment-content">
+ <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
+ {{if .RenderedContent}}
+ {{.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ <div id="issuecomment-{{.ID}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
+ <div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
+ {{if .Attachments}}
+ {{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
+ {{end}}
+ </div>
+ {{$reactions := .Reactions.GroupByType}}
+ {{if $reactions}}
+ {{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+ </div>
+ <div class="code-comment-buttons tw-flex tw-items-center tw-flex-wrap tw-mt-2 tw-mb-1 tw-mx-2">
+ <div class="tw-flex-1">
+ {{if $resolved}}
+ <div class="ui grey text">
+ {{svg "octicon-check" 16 "tw-mr-1"}}
+ <b>{{$resolveDoer.Name}}</b> {{ctx.Locale.Tr "repo.issues.review.resolved_by"}}
+ </div>
+ {{end}}
+ </div>
+ <div class="code-comment-buttons-buttons button-row">
+ {{if and $.CanMarkConversation $isNotPending}}
+ <button class="ui tiny basic button resolve-conversation" data-origin="timeline" data-action="{{if not $resolved}}Resolve{{else}}UnResolve{{end}}" data-comment-id="{{(index .comments 0).ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation">
+ {{if $resolved}}
+ {{ctx.Locale.Tr "repo.issues.review.un_resolve_conversation"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.resolve_conversation"}}
+ {{end}}
+ </button>
+ {{end}}
+ {{if and $.SignedUserID (not $.Repository.IsArchived)}}
+ <button class="comment-form-reply ui primary tiny labeled icon button">
+ {{svg "octicon-reply" 16 "reply icon tw-mr-1"}}{{ctx.Locale.Tr "repo.diff.comment.reply"}}
+ </button>
+ {{end}}
+ </div>
+ </div>
+ {{template "repo/diff/comment_form_datahandler" dict "hidden" true "reply" (index .comments 0).ReviewID "root" $ "comment" (index .comments 0)}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl
new file mode 100644
index 00000000..2672bd33
--- /dev/null
+++ b/templates/repo/issue/view_content/pull.tmpl
@@ -0,0 +1,396 @@
+{{if and .Issue.PullRequest.HasMerged (not .IsPullBranchDeletable)}}
+{{/* Then the merge box will not be displayed because this page already contains enough information */}}
+{{else}}
+<div class="timeline-item comment merge box">
+ <div class="timeline-avatar text {{if .Issue.PullRequest.HasMerged}}purple
+ {{- else if .Issue.IsClosed}}grey
+ {{- else if .IsPullWorkInProgress}}grey
+ {{- else if .IsFilesConflicted}}grey
+ {{- else if .IsPullRequestBroken}}red
+ {{- else if .IsBlockedByApprovals}}red
+ {{- else if .IsBlockedByRejection}}red
+ {{- else if .IsBlockedByOfficialReviewRequests}}red
+ {{- else if .IsBlockedByOutdatedBranch}}red
+ {{- else if .IsBlockedByChangedProtectedFiles}}red
+ {{- else if and .EnableStatusCheck (or .RequiredStatusCheckState.IsFailure .RequiredStatusCheckState.IsError)}}red
+ {{- else if and .EnableStatusCheck (or (not $.LatestCommitStatus) .RequiredStatusCheckState.IsPending .RequiredStatusCheckState.IsWarning)}}yellow
+ {{- else if and .AllowMerge .RequireSigned (not .WillSign)}}red
+ {{- else if .Issue.PullRequest.IsChecking}}yellow
+ {{- else if .Issue.PullRequest.IsEmpty}}grey
+ {{- else if .Issue.PullRequest.CanAutoMerge}}green
+ {{- else}}red{{end}}">{{svg "octicon-git-merge" 40}}</div>
+ <div class="content">
+ {{if .LatestCommitStatus}}
+ <div class="ui attached segment fitted">
+ {{template "repo/pulls/status" (dict
+ "CommitStatus" .LatestCommitStatus
+ "CommitStatuses" .LatestCommitStatuses
+ "MissingRequiredChecks" .MissingRequiredChecks
+ "ShowHideChecks" true
+ "is_context_required" .is_context_required
+ )}}
+ </div>
+ {{end}}
+ {{$showGeneralMergeForm := false}}
+ <div class="ui attached segment merge-section {{if not $.LatestCommitStatus}}no-header{{end}} flex-items-block">
+ {{if .Issue.PullRequest.HasMerged}}
+ {{if .IsPullBranchDeletable}}
+ <div class="item item-section text tw-flex-1">
+ <div class="item-section-left">
+ <h3 class="tw-mb-2">
+ {{ctx.Locale.Tr "repo.pulls.merged_success"}}
+ </h3>
+ <div class="merge-section-info">
+ {{ctx.Locale.Tr "repo.pulls.merged_info_text" (HTMLFormat "<code>%s</code>" .HeadTarget)}}
+ </div>
+ </div>
+ <div class="item-section-right">
+ <button class="delete-button ui button" data-url="{{.DeleteBranchLink}}">{{ctx.Locale.Tr "repo.branch.delete_html"}}</button>
+ </div>
+ </div>
+ {{end}}
+ {{else if .Issue.IsClosed}}
+ <div class="item item-section text tw-flex-1">
+ <div class="item-section-left">
+ <h3 class="tw-mb-2">{{ctx.Locale.Tr "repo.pulls.closed"}}</h3>
+ <div class="merge-section-info">
+ {{if .IsPullRequestBroken}}
+ {{ctx.Locale.Tr "repo.pulls.cant_reopen_deleted_branch"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.pulls.reopen_to_merge"}}
+ {{end}}
+ </div>
+ </div>
+ {{if and .IsPullBranchDeletable (not .IsPullRequestBroken)}}
+ <div class="item-section-right">
+ <button class="delete-button ui button" data-url="{{.DeleteBranchLink}}">{{ctx.Locale.Tr "repo.branch.delete_html"}}</button>
+ </div>
+ {{end}}
+ </div>
+ {{else if .IsPullFilesConflicted}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.files_conflicted"}}
+ </div>
+ <ul>
+ {{range .ConflictedFiles}}
+ <li>{{.}}</li>
+ {{end}}
+ </ul>
+ {{else if .IsPullRequestBroken}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.data_broken"}}
+ </div>
+ {{else if .IsPullWorkInProgress}}
+ <div class="item toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefixes="{{JsonUtils.EncodeToString .PullRequestWorkInProgressPrefixes}}" data-update-url="{{.Issue.Link}}/title">
+ <div class="item-section-left flex-text-inline tw-flex-1">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}}
+ </div>
+ {{if or .HasIssuesOrPullsWritePermission .IsIssuePoster}}
+ <button class="ui compact button">
+ {{ctx.Locale.Tr "repo.pulls.remove_prefix" .WorkInProgressPrefix}}
+ </button>
+ {{end}}
+ </div>
+ {{template "repo/issue/view_content/update_branch_by_merge" $}}
+ {{else if .Issue.PullRequest.IsChecking}}
+ <div class="item">
+ {{svg "octicon-sync"}}
+ {{ctx.Locale.Tr "repo.pulls.is_checking"}}
+ </div>
+ {{else if .Issue.PullRequest.IsAncestor}}
+ <div class="item">
+ {{svg "octicon-alert"}}
+ {{ctx.Locale.Tr "repo.pulls.is_ancestor"}}
+ </div>
+ {{else if or .Issue.PullRequest.CanAutoMerge .Issue.PullRequest.IsEmpty}}
+ {{if .IsBlockedByApprovals}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .ProtectedBranch.RequiredApprovals}}
+ </div>
+ {{else if .IsBlockedByRejection}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_rejection"}}
+ </div>
+ {{else if .IsBlockedByOfficialReviewRequests}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_official_review_requests"}}
+ </div>
+ {{else if .IsBlockedByOutdatedBranch}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_outdated_branch"}}
+ </div>
+ {{else if .IsBlockedByChangedProtectedFiles}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.TrN $.ChangedProtectedFilesNum "repo.pulls.blocked_by_changed_protected_files_1" "repo.pulls.blocked_by_changed_protected_files_n"}}
+ </div>
+ <ul>
+ {{range .ChangedProtectedFiles}}
+ <li>{{.}}</li>
+ {{end}}
+ </ul>
+ {{else if and .EnableStatusCheck (or .RequiredStatusCheckState.IsError .RequiredStatusCheckState.IsFailure)}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.required_status_check_failed"}}
+ </div>
+ {{else if and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess)}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.required_status_check_missing"}}
+ </div>
+ {{else if and .AllowMerge .RequireSigned (not .WillSign)}}
+ <div class="item">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.require_signed_wont_sign"}}
+ </div>
+ <div class="item">
+ {{svg "octicon-unlock"}}
+ {{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .WontSignReason)}}
+ </div>
+ {{end}}
+
+ {{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection .IsBlockedByOfficialReviewRequests .IsBlockedByOutdatedBranch .IsBlockedByChangedProtectedFiles (and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess))}}
+
+ {{/* admin can merge without checks, writer can merge when checks succeed */}}
+ {{$canMergeNow := and (or (and $.IsRepoAdmin (not .ProtectedBranch.ApplyToAdmins)) (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}}
+ {{/* admin and writer both can make an auto merge schedule */}}
+
+ {{if $canMergeNow}}
+ {{if $notAllOverridableChecksOk}}
+ <div class="item">
+ {{svg "octicon-dot-fill"}}
+ {{ctx.Locale.Tr "repo.pulls.required_status_check_administrator"}}
+ </div>
+ {{else}}
+ <div class="item">
+ {{svg "octicon-check"}}
+ {{ctx.Locale.Tr "repo.pulls.can_auto_merge_desc"}}
+ </div>
+ {{end}}
+ {{if .WillSign}}
+ <div class="item">
+ {{svg "octicon-lock" 16 "text green"}}
+ {{ctx.Locale.Tr "repo.signing.will_sign" .SigningKey}}
+ </div>
+ {{else if .IsSigned}}
+ <div class="item">
+ {{svg "octicon-unlock"}}
+ {{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .WontSignReason)}}
+ </div>
+ {{end}}
+ {{end}}
+ {{template "repo/issue/view_content/update_branch_by_merge" $}}
+ {{if .Issue.PullRequest.IsEmpty}}
+ <div class="divider"></div>
+
+ <div class="item">
+ {{svg "octicon-alert"}}
+ {{ctx.Locale.Tr "repo.pulls.is_empty"}}
+ </div>
+ {{end}}
+
+ {{if .AllowMerge}} {{/* user is allowed to merge */}}
+ {{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
+ {{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}}
+ {{$hasPendingPullRequestMergeTip := ""}}
+ {{if .HasPendingPullRequestMerge}}
+ {{$createdPRMergeStr := TimeSinceUnix .PendingPullRequestMerge.CreatedUnix ctx.Locale}}
+ {{$hasPendingPullRequestMergeTip = ctx.Locale.Tr "repo.pulls.auto_merge_has_pending_schedule" .PendingPullRequestMerge.Doer.Name $createdPRMergeStr}}
+ {{end}}
+ <div class="divider"></div>
+ <script type="module">
+ const defaultMergeTitle = {{.DefaultMergeMessage}};
+ const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}};
+ const defaultMergeMessage = {{.DefaultMergeBody}};
+ const defaultSquashMergeMessage = {{.DefaultSquashMergeBody}};
+ const mergeForm = {
+ 'baseLink': {{.Link}},
+ 'textCancel': {{ctx.Locale.Tr "cancel"}},
+ 'textDeleteBranch': {{ctx.Locale.Tr "repo.branch.delete" .HeadTarget}},
+ 'textAutoMergeButtonWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_button_when_succeed"}},
+ 'textAutoMergeWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_when_succeed"}},
+ 'textAutoMergeCancelSchedule': {{ctx.Locale.Tr "repo.pulls.auto_merge_cancel_schedule"}},
+ 'textClearMergeMessage': {{ctx.Locale.Tr "repo.pulls.clear_merge_message"}},
+ 'textClearMergeMessageHint': {{ctx.Locale.Tr "repo.pulls.clear_merge_message_hint"}},
+ 'textMergeCommitId': {{ctx.Locale.Tr "repo.pulls.merge_commit_id"}},
+
+ 'canMergeNow': {{$canMergeNow}},
+ 'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
+ 'emptyCommit': {{.Issue.PullRequest.IsEmpty}},
+ 'pullHeadCommitID': {{.PullHeadCommitID}},
+ 'isPullBranchDeletable': {{.IsPullBranchDeletable}},
+ 'defaultMergeStyle': {{.MergeStyle}},
+ 'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}},
+ 'mergeMessageFieldPlaceHolder': {{ctx.Locale.Tr "repo.editor.commit_message_desc"}},
+ 'defaultMergeMessage': defaultMergeMessage,
+
+ 'hasPendingPullRequestMerge': {{.HasPendingPullRequestMerge}},
+ 'hasPendingPullRequestMergeTip': {{$hasPendingPullRequestMergeTip}},
+ };
+
+ const generalHideAutoMerge = mergeForm.canMergeNow && mergeForm.allOverridableChecksOk; // if this pr can be merged now, then hide the auto merge
+ mergeForm['mergeStyles'] = [
+ {
+ 'name': 'merge',
+ 'allowed': {{$prUnit.PullRequestsConfig.AllowMerge}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_pull_request"}},
+ 'mergeTitleFieldText': defaultMergeTitle,
+ 'mergeMessageFieldText': defaultMergeMessage,
+ 'hideAutoMerge': generalHideAutoMerge,
+ },
+ {
+ 'name': 'rebase',
+ 'allowed': {{$prUnit.PullRequestsConfig.AllowRebase}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}},
+ 'hideMergeMessageTexts': true,
+ 'hideAutoMerge': generalHideAutoMerge,
+ },
+ {
+ 'name': 'rebase-merge',
+ 'allowed': {{$prUnit.PullRequestsConfig.AllowRebaseMerge}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}},
+ 'mergeTitleFieldText': defaultMergeTitle,
+ 'mergeMessageFieldText': defaultMergeMessage,
+ 'hideAutoMerge': generalHideAutoMerge,
+ },
+ {
+ 'name': 'squash',
+ 'allowed': {{$prUnit.PullRequestsConfig.AllowSquash}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}},
+ 'mergeTitleFieldText': defaultSquashMergeTitle,
+ 'mergeMessageFieldText': {{.GetCommitMessages}} + defaultSquashMergeMessage,
+ 'hideAutoMerge': generalHideAutoMerge,
+ },
+ {
+ 'name': 'fast-forward-only',
+ 'allowed': {{and $prUnit.PullRequestsConfig.AllowFastForwardOnly (eq .Issue.PullRequest.CommitsBehind 0)}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.fast_forward_only_merge_pull_request"}},
+ 'hideMergeMessageTexts': true,
+ 'hideAutoMerge': generalHideAutoMerge,
+ },
+ {
+ 'name': 'manually-merged',
+ 'allowed': {{$prUnit.PullRequestsConfig.AllowManualMerge}},
+ 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_manually"}},
+ 'hideMergeMessageTexts': true,
+ 'hideAutoMerge': true,
+ }
+ ];
+ window.config.pageData.pullRequestMergeForm = mergeForm;
+ </script>
+
+ {{$showGeneralMergeForm = true}}
+ <div id="pull-request-merge-form"></div>
+ {{else}}
+ {{/* no merge style was set in repo setting: not or ($prUnit.PullRequestsConfig.AllowMerge ...) */}}
+ <div class="divider"></div>
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.no_merge_desc"}}
+ </div>
+ <div class="item">
+ {{svg "octicon-info"}}
+ {{ctx.Locale.Tr "repo.pulls.no_merge_helper"}}
+ </div>
+ {{end}} {{/* end if the repo was set to use any merge style */}}
+ {{else}}
+ {{/* user is not allowed to merge */}}
+ <div class="divider"></div>
+ <div class="item">
+ {{svg "octicon-info"}}
+ {{ctx.Locale.Tr "repo.pulls.no_merge_access"}}
+ </div>
+ {{end}} {{/* end if user is allowed to merge or not */}}
+ {{else}}
+ {{/* Merge conflict without specific file. Suggest manual merge, only if all reviews and status checks OK. */}}
+ {{if .IsBlockedByApprovals}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .ProtectedBranch.RequiredApprovals}}
+ </div>
+ {{else if .IsBlockedByRejection}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_rejection"}}
+ </div>
+ {{else if .IsBlockedByOfficialReviewRequests}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_official_review_requests"}}
+ </div>
+ {{else if .IsBlockedByOutdatedBranch}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.blocked_by_outdated_branch"}}
+ </div>
+ {{else if .IsBlockedByChangedProtectedFiles}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.TrN $.ChangedProtectedFilesNum "repo.pulls.blocked_by_changed_protected_files_1" "repo.pulls.blocked_by_changed_protected_files_n"}}
+ </div>
+ <ul>
+ {{range .ChangedProtectedFiles}}
+ <li>{{.}}</li>
+ {{end}}
+ </ul>
+ {{else if and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess)}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.required_status_check_failed"}}
+ </div>
+ {{else if and .RequireSigned (not .WillSign)}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.require_signed_wont_sign"}}
+ </div>
+ {{else}}
+ <div class="item text red">
+ {{svg "octicon-x"}}
+ {{ctx.Locale.Tr "repo.pulls.cannot_auto_merge_desc"}}
+ </div>
+ <div class="item">
+ {{svg "octicon-info"}}
+ {{ctx.Locale.Tr "repo.pulls.cannot_auto_merge_helper"}}
+ </div>
+ {{end}}
+ {{end}}{{/* end if: pull request status */}}
+
+ {{/*
+ Manually Merged is not a well-known feature, it is used to mark a non-mergeable PR (already merged, conflicted) as merged
+ To test it:
+ * Enable "Manually Merged" feature in the Repository Settings
+ * Create a pull request, either:
+ * - Merge the pull request branch locally and push the merged commit to Gitea
+ * - Make some conflicts between the base branch and the pull request branch
+ * Then the Manually Merged form will be shown in the merge form
+ */}}
+ {{if and $.StillCanManualMerge (not $showGeneralMergeForm)}}
+ <div class="divider"></div>
+ <div class="ui form">
+ <form action="{{.Link}}/merge" method="post" class="form-fetch-action">
+ {{.CsrfTokenHtml}}
+ <div class="field">
+ <input type="text" name="merge_commit_id" placeholder="{{ctx.Locale.Tr "repo.pulls.merge_commit_id"}}">
+ </div>
+ <button class="ui red button" type="submit" name="do" value="manually-merged">
+ {{ctx.Locale.Tr "repo.pulls.merge_manually"}}
+ </button>
+ </form>
+ </div>
+ {{end}}
+
+ {{if and .Issue.PullRequest.HeadRepo (not .Issue.PullRequest.HasMerged) (not .Issue.IsClosed)}}
+ {{template "repo/issue/view_content/pull_merge_instruction" dict "PullRequest" .Issue.PullRequest "ShowMergeInstructions" .ShowMergeInstructions}}
+ {{end}}
+ </div>
+ </div>
+</div>
+{{end}}
diff --git a/templates/repo/issue/view_content/pull_merge_instruction.tmpl b/templates/repo/issue/view_content/pull_merge_instruction.tmpl
new file mode 100644
index 00000000..e8910280
--- /dev/null
+++ b/templates/repo/issue/view_content/pull_merge_instruction.tmpl
@@ -0,0 +1,49 @@
+<div class="divider"></div>
+<details class="collapsible">
+ <summary class="tw-py-2"> {{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}} </summary>
+ <div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}</div>
+ {{$localBranch := .PullRequest.HeadBranch}}
+ {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}
+ {{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}}
+ {{end}}
+ <div class="ui secondary segment">
+ {{if eq .PullRequest.Flow 0}}
+ <div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}<origin-url data-url="{{.PullRequest.HeadRepo.Link}}"></origin-url>{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div>
+ {{else}}
+ <div>git fetch -u origin +refs/pull/{{.PullRequest.Index}}/head:{{$localBranch}}</div>
+ {{end}}
+ <div>git checkout {{$localBranch}}</div>
+ </div>
+ {{if .ShowMergeInstructions}}
+ <div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}}</div>
+ <div class="ui secondary segment">
+ <div data-pull-merge-style="merge">
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge --no-ff {{$localBranch}}</div>
+ </div>
+ <div class="tw-hidden" data-pull-merge-style="rebase">
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge --ff-only {{$localBranch}}</div>
+ </div>
+ <div class="tw-hidden" data-pull-merge-style="rebase-merge">
+ <div>git checkout {{$localBranch}}</div>
+ <div>git rebase {{.PullRequest.BaseBranch}}</div>
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge --no-ff {{$localBranch}}</div>
+ </div>
+ <div class="tw-hidden" data-pull-merge-style="squash">
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge --squash {{$localBranch}}</div>
+ </div>
+ <div class="tw-hidden" data-pull-merge-style="fast-forward-only">
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge --ff-only {{$localBranch}}</div>
+ </div>
+ <div class="tw-hidden" data-pull-merge-style="manually-merged">
+ <div>git checkout {{.PullRequest.BaseBranch}}</div>
+ <div>git merge {{$localBranch}}</div>
+ </div>
+ <div>git push origin {{.PullRequest.BaseBranch}}</div>
+ </div>
+ {{end}}
+</details>
diff --git a/templates/repo/issue/view_content/reactions.tmpl b/templates/repo/issue/view_content/reactions.tmpl
new file mode 100644
index 00000000..da631966
--- /dev/null
+++ b/templates/repo/issue/view_content/reactions.tmpl
@@ -0,0 +1,17 @@
+<div class="ui attached segment reactions" data-action-url="{{$.ActionURL}}">
+{{range $key, $value := .Reactions}}
+ {{$hasReacted := $value.HasUser $.ctxData.SignedUserID}}
+ <a role="button" class="ui label basic{{if $hasReacted}} primary{{end}}{{if not $.ctxData.IsSigned}} disabled{{end}} comment-reaction-button"
+ data-tooltip-content
+ title="{{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
+ aria-label="{{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
+ data-tooltip-placement="bottom-start"
+ data-reaction-content="{{$key}}" data-has-reacted="{{$hasReacted}}">
+ <span class="reaction">{{ReactionToEmoji $key}}</span>
+ <span class="reaction-count">{{len $value}}</span>
+ </a>
+{{end}}
+{{if AllowedReactions}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $.ctxData "ActionURL" .ActionURL}}
+{{end}}
+</div>
diff --git a/templates/repo/issue/view_content/reference_issue_dialog.tmpl b/templates/repo/issue/view_content/reference_issue_dialog.tmpl
new file mode 100644
index 00000000..c7a471f5
--- /dev/null
+++ b/templates/repo/issue/view_content/reference_issue_dialog.tmpl
@@ -0,0 +1,28 @@
+<div class="ui small modal" id="reference-issue-modal">
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.context.reference_issue"}}
+ </div>
+ <div class="content">
+ <form class="ui form form-fetch-action" action="{{.Repository.Link}}/issues/new" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="field">
+ <label><strong>{{ctx.Locale.Tr "repository"}}</strong></label>
+ <div class="ui search selection dropdown issue_reference_repository_search">
+ <div class="default text gt-ellipsis">{{.Repository.FullName}}</div>
+ <div class="menu"></div>
+ </div>
+ </div>
+ <div class="field">
+ <label><strong>{{ctx.Locale.Tr "repo.milestones.title"}}</strong></label>
+ <input name="title" value="" autofocus required maxlength="255" autocomplete="off">
+ </div>
+ <div class="field">
+ <label><strong>{{ctx.Locale.Tr "repo.issues.reference_issue.body"}}</strong></label>
+ <textarea name="content"></textarea>
+ </div>
+ <div class="text right">
+ <button class="ui primary button">{{ctx.Locale.Tr "repo.issues.create"}}</button>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/show_role.tmpl b/templates/repo/issue/view_content/show_role.tmpl
new file mode 100644
index 00000000..0f1b8955
--- /dev/null
+++ b/templates/repo/issue/view_content/show_role.tmpl
@@ -0,0 +1,15 @@
+{{if and .ShowRole.IsPoster (not .IgnorePoster)}}
+ <div class="ui basic label role-label" data-tooltip-content="
+ {{if .IsPull}}
+ {{ctx.Locale.Tr "repo.issues.author.tooltip.pr"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.author.tooltip.issue"}}
+ {{end}}">
+ {{ctx.Locale.Tr "repo.issues.author"}}
+ </div>
+{{end}}
+{{if .ShowRole.RoleInRepo}}
+ <div class="ui basic label role-label" data-tooltip-content="{{.ShowRole.RoleInRepo.LocaleHelper ctx.Locale}}">
+ {{.ShowRole.RoleInRepo.LocaleString ctx.Locale}}
+ </div>
+{{end}}
diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl
new file mode 100644
index 00000000..ba155398
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar.tmpl
@@ -0,0 +1,66 @@
+<div class="issue-content-right ui segment">
+ {{template "repo/issue/view_content/sidebar/branch_selector_field" .}}
+ {{if .Issue.IsPull}}
+ {{template "repo/issue/view_content/sidebar/pull_review" .}}
+ {{template "repo/issue/view_content/sidebar/pull_wip" .}}
+ <div class="divider"></div>
+ {{end}}
+
+ {{template "repo/issue/labels/labels_selector_field" .}}
+ {{template "repo/issue/labels/labels_sidebar" dict "root" $}}
+
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/milestones" .}}
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/projects" .}}
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/assignees" .}}
+ <div class="divider"></div>
+
+ {{if .Participants}}
+ {{template "repo/issue/view_content/sidebar/participants" .}}
+ {{end}}
+
+ {{if and $.IssueWatch (not .Repository.IsArchived)}}
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/watch" .}}
+ {{end}}
+
+ {{if .Repository.IsTimetrackerEnabled $.Context}}
+ {{template "repo/issue/view_content/sidebar/timetracking" .}}
+ {{end}}
+
+ <div class="divider"></div>
+ {{template "repo/issue/view_content/sidebar/due_deadline" .}}
+
+ {{if .Repository.IsDependenciesEnabled $.Context}}
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/dependencies" .}}
+ {{end}}
+
+ <div class="divider"></div>
+ {{template "repo/issue/view_content/sidebar/reference" .}}
+
+ {{if and .IsRepoAdmin (not .Repository.IsArchived)}}
+ <div class="divider"></div>
+
+ {{template "repo/issue/view_content/sidebar/actions" .}}
+ {{end}}
+
+ {{if and
+ .Issue.IsPull
+ .IsIssuePoster
+ (not .Issue.IsClosed)
+ .Issue.PullRequest.HeadRepo
+ (not (eq .Issue.PullRequest.HeadRepo.FullName .Issue.PullRequest.BaseRepo.FullName))
+ .CanWriteToHeadRepo
+ }}
+ <div class="divider"></div>
+ {{template "repo/issue/view_content/sidebar/pull_maintainer_edits" .}}
+ {{end}}
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/actions.tmpl b/templates/repo/issue/view_content/sidebar/actions.tmpl
new file mode 100644
index 00000000..36f21822
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/actions.tmpl
@@ -0,0 +1,114 @@
+{{if or .PinEnabled .Issue.IsPinned}}
+ <form class="tw-mt-1 form-fetch-action single-button-form" method="post" {{if $.NewPinAllowed}}action="{{.Issue.Link}}/pin"{{else}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.max_pinned"}}"{{end}}>
+ {{$.CsrfTokenHtml}}
+ <button class="fluid ui button {{if not $.NewPinAllowed}}disabled{{end}}">
+ {{if not .Issue.IsPinned}}
+ {{svg "octicon-pin" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "pin"}}
+ {{else}}
+ {{svg "octicon-pin-slash" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "unpin"}}
+ {{end}}
+ </button>
+ </form>
+{{end}}
+
+<button class="tw-mt-1 fluid ui show-modal button {{if .Issue.IsLocked}} negative {{end}}" data-modal="#lock">
+ {{if .Issue.IsLocked}}
+ {{svg "octicon-key"}}
+ {{ctx.Locale.Tr "repo.issues.unlock"}}
+ {{else}}
+ {{svg "octicon-lock"}}
+ {{ctx.Locale.Tr "repo.issues.lock"}}
+ {{end}}
+</button>
+<div class="ui tiny modal" id="lock">
+ <div class="header">
+ {{if .Issue.IsLocked}}
+ {{ctx.Locale.Tr "repo.issues.unlock.title"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.lock.title"}}
+ {{end}}
+ </div>
+ <div class="content">
+ <div class="ui warning message">
+ {{if .Issue.IsLocked}}
+ {{ctx.Locale.Tr "repo.issues.unlock.notice_1"}}<br>
+ {{ctx.Locale.Tr "repo.issues.unlock.notice_2"}}<br>
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.lock.notice_1"}}<br>
+ {{ctx.Locale.Tr "repo.issues.lock.notice_2"}}<br>
+ {{ctx.Locale.Tr "repo.issues.lock.notice_3"}}<br>
+ {{end}}
+ </div>
+
+ <form class="ui form form-fetch-action" action="{{.Issue.Link}}{{if .Issue.IsLocked}}/unlock{{else}}/lock{{end}}"
+ method="post">
+ {{.CsrfTokenHtml}}
+
+ {{if not .Issue.IsLocked}}
+ <div class="field">
+ <strong> {{ctx.Locale.Tr "repo.issues.lock.reason"}} </strong>
+ </div>
+
+ <div class="field">
+ <div class="ui fluid dropdown selection">
+
+ <select name="reason">
+ <option value=""> </option>
+ {{range .LockReasons}}
+ <option value="{{.}}">{{.}}</option>
+ {{end}}
+ </select>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+
+ <div class="default text"> </div>
+
+ <div class="menu">
+ {{range .LockReasons}}
+ <div class="item" data-value="{{.}}">{{.}}</div>
+ {{end}}
+ </div>
+ </div>
+ </div>
+ {{end}}
+
+ <div class="text right actions">
+ <button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
+ <button class="ui red button">
+ {{if .Issue.IsLocked}}
+ {{ctx.Locale.Tr "repo.issues.unlock_confirm"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.lock_confirm"}}
+ {{end}}
+ </button>
+ </div>
+ </form>
+ </div>
+</div>
+<button class="tw-mt-1 fluid ui show-modal button" data-modal="#sidebar-delete-issue">
+ {{svg "octicon-trash"}}
+ {{ctx.Locale.Tr "repo.issues.delete"}}
+</button>
+<div class="ui g-modal-confirm modal" id="sidebar-delete-issue">
+ <div class="header">
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.pulls.delete.title"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.delete.title"}}
+ {{end}}
+ </div>
+ <div class="content">
+ <p>
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.pulls.delete.text"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.delete.text"}}
+ {{end}}
+ </p>
+ </div>
+ <form action="{{.Issue.Link}}/delete" method="post">
+ {{.CsrfTokenHtml}}
+ {{template "base/modal_actions_confirm" .}}
+ </form>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/assignees.tmpl b/templates/repo/issue/view_content/sidebar/assignees.tmpl
new file mode 100644
index 00000000..e51bda95
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/assignees.tmpl
@@ -0,0 +1,45 @@
+<input id="assignee_id" name="assignee_id" type="hidden" value="{{.assignee_id}}">
+<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-assignees-modify dropdown">
+ <a class="text muted flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.assignees"}}</strong>
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </a>
+ <div class="filter menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/assignee">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignees"}}">
+ </div>
+ <div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}</div>
+ {{range .Assignees}}
+
+ {{$AssigneeID := .ID}}
+ <a class="item{{range $.Issue.Assignees}}{{if eq .ID $AssigneeID}} checked{{end}}{{end}}" href="#" data-id="{{.ID}}" data-id-selector="#assignee_{{.ID}}">
+ {{$checked := false}}
+ {{range $.Issue.Assignees}}
+ {{if eq .ID $AssigneeID}}
+ {{$checked = true}}
+ {{end}}
+ {{end}}
+ <span class="octicon-check {{if not $checked}}tw-invisible{{end}}">{{svg "octicon-check"}}</span>
+ <span class="text">
+ {{ctx.AvatarUtils.Avatar . 20 "tw-mr-2"}}{{template "repo/search_name" .}}
+ </span>
+ </a>
+ {{end}}
+ </div>
+</div>
+<div class="ui assignees list">
+ <span class="no-select item {{if .Issue.Assignees}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_assignees"}}</span>
+ <div class="selected">
+ {{range .Issue.Assignees}}
+ <div class="item">
+ <a class="muted sidebar-item-link" href="{{$.RepoLink}}/{{if $.Issue.IsPull}}pulls{{else}}issues{{end}}?assignee={{.ID}}">
+ {{ctx.AvatarUtils.Avatar . 28 "tw-mr-2"}}
+ {{.GetDisplayName}}
+ </a>
+ </div>
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl b/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl
new file mode 100644
index 00000000..c23e13b2
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl
@@ -0,0 +1,59 @@
+{{if and (not .Issue.IsPull) (not .PageIsComparePull)}}
+<input id="ref_selector" name="ref" type="hidden" value="{{.Reference}}">
+<input id="editing_mode" name="edit_mode" type="hidden" value="{{(or .IsIssueWriter .HasIssuesOrPullsWritePermission)}}">
+<form method="post" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/ref" id="update_issueref_form">
+ {{$.CsrfTokenHtml}}
+</form>
+{{/* TODO: share this branch selector dropdown with the same in repo page */}}
+<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating filter select-branch dropdown tw-max-w-full" data-no-results="{{ctx.Locale.Tr "repo.pulls.no_results"}}">
+ <div class="ui basic small button">
+ <span class="text branch-name gt-ellipsis">{{if .Reference}}{{$.RefEndName}}{{else}}{{ctx.Locale.Tr "repo.issues.no_ref"}}{{end}}</span>
+ {{if .HasIssuesOrPullsWritePermission}}{{svg "octicon-triangle-down" 14 "dropdown icon"}}{{end}}
+ </div>
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-filter" 16}}</i>
+ <input name="search" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}...">
+ </div>
+ <div class="header">
+ <div class="ui grid">
+ <div class="two column row">
+ <a class="reference column muted" href="#" data-target="#branch-list">
+ <span class="text black">
+ {{svg "octicon-git-branch" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.branches"}}
+ </span>
+ </a>
+ <a class="reference column muted" href="#" data-target="#tag-list">
+ <span class="text">
+ {{svg "octicon-tag" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.tags"}}
+ </span>
+ </a>
+ </div>
+ </div>
+ </div>
+ <div class="branch-tag-divider"></div>
+ <div id="branch-list" class="scrolling menu reference-list-menu {{if not .Issue}}new-issue{{end}}">
+ {{if .Reference}}
+ <div class="item text small" data-id="" data-id-selector="#ref_selector"><strong><a href="#">{{ctx.Locale.Tr "repo.clear_ref"}}</a></strong></div>
+ {{end}}
+ {{range .Branches}}
+ <div class="item" data-id="refs/heads/{{.}}" data-name="{{.}}" data-id-selector="#ref_selector" title="{{.}}">{{.}}</div>
+ {{else}}
+ <div class="item">{{ctx.Locale.Tr "repo.pulls.no_results"}}</div>
+ {{end}}
+ </div>
+ <div id="tag-list" class="scrolling menu reference-list-menu {{if not .Issue}}new-issue{{end}} tw-hidden">
+ {{if .Reference}}
+ <div class="item text small" data-id="" data-id-selector="#ref_selector"><strong><a href="#">{{ctx.Locale.Tr "repo.clear_ref"}}</a></strong></div>
+ {{end}}
+ {{range .Tags}}
+ <div class="item" data-id="refs/tags/{{.}}" data-name="tags/{{.}}" data-id-selector="#ref_selector">{{.}}</div>
+ {{else}}
+ <div class="item">{{ctx.Locale.Tr "repo.pulls.no_results"}}</div>
+ {{end}}
+ </div>
+ </div>
+</div>
+
+<div class="divider"></div>
+{{end}}
diff --git a/templates/repo/issue/view_content/sidebar/dependencies.tmpl b/templates/repo/issue/view_content/sidebar/dependencies.tmpl
new file mode 100644
index 00000000..791bd5c4
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/dependencies.tmpl
@@ -0,0 +1,145 @@
+<div class="ui depending">
+ {{if (and (not .BlockedByDependencies) (not .BlockedByDependenciesNotPermitted) (not .BlockingDependencies) (not .BlockingDependenciesNotPermitted))}}
+ <span class="text"><strong>{{ctx.Locale.Tr "repo.issues.dependency.title"}}</strong></span>
+ <br>
+ <p>
+ {{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.issues.dependency.pr_no_dependencies"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.dependency.issue_no_dependencies"}}
+ {{end}}
+ </p>
+ {{end}}
+
+ {{if or .BlockingDependencies .BlockingDependenciesNotPermitted}}
+ <span class="text" data-tooltip-content="{{if .Issue.IsPull}}{{ctx.Locale.Tr "repo.issues.dependency.pr_close_blocks"}}{{else}}{{ctx.Locale.Tr "repo.issues.dependency.issue_close_blocks"}}{{end}}">
+ <strong>{{ctx.Locale.Tr "repo.issues.dependency.blocks_short"}}</strong>
+ </span>
+ <div class="ui relaxed divided list">
+ {{range .BlockingDependencies}}
+ <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between">
+ <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis">
+ <a class="title muted" href="{{.Issue.Link}}" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}">
+ #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}
+ </a>
+ <div class="text small gt-ellipsis" data-tooltip-content="{{.Repository.OwnerName}}/{{.Repository.Name}}">
+ {{.Repository.OwnerName}}/{{.Repository.Name}}
+ </div>
+ </div>
+ <div class="item-right tw-flex tw-items-center tw-m-1">
+ {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
+ <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}">
+ {{svg "octicon-trash" 16}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+ {{if .BlockingDependenciesNotPermitted}}
+ <div class="item tw-flex tw-items-center tw-justify-between gt-ellipsis">
+ <span>{{ctx.Locale.TrN (len .BlockingDependenciesNotPermitted) "repo.issues.dependency.no_permission_1" "repo.issues.dependency.no_permission_n" (len .BlockingDependenciesNotPermitted)}}</span>
+ </div>
+ {{end}}
+ </div>
+ {{end}}
+
+ {{if or .BlockedByDependencies .BlockedByDependenciesNotPermitted}}
+ <span class="text" data-tooltip-content="{{if .Issue.IsPull}}{{ctx.Locale.Tr "repo.issues.dependency.pr_closing_blockedby"}}{{else}}{{ctx.Locale.Tr "repo.issues.dependency.issue_closing_blockedby"}}{{end}}">
+ <strong>{{ctx.Locale.Tr "repo.issues.dependency.blocked_by_short"}}</strong>
+ </span>
+ <div class="ui relaxed divided list">
+ {{range .BlockedByDependencies}}
+ <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between">
+ <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis">
+ <a class="title muted" href="{{.Issue.Link}}" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}">
+ #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}
+ </a>
+ <div class="text small gt-ellipsis" data-tooltip-content="{{.Repository.OwnerName}}/{{.Repository.Name}}">
+ {{.Repository.OwnerName}}/{{.Repository.Name}}
+ </div>
+ </div>
+ <div class="item-right tw-flex tw-items-center tw-m-1">
+ {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
+ <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blockedBy" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}">
+ {{svg "octicon-trash" 16}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+ {{if $.CanCreateIssueDependencies}}
+ {{range .BlockedByDependenciesNotPermitted}}
+ <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between">
+ <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis">
+ <div class="gt-ellipsis">
+ <span data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.no_permission.can_remove"}}">{{svg "octicon-lock" 16}}</span>
+ <span class="title" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}">
+ #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}
+ </span>
+ </div>
+ <div class="text small gt-ellipsis" data-tooltip-content="{{.Repository.OwnerName}}/{{.Repository.Name}}">
+ {{.Repository.OwnerName}}/{{.Repository.Name}}
+ </div>
+ </div>
+ <div class="item-right tw-flex tw-items-center tw-m-1">
+ {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
+ <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}">
+ {{svg "octicon-trash" 16}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+ {{else if .BlockedByDependenciesNotPermitted}}
+ <div class="item tw-flex tw-items-center tw-justify-between gt-ellipsis">
+ <span>{{ctx.Locale.TrN (len .BlockedByDependenciesNotPermitted) "repo.issues.dependency.no_permission_1" "repo.issues.dependency.no_permission_n" (len .BlockedByDependenciesNotPermitted)}}</span>
+ </div>
+ {{end}}
+ </div>
+ {{end}}
+
+ {{if and .CanCreateIssueDependencies (not .Repository.IsArchived)}}
+ <div>
+ <form method="post" action="{{.Issue.Link}}/dependency/add" id="addDependencyForm">
+ {{$.CsrfTokenHtml}}
+ <div class="ui fluid action input">
+ <div class="ui search selection dropdown" id="new-dependency-drop-list" data-issue-id="{{.Issue.ID}}">
+ <input name="newDependency" type="hidden">
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <input type="text" class="search">
+ <div class="default text">{{ctx.Locale.Tr "repo.issues.dependency.add"}}</div>
+ </div>
+ <button class="ui icon button">
+ {{svg "octicon-plus"}}
+ </button>
+ </div>
+ </form>
+ </div>
+ {{end}}
+</div>
+
+{{if and .CanCreateIssueDependencies (not .Repository.IsArchived)}}
+ <input type="hidden" id="crossRepoSearch" value="{{.AllowCrossRepositoryDependencies}}">
+
+ <div class="ui g-modal-confirm modal remove-dependency">
+ <div class="header">
+ {{svg "octicon-trash"}}
+ {{ctx.Locale.Tr "repo.issues.dependency.remove_header"}}
+ </div>
+ <div class="content">
+ <form method="post" action="{{.Issue.Link}}/dependency/delete" id="removeDependencyForm">
+ {{$.CsrfTokenHtml}}
+ <input type="hidden" value="" name="removeDependencyID" id="removeDependencyID">
+ <input type="hidden" value="" name="dependencyType" id="dependencyType">
+ </form>
+ <p>{{if .Issue.IsPull}}
+ {{ctx.Locale.Tr "repo.issues.dependency.pr_remove_text"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.dependency.issue_remove_text"}}
+ {{end}}</p>
+ </div>
+ {{$ModalButtonCancelText := ctx.Locale.Tr "repo.issues.dependency.cancel"}}
+ {{$ModalButtonOkText := ctx.Locale.Tr "repo.issues.dependency.remove"}}
+ {{template "base/modal_actions_confirm" (dict "." . "ModalButtonCancelText" $ModalButtonCancelText "ModalButtonOkText" $ModalButtonOkText)}}
+ </div>
+{{end}}
diff --git a/templates/repo/issue/view_content/sidebar/due_deadline.tmpl b/templates/repo/issue/view_content/sidebar/due_deadline.tmpl
new file mode 100644
index 00000000..2de836b4
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/due_deadline.tmpl
@@ -0,0 +1,41 @@
+<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.due_date"}}</strong></span>
+<div class="ui form" id="deadline-loader">
+ <div class="ui negative message tw-hidden" id="deadline-err-invalid-date">
+ {{svg "octicon-x" 16 "close icon"}}
+ {{ctx.Locale.Tr "repo.issues.due_date_invalid"}}
+ </div>
+ {{if ne .Issue.DeadlineUnix 0}}
+ <p>
+ <div class="tw-flex tw-justify-between tw-items-center">
+ <div class="due-date {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_overdue"}}"{{end}}>
+ {{svg "octicon-calendar" 16 "tw-mr-2"}}
+ {{DateTime "long" .Issue.DeadlineUnix.FormatDate}}
+ </div>
+ <div>
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ <a class="issue-due-edit muted" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_form_edit"}}">{{svg "octicon-pencil" 16 "tw-mr-1"}}</a>
+ <a class="issue-due-remove muted" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_form_remove"}}">{{svg "octicon-trash"}}</a>
+ {{end}}
+ </div>
+ </div>
+ </p>
+ {{else}}
+ <p>{{ctx.Locale.Tr "repo.issues.due_date_not_set"}}</p>
+ {{end}}
+
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ <div {{if ne .Issue.DeadlineUnix 0}} class="tw-hidden"{{end}} id="deadlineForm">
+ <form class="ui fluid action input issue-due-form" action="{{AppSubUrl}}/{{PathEscape .Repository.Owner.Name}}/{{PathEscape .Repository.Name}}/issues/{{.Issue.Index}}/deadline" method="post" id="update-issue-deadline-form">
+ {{$.CsrfTokenHtml}}
+ <input required placeholder="{{ctx.Locale.Tr "repo.issues.due_date_form"}}" {{if gt .Issue.DeadlineUnix 0}}value="{{.Issue.DeadlineUnix.FormatDate}}"{{end}} type="date" name="deadlineDate" id="deadlineDate">
+ <button class="ui icon button">
+ {{if ne .Issue.DeadlineUnix 0}}
+ {{svg "octicon-pencil"}}
+ {{else}}
+ {{svg "octicon-plus"}}
+ {{end}}
+ </button>
+ </form>
+ </div>
+ {{end}}
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/milestones.tmpl b/templates/repo/issue/view_content/sidebar/milestones.tmpl
new file mode 100644
index 00000000..661ca807
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/milestones.tmpl
@@ -0,0 +1,22 @@
+<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-milestone dropdown">
+ <a class="text muted flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.milestone"}}</strong>
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </a>
+ <div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/milestone">
+ {{template "repo/issue/milestone/select_menu" .}}
+ </div>
+</div>
+<div class="ui select-milestone list">
+ <span class="no-select item {{if .Issue.Milestone}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_milestone"}}</span>
+ <div class="selected">
+ {{if .Issue.Milestone}}
+ <a class="item muted sidebar-item-link" href="{{.RepoLink}}/milestone/{{.Issue.Milestone.ID}}">
+ {{svg "octicon-milestone" 18 "tw-mr-2"}}
+ {{.Issue.Milestone.Name}}
+ </a>
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/participants.tmpl b/templates/repo/issue/view_content/sidebar/participants.tmpl
new file mode 100644
index 00000000..93e2579d
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/participants.tmpl
@@ -0,0 +1,8 @@
+<span class="text"><strong>{{ctx.Locale.TrN .NumParticipants "repo.issues.num_participants_one" "repo.issues.num_participants_few" .NumParticipants}}</strong></span>
+<div class="ui list tw-flex tw-flex-wrap">
+ {{range .Participants}}
+ <a {{if gt .ID 0}}href="{{.HomeLink}}"{{end}} data-tooltip-content="{{.GetDisplayName}}">
+ {{ctx.AvatarUtils.Avatar . 28 "tw-my-0.5 tw-mr-1"}}
+ </a>
+ {{end}}
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/projects.tmpl b/templates/repo/issue/view_content/sidebar/projects.tmpl
new file mode 100644
index 00000000..91d75f3b
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/projects.tmpl
@@ -0,0 +1,54 @@
+<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-project dropdown">
+ <a class="text muted flex-text-block">
+ <strong>{{ctx.Locale.Tr "repo.issues.new.projects"}}</strong>
+ {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </a>
+ <div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/projects">
+ {{if or .OpenProjects .ClosedProjects}}
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_projects"}}">
+ </div>
+ {{end}}
+ <div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_projects"}}</div>
+ {{if and (not .OpenProjects) (not .ClosedProjects)}}
+ <div class="disabled item">
+ {{ctx.Locale.Tr "repo.issues.new.no_items"}}
+ </div>
+ {{end}}
+ {{if .OpenProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.open_projects"}}
+ </div>
+ {{range .OpenProjects}}
+ <a class="item muted sidebar-item-link" data-id="{{.ID}}" data-href="{{.Link ctx}}">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </a>
+ {{end}}
+ {{end}}
+ {{if .ClosedProjects}}
+ <div class="divider"></div>
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.new.closed_projects"}}
+ </div>
+ {{range .ClosedProjects}}
+ <a class="item muted sidebar-item-link" data-id="{{.ID}}" data-href="{{.Link ctx}}">
+ {{svg .IconName 18 "tw-mr-2"}}{{.Title}}
+ </a>
+ {{end}}
+ {{end}}
+ </div>
+</div>
+<div class="ui select-project list">
+ <span class="no-select item {{if .Issue.Project}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_projects"}}</span>
+ <div class="selected">
+ {{if .Issue.Project}}
+ <a class="item muted sidebar-item-link" href="{{.Issue.Project.Link ctx}}">
+ {{svg .Issue.Project.IconName 18 "tw-mr-2"}}{{.Issue.Project.Title}}
+ </a>
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/pull_maintainer_edits.tmpl b/templates/repo/issue/view_content/sidebar/pull_maintainer_edits.tmpl
new file mode 100644
index 00000000..6ec5c05f
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/pull_maintainer_edits.tmpl
@@ -0,0 +1,10 @@
+<div class="inline field">
+ <div class="ui checkbox loading-icon-2px" id="allow-edits-from-maintainers"
+ data-url="{{.Issue.Link}}"
+ data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers_desc"}}"
+ data-prompt-error="{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers_err"}}"
+ >
+ <label><strong>{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers"}}</strong></label>
+ <input type="checkbox" {{if .Issue.PullRequest.AllowMaintainerEdit}}checked{{end}}>
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/pull_review.tmpl b/templates/repo/issue/view_content/sidebar/pull_review.tmpl
new file mode 100644
index 00000000..930c2a63
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/pull_review.tmpl
@@ -0,0 +1,45 @@
+<input id="reviewer_id" name="reviewer_id" type="hidden" value="{{.reviewer_id}}">
+<div class="ui {{if or (and (not .Reviewers) (not .TeamReviewers)) (not .CanChooseReviewer) .Repository.IsArchived}}disabled{{end}} floating jump select-reviewers-modify dropdown">
+ <a class="text tw-flex tw-items-center muted">
+ <strong>{{ctx.Locale.Tr "repo.issues.review.reviewers"}}</strong>
+ {{if and .CanChooseReviewer (not .Repository.IsArchived)}}
+ {{svg "octicon-gear" 16 "tw-ml-1"}}
+ {{end}}
+ </a>
+ <div class="filter menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/request_review">
+ {{if .Reviewers}}
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search" 16}}</i>
+ <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_reviewers"}}">
+ </div>
+ {{end}}
+ {{if .Reviewers}}
+ {{range .Reviewers}}
+ {{if .User}}
+ <a class="{{if not .CanChange}}ui{{end}} item {{if .Checked}}checked{{end}} {{if not .CanChange}}ban-change{{end}}" href="#" data-id="{{.ItemID}}" data-id-selector="#review_request_{{.ItemID}}" {{if not .CanChange}} data-tooltip-content="{{ctx.Locale.Tr "repo.issues.remove_request_review_block"}}"{{end}}>
+ <span class="octicon-check {{if not .Checked}}tw-invisible{{end}}">{{svg "octicon-check"}}</span>
+ <span class="text">
+ {{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}}{{template "repo/search_name" .User}}
+ </span>
+ </a>
+ {{end}}
+ {{end}}
+ {{end}}
+ {{if .TeamReviewers}}
+ {{if .Reviewers}}
+ <div class="divider"></div>
+ {{end}}
+ {{range .TeamReviewers}}
+ {{if .Team}}
+ <a class="{{if not .CanChange}}ui{{end}} item {{if .Checked}}checked{{end}} {{if not .CanChange}}ban-change{{end}}" href="#" data-id="{{.ItemID}}" data-id-selector="#review_request_team_{{.Team.ID}}" {{if not .CanChange}} data-tooltip-content="{{ctx.Locale.Tr "repo.issues.remove_request_review_block"}}"{{end}}>
+ <span class="octicon-check {{if not .Checked}}tw-invisible{{end}}">{{svg "octicon-check" 16}}</span>
+ <span class="text">
+ {{svg "octicon-people" 16 "tw-ml-4 tw-mr-1"}}{{$.Issue.Repo.OwnerName}}/{{.Team.Name}}
+ </span>
+ </a>
+ {{end}}
+ {{end}}
+ {{end}}
+ </div>
+</div>
+{{template "repo/issue/view_content/sidebar/pull_reviewers" .}}
diff --git a/templates/repo/issue/view_content/sidebar/pull_reviewers.tmpl b/templates/repo/issue/view_content/sidebar/pull_reviewers.tmpl
new file mode 100644
index 00000000..102508fd
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/pull_reviewers.tmpl
@@ -0,0 +1,67 @@
+<div class="ui assignees list">
+ <span class="no-select item {{if or .OriginalReviews .PullReviewers}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_reviewers"}}</span>
+ <div class="selected">
+ {{range .PullReviewers}}
+ <div class="item tw-flex tw-items-center tw-py-2">
+ <div class="tw-flex tw-items-center tw-flex-1">
+ {{if .User}}
+ <a class="muted sidebar-item-link" href="{{.User.HomeLink}}">{{ctx.AvatarUtils.Avatar .User 20 "tw-mr-2"}}{{.User.GetDisplayName}}</a>
+ {{else if .Team}}
+ <span class="text">{{svg "octicon-people" 20 "tw-mr-2"}}{{$.Issue.Repo.OwnerName}}/{{.Team.Name}}</span>
+ {{end}}
+ </div>
+ <div class="tw-flex tw-items-center tw-gap-2">
+ {{if (and $.Permission.IsAdmin (or (eq .Review.Type 1) (eq .Review.Type 3)) (not $.Issue.IsClosed) (not $.Issue.PullRequest.HasMerged))}}
+ <a href="#" class="ui muted icon tw-flex tw-items-center show-modal" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dismiss_review"}}" data-modal="#dismiss-review-modal-{{.Review.ID}}">
+ {{svg "octicon-x" 20}}
+ </a>
+ <div class="ui small modal" id="dismiss-review-modal-{{.Review.ID}}">
+ <div class="header">
+ {{ctx.Locale.Tr "repo.issues.dismiss_review"}}
+ </div>
+ <div class="content">
+ <div class="ui warning message">
+ {{ctx.Locale.Tr "repo.issues.dismiss_review_warning"}}
+ </div>
+ <form class="ui form dismiss-review-form" id="dismiss-review-{{.Review.ID}}" action="{{$.RepoLink}}/issues/dismiss_review" method="post">
+ {{$.CsrfTokenHtml}}
+ <input type="hidden" name="review_id" value="{{.Review.ID}}">
+ <div class="field">
+ <label for="message">{{ctx.Locale.Tr "action.review_dismissed_reason"}}</label>
+ <input id="message" name="message">
+ </div>
+ <div class="text right actions">
+ <button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
+ <button class="ui red button" type="submit">{{ctx.Locale.Tr "ok"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ {{end}}
+ {{if .Review.Stale}}
+ <span data-tooltip-content="{{ctx.Locale.Tr "repo.issues.is_stale"}}">
+ {{svg "octicon-hourglass" 16}}
+ </span>
+ {{end}}
+ {{if and .CanChange (or .Checked (and (not $.Issue.IsClosed) (not $.Issue.PullRequest.HasMerged)))}}
+ <a href="#" class="ui muted icon re-request-review{{if .Checked}} checked{{end}}" data-tooltip-content="{{if .Checked}}{{ctx.Locale.Tr "repo.issues.remove_request_review"}}{{else}}{{ctx.Locale.Tr "repo.issues.re_request_review"}}{{end}}" data-issue-id="{{$.Issue.ID}}" data-id="{{.ItemID}}" data-update-url="{{$.RepoLink}}/issues/request_review">{{if .Checked}}{{svg "octicon-trash"}}{{else}}{{svg "octicon-sync"}}{{end}}</a>
+ {{end}}
+ {{svg (printf "octicon-%s" .Review.Type.Icon) 16 (printf "text %s" (.Review.HTMLTypeColorName))}}
+ </div>
+ </div>
+ {{end}}
+ {{range .OriginalReviews}}
+ <div class="item tw-flex tw-items-center tw-py-2">
+ <div class="tw-flex tw-items-center tw-flex-1">
+ <a class="muted" href="{{$.Repository.OriginalURL}}" data-tooltip-content="{{ctx.Locale.Tr "repo.migrated_from_fake" $.Repository.GetOriginalURLHostname}}">
+ {{svg (MigrationIcon $.Repository.GetOriginalURLHostname) 20 "tw-mr-2"}}
+ {{.OriginalAuthor}}
+ </a>
+ </div>
+ <div class="tw-flex tw-items-center tw-gap-2">
+ {{svg (printf "octicon-%s" .Type.Icon) 16 (printf "text %s" (.HTMLTypeColorName))}}
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </div>
diff --git a/templates/repo/issue/view_content/sidebar/pull_wip.tmpl b/templates/repo/issue/view_content/sidebar/pull_wip.tmpl
new file mode 100644
index 00000000..f1588b3f
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/pull_wip.tmpl
@@ -0,0 +1,11 @@
+{{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .HasMerged) (not .Issue.IsClosed)}}
+ <div class="toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefixes="{{JsonUtils.EncodeToString .PullRequestWorkInProgressPrefixes}}" data-update-url="{{.Issue.Link}}/title">
+ <a class="muted">
+ {{if .IsPullWorkInProgress}}
+ {{ctx.Locale.Tr "repo.pulls.ready_for_review"}} {{ctx.Locale.Tr "repo.pulls.remove_prefix" (index .PullRequestWorkInProgressPrefixes 0)}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.pulls.still_in_progress"}} {{ctx.Locale.Tr "repo.pulls.add_prefix" (index .PullRequestWorkInProgressPrefixes 0)}}
+ {{end}}
+ </a>
+ </div>
+{{end}}
diff --git a/templates/repo/issue/view_content/sidebar/reference.tmpl b/templates/repo/issue/view_content/sidebar/reference.tmpl
new file mode 100644
index 00000000..bbbc0995
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/reference.tmpl
@@ -0,0 +1,7 @@
+<div class="ui equal width compact grid">
+ {{$issueReferenceLink := printf "%s#%d" .Issue.Repo.FullName .Issue.Index}}
+ <div class="row tw-items-center" data-tooltip-content="{{$issueReferenceLink}}">
+ <span class="text column truncate">{{ctx.Locale.Tr "repo.issues.reference_link" $issueReferenceLink}}</span>
+ <button class="ui two wide button column tw-p-2" data-clipboard-text="{{$issueReferenceLink}}">{{svg "octicon-copy" 14}}</button>
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/timetracking.tmpl b/templates/repo/issue/view_content/sidebar/timetracking.tmpl
new file mode 100644
index 00000000..610600b2
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/timetracking.tmpl
@@ -0,0 +1,73 @@
+{{if and .CanUseTimetracker (not .Repository.IsArchived)}}
+ <div class="divider"></div>
+ <div class="ui timetrack">
+ <span class="text"><strong>{{ctx.Locale.Tr "repo.issues.tracker"}}</strong></span>
+ <div class="tw-mt-2">
+ <form method="post" action="{{.Issue.Link}}/times/stopwatch/toggle" id="toggle_stopwatch_form">
+ {{$.CsrfTokenHtml}}
+ </form>
+ <form method="post" action="{{.Issue.Link}}/times/stopwatch/cancel" id="cancel_stopwatch_form">
+ {{$.CsrfTokenHtml}}
+ </form>
+ {{if $.IsStopwatchRunning}}
+ <button class="ui fluid button issue-stop-time">
+ {{svg "octicon-stopwatch" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.stop_tracking"}}
+ </button>
+ <button class="ui fluid button issue-cancel-time tw-mt-2">
+ {{svg "octicon-trash" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.cancel_tracking"}}
+ </button>
+ {{else}}
+ {{if .HasUserStopwatch}}
+ <div class="ui warning message">
+ {{ctx.Locale.Tr "repo.issues.tracking_already_started" .OtherStopwatchURL}}
+ </div>
+ {{end}}
+ <button class="ui fluid button issue-start-time" data-tooltip-content='{{ctx.Locale.Tr "repo.issues.start_tracking"}}'>
+ {{svg "octicon-stopwatch" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.start_tracking_short"}}
+ </button>
+ <div class="ui mini modal issue-start-time-modal">
+ <div class="header">{{ctx.Locale.Tr "repo.issues.add_time"}}</div>
+ <div class="content">
+ <form method="post" id="add_time_manual_form" action="{{.Issue.Link}}/times/add" class="ui input fluid tw-gap-2">
+ {{$.CsrfTokenHtml}}
+ <input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_hours"}}' type="number" name="hours">
+ <input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_minutes"}}' type="number" name="minutes" class="ui compact">
+ </form>
+ </div>
+ <div class="actions">
+ <button class="ui primary approve button">{{ctx.Locale.Tr "repo.issues.add_time_short"}}</button>
+ <button class="ui cancel button">{{ctx.Locale.Tr "repo.issues.add_time_cancel"}}</button>
+ </div>
+ </div>
+ <button class="ui fluid button issue-add-time tw-mt-2" data-tooltip-content='{{ctx.Locale.Tr "repo.issues.add_time"}}'>
+ {{svg "octicon-plus" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.add_time_short"}}
+ </button>
+ {{end}}
+ </div>
+ </div>
+{{end}}
+{{if .WorkingUsers}}
+ <div class="divider"></div>
+ <div class="ui comments">
+ <span class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Time)}}</strong></span>
+ <div>
+ {{range $user, $trackedtime := .WorkingUsers}}
+ <div class="comment tw-mt-2">
+ <a class="avatar">
+ {{ctx.AvatarUtils.Avatar $user}}
+ </a>
+ <div class="content">
+ {{template "shared/user/authorlink" $user}}
+ <div class="text">
+ {{$trackedtime|Sec2Time}}
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </div>
+{{end}}
diff --git a/templates/repo/issue/view_content/sidebar/watch.tmpl b/templates/repo/issue/view_content/sidebar/watch.tmpl
new file mode 100644
index 00000000..ee141680
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/watch.tmpl
@@ -0,0 +1,6 @@
+<div class="ui watching">
+ <span class="text"><strong>{{ctx.Locale.Tr "notification.notifications"}}</strong></span>
+ <div class="tw-mt-2">
+ {{template "repo/issue/view_content/sidebar/watching" .}}
+ </div>
+</div>
diff --git a/templates/repo/issue/view_content/sidebar/watching.tmpl b/templates/repo/issue/view_content/sidebar/watching.tmpl
new file mode 100644
index 00000000..d3d75946
--- /dev/null
+++ b/templates/repo/issue/view_content/sidebar/watching.tmpl
@@ -0,0 +1,19 @@
+<form hx-boost="true" hx-sync="this:replace" hx-target="this" method="post" action="{{.Issue.Link}}/watch"
+ {{if not $.IsSigned}}
+ {{if $.Issue.IsPull}}
+ data-tooltip-content="{{ctx.Locale.Tr "repo.subscribe.pull.guest.tooltip"}}"
+ {{else}}
+ data-tooltip-content="{{ctx.Locale.Tr "repo.subscribe.issue.guest.tooltip"}}"
+ {{end}}
+ {{end}}>
+ <input type="hidden" name="watch" value="{{if $.IssueWatch.IsWatching}}0{{else}}1{{end}}">
+ <button class="fluid ui button {{if not $.IsSigned}}disabled{{end}}">
+ {{if $.IssueWatch.IsWatching}}
+ {{svg "octicon-mute" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.unsubscribe"}}
+ {{else}}
+ {{svg "octicon-unmute" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.subscribe"}}
+ {{end}}
+ </button>
+</form>
diff --git a/templates/repo/issue/view_content/update_branch_by_merge.tmpl b/templates/repo/issue/view_content/update_branch_by_merge.tmpl
new file mode 100644
index 00000000..adce052d
--- /dev/null
+++ b/templates/repo/issue/view_content/update_branch_by_merge.tmpl
@@ -0,0 +1,37 @@
+{{if and (gt $.Issue.PullRequest.CommitsBehind 0) (not $.Issue.IsClosed) (not $.Issue.PullRequest.IsChecking) (not $.IsPullFilesConflicted) (not $.IsPullRequestBroken)}}
+ <div class="divider"></div>
+ <div class="item item-section">
+ <div class="item-section-left flex-text-inline">
+ {{svg "octicon-alert"}}
+ {{ctx.Locale.Tr "repo.pulls.outdated_with_base_branch"}}
+ </div>
+ <div class="item-section-right">
+ {{if and $.UpdateAllowed $.UpdateByRebaseAllowed}}
+ <div class="tw-inline-block">
+ <div class="ui buttons update-button">
+ <button class="ui button" data-do="{{$.Link}}/update" data-redirect="{{$.Link}}">
+ <span class="button-text">
+ {{ctx.Locale.Tr "repo.pulls.update_branch"}}
+ </span>
+ </button>
+ <div class="ui dropdown icon button">
+ {{svg "octicon-triangle-down"}}
+ <div class="menu">
+ <a class="item active selected" data-do="{{$.Link}}/update">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</a>
+ <a class="item" data-do="{{$.Link}}/update?style=rebase">{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ {{if and $.UpdateAllowed (not $.UpdateByRebaseAllowed)}}
+ <form action="{{$.Link}}/update" method="post" class="ui update-branch-form">
+ {{$.CsrfTokenHtml}}
+ <button class="ui compact button">
+ <span class="ui text">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</span>
+ </button>
+ </form>
+ {{end}}
+ </div>
+ </div>
+{{end}}
diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl
new file mode 100644
index 00000000..c6276279
--- /dev/null
+++ b/templates/repo/issue/view_title.tmpl
@@ -0,0 +1,145 @@
+{{if .Flash}}
+ <div class="sixteen wide column tw-mb-2">
+ {{template "base/alert" .}}
+ </div>
+{{end}}
+<div class="issue-title-header">
+ {{$canEditIssueTitle := and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .Repository.IsArchived)}}
+ <div class="issue-title" id="issue-title-display">
+ <h1 class="tw-break-anywhere">
+ {{RenderIssueTitle $.Context .Issue.Title ($.Repository.ComposeMetas ctx) | RenderCodeBlock}}
+ <span class="index">#{{.Issue.Index}}</span>
+ </h1>
+ <div class="button-row">
+ {{if $canEditIssueTitle}}
+ <button id="issue-title-edit-show" class="ui small basic button">{{ctx.Locale.Tr "repo.issues.edit"}}</button>
+ {{end}}
+ {{if not .Issue.IsPull}}
+ <a role="button" class="ui small primary button" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
+ {{end}}
+ </div>
+ </div>
+ {{if $canEditIssueTitle}}
+ <div class="ui form issue-title tw-hidden" id="issue-title-editor">
+ <div class="ui input tw-flex-1">
+ <input value="{{.Issue.Title}}" data-old-title="{{.Issue.Title}}" maxlength="255" autocomplete="off" class="js-quick-submit">
+ </div>
+ <div class="button-row">
+ <button class="ui small basic cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
+ <button class="ui small primary button"
+ data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/title">
+ {{ctx.Locale.Tr "repo.issues.save"}}
+ </button>
+ </div>
+ </div>
+ {{end}}
+ <div class="issue-title-meta">
+ {{if .HasMerged}}
+ <div class="ui purple label issue-state-label">{{svg "octicon-git-merge" 16 "tw-mr-1"}} {{if eq .Issue.PullRequest.Status 3}}{{ctx.Locale.Tr "repo.pulls.manually_merged"}}{{else}}{{ctx.Locale.Tr "repo.pulls.merged"}}{{end}}</div>
+ {{else if .Issue.IsClosed}}
+ <div class="ui red label issue-state-label">{{if .Issue.IsPull}}{{svg "octicon-git-pull-request"}}{{else}}{{svg "octicon-issue-closed"}}{{end}} {{ctx.Locale.Tr "repo.issues.closed_title"}}</div>
+ {{else if .Issue.IsPull}}
+ {{if .IsPullWorkInProgress}}
+ <div class="ui grey label issue-state-label">{{svg "octicon-git-pull-request-draft"}} {{ctx.Locale.Tr "repo.issues.draft_title"}}</div>
+ {{else}}
+ <div class="ui green label issue-state-label">{{svg "octicon-git-pull-request"}} {{ctx.Locale.Tr "repo.issues.open_title"}}</div>
+ {{end}}
+ {{else}}
+ <div class="ui green label issue-state-label">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.open_title"}}</div>
+ {{end}}
+ <div class="tw-ml-2 tw-flex-1 tw-break-anywhere">
+ {{if .Issue.IsPull}}
+ {{$headHref := .HeadTarget}}
+ {{if .HeadBranchLink}}
+ {{$headHref = HTMLFormat `<a href="%s">%s</a>` .HeadBranchLink $headHref}}
+ {{end}}
+ {{if not .MadeUsingAGit}}
+ {{$headHref = HTMLFormat `%s <button class="btn interact-fg" data-tooltip-content="%s" data-clipboard-text="%s">%s</button>` $headHref (ctx.Locale.Tr "copy_branch") .HeadTarget (svg "octicon-copy" 14)}}
+ {{end}}
+ {{$baseHref := .BaseTarget}}
+ {{if .BaseBranchLink}}
+ {{$baseHref = HTMLFormat `<a href="%s">%s</a>` .BaseBranchLink $baseHref}}
+ {{end}}
+ {{if .Issue.PullRequest.HasMerged}}
+ {{$mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix ctx.Locale}}
+ {{if .Issue.OriginalAuthor}}
+ {{.Issue.OriginalAuthor}}
+ <span class="pull-desc">{{ctx.Locale.TrN .NumCommits "repo.pulls.merged_title_desc_one" "repo.pulls.merged_title_desc_few" .NumCommits $headHref $baseHref $mergedStr}}</span>
+ {{else}}
+ <a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.GetDisplayName}}</a>
+ <span class="pull-desc">{{ctx.Locale.TrN .NumCommits "repo.pulls.merged_title_desc_one" "repo.pulls.merged_title_desc_few" .NumCommits $headHref $baseHref $mergedStr}}</span>
+ {{end}}
+ {{if .MadeUsingAGit}}
+ {{/* TODO: Move documentation link to the instructions at the bottom of the PR, show instructions when clicking label */}}
+ {{/* Note: #agit-label is necessary for testing whether the label appears when it should in tests/integration/git_test.go */}}
+ <a target="_blank" rel="noopener" href="https://forgejo.org/docs/latest/user/agit-support/">
+ <span id="agit-label" data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.agit_explanation"}}" class="ui small label">
+ {{ctx.Locale.Tr "repo.pulls.made_using_agit"}}
+ </span>
+ </a>
+ {{end}}
+ {{else}}
+ {{if .Issue.OriginalAuthor}}
+ <span id="pull-desc-display" class="pull-desc">{{.Issue.OriginalAuthor}} {{ctx.Locale.TrN .NumCommits "repo.pulls.title_desc_one" "repo.pulls.title_desc_few" .NumCommits $headHref $baseHref}}</span>
+ {{else}}
+ <span id="pull-desc-display" class="pull-desc">
+ <a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.GetDisplayName}}</a>
+ {{ctx.Locale.TrN .NumCommits "repo.pulls.title_desc_one" "repo.pulls.title_desc_few" .NumCommits $headHref $baseHref}}
+ </span>
+ {{end}}
+ {{if .MadeUsingAGit}}
+ {{/* TODO: Move documentation link to the instructions at the bottom of the PR, show instructions when clicking label */}}
+ {{/* Note: #agit-label is necessary for testing whether the label appears when it should in tests/integration/git_test.go */}}
+ <a target="_blank" rel="noopener" href="https://forgejo.org/docs/latest/user/agit-support/">
+ <span id="agit-label" data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.agit_explanation"}}" class="ui small label">
+ {{ctx.Locale.Tr "repo.pulls.made_using_agit"}}
+ </span>
+ </a>
+ {{end}}
+ <span id="pull-desc-editor" class="tw-hidden flex-text-block" data-target-update-url="{{$.RepoLink}}/pull/{{.Issue.Index}}/target_branch">
+ <div class="ui floating filter dropdown">
+ <div class="ui basic small button tw-mr-0">
+ <span class="text">{{ctx.Locale.Tr "repo.pulls.compare_compare"}}: {{$.HeadTarget}}</span>
+ </div>
+ </div>
+ {{svg "octicon-arrow-right"}}
+ <div class="ui floating filter dropdown" data-no-results="{{ctx.Locale.Tr "repo.pulls.no_results"}}">
+ <div class="ui basic small button">
+ <span class="text" id="pull-target-branch" data-basename="{{$.BaseName}}" data-branch="{{$.BaseBranch}}">{{ctx.Locale.Tr "repo.pulls.compare_base"}}: {{$.BaseName}}:{{$.BaseBranch}}</span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ </div>
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-filter" 16}}</i>
+ <input name="search" placeholder="{{ctx.Locale.Tr "repo.pulls.filter_branch"}}...">
+ </div>
+ <div class="scrolling menu" id="branch-select">
+ {{range .Branches}}
+ {{$sameBase := ne $.BaseName $.HeadUserName}}
+ {{$differentBranch := ne . $.HeadBranch}}
+ {{if or $sameBase $differentBranch}}
+ <div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-branch="{{.}}">{{$.BaseName}}{{if $.HeadRepo}}/{{$.HeadRepo}}{{end}}:{{.}}</div>
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+ </div>
+ </span>
+ {{end}}
+ {{else}}
+ {{$createdStr:= TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}
+ <span class="time-desc">
+ {{if .Issue.OriginalAuthor}}
+ {{ctx.Locale.Tr "repo.issues.opened_by_fake" $createdStr .Issue.OriginalAuthor}}
+ {{else if gt .Issue.Poster.ID 0}}
+ {{ctx.Locale.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.GetDisplayName}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.opened_by_fake" $createdStr .Issue.Poster.GetDisplayName}}
+ {{end}}
+ ยท
+ {{ctx.Locale.TrN .Issue.NumComments "repo.issues.num_comments_1" "repo.issues.num_comments" .Issue.NumComments}}
+ </span>
+ {{end}}
+ </div>
+ </div>
+</div>