* Added progressbar for issues (#1146). * Updated the generated index.css. Signed-off-by: modmew8 <modmew8@gmail.com> * Removed stored progress percentage and changed it to css calc. Also added the issue task progress to the user/dashboard/issues. Signed-off-by: modmew8 <modmew8@gmail.com> * Removed unnecessary blanks. Signed-off-by: modmew8 <modmew8@gmail.com> * Formatted the files correctly, fmt-check terminates now without errors. Signed-off-by: modmew8 <modmew8@gmail.com> * Removed variables, made computing the tasks on demand with precompiled regexp. Signed-off-by: modmew8 <modmew8@gmail.com>
This commit is contained in:
		
							parent
							
								
									22a7a7ec9b
								
							
						
					
					
						commit
						d996da6bab
					
				
					 5 changed files with 50 additions and 1 deletions
				
			
		|  | @ -7,6 +7,7 @@ package models | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"path" | 	"path" | ||||||
|  | 	"regexp" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
|  | @ -54,6 +55,19 @@ type Issue struct { | ||||||
| 	Reactions   ReactionList  `xorm:"-"` | 	Reactions   ReactionList  `xorm:"-"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var ( | ||||||
|  | 	issueTasksPat     *regexp.Regexp | ||||||
|  | 	issueTasksDonePat *regexp.Regexp | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const issueTasksRegexpStr = `(^\s*-\s\[[\sx]\]\s)|(\n\s*-\s\[[\sx]\]\s)` | ||||||
|  | const issueTasksDoneRegexpStr = `(^\s*-\s\[[x]\]\s)|(\n\s*-\s\[[x]\]\s)` | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	issueTasksPat = regexp.MustCompile(issueTasksRegexpStr) | ||||||
|  | 	issueTasksDonePat = regexp.MustCompile(issueTasksDoneRegexpStr) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (issue *Issue) loadRepo(e Engine) (err error) { | func (issue *Issue) loadRepo(e Engine) (err error) { | ||||||
| 	if issue.Repo == nil { | 	if issue.Repo == nil { | ||||||
| 		issue.Repo, err = getRepositoryByID(e, issue.RepoID) | 		issue.Repo, err = getRepositoryByID(e, issue.RepoID) | ||||||
|  | @ -741,6 +755,7 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc | ||||||
| func (issue *Issue) ChangeContent(doer *User, content string) (err error) { | func (issue *Issue) ChangeContent(doer *User, content string) (err error) { | ||||||
| 	oldContent := issue.Content | 	oldContent := issue.Content | ||||||
| 	issue.Content = content | 	issue.Content = content | ||||||
|  | 
 | ||||||
| 	if err = UpdateIssueCols(issue, "content"); err != nil { | 	if err = UpdateIssueCols(issue, "content"); err != nil { | ||||||
| 		return fmt.Errorf("UpdateIssueCols: %v", err) | 		return fmt.Errorf("UpdateIssueCols: %v", err) | ||||||
| 	} | 	} | ||||||
|  | @ -818,6 +833,16 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // GetTasks returns the amount of tasks in the issues content
 | ||||||
|  | func (issue *Issue) GetTasks() int { | ||||||
|  | 	return len(issueTasksPat.FindAllStringIndex(issue.Content, -1)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTasksDone returns the amount of completed tasks in the issues content
 | ||||||
|  | func (issue *Issue) GetTasksDone() int { | ||||||
|  | 	return len(issueTasksDonePat.FindAllStringIndex(issue.Content, -1)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // NewIssueOptions represents the options of a new issue.
 | // NewIssueOptions represents the options of a new issue.
 | ||||||
| type NewIssueOptions struct { | type NewIssueOptions struct { | ||||||
| 	Repo        *Repository | 	Repo        *Repository | ||||||
|  |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -1491,6 +1491,20 @@ | ||||||
|         .desc { |         .desc { | ||||||
|             padding-top: 5px; |             padding-top: 5px; | ||||||
|             color: #999; |             color: #999; | ||||||
|  | 	    .progress-bar { | ||||||
|  | 		width: 80px; | ||||||
|  | 		height: 6px; | ||||||
|  | 		display: inline-block; | ||||||
|  | 		background-color: #eee; | ||||||
|  | 		overflow: hidden; | ||||||
|  | 		border-radius: 3px; | ||||||
|  | 		vertical-align: middle !important; | ||||||
|  | 	        .progress { | ||||||
|  | 	            background-color: #ccc; | ||||||
|  | 	            display: block; | ||||||
|  | 	    	    height: 100%; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|             a.milestone { |             a.milestone { | ||||||
|                 padding-left: 5px; |                 padding-left: 5px; | ||||||
|                 color: #999!important; |                 color: #999!important; | ||||||
|  |  | ||||||
|  | @ -200,6 +200,11 @@ | ||||||
| 
 | 
 | ||||||
| 					<p class="desc"> | 					<p class="desc"> | ||||||
| 						{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.HomeLink .Poster.Name | Safe}} | 						{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.HomeLink .Poster.Name | Safe}} | ||||||
|  | 						{{$tasks := .GetTasks}} | ||||||
|  | 						{{if gt $tasks 0}} | ||||||
|  | 							{{$tasksDone := .GetTasksDone}} | ||||||
|  | 							<span class="octicon octicon-checklist"></span> {{$tasksDone}} / {{$tasks}} <span class="progress-bar"><span class="progress" style="width:calc(100% * {{$tasksDone}} / {{$tasks}});"></span></span> | ||||||
|  | 						{{end}} | ||||||
| 						{{if .Milestone}} | 						{{if .Milestone}} | ||||||
| 							<a class="milestone" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.Milestone.ID}}&assignee={{$.AssigneeID}}"> | 							<a class="milestone" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.Milestone.ID}}&assignee={{$.AssigneeID}}"> | ||||||
| 								<span class="octicon octicon-milestone"></span> {{.Milestone.Name}} | 								<span class="octicon octicon-milestone"></span> {{.Milestone.Name}} | ||||||
|  |  | ||||||
|  | @ -87,6 +87,11 @@ | ||||||
| 										<img class="ui avatar image" src="{{.Assignee.RelAvatarLink}}"> | 										<img class="ui avatar image" src="{{.Assignee.RelAvatarLink}}"> | ||||||
| 									</a> | 									</a> | ||||||
| 								{{end}} | 								{{end}} | ||||||
|  | 								{{$tasks := .GetTasks}} | ||||||
|  | 								{{if gt $tasks 0}} | ||||||
|  | 									{{$tasksDone := .GetTasksDone}} | ||||||
|  | 									<span class="octicon octicon-checklist"></span> {{$tasksDone}} / {{$tasks}} <span class="progress-bar"><span class="progress" style="width:calc(100% * {{$tasksDone}} / {{$tasks}});"></span></span> | ||||||
|  | 								{{end}} | ||||||
| 							</p> | 							</p> | ||||||
| 						</li> | 						</li> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue