mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-14 00:01:44 -04:00
Compare commits
9 Commits
1cb8d14bf7
...
b0f18726a3
Author | SHA1 | Date | |
---|---|---|---|
|
b0f18726a3 | ||
|
e460b6ef4d | ||
|
51ab495198 | ||
|
8fa54d0fda | ||
|
2152c4e98f | ||
|
d4a9b35c4b | ||
|
9057a008a1 | ||
|
fb1a2a13f0 | ||
|
e9288c2477 |
@ -28,7 +28,7 @@ linters:
|
|||||||
fast: false
|
fast: false
|
||||||
|
|
||||||
run:
|
run:
|
||||||
go: 1.20
|
go: "1.20"
|
||||||
timeout: 10m
|
timeout: 10m
|
||||||
skip-dirs:
|
skip-dirs:
|
||||||
- node_modules
|
- node_modules
|
||||||
|
@ -37,7 +37,9 @@ func (d *postgresSchemaDriver) Open(name string) (driver.Conn, error) {
|
|||||||
}
|
}
|
||||||
schemaValue, _ := driver.String.ConvertValue(setting.Database.Schema)
|
schemaValue, _ := driver.String.ConvertValue(setting.Database.Schema)
|
||||||
|
|
||||||
if execer, ok := conn.(driver.Execer); ok {
|
// golangci lint is incorrect here - there is no benefit to using driver.ExecerContext here
|
||||||
|
// and in any case pq does not implement it
|
||||||
|
if execer, ok := conn.(driver.Execer); ok { //nolint
|
||||||
_, err := execer.Exec(`SELECT set_config(
|
_, err := execer.Exec(`SELECT set_config(
|
||||||
'search_path',
|
'search_path',
|
||||||
$1 || ',' || current_setting('search_path'),
|
$1 || ',' || current_setting('search_path'),
|
||||||
@ -61,7 +63,8 @@ func (d *postgresSchemaDriver) Open(name string) (driver.Conn, error) {
|
|||||||
|
|
||||||
// driver.String.ConvertValue will never return err for string
|
// driver.String.ConvertValue will never return err for string
|
||||||
|
|
||||||
_, err = stmt.Exec([]driver.Value{schemaValue})
|
// golangci lint is incorrect here - there is no benefit to using stmt.ExecWithContext here
|
||||||
|
_, err = stmt.Exec([]driver.Value{schemaValue}) //nolint
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -455,6 +455,8 @@ var migrations = []Migration{
|
|||||||
NewMigration("Add scope for access_token", v1_19.AddScopeForAccessTokens),
|
NewMigration("Add scope for access_token", v1_19.AddScopeForAccessTokens),
|
||||||
// v240 -> v241
|
// v240 -> v241
|
||||||
NewMigration("Add actions tables", v1_19.AddActionsTables),
|
NewMigration("Add actions tables", v1_19.AddActionsTables),
|
||||||
|
// v241 -> v242
|
||||||
|
NewMigration("Add card_type column to project table", v1_19.AddCardTypeToProjectTable),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
17
models/migrations/v1_19/v241.go
Normal file
17
models/migrations/v1_19/v241.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1_19 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddCardTypeToProjectTable: add CardType column, setting existing rows to CardTypeTextOnly
|
||||||
|
func AddCardTypeToProjectTable(x *xorm.Engine) error {
|
||||||
|
type Project struct {
|
||||||
|
CardType int `xorm:"NOT NULL DEFAULT 0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.Sync(new(Project))
|
||||||
|
}
|
@ -19,6 +19,9 @@ type (
|
|||||||
// BoardType is used to represent a project board type
|
// BoardType is used to represent a project board type
|
||||||
BoardType uint8
|
BoardType uint8
|
||||||
|
|
||||||
|
// CardType is used to represent a project board card type
|
||||||
|
CardType uint8
|
||||||
|
|
||||||
// BoardList is a list of all project boards in a repository
|
// BoardList is a list of all project boards in a repository
|
||||||
BoardList []*Board
|
BoardList []*Board
|
||||||
)
|
)
|
||||||
@ -34,6 +37,14 @@ const (
|
|||||||
BoardTypeBugTriage
|
BoardTypeBugTriage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CardTypeTextOnly is a project board card type that is text only
|
||||||
|
CardTypeTextOnly CardType = iota
|
||||||
|
|
||||||
|
// CardTypeImagesAndText is a project board card type that has images and text
|
||||||
|
CardTypeImagesAndText
|
||||||
|
)
|
||||||
|
|
||||||
// BoardColorPattern is a regexp witch can validate BoardColor
|
// BoardColorPattern is a regexp witch can validate BoardColor
|
||||||
var BoardColorPattern = regexp.MustCompile("^#[0-9a-fA-F]{6}$")
|
var BoardColorPattern = regexp.MustCompile("^#[0-9a-fA-F]{6}$")
|
||||||
|
|
||||||
@ -85,6 +96,16 @@ func IsBoardTypeValid(p BoardType) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsCardTypeValid checks if the project board card type is valid
|
||||||
|
func IsCardTypeValid(p CardType) bool {
|
||||||
|
switch p {
|
||||||
|
case CardTypeTextOnly, CardTypeImagesAndText:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func createBoardsForProjectsType(ctx context.Context, project *Project) error {
|
func createBoardsForProjectsType(ctx context.Context, project *Project) error {
|
||||||
var items []string
|
var items []string
|
||||||
|
|
||||||
|
@ -19,12 +19,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// ProjectsConfig is used to identify the type of board that is being created
|
// BoardConfig is used to identify the type of board that is being created
|
||||||
ProjectsConfig struct {
|
BoardConfig struct {
|
||||||
BoardType BoardType
|
BoardType BoardType
|
||||||
Translation string
|
Translation string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CardConfig is used to identify the type of board card that is being used
|
||||||
|
CardConfig struct {
|
||||||
|
CardType CardType
|
||||||
|
Translation string
|
||||||
|
}
|
||||||
|
|
||||||
// Type is used to identify the type of project in question and ownership
|
// Type is used to identify the type of project in question and ownership
|
||||||
Type uint8
|
Type uint8
|
||||||
)
|
)
|
||||||
@ -91,6 +97,7 @@ type Project struct {
|
|||||||
CreatorID int64 `xorm:"NOT NULL"`
|
CreatorID int64 `xorm:"NOT NULL"`
|
||||||
IsClosed bool `xorm:"INDEX"`
|
IsClosed bool `xorm:"INDEX"`
|
||||||
BoardType BoardType
|
BoardType BoardType
|
||||||
|
CardType CardType
|
||||||
Type Type
|
Type Type
|
||||||
|
|
||||||
RenderedContent string `xorm:"-"`
|
RenderedContent string `xorm:"-"`
|
||||||
@ -145,15 +152,23 @@ func init() {
|
|||||||
db.RegisterModel(new(Project))
|
db.RegisterModel(new(Project))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProjectsConfig retrieves the types of configurations projects could have
|
// GetBoardConfig retrieves the types of configurations project boards could have
|
||||||
func GetProjectsConfig() []ProjectsConfig {
|
func GetBoardConfig() []BoardConfig {
|
||||||
return []ProjectsConfig{
|
return []BoardConfig{
|
||||||
{BoardTypeNone, "repo.projects.type.none"},
|
{BoardTypeNone, "repo.projects.type.none"},
|
||||||
{BoardTypeBasicKanban, "repo.projects.type.basic_kanban"},
|
{BoardTypeBasicKanban, "repo.projects.type.basic_kanban"},
|
||||||
{BoardTypeBugTriage, "repo.projects.type.bug_triage"},
|
{BoardTypeBugTriage, "repo.projects.type.bug_triage"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCardConfig retrieves the types of configurations project board cards could have
|
||||||
|
func GetCardConfig() []CardConfig {
|
||||||
|
return []CardConfig{
|
||||||
|
{CardTypeTextOnly, "repo.projects.card_type.text_only"},
|
||||||
|
{CardTypeImagesAndText, "repo.projects.card_type.images_and_text"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IsTypeValid checks if a project type is valid
|
// IsTypeValid checks if a project type is valid
|
||||||
func IsTypeValid(p Type) bool {
|
func IsTypeValid(p Type) bool {
|
||||||
switch p {
|
switch p {
|
||||||
@ -237,6 +252,10 @@ func NewProject(p *Project) error {
|
|||||||
p.BoardType = BoardTypeNone
|
p.BoardType = BoardTypeNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !IsCardTypeValid(p.CardType) {
|
||||||
|
p.CardType = CardTypeTextOnly
|
||||||
|
}
|
||||||
|
|
||||||
if !IsTypeValid(p.Type) {
|
if !IsTypeValid(p.Type) {
|
||||||
return util.NewInvalidArgumentErrorf("project type is not valid")
|
return util.NewInvalidArgumentErrorf("project type is not valid")
|
||||||
}
|
}
|
||||||
@ -280,9 +299,14 @@ func GetProjectByID(ctx context.Context, id int64) (*Project, error) {
|
|||||||
|
|
||||||
// UpdateProject updates project properties
|
// UpdateProject updates project properties
|
||||||
func UpdateProject(ctx context.Context, p *Project) error {
|
func UpdateProject(ctx context.Context, p *Project) error {
|
||||||
|
if !IsCardTypeValid(p.CardType) {
|
||||||
|
p.CardType = CardTypeTextOnly
|
||||||
|
}
|
||||||
|
|
||||||
_, err := db.GetEngine(ctx).ID(p.ID).Cols(
|
_, err := db.GetEngine(ctx).ID(p.ID).Cols(
|
||||||
"title",
|
"title",
|
||||||
"description",
|
"description",
|
||||||
|
"card_type",
|
||||||
).Update(p)
|
).Update(p)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ func TestProject(t *testing.T) {
|
|||||||
project := &Project{
|
project := &Project{
|
||||||
Type: TypeRepository,
|
Type: TypeRepository,
|
||||||
BoardType: BoardTypeBasicKanban,
|
BoardType: BoardTypeBasicKanban,
|
||||||
|
CardType: CardTypeTextOnly,
|
||||||
Title: "New Project",
|
Title: "New Project",
|
||||||
RepoID: 1,
|
RepoID: 1,
|
||||||
CreatedUnix: timeutil.TimeStampNow(),
|
CreatedUnix: timeutil.TimeStampNow(),
|
||||||
|
@ -132,6 +132,21 @@ func GetAttachmentsByIssueID(ctx context.Context, issueID int64) ([]*Attachment,
|
|||||||
return attachments, db.GetEngine(ctx).Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments)
|
return attachments, db.GetEngine(ctx).Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAttachmentsByIssueIDImagesLatest returns the latest image attachments of an issue.
|
||||||
|
func GetAttachmentsByIssueIDImagesLatest(ctx context.Context, issueID int64) ([]*Attachment, error) {
|
||||||
|
attachments := make([]*Attachment, 0, 5)
|
||||||
|
return attachments, db.GetEngine(ctx).Where(`issue_id = ? AND (name like '%.apng'
|
||||||
|
OR name like '%.avif'
|
||||||
|
OR name like '%.bmp'
|
||||||
|
OR name like '%.gif'
|
||||||
|
OR name like '%.jpg'
|
||||||
|
OR name like '%.jpeg'
|
||||||
|
OR name like '%.jxl'
|
||||||
|
OR name like '%.png'
|
||||||
|
OR name like '%.svg'
|
||||||
|
OR name like '%.webp')`, issueID).Desc("comment_id").Limit(5).Find(&attachments)
|
||||||
|
}
|
||||||
|
|
||||||
// GetAttachmentsByCommentID returns all attachments if comment by given ID.
|
// GetAttachmentsByCommentID returns all attachments if comment by given ID.
|
||||||
func GetAttachmentsByCommentID(ctx context.Context, commentID int64) ([]*Attachment, error) {
|
func GetAttachmentsByCommentID(ctx context.Context, commentID int64) ([]*Attachment, error) {
|
||||||
attachments := make([]*Attachment, 0, 10)
|
attachments := make([]*Attachment, 0, 10)
|
||||||
|
@ -274,7 +274,7 @@ func (repo *Repository) CommitLink(commitID string) (result string) {
|
|||||||
if commitID == "" || commitID == "0000000000000000000000000000000000000000" {
|
if commitID == "" || commitID == "0000000000000000000000000000000000000000" {
|
||||||
result = ""
|
result = ""
|
||||||
} else {
|
} else {
|
||||||
result = repo.HTMLURL() + "/commit/" + url.PathEscape(commitID)
|
result = repo.Link() + "/commit/" + url.PathEscape(commitID)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -743,9 +743,9 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
|
|||||||
|
|
||||||
if ctx.FormString("go-get") == "1" {
|
if ctx.FormString("go-get") == "1" {
|
||||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name)
|
ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name)
|
||||||
prefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
fullURLPrefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
||||||
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}"
|
||||||
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}"
|
||||||
}
|
}
|
||||||
return cancel
|
return cancel
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package lfs
|
package lfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -12,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url.
|
// DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url.
|
||||||
@ -95,7 +95,7 @@ func endpointFromLocalPath(path string) *url.URL {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
path = fmt.Sprintf("file://%s%s", slash, filepath.ToSlash(path))
|
path = "file://" + slash + util.PathEscapeSegments(filepath.ToSlash(path))
|
||||||
|
|
||||||
u, _ := url.Parse(path)
|
u, _ := url.Parse(path)
|
||||||
|
|
||||||
|
@ -1231,6 +1231,9 @@ projects.board.color = "Color"
|
|||||||
projects.open = Open
|
projects.open = Open
|
||||||
projects.close = Close
|
projects.close = Close
|
||||||
projects.board.assigned_to = Assigned to
|
projects.board.assigned_to = Assigned to
|
||||||
|
projects.card_type.desc = "Card Previews"
|
||||||
|
projects.card_type.images_and_text = "Images and Text"
|
||||||
|
projects.card_type.text_only = "Text Only"
|
||||||
|
|
||||||
issues.desc = Organize bug reports, tasks and milestones.
|
issues.desc = Organize bug reports, tasks and milestones.
|
||||||
issues.filter_assignees = Filter Assignee
|
issues.filter_assignees = Filter Assignee
|
||||||
|
@ -286,9 +286,18 @@ func CommonRoutes(ctx gocontext.Context) *web.Route {
|
|||||||
}, reqPackageAccess(perm.AccessModeWrite))
|
}, reqPackageAccess(perm.AccessModeWrite))
|
||||||
r.Get("/symbols/{filename}/{guid:[0-9a-fA-F]{32}[fF]{8}}/{filename2}", nuget.DownloadSymbolFile)
|
r.Get("/symbols/{filename}/{guid:[0-9a-fA-F]{32}[fF]{8}}/{filename2}", nuget.DownloadSymbolFile)
|
||||||
r.Get("/Packages(Id='{id:[^']+}',Version='{version:[^']+}')", nuget.RegistrationLeafV2)
|
r.Get("/Packages(Id='{id:[^']+}',Version='{version:[^']+}')", nuget.RegistrationLeafV2)
|
||||||
r.Get("/Packages()", nuget.SearchServiceV2)
|
r.Group("/Packages()", func() {
|
||||||
r.Get("/FindPackagesById()", nuget.EnumeratePackageVersionsV2)
|
r.Get("", nuget.SearchServiceV2)
|
||||||
r.Get("/Search()", nuget.SearchServiceV2)
|
r.Get("/$count", nuget.SearchServiceV2Count)
|
||||||
|
})
|
||||||
|
r.Group("/FindPackagesById()", func() {
|
||||||
|
r.Get("", nuget.EnumeratePackageVersionsV2)
|
||||||
|
r.Get("/$count", nuget.EnumeratePackageVersionsV2Count)
|
||||||
|
})
|
||||||
|
r.Group("/Search()", func() {
|
||||||
|
r.Get("", nuget.SearchServiceV2)
|
||||||
|
r.Get("/$count", nuget.SearchServiceV2Count)
|
||||||
|
})
|
||||||
}, reqPackageAccess(perm.AccessModeRead))
|
}, reqPackageAccess(perm.AccessModeRead))
|
||||||
})
|
})
|
||||||
r.Group("/npm", func() {
|
r.Group("/npm", func() {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
@ -94,8 +95,7 @@ func FeedCapabilityResource(ctx *context.Context) {
|
|||||||
|
|
||||||
var searchTermExtract = regexp.MustCompile(`'([^']+)'`)
|
var searchTermExtract = regexp.MustCompile(`'([^']+)'`)
|
||||||
|
|
||||||
// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
|
func getSearchTerm(ctx *context.Context) string {
|
||||||
func SearchServiceV2(ctx *context.Context) {
|
|
||||||
searchTerm := strings.Trim(ctx.FormTrim("searchTerm"), "'")
|
searchTerm := strings.Trim(ctx.FormTrim("searchTerm"), "'")
|
||||||
if searchTerm == "" {
|
if searchTerm == "" {
|
||||||
// $filter contains a query like:
|
// $filter contains a query like:
|
||||||
@ -106,7 +106,11 @@ func SearchServiceV2(ctx *context.Context) {
|
|||||||
searchTerm = strings.TrimSpace(match[1])
|
searchTerm = strings.TrimSpace(match[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return searchTerm
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
|
||||||
|
func SearchServiceV2(ctx *context.Context) {
|
||||||
skip, take := ctx.FormInt("skip"), ctx.FormInt("take")
|
skip, take := ctx.FormInt("skip"), ctx.FormInt("take")
|
||||||
if skip == 0 {
|
if skip == 0 {
|
||||||
skip = ctx.FormInt("$skip")
|
skip = ctx.FormInt("$skip")
|
||||||
@ -116,9 +120,11 @@ func SearchServiceV2(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
Type: packages_model.TypeNuGet,
|
Type: packages_model.TypeNuGet,
|
||||||
Name: packages_model.SearchValue{Value: searchTerm},
|
Name: packages_model.SearchValue{
|
||||||
|
Value: getSearchTerm(ctx),
|
||||||
|
},
|
||||||
IsInternal: util.OptionalBoolFalse,
|
IsInternal: util.OptionalBoolFalse,
|
||||||
Paginator: db.NewAbsoluteListOptions(
|
Paginator: db.NewAbsoluteListOptions(
|
||||||
skip,
|
skip,
|
||||||
@ -145,6 +151,24 @@ func SearchServiceV2(ctx *context.Context) {
|
|||||||
xmlResponse(ctx, http.StatusOK, resp)
|
xmlResponse(ctx, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351
|
||||||
|
func SearchServiceV2Count(ctx *context.Context) {
|
||||||
|
count, err := packages_model.CountVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
|
Type: packages_model.TypeNuGet,
|
||||||
|
Name: packages_model.SearchValue{
|
||||||
|
Value: getSearchTerm(ctx),
|
||||||
|
},
|
||||||
|
IsInternal: util.OptionalBoolFalse,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.PlainText(http.StatusOK, strconv.FormatInt(count, 10))
|
||||||
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-for-packages
|
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-for-packages
|
||||||
func SearchServiceV3(ctx *context.Context) {
|
func SearchServiceV3(ctx *context.Context) {
|
||||||
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
@ -288,6 +312,25 @@ func EnumeratePackageVersionsV2(ctx *context.Context) {
|
|||||||
xmlResponse(ctx, http.StatusOK, resp)
|
xmlResponse(ctx, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351
|
||||||
|
func EnumeratePackageVersionsV2Count(ctx *context.Context) {
|
||||||
|
count, err := packages_model.CountVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
|
Type: packages_model.TypeNuGet,
|
||||||
|
Name: packages_model.SearchValue{
|
||||||
|
ExactMatch: true,
|
||||||
|
Value: strings.Trim(ctx.FormTrim("id"), "'"),
|
||||||
|
},
|
||||||
|
IsInternal: util.OptionalBoolFalse,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.PlainText(http.StatusOK, strconv.FormatInt(count, 10))
|
||||||
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#enumerate-package-versions
|
// https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#enumerate-package-versions
|
||||||
func EnumeratePackageVersionsV3(ctx *context.Context) {
|
func EnumeratePackageVersionsV3(ctx *context.Context) {
|
||||||
packageName := ctx.Params("id")
|
packageName := ctx.Params("id")
|
||||||
|
@ -121,7 +121,7 @@ func canWriteUnit(ctx *context.Context) bool {
|
|||||||
// NewProject render creating a project page
|
// NewProject render creating a project page
|
||||||
func NewProject(ctx *context.Context) {
|
func NewProject(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||||
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
|
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
|
||||||
shared_user.RenderUserHeader(ctx)
|
shared_user.RenderUserHeader(ctx)
|
||||||
@ -137,7 +137,7 @@ func NewProjectPost(ctx *context.Context) {
|
|||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||||
ctx.Data["PageIsViewProjects"] = true
|
ctx.Data["PageIsViewProjects"] = true
|
||||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func List(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["workflows"] = workflows
|
ctx.Data["workflows"] = workflows
|
||||||
ctx.Data["RepoLink"] = ctx.Repo.Repository.HTMLURL()
|
ctx.Data["RepoLink"] = ctx.Repo.Repository.Link()
|
||||||
|
|
||||||
page := ctx.FormInt("page")
|
page := ctx.FormInt("page")
|
||||||
if page <= 0 {
|
if page <= 0 {
|
||||||
|
@ -100,7 +100,7 @@ func MustAllowUserComment(ctx *context.Context) {
|
|||||||
|
|
||||||
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
|
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -927,7 +927,7 @@ func NewIssueChooseTemplate(ctx *context.Context) {
|
|||||||
|
|
||||||
if len(issueTemplates) == 0 {
|
if len(issueTemplates) == 0 {
|
||||||
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters.
|
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters.
|
||||||
ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.HTMLURL(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
|
ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,11 +950,11 @@ func DeleteIssue(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if issue.IsPull {
|
if issue.IsPull {
|
||||||
ctx.Redirect(fmt.Sprintf("%s/pulls", ctx.Repo.Repository.HTMLURL()), http.StatusSeeOther)
|
ctx.Redirect(fmt.Sprintf("%s/pulls", ctx.Repo.Repository.Link()), http.StatusSeeOther)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(fmt.Sprintf("%s/issues", ctx.Repo.Repository.HTMLURL()), http.StatusSeeOther)
|
ctx.Redirect(fmt.Sprintf("%s/issues", ctx.Repo.Repository.Link()), http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRepoMetas check and returns repository's meta information
|
// ValidateRepoMetas check and returns repository's meta information
|
||||||
@ -1425,7 +1425,7 @@ func ViewIssue(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Add link to the issue of the already running stopwatch
|
// Add link to the issue of the already running stopwatch
|
||||||
ctx.Data["OtherStopwatchURL"] = otherIssue.HTMLURL()
|
ctx.Data["OtherStopwatchURL"] = otherIssue.Link()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Data["CanUseTimetracker"] = ctx.Repo.CanUseTimetracker(issue, ctx.Doer)
|
ctx.Data["CanUseTimetracker"] = ctx.Repo.CanUseTimetracker(issue, ctx.Doer)
|
||||||
@ -2658,7 +2658,7 @@ func NewComment(ctx *context.Context) {
|
|||||||
|
|
||||||
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
|
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2669,7 +2669,7 @@ func NewComment(ctx *context.Context) {
|
|||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
|
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ func AddDependency(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Redirect
|
// Redirect
|
||||||
defer ctx.Redirect(issue.HTMLURL())
|
defer ctx.Redirect(issue.Link())
|
||||||
|
|
||||||
// Dependency
|
// Dependency
|
||||||
dep, err := issues_model.GetIssueByID(ctx, depID)
|
dep, err := issues_model.GetIssueByID(ctx, depID)
|
||||||
@ -124,5 +124,5 @@ func RemoveDependency(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Redirect
|
// Redirect
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,13 @@ func LockIssue(ctx *context.Context) {
|
|||||||
|
|
||||||
if issue.IsLocked {
|
if issue.IsLocked {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.lock_duplicate"))
|
ctx.Flash.Error(ctx.Tr("repo.issues.lock_duplicate"))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !form.HasValidReason() {
|
if !form.HasValidReason() {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.lock.unknown_reason"))
|
ctx.Flash.Error(ctx.Tr("repo.issues.lock.unknown_reason"))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ func LockIssue(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlockIssue unlocks a previously locked issue.
|
// UnlockIssue unlocks a previously locked issue.
|
||||||
@ -52,7 +52,7 @@ func UnlockIssue(ctx *context.Context) {
|
|||||||
|
|
||||||
if !issue.IsLocked {
|
if !issue.IsLocked {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.unlock_error"))
|
ctx.Flash.Error(ctx.Tr("repo.issues.unlock_error"))
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,5 +64,5 @@ func UnlockIssue(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func IssueStopwatch(c *context.Context) {
|
|||||||
c.Flash.Success(c.Tr("repo.issues.tracker_auto_close"))
|
c.Flash.Success(c.Tr("repo.issues.tracker_auto_close"))
|
||||||
}
|
}
|
||||||
|
|
||||||
url := issue.HTMLURL()
|
url := issue.Link()
|
||||||
c.Redirect(url, http.StatusSeeOther)
|
c.Redirect(url, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ func CancelStopwatch(c *context.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
url := issue.HTMLURL()
|
url := issue.Link()
|
||||||
c.Redirect(url, http.StatusSeeOther)
|
c.Redirect(url, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ func AddTimeManually(c *context.Context) {
|
|||||||
c.NotFound("CanUseTimetracker", nil)
|
c.NotFound("CanUseTimetracker", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url := issue.HTMLURL()
|
url := issue.Link()
|
||||||
|
|
||||||
if c.HasError() {
|
if c.HasError() {
|
||||||
c.Flash.Error(c.GetErrMsg())
|
c.Flash.Error(c.GetErrMsg())
|
||||||
@ -83,5 +83,5 @@ func DeleteTime(c *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.Flash.Success(c.Tr("repo.issues.del_time_history", util.SecToTime(t.Time)))
|
c.Flash.Success(c.Tr("repo.issues.del_time_history", util.SecToTime(t.Time)))
|
||||||
c.Redirect(issue.HTMLURL())
|
c.Redirect(issue.Link())
|
||||||
}
|
}
|
||||||
|
@ -52,5 +52,5 @@ func IssueWatch(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(issue.HTMLURL())
|
ctx.Redirect(issue.Link())
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
|
attachment_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
@ -123,7 +124,8 @@ func Projects(ctx *context.Context) {
|
|||||||
// NewProject render creating a project page
|
// NewProject render creating a project page
|
||||||
func NewProject(ctx *context.Context) {
|
func NewProject(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||||
|
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||||
}
|
}
|
||||||
@ -135,7 +137,8 @@ func NewProjectPost(ctx *context.Context) {
|
|||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||||
|
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -146,6 +149,7 @@ func NewProjectPost(ctx *context.Context) {
|
|||||||
Description: form.Content,
|
Description: form.Content,
|
||||||
CreatorID: ctx.Doer.ID,
|
CreatorID: ctx.Doer.ID,
|
||||||
BoardType: form.BoardType,
|
BoardType: form.BoardType,
|
||||||
|
CardType: form.CardType,
|
||||||
Type: project_model.TypeRepository,
|
Type: project_model.TypeRepository,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
ctx.ServerError("NewProject", err)
|
ctx.ServerError("NewProject", err)
|
||||||
@ -212,6 +216,7 @@ func EditProject(ctx *context.Context) {
|
|||||||
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
||||||
ctx.Data["PageIsEditProjects"] = true
|
ctx.Data["PageIsEditProjects"] = true
|
||||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||||
|
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||||
|
|
||||||
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -229,6 +234,7 @@ func EditProject(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Data["title"] = p.Title
|
ctx.Data["title"] = p.Title
|
||||||
ctx.Data["content"] = p.Description
|
ctx.Data["content"] = p.Description
|
||||||
|
ctx.Data["card_type"] = p.CardType
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||||
}
|
}
|
||||||
@ -239,6 +245,7 @@ func EditProjectPost(ctx *context.Context) {
|
|||||||
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
||||||
ctx.Data["PageIsEditProjects"] = true
|
ctx.Data["PageIsEditProjects"] = true
|
||||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||||
|
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||||
@ -261,6 +268,7 @@ func EditProjectPost(ctx *context.Context) {
|
|||||||
|
|
||||||
p.Title = form.Title
|
p.Title = form.Title
|
||||||
p.Description = form.Content
|
p.Description = form.Content
|
||||||
|
p.CardType = form.CardType
|
||||||
if err = project_model.UpdateProject(ctx, p); err != nil {
|
if err = project_model.UpdateProject(ctx, p); err != nil {
|
||||||
ctx.ServerError("UpdateProjects", err)
|
ctx.ServerError("UpdateProjects", err)
|
||||||
return
|
return
|
||||||
@ -302,6 +310,18 @@ func ViewProject(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if project.CardType != project_model.CardTypeTextOnly {
|
||||||
|
issuesAttachmentMap := make(map[int64][]*attachment_model.Attachment)
|
||||||
|
for _, issuesList := range issuesMap {
|
||||||
|
for _, issue := range issuesList {
|
||||||
|
if issueAttachment, err := attachment_model.GetAttachmentsByIssueIDImagesLatest(ctx, issue.ID); err == nil {
|
||||||
|
issuesAttachmentMap[issue.ID] = issueAttachment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap
|
||||||
|
}
|
||||||
|
|
||||||
linkedPrsMap := make(map[int64][]*issues_model.Issue)
|
linkedPrsMap := make(map[int64][]*issues_model.Issue)
|
||||||
for _, issuesList := range issuesMap {
|
for _, issuesList := range issuesMap {
|
||||||
for _, issue := range issuesList {
|
for _, issue := range issuesList {
|
||||||
|
@ -98,7 +98,7 @@ func CreateCodeComment(ctx *context.Context) {
|
|||||||
renderConversation(ctx, comment)
|
renderConversation(ctx, comment)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Redirect(comment.HTMLURL())
|
ctx.Redirect(comment.Link())
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResolveConversation add or remove an Conversation resolved mark
|
// UpdateResolveConversation add or remove an Conversation resolved mark
|
||||||
|
@ -295,7 +295,7 @@ func LatestRelease(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(release.HTMLURL())
|
ctx.Redirect(release.Link())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRelease render creating or edit release page
|
// NewRelease render creating or edit release page
|
||||||
|
@ -344,7 +344,7 @@ func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
|
|||||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(ctx.Repo.Repository.HTMLURL())
|
ctx.Redirect(ctx.Repo.Repository.Link())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func Search(ctx *context.Context) {
|
|||||||
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
|
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["SourcePath"] = ctx.Repo.Repository.HTMLURL()
|
ctx.Data["SourcePath"] = ctx.Repo.Repository.Link()
|
||||||
ctx.Data["SearchResults"] = searchResults
|
ctx.Data["SearchResults"] = searchResults
|
||||||
ctx.Data["SearchResultLanguages"] = searchResultLanguages
|
ctx.Data["SearchResultLanguages"] = searchResultLanguages
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
|
|||||||
|
|
||||||
if fInfo.isLFSFile {
|
if fInfo.isLFSFile {
|
||||||
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
|
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
|
||||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.HTMLURL(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
|
ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.Link(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fInfo.isTextFile {
|
if !fInfo.isTextFile {
|
||||||
@ -738,7 +738,7 @@ func Home(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["EnableFeed"] = true
|
ctx.Data["EnableFeed"] = true
|
||||||
ctx.Data["FeedURL"] = ctx.Repo.Repository.HTMLURL()
|
ctx.Data["FeedURL"] = ctx.Repo.Repository.Link()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkHomeCodeViewable(ctx)
|
checkHomeCodeViewable(ctx)
|
||||||
|
@ -376,7 +376,7 @@ func PackageSettingsPost(ctx *context.Context) {
|
|||||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Redirect(ctx.Package.Owner.HTMLURL() + "/-/packages")
|
ctx.Redirect(ctx.Package.Owner.HomeLink() + "/-/packages")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func Profile(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// advertise feed via meta tag
|
// advertise feed via meta tag
|
||||||
ctx.Data["FeedURL"] = ctx.ContextUser.HTMLURL()
|
ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink()
|
||||||
|
|
||||||
// Show OpenID URIs
|
// Show OpenID URIs
|
||||||
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
|
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
|
||||||
|
@ -59,7 +59,7 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
|
|||||||
Creator: creator,
|
Creator: creator,
|
||||||
CommitStatus: &git_model.CommitStatus{
|
CommitStatus: &git_model.CommitStatus{
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
TargetURL: run.HTMLURL(),
|
TargetURL: run.Link(),
|
||||||
Description: "",
|
Description: "",
|
||||||
Context: ctxname,
|
Context: ctxname,
|
||||||
CreatorID: payload.Pusher.ID,
|
CreatorID: payload.Pusher.ID,
|
||||||
|
@ -512,6 +512,7 @@ type CreateProjectForm struct {
|
|||||||
Title string `binding:"Required;MaxSize(100)"`
|
Title string `binding:"Required;MaxSize(100)"`
|
||||||
Content string
|
Content string
|
||||||
BoardType project_model.BoardType
|
BoardType project_model.BoardType
|
||||||
|
CardType project_model.CardType
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserCreateProjectForm is a from for creating an individual or organization
|
// UserCreateProjectForm is a from for creating an individual or organization
|
||||||
@ -520,6 +521,7 @@ type UserCreateProjectForm struct {
|
|||||||
Title string `binding:"Required;MaxSize(100)"`
|
Title string `binding:"Required;MaxSize(100)"`
|
||||||
Content string
|
Content string
|
||||||
BoardType project_model.BoardType
|
BoardType project_model.BoardType
|
||||||
|
CardType project_model.CardType
|
||||||
UID int64 `binding:"Required"`
|
UID int64 `binding:"Required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContentType repo content type
|
// ContentType repo content type
|
||||||
@ -158,7 +159,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
|||||||
return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
|
return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", repo.APIURL(), treePath, origRef))
|
selfURL, err := url.Parse(repo.APIURL() + "/contents/" + util.PathEscapeSegments(treePath) + "?ref=" + url.QueryEscape(origRef))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -217,7 +218,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
|||||||
}
|
}
|
||||||
// Handle links
|
// Handle links
|
||||||
if entry.IsRegular() || entry.IsLink() {
|
if entry.IsRegular() || entry.IsLink() {
|
||||||
downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
downloadURL, err := url.Parse(repo.HTMLURL() + "/raw/" + url.PathEscape(string(refType)) + "/" + util.PathEscapeSegments(ref) + "/" + util.PathEscapeSegments(treePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
|||||||
contentsResponse.DownloadURL = &downloadURLString
|
contentsResponse.DownloadURL = &downloadURLString
|
||||||
}
|
}
|
||||||
if !entry.IsSubModule() {
|
if !entry.IsSubModule() {
|
||||||
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
htmlURL, err := url.Parse(repo.HTMLURL() + "/src/" + url.PathEscape(string(refType)) + "/" + util.PathEscapeSegments(ref) + "/" + util.PathEscapeSegments(treePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -233,7 +234,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
|||||||
contentsResponse.HTMLURL = &htmlURLString
|
contentsResponse.HTMLURL = &htmlURLString
|
||||||
contentsResponse.Links.HTMLURL = &htmlURLString
|
contentsResponse.Links.HTMLURL = &htmlURLString
|
||||||
|
|
||||||
gitURL, err := url.Parse(fmt.Sprintf("%s/git/blobs/%s", repo.APIURL(), entry.ID.String()))
|
gitURL, err := url.Parse(repo.APIURL() + "/git/blobs/" + url.PathEscape(entry.ID.String()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<input type="hidden" name="board_type" value="{{.type}}">
|
<input type="hidden" name="board_type" value="{{.type}}">
|
||||||
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
{{range $element := .ProjectTypes}}
|
{{range $element := .BoardTypes}}
|
||||||
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,9 +62,9 @@
|
|||||||
{{range .Milestones}}
|
{{range .Milestones}}
|
||||||
<li class="item">
|
<li class="item">
|
||||||
<div class="df ac sb">
|
<div class="df ac sb">
|
||||||
<h2 class="df ac m-0 fw">
|
<h3 class="df ac m-0 fw">
|
||||||
{{svg "octicon-milestone" 16 "mr-3"}}<a class="muted" href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a>
|
{{svg "octicon-milestone" 16 "mr-3"}}<a class="muted" href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a>
|
||||||
</h2>
|
</h3>
|
||||||
<div class="df ac">
|
<div class="df ac">
|
||||||
<span class="mr-3">{{.Completeness}}%</span>
|
<span class="mr-3">{{.Completeness}}%</span>
|
||||||
<progress value="{{.Completeness}}" max="100"></progress>
|
<progress value="{{.Completeness}}" max="100"></progress>
|
||||||
|
@ -34,17 +34,38 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if not .PageIsEditProjects}}
|
{{if not .PageIsEditProjects}}
|
||||||
<label>{{.locale.Tr "repo.projects.template.desc"}}</label>
|
<div class="field">
|
||||||
<div class="ui selection dropdown">
|
<label>{{.locale.Tr "repo.projects.template.desc"}}</label>
|
||||||
<input type="hidden" name="board_type" value="{{.type}}">
|
<div class="ui selection dropdown">
|
||||||
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
<input type="hidden" name="board_type" value="{{.type}}">
|
||||||
<div class="menu">
|
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
||||||
{{range $element := .ProjectTypes}}
|
<div class="menu">
|
||||||
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
{{range $element := .BoardTypes}}
|
||||||
{{end}}
|
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label>{{.locale.Tr "repo.projects.card_type.desc"}}</label>
|
||||||
|
<div class="ui selection dropdown">
|
||||||
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
|
{{range $element := .CardTypes}}
|
||||||
|
{{if or (eq $.card_type $element.CardType) (and (not $.card_type) (eq $element.CardType 2))}}
|
||||||
|
<input type="hidden" name="card_type" value="{{$element.CardType}}">
|
||||||
|
<div class="default text">{{$.locale.Tr $element.Translation}}</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
<div class="menu">
|
||||||
|
{{range $element := .CardTypes}}
|
||||||
|
<div class="item" data-id="{{$element.CardType}}" data-value="{{$element.CardType}}">{{$.locale.Tr $element.Translation}}</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
|
@ -179,6 +179,13 @@
|
|||||||
|
|
||||||
<!-- start issue card -->
|
<!-- start issue card -->
|
||||||
<div class="card board-card" data-issue="{{.ID}}">
|
<div class="card board-card" data-issue="{{.ID}}">
|
||||||
|
{{if eq $.Project.CardType 1}}{{/* Images and Text*/}}
|
||||||
|
<div class="card-attachment-images">
|
||||||
|
{{range (index $.issuesAttachmentMap .ID)}}
|
||||||
|
<img src="{{.DownloadURL}}" alt="{{.Name}}" />
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<div class="content p-0">
|
<div class="content p-0">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<span class="dif ac vm {{if .IsClosed}}red{{else}}green{{end}}">
|
<span class="dif ac vm {{if .IsClosed}}red{{else}}green{{end}}">
|
||||||
|
@ -81,10 +81,10 @@
|
|||||||
{{range .Milestones}}
|
{{range .Milestones}}
|
||||||
<li class="item">
|
<li class="item">
|
||||||
<div class="df ac sb">
|
<div class="df ac sb">
|
||||||
<h2 class="df ac m-0 fw">
|
<h3 class="df ac m-0 fw">
|
||||||
<span class="ui large label">{{.Repo.FullName}}</span>
|
<span class="ui large label">{{.Repo.FullName}}</span>
|
||||||
{{svg "octicon-milestone" 16 "mr-3"}}<a class="muted" href="{{.Repo.Link}}/milestone/{{.ID}}">{{.Name}}</a>
|
{{svg "octicon-milestone" 16 "mr-3"}}<a class="muted" href="{{.Repo.Link}}/milestone/{{.ID}}">{{.Name}}</a>
|
||||||
</h2>
|
</h3>
|
||||||
<div class="df ac">
|
<div class="df ac">
|
||||||
<span class="mr-3">{{.Completeness}}%</span>
|
<span class="mr-3">{{.Completeness}}%</span>
|
||||||
<progress value="{{.Completeness}}" max="100"></progress>
|
<progress value="{{.Completeness}}" max="100"></progress>
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<input type="hidden" name="board_type" value="{{.type}}">
|
<input type="hidden" name="board_type" value="{{.type}}">
|
||||||
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
{{range $element := .ProjectTypes}}
|
{{range $element := .BoardTypes}}
|
||||||
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -109,8 +110,6 @@ func TestPackageNuGet(t *testing.T) {
|
|||||||
url := fmt.Sprintf("/api/packages/%s/nuget", user.Name)
|
url := fmt.Sprintf("/api/packages/%s/nuget", user.Name)
|
||||||
|
|
||||||
t.Run("ServiceIndex", func(t *testing.T) {
|
t.Run("ServiceIndex", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
|
||||||
|
|
||||||
t.Run("v2", func(t *testing.T) {
|
t.Run("v2", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
@ -374,8 +373,6 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("SearchService", func(t *testing.T) {
|
t.Run("SearchService", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Query string
|
Query string
|
||||||
Skip int
|
Skip int
|
||||||
@ -391,8 +388,6 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Run("v2", func(t *testing.T) {
|
t.Run("v2", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
|
||||||
|
|
||||||
t.Run("Search()", func(t *testing.T) {
|
t.Run("Search()", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
@ -406,6 +401,12 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
|
|
||||||
assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
|
assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
|
||||||
assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
|
assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/Search()/$count?searchTerm='%s'&skip=%d&take=%d", url, c.Query, c.Skip, c.Take))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
resp = MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assert.Equal(t, strconv.FormatInt(c.ExpectedTotal, 10), resp.Body.String(), "case %d: unexpected total hits", i)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -413,7 +414,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
for i, c := range cases {
|
for i, c := range cases {
|
||||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take))
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages()?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take))
|
||||||
req = AddBasicAuthHeader(req, user.Name)
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
@ -422,6 +423,12 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
|
|
||||||
assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
|
assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
|
||||||
assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
|
assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/Packages()/$count?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
resp = MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assert.Equal(t, strconv.FormatInt(c.ExpectedTotal, 10), resp.Body.String(), "case %d: unexpected total hits", i)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -512,8 +519,6 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("RegistrationLeaf", func(t *testing.T) {
|
t.Run("RegistrationLeaf", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
|
||||||
|
|
||||||
t.Run("v2", func(t *testing.T) {
|
t.Run("v2", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
@ -549,8 +554,6 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("PackageService", func(t *testing.T) {
|
t.Run("PackageService", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
|
||||||
|
|
||||||
t.Run("v2", func(t *testing.T) {
|
t.Run("v2", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
@ -563,6 +566,12 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
|||||||
|
|
||||||
assert.Len(t, result.Entries, 1)
|
assert.Len(t, result.Entries, 1)
|
||||||
assert.Equal(t, packageVersion, result.Entries[0].Properties.Version)
|
assert.Equal(t, packageVersion, result.Entries[0].Properties.Version)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()/$count?id='%s'", url, packageName))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
resp = MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assert.Equal(t, "1", resp.Body.String())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("v3", func(t *testing.T) {
|
t.Run("v3", func(t *testing.T) {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
/>
|
/>
|
||||||
<a
|
<a
|
||||||
v-if="item.isFile"
|
v-if="item.isFile"
|
||||||
class="file ellipsis"
|
class="file ellipsis muted"
|
||||||
:href="item.isFile ? '#diff-' + item.file.NameHash : ''"
|
:href="item.isFile ? '#diff-' + item.file.NameHash : ''"
|
||||||
>{{ item.name }}</a>
|
>{{ item.name }}</a>
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
@ -63,7 +63,7 @@ export default {
|
|||||||
if (itemIsFile) {
|
if (itemIsFile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$set(this, 'collapsed', !this.collapsed);
|
this.collapsed = !this.collapsed;
|
||||||
},
|
},
|
||||||
getIconForDiffType(pType) {
|
getIconForDiffType(pType) {
|
||||||
const diffTypes = {
|
const diffTypes = {
|
||||||
@ -83,6 +83,7 @@ export default {
|
|||||||
span.svg-icon.status {
|
span.svg-icon.status {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.svg-icon.file {
|
span.svg-icon.file {
|
||||||
color: var(--color-secondary-dark-7);
|
color: var(--color-secondary-dark-7);
|
||||||
}
|
}
|
||||||
@ -122,6 +123,8 @@ span.svg-icon.octicon-diff-renamed {
|
|||||||
div.directory {
|
div.directory {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 18px 20px auto;
|
grid-template-columns: 18px 20px auto;
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.directory:hover {
|
div.directory:hover {
|
||||||
|
@ -1803,6 +1803,7 @@ footer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: remove in favor of .hidden helper */
|
||||||
.hide {
|
.hide {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
|
@ -1614,6 +1614,20 @@
|
|||||||
margin-right: .25rem;
|
margin-right: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Because the translations contain the <strong> we need to style with nth-of-type
|
||||||
|
|
||||||
|
.diff-detail-stats strong:nth-of-type(1) {
|
||||||
|
color: var(--color-yellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-detail-stats strong:nth-of-type(2) {
|
||||||
|
color: var(--color-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-detail-stats strong:nth-of-type(3) {
|
||||||
|
color: var(--color-red);
|
||||||
|
}
|
||||||
|
|
||||||
.diff-detail-stats {
|
.diff-detail-stats {
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
|
@ -72,6 +72,10 @@
|
|||||||
margin-right: auto !important;
|
margin-right: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.board-column .ui.cards > .card > .content {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
.board-card {
|
.board-card {
|
||||||
margin: 4px 2px !important;
|
margin: 4px 2px !important;
|
||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
@ -90,6 +94,25 @@
|
|||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.board-card .card-attachment-images {
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-card .card-attachment-images img {
|
||||||
|
display: inline-block;
|
||||||
|
max-height: 50px;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-card .card-attachment-images img:only-child {
|
||||||
|
max-height: 90px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.card-ghost {
|
.card-ghost {
|
||||||
border-style: dashed !important;
|
border-style: dashed !important;
|
||||||
background: none !important;
|
background: none !important;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
/* below class names match Tailwind CSS */
|
/* below class names match Tailwind CSS */
|
||||||
.pointer-events-none { pointer-events: none !important; }
|
.pointer-events-none { pointer-events: none !important; }
|
||||||
.relative { position: relative !important; }
|
.relative { position: relative !important; }
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
.mono {
|
.mono {
|
||||||
font-family: var(--fonts-monospace) !important;
|
font-family: var(--fonts-monospace) !important;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user