Skip to content

Commit 89d7929

Browse files
lunnywxiaoguangGiteaBot
authored
Fix package link setting can only list limited repositories (go-gitea#35394)
Fix go-gitea#24801 <img width="1123" height="503" alt="image" src="https://github.com/user-attachments/assets/823f4214-e08a-4506-9018-057c50e7fc52" /> --------- Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: Giteabot <[email protected]>
1 parent 593a52c commit 89d7929

File tree

9 files changed

+99
-106
lines changed

9 files changed

+99
-106
lines changed

options/locale/locale_en-US.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3729,11 +3729,14 @@ swift.install = Add the package in your <code>Package.swift</code> file:
37293729
swift.install2 = and run the following command:
37303730
vagrant.install = To add a Vagrant box, run the following command:
37313731
settings.link = Link this package to a repository
3732-
settings.link.description = If you link a package with a repository, the package is listed in the repository's package list.
3732+
settings.link.description = If you link a package with a repository, the package will appear in the repository's package list. Only repositories under the same owner can be linked. Leaving the field empty will remove the link.
37333733
settings.link.select = Select Repository
37343734
settings.link.button = Update Repository Link
37353735
settings.link.success = Repository link was successfully updated.
37363736
settings.link.error = Failed to update repository link.
3737+
settings.link.repo_not_found = Repository %s not found.
3738+
settings.unlink.error = Failed to remove repository link.
3739+
settings.unlink.success = Repository link was successfully removed.
37373740
settings.delete = Delete package
37383741
settings.delete.description = Deleting a package is permanent and cannot be undone.
37393742
settings.delete.notice = You are about to delete %s (%s). This operation is irreversible, are you sure?

routers/web/user/package.go

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -431,74 +431,81 @@ func PackageSettings(ctx *context.Context) {
431431
ctx.Data["Title"] = pd.Package.Name
432432
ctx.Data["IsPackagesPage"] = true
433433
ctx.Data["PackageDescriptor"] = pd
434-
435-
repos, _, _ := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
436-
Actor: pd.Owner,
437-
Private: true,
438-
})
439-
ctx.Data["Repos"] = repos
440434
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
441435

436+
if pd.Package.RepoID > 0 {
437+
repo, err := repo_model.GetRepositoryByID(ctx, pd.Package.RepoID)
438+
if err != nil {
439+
ctx.ServerError("GetRepositoryByID", err)
440+
return
441+
}
442+
ctx.Data["LinkedRepoName"] = repo.Name
443+
}
444+
442445
ctx.HTML(http.StatusOK, tplPackagesSettings)
443446
}
444447

445448
// PackageSettingsPost updates the package settings
446449
func PackageSettingsPost(ctx *context.Context) {
447-
pd := ctx.Package.Descriptor
448-
449450
form := web.GetForm(ctx).(*forms.PackageSettingForm)
450451
switch form.Action {
451452
case "link":
452-
success := func() bool {
453-
repoID := int64(0)
454-
if form.RepoID != 0 {
455-
repo, err := repo_model.GetRepositoryByID(ctx, form.RepoID)
456-
if err != nil {
457-
log.Error("Error getting repository: %v", err)
458-
return false
459-
}
460-
461-
if repo.OwnerID != pd.Owner.ID {
462-
return false
463-
}
464-
465-
repoID = repo.ID
466-
}
453+
packageSettingsPostActionLink(ctx, form)
454+
case "delete":
455+
packageSettingsPostActionDelete(ctx)
456+
default:
457+
ctx.NotFound(nil)
458+
}
459+
}
467460

468-
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repoID); err != nil {
469-
log.Error("Error updating package: %v", err)
470-
return false
471-
}
461+
func packageSettingsPostActionLink(ctx *context.Context, form *forms.PackageSettingForm) {
462+
pd := ctx.Package.Descriptor
463+
if form.RepoName == "" { // remove the link
464+
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, 0); err != nil {
465+
ctx.JSONError(ctx.Tr("packages.settings.unlink.error"))
466+
return
467+
}
472468

473-
return true
474-
}()
469+
ctx.Flash.Success(ctx.Tr("packages.settings.unlink.success"))
470+
ctx.JSONRedirect("")
471+
return
472+
}
475473

476-
if success {
477-
ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
474+
repo, err := repo_model.GetRepositoryByName(ctx, pd.Owner.ID, form.RepoName)
475+
if err != nil {
476+
if repo_model.IsErrRepoNotExist(err) {
477+
ctx.JSONError(ctx.Tr("packages.settings.link.repo_not_found", form.RepoName))
478478
} else {
479-
ctx.Flash.Error(ctx.Tr("packages.settings.link.error"))
479+
ctx.ServerError("GetRepositoryByOwnerAndName", err)
480480
}
481+
return
482+
}
481483

482-
ctx.Redirect(ctx.Link)
484+
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repo.ID); err != nil {
485+
ctx.JSONError(ctx.Tr("packages.settings.link.error"))
483486
return
484-
case "delete":
485-
err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
486-
if err != nil {
487-
log.Error("Error deleting package: %v", err)
488-
ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
489-
} else {
490-
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
491-
}
487+
}
492488

493-
redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
494-
// redirect to the package if there are still versions available
495-
if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has {
496-
redirectURL = ctx.Package.Descriptor.PackageWebLink()
497-
}
489+
ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
490+
ctx.JSONRedirect("")
491+
}
498492

499-
ctx.Redirect(redirectURL)
500-
return
493+
func packageSettingsPostActionDelete(ctx *context.Context) {
494+
err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
495+
if err != nil {
496+
log.Error("Error deleting package: %v", err)
497+
ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
498+
} else {
499+
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
501500
}
501+
502+
redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
503+
// redirect to the package if there are still versions available
504+
if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has {
505+
redirectURL = ctx.Package.Descriptor.PackageWebLink()
506+
}
507+
508+
ctx.Redirect(redirectURL)
502509
}
503510

504511
// DownloadPackageFile serves the content of a package file

services/forms/user_form.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,8 @@ func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) bi
416416

417417
// PackageSettingForm form for package settings
418418
type PackageSettingForm struct {
419-
Action string
420-
RepoID int64 `form:"repo_id"`
419+
Action string
420+
RepoName string `form:"repo_name"`
421421
}
422422

423423
// Validate validates the fields

templates/org/team/repositories.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<div class="ui top attached segment tw-flex tw-flex-wrap tw-gap-2">
1313
<form class="ui form ignore-dirty tw-flex-1 tw-flex" action="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/add" method="post">
1414
{{.CsrfTokenHtml}}
15-
<div id="search-repo-box" data-uid="{{.Org.ID}}" class="ui search">
15+
<div data-global-init="initSearchRepoBox" data-uid="{{.Org.ID}}" class="ui search">
1616
<div class="ui input">
1717
<input class="prompt" name="repo_name" placeholder="{{ctx.Locale.Tr "search.repo_kind"}}" autocomplete="off" required>
1818
</div>

templates/package/settings.tmpl

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{{template "base/head" .}}
2-
<div role="main" aria-label="{{.Title}}" class="page-content repository settings options{{if .ContextUser.IsOrganization}} organization{{end}}">
2+
<div role="main" aria-label="{{.Title}}" class="page-content package settings options{{if .ContextUser.IsOrganization}} organization{{end}}">
33
{{if .ContextUser.IsOrganization}}
44
{{template "org/header" .}}
55
{{else}}
@@ -16,29 +16,15 @@
1616
</h4>
1717
<div class="ui attached segment">
1818
<p>{{ctx.Locale.Tr "packages.settings.link.description"}}</p>
19-
<form class="ui form" action="{{.Link}}" method="post">
20-
{{template "base/disable_form_autofill"}}
19+
<form class="ui form form-fetch-action ignore-dirty flex-text-block" action="{{.Link}}" method="post">
2120
{{.CsrfTokenHtml}}
2221
<input type="hidden" name="action" value="link">
23-
<div class="field">
24-
<div class="ui clearable selection dropdown">
25-
{{$repoID := 0}}
26-
{{if .PackageDescriptor.Repository}}
27-
{{$repoID = .PackageDescriptor.Repository.ID}}
28-
{{end}}
29-
<input type="hidden" name="repo_id" value="{{$repoID}}">
30-
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
31-
<div class="default text">{{ctx.Locale.Tr "packages.settings.link.select"}}</div>
32-
<div class="menu">
33-
{{range .Repos}}
34-
<div class="item" data-value="{{.ID}}">{{.Name}}</div>
35-
{{end}}
36-
</div>
22+
<div data-global-init="initSearchRepoBox" class="ui search" data-uid="{{.PackageDescriptor.Owner.ID}}">
23+
<div class="ui input">
24+
<input class="prompt" name="repo_name" value="{{.LinkedRepoName}}" placeholder="{{ctx.Locale.Tr "search.repo_kind"}}" autocomplete="off">
3725
</div>
3826
</div>
39-
<div class="field">
40-
<button class="ui primary button">{{ctx.Locale.Tr "packages.settings.link.button"}}</button>
41-
</div>
27+
<button class="ui primary button">{{ctx.Locale.Tr "packages.settings.link.button"}}</button>
4228
</form>
4329
</div>
4430
<h4 class="ui top attached error header">

web_src/js/features/common-page.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {fomanticQuery} from '../modules/fomantic/base.ts';
44
import {queryElems} from '../utils/dom.ts';
55
import {registerGlobalInitFunc, registerGlobalSelectorFunc} from '../modules/observer.ts';
66
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
7+
import {initCompSearchRepoBox} from './comp/SearchRepoBox.ts';
78

89
const {appUrl} = window.config;
910

@@ -77,12 +78,10 @@ export function initGlobalDropdown() {
7778
});
7879
}
7980

80-
export function initGlobalTabularMenu() {
81+
export function initGlobalComponent() {
8182
fomanticQuery('.ui.menu.tabular:not(.custom) .item').tab();
82-
}
83-
84-
export function initGlobalAvatarUploader() {
8583
registerGlobalInitFunc('initAvatarUploader', initAvatarUploaderWithCropper);
84+
registerGlobalInitFunc('initSearchRepoBox', initCompSearchRepoBox);
8685
}
8786

8887
// for performance considerations, it only uses performant syntax
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {fomanticQuery} from '../../modules/fomantic/base.ts';
2+
import {htmlEscape} from '../../utils/html.ts';
3+
4+
const {appSubUrl} = window.config;
5+
6+
export function initCompSearchRepoBox(el: HTMLElement) {
7+
const uid = el.getAttribute('data-uid');
8+
fomanticQuery(el).search({
9+
minCharacters: 2,
10+
apiSettings: {
11+
url: `${appSubUrl}/repo/search?q={query}&uid=${uid}`,
12+
onResponse(response: any) {
13+
const items = [];
14+
for (const item of response.data) {
15+
items.push({
16+
title: htmlEscape(item.repository.full_name.split('/')[1]),
17+
description: htmlEscape(item.repository.full_name),
18+
});
19+
}
20+
return {results: items};
21+
},
22+
},
23+
searchFields: ['full_name'],
24+
showNoResults: false,
25+
});
26+
}

web_src/js/features/org-team.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import {queryElems, toggleElem} from '../utils/dom.ts';
2-
import {fomanticQuery} from '../modules/fomantic/base.ts';
3-
4-
const {appSubUrl} = window.config;
52

63
function initOrgTeamSettings() {
74
// on the page "page-content organization new team"
@@ -14,31 +11,7 @@ function initOrgTeamSettings() {
1411
}));
1512
}
1613

17-
function initOrgTeamSearchRepoBox() {
18-
// on the page "page-content organization teams"
19-
const $searchRepoBox = fomanticQuery('#search-repo-box');
20-
$searchRepoBox.search({
21-
minCharacters: 2,
22-
apiSettings: {
23-
url: `${appSubUrl}/repo/search?q={query}&uid=${$searchRepoBox.data('uid')}`,
24-
onResponse(response: any) {
25-
const items = [];
26-
for (const item of response.data) {
27-
items.push({
28-
title: item.repository.full_name.split('/')[1],
29-
description: item.repository.full_name,
30-
});
31-
}
32-
return {results: items};
33-
},
34-
},
35-
searchFields: ['full_name'],
36-
showNoResults: false,
37-
});
38-
}
39-
4014
export function initOrgTeam() {
4115
if (!document.querySelector('.page-content.organization')) return;
4216
initOrgTeamSettings();
43-
initOrgTeamSearchRepoBox();
4417
}

web_src/js/index-domready.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import {initColorPickers} from './features/colorpicker.ts';
6161
import {initAdminSelfCheck} from './features/admin/selfcheck.ts';
6262
import {initOAuth2SettingsDisableCheckbox} from './features/oauth2-settings.ts';
6363
import {initGlobalFetchAction} from './features/common-fetch-action.ts';
64-
import {initFootLanguageMenu, initGlobalAvatarUploader, initGlobalDropdown, initGlobalInput, initGlobalTabularMenu, initHeadNavbarContentToggle} from './features/common-page.ts';
64+
import {initFootLanguageMenu, initGlobalComponent, initGlobalDropdown, initGlobalInput, initHeadNavbarContentToggle} from './features/common-page.ts';
6565
import {initGlobalButtonClickOnEnter, initGlobalButtons, initGlobalDeleteButton} from './features/common-button.ts';
6666
import {initGlobalComboMarkdownEditor, initGlobalEnterQuickSubmit, initGlobalFormDirtyLeaveConfirm} from './features/common-form.ts';
6767
import {callInitFunctions} from './modules/init.ts';
@@ -73,9 +73,8 @@ const initPerformanceTracer = callInitFunctions([
7373
initSubmitEventPolyfill,
7474
initGiteaFomantic,
7575

76-
initGlobalAvatarUploader,
76+
initGlobalComponent,
7777
initGlobalDropdown,
78-
initGlobalTabularMenu,
7978
initGlobalFetchAction,
8079
initGlobalTooltips,
8180
initGlobalButtonClickOnEnter,

0 commit comments

Comments
 (0)