Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4343688
Fix package link setting can only list limited repositories
lunny Sep 1, 2025
18a1050
Remove unused file
lunny Sep 1, 2025
f623d68
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 5, 2025
4c6ef5f
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 7, 2025
7a7e4ad
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 8, 2025
538536d
fix
lunny Sep 9, 2025
0b34ff8
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 9, 2025
3f82970
Merge branch 'lunny/fix_package_link_search_repo' of github.com:lunny…
lunny Sep 9, 2025
d4645fd
improvements
lunny Sep 9, 2025
4146753
Add html escape for repository full name
lunny Sep 9, 2025
c0a2fd3
improvements
lunny Sep 10, 2025
b834153
fix
wxiaoguang Sep 10, 2025
7c62d08
improvements
lunny Sep 10, 2025
f7156c6
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 10, 2025
fdc0bcd
Merge branch 'lunny/fix_package_link_search_repo' of github.com:lunny…
lunny Sep 10, 2025
1f91aa7
Merge branch 'main' into lunny/fix_package_link_search_repo
lunny Sep 10, 2025
77f022d
Merge branch 'main' into lunny/fix_package_link_search_repo
GiteaBot Sep 10, 2025
0f9ce74
Merge branch 'main' into lunny/fix_package_link_search_repo
GiteaBot Sep 10, 2025
d81cb1e
improvement the package link description
lunny Sep 10, 2025
99603c6
Merge branch 'lunny/fix_package_link_search_repo' of github.com:lunny…
lunny Sep 10, 2025
b004ef5
Merge branch 'main' into lunny/fix_package_link_search_repo
GiteaBot Sep 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3729,11 +3729,14 @@ swift.install = Add the package in your <code>Package.swift</code> file:
swift.install2 = and run the following command:
vagrant.install = To add a Vagrant box, run the following command:
settings.link = Link this package to a repository
settings.link.description = If you link a package with a repository, the package is listed in the repository's package list.
settings.link.description = If you link a package with a repository, the package is listed in the repository's package list. Only repositories on the same owner will be listed. Empty will remove the link.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on the same owner.

No idea whether it is right English: "on".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

under the same owner would read better I think

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

settings.link.select = Select Repository
settings.link.button = Update Repository Link
settings.link.success = Repository link was successfully updated.
settings.link.error = Failed to update repository link.
settings.link.repo_not_found = Repository %s not found.
settings.unlink.error = Failed to remove repository link.
settings.unlink.success = Repository link was successfully removed.
settings.delete = Delete package
settings.delete.description = Deleting a package is permanent and cannot be undone.
settings.delete.notice = You are about to delete %s (%s). This operation is irreversible, are you sure?
Expand Down
68 changes: 39 additions & 29 deletions routers/web/user/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"net/http"
"net/url"
"strings"

"code.gitea.io/gitea/models/db"
org_model "code.gitea.io/gitea/models/organization"
Expand Down Expand Up @@ -431,14 +432,18 @@ func PackageSettings(ctx *context.Context) {
ctx.Data["Title"] = pd.Package.Name
ctx.Data["IsPackagesPage"] = true
ctx.Data["PackageDescriptor"] = pd

repos, _, _ := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
Actor: pd.Owner,
Private: true,
})
ctx.Data["Repos"] = repos
ctx.Data["OwnerID"] = pd.Owner.ID
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()

if pd.Package.RepoID > 0 {
repo, err := repo_model.GetRepositoryByID(ctx, pd.Package.RepoID)
if err != nil {
ctx.ServerError("GetRepositoryByID", err)
return
}
ctx.Data["LinkedRepoFullName"] = repo.FullName()
}

ctx.HTML(http.StatusOK, tplPackagesSettings)
}

Expand All @@ -449,37 +454,42 @@ func PackageSettingsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.PackageSettingForm)
switch form.Action {
case "link":
success := func() bool {
repoID := int64(0)
if form.RepoID != 0 {
repo, err := repo_model.GetRepositoryByID(ctx, form.RepoID)
if err != nil {
log.Error("Error getting repository: %v", err)
return false
}

if repo.OwnerID != pd.Owner.ID {
return false
}

repoID = repo.ID
if form.RepoFullName == "" { // remove the link
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, 0); err != nil {
ctx.Flash.Error(ctx.Tr("packages.settings.unlink.error"))
} else {
ctx.Flash.Success(ctx.Tr("packages.settings.unlink.success"))
}
ctx.JSONRedirect("")
return
}

if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repoID); err != nil {
log.Error("Error updating package: %v", err)
return false
owner, name, _ := strings.Cut(form.RepoFullName, "/")
repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, name)
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
ctx.Flash.Error(ctx.Tr("packages.settings.link.repo_not_found", form.RepoFullName))
ctx.JSONRedirect("")
} else {
ctx.ServerError("GetRepositoryByOwnerAndName", err)
}
return
}

return true
}()
if repo.OwnerID != pd.Owner.ID {
ctx.Flash.Error(ctx.Tr("packages.settings.link.repo_not_found", form.RepoFullName))
ctx.JSONRedirect("")
return
}

if success {
ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
} else {
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repo.ID); err != nil {
ctx.Flash.Error(ctx.Tr("packages.settings.link.error"))
ctx.JSONRedirect("")
return
}

ctx.Redirect(ctx.Link)
ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
ctx.JSONRedirect("")
return
case "delete":
err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
Expand Down
4 changes: 2 additions & 2 deletions services/forms/user_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) bi

// PackageSettingForm form for package settings
type PackageSettingForm struct {
Action string
RepoID int64 `form:"repo_id"`
Action string
RepoFullName string `form:"repo_full_name"`
}

// Validate validates the fields
Expand Down
24 changes: 5 additions & 19 deletions templates/package/settings.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,15 @@
</h4>
<div class="ui attached segment">
<p>{{ctx.Locale.Tr "packages.settings.link.description"}}</p>
<form class="ui form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form form-fetch-action ignore-dirty tw-flex-1 tw-flex" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="link">
<div class="field">
<div class="ui clearable selection dropdown">
{{$repoID := 0}}
{{if .PackageDescriptor.Repository}}
{{$repoID = .PackageDescriptor.Repository.ID}}
{{end}}
<input type="hidden" name="repo_id" value="{{$repoID}}">
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="default text">{{ctx.Locale.Tr "packages.settings.link.select"}}</div>
<div class="menu">
{{range .Repos}}
<div class="item" data-value="{{.ID}}">{{.Name}}</div>
{{end}}
</div>
<div id="search-repo-box" class="ui search" data-full-name="true" data-uid="{{.OwnerID}}">
<div class="ui input">
<input class="prompt" name="repo_full_name" value="{{.LinkedRepoFullName}}" placeholder="{{ctx.Locale.Tr "search.repo_kind"}}" autocomplete="off">
</div>
</div>
<div class="field">
<button class="ui primary button">{{ctx.Locale.Tr "packages.settings.link.button"}}</button>
</div>
<button class="ui primary button tw-ml-2">{{ctx.Locale.Tr "packages.settings.link.button"}}</button>
</form>
</div>
<h4 class="ui top attached error header">
Expand Down
31 changes: 31 additions & 0 deletions web_src/js/features/comp/SearchRepoBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {fomanticQuery} from '../../modules/fomantic/base.ts';

const {appSubUrl} = window.config;

export function initCompSearchRepoBox() {
// on the page "page-content organization teams"
const $searchRepoBox = fomanticQuery('#search-repo-box');
const showFullName = $searchRepoBox.data('full-name');
$searchRepoBox.search({
minCharacters: 2,
apiSettings: {
url: `${appSubUrl}/repo/search?q={query}&uid=${$searchRepoBox.data('uid')}`,
onResponse(response: any) {
const items = [];
for (const item of response.data) {
let title = item.repository.full_name.split('/')[1];
if (showFullName) {
title = item.repository.full_name;
}
items.push({
title,
description: item.repository.full_name,
});
}
return {results: items};
},
},
searchFields: ['full_name'],
showNoResults: false,
});
}
29 changes: 2 additions & 27 deletions web_src/js/features/org-team.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {queryElems, toggleElem} from '../utils/dom.ts';
import {fomanticQuery} from '../modules/fomantic/base.ts';

const {appSubUrl} = window.config;
import {initCompSearchRepoBox} from './comp/SearchRepoBox.ts';

function initOrgTeamSettings() {
// on the page "page-content organization new team"
Expand All @@ -14,31 +12,8 @@ function initOrgTeamSettings() {
}));
}

function initOrgTeamSearchRepoBox() {
// on the page "page-content organization teams"
const $searchRepoBox = fomanticQuery('#search-repo-box');
$searchRepoBox.search({
minCharacters: 2,
apiSettings: {
url: `${appSubUrl}/repo/search?q={query}&uid=${$searchRepoBox.data('uid')}`,
onResponse(response: any) {
const items = [];
for (const item of response.data) {
items.push({
title: item.repository.full_name.split('/')[1],
description: item.repository.full_name,
});
}
return {results: items};
},
},
searchFields: ['full_name'],
showNoResults: false,
});
}

export function initOrgTeam() {
if (!document.querySelector('.page-content.organization')) return;
initOrgTeamSettings();
initOrgTeamSearchRepoBox();
initCompSearchRepoBox();
}
5 changes: 5 additions & 0 deletions web_src/js/features/package-setting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {initCompSearchRepoBox} from './comp/SearchRepoBox.ts';

export function initPackageSettings() {
initCompSearchRepoBox();
}
3 changes: 3 additions & 0 deletions web_src/js/index-domready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {initGlobalButtonClickOnEnter, initGlobalButtons, initGlobalDeleteButton}
import {initGlobalComboMarkdownEditor, initGlobalEnterQuickSubmit, initGlobalFormDirtyLeaveConfirm} from './features/common-form.ts';
import {callInitFunctions} from './modules/init.ts';
import {initRepoViewFileTree} from './features/repo-view-file-tree.ts';
import {initPackageSettings} from './features/package-setting.ts';

const initStartTime = performance.now();
const initPerformanceTracer = callInitFunctions([
Expand Down Expand Up @@ -163,6 +164,8 @@ const initPerformanceTracer = callInitFunctions([

initOAuth2SettingsDisableCheckbox,

initPackageSettings,

initRepoFileView,
]);

Expand Down