Compare commits
6 commits
main
...
issue_2060
Author | SHA1 | Date | |
---|---|---|---|
Simon Vieille | 28f3f4ecc7 | ||
Simon Vieille | 3dceba98f8 | ||
Simon Vieille | 413a27d562 | ||
Simon Vieille | 86d371eb6f | ||
Simon Vieille | adb7da0cec | ||
Simon Vieille | e7c2d8258c |
|
@ -406,6 +406,8 @@ var migrations = []Migration{
|
|||
NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn),
|
||||
// v223 -> v224
|
||||
NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes),
|
||||
// v224 -> v225
|
||||
NewMigration("Add container repository property", addDescriptionAndReadmeColsForPackage),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
18
models/migrations/v224.go
Normal file
18
models/migrations/v224.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2022 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 migrations
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addDescriptionAndReadmeColsForPackage(x *xorm.Engine) error {
|
||||
type Package struct {
|
||||
Description string `xorm:"TEXT"`
|
||||
Readme string `xorm:"LONGBLOB"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(Package))
|
||||
}
|
|
@ -106,6 +106,8 @@ type Package struct {
|
|||
Name string `xorm:"NOT NULL"`
|
||||
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
SemverCompatible bool `xorm:"NOT NULL DEFAULT false"`
|
||||
Description string `xorm:"VARCHAR(255)"`
|
||||
Readme string `xorm:"LONGBLOB"`
|
||||
}
|
||||
|
||||
// TryInsertPackage inserts a package. If a package exists already, ErrDuplicatePackage is returned
|
||||
|
@ -143,6 +145,15 @@ func SetRepositoryLink(ctx context.Context, packageID, repoID int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// SetDescriptions sets descriptions
|
||||
func SetDescriptions(ctx context.Context, packageID int64, description string, readme string) error {
|
||||
_, err := db.GetEngine(ctx).ID(packageID).Update(&Package{
|
||||
Description: description,
|
||||
Readme: readme,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// UnlinkRepositoryFromAllPackages unlinks every package from the repository
|
||||
func UnlinkRepositoryFromAllPackages(ctx context.Context, repoID int64) error {
|
||||
_, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Cols("repo_id").Update(&Package{})
|
||||
|
|
|
@ -355,6 +355,27 @@ func PackageSettingsPost(ctx *context.Context) {
|
|||
ctx.Flash.Error(ctx.Tr("packages.settings.link.error"))
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Link)
|
||||
return
|
||||
case "update":
|
||||
success := func() bool {
|
||||
description := form.Description
|
||||
readme := form.Readme
|
||||
|
||||
if err := packages_model.SetDescriptions(ctx, pd.Package.ID, description, readme); err != nil {
|
||||
log.Error("Error updating package: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}()
|
||||
|
||||
if success {
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.descriptions.success"))
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("packages.settings.descriptions.error"))
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Link)
|
||||
return
|
||||
case "delete":
|
||||
|
|
|
@ -728,6 +728,7 @@ func RegisterRoutes(m *web.Route) {
|
|||
m.Group("/{type}/{name}", func() {
|
||||
m.Get("", user.RedirectToLastVersion)
|
||||
m.Get("/versions", user.ListPackageVersions)
|
||||
m.Post("/markdown", bindIgnErr(structs.MarkdownOption{}), misc.Markdown)
|
||||
m.Group("/{version}", func() {
|
||||
m.Get("", user.ViewPackageVersion)
|
||||
m.Get("/files/{fileid}", user.DownloadPackageFile)
|
||||
|
|
|
@ -434,8 +434,10 @@ 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
|
||||
RepoID int64 `form:"repo_id"`
|
||||
Description string `form:"description"`
|
||||
Readme string `form:"readme"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.Description}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.Description}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.MultiArch}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.container.multi_arch"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -11,4 +11,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
{{end}}
|
||||
|
|
|
@ -17,6 +17,8 @@ helm repo update</code></pre></div>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.Description}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.Description}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.Readme}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.ReleaseNotes}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
|
|
6
templates/package/content/readme.tmpl
Normal file
6
templates/package/content/readme.tmpl
Normal file
|
@ -0,0 +1,6 @@
|
|||
{{if .PackageDescriptor.Package.Readme}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.readme"}}</h4>
|
||||
<div class="ui attached segment">
|
||||
{{RenderMarkdownToHtml .PackageDescriptor.Package.Readme}}
|
||||
</div>
|
||||
{{end}}
|
|
@ -17,6 +17,9 @@ end</code></pre></div>
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "package/content/readme" .}}
|
||||
|
||||
{{if .PackageDescriptor.Metadata.Description}}
|
||||
<h4 class="ui top attached header">{{.locale.Tr "packages.about"}}</h4>
|
||||
<div class="ui attached segment">{{.PackageDescriptor.Metadata.Description}}</div>
|
||||
|
|
14
templates/package/readme_tab.tmpl
Normal file
14
templates/package/readme_tab.tmpl
Normal file
|
@ -0,0 +1,14 @@
|
|||
<div class="ui top tabular menu" data-write="write" data-preview="preview">
|
||||
<a class="active item" data-tab="write">{{.locale.Tr "write"}}</a>
|
||||
<a class="item" data-tab="preview" data-url="{{.PackageDescriptor.PackageWebLink}}/markdown" data-context="{{.PackageDescriptor.Owner.Name}}/{{.PackageDescriptor.Package.Name}}">{{.locale.Tr "preview"}}</a>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui bottom active tab" data-tab="write">
|
||||
<textarea id="content" class="edit_area js-quick-submit" name="readme" tabindex="4" data-id="-{{.PackageDescriptor.Package.ID}}" data-url="{{.PackageDescriptor.PackageWebLink}}/markdown" data-context="{{.PackageDescriptor.Owner.Name}}/{{.PackageDescriptor.Package.Name}}">
|
||||
{{- .PackageDescriptor.Package.Readme -}}
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="ui bottom tab markup" data-tab="preview">
|
||||
{{.locale.Tr "loading"}}
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,5 @@
|
|||
{{template "base/head" .}}
|
||||
<div class="page-content repository settings options">
|
||||
<div class="page-content repository package settings options">
|
||||
{{template "user/overview/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
|
@ -34,6 +34,28 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<h4 class="ui top attached header">
|
||||
{{.locale.Tr "packages.settings.descriptions"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui descriptions form" action="{{.Link}}" method="post">
|
||||
{{template "base/disable_form_autofill"}}
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="update">
|
||||
|
||||
<div class="field {{if .Err_Description}}error{{end}}">
|
||||
<label for="description">{{$.locale.Tr "packages.settings.description.description"}}</label>
|
||||
<textarea id="description" name="description" rows="2" maxlength="255">{{.PackageDescriptor.Package.Description}}</textarea>
|
||||
</div>
|
||||
|
||||
<label for="readme">{{$.locale.Tr "packages.settings.readme.description"}}</label>
|
||||
{{template "package/readme_tab" .}}
|
||||
|
||||
<div class="field">
|
||||
<button class="ui green button">{{.locale.Tr "packages.settings.descriptions.button"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<h4 class="ui top attached error header">
|
||||
{{.locale.Tr "repo.settings.danger_zone"}}
|
||||
</h4>
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
<span class="ui label">{{svg .Package.Type.SVGName 16}} {{.Package.Type.Name}}</span>
|
||||
</div>
|
||||
<div class="desc issue-item-bottom-row df ac fw my-1">
|
||||
{{if .Package.Description}}
|
||||
<p>{{- .Package.Description -}}</p>
|
||||
{{end}}
|
||||
|
||||
{{$timeStr := TimeSinceUnix .Version.CreatedUnix $.locale}}
|
||||
{{$hasRepositoryAccess := false}}
|
||||
{{if .Repository}}
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
<div class="sixteen wide column title">
|
||||
<div class="issue-title">
|
||||
<h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1>
|
||||
|
||||
<p class="description">
|
||||
{{if .PackageDescriptor.Package.Description}}
|
||||
{{- .PackageDescriptor.Package.Description -}}
|
||||
{{end}}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
{{$timeStr := TimeSinceUnix .PackageDescriptor.Version.CreatedUnix $.locale}}
|
||||
|
@ -18,6 +24,7 @@
|
|||
</div>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
|
||||
<div class="twelve wide column">
|
||||
{{template "package/content/composer" .}}
|
||||
{{template "package/content/conan" .}}
|
||||
|
|
31
web_src/js/features/package-editor.js
Normal file
31
web_src/js/features/package-editor.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import $ from 'jquery';
|
||||
|
||||
const {csrfToken} = window.config;
|
||||
|
||||
function initEditPreviewTab($form) {
|
||||
const $tabMenu = $form.find('.tabular.menu');
|
||||
$tabMenu.find('.item').tab();
|
||||
$tabMenu.find(`.item[data-tab="${$tabMenu.data('preview')}"]`).on('click', function () {
|
||||
const $this = $(this);
|
||||
const context = `/${$this.data('context')}`;
|
||||
const mode = $this.data('markdown-mode') || 'comment';
|
||||
|
||||
$.post($this.data('url'), {
|
||||
_csrf: csrfToken,
|
||||
mode,
|
||||
context,
|
||||
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(),
|
||||
}, (data) => {
|
||||
const $diffPreviewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('preview')}"]`);
|
||||
$diffPreviewPanel.html(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function initPackageEditor() {
|
||||
if ($('.package.settings .descriptions').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
initEditPreviewTab($('.package.settings .descriptions'));
|
||||
}
|
|
@ -77,6 +77,7 @@ import {initOrgTeamSearchRepoBox, initOrgTeamSettings} from './features/org-team
|
|||
import {initUserAuthWebAuthn, initUserAuthWebAuthnRegister} from './features/user-auth-webauthn.js';
|
||||
import {initRepoRelease, initRepoReleaseEditor} from './features/repo-release.js';
|
||||
import {initRepoEditor} from './features/repo-editor.js';
|
||||
import {initPackageEditor} from './features/package-editor.js';
|
||||
import {initCompSearchUserBox} from './features/comp/SearchUserBox.js';
|
||||
import {initInstall} from './features/install.js';
|
||||
import {initCompWebHookEditor} from './features/comp/WebHookEditor.js';
|
||||
|
@ -181,6 +182,8 @@ $(document).ready(() => {
|
|||
initRepoWikiForm();
|
||||
initRepository();
|
||||
|
||||
initPackageEditor();
|
||||
|
||||
initCommitStatuses();
|
||||
|
||||
initUserAuthLinkAccountView();
|
||||
|
|
Loading…
Reference in a new issue