diff options
Diffstat (limited to 'routers/web/shared')
-rw-r--r-- | routers/web/shared/actions/runners.go | 21 | ||||
-rw-r--r-- | routers/web/shared/actions/variables.go | 5 | ||||
-rw-r--r-- | routers/web/shared/issue/issue_label.go | 21 | ||||
-rw-r--r-- | routers/web/shared/label/label.go | 26 | ||||
-rw-r--r-- | routers/web/shared/packages/packages.go | 10 | ||||
-rw-r--r-- | routers/web/shared/secrets/secrets.go | 4 | ||||
-rw-r--r-- | routers/web/shared/user/header.go | 92 | ||||
-rw-r--r-- | routers/web/shared/user/helper.go | 19 |
8 files changed, 107 insertions, 91 deletions
diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index 444bd960db..648f8046a4 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -57,9 +57,8 @@ func getRunnersCtx(ctx *context.Context) (*runnersCtx, error) { } if ctx.Data["PageIsOrgSettings"] == true { - err := shared_user.LoadHeaderCount(ctx) - if err != nil { - ctx.ServerError("LoadHeaderCount", err) + if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil { + ctx.ServerError("RenderUserOrgHeader", err) return nil, nil } return &runnersCtx{ @@ -109,10 +108,7 @@ func Runners(ctx *context.Context) { return } - page := ctx.FormInt("page") - if page <= 1 { - page = 1 - } + page := max(ctx.FormInt("page"), 1) opts := actions_model.FindRunnerOptions{ ListOptions: db.ListOptions{ @@ -180,10 +176,7 @@ func RunnersEdit(ctx *context.Context) { return } - page := ctx.FormInt("page") - if page <= 1 { - page = 1 - } + page := max(ctx.FormInt("page"), 1) runnerID := ctx.PathParamInt64("runnerid") ownerID := rCtx.OwnerID @@ -198,7 +191,7 @@ func RunnersEdit(ctx *context.Context) { ctx.ServerError("LoadAttributes", err) return } - if !runner.Editable(ownerID, repoID) { + if !runner.EditableInContext(ownerID, repoID) { err = errors.New("no permission to edit this runner") ctx.NotFound(err) return @@ -251,7 +244,7 @@ func RunnersEditPost(ctx *context.Context) { ctx.ServerError("RunnerDetailsEditPost.GetRunnerByID", err) return } - if !runner.Editable(ownerID, repoID) { + if !runner.EditableInContext(ownerID, repoID) { ctx.NotFound(util.NewPermissionDeniedErrorf("no permission to edit this runner")) return } @@ -305,7 +298,7 @@ func RunnerDeletePost(ctx *context.Context) { return } - if !runner.Editable(rCtx.OwnerID, rCtx.RepoID) { + if !runner.EditableInContext(rCtx.OwnerID, rCtx.RepoID) { ctx.NotFound(util.NewPermissionDeniedErrorf("no permission to delete this runner")) return } diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go index 9cc1676d7b..a43c2c2690 100644 --- a/routers/web/shared/actions/variables.go +++ b/routers/web/shared/actions/variables.go @@ -49,9 +49,8 @@ func getVariablesCtx(ctx *context.Context) (*variablesCtx, error) { } if ctx.Data["PageIsOrgSettings"] == true { - err := shared_user.LoadHeaderCount(ctx) - if err != nil { - ctx.ServerError("LoadHeaderCount", err) + if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil { + ctx.ServerError("RenderUserOrgHeader", err) return nil, nil } return &variablesCtx{ diff --git a/routers/web/shared/issue/issue_label.go b/routers/web/shared/issue/issue_label.go index eacea36b02..e2eeaaf0af 100644 --- a/routers/web/shared/issue/issue_label.go +++ b/routers/web/shared/issue/issue_label.go @@ -14,14 +14,18 @@ import ( ) // PrepareFilterIssueLabels reads the "labels" query parameter, sets `ctx.Data["Labels"]` and `ctx.Data["SelectLabels"]` -func PrepareFilterIssueLabels(ctx *context.Context, repoID int64, owner *user_model.User) (labelIDs []int64) { +func PrepareFilterIssueLabels(ctx *context.Context, repoID int64, owner *user_model.User) (ret struct { + AllLabels []*issues_model.Label + SelectedLabelIDs []int64 +}, +) { // 1,-2 means including label 1 and excluding label 2 // 0 means issues with no label // blank means labels will not be filtered for issues selectLabels := ctx.FormString("labels") if selectLabels != "" { var err error - labelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ",")) + ret.SelectedLabelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ",")) if err != nil { ctx.Flash.Error(ctx.Tr("invalid_data", selectLabels), true) } @@ -32,7 +36,7 @@ func PrepareFilterIssueLabels(ctx *context.Context, repoID int64, owner *user_mo repoLabels, err := issues_model.GetLabelsByRepoID(ctx, repoID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) - return nil + return ret } allLabels = append(allLabels, repoLabels...) } @@ -41,14 +45,14 @@ func PrepareFilterIssueLabels(ctx *context.Context, repoID int64, owner *user_mo orgLabels, err := issues_model.GetLabelsByOrgID(ctx, owner.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) - return nil + return ret } allLabels = append(allLabels, orgLabels...) } // Get the exclusive scope for every label ID - labelExclusiveScopes := make([]string, 0, len(labelIDs)) - for _, labelID := range labelIDs { + labelExclusiveScopes := make([]string, 0, len(ret.SelectedLabelIDs)) + for _, labelID := range ret.SelectedLabelIDs { foundExclusiveScope := false for _, label := range allLabels { if label.ID == labelID || label.ID == -labelID { @@ -63,9 +67,10 @@ func PrepareFilterIssueLabels(ctx *context.Context, repoID int64, owner *user_mo } for _, l := range allLabels { - l.LoadSelectedLabelsAfterClick(labelIDs, labelExclusiveScopes) + l.LoadSelectedLabelsAfterClick(ret.SelectedLabelIDs, labelExclusiveScopes) } ctx.Data["Labels"] = allLabels ctx.Data["SelectLabels"] = selectLabels - return labelIDs + ret.AllLabels = allLabels + return ret } diff --git a/routers/web/shared/label/label.go b/routers/web/shared/label/label.go new file mode 100644 index 0000000000..6968a318c4 --- /dev/null +++ b/routers/web/shared/label/label.go @@ -0,0 +1,26 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package label + +import ( + "code.gitea.io/gitea/modules/label" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/forms" +) + +func GetLabelEditForm(ctx *context.Context) *forms.CreateLabelForm { + form := web.GetForm(ctx).(*forms.CreateLabelForm) + if ctx.HasError() { + ctx.JSONError(ctx.Data["ErrorMsg"].(string)) + return nil + } + var err error + form.Color, err = label.NormalizeColor(form.Color) + if err != nil { + ctx.JSONError(ctx.Tr("repo.issues.label_color_invalid")) + return nil + } + return form +} diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go index 3d1795b42c..a18dedf89c 100644 --- a/routers/web/shared/packages/packages.go +++ b/routers/web/shared/packages/packages.go @@ -8,7 +8,6 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -159,12 +158,18 @@ func SetRulePreviewContext(ctx *context.Context, owner *user_model.User) { PackageID: p.ID, IsInternal: optional.Some(false), Sort: packages_model.SortCreatedDesc, - Paginator: db.NewAbsoluteListOptions(pcr.KeepCount, 200), }) if err != nil { ctx.ServerError("SearchVersions", err) return } + if pcr.KeepCount > 0 { + if pcr.KeepCount < len(pvs) { + pvs = pvs[pcr.KeepCount:] + } else { + pvs = nil + } + } for _, pv := range pvs { if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil { ctx.ServerError("ShouldBeSkipped", err) @@ -177,7 +182,6 @@ func SetRulePreviewContext(ctx *context.Context, owner *user_model.User) { if pcr.MatchFullName { toMatch = p.LowerName + "/" + pv.LowerVersion } - if pcr.KeepPatternMatcher != nil && pcr.KeepPatternMatcher.MatchString(toMatch) { continue } diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go index c8b80ebb26..29f4e9520d 100644 --- a/routers/web/shared/secrets/secrets.go +++ b/routers/web/shared/secrets/secrets.go @@ -32,11 +32,11 @@ func PerformSecretsPost(ctx *context.Context, ownerID, repoID int64, redirectURL s, _, err := secret_service.CreateOrUpdateSecret(ctx, ownerID, repoID, form.Name, util.ReserveLineBreakForTextarea(form.Data), form.Description) if err != nil { log.Error("CreateOrUpdateSecret failed: %v", err) - ctx.JSONError(ctx.Tr("secrets.creation.failed")) + ctx.JSONError(ctx.Tr("secrets.save_failed")) return } - ctx.Flash.Success(ctx.Tr("secrets.creation.success", s.Name)) + ctx.Flash.Success(ctx.Tr("secrets.save_success", s.Name)) ctx.JSONRedirect(redirectURL) } diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 62b146c7f3..2bd0abc4c0 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -24,19 +24,8 @@ import ( "code.gitea.io/gitea/services/context" ) -// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu) -// It is designed to be fast and safe to be called multiple times in one request -func prepareContextForCommonProfile(ctx *context.Context) { - ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - ctx.Data["EnableFeed"] = setting.Other.EnableFeed - ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink() -} - -// PrepareContextForProfileBigAvatar set the context for big avatar view on the profile page -func PrepareContextForProfileBigAvatar(ctx *context.Context) { - prepareContextForCommonProfile(ctx) - +// prepareContextForProfileBigAvatar set the context for big avatar view on the profile page +func prepareContextForProfileBigAvatar(ctx *context.Context) { ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate if setting.Service.UserLocationMapURL != "" { @@ -58,13 +47,12 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { ctx.Data["RenderedDescription"] = content } - showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) orgs, err := db.Find[organization.Organization](ctx, organization.FindOrgOptions{ - UserID: ctx.ContextUser.ID, - IncludePrivate: showPrivate, + UserID: ctx.ContextUser.ID, + IncludeVisibility: organization.DoerViewOtherVisibility(ctx.Doer, ctx.ContextUser), ListOptions: db.ListOptions{ Page: 1, - // query one more results (without a separate counting) to see whether we need to add the "show more orgs" link + // query one more result (without a separate counting) to see whether we need to add the "show more orgs" link PageSize: setting.UI.User.OrgPagingNum + 1, }, }) @@ -138,17 +126,45 @@ func FindOwnerProfileReadme(ctx *context.Context, doer *user_model.User, optProf return profileDbRepo, profileReadmeBlob } -func RenderUserHeader(ctx *context.Context) { - prepareContextForCommonProfile(ctx) - - _, profileReadmeBlob := FindOwnerProfileReadme(ctx, ctx.Doer) - ctx.Data["HasUserProfileReadme"] = profileReadmeBlob != nil +type PrepareOwnerHeaderResult struct { + ProfilePublicRepo *repo_model.Repository + ProfilePublicReadmeBlob *git.Blob + ProfilePrivateRepo *repo_model.Repository + ProfilePrivateReadmeBlob *git.Blob + HasOrgProfileReadme bool } -func LoadHeaderCount(ctx *context.Context) error { - prepareContextForCommonProfile(ctx) +const ( + RepoNameProfilePrivate = ".profile-private" + RepoNameProfile = ".profile" +) + +func RenderUserOrgHeader(ctx *context.Context) (result *PrepareOwnerHeaderResult, err error) { + ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.Data["EnableFeed"] = setting.Other.EnableFeed + ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink() + + if err := loadHeaderCount(ctx); err != nil { + return nil, err + } - repoCount, err := repo_model.CountRepository(ctx, &repo_model.SearchRepoOptions{ + result = &PrepareOwnerHeaderResult{} + if ctx.ContextUser.IsOrganization() { + result.ProfilePublicRepo, result.ProfilePublicReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer) + result.ProfilePrivateRepo, result.ProfilePrivateReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer, RepoNameProfilePrivate) + result.HasOrgProfileReadme = result.ProfilePublicReadmeBlob != nil || result.ProfilePrivateReadmeBlob != nil + ctx.Data["HasOrgProfileReadme"] = result.HasOrgProfileReadme // many pages need it to show the "overview" tab + } else { + _, profileReadmeBlob := FindOwnerProfileReadme(ctx, ctx.Doer) + ctx.Data["HasUserProfileReadme"] = profileReadmeBlob != nil + prepareContextForProfileBigAvatar(ctx) + } + return result, nil +} + +func loadHeaderCount(ctx *context.Context) error { + repoCount, err := repo_model.CountRepository(ctx, repo_model.SearchRepoOptions{ Actor: ctx.Doer, OwnerID: ctx.ContextUser.ID, Private: ctx.IsSigned, @@ -178,29 +194,3 @@ func LoadHeaderCount(ctx *context.Context) error { return nil } - -const ( - RepoNameProfilePrivate = ".profile-private" - RepoNameProfile = ".profile" -) - -type PrepareOrgHeaderResult struct { - ProfilePublicRepo *repo_model.Repository - ProfilePublicReadmeBlob *git.Blob - ProfilePrivateRepo *repo_model.Repository - ProfilePrivateReadmeBlob *git.Blob - HasOrgProfileReadme bool -} - -func PrepareOrgHeader(ctx *context.Context) (result *PrepareOrgHeaderResult, err error) { - if err = LoadHeaderCount(ctx); err != nil { - return nil, err - } - - result = &PrepareOrgHeaderResult{} - result.ProfilePublicRepo, result.ProfilePublicReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer) - result.ProfilePrivateRepo, result.ProfilePrivateReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer, RepoNameProfilePrivate) - result.HasOrgProfileReadme = result.ProfilePublicReadmeBlob != nil || result.ProfilePrivateReadmeBlob != nil - ctx.Data["HasOrgProfileReadme"] = result.HasOrgProfileReadme // many pages need it to show the "overview" tab - return result, nil -} diff --git a/routers/web/shared/user/helper.go b/routers/web/shared/user/helper.go index b82181a1df..3fc39fd3ab 100644 --- a/routers/web/shared/user/helper.go +++ b/routers/web/shared/user/helper.go @@ -8,9 +8,7 @@ import ( "slices" "strconv" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/optional" ) func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User { @@ -34,19 +32,20 @@ func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User { // So it's better to make it work like GitHub: users could input username directly. // Since it only converts the username to ID directly and is only used internally (to search issues), so no permission check is needed. // Return values: -// * nil: no filter -// * some(id): match the id, the id could be -1 to match the issues without assignee -// * some(NonExistingID): match no issue (due to the user doesn't exist) -func GetFilterUserIDByName(ctx context.Context, name string) optional.Option[int64] { +// * "": no filter +// * "{the-id}": match the id +// * "(none)": match no issue (due to the user doesn't exist) +func GetFilterUserIDByName(ctx context.Context, name string) string { if name == "" { - return optional.None[int64]() + return "" } u, err := user.GetUserByName(ctx, name) if err != nil { if id, err := strconv.ParseInt(name, 10, 64); err == nil { - return optional.Some(id) + return strconv.FormatInt(id, 10) } - return optional.Some(db.NonExistingID) + // The "(none)" is for internal usage only: when doer tries to search non-existing user, use "(none)" to return empty result. + return "(none)" } - return optional.Some(u.ID) + return strconv.FormatInt(u.ID, 10) } |