From 920c0bde2da8b5c7e518b090fde654071715b7d1 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Wed, 13 Jan 2021 08:53:17 -0700 Subject: [PATCH 0001/1137] Kd/add bountysource (#14323) * Add bountysource to Sponsors link * Add badge to readme --- .github/FUNDING.yml | 1 + README.md | 3 +++ README_ZH.md | 3 +++ 3 files changed, 7 insertions(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 1447a6ea3..624a2d97d 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ open_collective: gitea +custom: https://www.bountysource.com/teams/gitea diff --git a/README.md b/README.md index 8fd3f5f60..23ed06dbe 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ + + +

diff --git a/README_ZH.md b/README_ZH.md index cb3c7d64b..037f27dc9 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -42,6 +42,9 @@ + + +

From 648d85d426044686c8fd03591401c1c9d21ed3fa Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 13 Jan 2021 15:54:47 +0000 Subject: [PATCH 0002/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_zh-TW.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 4864698ee..b1eb4eaab 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -821,6 +821,8 @@ tag=標籤 released_this=發佈了此版本 file_raw=原始文件 file_history=歷史記錄 +file_view_source=檢視原始碼 +file_view_rendered=檢視渲染圖 file_view_raw=查看原始文件 file_permalink=永久連結 file_too_large=檔案太大,無法顯示。 From 954aeefb05ee48a8c4ff6006ea449f313a6b9848 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Wed, 13 Jan 2021 10:55:52 -0500 Subject: [PATCH 0003/1137] Update Link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23ed06dbe..ea0d83c90 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ - +

From edbc5c86dfda07a0eada0acd7461a610fee00ae3 Mon Sep 17 00:00:00 2001 From: Kyungmin Bae Date: Thu, 14 Jan 2021 05:30:46 +0900 Subject: [PATCH 0004/1137] Use Request.URL.RequestURI() for fcgi (#14312) (#14314) --- custom/conf/app.example.ini | 2 +- routers/routes/chi.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 045b4cfed..e68727eb8 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -867,7 +867,7 @@ MACARON = file ROUTER_LOG_LEVEL = Info ROUTER = console ENABLE_ACCESS_LOG = false -ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}" +ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}" ACCESS = file ; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace" LEVEL = Info diff --git a/routers/routes/chi.go b/routers/routes/chi.go index 6e609fc2f..16fd6ea90 100644 --- a/routers/routes/chi.go +++ b/routers/routes/chi.go @@ -86,14 +86,14 @@ func LoggerHandler(level log.Level) func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { start := time.Now() - _ = log.GetLogger("router").Log(0, level, "Started %s %s for %s", log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr) + _ = log.GetLogger("router").Log(0, level, "Started %s %s for %s", log.ColoredMethod(req.Method), req.URL.RequestURI(), req.RemoteAddr) next.ServeHTTP(w, req) ww := middleware.NewWrapResponseWriter(w, req.ProtoMajor) status := ww.Status() - _ = log.GetLogger("router").Log(0, level, "Completed %s %s %v %s in %v", log.ColoredMethod(req.Method), req.RequestURI, log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(start))) + _ = log.GetLogger("router").Log(0, level, "Completed %s %s %v %s in %v", log.ColoredMethod(req.Method), req.URL.RequestURI(), log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(start))) }) } } @@ -107,12 +107,12 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor return } - if !strings.HasPrefix(req.RequestURI, "/"+prefix) { + if !strings.HasPrefix(req.URL.RequestURI(), "/"+prefix) { next.ServeHTTP(w, req) return } - rPath := strings.TrimPrefix(req.RequestURI, "/"+prefix) + rPath := strings.TrimPrefix(req.URL.RequestURI(), "/"+prefix) u, err := objStore.URL(rPath, path.Base(rPath)) if err != nil { if os.IsNotExist(err) || errors.Is(err, os.ErrNotExist) { @@ -139,12 +139,12 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor return } - if !strings.HasPrefix(req.RequestURI, "/"+prefix) { + if !strings.HasPrefix(req.URL.RequestURI(), "/"+prefix) { next.ServeHTTP(w, req) return } - rPath := strings.TrimPrefix(req.RequestURI, "/"+prefix) + rPath := strings.TrimPrefix(req.URL.RequestURI(), "/"+prefix) rPath = strings.TrimPrefix(rPath, "/") fi, err := objStore.Stat(rPath) From f76c30094f086162d09926a95e9a75c91177a674 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 14 Jan 2021 23:35:10 +0800 Subject: [PATCH 0005/1137] Fix typo (#14332) --- modules/auth/sso/sspi_windows.go | 2 +- routers/routes/recovery.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auth/sso/sspi_windows.go b/modules/auth/sso/sspi_windows.go index 44dfa81aa..46309c27f 100644 --- a/modules/auth/sso/sspi_windows.go +++ b/modules/auth/sso/sspi_windows.go @@ -95,7 +95,7 @@ func (s *SSPI) VerifyAuthData(req *http.Request, w http.ResponseWriter, store Da // to login with another authentication method if SSPI authentication // fails store.GetData()["Flash"] = map[string]string{ - "ErrMsg": err.Error(), + "ErrorMsg": err.Error(), } store.GetData()["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn store.GetData()["EnableSSPI"] = true diff --git a/routers/routes/recovery.go b/routers/routes/recovery.go index f392d1d55..7f33fee0f 100644 --- a/routers/routes/recovery.go +++ b/routers/routes/recovery.go @@ -95,7 +95,7 @@ func Recovery() func(next http.Handler) http.Handler { w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) if setting.RunMode != "prod" { - store.Data["ErrMsg"] = combinedErr + store.Data["ErrorMsg"] = combinedErr } err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store.Data)) if err != nil { From 60a3297a33b2209ae7acf6fd84afd62e095e01aa Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 15 Jan 2021 04:27:22 +0800 Subject: [PATCH 0006/1137] Use ServerError provided by Context (#14333) ... instead of InternalServerError by macaron --- routers/admin/users.go | 8 ++++---- routers/repo/issue.go | 2 +- routers/repo/projects.go | 4 ++-- routers/repo/pull.go | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/routers/admin/users.go b/routers/admin/users.go index 9fe5c3ef7..74fce9a10 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -188,7 +188,7 @@ func prepareUserInfo(ctx *context.Context) *models.User { _, err = models.GetTwoFactorByUID(u.ID) if err != nil { if !models.IsErrTwoFactorNotEnrolled(err) { - ctx.InternalServerError(err) + ctx.ServerError("IsErrTwoFactorNotEnrolled", err) return nil } ctx.Data["TwoFactorEnabled"] = false @@ -268,7 +268,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { return } if err = u.SetPassword(form.Password); err != nil { - ctx.InternalServerError(err) + ctx.ServerError("SetPassword", err) return } } @@ -285,12 +285,12 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { if form.Reset2FA { tf, err := models.GetTwoFactorByUID(u.ID) if err != nil && !models.IsErrTwoFactorNotEnrolled(err) { - ctx.InternalServerError(err) + ctx.ServerError("GetTwoFactorByUID", err) return } if err = models.DeleteTwoFactorByID(tf.ID, u.ID); err != nil { - ctx.InternalServerError(err) + ctx.ServerError("DeleteTwoFactorByID", err) return } } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 1d8d9c036..478baf8d8 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1117,7 +1117,7 @@ func ViewIssue(ctx *context.Context) { iw.IssueID = issue.ID iw.IsWatching, err = models.CheckIssueWatch(ctx.User, issue) if err != nil { - ctx.InternalServerError(err) + ctx.ServerError("CheckIssueWatch", err) return } } diff --git a/routers/repo/projects.go b/routers/repo/projects.go index 07327df9e..08746aad9 100644 --- a/routers/repo/projects.go +++ b/routers/repo/projects.go @@ -355,7 +355,7 @@ func DeleteProjectBoard(ctx *context.Context) { pb, err := models.GetProjectBoard(ctx.ParamsInt64(":boardID")) if err != nil { - ctx.InternalServerError(err) + ctx.ServerError("GetProjectBoard", err) return } if pb.ProjectID != ctx.ParamsInt64(":id") { @@ -445,7 +445,7 @@ func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitle board, err := models.GetProjectBoard(ctx.ParamsInt64(":boardID")) if err != nil { - ctx.InternalServerError(err) + ctx.ServerError("GetProjectBoard", err) return } if board.ProjectID != ctx.ParamsInt64(":id") { diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 1594e9a9c..01c6efaa1 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -713,11 +713,11 @@ func UpdatePullRequest(ctx *context.Context) { } if err := issue.PullRequest.LoadBaseRepo(); err != nil { - ctx.InternalServerError(err) + ctx.ServerError("LoadBaseRepo", err) return } if err := issue.PullRequest.LoadHeadRepo(); err != nil { - ctx.InternalServerError(err) + ctx.ServerError("LoadHeadRepo", err) return } From 84b147c7f0c2575723d3471783cb24078232fe7a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 15 Jan 2021 05:17:03 +0800 Subject: [PATCH 0007/1137] Use IsProd instead of testing if it's equal. (#14336) Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath --- cmd/serv.go | 4 ++-- models/models.go | 4 ++-- modules/auth/sso/sspi_windows.go | 2 +- modules/httpcache/httpcache.go | 2 +- modules/setting/setting.go | 6 +++++- routers/init.go | 2 +- routers/routes/recovery.go | 11 +++++------ 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index fb1e58113..1e66cb511 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -58,7 +58,7 @@ func setup(logPath string, debug bool) { } setting.NewContext() if debug { - setting.ProdMode = false + setting.RunMode = "dev" } } @@ -76,7 +76,7 @@ func fail(userMessage, logMessage string, args ...interface{}) { fmt.Fprintln(os.Stderr, "Gitea:", userMessage) if len(logMessage) > 0 { - if !setting.ProdMode { + if !setting.IsProd() { fmt.Fprintf(os.Stderr, logMessage+"\n", args...) } } diff --git a/models/models.go b/models/models.go index f12a4e8b3..2ace1ea6d 100644 --- a/models/models.go +++ b/models/models.go @@ -175,8 +175,8 @@ func NewTestEngine() (err error) { } x.SetMapper(names.GonicMapper{}) - x.SetLogger(NewXORMLogger(!setting.ProdMode)) - x.ShowSQL(!setting.ProdMode) + x.SetLogger(NewXORMLogger(!setting.IsProd())) + x.ShowSQL(!setting.IsProd()) return x.StoreEngine("InnoDB").Sync2(tables...) } diff --git a/modules/auth/sso/sspi_windows.go b/modules/auth/sso/sspi_windows.go index 46309c27f..448336c07 100644 --- a/modules/auth/sso/sspi_windows.go +++ b/modules/auth/sso/sspi_windows.go @@ -56,7 +56,7 @@ func (s *SSPI) Init() error { Funcs: templates.NewFuncMap(), Asset: templates.GetAsset, AssetNames: templates.GetAssetNames, - IsDevelopment: setting.RunMode != "prod", + IsDevelopment: !setting.IsProd(), }) return nil } diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index c4134f8e1..cf35cef12 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,7 +17,7 @@ import ( // GetCacheControl returns a suitable "Cache-Control" header value func GetCacheControl() string { - if setting.RunMode == "dev" { + if !setting.IsProd() { return "no-store" } return "private, max-age=" + strconv.FormatInt(int64(setting.StaticCacheTime.Seconds()), 10) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 8ab4508ce..c162c751c 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -376,7 +376,6 @@ var ( CustomConf string PIDFile = "/run/gitea.pid" WritePIDFile bool - ProdMode bool RunMode string RunUser string IsWindows bool @@ -388,6 +387,11 @@ var ( UILocation = time.Local ) +// IsProd if it's a production mode +func IsProd() bool { + return strings.EqualFold(RunMode, "prod") +} + func getAppPath() (string, error) { var appPath string var err error diff --git a/routers/init.go b/routers/init.go index ff2ddcc0b..79e2f9130 100644 --- a/routers/init.go +++ b/routers/init.go @@ -50,7 +50,7 @@ func checkRunMode() { default: macaron.Env = macaron.PROD macaron.ColorLog = false - setting.ProdMode = true + git.Debug = false } log.Info("Run Mode: %s", strings.Title(macaron.Env)) } diff --git a/routers/routes/recovery.go b/routers/routes/recovery.go index 7f33fee0f..cfe1a4114 100644 --- a/routers/routes/recovery.go +++ b/routers/routes/recovery.go @@ -29,7 +29,6 @@ func (d *dataStore) GetData() map[string]interface{} { // Although similar to macaron.Recovery() the main difference is that this error will be created // with the gitea 500 page. func Recovery() func(next http.Handler) http.Handler { - var isDevelopment = setting.RunMode != "prod" return func(next http.Handler) http.Handler { rnd := render.New(render.Options{ Extensions: []string{".tmpl"}, @@ -37,7 +36,7 @@ func Recovery() func(next http.Handler) http.Handler { Funcs: templates.NewFuncMap(), Asset: templates.GetAsset, AssetNames: templates.GetAssetNames, - IsDevelopment: isDevelopment, + IsDevelopment: !setting.IsProd(), }) return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -50,10 +49,10 @@ func Recovery() func(next http.Handler) http.Handler { if err := recover(); err != nil { combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, string(log.Stack(2))) log.Error(combinedErr) - if isDevelopment { - http.Error(w, combinedErr, 500) - } else { + if setting.IsProd() { http.Error(w, http.StatusText(500), 500) + } else { + http.Error(w, combinedErr, 500) } } }() @@ -94,7 +93,7 @@ func Recovery() func(next http.Handler) http.Handler { w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) - if setting.RunMode != "prod" { + if !setting.IsProd() { store.Data["ErrorMsg"] = combinedErr } err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store.Data)) From 6eee9f0f4e56e620b2eacfc9c2b59c6448308290 Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Fri, 15 Jan 2021 01:24:03 +0200 Subject: [PATCH 0008/1137] Merge default and system webhooks under one menu (#14244) --- models/webhook.go | 20 +----- options/locale/locale_en-US.ini | 13 ++-- routers/admin/hooks.go | 54 ++++++++-------- routers/org/setting.go | 1 + routers/repo/webhook.go | 30 +++++---- routers/routes/macaron.go | 25 ++++---- templates/admin/hook_new.tmpl | 10 ++- templates/admin/hooks.tmpl | 7 ++- templates/admin/navbar.tmpl | 5 +- .../repo/settings/webhook/base_list.tmpl | 60 ++++++++++++++++++ templates/repo/settings/webhook/list.tmpl | 62 +------------------ templates/repo/settings/webhook/settings.tmpl | 2 +- 12 files changed, 148 insertions(+), 141 deletions(-) create mode 100644 templates/repo/settings/webhook/base_list.tmpl diff --git a/models/webhook.go b/models/webhook.go index e0a75843d..5174bb612 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -400,20 +400,6 @@ func GetWebhooksByOrgID(orgID int64, listOptions ListOptions) ([]*Webhook, error return ws, sess.Find(&ws, &Webhook{OrgID: orgID}) } -// GetDefaultWebhook returns admin-default webhook by given ID. -func GetDefaultWebhook(id int64) (*Webhook, error) { - webhook := &Webhook{ID: id} - has, err := x. - Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false). - Get(webhook) - if err != nil { - return nil, err - } else if !has { - return nil, ErrWebhookNotExist{id} - } - return webhook, nil -} - // GetDefaultWebhooks returns all admin-default webhooks. func GetDefaultWebhooks() ([]*Webhook, error) { return getDefaultWebhooks(x) @@ -426,11 +412,11 @@ func getDefaultWebhooks(e Engine) ([]*Webhook, error) { Find(&webhooks) } -// GetSystemWebhook returns admin system webhook by given ID. -func GetSystemWebhook(id int64) (*Webhook, error) { +// GetSystemOrDefaultWebhook returns admin system or default webhook by given ID. +func GetSystemOrDefaultWebhook(id int64) (*Webhook, error) { webhook := &Webhook{ID: id} has, err := x. - Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true). + Where("repo_id=? AND org_id=?", 0, 0). Get(webhook) if err != nil { return nil, err diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 48a43aa90..4264d260d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2001,8 +2001,7 @@ dashboard = Dashboard users = User Accounts organizations = Organizations repositories = Repositories -hooks = Default Webhooks -systemhooks = System Webhooks +hooks = Webhooks authentication = Authentication Sources emails = User Emails config = Configuration @@ -2152,11 +2151,13 @@ repos.forks = Forks repos.issues = Issues repos.size = Size -hooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Gitea events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide. -hooks.add_webhook = Add Default Webhook -hooks.update_webhook = Update Default Webhook +defaulthooks = Default Webhooks +defaulthooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Gitea events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide. +defaulthooks.add_webhook = Add Default Webhook +defaulthooks.update_webhook = Update Default Webhook -systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Gitea events trigger. Webhooks defined will act on all repositories on the system, so please consider any performance implications this may have. Read more in the webhooks guide. +systemhooks = System Webhooks +systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Gitea events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the webhooks guide. systemhooks.add_webhook = Add System Webhook systemhooks.update_webhook = Update System Webhook diff --git a/routers/admin/hooks.go b/routers/admin/hooks.go index 4697c4d93..e233e8ac0 100644 --- a/routers/admin/hooks.go +++ b/routers/admin/hooks.go @@ -18,30 +18,41 @@ const ( // DefaultOrSystemWebhooks renders both admin default and system webhook list pages func DefaultOrSystemWebhooks(ctx *context.Context) { - var ws []*models.Webhook var err error - // Are we looking at default webhooks? - if ctx.Params(":configType") == "hooks" { - ctx.Data["Title"] = ctx.Tr("admin.hooks") - ctx.Data["Description"] = ctx.Tr("admin.hooks.desc") - ctx.Data["PageIsAdminHooks"] = true - ctx.Data["BaseLink"] = setting.AppSubURL + "/admin/hooks" - ws, err = models.GetDefaultWebhooks() - } else { - ctx.Data["Title"] = ctx.Tr("admin.systemhooks") - ctx.Data["Description"] = ctx.Tr("admin.systemhooks.desc") - ctx.Data["PageIsAdminSystemHooks"] = true - ctx.Data["BaseLink"] = setting.AppSubURL + "/admin/system-hooks" - ws, err = models.GetSystemWebhooks() + ctx.Data["PageIsAdminSystemHooks"] = true + ctx.Data["PageIsAdminDefaultHooks"] = true + + def := make(map[string]interface{}, len(ctx.Data)) + sys := make(map[string]interface{}, len(ctx.Data)) + for k, v := range ctx.Data { + def[k] = v + sys[k] = v } + sys["Title"] = ctx.Tr("admin.systemhooks") + sys["Description"] = ctx.Tr("admin.systemhooks.desc") + sys["Webhooks"], err = models.GetSystemWebhooks() + sys["BaseLink"] = setting.AppSubURL + "/admin/hooks" + sys["BaseLinkNew"] = setting.AppSubURL + "/admin/system-hooks" if err != nil { ctx.ServerError("GetWebhooksAdmin", err) return } - ctx.Data["Webhooks"] = ws + def["Title"] = ctx.Tr("admin.defaulthooks") + def["Description"] = ctx.Tr("admin.defaulthooks.desc") + def["Webhooks"], err = models.GetDefaultWebhooks() + def["BaseLink"] = setting.AppSubURL + "/admin/hooks" + def["BaseLinkNew"] = setting.AppSubURL + "/admin/default-hooks" + if err != nil { + ctx.ServerError("GetWebhooksAdmin", err) + return + } + + ctx.Data["DefaultWebhooks"] = def + ctx.Data["SystemWebhooks"] = sys + ctx.HTML(200, tplAdminHooks) } @@ -53,14 +64,7 @@ func DeleteDefaultOrSystemWebhook(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) } - // Are we looking at default webhooks? - if ctx.Params(":configType") == "hooks" { - ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/hooks", - }) - } else { - ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/system-hooks", - }) - } + ctx.JSON(200, map[string]interface{}{ + "redirect": setting.AppSubURL + "/admin/hooks", + }) } diff --git a/routers/org/setting.go b/routers/org/setting.go index 454714c7e..05075ca82 100644 --- a/routers/org/setting.go +++ b/routers/org/setting.go @@ -173,6 +173,7 @@ func Webhooks(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("org.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["BaseLink"] = ctx.Org.OrgLink + "/settings/hooks" + ctx.Data["BaseLinkNew"] = ctx.Org.OrgLink + "/settings/hooks" ctx.Data["Description"] = ctx.Tr("org.settings.hooks_desc") ws, err := models.GetWebhooksByOrgID(ctx.Org.Organization.ID, models.ListOptions{}) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 0c3fd1267..5d7074b33 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -36,6 +36,7 @@ func Webhooks(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.settings.hooks") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["BaseLink"] = ctx.Repo.RepoLink + "/settings/hooks" + ctx.Data["BaseLinkNew"] = ctx.Repo.RepoLink + "/settings/hooks" ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.io/en-us/webhooks/") ws, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID, models.ListOptions{}) @@ -54,6 +55,7 @@ type orgRepoCtx struct { IsAdmin bool IsSystemWebhook bool Link string + LinkNew string NewTemplate base.TplName } @@ -63,6 +65,7 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) { return &orgRepoCtx{ RepoID: ctx.Repo.Repository.ID, Link: path.Join(ctx.Repo.RepoLink, "settings/hooks"), + LinkNew: path.Join(ctx.Repo.RepoLink, "settings/hooks"), NewTemplate: tplHookNew, }, nil } @@ -71,16 +74,18 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) { return &orgRepoCtx{ OrgID: ctx.Org.Organization.ID, Link: path.Join(ctx.Org.OrgLink, "settings/hooks"), + LinkNew: path.Join(ctx.Org.OrgLink, "settings/hooks"), NewTemplate: tplOrgHookNew, }, nil } if ctx.User.IsAdmin { // Are we looking at default webhooks? - if ctx.Params(":configType") == "hooks" { + if ctx.Params(":configType") == "default-hooks" { return &orgRepoCtx{ IsAdmin: true, Link: path.Join(setting.AppSubURL, "/admin/hooks"), + LinkNew: path.Join(setting.AppSubURL, "/admin/default-hooks"), NewTemplate: tplAdminHookNew, }, nil } @@ -89,7 +94,8 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) { return &orgRepoCtx{ IsAdmin: true, IsSystemWebhook: true, - Link: path.Join(setting.AppSubURL, "/admin/system-hooks"), + Link: path.Join(setting.AppSubURL, "/admin/hooks"), + LinkNew: path.Join(setting.AppSubURL, "/admin/system-hooks"), NewTemplate: tplAdminHookNew, }, nil } @@ -121,8 +127,8 @@ func WebhooksNew(ctx *context.Context) { ctx.Data["PageIsAdminSystemHooks"] = true ctx.Data["PageIsAdminSystemHooksNew"] = true } else if orCtx.IsAdmin { - ctx.Data["PageIsAdminHooks"] = true - ctx.Data["PageIsAdminHooksNew"] = true + ctx.Data["PageIsAdminDefaultHooks"] = true + ctx.Data["PageIsAdminDefaultHooksNew"] = true } else { ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -139,7 +145,7 @@ func WebhooksNew(ctx *context.Context) { "IconURL": setting.AppURL + "img/favicon.png", } } - ctx.Data["BaseLink"] = orCtx.Link + ctx.Data["BaseLink"] = orCtx.LinkNew ctx.HTML(200, orCtx.NewTemplate) } @@ -187,7 +193,7 @@ func GiteaHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { ctx.ServerError("getOrgRepoCtx", err) return } - ctx.Data["BaseLink"] = orCtx.Link + ctx.Data["BaseLink"] = orCtx.LinkNew if ctx.HasError() { ctx.HTML(200, orCtx.NewTemplate) @@ -241,7 +247,7 @@ func newGogsWebhookPost(ctx *context.Context, form auth.NewGogshookForm, kind mo ctx.ServerError("getOrgRepoCtx", err) return } - ctx.Data["BaseLink"] = orCtx.Link + ctx.Data["BaseLink"] = orCtx.LinkNew if ctx.HasError() { ctx.HTML(200, orCtx.NewTemplate) @@ -537,7 +543,7 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { if form.HasInvalidChannel() { ctx.Flash.Error(ctx.Tr("repo.settings.add_webhook.invalid_channel_name")) - ctx.Redirect(orCtx.Link + "/slack/new") + ctx.Redirect(orCtx.LinkNew + "/slack/new") return } @@ -632,12 +638,10 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) { w, err = models.GetWebhookByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) } else if orCtx.OrgID > 0 { w, err = models.GetWebhookByOrgID(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) - } else if orCtx.IsSystemWebhook { - w, err = models.GetSystemWebhook(ctx.ParamsInt64(":id")) - } else { - w, err = models.GetDefaultWebhook(ctx.ParamsInt64(":id")) + } else if orCtx.IsAdmin { + w, err = models.GetSystemOrDefaultWebhook(ctx.ParamsInt64(":id")) } - if err != nil { + if err != nil || w == nil { if models.IsErrWebhookNotExist(err) { ctx.NotFound("GetWebhookByID", nil) } else { diff --git a/routers/routes/macaron.go b/routers/routes/macaron.go index 66c39b7f8..d331e4ca8 100644 --- a/routers/routes/macaron.go +++ b/routers/routes/macaron.go @@ -370,19 +370,9 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/delete", admin.DeleteRepo) }) - m.Group("/^:configType(hooks|system-hooks)$", func() { + m.Group("/hooks", func() { m.Get("", admin.DefaultOrSystemWebhooks) m.Post("/delete", admin.DeleteDefaultOrSystemWebhook) - m.Get("/:type/new", repo.WebhooksNew) - m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) - m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) - m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) - m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) - m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) - m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost) - m.Post("/matrix/new", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksNewPost) - m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) - m.Post("/feishu/new", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksNewPost) m.Get("/:id", repo.WebHooksEdit) m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) @@ -395,6 +385,19 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/feishu/:id", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) }) + m.Group("/^:configType(default-hooks|system-hooks)$", func() { + m.Get("/:type/new", repo.WebhooksNew) + m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) + m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) + m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) + m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) + m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) + m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost) + m.Post("/matrix/new", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksNewPost) + m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) + m.Post("/feishu/new", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksNewPost) + }) + m.Group("/auths", func() { m.Get("", admin.Authentications) m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost) diff --git a/templates/admin/hook_new.tmpl b/templates/admin/hook_new.tmpl index c6f02ee20..9b251ec4c 100644 --- a/templates/admin/hook_new.tmpl +++ b/templates/admin/hook_new.tmpl @@ -4,10 +4,14 @@
{{template "base/alert" .}}

- {{if .PageIsAdminHooksNew}} - {{.i18n.Tr "admin.hooks.add_webhook"}} + {{if .PageIsAdminDefaultHooksNew}} + {{.i18n.Tr "admin.defaulthooks.add_webhook"}} + {{else if .PageIsAdminSystemHooksNew}} + {{.i18n.Tr "admin.systemhooks.add_webhook"}} + {{else if .Webhook.IsSystemWebhook}} + {{.i18n.Tr "admin.systemhooks.update_webhook"}} {{else}} - {{.i18n.Tr "admin.hooks.update_webhook"}} + {{.i18n.Tr "admin.defaulthooks.update_webhook"}} {{end}}
{{if eq .HookType "gitea"}} diff --git a/templates/admin/hooks.tmpl b/templates/admin/hooks.tmpl index c09c6fcaf..a23cff434 100644 --- a/templates/admin/hooks.tmpl +++ b/templates/admin/hooks.tmpl @@ -2,7 +2,12 @@
{{template "admin/navbar" .}}
- {{template "repo/settings/webhook/list" .}} + {{template "base/alert" .}} + + {{template "repo/settings/webhook/base_list" .SystemWebhooks}} + {{template "repo/settings/webhook/base_list" .DefaultWebhooks}} + + {{template "repo/settings/webhook/delete_modal" .}}
{{template "base/footer" .}} diff --git a/templates/admin/navbar.tmpl b/templates/admin/navbar.tmpl index 8c895b8c2..953076d80 100644 --- a/templates/admin/navbar.tmpl +++ b/templates/admin/navbar.tmpl @@ -12,12 +12,9 @@ {{.i18n.Tr "admin.repositories"}} - + {{.i18n.Tr "admin.hooks"}} - - {{.i18n.Tr "admin.systemhooks"}} - {{.i18n.Tr "admin.authentication"}} diff --git a/templates/repo/settings/webhook/base_list.tmpl b/templates/repo/settings/webhook/base_list.tmpl new file mode 100644 index 000000000..b978a6a19 --- /dev/null +++ b/templates/repo/settings/webhook/base_list.tmpl @@ -0,0 +1,60 @@ +

+ {{.Title}} + +

+
+
+
+ {{.Description | Str2html}} +
+ {{range .Webhooks}} +
+ {{if eq .LastStatus 1}} + {{svg "octicon-check"}} + {{else if eq .LastStatus 2}} + {{svg "octicon-alert"}} + {{else}} + {{svg "octicon-dot-fill"}} + {{end}} + {{.URL}} + +
+ {{end}} +
+
diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl index 5efd6d4a3..507f5e1f6 100644 --- a/templates/repo/settings/webhook/list.tmpl +++ b/templates/repo/settings/webhook/list.tmpl @@ -1,63 +1,5 @@ {{template "base/alert" .}} -

- {{.i18n.Tr "repo.settings.hooks"}} - -

-
-
-
- {{.Description | Str2html}} -
- {{range .Webhooks}} -
- {{if eq .LastStatus 1}} - {{svg "octicon-check"}} - {{else if eq .LastStatus 2}} - {{svg "octicon-alert"}} - {{else}} - {{svg "octicon-dot-fill"}} - {{end}} - {{.URL}} - -
- {{end}} -
-
+ +{{template "repo/settings/webhook/base_list" .}} {{template "repo/settings/webhook/delete_modal" .}} diff --git a/templates/repo/settings/webhook/settings.tmpl b/templates/repo/settings/webhook/settings.tmpl index de74dab05..934794b53 100644 --- a/templates/repo/settings/webhook/settings.tmpl +++ b/templates/repo/settings/webhook/settings.tmpl @@ -1,4 +1,4 @@ -{{$isNew:=or .PageIsSettingsHooksNew .PageIsAdminHooksNew}} +{{$isNew:=or .PageIsSettingsHooksNew .PageIsAdminDefaultHooksNew .PageIsAdminSystemHooksNew}}

{{.i18n.Tr "repo.settings.event_desc"}}

From a21adf92ec04ed6b957da9f58d49afbb93d584e9 Mon Sep 17 00:00:00 2001 From: Norwin Date: Fri, 15 Jan 2021 04:55:51 +0000 Subject: [PATCH 0009/1137] restrict query selector to edit form (#14307) Co-authored-by: Lauris BH --- templates/repo/issue/labels/edit_delete_label.tmpl | 2 +- web_src/js/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/repo/issue/labels/edit_delete_label.tmpl b/templates/repo/issue/labels/edit_delete_label.tmpl index 54ef58422..ed7e585e4 100644 --- a/templates/repo/issue/labels/edit_delete_label.tmpl +++ b/templates/repo/issue/labels/edit_delete_label.tmpl @@ -23,7 +23,7 @@ {{.i18n.Tr "repo.issues.label_modify"}}
-
+ {{.CsrfTokenHtml}}
diff --git a/web_src/js/index.js b/web_src/js/index.js index 07d5b99e3..f64f9e6ef 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -162,12 +162,12 @@ function initLabelEdit() { $('.minicolors-swatch-color').css('background-color', color_hex); }); $('.edit-label-button').on('click', function () { - $('.color-picker').minicolors('value', $(this).data('color')); + $('.edit-label .color-picker').minicolors('value', $(this).data('color')); $('#label-modal-id').val($(this).data('id')); $('.edit-label .new-label-input').val($(this).data('title')); $('.edit-label .new-label-desc-input').val($(this).data('description')); $('.edit-label .color-picker').val($(this).data('color')); - $('.minicolors-swatch-color').css('background-color', $(this).data('color')); + $('.edit-label .minicolors-swatch-color').css('background-color', $(this).data('color')); $('.edit-label.modal').modal({ onApprove() { $('.edit-label.form').trigger('submit'); From bfd0c47ef67b25b916e6fbde9d9f6e2d9c4e2cb6 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Fri, 15 Jan 2021 02:38:41 -0700 Subject: [PATCH 0010/1137] Kd/fix allow svg doctype (#14344) * make svg regex case-insensitive & use strict word boundary * allow doctype svg * add doctype tests * allow and --- modules/base/tool.go | 4 ++-- modules/base/tool_test.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/base/tool.go b/modules/base/tool.go index c497bee44..53339d644 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -35,8 +35,8 @@ const sniffLen = 512 // SVGMimeType MIME type of SVG images. const SVGMimeType = "image/svg+xml" -var svgTagRegex = regexp.MustCompile(`(?s)\A\s*(?:\s*)*\s*(?:\s*)*||>))\s*)*\/]`) +var svgTagInXMLRegex = regexp.MustCompile(`(?si)\A<\?xml\b.*?\?>\s*(?:(||>))\s*)*\/]`) // EncodeMD5 encodes string to md5 hex value. func EncodeMD5(str string) string { diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index cda1685da..a2a989b31 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -216,6 +216,9 @@ func TestIsSVGImageFile(t *testing.T) { assert.True(t, IsSVGImageFile([]byte(` `))) + assert.True(t, IsSVGImageFile([]byte(` + `))) assert.True(t, IsSVGImageFile([]byte(` `))) @@ -227,6 +230,11 @@ func TestIsSVGImageFile(t *testing.T) { `))) + assert.True(t, IsSVGImageFile([]byte(` + + + `))) assert.False(t, IsSVGImageFile([]byte{})) assert.False(t, IsSVGImageFile([]byte("svg"))) assert.False(t, IsSVGImageFile([]byte(""))) From c09e11d018c4a92dc83f58e6a6eacd6b085d3328 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 15 Jan 2021 09:39:56 +0000 Subject: [PATCH 0011/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 7 +------ options/locale/locale_de-DE.ini | 7 +------ options/locale/locale_es-ES.ini | 7 +------ options/locale/locale_fa-IR.ini | 4 ---- options/locale/locale_fr-FR.ini | 7 +------ options/locale/locale_it-IT.ini | 6 +----- options/locale/locale_ja-JP.ini | 7 +------ options/locale/locale_lv-LV.ini | 7 +------ options/locale/locale_nl-NL.ini | 6 +----- options/locale/locale_pl-PL.ini | 7 +------ options/locale/locale_pt-BR.ini | 4 ---- options/locale/locale_pt-PT.ini | 7 +------ options/locale/locale_ru-RU.ini | 7 +------ options/locale/locale_sv-SE.ini | 7 +------ options/locale/locale_tr-TR.ini | 7 +------ options/locale/locale_uk-UA.ini | 7 +------ options/locale/locale_zh-CN.ini | 7 +------ options/locale/locale_zh-TW.ini | 7 +------ 18 files changed, 16 insertions(+), 102 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 28a17bf88..de1f5834c 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -1997,8 +1997,6 @@ dashboard=Přehled users=Uživatelské účty organizations=Organizace repositories=Repozitáře -hooks=Výchozí webové háčky -systemhooks=Systémové webové háčky authentication=Zdroje ověření emails=Uživatelské e-maily config=Nastavení @@ -2148,11 +2146,8 @@ repos.forks=Rozštěpení repos.issues=Úkoly repos.size=Velikost -hooks.desc=Webové háčky automaticky vytvářejí HTTP POST dotazy na server při určitých Gitea událostech. Webové háčky definované zde jsou výchozí a budou zkopírovány do všech nových repozitářů. Přečtěte si více v průvodci webovými háčky. -hooks.add_webhook=Přidat výchozí webový háček -hooks.update_webhook=Aktualizovat výchozí webový háček -systemhooks.desc=Webové háčky automaticky vytvářejí HTTP POST dotazy na server při určitých Gitea událostech. Webové háčky definované zde budou vykonány na všech repozitářích systému, proto prosím zvažte jakékoli důsledky, které to může mít na výkon. Přečtěte si více v průvodci webovými háčky. +systemhooks=Systémové webové háčky systemhooks.add_webhook=Přidat systémový webový háček systemhooks.update_webhook=Aktualizovat systémový webový háček diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 94de786a9..5012a7bf7 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -1990,8 +1990,6 @@ dashboard=Dashboard users=Benutzerkonten organizations=Organisationen repositories=Repositories -hooks=Standard-Webhooks -systemhooks=System-Webhooks authentication=Authentifizierungsquellen emails=Benutzer E-Mails config=Konfiguration @@ -2141,11 +2139,8 @@ repos.forks=Forks repos.issues=Issues repos.size=Größe -hooks.desc=Webhooks stellen automatisch HTTP POST-Anfragen an einen Server, wenn bestimmte Gitea-Ereignisse ausgelöst werden. Die hier definierten Webhooks sind Standardwerte und werden in alle neuen Repositories kopiert. Mehr Infos findest du in der Webhooks-Anleitung. -hooks.add_webhook=Standard-Webhook hinzufügen -hooks.update_webhook=Standard-Webhook aktualisieren -systemhooks.desc=Webhooks senden automatisch POST-HTTP-Anfragen an einen anderen Server, wenn ein bestimmtes Gitea-Event ausgelöst wird. Webhook-Events können von allen Repositories ausgelöst werden, beachte daher mögliche Leistungs-Implikationen. Mehr Informationen sind in der Webhook-Anleitung in der Dokumentation zu finden. +systemhooks=System-Webhooks systemhooks.add_webhook=System-Webhook hinzufügen systemhooks.update_webhook=System-Webhook aktualisieren diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index b0daa3d47..376786b59 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -1986,8 +1986,6 @@ dashboard=Panel de control users=Cuenta de Usuario organizations=Organizaciones repositories=Repositorios -hooks=Webhooks por defecto -systemhooks=Webhooks del sistema authentication=Orígenes de autenticación emails=Correos de usuario config=Configuración @@ -2136,11 +2134,8 @@ repos.forks=Forks repos.issues=Incidencias repos.size=Tamaño -hooks.desc=Los Webhooks automáticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Gitea se activan. Los ganchos definidos aquí son predeterminados y serán copiados en todos los nuevos repositorios. Leer más en la guía webhooks. -hooks.add_webhook=Añadir Webhook por defecto -hooks.update_webhook=Actualizar Webhook por defecto -systemhooks.desc=Los webhooks automáticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Gitea se activan. Los webhooks definidos actuarán en todos los repositorios del sistema, así que por favor considere las implicaciones de rendimiento que esto pueda tener. Lea más en la guía de webhooks. +systemhooks=Webhooks del sistema systemhooks.add_webhook=Añadir Webhook del Sistema systemhooks.update_webhook=Actualizar Webhook del Sistema diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 012ceda6c..eb03210f6 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1779,7 +1779,6 @@ dashboard=پیشخوان users=حساب کاربران organizations=تشکیلات repositories=مخازن -hooks=افزودن هوک‌های تحت وب پیش فرض authentication=منابع احراز هویت config=پیکربندی notices=هشدارهای سامانه @@ -1883,9 +1882,6 @@ repos.forks=انشعاب‌ها repos.issues=مسائل repos.size=اندازه -hooks.desc=هوک تحت وب به صورت خودکار درخواست POST HTTP را به سمت سرور روانه می‌کند زمانی که ماشه رخداد Gitea کشیده شود. هوک تحت وب اینجا به صورت پیش فرض اینجا تعریف شده و برای تمامی مخزن جدید کپی خواهد شد. برای اطلاعات بیشتر به e راهنمای هوک تحت وب مراجعه کنید. -hooks.add_webhook=افزودن هوک تحت وب پیش فرض -hooks.update_webhook=به روز رسانی هوک تحت وب پیش فرض auths.auth_manage_panel=مدیریت منابع احراز هویت diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index ed729ae10..a8d77a1d9 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1794,8 +1794,6 @@ dashboard=Tableau de bord users=Comptes utilisateurs organizations=Organisations repositories=Dépôts -hooks=Webhooks par défaut -systemhooks=Rappels système authentication=Sources d'authentification emails=Courriels de l'utilisateur config=Configuration @@ -1917,11 +1915,8 @@ repos.forks=Bifurcations repos.issues=Tickets repos.size=Taille -hooks.desc=Les Webhooks font automatiquement une requête HTTP POST à un serveur quand certains événements Gitea sont déclenchés. Les Webhooks définis ici sont ceux par défaut et seront copiés dans tous les nouveaux dépôts. Lire la suite dans le guide sur les Webhooks. -hooks.add_webhook=Ajouter un Webhook par défaut -hooks.update_webhook=Modifier un Webhook par défaut -systemhooks.desc=Les Webhooks font automatiquement une requête HTTP POST à un serveur quand certains événements Gitea sont déclenchés. Les Webhooks définis ici sont ceux par défaut et seront copiés dans tous les nouveaux dépôts. pour plus d'information voir le guide sur les Webhooks. +systemhooks=Rappels système systemhooks.add_webhook=Ajouter un rappel système systemhooks.update_webhook=Mettre à jour un rappel système diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index abec12913..311c9fd26 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -1901,8 +1901,6 @@ dashboard=Pannello di Controllo users=Account utenti organizations=Organizzazioni repositories=Repository -hooks=Webhook predefiniti -systemhooks=Webhooks di Sistema authentication=Fonti di autenticazione emails=Email Utente config=Configurazione @@ -2042,10 +2040,8 @@ repos.forks=Fork repos.issues=Problemi repos.size=Dimensione -hooks.desc=I Webhooks effettuano automaticamente richieste HTTP POST ad un server quando si verificano determinati eventi Gitea. I Webhooks definiti qui sono predefiniti e verranno copiati in tutti le nuove repository. Per saperne di più leggi la guida ai webhooks. -hooks.add_webhook=Aggiungi Webhook predefinito -hooks.update_webhook=Aggiorna Webhook predefinito +systemhooks=Webhooks di Sistema systemhooks.add_webhook=Aggiungi Webhook di Sistema systemhooks.update_webhook=Aggiorna Webhook di Sistema diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index fdd5e4561..322f0c9c9 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1997,8 +1997,6 @@ dashboard=ダッシュボード users=ユーザーアカウント organizations=組織 repositories=リポジトリ -hooks=デフォルトのWebhooks -systemhooks=システムWebhook authentication=認証ソース emails=ユーザーメールアドレス config=設定 @@ -2148,11 +2146,8 @@ repos.forks=フォーク repos.issues=課題 repos.size=サイズ -hooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義されたWebhookはデフォルトとなり、全ての新規リポジトリにコピーされます。 詳しくはwebhooks guideをご覧下さい。 -hooks.add_webhook=デフォルトのWebhookを追加 -hooks.update_webhook=デフォルトのWebhookを更新 -systemhooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義したWebhookはシステム内のすべてのリポジトリで呼び出されます。 そのため、パフォーマンスに及ぼす影響を考慮したうえで設定してください。 詳しくはwebhooks guideをご覧下さい。 +systemhooks=システムWebhook systemhooks.add_webhook=システムWebhookを追加 systemhooks.update_webhook=システムWebhookを更新 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 54e226c9c..8db504731 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -1948,8 +1948,6 @@ dashboard=Infopanelis users=Lietotāju konti organizations=Organizācijas repositories=Repozitoriji -hooks=Noklusēti tīmekļa āķi -systemhooks=Sistēmas tīmekļa āķi authentication=Autentificēšanas avoti emails=Lietotāja e-pasts config=Konfigurācija @@ -2098,11 +2096,8 @@ repos.forks=Atdalītie repos.issues=Problēmas repos.size=Izmērs -hooks.desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikumiem, kas notiek Gitea. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Šeit izveidotie tīmekļa āķi tiks pievienoti visiem jaunajajiem repozitorijiem. Lai uzzinātu sīkāk skatieties tīmekļa āķu rokasgrāmatā. -hooks.add_webhook=Pievienot noklusēto tīmekļa āķi -hooks.update_webhook=Mainīt noklusēto tīmekļa āķi -systemhooks.desc=Tīmekļa āķi automātiski veic HTTP POST pieprasījumus uz serveri, kad notiek noteikti Gitea notikumi. Tīmekļa āķi izpildīsies uz visu servera repozitoriju notikumiem, tāpēc būtu jāņem vērā, ka tas var radīt ātrdarbības problēmas. Vairāk par tiem var uzzināt tīmekļa āķu dokumentācijā. +systemhooks=Sistēmas tīmekļa āķi systemhooks.add_webhook=Pievienot sistēmas tīmekļa āķi systemhooks.update_webhook=Mainīt sistēmas tīmekļa āķi diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 8fc84e799..1fb05ec01 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -1948,8 +1948,6 @@ dashboard=Overzicht users=Gebruikersacount organizations=Organisaties repositories=Repositories -hooks=Standaard Webhooks -systemhooks=Systeem webhooks authentication=Authenticatie bronnen emails=Gebruikeremails config=Configuratie @@ -2098,10 +2096,8 @@ repos.forks=Forks repos.issues=Kwesties repos.size=Grootte -hooks.add_webhook=Standaard Webhook toevoegen -hooks.update_webhook=Standaard Webhook bijwerken -systemhooks.desc=Webhooks maken automatisch HTTP POST-verzoeken naar een server wanneer bepaalde Gitea-gebeurtenissen geactiveerd worden. Gedefinieerd webhooks zullen werken op alle repositories van het systeem, dus overweeg eventuele prestatiegevolgen die dit kan hebben. Lees meer in de webhooks gids. +systemhooks=Systeem webhooks systemhooks.add_webhook=Systeem Webhook toevoegen systemhooks.update_webhook=Systeem-webhook bijwerken diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index ef6a3222f..4b54b3789 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1871,8 +1871,6 @@ dashboard=Pulpit users=Konta użytkownika organizations=Organizacje repositories=Repozytoria -hooks=Domyślne Webhooki -systemhooks=Webhooki Systemowe authentication=Źródła uwierzytelniania emails=Emaile użytkowników config=Konfiguracja @@ -2014,11 +2012,8 @@ repos.forks=Forki repos.issues=Zgłoszenia repos.size=Rozmiar -hooks.desc=Webhooki automatycznie tworzą zapytania HTTP POST do serwera, kiedy następują pewne zdarzenia w Gitea. Webhooki zdefiniowane w tym miejscu będą domyślnie kopiowane do wszystkich nowych repozytoriów. Przeczytaj o tym więcej w przewodniku o Webhookach. -hooks.add_webhook=Dodaj domyślny Webhook -hooks.update_webhook=Zaktualizuj domyślny Webhook -systemhooks.desc=Webhooki automatycznie tworzą zapytania HTTP POST do serwera, kiedy następują pewne zdarzenia w Gitea. Webhooki zdefiniowane w tym miejscu będą wykonywane dla wszystkich repozytoriów, więc rozważ ewentualne konsekwencje pod względem wydajności. Przeczytaj o tym więcej w przewodniku o Webhookach. +systemhooks=Webhooki Systemowe systemhooks.add_webhook=Dodaj Webhook Systemowy systemhooks.update_webhook=Aktualizuj Webhook Systemowy diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 56a5b6fb0..ddd38702d 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1715,7 +1715,6 @@ dashboard=Painel users=Contas de usuário organizations=Organizações repositories=Repositórios -hooks=Webhooks padrão authentication=Fontes de autenticação config=Configuração notices=Avisos do sistema @@ -1831,9 +1830,6 @@ repos.forks=Forks repos.issues=Issues repos.size=Tamanho -hooks.desc=Os webhooks fazem solicitações HTTP POST automaticamente para um servidor quando determinados eventos do Gitea são acionados. Webhooks definidos aqui são padrões e serão copiados em todos os novos repositórios. Leia mais em guia de webhooks . -hooks.add_webhook=Adicionar Webhook padrão -hooks.update_webhook=Atualizar Webhook padrão auths.auth_manage_panel=Gerenciamento de fonte de autenticação diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 21ddf16af..2cd5134bf 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1986,8 +1986,6 @@ dashboard=Painel de controlo users=Contas de utilizador organizations=Organizações repositories=Repositórios -hooks=Automatismos web padrão -systemhooks=Automatismos web do sistema authentication=Fontes de autenticação emails=Emails do utilizador config=Configuração @@ -2136,11 +2134,8 @@ repos.forks=Derivações repos.issues=Questões repos.size=Tamanho -hooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando são despoletados determinados eventos do Gitea. Os automatismos web definidos aqui são os padrões e serão copiados para todos os novos repositórios. Leia mais no guia de automatismos web. -hooks.add_webhook=Adicionar automatismo web padrão -hooks.update_webhook=Modificar automatismo web padrão -systemhooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando são despoletados determinados eventos do Gitea. Os automatismos web definidos irão operar em todos os repositórios deste sistema, por isso tenha em consideração quaisquer implicações de desempenho que isso possa ter. Leia mais no guia de automatismos web. +systemhooks=Automatismos web do sistema systemhooks.add_webhook=Adicionar automatismo web do sistema systemhooks.update_webhook=Modificar automatismo do sistema diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 26521cf13..6ccc80756 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1933,8 +1933,6 @@ dashboard=Панель users=Пользователи organizations=Организации repositories=Репозитории -hooks=Стандартные Веб-хуки -systemhooks=Системные вебхуки authentication=Авторизация emails=Адреса эл. почты пользователей config=Конфигурация @@ -2080,11 +2078,8 @@ repos.forks=Форки repos.issues=Задачи repos.size=Размер -hooks.desc=Вебхуки автоматически делают HTTP-POST запросы на сервер, когда вызываются определенные события Gitea. Вебхуки, определённые здесь, по умолчанию и будут скопированы во все новые репозитории. Подробнее читайте в руководстве по вебхукам. -hooks.add_webhook=Добавить стандартный Веб-хук -hooks.update_webhook=Обновить стандартный Веб-хук -systemhooks.desc=Вебхуки автоматически делают HTTP-POST запросы на сервер, когда вызываются определённые события Gitea. Определённые вебхуки будут действовать на всех репозиториях системы, поэтому пожалуйста, учитывайте любые последствия для производительности. Подробнее читайте в руководстве по вебхукам. +systemhooks=Системные вебхуки systemhooks.add_webhook=Добавить системный вебхук systemhooks.update_webhook=Обновить системный вебхук diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 992b22826..5240edd43 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -1780,8 +1780,6 @@ dashboard=Instrumentpanel users=Användarkonto organizations=Organisationer repositories=Utvecklingskataloger -hooks=Förvalda webhooks -systemhooks=Systemets webbhooks authentication=Autentiseringskälla config=Konfiguration notices=Systemaviseringar @@ -1892,11 +1890,8 @@ repos.forks=Forkar repos.issues=Ärenden repos.size=Storlek -hooks.desc=Webbhookar gör automatiskt HTTP POST förfrågningar till en server när särskilda Gitea-händelser utlöses. Webbhookar som definieras här är förinställda och kommer kopieras till alla nya utvecklingskataloger. Läs mer i guiden för webbhookar. -hooks.add_webhook=Lägg till en förvald webhook -hooks.update_webhook=Uppdatera en förvald webhook -systemhooks.desc=Webhooks gör automatiskt HTTP POST förfrågningar till en server när vissa Gitea händelser utlösare. Webhooks definierade kommer att agera på alla utvecklingskataloger på systemet, så tänk på eventuella prestandakonsekvenser detta kan ha. Läs mer i guiden för webbhookar. +systemhooks=Systemets webbhooks auths.auth_manage_panel=Hantering av autentiseringkälla auths.new=Lägg till autensieringskälla diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 0e1b24422..e0f279055 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -1997,8 +1997,6 @@ dashboard=Pano users=Kullanıcı Hesapları organizations=Organizasyonlar repositories=Depolar -hooks=Varsayılan Web İstemcileri -systemhooks=Sistem Web İstemcileri authentication=Yetkilendirme Kaynakları emails=Kullanıcı E-postaları config=Yapılandırma @@ -2147,11 +2145,8 @@ repos.forks=Çatallar repos.issues=Konular repos.size=Boyut -hooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. web istemcileri kılavuzunda daha fazla bilgi edinin. -hooks.add_webhook=Varsayılan Web İstemcisi Ekle -hooks.update_webhook=Varsayılan Web İstemcisini Güncelle -systemhooks.desc=Belirli Gitea olayları tetiklendiğinde Web istemcileri otomatik olarak bir sunucuya HTTP POST istekleri yapar. Tanımlanan web istemcileri sistemdeki tüm depolar üzerinde çalışır, bu yüzden lütfen bunun olabilecek tüm performans sonuçlarını göz önünde bulundurun. web istemcileri kılavuzunda daha fazla bilgi edinin. +systemhooks=Sistem Web İstemcileri systemhooks.add_webhook=Sistem Web İstemcisi Ekle systemhooks.update_webhook=Sistem Web İstemcisi Güncelle diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index a3adc11f5..a1f95a0c1 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1877,8 +1877,6 @@ dashboard=Панель управління users=Облікові записи користувачів organizations=Організації repositories=Репозиторії -hooks=Типові веб-хуки -systemhooks=Системні вебхуки authentication=Джерела автентифікації emails=Електронні адреси Користувача config=Конфігурація @@ -2022,11 +2020,8 @@ repos.forks=Форки repos.issues=Проблеми repos.size=Розмір -hooks.desc=Веб-хуки автоматично створюють HTTP POST-запити до сервера, коли виконуються певні події Gitea. Визначені тут веб-хуки є типовими і копіюються у всі нові сховища. Детальніше читайте в інструкції по використанню web-хуків. -hooks.add_webhook=Додати типовий веб-хук -hooks.update_webhook=Змінити типовий веб-хук -systemhooks.desc=Веб-хуки автоматично створюють HTTP POST-запити до сервера, коли виконуються певні тригери в Gitea. Визначені тут веб-хуки є типовими і копіюються у всі нові сховища. Детальніше читайте в інструкції по використанню web-хуків. +systemhooks=Системні вебхуки systemhooks.add_webhook=Додати системний вебхук systemhooks.update_webhook=Оновити системний вебхук diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 002c6aefa..f514a0f42 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1992,8 +1992,6 @@ dashboard=管理面板 users=帐户管理 organizations=组织管理 repositories=仓库管理 -hooks=默认Web钩子 -systemhooks=系统 Web 钩子 authentication=认证源 emails=用户邮件 config=应用配置 @@ -2142,11 +2140,8 @@ repos.forks=派生数 repos.issues=工单数 repos.size=大小 -hooks.desc=当某些 Gitea 事件触发时, Web 钩子会自动向服务器发出 HTTP POST 请求。此处定义的 Web 钩子是默认值, 将复制到所有新建仓库中。参阅 Web钩子指南 获取更多内容。 -hooks.add_webhook=新增默认Web钩子 -hooks.update_webhook=更新默认Web钩子 -systemhooks.desc=当某些 Gitea 事件触发时, Web 钩子会自动向服务器发出 HTTP POST 请求。此处定义的 Web 钩子是默认值, 将复制到所有新建仓库中。参阅 Web钩子指南 获取更多内容。 +systemhooks=系统 Web 钩子 systemhooks.add_webhook=添加系统 Web 钩子 systemhooks.update_webhook=更新系统 Web 钩子 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index b1eb4eaab..4d7d19e14 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1999,8 +1999,6 @@ dashboard=資訊主頁 users=使用者帳戶 organizations=組織 repositories=儲存庫 -hooks=預設 Webhook -systemhooks=系統 Webhook authentication=認證來源 emails=使用者電子信箱 config=組態 @@ -2150,11 +2148,8 @@ repos.forks=Fork 數 repos.issues=問題數 repos.size=大小 -hooks.desc=當觸發某些 Gitea 事件時,Webhook 會自動發出 HTTP POST 請求到指定的伺服器。這裡所定義的 Webhook 是預設的,並且會複製到所有新儲存庫。在 Webhook 指南閱讀更多內容。 -hooks.add_webhook=新增預設 Webhook -hooks.update_webhook=更新預設 Webhook -systemhooks.desc=當觸發某些 Gitea 事件時,Webhook 會自動發出 HTTP POST 請求到指定的伺服器。由於這裡所定義的 Webhook 會影響此系統上的所有儲存庫,因此請評估這會對效能造成多少影響。在 Webhook 指南閱讀更多內容。 +systemhooks=系統 Webhook systemhooks.add_webhook=新增系統 Webhook systemhooks.update_webhook=更新系統 Webhook From 3091600cc866bb5236be991e764ad113b8f542a1 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 15 Jan 2021 21:29:32 +0100 Subject: [PATCH 0012/1137] KanBan: be able to set default board (#14147) Co-authored-by: silverwind Co-authored-by: zeripath --- models/project_board.go | 97 ++++++++++++++++++++++++------- options/locale/locale_en-US.ini | 2 + routers/repo/projects.go | 58 ++++++++++++------ routers/repo/projects_test.go | 28 +++++++++ routers/routes/macaron.go | 1 + templates/repo/projects/view.tmpl | 40 +++++++++---- web_src/js/features/projects.js | 23 ++++++-- 7 files changed, 193 insertions(+), 56 deletions(-) create mode 100644 routers/repo/projects_test.go diff --git a/models/project_board.go b/models/project_board.go index 260fc8304..8ffa21837 100644 --- a/models/project_board.go +++ b/models/project_board.go @@ -8,6 +8,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" "xorm.io/xorm" ) @@ -164,22 +165,43 @@ func UpdateProjectBoard(board *ProjectBoard) error { func updateProjectBoard(e Engine, board *ProjectBoard) error { _, err := e.ID(board.ID).Cols( "title", - "default", ).Update(board) return err } // GetProjectBoards fetches all boards related to a project -func GetProjectBoards(projectID int64) ([]*ProjectBoard, error) { - - var boards = make([]*ProjectBoard, 0, 5) - - sess := x.Where("project_id=?", projectID) - return boards, sess.Find(&boards) +// if no default board set, first board is a temporary "Uncategorized" board +func GetProjectBoards(projectID int64) (ProjectBoardList, error) { + return getProjectBoards(x, projectID) } -// GetUncategorizedBoard represents a board for issues not assigned to one -func GetUncategorizedBoard(projectID int64) (*ProjectBoard, error) { +func getProjectBoards(e Engine, projectID int64) ([]*ProjectBoard, error) { + var boards = make([]*ProjectBoard, 0, 5) + + if err := e.Where("project_id=? AND `default`=?", projectID, false).Find(&boards); err != nil { + return nil, err + } + + defaultB, err := getDefaultBoard(e, projectID) + if err != nil { + return nil, err + } + + return append([]*ProjectBoard{defaultB}, boards...), nil +} + +// getDefaultBoard return default board and create a dummy if none exist +func getDefaultBoard(e Engine, projectID int64) (*ProjectBoard, error) { + var board ProjectBoard + exist, err := e.Where("project_id=? AND `default`=?", projectID, true).Get(&board) + if err != nil { + return nil, err + } + if exist { + return &board, nil + } + + // represents a board for issues not assigned to one return &ProjectBoard{ ProjectID: projectID, Title: "Uncategorized", @@ -187,22 +209,55 @@ func GetUncategorizedBoard(projectID int64) (*ProjectBoard, error) { }, nil } +// SetDefaultBoard represents a board for issues not assigned to one +// if boardID is 0 unset default +func SetDefaultBoard(projectID, boardID int64) error { + sess := x + + _, err := sess.Where(builder.Eq{ + "project_id": projectID, + "`default`": true, + }).Cols("`default`").Update(&ProjectBoard{Default: false}) + if err != nil { + return err + } + + if boardID > 0 { + _, err = sess.ID(boardID).Where(builder.Eq{"project_id": projectID}). + Cols("`default`").Update(&ProjectBoard{Default: true}) + } + + return err +} + // LoadIssues load issues assigned to this board func (b *ProjectBoard) LoadIssues() (IssueList, error) { - var boardID int64 - if !b.Default { - boardID = b.ID + issueList := make([]*Issue, 0, 10) - } else { - // Issues without ProjectBoardID - boardID = -1 + if b.ID != 0 { + issues, err := Issues(&IssuesOptions{ + ProjectBoardID: b.ID, + ProjectID: b.ProjectID, + }) + if err != nil { + return nil, err + } + issueList = issues } - issues, err := Issues(&IssuesOptions{ - ProjectBoardID: boardID, - ProjectID: b.ProjectID, - }) - b.Issues = issues - return issues, err + + if b.Default { + issues, err := Issues(&IssuesOptions{ + ProjectBoardID: -1, // Issues without ProjectBoardID + ProjectID: b.ProjectID, + }) + if err != nil { + return nil, err + } + issueList = append(issueList, issues...) + } + + b.Issues = issueList + return issueList, nil } // LoadIssues load issues assigned to the boards diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4264d260d..4546a06e8 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -945,6 +945,8 @@ projects.board.edit_title = "New Board Name" projects.board.new_title = "New Board Name" projects.board.new_submit = "Submit" projects.board.new = "New Board" +projects.board.set_default = "Set Default" +projects.board.set_default_desc = "Set this board as default for uncategorized issues and pulls" projects.board.delete = "Delete Board" projects.board.deletion_desc = "Deleting a project board moves all related issues to 'Uncategorized'. Continue?" projects.open = Open diff --git a/routers/repo/projects.go b/routers/repo/projects.go index 08746aad9..d3cdab6b7 100644 --- a/routers/repo/projects.go +++ b/routers/repo/projects.go @@ -270,23 +270,17 @@ func ViewProject(ctx *context.Context) { return } - uncategorizedBoard, err := models.GetUncategorizedBoard(project.ID) - uncategorizedBoard.Title = ctx.Tr("repo.projects.type.uncategorized") - if err != nil { - ctx.ServerError("GetUncategorizedBoard", err) - return - } - boards, err := models.GetProjectBoards(project.ID) if err != nil { ctx.ServerError("GetProjectBoards", err) return } - allBoards := models.ProjectBoardList{uncategorizedBoard} - allBoards = append(allBoards, boards...) + if boards[0].ID == 0 { + boards[0].Title = ctx.Tr("repo.projects.type.uncategorized") + } - if ctx.Data["Issues"], err = allBoards.LoadIssues(); err != nil { + if ctx.Data["Issues"], err = boards.LoadIssues(); err != nil { ctx.ServerError("LoadIssuesOfBoards", err) return } @@ -295,7 +289,7 @@ func ViewProject(ctx *context.Context) { ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects) ctx.Data["Project"] = project - ctx.Data["Boards"] = allBoards + ctx.Data["Boards"] = boards ctx.Data["PageIsProjects"] = true ctx.Data["RequiresDraggable"] = true @@ -416,21 +410,19 @@ func AddBoardToProjectPost(ctx *context.Context, form auth.EditProjectBoardTitle }) } -// EditProjectBoardTitle allows a project board's title to be updated -func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitleForm) { - +func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project, *models.ProjectBoard) { if ctx.User == nil { ctx.JSON(403, map[string]string{ "message": "Only signed in users are allowed to perform this action.", }) - return + return nil, nil } if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, models.UnitTypeProjects) { ctx.JSON(403, map[string]string{ "message": "Only authorized users are allowed to perform this action.", }) - return + return nil, nil } project, err := models.GetProjectByID(ctx.ParamsInt64(":id")) @@ -440,25 +432,35 @@ func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitle } else { ctx.ServerError("GetProjectByID", err) } - return + return nil, nil } board, err := models.GetProjectBoard(ctx.ParamsInt64(":boardID")) if err != nil { ctx.ServerError("GetProjectBoard", err) - return + return nil, nil } if board.ProjectID != ctx.ParamsInt64(":id") { ctx.JSON(422, map[string]string{ "message": fmt.Sprintf("ProjectBoard[%d] is not in Project[%d] as expected", board.ID, project.ID), }) - return + return nil, nil } if project.RepoID != ctx.Repo.Repository.ID { ctx.JSON(422, map[string]string{ "message": fmt.Sprintf("ProjectBoard[%d] is not in Repository[%d] as expected", board.ID, ctx.Repo.Repository.ID), }) + return nil, nil + } + return project, board +} + +// EditProjectBoardTitle allows a project board's title to be updated +func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitleForm) { + + _, board := checkProjectBoardChangePermissions(ctx) + if ctx.Written() { return } @@ -476,6 +478,24 @@ func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitle }) } +// SetDefaultProjectBoard set default board for uncategorized issues/pulls +func SetDefaultProjectBoard(ctx *context.Context) { + + project, board := checkProjectBoardChangePermissions(ctx) + if ctx.Written() { + return + } + + if err := models.SetDefaultBoard(project.ID, board.ID); err != nil { + ctx.ServerError("SetDefaultBoard", err) + return + } + + ctx.JSON(200, map[string]interface{}{ + "ok": true, + }) +} + // MoveIssueAcrossBoards move a card from one board to another in a project func MoveIssueAcrossBoards(ctx *context.Context) { diff --git a/routers/repo/projects_test.go b/routers/repo/projects_test.go new file mode 100644 index 000000000..c43cf6d95 --- /dev/null +++ b/routers/repo/projects_test.go @@ -0,0 +1,28 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "testing" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/test" + + "github.com/stretchr/testify/assert" +) + +func TestCheckProjectBoardChangePermissions(t *testing.T) { + models.PrepareTestEnv(t) + ctx := test.MockContext(t, "user2/repo1/projects/1/2") + test.LoadUser(t, ctx, 2) + test.LoadRepo(t, ctx, 1) + ctx.SetParams(":id", "1") + ctx.SetParams(":boardID", "2") + + project, board := checkProjectBoardChangePermissions(ctx) + assert.NotNil(t, project) + assert.NotNil(t, board) + assert.False(t, ctx.Written()) +} diff --git a/routers/routes/macaron.go b/routers/routes/macaron.go index d331e4ca8..34978724a 100644 --- a/routers/routes/macaron.go +++ b/routers/routes/macaron.go @@ -800,6 +800,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/:boardID", func() { m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle) m.Delete("", repo.DeleteProjectBoard) + m.Post("/default", repo.SetDefaultProjectBoard) m.Post("/:index", repo.MoveIssueAcrossBoards) }) diff --git a/templates/repo/projects/view.tmpl b/templates/repo/projects/view.tmpl index b27773f71..a3606c169 100644 --- a/templates/repo/projects/view.tmpl +++ b/templates/repo/projects/view.tmpl @@ -85,6 +85,12 @@ {{svg "octicon-pencil"}} {{$.i18n.Tr "repo.projects.board.edit"}} + {{if not .Default}} + + {{svg "octicon-pin"}} + {{$.i18n.Tr "repo.projects.board.set_default"}} + + {{end}} {{svg "octicon-trashcan"}} {{$.i18n.Tr "repo.projects.board.delete"}} @@ -109,24 +115,34 @@
+ +
diff --git a/web_src/js/features/projects.js b/web_src/js/features/projects.js index 13318c9f8..b5f52f744 100644 --- a/web_src/js/features/projects.js +++ b/web_src/js/features/projects.js @@ -27,14 +27,14 @@ export default async function initProject() { }, }); }, - } + }, ); } $('.edit-project-board').each(function () { const projectTitleLabel = $(this).closest('.board-column-header').find('.board-label'); const projectTitleInput = $(this).find( - '.content > .form > .field > .project-board-title' + '.content > .form > .field > .project-board-title', ); $(this) @@ -59,6 +59,21 @@ export default async function initProject() { }); }); + $(document).on('click', '.set-default-project-board', async function (e) { + e.preventDefault(); + + await $.ajax({ + method: 'POST', + url: $(this).data('url'), + headers: { + 'X-Csrf-Token': csrf, + 'X-Remote': true, + }, + contentType: 'application/json', + }); + + window.location.reload(); + }); $('.delete-project-board').each(function () { $(this).click(function (e) { e.preventDefault(); @@ -72,7 +87,7 @@ export default async function initProject() { contentType: 'application/json', method: 'DELETE', }).done(() => { - setTimeout(window.location.reload(true), 2000); + window.location.reload(); }); }); }); @@ -93,7 +108,7 @@ export default async function initProject() { method: 'POST', }).done(() => { boardTitle.closest('form').removeClass('dirty'); - setTimeout(window.location.reload(true), 2000); + window.location.reload(); }); }); } From 2db4733c7d75b3ca3d1b2750f7b6ed53ac75303c Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 15 Jan 2021 20:30:48 +0000 Subject: [PATCH 0013/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_zh-TW.ini | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 4d7d19e14..7625a5816 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1999,6 +1999,7 @@ dashboard=資訊主頁 users=使用者帳戶 organizations=組織 repositories=儲存庫 +hooks=Webhook authentication=認證來源 emails=使用者電子信箱 config=組態 @@ -2148,8 +2149,13 @@ repos.forks=Fork 數 repos.issues=問題數 repos.size=大小 +defaulthooks=預設 Webhook +defaulthooks.desc=當觸發某些 Gitea 事件時,Webhook 會自動發出 HTTP POST 請求到指定的伺服器。這裡所定義的 Webhook 是預設的,並且會複製到所有新儲存庫。在 Webhook 指南閱讀更多內容。 +defaulthooks.add_webhook=新增預設 Webhook +defaulthooks.update_webhook=更新預設 Webhook systemhooks=系統 Webhook +systemhooks.desc=當觸發某些 Gitea 事件時,Webhook 會自動發出 HTTP POST 請求到指定的伺服器。由於這裡所定義的 Webhook 會影響此系統上的所有儲存庫,因此請評估這會對效能造成多少影響。在 Webhook 指南閱讀更多內容。 systemhooks.add_webhook=新增系統 Webhook systemhooks.update_webhook=更新系統 Webhook From 0a3c3357f388cc60d5f43a056ee2381e51586cff Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Sat, 16 Jan 2021 06:55:17 +0200 Subject: [PATCH 0014/1137] Sort issue search results by revelance (#14353) --- models/issue.go | 2 +- models/issue_test.go | 2 +- modules/indexer/issues/bleve.go | 1 + modules/indexer/issues/elastic_search.go | 2 +- modules/indexer/issues/indexer_test.go | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/models/issue.go b/models/issue.go index b517f334c..7731a59ed 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1682,7 +1682,7 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6 ) var ids = make([]int64, 0, limit) - err := x.Distinct("id").Table("issue").Where(cond).Limit(limit, start).Find(&ids) + err := x.Distinct("id").Table("issue").Where(cond).OrderBy("`updated_unix` DESC").Limit(limit, start).Find(&ids) if err != nil { return 0, nil, err } diff --git a/models/issue_test.go b/models/issue_test.go index 1f65cb433..8fbc49a46 100644 --- a/models/issue_test.go +++ b/models/issue_test.go @@ -299,7 +299,7 @@ func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { total, ids, err = SearchIssueIDsByKeyword("for", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 5, total) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) // issue1's comment id 2 total, ids, err = SearchIssueIDsByKeyword("good", []int64{1}, 10, 0) diff --git a/modules/indexer/issues/bleve.go b/modules/indexer/issues/bleve.go index a1f51dba5..4a1e2bc51 100644 --- a/modules/indexer/issues/bleve.go +++ b/modules/indexer/issues/bleve.go @@ -247,6 +247,7 @@ func (b *BleveIndexer) Search(keyword string, repoIDs []int64, limit, start int) newMatchPhraseQuery(keyword, "Comments", issueIndexerAnalyzer), )) search := bleve.NewSearchRequestOptions(indexerQuery, limit, start, false) + search.SortBy([]string{"-_score"}) result, err := b.indexer.Search(search) if err != nil { diff --git a/modules/indexer/issues/elastic_search.go b/modules/indexer/issues/elastic_search.go index 4cdeff53d..3af64ed30 100644 --- a/modules/indexer/issues/elastic_search.go +++ b/modules/indexer/issues/elastic_search.go @@ -205,7 +205,7 @@ func (b *ElasticSearchIndexer) Search(keyword string, repoIDs []int64, limit, st searchResult, err := b.client.Search(). Index(b.indexerName). Query(query). - Sort("id", true). + Sort("_score", false). From(start).Size(limit). Do(context.Background()) if err != nil { diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 95007d8fa..8c163f78d 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -65,7 +65,7 @@ func TestBleveSearchIssues(t *testing.T) { ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) @@ -89,7 +89,7 @@ func TestDBSearchIssues(t *testing.T) { ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) From 76fefd803fde5899022777dc9aef8bdc09472107 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 16 Jan 2021 04:56:29 +0000 Subject: [PATCH 0015/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 9 +++++++++ options/locale/locale_tr-TR.ini | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 322f0c9c9..af0b98515 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -358,6 +358,7 @@ password_not_match=パスワードが一致しません。 lang_select_error=言語をリストから選択してください。 username_been_taken=ユーザー名が既に使用されています。 +username_change_not_local_user=非ローカルユーザーのユーザー名は変更できません。 repo_name_been_taken=リポジトリ名が既に使用されています。 repository_files_already_exist=このリポジトリのファイルはすでに存在します。システム管理者に問い合わせてください。 repository_files_already_exist.adopt=このリポジトリのファイルはすでに存在しており、それらを登録することしかできません。 @@ -821,6 +822,8 @@ tag=タグ released_this=がこれをリリース file_raw=Raw file_history=履歴 +file_view_source=ソースを表示 +file_view_rendered=レンダリング表示 file_view_raw=Rawデータを見る file_permalink=パーマリンク file_too_large=このファイルは大きすぎるため、表示できません。 @@ -1997,6 +2000,7 @@ dashboard=ダッシュボード users=ユーザーアカウント organizations=組織 repositories=リポジトリ +hooks=Webhook authentication=認証ソース emails=ユーザーメールアドレス config=設定 @@ -2146,8 +2150,13 @@ repos.forks=フォーク repos.issues=課題 repos.size=サイズ +defaulthooks=デフォルトWebhook +defaulthooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義されたWebhookはデフォルトとなり、全ての新規リポジトリにコピーされます。 詳しくはwebhooks guideをご覧下さい。 +defaulthooks.add_webhook=デフォルトWebhookの追加 +defaulthooks.update_webhook=デフォルトWebhookの更新 systemhooks=システムWebhook +systemhooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義したWebhookはシステム内のすべてのリポジトリで呼び出されます。 そのため、パフォーマンスに及ぼす影響を考慮したうえで設定してください。 詳しくはwebhooks guideをご覧下さい。 systemhooks.add_webhook=システムWebhookを追加 systemhooks.update_webhook=システムWebhookを更新 diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index e0f279055..e5b2ad575 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -358,6 +358,7 @@ password_not_match=Parolalar uyuşmuyor. lang_select_error=Listeden bir dil seçin. username_been_taken=Bu kullanıcı adı daha önce alınmış. +username_change_not_local_user=Yerel olmayan kullanıcılar kendi kullanıcı adlarını değiştiremezler. repo_name_been_taken=Depo adı zaten kullanılıyor. repository_files_already_exist=Bu depo için dosyalar zaten var. Sistem yöneticisine başvurun. repository_files_already_exist.adopt=Bu depo için dosyalar zaten var ve yalnızca Kabul Edilebilir. @@ -821,6 +822,8 @@ tag=Etiket released_this=bu sürümü yayınladı file_raw=Ham file_history=Geçmiş +file_view_source=Kaynağı Görüntüle +file_view_rendered=Oluşturulanları Görüntüle file_view_raw=Ham Görünüm file_permalink=Kalıcı Bağlantı file_too_large=Bu dosya görüntülemek için çok büyük. @@ -941,6 +944,8 @@ projects.board.edit_title=Yeni Pano Adı projects.board.new_title=Yeni Pano Adı projects.board.new_submit=Gönder projects.board.new=Yeni Pano +projects.board.set_default=Varsayılana Ayarla +projects.board.set_default_desc=Kategorize edilmemiş konular ve çekme istekleri için bu panoyu varsayılan olarak ayarlayın projects.board.delete=Panoyu Sil projects.board.deletion_desc=Bir proje panosunun silinmesi, ilgili tüm konuları 'Kategorize edilmemiş'e taşır. Devam edilsin mi? projects.open=Aç @@ -1482,7 +1487,7 @@ settings.use_external_issue_tracker=Harici Konu İzleyici Kullan settings.external_tracker_url=Harici Konu İzleyici URLsi settings.external_tracker_url_error=Harici konu izleyici URL'si geçerli bir URL değil. settings.external_tracker_url_desc=Ziyaretçiler, konular sekmesine tıkladığında harici konu izleyici URL'sine yönlendirilir. -settings.tracker_url_format=Harici Sorun Takipçisi Bağlantı Formatı +settings.tracker_url_format=Harici Konu İzleyici URL Biçimi settings.tracker_url_format_error=Harici konu izleyici URL biçimi geçerli bir URL değil. settings.tracker_issue_style=Harici Konu İzleyici Numara Biçimi settings.tracker_issue_style.numeric=Sayısal @@ -1997,6 +2002,7 @@ dashboard=Pano users=Kullanıcı Hesapları organizations=Organizasyonlar repositories=Depolar +hooks=Web İstemcileri authentication=Yetkilendirme Kaynakları emails=Kullanıcı E-postaları config=Yapılandırma @@ -2084,7 +2090,7 @@ users.full_name=Tam İsim users.activated=Aktifleştirilmiş users.admin=Yönetici users.restricted=Kısıtlanmış -users.2fa=2ED +users.2fa=2FD users.repos=Depolar users.created=Oluşturuldu users.last_login=Son Oturum Açma @@ -2113,6 +2119,7 @@ users.delete_account=Kullanıcı Hesabını Sil users.still_own_repo=Bu kullanıcı hala bir veya daha fazla depoya sahip. Önce bu depoları silin veya transfer edin. users.still_has_org=Bu kullanıcı bir organizasyonun üyesidir. Önce kullanıcıyı tüm organizasyonlardan çıkarın. users.deletion_success=Kullanıcı hesabı silindi. +users.reset_2fa=2FD'yi sıfırla emails.email_manage_panel=Kullanıcı E-posta Yönetimi emails.primary=Birincil @@ -2145,8 +2152,13 @@ repos.forks=Çatallar repos.issues=Konular repos.size=Boyut +defaulthooks=Varsayılan Web İstemcileri +defaulthooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. web istemcileri kılavuzunda daha fazla bilgi edinin. +defaulthooks.add_webhook=Varsayılan Web İstemcisi Ekle +defaulthooks.update_webhook=Varsayılan Web İstemcisini Güncelle systemhooks=Sistem Web İstemcileri +systemhooks.desc=Belirli Gitea olayları tetiklendiğinde Web istemcileri otomatik olarak bir sunucuya HTTP POST istekleri yapar. Burada tanımlanan web istemcileri sistemdeki tüm depolar üzerinde çalışır, bu yüzden lütfen bunun olabilecek tüm performans sonuçlarını göz önünde bulundurun. web istemcileri kılavuzunda daha fazla bilgi edinin. systemhooks.add_webhook=Sistem Web İstemcisi Ekle systemhooks.update_webhook=Sistem Web İstemcisi Güncelle From dc66e4740f1d788e67f758ee3a6bbeb646ad704a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 16 Jan 2021 19:23:02 +0800 Subject: [PATCH 0016/1137] Fix middlewares sequences (#14354) Co-authored-by: 6543 <6543@obermui.de> --- routers/api/v1/api.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index e9f1a395e..02ad8ab36 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -640,7 +640,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/:username/:reponame", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). Delete(reqToken(), reqOwner(), repo.Delete). - Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRefForAPI(), repo.Edit) + Patch(reqToken(), reqAdmin(), context.RepoRefForAPI(), bind(api.EditRepoOption{}), repo.Edit) m.Post("/transfer", reqOwner(), bind(api.TransferRepoOption{}), repo.Transfer) m.Combo("/notifications"). Get(reqToken(), notify.ListRepoNotifications). @@ -713,8 +713,8 @@ func RegisterRoutes(m *macaron.Macaron) { Delete(reqToken(), repo.DeleteIssueComment) m.Combo("/reactions"). Get(repo.GetIssueCommentReactions). - Post(bind(api.EditReactionOption{}), reqToken(), repo.PostIssueCommentReaction). - Delete(bind(api.EditReactionOption{}), reqToken(), repo.DeleteIssueCommentReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) }) }) m.Group("/:index", func() { @@ -754,8 +754,8 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Combo("/reactions"). Get(repo.GetIssueReactions). - Post(bind(api.EditReactionOption{}), reqToken(), repo.PostIssueReaction). - Delete(bind(api.EditReactionOption{}), reqToken(), repo.DeleteIssueReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueReaction) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { From e6155ff9b689872b3797fe1e2504e5919b0c4888 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 16 Jan 2021 11:24:18 +0000 Subject: [PATCH 0017/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_zh-TW.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 7625a5816..d23d8a9c1 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -943,6 +943,8 @@ projects.board.edit_title=新看板名稱 projects.board.new_title=新看板名稱 projects.board.new_submit=送出 projects.board.new=新增看板 +projects.board.set_default=設為預設 +projects.board.set_default_desc=將此看板設定為未分類問題及合併請求的預設看板 projects.board.delete=刪除看板 projects.board.deletion_desc=刪除專案看板會將相關的問題移動到 '未分類'。是否繼續? projects.open=開啟 From 4d9349123fb6102357c39a728c55d648a16be3b8 Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 15:15:57 +0100 Subject: [PATCH 0018/1137] label and milestone webhooks on issue/pull creation (#14363) --- services/issue/issue.go | 6 ++++++ services/pull/pull.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/services/issue/issue.go b/services/issue/issue.go index 14de0290a..90f689a55 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -29,6 +29,12 @@ func NewIssue(repo *models.Repository, issue *models.Issue, labelIDs []int64, uu } notification.NotifyNewIssue(issue, mentions) + if len(issue.Labels) > 0 { + notification.NotifyIssueChangeLabels(issue.Poster, issue, issue.Labels, nil) + } + if issue.Milestone != nil { + notification.NotifyIssueChangeMilestone(issue.Poster, issue, 0) + } return nil } diff --git a/services/pull/pull.go b/services/pull/pull.go index 1886448ee..92f1ff65f 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -59,6 +59,12 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6 } notification.NotifyNewPullRequest(pr, mentions) + if len(pull.Labels) > 0 { + notification.NotifyIssueChangeLabels(pull.Poster, pull, pull.Labels, nil) + } + if pull.Milestone != nil { + notification.NotifyIssueChangeMilestone(pull.Poster, pull, 0) + } // add first push codes comment baseGitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) From 66e426b2f18dfa8806e89f3c225051dd1b3a37e2 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 17 Jan 2021 14:17:10 +0000 Subject: [PATCH 0019/1137] [skip ci] Updated translations via Crowdin --- options/locale/locale_tr-TR.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index e5b2ad575..2beebac8b 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2501,6 +2501,7 @@ mirror_sync_delete=%[3]s adresindeki %[2]s refe approve_pull_request=`%s#%[2]s onaylandı` reject_pull_request=`%s#%[2]s için değişiklik önerdi ` publish_release=` %[3]s deposunda "%[4]s" sürümü yayınlandı` +create_branch=%[3]s dalını %[4]s içinde oluşturdu [tool] ago=%s önce From 872d3088920f8da2070f497f40d89d35fff9679f Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 15:57:42 +0100 Subject: [PATCH 0020/1137] escape branch names in compare url (#14364) --- routers/repo/editor.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/repo/editor.go b/routers/repo/editor.go index 7538c4cda..afb6605dc 100644 --- a/routers/repo/editor.go +++ b/routers/repo/editor.go @@ -287,7 +287,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } else if models.IsErrCommitIDDoesNotMatch(err) { ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplEditFile, &form) } else if git.IsErrPushOutOfDate(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+form.NewBranchName), tplEditFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { @@ -319,7 +319,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } @@ -500,7 +500,7 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) { ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath)) if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { treePath := filepath.Dir(ctx.Repo.TreePath) if treePath == "." { @@ -677,7 +677,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { branchErr := err.(models.ErrBranchAlreadyExists) ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplUploadFile, &form) } else if git.IsErrPushOutOfDate(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+ctx.Repo.CommitID+"..."+form.NewBranchName), tplUploadFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+ctx.Repo.CommitID+"..."+util.PathEscapeSegments(form.NewBranchName)), tplUploadFile, &form) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { @@ -703,7 +703,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } From acb1ceb1f426e87e7f821c01ab5b60dad7abc03d Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 17:34:19 +0100 Subject: [PATCH 0021/1137] Add review requested filter on pull request overview (#13701) * Add review requested filter on pull request overview #13682 fix formatting * add review_requested filter to /repos/issues/search API endpoint * only Approve and Reject status should supersede Request status * add support for team reviews * refactor: remove duplication of issue filtering conditions --- models/issue.go | 159 +++++++++++++-------- options/locale/locale_en-US.ini | 1 + routers/api/v1/repo/issue.go | 9 +- routers/repo/issue.go | 53 +++---- routers/user/home.go | 6 +- templates/repo/issue/list.tmpl | 3 + templates/repo/issue/milestone_issues.tmpl | 1 + templates/swagger/v1_json.tmpl | 6 + templates/user/dashboard/issues.tmpl | 6 + 9 files changed, 156 insertions(+), 88 deletions(-) diff --git a/models/issue.go b/models/issue.go index 7731a59ed..3cd85dc6a 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1090,6 +1090,7 @@ type IssuesOptions struct { AssigneeID int64 PosterID int64 MentionedID int64 + ReviewRequestedID int64 MilestoneIDs []int64 ProjectID int64 ProjectBoardID int64 @@ -1151,8 +1152,7 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } if len(opts.RepoIDs) > 0 { - // In case repository IDs are provided but actually no repository has issue. - sess.In("issue.repo_id", opts.RepoIDs) + applyReposCondition(sess, opts.RepoIDs) } switch opts.IsClosed { @@ -1163,18 +1163,19 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } if opts.AssigneeID > 0 { - sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.AssigneeID) + applyAssigneeCondition(sess, opts.AssigneeID) } if opts.PosterID > 0 { - sess.And("issue.poster_id=?", opts.PosterID) + applyPosterCondition(sess, opts.PosterID) } if opts.MentionedID > 0 { - sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). - And("issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.MentionedID) + applyMentionedCondition(sess, opts.MentionedID) + } + + if opts.ReviewRequestedID > 0 { + applyReviewRequestedCondition(sess, opts.ReviewRequestedID) } if len(opts.MilestoneIDs) > 0 { @@ -1232,6 +1233,33 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } } +func applyReposCondition(sess *xorm.Session, repoIDs []int64) *xorm.Session { + return sess.In("issue.repo_id", repoIDs) +} + +func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) *xorm.Session { + return sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). + And("issue_assignees.assignee_id = ?", assigneeID) +} + +func applyPosterCondition(sess *xorm.Session, posterID int64) *xorm.Session { + return sess.And("issue.poster_id=?", posterID) +} + +func applyMentionedCondition(sess *xorm.Session, mentionedID int64) *xorm.Session { + return sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). + And("issue_user.is_mentioned = ?", true). + And("issue_user.uid = ?", mentionedID) +} + +func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64) *xorm.Session { + return sess.Join("INNER", []string{"review", "r"}, "issue.id = r.issue_id"). + And("r.type = ?", ReviewTypeRequest). + And("r.reviewer_id = ? and r.id in (select max(id) from review where issue_id = r.issue_id and reviewer_id = r.reviewer_id and type in (?, ?, ?))"+ + " or r.reviewer_team_id in (select team_id from team_user where uid = ?)", + reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID) +} + // CountIssuesByRepo map from repoID to number of issues matching the options func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) { sess := x.NewSession() @@ -1364,6 +1392,7 @@ type IssueStats struct { AssignCount int64 CreateCount int64 MentionCount int64 + ReviewRequestedCount int64 } // Filter modes. @@ -1372,6 +1401,7 @@ const ( FilterModeAssign FilterModeCreate FilterModeMention + FilterModeReviewRequested ) func parseCountResult(results []map[string][]byte) int64 { @@ -1387,14 +1417,15 @@ func parseCountResult(results []map[string][]byte) int64 { // IssueStatsOptions contains parameters accepted by GetIssueStats. type IssueStatsOptions struct { - RepoID int64 - Labels string - MilestoneID int64 - AssigneeID int64 - MentionedID int64 - PosterID int64 - IsPull util.OptionalBool - IssueIDs []int64 + RepoID int64 + Labels string + MilestoneID int64 + AssigneeID int64 + MentionedID int64 + PosterID int64 + ReviewRequestedID int64 + IsPull util.OptionalBool + IssueIDs []int64 } // GetIssueStats returns issue statistic information by given conditions. @@ -1423,6 +1454,7 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { accum.AssignCount += stats.AssignCount accum.CreateCount += stats.CreateCount accum.OpenCount += stats.MentionCount + accum.ReviewRequestedCount += stats.ReviewRequestedCount i = chunk } return accum, nil @@ -1460,18 +1492,19 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, } if opts.AssigneeID > 0 { - sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.AssigneeID) + applyAssigneeCondition(sess, opts.AssigneeID) } if opts.PosterID > 0 { - sess.And("issue.poster_id = ?", opts.PosterID) + applyPosterCondition(sess, opts.PosterID) } if opts.MentionedID > 0 { - sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). - And("issue_user.uid = ?", opts.MentionedID). - And("issue_user.is_mentioned = ?", true) + applyMentionedCondition(sess, opts.MentionedID) + } + + if opts.ReviewRequestedID > 0 { + applyReviewRequestedCondition(sess, opts.ReviewRequestedID) } switch opts.IsPull { @@ -1539,57 +1572,66 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) { switch opts.FilterMode { case FilterModeAll: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). + stats.OpenCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). + stats.ClosedCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeAssign: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). + stats.OpenCount, err = applyAssigneeCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). + stats.ClosedCount, err = applyAssigneeCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeCreate: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - And("issue.poster_id = ?", opts.UserID). + stats.OpenCount, err = applyPosterCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - And("issue.poster_id = ?", opts.UserID). + stats.ClosedCount, err = applyPosterCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeMention: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). + stats.OpenCount, err = applyMentionedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). + stats.ClosedCount, err = applyMentionedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). + Count(new(Issue)) + if err != nil { + return nil, err + } + case FilterModeReviewRequested: + stats.OpenCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). + Count(new(Issue)) + if err != nil { + return nil, err + } + stats.ClosedCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err @@ -1597,32 +1639,27 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) { } cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed}) - stats.AssignCount, err = sess(cond). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). - Count(new(Issue)) + stats.AssignCount, err = applyAssigneeCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.CreateCount, err = sess(cond). - And("poster_id = ?", opts.UserID). - Count(new(Issue)) + stats.CreateCount, err = applyPosterCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.MentionCount, err = sess(cond). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). - Count(new(Issue)) + stats.MentionCount, err = applyMentionedCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.YourRepositoriesCount, err = sess(cond). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). - Count(new(Issue)) + stats.YourRepositoriesCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs).Count(new(Issue)) + if err != nil { + return nil, err + } + + stats.ReviewRequestedCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } @@ -1646,13 +1683,11 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen switch filterMode { case FilterModeAssign: - openCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", uid) - closedCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", uid) + applyAssigneeCondition(openCountSession, uid) + applyAssigneeCondition(closedCountSession, uid) case FilterModeCreate: - openCountSession.And("poster_id = ?", uid) - closedCountSession.And("poster_id = ?", uid) + applyPosterCondition(openCountSession, uid) + applyPosterCondition(closedCountSession, uid) } openResult, _ := openCountSession.Count(new(Issue)) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4546a06e8..73451eeeb 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1030,6 +1030,7 @@ issues.filter_type.all_issues = All issues issues.filter_type.assigned_to_you = Assigned to you issues.filter_type.created_by_you = Created by you issues.filter_type.mentioning_you = Mentioning you +issues.filter_type.review_requested = Review requested issues.filter_sort = Sort issues.filter_sort.latest = Newest issues.filter_sort.oldest = Oldest diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 25153ad50..bab8f373c 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -79,6 +79,10 @@ func SearchIssues(ctx *context.APIContext) { // in: query // description: filter (issues / pulls) mentioning you, default is false // type: boolean + // - name: review_requested + // in: query + // description: filter pulls requesting your review, default is false + // type: boolean // - name: page // in: query // description: page number of results to return (1-based) @@ -204,7 +208,7 @@ func SearchIssues(ctx *context.APIContext) { UpdatedAfterUnix: since, } - // Filter for: Created by User, Assigned to User, Mentioning User + // Filter for: Created by User, Assigned to User, Mentioning User, Review of User Requested if ctx.QueryBool("created") { issuesOpt.PosterID = ctx.User.ID } @@ -214,6 +218,9 @@ func SearchIssues(ctx *context.APIContext) { if ctx.QueryBool("mentioned") { issuesOpt.MentionedID = ctx.User.ID } + if ctx.QueryBool("review_requested") { + issuesOpt.ReviewRequestedID = ctx.User.ID + } if issues, err = models.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 478baf8d8..7b4044ac7 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -113,16 +113,17 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti var err error viewType := ctx.Query("type") sortType := ctx.Query("sort") - types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned"} + types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested"} if !util.IsStringInSlice(viewType, types, true) { viewType = "all" } var ( - assigneeID = ctx.QueryInt64("assignee") - posterID int64 - mentionedID int64 - forceEmpty bool + assigneeID = ctx.QueryInt64("assignee") + posterID int64 + mentionedID int64 + reviewRequestedID int64 + forceEmpty bool ) if ctx.IsSigned { @@ -133,6 +134,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti mentionedID = ctx.User.ID case "assigned": assigneeID = ctx.User.ID + case "review_requested": + reviewRequestedID = ctx.User.ID } } @@ -169,14 +172,15 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti issueStats = &models.IssueStats{} } else { issueStats, err = models.GetIssueStats(&models.IssueStatsOptions{ - RepoID: repo.ID, - Labels: selectLabels, - MilestoneID: milestoneID, - AssigneeID: assigneeID, - MentionedID: mentionedID, - PosterID: posterID, - IsPull: isPullOption, - IssueIDs: issueIDs, + RepoID: repo.ID, + Labels: selectLabels, + MilestoneID: milestoneID, + AssigneeID: assigneeID, + MentionedID: mentionedID, + PosterID: posterID, + ReviewRequestedID: reviewRequestedID, + IsPull: isPullOption, + IssueIDs: issueIDs, }) if err != nil { ctx.ServerError("GetIssueStats", err) @@ -217,17 +221,18 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti Page: pager.Paginater.Current(), PageSize: setting.UI.IssuePagingNum, }, - RepoIDs: []int64{repo.ID}, - AssigneeID: assigneeID, - PosterID: posterID, - MentionedID: mentionedID, - MilestoneIDs: mileIDs, - ProjectID: projectID, - IsClosed: util.OptionalBoolOf(isShowClosed), - IsPull: isPullOption, - LabelIDs: labelIDs, - SortType: sortType, - IssueIDs: issueIDs, + RepoIDs: []int64{repo.ID}, + AssigneeID: assigneeID, + PosterID: posterID, + MentionedID: mentionedID, + ReviewRequestedID: reviewRequestedID, + MilestoneIDs: mileIDs, + ProjectID: projectID, + IsClosed: util.OptionalBoolOf(isShowClosed), + IsPull: isPullOption, + LabelIDs: labelIDs, + SortType: sortType, + IssueIDs: issueIDs, }) if err != nil { ctx.ServerError("Issues", err) diff --git a/routers/user/home.go b/routers/user/home.go index 3c27bbe2a..a8a8a5f3d 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -392,6 +392,8 @@ func buildIssueOverview(ctx *context.Context, unitType models.UnitType) { filterMode = models.FilterModeCreate case "mentioned": filterMode = models.FilterModeMention + case "review_requested": + filterMode = models.FilterModeReviewRequested case "your_repositories": // filterMode already set to All default: viewType = "your_repositories" @@ -431,7 +433,9 @@ func buildIssueOverview(ctx *context.Context, unitType models.UnitType) { case models.FilterModeCreate: opts.PosterID = ctx.User.ID case models.FilterModeMention: - opts.MentionedID = ctx.User.ID + opts.MentionedID = ctxUser.ID + case models.FilterModeReviewRequested: + opts.ReviewRequestedID = ctxUser.ID } if ctxUser.IsOrganization() { diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 2b64d2670..7b856e60c 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -89,6 +89,9 @@ {{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}} {{.i18n.Tr "repo.issues.filter_type.created_by_you"}} {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} + {{if .PageIsPullList}} + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} + {{end}}

{{end}} diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index 638134c44..c2c81682f 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -88,6 +88,7 @@ {{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}} {{.i18n.Tr "repo.issues.filter_type.created_by_you"}} {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} {{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 81ccf4f72..6650c09bb 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1911,6 +1911,12 @@ "name": "mentioned", "in": "query" }, + { + "type": "boolean", + "description": "filter pulls requesting your review, default is false", + "name": "review_requested", + "in": "query" + }, { "type": "integer", "description": "page number of results to return (1-based)", diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl index 62428dce4..dfd0e5d8e 100644 --- a/templates/user/dashboard/issues.tmpl +++ b/templates/user/dashboard/issues.tmpl @@ -21,6 +21,12 @@ {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} {{CountFmt .IssueStats.MentionCount}} + {{if .PageIsPulls}} + + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} + {{CountFmt .IssueStats.ReviewRequestedCount}} + + {{end}}
All From ca63a9d3f1120d8c76eb83ff1fd07e0992a683a8 Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Sun, 17 Jan 2021 19:29:10 +0200 Subject: [PATCH 0022/1137] Add edit, delete and reaction support to code review comments on issue page (#14339) --- routers/repo/issue.go | 19 ++++++ templates/repo/diff/comments.tmpl | 2 +- .../repo/issue/view_content/comments.tmpl | 63 ++++++++++++++----- .../repo/issue/view_content/context_menu.tmpl | 6 +- web_src/less/_repository.less | 31 +++++++++ 5 files changed, 101 insertions(+), 20 deletions(-) diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 7b4044ac7..6a532dc12 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1377,7 +1377,26 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("Review.LoadCodeComments", err) return } + for _, codeComments := range comment.Review.CodeComments { + for _, lineComments := range codeComments { + for _, c := range lineComments { + // Check tag. + tag, ok = marked[c.PosterID] + if ok { + c.ShowTag = tag + continue + } + c.ShowTag, err = commentTag(repo, c.Poster, issue) + if err != nil { + ctx.ServerError("commentTag", err) + return + } + marked[c.PosterID] = c.ShowTag + participants = addParticipant(c.Poster, participants) + } + } + } if err = comment.LoadResolveDoer(); err != nil { ctx.ServerError("LoadResolveDoer", err) return diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index 59bc89b79..36e725936 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -47,7 +47,7 @@ {{end}} {{end}} {{template "repo/issue/view_content/add_reaction" Dict "ctx" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }} - {{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 8f5426b83..abf5792a9 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -58,7 +58,7 @@
{{end}} {{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} - {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} {{end}} @@ -494,25 +494,49 @@ {{end}} -
+
{{range $comms}} {{ $createdSubStr:= TimeSinceUnix .CreatedUnix $.Lang }}
- {{if not .OriginalAuthor }} - - {{avatar .Poster}} - - {{end}}
- - {{if .OriginalAuthor }} - {{ .OriginalAuthor }} {{if $.Repository.OriginalURL}}({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}} - {{else}} - {{.Poster.GetDisplayName}} - {{end}} - {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}} - +
+
+ {{if not .OriginalAuthor }} + + {{avatar .Poster}} + + {{end}} + + {{if .OriginalAuthor }} + {{ .OriginalAuthor }} {{if $.Repository.OriginalURL}}({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}} + {{else}} + {{.Poster.GetDisplayName}} + {{end}} + {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}} + +
+
+ {{if not $.Repository.IsArchived}} + {{if or (and (eq .PosterID $.Issue.PosterID) (eq $.Issue.OriginalAuthorID 0)) (eq $.Issue.OriginalAuthorID .OriginalAuthorID) }} +
+ {{$.i18n.Tr "repo.issues.poster"}} +
+ {{end}} + {{if gt .ShowTag 0}} +
+ {{if eq .ShowTag 2}} + {{$.i18n.Tr "repo.issues.collaborator"}} + {{else if eq .ShowTag 3}} + {{$.i18n.Tr "repo.issues.owner"}} + {{end}} +
+ {{end}} + {{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} + {{end}} +
+
{{if .RenderedContent}} @@ -521,8 +545,15 @@ {{$.i18n.Tr "repo.issues.no_content"}} {{end}}
-
{{.Content}}
+
{{.Content}}
+
+ {{$reactions := .Reactions.GroupByType}} + {{if $reactions}} +
+ {{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} +
+ {{end}}
{{end}} diff --git a/templates/repo/issue/view_content/context_menu.tmpl b/templates/repo/issue/view_content/context_menu.tmpl index 744821cb3..0b8b84e9f 100644 --- a/templates/repo/issue/view_content/context_menu.tmpl +++ b/templates/repo/issue/view_content/context_menu.tmpl @@ -4,10 +4,10 @@ {{svg "octicon-kebab-horizontal"}}
From e05670da842772869cdef15d3ffeda5e36c7d6d5 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Tue, 19 Jan 2021 15:50:55 +0000 Subject: [PATCH 0036/1137] Note that all template directories are relative to the `CustomPath` configuration, not a `custom` directory inside it (#14399) * Note that all template directories are relative to the `CustomPath` configuration, not a `custom` directory inside it. This is a minor clarification, which makes locating where the templates need to be much easier * Note that it's possible to read the `GITEA_CUSTOM` value from the admin * Use "$GITEA_CUSTOM" as placeholder It's more obvious it's a variable and not a typo --- .../doc/advanced/customizing-gitea.en-us.md | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/content/doc/advanced/customizing-gitea.en-us.md b/docs/content/doc/advanced/customizing-gitea.en-us.md index 9f1a43c01..4ca5a4285 100644 --- a/docs/content/doc/advanced/customizing-gitea.en-us.md +++ b/docs/content/doc/advanced/customizing-gitea.en-us.md @@ -30,7 +30,7 @@ the Linux Filesystem Standard. Gitea will attempt to create required folders, in `custom/`. Distributions may provide a symlink for `custom` using `/etc/gitea/`. Application settings can be found in file `CustomConf` which is by default, -`CustomPath/conf/app.ini` but may be different if your build has set this differently. +`$GITEA_CUSTOM/conf/app.ini` but may be different if your build has set this differently. Again `gitea help` will allow you review this variable and you can override it using the `--config` option on the `gitea` binary. @@ -39,7 +39,8 @@ Again `gitea help` will allow you review this variable and you can override it u If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM` environment variable; this can be used to override the default path to something else. -`GITEA_CUSTOM` might, for example, be set by an init script. +`GITEA_CUSTOM` might, for example, be set by an init script. You can check whether the value +is set under the "Configuration" tab on the site administration page. - [List of Environment Variables](https://docs.gitea.io/en-us/specific-variables/) @@ -52,15 +53,15 @@ environment variable; this can be used to override the default path to something ## Serving custom public files To make Gitea serve custom public files (like pages and images), use the folder -`custom/public/` as the webroot. Symbolic links will be followed. +`$GITEA_CUSTOM/public/` as the webroot. Symbolic links will be followed. -For example, a file `image.png` stored in `custom/public/`, can be accessed with +For example, a file `image.png` stored in `$GITEA_CUSTOM/public/`, can be accessed with the url `http://gitea.domain.tld/image.png`. ## Changing the default logo To build a custom logo replace `assets/logo.svg` and run `make generate-images`. This will update -these customizable logo files which you can then place in `custom/public/img` on your server: +these customizable logo files which you can then place in `$GITEA_CUSTOM/public/img` on your server: - `public/img/logo.svg` - `public/img/logo.png` @@ -72,7 +73,7 @@ these customizable logo files which you can then place in `custom/public/img` on Either generate it via above method or place the png image at the following path: -- `custom/public/img/avatar_default.png` +- `$GITEA_CUSTOM/public/img/avatar_default.png` ## Customizing Gitea pages and resources @@ -80,11 +81,11 @@ Gitea's executable contains all the resources required to run: templates, images and translations. Any of them can be overridden by placing a replacement in a matching path inside the `custom` directory. For example, to replace the default `.gitignore` provided for C++ repositories, we want to replace `options/gitignore/C++`. To do this, a replacement -must be placed in `custom/options/gitignore/C++` (see about the location of the `custom` +must be placed in `$GITEA_CUSTOM/options/gitignore/C++` (see about the location of the `CustomPath` directory at the top of this document). Every single page of Gitea can be changed. Dynamic content is generated using [go templates](https://golang.org/pkg/html/template/), -which can be modified by placing replacements below the `custom/templates` directory. +which can be modified by placing replacements below the `$GITEA_CUSTOM/templates` directory. To obtain any embedded file (including templates), the [`gitea embedded` tool]({{< relref "doc/advanced/cmd-embedded.en-us.md" >}}) can be used. Alternatively, they can be found in the [`templates`](https://github.com/go-gitea/gitea/tree/master/templates) directory of Gitea source (Note: the example link is from the `master` branch. Make sure to use templates compatible with the release you are using). @@ -93,16 +94,16 @@ shouldn't be touched without fully understanding these components. ### Customizing startpage / homepage -Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/master/templates/home.tmpl) for your version of Gitea from `templates` to `custom/templates`. +Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/master/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`. Edit as you wish. Dont forget to restart your gitea to apply the changes. ### Adding links and tabs -If all you want is to add extra links to the top navigation bar or footer, or extra tabs to the repository view, you can put them in `extra_links.tmpl` (links added to the navbar), `extra_links_footer.tmpl` (links added to the left side of footer), and `extra_tabs.tmpl` inside your `custom/templates/custom/` directory. +If all you want is to add extra links to the top navigation bar or footer, or extra tabs to the repository view, you can put them in `extra_links.tmpl` (links added to the navbar), `extra_links_footer.tmpl` (links added to the left side of footer), and `extra_tabs.tmpl` inside your `$GITEA_CUSTOM/templates/custom/` directory. For instance, let's say you are in Germany and must add the famously legally-required "Impressum"/about page, listing who is responsible for the site's content: -just place it under your "custom/public/" directory (for instance `custom/public/impressum.html`) and put a link to it in either `custom/templates/custom/extra_links.tmpl` or `custom/templates/custom/extra_links_footer.tmpl`. +just place it under your "$GITEA_CUSTOM/public/" directory (for instance `$GITEA_CUSTOM/public/impressum.html`) and put a link to it in either `$GITEA_CUSTOM/templates/custom/extra_links.tmpl` or `$GITEA_CUSTOM/templates/custom/extra_links_footer.tmpl`. To match the current style, the link should have the class name "item", and you can use `{{AppSubUrl}}` to get the base URL: `Impressum` @@ -116,7 +117,7 @@ The exact HTML needed to match the style of other tabs is in the file ### Other additions to the page -Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful templates you can put in your `custom/templates/custom/` directory: +Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful templates you can put in your `$GITEA_CUSTOM/templates/custom/` directory: - `header.tmpl`, just before the end of the `` tag where you can add custom CSS files for instance. - `body_outer_pre.tmpl`, right after the start of ``. @@ -132,7 +133,7 @@ The data is encoded and sent to the PlantUML server which generates the picture. demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering, copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your -`custom/public` folder. Then add the following to `custom/footer.tmpl`: +`$GITEA_CUSTOM/public` folder. Then add the following to `custom/footer.tmpl`: ```html {{if .RequireHighlightJS}} @@ -201,15 +202,15 @@ You can display STL file directly in Gitea by adding: to the file `templates/custom/footer.tmpl` -You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `custom/public/` folder. +You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder. You should end-up with a folder structucture similar to: ``` -custom/templates +$GITEA_CUSTOM/templates -- custom `-- footer.tmpl -custom/public +$GITEA_CUSTOM/public -- Madeleine.js |-- LICENSE |-- README.md @@ -255,11 +256,11 @@ Then restart gitea and open a STL file on your gitea instance. ## Customizing Gitea mails -The `custom/templates/mail` folder allows changing the body of every mail of Gitea. +The `$GITEA_CUSTOM/templates/mail` folder allows changing the body of every mail of Gitea. Templates to override can be found in the [`templates/mail`](https://github.com/go-gitea/gitea/tree/master/templates/mail) directory of Gitea source. -Override by making a copy of the file under `custom/templates/mail` using a +Override by making a copy of the file under `$GITEA_CUSTOM/templates/mail` using a full path structure matching source. Any statement contained inside `{{` and `}}` are Gitea's template @@ -267,7 +268,7 @@ syntax and shouldn't be touched without fully understanding these components. ## Adding Analytics to Gitea -Google Analytics, Matomo (previously Piwik), and other analytics services can be added to Gitea. To add the tracking code, refer to the `Other additions to the page` section of this document, and add the JavaScript to the `custom/templates/custom/header.tmpl` file. +Google Analytics, Matomo (previously Piwik), and other analytics services can be added to Gitea. To add the tracking code, refer to the `Other additions to the page` section of this document, and add the JavaScript to the `$GITEA_CUSTOM/templates/custom/header.tmpl` file. ## Customizing gitignores, labels, licenses, locales, and readmes. @@ -277,21 +278,21 @@ Place custom files in corresponding sub-folder under `custom/options`. ### gitignores -To add custom .gitignore, add a file with existing [.gitignore rules](https://git-scm.com/docs/gitignore) in it to `custom/options/gitignore` +To add custom .gitignore, add a file with existing [.gitignore rules](https://git-scm.com/docs/gitignore) in it to `$GITEA_CUSTOM/options/gitignore` ### Labels -To add a custom label set, add a file that follows the [label format](https://github.com/go-gitea/gitea/blob/master/options/label/Default) to `custom/options/label` +To add a custom label set, add a file that follows the [label format](https://github.com/go-gitea/gitea/blob/master/options/label/Default) to `$GITEA_CUSTOM/options/label` `#hex-color label name ; label description` ### Licenses -To add a custom license, add a file with the license text to `custom/options/license` +To add a custom license, add a file with the license text to `$GITEA_CUSTOM/options/license` ### Locales -Locales are managed via our [crowdin](https://crowdin.com/project/gitea). -You can override a locale by placing an altered locale file in `custom/options/locale`. +Locales are managed via our [crowdin](https://crowdin.com/project/gitea). +You can override a locale by placing an altered locale file in `$GITEA_CUSTOM/options/locale`. Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/master/options/locale) source folder and these should be used as examples for your changes. To add a completely new locale, as well as placing the file in the above location, you will need to add the new lang and name to the `[i18n]` section in your `app.ini`. Keep in mind that Gitea will use those settings as **overrides**, so if you want to keep the other languages as well you will need to copy/paste the default values and add your own to them. @@ -306,9 +307,9 @@ Locales may change between versions, so keeping track of your customized locales ### Readmes -To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `custom/options/readme` +To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `$GITEA_CUSTOM/options/readme` -**NOTE:** readme templates support **variable expansion**. +**NOTE:** readme templates support **variable expansion**. currently there are `{Name}` (name of repository), `{Description}`, `{CloneURL.SSH}`, `{CloneURL.HTTPS}` and `{OwnerName}` ### Reactions @@ -324,7 +325,7 @@ A full list of supported emoji's is at [emoji list](https://gitea.com/gitea/gite ## Customizing the look of Gitea -As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options. +As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options. As of version 1.8.0 Gitea also has per-user themes. The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` (defaults to `gitea` and `arc-green`, light and dark respectively) ## Customizing fonts From 41e19b93a27318a1f8b88ee76837a30969ccb767 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Tue, 19 Jan 2021 18:08:21 -0700 Subject: [PATCH 0037/1137] Align dropdown right (#14406) --- templates/repo/issue/view_content/add_reaction.tmpl | 2 +- templates/repo/issue/view_content/context_menu.tmpl | 2 +- web_src/less/_base.less | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/repo/issue/view_content/add_reaction.tmpl b/templates/repo/issue/view_content/add_reaction.tmpl index 95778cc5b..c02f2db6f 100644 --- a/templates/repo/issue/view_content/add_reaction.tmpl +++ b/templates/repo/issue/view_content/add_reaction.tmpl @@ -1,5 +1,5 @@ {{if .ctx.IsSigned}} -