new user dahsboard issues

This commit is contained in:
Unknwon committed 2015-08-25 22:58:34 +08:00
1 parent be90ea583a
commit f808df5a7b
16 files changed
+427 -258

No files matched your search

+2
View File
@@ -124,6 +124,8 @@ collaborative_repos = Collaborative Repositories
my_orgs = My Organizations
my_mirrors = My Mirrors
issues.in_your_repos = In your repositories
[explore]
repos = Repositories
+20
View File
@@ -275,6 +275,26 @@
"strictMath": 0,
"strictUnits": 0
},
"\/public\/less\/_dashboard.less": {
"allowInsecureImports": 0,
"createSourceMap": 0,
"disableJavascript": 0,
"fileType": 1,
"ieCompatibility": 1,
"ignore": 1,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/public\/less\/_dashboard.less",
"outputAbbreviatedPath": "\/public\/css\/_dashboard.css",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0,
"outputStyle": 0,
"relativeURLS": 0,
"shouldRunAutoprefixer": 0,
"shouldRunBless": 0,
"strictImports": 0,
"strictMath": 0,
"strictUnits": 0
},
"\/public\/less\/_form.less": {
"allowInsecureImports": 0,
"createSourceMap": 0,
+51 -15
View File
@@ -641,9 +641,8 @@ func parseCountResult(results []map[string][]byte) int64 {
}
// GetIssueStats returns issue statistic information by given conditions.
func GetIssueStats(repoID, uid, labelID, milestoneID, assigneeID int64, isShowClosed bool, filterMode int) *IssueStats {
func GetIssueStats(repoID, uid, labelID, milestoneID, assigneeID int64, filterMode int) *IssueStats {
stats := &IssueStats{}
// issue := new(Issue)
queryStr := "SELECT COUNT(*) FROM `issue` "
if labelID > 0 {
@@ -659,38 +658,75 @@ func GetIssueStats(repoID, uid, labelID, milestoneID, assigneeID int64, isShowCl
}
switch filterMode {
case FM_ALL, FM_ASSIGN:
resutls, _ := x.Query(queryStr+baseCond, repoID, false)
stats.OpenCount = parseCountResult(resutls)
resutls, _ = x.Query(queryStr+baseCond, repoID, true)
stats.ClosedCount = parseCountResult(resutls)
results, _ := x.Query(queryStr+baseCond, repoID, false)
stats.OpenCount = parseCountResult(results)
results, _ = x.Query(queryStr+baseCond, repoID, true)
stats.ClosedCount = parseCountResult(results)
case FM_CREATE:
baseCond += " AND poster_id=?"
resutls, _ := x.Query(queryStr+baseCond, repoID, false, uid)
stats.OpenCount = parseCountResult(resutls)
resutls, _ = x.Query(queryStr+baseCond, repoID, true, uid)
stats.ClosedCount = parseCountResult(resutls)
results, _ := x.Query(queryStr+baseCond, repoID, false, uid)
stats.OpenCount = parseCountResult(results)
results, _ = x.Query(queryStr+baseCond, repoID, true, uid)
stats.ClosedCount = parseCountResult(results)
case FM_MENTION:
queryStr += " INNER JOIN `issue_user` ON `issue`.id=`issue_user`.issue_id"
baseCond += " AND `issue_user`.uid=? AND `issue_user`.is_mentioned=?"
resutls, _ := x.Query(queryStr+baseCond, repoID, false, uid, true)
stats.OpenCount = parseCountResult(resutls)
resutls, _ = x.Query(queryStr+baseCond, repoID, true, uid, true)
stats.ClosedCount = parseCountResult(resutls)
results, _ := x.Query(queryStr+baseCond, repoID, false, uid, true)
stats.OpenCount = parseCountResult(results)
results, _ = x.Query(queryStr+baseCond, repoID, true, uid, true)
stats.ClosedCount = parseCountResult(results)
}
return stats
}
// GetUserIssueStats returns issue statistic information for dashboard by given conditions.
func GetUserIssueStats(uid int64, filterMode int) *IssueStats {
func GetUserIssueStats(repoID, uid int64, filterMode int) *IssueStats {
stats := &IssueStats{}
issue := new(Issue)
stats.AssignCount, _ = x.Where("assignee_id=?", uid).And("is_closed=?", false).Count(issue)
stats.CreateCount, _ = x.Where("poster_id=?", uid).And("is_closed=?", false).Count(issue)
queryStr := "SELECT COUNT(*) FROM `issue` "
baseCond := " WHERE issue.is_closed=?"
if repoID > 0 {
baseCond += " AND issue.repo_id=" + com.ToStr(repoID)
}
switch filterMode {
case FM_ASSIGN:
baseCond += " AND assignee_id=" + com.ToStr(uid)
case FM_CREATE:
baseCond += " AND poster_id=" + com.ToStr(uid)
}
results, _ := x.Query(queryStr+baseCond, false)
stats.OpenCount = parseCountResult(results)
results, _ = x.Query(queryStr+baseCond, true)
stats.ClosedCount = parseCountResult(results)
return stats
}
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
func GetRepoIssueStats(repoID, uid int64, filterMode int) (numOpen int64, numClosed int64) {
queryStr := "SELECT COUNT(*) FROM `issue` "
baseCond := " WHERE issue.repo_id=? AND issue.is_closed=?"
switch filterMode {
case FM_ASSIGN:
baseCond += " AND assignee_id=" + com.ToStr(uid)
case FM_CREATE:
baseCond += " AND poster_id=" + com.ToStr(uid)
}
results, _ := x.Query(queryStr+baseCond, repoID, false)
numOpen = parseCountResult(results)
results, _ = x.Query(queryStr+baseCond, repoID, true)
numClosed = parseCountResult(results)
return numOpen, numClosed
}
func updateIssue(e Engine, issue *Issue) error {
_, err := e.Id(issue.ID).AllCols().Update(issue)
return err
+5
View File
@@ -221,6 +221,11 @@ func (repo *Repository) GetMilestoneByID(milestoneID int64) (*Milestone, error)
return GetRepoMilestoneByID(repo.ID, milestoneID)
}
// IssueStats returns number of open and closed repository issues by given filter mode.
func (repo *Repository) IssueStats(uid int64, filterMode int) (int64, int64) {
return GetRepoIssueStats(repo.ID, uid, filterMode)
}
func (repo *Repository) GetMirror() (err error) {
repo.Mirror, err = GetMirror(repo.ID)
return err
+2 -2
View File
@@ -772,7 +772,7 @@ func confLocaleLocale_deDeIni() (*asset, error) {
return a, nil
}
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\x7d\xfd\x72\xdb\x48\x92\xe7\xff\x78\x0a\xb4\x37\x7c\x76\x47\xc8\x74\x74\x4f\xdc\x47\x4c\xd8\xee\x93\xa5\xf6\xc7\xac\x65\x69\x2d\x79\xe6\xe6\x1c\x0e\x34\x48\x40\x24\x46\x24\xc0\x06\x40\xd1\x9a\x8d\x8d\xb8\xd7\xb8\xd7\xbb\x27\xb9\xcc\x5f\x66\xd6\x07\x00\xca\xf6\xec\xc6\xdd\x3f\x64\xa1\x2a\xeb\x2b\x2b\x2b\x2b\x2b\x2b\x2b\x2b\xdf\x6e\xb3\xa2\xec\x16\xe9\xf3\xf4\x38\xdd\xe6\x55\xbd\x2e\xbb\x2e\xed\xca\xf5\xf5\x93\x55\xd3\xf5\x65\x91\xbe\xae\x7a\xfa\x6e\x6f\xab\x45\x99\x24\xab\x66\x53\x12\xe8\x1b\xfa\x4b\x8a\xbc\x5b\xcd\x9b\xbc\x2d\x28\xe2\xd4\xc2\x49\xf9\x65\xbb\x6e\x5a\x06\xfa\x55\x42\xc9\xaa\x5c\x6f\x39\x0f\xfd\x25\x5d\xb5\xac\xb3\xaa\xa6\xcf\x4b\x0a\xa5\x6f\xeb\xa4\x6b\x16\x55\xbe\xce\x82\x04\x44\x58\xfa\x1f\xd3\x9f\xeb\x22\xbd\xec\xcb\x6d\xfa\xac\xdb\xe4\xeb\xf5\x8b\xbc\x43\x96\xbe\x4c\xf3\xc5\xa2\xd9\xd5\xfd\xb3\xa7\x92\x20\x85\x37\xbb\xde\x4a\x3f\xdf\xf5\x12\xb7\xdb\x5a\xd4\xc7\x6d\xd2\x96\xcb\x8a\x3a\xd6\x52\xd4\x07\x0d\x26\xfb\x72\xde\x55\x3d\x37\xfa\x2f\x12\x4a\x6e\xcb\xb6\xab\x1a\x6e\xcf\x9f\x25\x94\x6c\xf3\x25\x03\x5c\xd0\x5f\xd2\x97\x9b\xed\x3a\x47\x86\x2b\x0d\x26\xeb\xbc\x5e\xee\x04\xe6\x9d\x06\x93\x45\x5b\x52\x52\x56\x97\x7b\x8a\x3d\xc1\x47\x4a\x1f\xb3\xd9\x2c\xd9\x11\x4e\xb3\x6d\xdb\x5c\x57\xeb\x32\xcb\xeb\x22\xdb\x08\xd6\x3e\x52\x7c\xaa\xf1\x29\xc5\xa7\x1c\x8f\x6e\x94\x05\x21\x28\xcb\x3b\xed\x0b\x0d\x0d\xe1\x2b\xef\x12\x14\x55\xe7\x1b\xcb\xcd\xc1\xa4\xdc\xe4\xd5\x9a\x07\xe1\x09\x07\xa8\xf1\x5d\xb7\x6f\x30\x54\x17\x1a\x24\x44\x64\xfd\xdd\xb6\x04\x1e\x9e\x5c\x51\x28\x59\xe4\xdb\x7e\xb1\xca\xb9\xad\x12\x4a\x08\x68\xdb\x10\x42\x9a\xf6\x0e\x70\xf6\x91\x34\xed\x32\xaf\xab\xbf\xe7\xbd\x20\xe9\x3c\xf8\x4c\x36\x55\xdb\x36\x8c\xdf\x33\x04\x12\xea\x71\xc6\xe5\x50\xcc\x7b\xc2\x44\x50\x0a\xa7\x6c\xaa\x65\x2b\xa8\xe4\xc4\x33\x7c\x71\x29\x9c\x76\xdd\xb4\x37\x9a\xf0\x8a\x83\x83\xac\xd4\x08\x4d\x8d\xeb\xcf\x6b\x42\xbe\xa6\x9e\xe1\x23\x02\xe8\x92\xbc\xd8\x10\x2a\xb7\x79\x5d\x32\x8e\x8e\xf9\x8b\xf0\x42\x5f\x89\xd2\x54\xd6\x95\x7d\x5f\xd5\x4b\x46\xf6\xb1\x44\xa5\x97\x1a\x95\x04\x69\x2e\xee\xae\xd9\xb9\xe1\xa4\xf8\xbf\xd2\x67\x7a\x21\x9f\x92\x16\x64\x42\xa2\xcb\xc9\x3d\xe9\xb2\xeb\xb2\x2c\xa4\x2f\x5d\xfa\x8a\xc2\xc9\x76\xb7\x5e\x13\xd6\x7e\xdf\x95\x5d\xcf\x99\x2e\xe8\x9b\xfa\x2f\xdf\x49\xd5\x75\x14\xa0\xe8\xb7\x08\x24\x34\x74\xf5\x02\x9d\x39\x41\x20\x49\x3e\x75\x65\xde\x2e\x56\x9f\x13\xf9\x47\x5b\x39\xc0\xb4\x77\x68\x50\x99\x90\x94\x88\xa4\x06\xab\x20\x59\x34\x05\x7f\x9c\xd0\x1f\x15\x5d\xd5\x5d\x4f\x33\xee\x73\xa2\x01\x06\x93\x90\x0c\x40\x5f\xf5\xc0\x82\x46\x62\xfa\x76\x3c\x82\xe9\xab\xaa\xed\xfa\x27\x7d\x45\xc4\xfa\x61\x57\x27\xdc\x3f\x9a\x6d\x59\x31\x37\x26\xf4\xba\x21\x14\x21\xba\xa5\xfe\x9d\xdd\x5d\xfe\xcb\xbb\xa3\xf4\x82\x38\xd1\xb2\x2d\x29\x9c\x52\x19\xf4\x47\x79\xfe\x30\x4b\x28\x97\xd5\x74\x9a\xf7\xf9\x3c\xef\x4a\x8f\x56\x4e\x14\xea\x76\x69\xa0\x71\xe6\x6a\xe0\x60\x5d\x1f\xf5\x77\x6a\x86\x50\x19\x3a\xaf\x5c\x19\xef\x79\x72\x51\x3c\x33\x35\x64\xbe\x58\x97\x1c\x4f\x45\xa5\x6f\xdf\xbf\x3f\x3f\x7d\x99\x96\xf5\xb2\xaa\xcb\x74\x5f\xf5\xab\x74\xd7\x5f\xff\xb7\x6c\x59\xd6\x65\x4b\x3c\x6e\x51\xa5\x34\xa7\x5a\xa2\x84\x94\x08\x5b\x3a\x37\x4b\xba\x6e\x4d\x73\x1f\xe8\xbd\xbc\x7c\x97\x9e\x31\x8a\xb7\x79\xbf\x42\x43\xfa\x55\xd2\xfd\xbe\x66\x14\xb9\x0a\xaf\x56\x65\x0a\x2a\x03\x50\x73\x6d\xf8\x48\x0b\x6d\xe3\x2c\x29\xdb\x36\x23\xb6\xd4\xdf\x65\x9a\x59\xcb\x1b\x42\x4a\x11\x44\x3a\x75\xd3\xa7\xf3\x32\x45\x9e\x59\x92\x58\x83\x0d\xbb\xc7\xdb\xed\xba\x5a\xc8\x5c\x7f\x2d\x69\x1e\xd1\xbc\x82\x28\x96\x42\x38\x20\xca\xd2\x02\x74\x11\x7b\xe6\xf9\x90\x46\x0c\x04\xf9\x57\x25\x31\xc0\xd5\x6e\x29\x6c\x6f\xdd\xec\x8a\x1f\x40\xa9\xd6\x7a\x4f\xa8\xe9\x87\x86\x1a\x0c\xec\x38\x00\x5f\xc5\x31\x51\x1c\x2f\x5a\x6d\xb9\x69\x88\xaf\x38\x62\xaf\x88\xa0\xf6\x15\x25\x52\x4f\xbb\xfc\x96\xe6\x5b\xdf\xa4\xfd\xaa\xea\xd2\x82\x88\x6d\xc1\x05\xd3\xd4\xd8\xd1\x72\x21\x64\x41\x04\x2a\xa4\x61\x71\xf1\x18\x00\x6a\xb3\x23\x6a\x5a\x51\x61\xbc\x18\xf1\xca\x49\x45\x4e\xb5\x13\x5d\xa2\x72\x40\xdf\x44\xb9\x0d\x71\x65\xe6\x9b\xa7\x08\xe8\x77\x58\x3e\xb5\x2a\xbf\xbe\xa6\x56\x75\x44\x15\x6f\xd2\xc5\xba\x21\x92\xfa\xf8\xe1\x5d\xc7\x04\xb3\xca\xb6\x4d\x8b\x65\x8e\x92\x2e\x28\xe8\xe2\x02\x44\x33\x44\xbd\xdb\xcc\xe9\x6b\xbf\xaa\x88\x03\x00\xed\x9c\x83\x57\x73\x8a\xa5\x2a\x76\x1d\x0d\xe1\x51\x4a\x24\x4c\x3d\x20\x94\x81\x00\xb8\x0f\x45\xd5\xe5\x73\x1a\x7b\x06\xbf\xa6\x65\x6b\xd7\x12\x59\xad\xfa\x7e\x6b\x35\xbf\xb9\xba\xba\x90\xaa\x5d\xec\x7d\x75\xe7\x01\x65\x60\x0c\xd6\xbc\xf0\xd6\x69\x53\xcf\x40\x24\xbb\x76\x3d\xa0\x1f\xea\xab\xa5\x1c\xc0\x0b\x37\xe1\x29\xff\x5c\x7a\xf4\x00\xcf\x1d\x49\x27\x7b\x50\x13\xe1\xb8\xc4\x02\x48\x44\xdd\x6c\xb9\xdc\x80\xaa\xcf\x35\xc2\x93\x32\x16\x4d\x97\x2e\x4b\x27\xa5\x42\xf6\x09\xd8\xff\x86\x3a\xac\x6c\xe4\xf2\x8c\xd0\x00\x5e\x82\xd8\xeb\xb6\xd9\x50\xec\x2b\xfa\xf3\x11\xbe\xf9\x67\x5c\x1e\x60\xf2\xa2\x20\xfe\xd6\x1d\xa5\x1f\x5e\x9d\xa4\xff\xf9\x0f\x3f\xff\x3c\x4b\xdf\xf6\x3c\x13\x99\x38\xff\xc6\x44\x45\x41\x59\xc3\x1d\x28\xb1\x8c\x9e\xe8\xee\x01\xcf\xac\x07\xe9\x3Line truncated
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\x7d\xfd\x72\xdb\x48\x92\xe7\xff\x78\x0a\xb4\x37\x7c\x76\x47\xc8\x74\x74\x4f\xdc\x47\x4c\xd8\xee\x93\xa5\xf6\xc7\xac\x65\x69\x2d\x79\xe6\xe6\x1c\x0e\x34\x48\x40\x24\x46\x24\xc0\x06\x40\xd1\x9a\x8d\x8d\xb8\xd7\xb8\xd7\xbb\x27\xb9\xcc\x5f\x66\xd6\x07\x00\xca\xf6\xec\xc6\xdd\x3f\x64\xa1\x2a\xeb\x2b\x2b\x2b\x2b\x2b\x2b\x2b\x2b\xdf\x6e\xb3\xa2\xec\x16\xe9\xf3\xf4\x38\xdd\xe6\x55\xbd\x2e\xbb\x2e\xed\xca\xf5\xf5\x93\x55\xd3\xf5\x65\x91\xbe\xae\x7a\xfa\x6e\x6f\xab\x45\x99\x24\xab\x66\x53\x12\xe8\x1b\xfa\x4b\x8a\xbc\x5b\xcd\x9b\xbc\x2d\x28\xe2\xd4\xc2\x49\xf9\x65\xbb\x6e\x5a\x06\xfa\x55\x42\xc9\xaa\x5c\x6f\x39\x0f\xfd\x25\x5d\xb5\xac\xb3\xaa\xa6\xcf\x4b\x0a\xa5\x6f\xeb\xa4\x6b\x16\x55\xbe\xce\x82\x04\x44\x58\xfa\x1f\xd3\x9f\xeb\x22\xbd\xec\xcb\x6d\xfa\xac\xdb\xe4\xeb\xf5\x8b\xbc\x43\x96\xbe\x4c\xf3\xc5\xa2\xd9\xd5\xfd\xb3\xa7\x92\x20\x85\x37\xbb\xde\x4a\x3f\xdf\xf5\x12\xb7\xdb\x5a\xd4\xc7\x6d\xd2\x96\xcb\x8a\x3a\xd6\x52\xd4\x07\x0d\x26\xfb\x72\xde\x55\x3d\x37\xfa\x2f\x12\x4a\x6e\xcb\xb6\xab\x1a\x6e\xcf\x9f\x25\x94\x6c\xf3\x25\x03\x5c\xd0\x5f\xd2\x97\x9b\xed\x3a\x47\x86\x2b\x0d\x26\xeb\xbc\x5e\xee\x04\xe6\x9d\x06\x93\x45\x5b\x52\x52\x56\x97\x7b\x8a\x3d\xc1\x47\x4a\x1f\xb3\xd9\x2c\xd9\x11\x4e\xb3\x6d\xdb\x5c\x57\xeb\x32\xcb\xeb\x22\xdb\x08\xd6\x3e\x52\x7c\xaa\xf1\x29\xc5\xa7\x1c\x8f\x6e\x94\x05\x21\x28\xcb\x3b\xed\x0b\x0d\x0d\xe1\x2b\xef\x12\x14\x55\xe7\x1b\xcb\xcd\xc1\xa4\xdc\xe4\xd5\x9a\x07\xe1\x09\x07\xa8\xf1\x5d\xb7\x6f\x30\x54\x17\x1a\x24\x44\x64\xfd\xdd\xb6\x04\x1e\x9e\x5c\x51\x28\x59\xe4\xdb\x7e\xb1\xca\xb9\xad\x12\x4a\x08\x68\xdb\x10\x42\x9a\xf6\x0e\x70\xf6\x91\x34\xed\x32\xaf\xab\xbf\xe7\xbd\x20\xe9\x3c\xf8\x4c\x36\x55\xdb\x36\x8c\xdf\x33\x04\x12\xea\x71\xc6\xe5\x50\xcc\x7b\xc2\x44\x50\x0a\xa7\x6c\xaa\x65\x2b\xa8\xe4\xc4\x33\x7c\x71\x29\x9c\x76\xdd\xb4\x37\x9a\xf0\x8a\x83\x83\xac\xd4\x08\x4d\x8d\xeb\xcf\x6b\x42\xbe\xa6\x9e\xe1\x23\x02\xe8\x92\xbc\xd8\x10\x2a\xb7\x79\x5d\x32\x8e\x8e\xf9\x8b\xf0\x42\x5f\x89\xd2\x54\xd6\x95\x7d\x5f\xd5\x4b\x46\xf6\xb1\x44\xa5\x97\x1a\x95\x04\x69\x2e\xee\xae\xd9\xb9\xe1\xa4\xf8\xbf\xd2\x67\x7a\x21\x9f\x92\x16\x64\x42\xa2\xcb\xc9\x3d\xe9\xb2\xeb\xb2\x2c\xa4\x2f\x5d\xfa\x8a\xc2\xc9\x76\xb7\x5e\x13\xd6\x7e\xdf\x95\x5d\xcf\x99\x2e\xe8\x9b\xfa\x2f\xdf\x49\xd5\x75\x14\xa0\xe8\xb7\x08\x24\x34\x74\xf5\x02\x9d\x39\x41\x20\x49\x3e\x75\x65\xde\x2e\x56\x9f\x13\xf9\x47\x5b\x39\xc0\xb4\x77\x68\x50\x99\x90\x94\x88\xa4\x06\xab\x20\x59\x34\x05\x7f\x9c\xd0\x1f\x15\x5d\xd5\x5d\x4f\x33\xee\x73\xa2\x01\x06\x93\x90\x0c\x40\x5f\xf5\xc0\x82\x46\x62\xfa\x76\x3c\x82\xe9\xab\xaa\xed\xfa\x27\x7d\x45\xc4\xfa\x61\x57\x27\xdc\x3f\x9a\x6d\x59\x31\x37\x26\xf4\xba\x21\x14\x21\xba\xa5\xfe\x9d\xdd\x5d\xfe\xcb\xbb\xa3\xf4\x82\x38\xd1\xb2\x2d\x29\x9c\x52\x19\xf4\x47\x79\xfe\x30\x4b\x28\x97\xd5\x74\x9a\xf7\xf9\x3c\xef\x4a\x8f\x56\x4e\x14\xea\x76\x69\xa0\x71\xe6\x6a\xe0\x60\x5d\x1f\xf5\x77\x6a\x86\x50\x19\x3a\xaf\x5c\x19\xef\x79\x72\x51\x3c\x33\x35\x64\xbe\x58\x97\x1c\x4f\x45\xa5\x6f\xdf\xbf\x3f\x3f\x7d\x99\x96\xf5\xb2\xaa\xcb\x74\x5f\xf5\xab\x74\xd7\x5f\xff\xb7\x6c\x59\xd6\x65\x4b\x3c\x6e\x51\xa5\x34\xa7\x5a\xa2\x84\x94\x08\x5b\x3a\x37\x4b\xba\x6e\x4d\x73\x1f\xe8\xbd\xbc\x7c\x97\x9e\x31\x8a\xb7\x79\xbf\x42\x43\xfa\x55\xd2\xfd\xbe\x66\x14\xb9\x0a\xaf\x56\x65\x0a\x2a\x03\x50\x73\x6d\xf8\x48\x0b\x6d\xe3\x2c\x29\xdb\x36\x23\xb6\xd4\xdf\x65\x9a\x59\xcb\x1b\x42\x4a\x11\x44\x3a\x75\xd3\xa7\xf3\x32\x45\x9e\x59\x92\x58\x83\x0d\xbb\xc7\xdb\xed\xba\x5a\xc8\x5c\x7f\x2d\x69\x1e\xd1\xbc\x82\x28\x96\x42\x38\x20\xca\xd2\x02\x74\x11\x7b\xe6\xf9\x90\x46\x0c\x04\xf9\x57\x25\x31\xc0\xd5\x6e\x29\x6c\x6f\xdd\xec\x8a\x1f\x40\xa9\xd6\x7a\x4f\xa8\xe9\x87\x86\x1a\x0c\xec\x38\x00\x5f\xc5\x31\x51\x1c\x2f\x5a\x6d\xb9\x69\x88\xaf\x38\x62\xaf\x88\xa0\xf6\x15\x25\x52\x4f\xbb\xfc\x96\xe6\x5b\xdf\xa4\xfd\xaa\xea\xd2\x82\x88\x6d\xc1\x05\xd3\xd4\xd8\xd1\x72\x21\x64\x41\x04\x2a\xa4\x61\x71\xf1\x18\x00\x6a\xb3\x23\x6a\x5a\x51\x61\xbc\x18\xf1\xca\x49\x45\x4e\xb5\x13\x5d\xa2\x72\x40\xdf\x44\xb9\x0d\x71\x65\xe6\x9b\xa7\x08\xe8\x77\x58\x3e\xb5\x2a\xbf\xbe\xa6\x56\x75\x44\x15\x6f\xd2\xc5\xba\x21\x92\xfa\xf8\xe1\x5d\xc7\x04\xb3\xca\xb6\x4d\x8b\x65\x8e\x92\x2e\x28\xe8\xe2\x02\x44\x33\x44\xbd\xdb\xcc\xe9\x6b\xbf\xaa\x88\x03\x00\xed\x9c\x83\x57\x73\x8a\xa5\x2a\x76\x1d\x0d\xe1\x51\x4a\x24\x4c\x3d\x20\x94\x81\x00\xb8\x0f\x45\xd5\xe5\x73\x1a\x7b\x06\xbf\xa6\x65\x6b\xd7\x12\x59\xad\xfa\x7e\x6b\x35\xbf\xb9\xba\xba\x90\xaa\x5d\xec\x7d\x75\xe7\x01\x65\x60\x0c\xd6\xbc\xf0\xd6\x69\x53\xcf\x40\x24\xbb\x76\x3d\xa0\x1f\xea\xab\xa5\x1c\xc0\x0b\x37\xe1\x29\xff\x5c\x7a\xf4\x00\xcf\x1d\x49\x27\x7b\x50\x13\xe1\xb8\xc4\x02\x48\x44\xdd\x6c\xb9\xdc\x80\xaa\xcf\x35\xc2\x93\x32\x16\x4d\x97\x2e\x4b\x27\xa5\x42\xf6\x09\xd8\xff\x86\x3a\xac\x6c\xe4\xf2\x8c\xd0\x00\x5e\x82\xd8\xeb\xb6\xd9\x50\xec\x2b\xfa\xf3\x11\xbe\xf9\x67\x5c\x1e\x60\xf2\xa2\x20\xfe\xd6\x1d\xa5\x1f\x5e\x9d\xa4\xff\xf9\x0f\x3f\xff\x3c\x4b\xdf\xf6\x3c\x13\x99\x38\xff\xc6\x44\x45\x41\x59\xc3\x1d\x28\xb1\x8c\x9e\xe8\xee\x01\xcf\xac\x07\xe9\x3Line truncated
func confLocaleLocale_enUsIniBytes() ([]byte, error) {
return bindataRead(
@@ -787,7 +787,7 @@ func confLocaleLocale_enUsIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 38939, mode: os.FileMode(420), modTime: time.Unix(1440061419, 0)}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 38984, mode: os.FileMode(420), modTime: time.Unix(1440506859, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
+1 -1
View File
@@ -1 +1 @@
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('embedded-opentype'),url(../fonts/octicons.woff?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('woff'),url(../fonts/octicons.ttf?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('truetype'),url(../fonts/octicons.svg?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d#octicons) format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beaker:before,.octicon-microscope:before{content:'\f0dd'}.octicon-bell:before{content:'\f0de'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-clone:before,.octicon-desktop-download:before{content:'\f0dc'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gLine truncated
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('embedded-opentype'),url(../fonts/octicons.woff?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('woff'),url(../fonts/octicons.ttf?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('truetype'),url(../fonts/octicons.svg?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d#octicons) format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beaker:before,.octicon-microscope:before{content:'\f0dd'}.octicon-bell:before{content:'\f0de'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-clone:before,.octicon-desktop-download:before{content:'\f0dc'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gLine truncated
+20
View File
@@ -0,0 +1,20 @@
.dashboard {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
&.issues {
.context.user.menu {
min-width: 200px;
.ui.header {
font-size: 1rem;
text-transform: none;
}
}
.filter.menu {
.item.active {
background-color: #4183c4;
color: #FFF;
}
}
}
}
+42 -41
View File
@@ -79,47 +79,6 @@
}
}
.page.buttons {
padding-top: 15px;
}
.issue.list {
list-style: none;
padding-top: 15px;
>.item {
padding-top: 15px;
padding-bottom: 10px;
border-bottom: 1px dashed #AAA;
.title {
color: #444;
font-size: 15px;
font-weight: bold;
margin: 0 6px;
&:hover {
color: #000;
}
}
.comment {
padding-right: 10px;
color: #666;
}
.desc {
padding-top: 5px;
color: #999;
a.milestone {
padding-left: 5px;
color: #999!important;
&:hover {
color: #000!important;
}
}
.assignee {
margin-top: -5px;
margin-right: 5px;
}
}
}
}
@comment-avatar-width: 3em;
&.new.issue {
.comment.form {
@@ -607,6 +566,48 @@
}
}
.issue.list {
list-style: none;
padding-top: 15px;
>.item {
padding-top: 15px;
padding-bottom: 10px;
border-bottom: 1px dashed #AAA;
.title {
color: #444;
font-size: 15px;
font-weight: bold;
margin: 0 6px;
&:hover {
color: #000;
}
}
.comment {
padding-right: 10px;
color: #666;
}
.desc {
padding-top: 5px;
color: #999;
a.milestone {
padding-left: 5px;
color: #999!important;
&:hover {
color: #000!important;
}
}
.assignee {
margin-top: -5px;
margin-right: 5px;
}
}
}
}
.page.buttons {
padding-top: 15px;
}
.ui.comments {
.dropzone {
width: 100%;
+1
View File
@@ -6,4 +6,5 @@
@import "_form";
@import "_repository";
@import "_user";
@import "_dashboard";
@import "_admin";
+3 -3
View File
@@ -79,11 +79,11 @@ func Issues(ctx *middleware.Context) {
filterMode := models.FM_ALL
switch viewType {
case "assigned":
assigneeID = ctx.User.Id
filterMode = models.FM_ASSIGN
assigneeID = ctx.User.Id
case "created_by":
posterID = ctx.User.Id
filterMode = models.FM_CREATE
posterID = ctx.User.Id
case "mentioned":
filterMode = models.FM_MENTION
}
@@ -97,7 +97,7 @@ func Issues(ctx *middleware.Context) {
selectLabels := ctx.Query("labels")
milestoneID := ctx.QueryInt64("milestone")
isShowClosed := ctx.Query("state") == "closed"
issueStats := models.GetIssueStats(repo.ID, uid, com.StrTo(selectLabels).MustInt64(), milestoneID, assigneeID, isShowClosed, filterMode)
issueStats := models.GetIssueStats(repo.ID, uid, com.StrTo(selectLabels).MustInt64(), milestoneID, assigneeID, filterMode)
page := ctx.QueryInt("page")
if page <= 1 {
+161 -151
View File
@@ -10,10 +10,10 @@ import (
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/paginater"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
@@ -21,18 +21,13 @@ import (
const (
DASHBOARD base.TplName = "user/dashboard/dashboard"
PULLS base.TplName = "user/dashboard/pulls"
ISSUES base.TplName = "user/issues"
ISSUES base.TplName = "user/dashboard/issues"
STARS base.TplName = "user/stars"
PROFILE base.TplName = "user/profile"
)
func Dashboard(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("dashboard")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsNews"] = true
var ctxUser *models.User
// Check context type.
func getDashboardContextUser(ctx *middleware.Context) *models.User {
ctxUser := ctx.User
orgName := ctx.Params(":org")
if len(orgName) > 0 {
// Organization.
@@ -43,10 +38,33 @@ func Dashboard(ctx *middleware.Context) {
} else {
ctx.Handle(500, "GetUserByName", err)
}
return
return nil
}
ctxUser = org
} else {
}
ctx.Data["ContextUser"] = ctxUser
if err := ctx.User.GetOrganizations(); err != nil {
ctx.Handle(500, "GetOrganizations", err)
return nil
}
ctx.Data["Orgs"] = ctx.User.Orgs
return ctxUser
}
func Dashboard(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("dashboard")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsNews"] = true
ctxUser := getDashboardContextUser(ctx)
if ctx.Written() {
return
}
// Check context type.
if !ctxUser.IsOrganization() {
// Normal user.
ctxUser = ctx.User
collaborates, err := ctx.User.GetAccessibleRepositories()
@@ -63,13 +81,6 @@ func Dashboard(ctx *middleware.Context) {
ctx.Data["CollaborateCount"] = len(repositories)
ctx.Data["CollaborativeRepos"] = repositories
}
ctx.Data["ContextUser"] = ctxUser
if err := ctx.User.GetOrganizations(); err != nil {
ctx.Handle(500, "GetOrganizations", err)
return
}
ctx.Data["Orgs"] = ctx.User.Orgs
repos, err := models.GetRepositories(ctxUser.Id, true)
if err != nil {
@@ -142,6 +153,138 @@ func Pulls(ctx *middleware.Context) {
ctx.HTML(200, PULLS)
}
func Issues(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("issues")
ctx.Data["PageIsIssues"] = true
ctxUser := getDashboardContextUser(ctx)
if ctx.Written() {
return
}
// Organization does not have view type and filter mode.
var (
viewType string
filterMode = models.FM_ALL
assigneeID int64
posterID int64
)
if ctxUser.IsOrganization() {
viewType = "all"
} else {
viewType = ctx.Query("type")
types := []string{"assigned", "created_by"}
if !com.IsSliceContainsStr(types, viewType) {
viewType = "all"
}
switch viewType {
case "assigned":
filterMode = models.FM_ASSIGN
assigneeID = ctxUser.Id
case "created_by":
filterMode = models.FM_CREATE
posterID = ctxUser.Id
}
}
repoID := ctx.QueryInt64("repo")
isShowClosed := ctx.Query("state") == "closed"
issueStats := models.GetUserIssueStats(repoID, ctxUser.Id, filterMode)
page := ctx.QueryInt("page")
if page <= 1 {
page = 1
}
var total int
if !isShowClosed {
total = int(issueStats.OpenCount)
} else {
total = int(issueStats.ClosedCount)
}
ctx.Data["Page"] = paginater.New(total, setting.IssuePagingNum, page, 5)
// Get repositories.
repos, err := models.GetRepositories(ctxUser.Id, true)
if err != nil {
ctx.Handle(500, "GetRepositories", err)
return
}
repoIDs := make([]int64, 0, len(repos))
showRepos := make([]*models.Repository, 0, len(repos))
for _, repo := range repos {
if repo.NumIssues == 0 {
continue
}
repoIDs = append(repoIDs, repo.ID)
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
issueStats.AllCount += int64(repo.NumOpenIssues)
if repo.ID == repoID {
repo.NumOpenIssues = int(issueStats.OpenCount)
repo.NumClosedIssues = int(issueStats.ClosedCount)
} else if filterMode != models.FM_ALL && repo.NumIssues > 0 {
// Calculate repository issue count with filter mode.
numOpen, numClosed := repo.IssueStats(ctxUser.Id, filterMode)
repo.NumOpenIssues, repo.NumClosedIssues = int(numOpen), int(numClosed)
}
if repo.ID == repoID ||
(isShowClosed && repo.NumClosedIssues > 0) ||
(!isShowClosed && repo.NumOpenIssues > 0) {
showRepos = append(showRepos, repo)
}
}
ctx.Data["Repos"] = showRepos
if repoID > 0 {
repoIDs = []int64{repoID}
}
// Get issues.
issues, err := models.Issues(ctxUser.Id, assigneeID, repoID, posterID, 0,
page, isShowClosed, false, "", "")
if err != nil {
ctx.Handle(500, "Issues: %v", err)
return
}
// Get posters and repository.
for i := range issues {
issues[i].Repo, err = models.GetRepositoryByID(issues[i].RepoID)
if err != nil {
ctx.Handle(500, "GetRepositoryByID", fmt.Errorf("[#%d]%v", issues[i].ID, err))
return
}
if err = issues[i].Repo.GetOwner(); err != nil {
ctx.Handle(500, "GetOwner", fmt.Errorf("[#%d]%v", issues[i].ID, err))
return
}
if err = issues[i].GetPoster(); err != nil {
ctx.Handle(500, "GetPoster", fmt.Errorf("[#%d]%v", issues[i].ID, err))
return
}
}
ctx.Data["Issues"] = issues
ctx.Data["IssueStats"] = issueStats
ctx.Data["ViewType"] = viewType
ctx.Data["RepoID"] = repoID
ctx.Data["IsShowClosed"] = isShowClosed
if isShowClosed {
ctx.Data["State"] = "closed"
} else {
ctx.Data["State"] = "open"
}
ctx.HTML(200, ISSUES)
}
func ShowSSHKeys(ctx *middleware.Context, uid int64) {
keys, err := models.ListPublicKeys(uid)
if err != nil {
@@ -256,136 +399,3 @@ func Email2User(ctx *middleware.Context) {
}
ctx.Redirect(setting.AppSubUrl + "/user/" + u.Name)
}
func Issues(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("issues")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsIssues"] = true
viewType := ctx.Query("type")
types := []string{"assigned", "created_by"}
if !com.IsSliceContainsStr(types, viewType) {
viewType = "all"
}
isShowClosed := ctx.Query("state") == "closed"
var filterMode int
switch viewType {
case "assigned":
filterMode = models.FM_ASSIGN
case "created_by":
filterMode = models.FM_CREATE
}
repoId, _ := com.StrTo(ctx.Query("repoid")).Int64()
issueStats := models.GetUserIssueStats(ctx.User.Id, filterMode)
// Get all repositories.
repos, err := models.GetRepositories(ctx.User.Id, true)
if err != nil {
ctx.Handle(500, "user.Issues(GetRepositories)", err)
return
}
repoIds := make([]int64, 0, len(repos))
showRepos := make([]*models.Repository, 0, len(repos))
for _, repo := range repos {
if repo.NumIssues == 0 {
continue
}
repoIds = append(repoIds, repo.ID)
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
issueStats.AllCount += int64(repo.NumOpenIssues)
if isShowClosed {
if repo.NumClosedIssues > 0 {
if filterMode == models.FM_CREATE {
repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed))
}
showRepos = append(showRepos, repo)
}
} else {
if repo.NumOpenIssues > 0 {
if filterMode == models.FM_CREATE {
repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed))
}
showRepos = append(showRepos, repo)
}
}
}
if repoId > 0 {
repoIds = []int64{repoId}
}
page, _ := com.StrTo(ctx.Query("page")).Int()
// Get all issues.
var ius []*models.IssueUser
switch viewType {
case "assigned":
fallthrough
case "created_by":
ius, err = models.GetIssueUserPairsByMode(ctx.User.Id, repoId, isShowClosed, page, filterMode)
default:
ius, err = models.GetIssueUserPairsByRepoIds(repoIds, isShowClosed, page)
}
if err != nil {
ctx.Handle(500, "user.Issues(GetAllIssueUserPairs)", err)
return
}
issues := make([]*models.Issue, len(ius))
for i := range ius {
issues[i], err = models.GetIssueByID(ius[i].IssueID)
if err != nil {
if models.IsErrIssueNotExist(err) {
log.Warn("user.Issues(GetIssueById #%d): issue not exist", ius[i].IssueID)
continue
} else {
ctx.Handle(500, fmt.Sprintf("user.Issues(GetIssueById #%d)", ius[i].IssueID), err)
return
}
}
issues[i].Repo, err = models.GetRepositoryByID(issues[i].RepoID)
if err != nil {
if models.IsErrRepoNotExist(err) {
log.Warn("GetRepositoryById[%d]: repository not exist", issues[i].RepoID)
continue
} else {
ctx.Handle(500, fmt.Sprintf("GetRepositoryById[%d]", issues[i].RepoID), err)
return
}
}
if err = issues[i].Repo.GetOwner(); err != nil {
ctx.Handle(500, "user.Issues(GetOwner)", err)
return
}
if err = issues[i].GetPoster(); err != nil {
ctx.Handle(500, "user.Issues(GetUserById)", err)
return
}
}
ctx.Data["RepoId"] = repoId
ctx.Data["Repos"] = showRepos
ctx.Data["Issues"] = issues
ctx.Data["ViewType"] = viewType
ctx.Data["IssueStats"] = issueStats
ctx.Data["IsShowClosed"] = isShowClosed
if isShowClosed {
ctx.Data["State"] = "closed"
ctx.Data["ShowCount"] = issueStats.ClosedCount
} else {
ctx.Data["ShowCount"] = issueStats.OpenCount
}
ctx.Data["ContextUser"] = ctx.User
ctx.HTML(200, ISSUES)
}
+1 -1
View File
@@ -62,6 +62,7 @@
{{if .IsSigned}}
<a class="item{{if .PageIsDashboard}} active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "dashboard"}}</a>
<a class="item{{if .PageIsIssues}} active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
{{else}}
<a class="item{{if .PageIsHome}} active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "home"}}</a>
{{end}}
@@ -75,7 +76,6 @@
</div> -->
{{if .IsSigned}}
<a class="item{{if .PageIsIssues}} active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
<div class="right menu">
<div class="ui dropdown head link jump item poping up" data-content="{{.i18n.Tr "create_new"}}" data-variation="tiny inverted">
<span class="text">
+2
View File
@@ -10,9 +10,11 @@
<a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks">
{{.i18n.Tr "repo.settings.hooks"}}
</a>
{{if or .SignedUser.AllowGitHook .SignedUser.IsAdmin}}
<a class="{{if .PageIsSettingsGitHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks/git">
{{.i18n.Tr "repo.settings.githooks"}}
</a>
{{end}}
<a class="{{if .PageIsSettingsKeys}}active{{end}} item" href="{{.RepoLink}}/settings/keys">
{{.i18n.Tr "repo.settings.deploy_keys"}}
</a>
+86
View File
@@ -0,0 +1,86 @@
{{template "base/head" .}}
<div class="dashboard issues">
{{template "user/dashboard/navbar" .}}
<div class="ui container">
<div class="ui grid">
<div class="four wide column">
<div class="ui secondary vertical filter menu">
<a class="{{if eq .ViewType "all"}}active{{end}} item" href="{{.Link}}?repo={{.RepoID}}&state={{.State}}">
{{.i18n.Tr "home.issues.in_your_repos"}}
<strong class="ui right">{{.IssueStats.AllCount}}</strong>
</a>
<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="{{.Link}}?type=assigned&repo={{.RepoID}}&state={{.State}}">
{{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}}
<strong class="ui right">{{.IssueStats.AssignCount}}</strong>
</a>
<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="{{.Link}}?type=created_by&repo={{.RepoID}}&state={{.State}}">
{{.i18n.Tr "repo.issues.filter_type.created_by_you"}}
<strong class="ui right">{{.IssueStats.CreateCount}}</strong>
</a>
<div class="ui divider"></div>
{{range .Repos}}
<a class="{{if eq $.RepoID .ID}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}{{if not (eq $.RepoID .ID)}}&repo={{.ID}}{{end}}&state={{$.State}}">{{$.SignedUser.Name}}/{{.Name}} <strong class="ui right">{{if $.IsShowClosed}}{{.NumClosedIssues}}{{else}}{{.NumOpenIssues}}{{end}}</strong></a>
{{end}}
</div>
</div>
<div class="twelve wide column content">
<div class="ui tiny buttons">
<a class="ui green basic button {{if not .IsShowClosed}}active{{end}}" href="{{.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&state=open">
<i class="octicon octicon-issue-opened"></i>
{{.i18n.Tr "repo.issues.open_tab" .IssueStats.OpenCount}}
</a>
<a class="ui red basic button {{if .IsShowClosed}}active{{end}}" href="{{.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&state=closed">
<i class="octicon octicon-issue-closed"></i>
{{.i18n.Tr "repo.issues.close_tab" .IssueStats.ClosedCount}}
</a>
</div>
<div class="issue list">
{{range .Issues}}
{{ $timeStr:= TimeSince .Created $.Lang }}
<li class="item">
<div class="ui label">#{{.ID}}</div>
<a class="title" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a>
{{if .NumComments}}
<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>
{{end}}
<p class="desc">
{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name | Safe}}
{{if .Assignee}}
<a class="ui right assignee poping up" href="{{.Assignee.HomeLink}}" data-content="{{.Assignee.Name}}" data-variation="inverted" data-position="left center">
<img class="ui avatar image" src="{{.Assignee.AvatarLink}}">
</a>
{{end}}
</p>
</li>
{{end}}
{{with .Page}}
{{if gt .TotalPages 1}}
<div class="center page buttons">
<div class="ui borderless pagination menu">
<a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Previous}}"{{end}}>
<i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
</a>
{{range .Pages}}
{{if eq .Num -1}}
<a class="disabled item">...</a>
{{else}}
<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Num}}"{{end}}>{{.Num}}</a>
{{end}}
{{end}}
<a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Next}}"{{end}}>
{{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
</a>
</div>
</div>
{{end}}
{{end}}
</div>
</div>
</div>
</div>
</div>
{{template "base/footer" .}}
+30
View File
@@ -0,0 +1,30 @@
<div class="ui container">
<div class="ui floating dropdown link jump">
<span class="text">
<img class="ui avatar image" src="{{.ContextUser.AvatarLink}}">
{{.ContextUser.Name}}
<i class="dropdown icon"></i>
</span>
<div class="context user menu" tabindex="-1">
<div class="ui header">
{{.i18n.Tr "home.switch_dashboard_context"}}
</div>
<a class="{{if eq .ContextUser.Id .SignedUser.Id}}active selected{{end}} item" href="{{AppSubUrl}}/issues">
<img class="ui image" src="{{.SignedUser.AvatarLink}}">
{{.SignedUser.Name}}
</a>
{{range .Orgs}}
{{if .IsOwnedBy $.SignedUser.Id}}
<a class="{{if eq $.ContextUser.Id .Id}}active selected{{end}} item" href="{{AppSubUrl}}/org/{{.Name}}/issues">
<img class="ui image" src="{{.AvatarLink}}">
{{.Name}}
</a>
{{end}}
{{end}}
<a class="item" href="{{AppSubUrl}}/org/create">
<i class="octicon octicon-repo-create"></i>&nbsp;&nbsp;&nbsp;{{.i18n.Tr "new_org"}}
</a>
</div>
</div>
</div>
<div class="ui divider"></div>
-44
View File
@@ -1,44 +0,0 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
{{template "user/dashboard/nav" .}}
<div id="dashboard-wrapper">
<div id="dashboard" class="container" data-page="user">
{{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
<div id="issue">
<div class="left grid-1-5 filter-list">
<ul class="list-unstyled menu menu-vertical">
<li><a href="{{AppSubUrl}}/issues?state={{.State}}&repoid={{.RepoId}}" class="radius{{if eq .ViewType "all"}} active{{end}}" >In your repositories <strong class="pull-right">{{.IssueStats.AllCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=assigned&repoid={{.RepoId}}&state={{.State}}" class="radius{{if eq .ViewType "assigned"}} active{{end}}">Assigned to you <strong class="pull-right">{{.IssueStats.AssignCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=created_by&repoid={{.RepoId}}&state={{.State}}" class="radius{{if eq .ViewType "created_by"}} active{{end}}">Created by you <strong class="pull-right">{{.IssueStats.CreateCount}}</strong></a></li>
<li><hr/></li>
{{range .Repos}}
<li><a href="{{AppSubUrl}}/issues?type={{$.ViewType}}{{if eq $.RepoId .ID}}{{else}}&repoid={{.ID}}{{end}}&state={{$.State}}" class="radius{{if eq $.RepoId .ID}} active{{end}}">{{$.SignedUser.Name}}/{{.Name}} <strong class="pull-right">{{if $.IsShowClosed}}{{.NumClosedIssues}}{{else}}{{.NumOpenIssues}}{{end}}</strong></a></li>
{{end}}
</ul>
</div>
<div class="right grid-3-4">
<div class="filter-option">
<div class="btn-group">
<a class="btn btn-white btn-small issue-open{{if not .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}">Open</a>
<a class="btn btn-white btn-small issue-close{{if .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}&state=closed">Closed</a>
</div>
</div>
<div class="issues list-group">
{{range .Issues}}{{if .}}
<div class="list-group-item issue-item" id="issue-{{.ID}}" onclick="window.location.href='{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}'">
<span class="number pull-right">#{{.Index}}</span>
<h5 class="title"><a href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a></h5>
<p class="info">
<span class="author"><img class="avatar" src="{{.Poster.AvatarLink}}" alt="" width="20"/>
<a href="{{AppSubUrl}}/{{.Poster.Name}}">{{.Poster.Name}}</a></span>
<span class="time">{{TimeSince .Created $.Lang}}</span>
<span class="comment"><i class="fa fa-comments"></i> {{.NumComments}}</span>
</p>
</div>
{{end}}{{end}}
</div>
</div>
</div>
</div>
</div>
{{template "ng/base/footer" .}}