mirror of https://github.com/go-gitea/gitea.git
Merge branch 'main' into feature/remove-signin-tabs
This commit is contained in:
commit
5471834c2b
|
@ -318,7 +318,7 @@ rules:
|
|||
jquery/no-serialize: [2]
|
||||
jquery/no-show: [2]
|
||||
jquery/no-size: [2]
|
||||
jquery/no-sizzle: [0]
|
||||
jquery/no-sizzle: [2]
|
||||
jquery/no-slide: [0]
|
||||
jquery/no-submit: [0]
|
||||
jquery/no-text: [0]
|
||||
|
@ -470,7 +470,7 @@ rules:
|
|||
no-jquery/no-selector-prop: [2]
|
||||
no-jquery/no-serialize: [2]
|
||||
no-jquery/no-size: [2]
|
||||
no-jquery/no-sizzle: [0]
|
||||
no-jquery/no-sizzle: [2]
|
||||
no-jquery/no-slide: [2]
|
||||
no-jquery/no-sub: [2]
|
||||
no-jquery/no-support: [2]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
* text=auto eol=lf
|
||||
*.tmpl linguist-language=Handlebars
|
||||
*.pb.go linguist-generated
|
||||
/assets/*.json linguist-generated
|
||||
/public/assets/img/svg/*.svg linguist-generated
|
||||
/templates/swagger/v1_json.tmpl linguist-generated
|
||||
|
|
|
@ -86,6 +86,8 @@ linters-settings:
|
|||
desc: do not use the internal package, use AddXxx function instead
|
||||
- pkg: gopkg.in/ini.v1
|
||||
desc: do not use the ini package, use gitea's config system instead
|
||||
- pkg: gitea.com/go-chi/cache
|
||||
desc: do not use the go-chi cache package, use gitea's cache system
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
|
|
2
Makefile
2
Makefile
|
@ -295,7 +295,7 @@ clean:
|
|||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||
@GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
|
||||
@# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only
|
||||
@# whitespace before it
|
||||
|
|
|
@ -69,6 +69,7 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error)
|
|||
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))
|
||||
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`.*\bbindata\.go$`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`\.pb\.go$`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/gitea-repositories-meta`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/integration/migration-test`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`modules/git/tests`))
|
||||
|
@ -203,17 +204,6 @@ Example:
|
|||
`, "file-batch-exec")
|
||||
}
|
||||
|
||||
func getGoVersion() string {
|
||||
goModFile, err := os.ReadFile("go.mod")
|
||||
if err != nil {
|
||||
log.Fatalf(`Faild to read "go.mod": %v`, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
goModVersionRegex := regexp.MustCompile(`go \d+\.\d+`)
|
||||
goModVersionLine := goModVersionRegex.Find(goModFile)
|
||||
return string(goModVersionLine[3:])
|
||||
}
|
||||
|
||||
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
|
||||
fileFilter := mainOptions["file-filter"]
|
||||
if fileFilter == "" {
|
||||
|
@ -278,7 +268,8 @@ func main() {
|
|||
log.Print("the -d option is not supported by gitea-fmt")
|
||||
}
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("gofmt", append([]string{"-w", "-r", "interface{} -> any"}, substArgs...)))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra"}, substArgs...)))
|
||||
default:
|
||||
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ var microcmdUserChangePassword = &cli.Command{
|
|||
&cli.BoolFlag{
|
||||
Name: "must-change-password",
|
||||
Usage: "User must change password",
|
||||
Value: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -57,23 +58,18 @@ func runChangePassword(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var mustChangePassword optional.Option[bool]
|
||||
if c.IsSet("must-change-password") {
|
||||
mustChangePassword = optional.Some(c.Bool("must-change-password"))
|
||||
}
|
||||
|
||||
opts := &user_service.UpdateAuthOptions{
|
||||
Password: optional.Some(c.String("password")),
|
||||
MustChangePassword: mustChangePassword,
|
||||
MustChangePassword: optional.Some(c.Bool("must-change-password")),
|
||||
}
|
||||
if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, password.ErrMinLength):
|
||||
return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
|
||||
return fmt.Errorf("password is not long enough, needs to be at least %d characters", setting.MinPasswordLength)
|
||||
case errors.Is(err, password.ErrComplexity):
|
||||
return errors.New("Password does not meet complexity requirements")
|
||||
return errors.New("password does not meet complexity requirements")
|
||||
case errors.Is(err, password.ErrIsPwned):
|
||||
return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
|
||||
return errors.New("the password is in a list of stolen passwords previously exposed in public data breaches, please try again with a different password, to see more details: https://haveibeenpwned.com/Passwords")
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
pwd "code.gitea.io/gitea/modules/auth/password"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
|
@ -46,8 +47,9 @@ var microcmdUserCreate = &cli.Command{
|
|||
Usage: "Generate a random password for the user",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "must-change-password",
|
||||
Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
|
||||
Name: "must-change-password",
|
||||
Usage: "Set to false to prevent forcing the user to change their password after initial login",
|
||||
DisableDefaultText: true,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "random-password-length",
|
||||
|
@ -71,10 +73,10 @@ func runCreateUser(c *cli.Context) error {
|
|||
}
|
||||
|
||||
if c.IsSet("name") && c.IsSet("username") {
|
||||
return errors.New("Cannot set both --name and --username flags")
|
||||
return errors.New("cannot set both --name and --username flags")
|
||||
}
|
||||
if !c.IsSet("name") && !c.IsSet("username") {
|
||||
return errors.New("One of --name or --username flags must be set")
|
||||
return errors.New("one of --name or --username flags must be set")
|
||||
}
|
||||
|
||||
if c.IsSet("password") && c.IsSet("random-password") {
|
||||
|
@ -110,17 +112,21 @@ func runCreateUser(c *cli.Context) error {
|
|||
return errors.New("must set either password or random-password flag")
|
||||
}
|
||||
|
||||
// always default to true
|
||||
changePassword := true
|
||||
|
||||
// If this is the first user being created.
|
||||
// Take it as the admin and don't force a password update.
|
||||
if n := user_model.CountUsers(ctx, nil); n == 0 {
|
||||
changePassword = false
|
||||
}
|
||||
|
||||
isAdmin := c.Bool("admin")
|
||||
mustChangePassword := true // always default to true
|
||||
if c.IsSet("must-change-password") {
|
||||
changePassword = c.Bool("must-change-password")
|
||||
// if the flag is set, use the value provided by the user
|
||||
mustChangePassword = c.Bool("must-change-password")
|
||||
} else {
|
||||
// check whether there are users in the database
|
||||
hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("IsTableNotEmpty: %w", err)
|
||||
}
|
||||
if !hasUserRecord && isAdmin {
|
||||
// if this is the first admin being created, don't force to change password (keep the old behavior)
|
||||
mustChangePassword = false
|
||||
}
|
||||
}
|
||||
|
||||
restricted := optional.None[bool]()
|
||||
|
@ -136,8 +142,8 @@ func runCreateUser(c *cli.Context) error {
|
|||
Name: username,
|
||||
Email: c.String("email"),
|
||||
Passwd: password,
|
||||
IsAdmin: c.Bool("admin"),
|
||||
MustChangePassword: changePassword,
|
||||
IsAdmin: isAdmin,
|
||||
MustChangePassword: mustChangePassword,
|
||||
Visibility: visibility,
|
||||
}
|
||||
|
||||
|
|
|
@ -83,8 +83,7 @@ Admin operations:
|
|||
- `--email value`: Email. Required.
|
||||
- `--admin`: If provided, this makes the user an admin. Optional.
|
||||
- `--access-token`: If provided, an access token will be created for the user. Optional. (default: false).
|
||||
- `--must-change-password`: If provided, the created user will be required to choose a newer password after the
|
||||
initial login. Optional. (default: true).
|
||||
- `--must-change-password`: The created user will be required to set a new password after the initial login, default: true. It could be disabled by `--must-change-password=false`.
|
||||
- `--random-password`: If provided, a randomly generated password will be used as the password of the created
|
||||
user. The value of `--password` will be discarded. Optional.
|
||||
- `--random-password-length`: If provided, it will be used to configure the length of the randomly generated
|
||||
|
@ -95,7 +94,7 @@ Admin operations:
|
|||
- Options:
|
||||
- `--username value`, `-u value`: Username. Required.
|
||||
- `--password value`, `-p value`: New password. Required.
|
||||
- `--must-change-password`: If provided, the user is required to choose a new password after the login. Optional.
|
||||
- `--must-change-password`: The user is required to set a new password after the login, default: true. It could be disabled by `--must-change-password=false`.
|
||||
- Examples:
|
||||
- `gitea admin user change-password --username myname --password asecurepassword`
|
||||
- `must-change-password`:
|
||||
|
|
|
@ -137,6 +137,11 @@ func (app *OAuth2Application) TableName() string {
|
|||
|
||||
// ContainsRedirectURI checks if redirectURI is allowed for app
|
||||
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
|
||||
// OAuth2 requires the redirect URI to be an exact match, no dynamic parts are allowed.
|
||||
// https://stackoverflow.com/questions/55524480/should-dynamic-query-parameters-be-present-in-the-redirection-uri-for-an-oauth2
|
||||
// https://www.rfc-editor.org/rfc/rfc6819#section-5.2.3.3
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
||||
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-12#section-3.1
|
||||
contains := func(s string) bool {
|
||||
s = strings.TrimSuffix(strings.ToLower(s), "/")
|
||||
for _, u := range app.RedirectURIs {
|
||||
|
|
|
@ -284,8 +284,8 @@ func MaxBatchInsertSize(bean any) int {
|
|||
}
|
||||
|
||||
// IsTableNotEmpty returns true if table has at least one record
|
||||
func IsTableNotEmpty(tableName string) (bool, error) {
|
||||
return x.Table(tableName).Exist()
|
||||
func IsTableNotEmpty(beanOrTableName any) (bool, error) {
|
||||
return x.Table(beanOrTableName).Exist()
|
||||
}
|
||||
|
||||
// DeleteAllRecords will delete all the records of this table
|
||||
|
|
|
@ -15,10 +15,11 @@ import (
|
|||
|
||||
// CommitStatusSummary holds the latest commit Status of a single Commit
|
||||
type CommitStatusSummary struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
|
||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
|
||||
State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
|
||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
|
||||
State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
|
||||
TargetURL string `xorm:"TEXT"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -44,9 +45,10 @@ func GetLatestCommitStatusForRepoAndSHAs(ctx context.Context, repoSHAs []RepoSHA
|
|||
commitStatuses := make([]*CommitStatus, 0, len(repoSHAs))
|
||||
for _, summary := range summaries {
|
||||
commitStatuses = append(commitStatuses, &CommitStatus{
|
||||
RepoID: summary.RepoID,
|
||||
SHA: summary.SHA,
|
||||
State: summary.State,
|
||||
RepoID: summary.RepoID,
|
||||
SHA: summary.SHA,
|
||||
State: summary.State,
|
||||
TargetURL: summary.TargetURL,
|
||||
})
|
||||
}
|
||||
return commitStatuses, nil
|
||||
|
@ -61,22 +63,24 @@ func UpdateCommitStatusSummary(ctx context.Context, repoID int64, sha string) er
|
|||
// mysql will return 0 when update a record which state hasn't been changed which behaviour is different from other database,
|
||||
// so we need to use insert in on duplicate
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
_, err := db.GetEngine(ctx).Exec("INSERT INTO commit_status_summary (repo_id,sha,state) VALUES (?,?,?) ON DUPLICATE KEY UPDATE state=?",
|
||||
repoID, sha, state.State, state.State)
|
||||
_, err := db.GetEngine(ctx).Exec("INSERT INTO commit_status_summary (repo_id,sha,state,target_url) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE state=?",
|
||||
repoID, sha, state.State, state.TargetURL, state.State)
|
||||
return err
|
||||
}
|
||||
|
||||
if cnt, err := db.GetEngine(ctx).Where("repo_id=? AND sha=?", repoID, sha).
|
||||
Cols("state").
|
||||
Cols("state, target_url").
|
||||
Update(&CommitStatusSummary{
|
||||
State: state.State,
|
||||
State: state.State,
|
||||
TargetURL: state.TargetURL,
|
||||
}); err != nil {
|
||||
return err
|
||||
} else if cnt == 0 {
|
||||
_, err = db.GetEngine(ctx).Insert(&CommitStatusSummary{
|
||||
RepoID: repoID,
|
||||
SHA: sha,
|
||||
State: state.State,
|
||||
RepoID: repoID,
|
||||
SHA: sha,
|
||||
State: state.State,
|
||||
TargetURL: state.TargetURL,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -580,6 +580,8 @@ var migrations = []Migration{
|
|||
NewMigration("Add unique index for project issue table", v1_23.AddUniqueIndexForProjectIssue),
|
||||
// v295 -> v296
|
||||
NewMigration("Add commit status summary table", v1_23.AddCommitStatusSummary),
|
||||
// v296 -> v297
|
||||
NewMigration("Add missing field of commit status summary table", v1_23.AddCommitStatusSummary2),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddCommitStatusSummary2(x *xorm.Engine) error {
|
||||
type CommitStatusSummary struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
TargetURL string `xorm:"TEXT"`
|
||||
}
|
||||
// there is no migrations because if there is no data on this table, it will fall back to get data
|
||||
// from commit status
|
||||
return x.Sync(new(CommitStatusSummary))
|
||||
}
|
|
@ -4,149 +4,75 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
mc "gitea.com/go-chi/cache"
|
||||
|
||||
_ "gitea.com/go-chi/cache/memcache" // memcache plugin for cache
|
||||
)
|
||||
|
||||
var conn mc.Cache
|
||||
|
||||
func newCache(cacheConfig setting.Cache) (mc.Cache, error) {
|
||||
return mc.NewCacher(mc.Options{
|
||||
Adapter: cacheConfig.Adapter,
|
||||
AdapterConfig: cacheConfig.Conn,
|
||||
Interval: cacheConfig.Interval,
|
||||
})
|
||||
}
|
||||
var defaultCache StringCache
|
||||
|
||||
// Init start cache service
|
||||
func Init() error {
|
||||
var err error
|
||||
|
||||
if conn == nil {
|
||||
if conn, err = newCache(setting.CacheService.Cache); err != nil {
|
||||
if defaultCache == nil {
|
||||
c, err := NewStringCache(setting.CacheService.Cache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = conn.Ping(); err != nil {
|
||||
for i := 0; i < 10; i++ {
|
||||
if err = c.Ping(); err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defaultCache = c
|
||||
}
|
||||
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCache returns the currently configured cache
|
||||
func GetCache() mc.Cache {
|
||||
return conn
|
||||
func GetCache() StringCache {
|
||||
return defaultCache
|
||||
}
|
||||
|
||||
// GetString returns the key value from cache with callback when no key exists in cache
|
||||
func GetString(key string, getFunc func() (string, error)) (string, error) {
|
||||
if conn == nil || setting.CacheService.TTL == 0 {
|
||||
if defaultCache == nil || setting.CacheService.TTL == 0 {
|
||||
return getFunc()
|
||||
}
|
||||
|
||||
cached := conn.Get(key)
|
||||
|
||||
if cached == nil {
|
||||
cached, exist := defaultCache.Get(key)
|
||||
if !exist {
|
||||
value, err := getFunc()
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
}
|
||||
|
||||
if value, ok := cached.(string); ok {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if stringer, ok := cached.(fmt.Stringer); ok {
|
||||
return stringer.String(), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s", cached), nil
|
||||
}
|
||||
|
||||
// GetInt returns key value from cache with callback when no key exists in cache
|
||||
func GetInt(key string, getFunc func() (int, error)) (int, error) {
|
||||
if conn == nil || setting.CacheService.TTL == 0 {
|
||||
return getFunc()
|
||||
}
|
||||
|
||||
cached := conn.Get(key)
|
||||
|
||||
if cached == nil {
|
||||
value, err := getFunc()
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
|
||||
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
}
|
||||
|
||||
switch v := cached.(type) {
|
||||
case int:
|
||||
return v, nil
|
||||
case string:
|
||||
value, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return value, nil
|
||||
default:
|
||||
value, err := getFunc()
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
return value, defaultCache.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
}
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
// GetInt64 returns key value from cache with callback when no key exists in cache
|
||||
func GetInt64(key string, getFunc func() (int64, error)) (int64, error) {
|
||||
if conn == nil || setting.CacheService.TTL == 0 {
|
||||
return getFunc()
|
||||
s, err := GetString(key, func() (string, error) {
|
||||
v, err := getFunc()
|
||||
return strconv.FormatInt(v, 10), err
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
cached := conn.Get(key)
|
||||
|
||||
if cached == nil {
|
||||
value, err := getFunc()
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
|
||||
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
}
|
||||
|
||||
switch v := conn.Get(key).(type) {
|
||||
case int64:
|
||||
return v, nil
|
||||
case string:
|
||||
value, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return value, nil
|
||||
default:
|
||||
value, err := getFunc()
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
|
||||
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
|
||||
if s == "" {
|
||||
return 0, nil
|
||||
}
|
||||
return strconv.ParseInt(s, 10, 64)
|
||||
}
|
||||
|
||||
// Remove key from cache
|
||||
func Remove(key string) {
|
||||
if conn == nil {
|
||||
if defaultCache == nil {
|
||||
return
|
||||
}
|
||||
_ = conn.Delete(key)
|
||||
_ = defaultCache.Delete(key)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/nosql"
|
||||
|
||||
"gitea.com/go-chi/cache"
|
||||
"gitea.com/go-chi/cache" //nolint:depguard
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func createTestCache() {
|
||||
conn, _ = newCache(setting.Cache{
|
||||
defaultCache, _ = NewStringCache(setting.Cache{
|
||||
Adapter: "memory",
|
||||
TTL: time.Minute,
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ func TestNewContext(t *testing.T) {
|
|||
assert.NoError(t, Init())
|
||||
|
||||
setting.CacheService.Cache = setting.Cache{Adapter: "redis", Conn: "some random string"}
|
||||
con, err := newCache(setting.Cache{
|
||||
con, err := NewStringCache(setting.Cache{
|
||||
Adapter: "rand",
|
||||
Conn: "false conf",
|
||||
Interval: 100,
|
||||
|
@ -76,42 +76,6 @@ func TestGetString(t *testing.T) {
|
|||
Remove("key")
|
||||
}
|
||||
|
||||
func TestGetInt(t *testing.T) {
|
||||
createTestCache()
|
||||
|
||||
data, err := GetInt("key", func() (int, error) {
|
||||
return 0, fmt.Errorf("some error")
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, 0, data)
|
||||
|
||||
data, err = GetInt("key", func() (int, error) {
|
||||
return 0, nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, data)
|
||||
|
||||
data, err = GetInt("key", func() (int, error) {
|
||||
return 100, nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, data)
|
||||
Remove("key")
|
||||
|
||||
data, err = GetInt("key", func() (int, error) {
|
||||
return 100, nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 100, data)
|
||||
|
||||
data, err = GetInt("key", func() (int, error) {
|
||||
return 0, fmt.Errorf("some error")
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 100, data)
|
||||
Remove("key")
|
||||
}
|
||||
|
||||
func TestGetInt64(t *testing.T) {
|
||||
createTestCache()
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
|
||||
mc "gitea.com/go-chi/cache"
|
||||
mc "gitea.com/go-chi/cache" //nolint:depguard
|
||||
lru "github.com/hashicorp/golang-lru/v2"
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
chi_cache "gitea.com/go-chi/cache" //nolint:depguard
|
||||
)
|
||||
|
||||
type GetJSONError struct {
|
||||
err error
|
||||
cachedError string // Golang error can't be stored in cache, only the string message could be stored
|
||||
}
|
||||
|
||||
func (e *GetJSONError) ToError() error {
|
||||
if e.err != nil {
|
||||
return e.err
|
||||
}
|
||||
return errors.New("cached error: " + e.cachedError)
|
||||
}
|
||||
|
||||
type StringCache interface {
|
||||
Ping() error
|
||||
|
||||
Get(key string) (string, bool)
|
||||
Put(key, value string, ttl int64) error
|
||||
Delete(key string) error
|
||||
IsExist(key string) bool
|
||||
|
||||
PutJSON(key string, v any, ttl int64) error
|
||||
GetJSON(key string, ptr any) (exist bool, err *GetJSONError)
|
||||
|
||||
ChiCache() chi_cache.Cache
|
||||
}
|
||||
|
||||
type stringCache struct {
|
||||
chiCache chi_cache.Cache
|
||||
}
|
||||
|
||||
func NewStringCache(cacheConfig setting.Cache) (StringCache, error) {
|
||||
adapter := util.IfZero(cacheConfig.Adapter, "memory")
|
||||
interval := util.IfZero(cacheConfig.Interval, 60)
|
||||
cc, err := chi_cache.NewCacher(chi_cache.Options{
|
||||
Adapter: adapter,
|
||||
AdapterConfig: cacheConfig.Conn,
|
||||
Interval: interval,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &stringCache{chiCache: cc}, nil
|
||||
}
|
||||
|
||||
func (sc *stringCache) Ping() error {
|
||||
return sc.chiCache.Ping()
|
||||
}
|
||||
|
||||
func (sc *stringCache) Get(key string) (string, bool) {
|
||||
v := sc.chiCache.Get(key)
|
||||
if v == nil {
|
||||
return "", false
|
||||
}
|
||||
s, ok := v.(string)
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (sc *stringCache) Put(key, value string, ttl int64) error {
|
||||
return sc.chiCache.Put(key, value, ttl)
|
||||
}
|
||||
|
||||
func (sc *stringCache) Delete(key string) error {
|
||||
return sc.chiCache.Delete(key)
|
||||
}
|
||||
|
||||
func (sc *stringCache) IsExist(key string) bool {
|
||||
return sc.chiCache.IsExist(key)
|
||||
}
|
||||
|
||||
const cachedErrorPrefix = "<CACHED-ERROR>:"
|
||||
|
||||
func (sc *stringCache) PutJSON(key string, v any, ttl int64) error {
|
||||
var s string
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
s = cachedErrorPrefix + v.Error()
|
||||
default:
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s = util.UnsafeBytesToString(b)
|
||||
}
|
||||
return sc.chiCache.Put(key, s, ttl)
|
||||
}
|
||||
|
||||
func (sc *stringCache) GetJSON(key string, ptr any) (exist bool, getErr *GetJSONError) {
|
||||
s, ok := sc.Get(key)
|
||||
if !ok || s == "" {
|
||||
return false, nil
|
||||
}
|
||||
s, isCachedError := strings.CutPrefix(s, cachedErrorPrefix)
|
||||
if isCachedError {
|
||||
return true, &GetJSONError{cachedError: s}
|
||||
}
|
||||
if err := json.Unmarshal(util.UnsafeStringToBytes(s), ptr); err != nil {
|
||||
return false, &GetJSONError{err: err}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (sc *stringCache) ChiCache() chi_cache.Cache {
|
||||
return sc.chiCache
|
||||
}
|
|
@ -7,18 +7,11 @@ import (
|
|||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// Cache represents a caching interface
|
||||
type Cache interface {
|
||||
// Put puts value into cache with key and expire time.
|
||||
Put(key string, val any, timeout int64) error
|
||||
// Get gets cached value by given key.
|
||||
Get(key string) any
|
||||
}
|
||||
|
||||
func getCacheKey(repoPath, commitID, entryPath string) string {
|
||||
hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, commitID, entryPath)))
|
||||
return fmt.Sprintf("last_commit:%x", hashBytes)
|
||||
|
@ -30,11 +23,11 @@ type LastCommitCache struct {
|
|||
ttl func() int64
|
||||
repo *Repository
|
||||
commitCache map[string]*Commit
|
||||
cache Cache
|
||||
cache cache.StringCache
|
||||
}
|
||||
|
||||
// NewLastCommitCache creates a new last commit cache for repo
|
||||
func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache Cache) *LastCommitCache {
|
||||
func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache cache.StringCache) *LastCommitCache {
|
||||
if cache == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -65,7 +58,7 @@ func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath)).(string)
|
||||
commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath))
|
||||
if !ok || commitID == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func (o *Option[T]) UnmarshalYAML(value *yaml.Node) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o Option[T]) MarshalYAML() (interface{}, error) {
|
||||
func (o Option[T]) MarshalYAML() (any, error) {
|
||||
if !o.Has() {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ package session
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
|
||||
"gitea.com/go-chi/session"
|
||||
)
|
||||
|
||||
|
@ -18,6 +21,10 @@ type Store interface {
|
|||
|
||||
// RegenerateSession regenerates the underlying session and returns the new store
|
||||
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
|
||||
// Ensure that a cookie with a trailing slash does not take precedence over
|
||||
// the cookie written by the middleware.
|
||||
middleware.DeleteLegacySiteCookie(resp, setting.SessionConfig.CookieName)
|
||||
|
||||
s, err := session.RegenerateSession(resp, req)
|
||||
return s, err
|
||||
}
|
||||
|
|
|
@ -142,35 +142,39 @@ type remoteAddress struct {
|
|||
Password string
|
||||
}
|
||||
|
||||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string, ignoreOriginalURL bool) remoteAddress {
|
||||
a := remoteAddress{}
|
||||
|
||||
remoteURL := m.OriginalURL
|
||||
if ignoreOriginalURL || remoteURL == "" {
|
||||
var err error
|
||||
remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
|
||||
if err != nil {
|
||||
log.Error("GetRemoteURL %v", err)
|
||||
return a
|
||||
}
|
||||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
|
||||
ret := remoteAddress{}
|
||||
remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
|
||||
if err != nil {
|
||||
log.Error("GetRemoteURL %v", err)
|
||||
return ret
|
||||
}
|
||||
|
||||
u, err := giturl.Parse(remoteURL)
|
||||
if err != nil {
|
||||
log.Error("giturl.Parse %v", err)
|
||||
return a
|
||||
return ret
|
||||
}
|
||||
|
||||
if u.Scheme != "ssh" && u.Scheme != "file" {
|
||||
if u.User != nil {
|
||||
a.Username = u.User.Username()
|
||||
a.Password, _ = u.User.Password()
|
||||
ret.Username = u.User.Username()
|
||||
ret.Password, _ = u.User.Password()
|
||||
}
|
||||
u.User = nil
|
||||
}
|
||||
a.Address = u.String()
|
||||
|
||||
return a
|
||||
// The URL stored in the git repo could contain authentication,
|
||||
// erase it, or it will be shown in the UI.
|
||||
u.User = nil
|
||||
ret.Address = u.String()
|
||||
// Why not use m.OriginalURL to set ret.Address?
|
||||
// It should be OK to use it, since m.OriginalURL should be the same as the authentication-erased URL from the Git repository.
|
||||
// However, the old code has already stored authentication in m.OriginalURL when updating mirror settings.
|
||||
// That means we need to use "giturl.Parse" for m.OriginalURL again to ensure authentication is erased.
|
||||
// Instead of doing this, why not directly use the authentication-erased URL from the Git repository?
|
||||
// It should be the same as long as there are no bugs.
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func FilenameIsImage(filename string) bool {
|
||||
|
|
|
@ -216,15 +216,16 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n
|
|||
return output
|
||||
}
|
||||
|
||||
func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string) template.HTML {
|
||||
func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string, issue *issues_model.Issue) template.HTML {
|
||||
isPullRequest := issue != nil && issue.IsPull
|
||||
baseLink := fmt.Sprintf("%s/%s", repoLink, util.Iif(isPullRequest, "pulls", "issues"))
|
||||
htmlCode := `<span class="labels-list">`
|
||||
for _, label := range labels {
|
||||
// Protect against nil value in labels - shouldn't happen but would cause a panic if so
|
||||
if label == nil {
|
||||
continue
|
||||
}
|
||||
htmlCode += fmt.Sprintf("<a href='%s/issues?labels=%d'>%s</a> ",
|
||||
repoLink, label.ID, RenderLabel(ctx, locale, label))
|
||||
htmlCode += fmt.Sprintf(`<a href="%s?labels=%d">%s</a>`, baseLink, label.ID, RenderLabel(ctx, locale, label))
|
||||
}
|
||||
htmlCode += "</span>"
|
||||
return template.HTML(htmlCode)
|
||||
|
|
|
@ -7,17 +7,21 @@ import (
|
|||
"context"
|
||||
"html/template"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const testInput = ` space @mention-user
|
||||
func testInput() string {
|
||||
s := ` space @mention-user<SPACE><SPACE>
|
||||
/just/a/path.bin
|
||||
https://example.com/file.bin
|
||||
[local link](file.bin)
|
||||
|
@ -36,8 +40,10 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
mail@domain.com
|
||||
@mention-user test
|
||||
#123
|
||||
space
|
||||
space<SPACE><SPACE>
|
||||
`
|
||||
return strings.ReplaceAll(s, "<SPACE>", " ")
|
||||
}
|
||||
|
||||
var testMetas = map[string]string{
|
||||
"user": "user13",
|
||||
|
@ -121,23 +127,23 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
|
||||
space`
|
||||
|
||||
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput(), testMetas))
|
||||
}
|
||||
|
||||
func TestRenderCommitMessage(t *testing.T) {
|
||||
expected := `space <a href="/mention-user" class="mention">@mention-user</a> `
|
||||
|
||||
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput(), testMetas))
|
||||
}
|
||||
|
||||
func TestRenderCommitMessageLinkSubject(t *testing.T) {
|
||||
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" class="mention">@mention-user</a>`
|
||||
|
||||
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput(), "https://example.com/link", testMetas))
|
||||
}
|
||||
|
||||
func TestRenderIssueTitle(t *testing.T) {
|
||||
expected := ` space @mention-user
|
||||
expected := ` space @mention-user<SPACE><SPACE>
|
||||
/just/a/path.bin
|
||||
https://example.com/file.bin
|
||||
[local link](file.bin)
|
||||
|
@ -156,9 +162,10 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
mail@domain.com
|
||||
@mention-user test
|
||||
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
|
||||
space
|
||||
space<SPACE><SPACE>
|
||||
`
|
||||
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
|
||||
expected = strings.ReplaceAll(expected, "<SPACE>", " ")
|
||||
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput(), testMetas))
|
||||
}
|
||||
|
||||
func TestRenderMarkdownToHtml(t *testing.T) {
|
||||
|
@ -183,5 +190,20 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
#123
|
||||
space</p>
|
||||
`
|
||||
assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput))
|
||||
assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput()))
|
||||
}
|
||||
|
||||
func TestRenderLabels(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
locale := &translation.MockLocale{}
|
||||
|
||||
label := &issues.Label{ID: 123, Name: "label-name", Color: "label-color"}
|
||||
issue := &issues.Issue{}
|
||||
expected := `/owner/repo/issues?labels=123`
|
||||
assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
|
||||
|
||||
label = &issues.Label{ID: 123, Name: "label-name", Color: "label-color"}
|
||||
issue = &issues.Issue{IsPull: true}
|
||||
expected = `/owner/repo/pulls?labels=123`
|
||||
assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
|
||||
}
|
||||
|
|
|
@ -45,10 +45,32 @@ func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
|
|||
SameSite: setting.SessionConfig.SameSite,
|
||||
}
|
||||
resp.Header().Add("Set-Cookie", cookie.String())
|
||||
if maxAge < 0 {
|
||||
// There was a bug in "setting.SessionConfig.CookiePath" code, the old default value of it was empty "".
|
||||
// So we have to delete the cookie on path="" again, because some old code leaves cookies on path="".
|
||||
cookie.Path = strings.TrimSuffix(setting.SessionConfig.CookiePath, "/")
|
||||
resp.Header().Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
// Previous versions would use a cookie path with a trailing /.
|
||||
// These are more specific than cookies without a trailing /, so
|
||||
// we need to delete these if they exist.
|
||||
DeleteLegacySiteCookie(resp, name)
|
||||
}
|
||||
|
||||
// DeleteLegacySiteCookie deletes the cookie with the given name at the cookie
|
||||
// path with a trailing /, which would unintentionally override the cookie.
|
||||
func DeleteLegacySiteCookie(resp http.ResponseWriter, name string) {
|
||||
if setting.SessionConfig.CookiePath == "" || strings.HasSuffix(setting.SessionConfig.CookiePath, "/") {
|
||||
// If the cookie path ends with /, no legacy cookies will take
|
||||
// precedence, so do nothing. The exception is that cookies with no
|
||||
// path could override other cookies, but it's complicated and we don't
|
||||
// currently handle that.
|
||||
return
|
||||
}
|
||||
|
||||
cookie := &http.Cookie{
|
||||
Name: name,
|
||||
Value: "",
|
||||
MaxAge: -1,
|
||||
Path: setting.SessionConfig.CookiePath + "/",
|
||||
Domain: setting.SessionConfig.Domain,
|
||||
Secure: setting.SessionConfig.Secure,
|
||||
HttpOnly: true,
|
||||
SameSite: setting.SessionConfig.SameSite,
|
||||
}
|
||||
resp.Header().Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (C) 2006,2007,2009 NTT (Nippon Telegraph and Telephone
|
||||
Corporation). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer as the first lines of this file unmodified.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY NTT "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,13 @@
|
|||
Copyright (c) 2000 by Sun Microsystems, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation is hereby granted, provided that the above copyright
|
||||
notice appears in all copies.
|
||||
|
||||
SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
|
||||
THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
|
||||
ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
|
||||
DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
|
|
@ -0,0 +1,7 @@
|
|||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
This software is provided 'as is' and without any warranty, express or
|
||||
implied. In no event shall the authors be liable for any damages arising
|
||||
from the use of this software.
|
|
@ -21,7 +21,7 @@
|
|||
"chartjs-adapter-dayjs-4": "1.0.4",
|
||||
"chartjs-plugin-zoom": "2.0.1",
|
||||
"clippie": "4.0.7",
|
||||
"css-loader": "7.0.0",
|
||||
"css-loader": "7.1.1",
|
||||
"dayjs": "1.11.10",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.18.0",
|
||||
|
@ -44,9 +44,9 @@
|
|||
"postcss-nesting": "12.1.1",
|
||||
"pretty-ms": "9.0.0",
|
||||
"sortablejs": "1.15.2",
|
||||
"swagger-ui-dist": "5.13.0",
|
||||
"swagger-ui-dist": "5.15.1",
|
||||
"tailwindcss": "3.4.3",
|
||||
"temporal-polyfill": "0.2.3",
|
||||
"temporal-polyfill": "0.2.4",
|
||||
"throttle-debounce": "5.0.0",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tippy.js": "6.3.7",
|
||||
|
@ -56,7 +56,7 @@
|
|||
"vanilla-colorful": "0.7.2",
|
||||
"vue": "3.4.21",
|
||||
"vue-bar-graph": "2.0.0",
|
||||
"vue-chartjs": "5.3.0",
|
||||
"vue-chartjs": "5.3.1",
|
||||
"vue-loader": "17.4.2",
|
||||
"vue3-calendar-heatmap": "2.0.5",
|
||||
"webpack": "5.91.0",
|
||||
|
@ -64,8 +64,8 @@
|
|||
"wrap-ansi": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
|
||||
"@playwright/test": "1.42.1",
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
|
||||
"@playwright/test": "1.43.1",
|
||||
"@stoplight/spectral-cli": "6.11.1",
|
||||
"@stylistic/eslint-plugin-js": "1.7.0",
|
||||
"@stylistic/stylelint-plugin": "2.1.1",
|
||||
|
@ -77,15 +77,15 @@
|
|||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-no-jquery": "2.7.0",
|
||||
"eslint-plugin-no-use-extend-native": "0.5.0",
|
||||
"eslint-plugin-regexp": "2.4.0",
|
||||
"eslint-plugin-regexp": "2.5.0",
|
||||
"eslint-plugin-sonarjs": "0.25.1",
|
||||
"eslint-plugin-unicorn": "52.0.0",
|
||||
"eslint-plugin-vitest": "0.4.1",
|
||||
"eslint-plugin-vitest-globals": "1.5.0",
|
||||
"eslint-plugin-vue": "9.24.0",
|
||||
"eslint-plugin-vue": "9.24.1",
|
||||
"eslint-plugin-vue-scoped-css": "2.8.0",
|
||||
"eslint-plugin-wc": "2.0.4",
|
||||
"happy-dom": "14.5.0",
|
||||
"eslint-plugin-wc": "2.1.0",
|
||||
"happy-dom": "14.7.1",
|
||||
"markdownlint-cli": "0.39.0",
|
||||
"postcss-html": "1.6.0",
|
||||
"stylelint": "16.3.1",
|
||||
|
@ -93,9 +93,9 @@
|
|||
"stylelint-declaration-strict-value": "1.10.4",
|
||||
"stylelint-value-no-unknown-custom-properties": "6.0.1",
|
||||
"svgo": "3.2.0",
|
||||
"updates": "16.0.0",
|
||||
"updates": "16.0.1",
|
||||
"vite-string-plugin": "1.1.5",
|
||||
"vitest": "1.4.0"
|
||||
"vitest": "1.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
|
@ -865,9 +865,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-plugin-eslint-comments": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.1.0.tgz",
|
||||
"integrity": "sha512-B2mwipifrBS5E00vN8vME68laPMZ0h3sNGOEDj5g9iUN9k5EU99Omq0Nc325eKNoFFDnDtiHp3DqIjO+1bstag==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.3.0.tgz",
|
||||
"integrity": "sha512-6e93KtgsndNkvwCCa07LOQJSwzzLLxwrFll3+huyFoiiQXWG0KBcmo0Q1bVgYQQDLfWOOZl2VPBsXqZL6vHIBQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
|
@ -877,7 +877,7 @@
|
|||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
|
@ -1344,12 +1344,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz",
|
||||
"integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.43.1.tgz",
|
||||
"integrity": "sha512-HgtQzFgNEEo4TE22K/X7sYTYNqEMMTZmFS8kTq6m8hXj+m1D8TgwgIbumHddJa9h4yl4GkKb8/bgAl2+g7eDgA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright": "1.42.1"
|
||||
"playwright": "1.43.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
@ -1420,9 +1420,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz",
|
||||
"integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz",
|
||||
"integrity": "sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -1433,9 +1433,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz",
|
||||
"integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz",
|
||||
"integrity": "sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1446,9 +1446,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz",
|
||||
"integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz",
|
||||
"integrity": "sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1459,9 +1459,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz",
|
||||
"integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz",
|
||||
"integrity": "sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1472,9 +1472,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz",
|
||||
"integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz",
|
||||
"integrity": "sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -1485,9 +1485,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz",
|
||||
"integrity": "sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1498,9 +1498,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz",
|
||||
"integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz",
|
||||
"integrity": "sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1511,11 +1511,11 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz",
|
||||
"integrity": "sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==",
|
||||
"cpu": [
|
||||
"ppc64le"
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -1524,9 +1524,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz",
|
||||
"integrity": "sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
@ -1537,9 +1537,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz",
|
||||
"integrity": "sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
|
@ -1550,9 +1550,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz",
|
||||
"integrity": "sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1563,9 +1563,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz",
|
||||
"integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz",
|
||||
"integrity": "sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1576,9 +1576,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz",
|
||||
"integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz",
|
||||
"integrity": "sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1589,9 +1589,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz",
|
||||
"integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz",
|
||||
"integrity": "sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
@ -1602,9 +1602,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz",
|
||||
"integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz",
|
||||
"integrity": "sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -2217,9 +2217,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.56.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz",
|
||||
"integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==",
|
||||
"version": "8.56.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.9.tgz",
|
||||
"integrity": "sha512-W4W3KcqzjJ0sHg2vAq9vfml6OhsJ53TcUjUqfzzZf/EChUtwspszj/S0pzMxnfRcO55/iGq47dscXw71Fxc4Zg==",
|
||||
"dependencies": {
|
||||
"@types/estree": "*",
|
||||
"@types/json-schema": "*"
|
||||
|
@ -2269,9 +2269,9 @@
|
|||
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz",
|
||||
"integrity": "sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==",
|
||||
"version": "20.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
|
@ -2314,22 +2314,22 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
|
||||
"integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz",
|
||||
"integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/type-utils": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "7.6.0",
|
||||
"@typescript-eslint/type-utils": "7.6.0",
|
||||
"@typescript-eslint/utils": "7.6.0",
|
||||
"@typescript-eslint/visitor-keys": "7.6.0",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
"ignore": "^5.3.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2349,15 +2349,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
|
||||
"integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz",
|
||||
"integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.6.0",
|
||||
"@typescript-eslint/types": "7.6.0",
|
||||
"@typescript-eslint/typescript-estree": "7.6.0",
|
||||
"@typescript-eslint/visitor-keys": "7.6.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -2377,13 +2377,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
|
||||
"integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz",
|
||||
"integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0"
|
||||
"@typescript-eslint/types": "7.6.0",
|
||||
"@typescript-eslint/visitor-keys": "7.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2394,15 +2394,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
|
||||
"integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz",
|
||||
"integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.6.0",
|
||||
"@typescript-eslint/utils": "7.6.0",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2421,9 +2421,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
|
||||
"integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
|
||||
"integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2434,19 +2434,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
|
||||
"integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz",
|
||||
"integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/types": "7.6.0",
|
||||
"@typescript-eslint/visitor-keys": "7.6.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "9.0.3",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"minimatch": "^9.0.4",
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2461,34 +2461,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
|
||||
"integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz",
|
||||
"integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"semver": "^7.5.4"
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/scope-manager": "7.6.0",
|
||||
"@typescript-eslint/types": "7.6.0",
|
||||
"@typescript-eslint/typescript-estree": "7.6.0",
|
||||
"semver": "^7.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2502,13 +2487,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
|
||||
"integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
|
||||
"integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
"@typescript-eslint/types": "7.6.0",
|
||||
"eslint-visitor-keys": "^3.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
|
@ -2538,13 +2523,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz",
|
||||
"integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.0.tgz",
|
||||
"integrity": "sha512-0pzuCI6KYi2SIC3LQezmxujU9RK/vwC1U9R0rLuGlNGcOuDWxqWKu6nUdFsX9tH1WU0SXtAxToOsEjeUn1s3hA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/spy": "1.4.0",
|
||||
"@vitest/utils": "1.4.0",
|
||||
"@vitest/spy": "1.5.0",
|
||||
"@vitest/utils": "1.5.0",
|
||||
"chai": "^4.3.10"
|
||||
},
|
||||
"funding": {
|
||||
|
@ -2552,12 +2537,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz",
|
||||
"integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.0.tgz",
|
||||
"integrity": "sha512-7HWwdxXP5yDoe7DTpbif9l6ZmDwCzcSIK38kTSIt6CFEpMjX4EpCgT6wUmS0xTXqMI6E/ONmfgRKmaujpabjZQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/utils": "1.4.0",
|
||||
"@vitest/utils": "1.5.0",
|
||||
"p-limit": "^5.0.0",
|
||||
"pathe": "^1.1.1"
|
||||
},
|
||||
|
@ -2593,9 +2578,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz",
|
||||
"integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.0.tgz",
|
||||
"integrity": "sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"magic-string": "^0.30.5",
|
||||
|
@ -2619,9 +2604,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz",
|
||||
"integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.0.tgz",
|
||||
"integrity": "sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tinyspy": "^2.2.0"
|
||||
|
@ -2631,9 +2616,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz",
|
||||
"integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.0.tgz",
|
||||
"integrity": "sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"diff-sequences": "^29.6.3",
|
||||
|
@ -3566,9 +3551,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001605",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz",
|
||||
"integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==",
|
||||
"version": "1.0.30001609",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz",
|
||||
"integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -3960,9 +3945,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/css-loader": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.0.0.tgz",
|
||||
"integrity": "sha512-WrO4FVoamxt5zY9CauZjoJgXRi/LZKIk+Ta7YvpSGr5r/eMYPNp5/T9ODlMe4/1rF5DYlycG1avhV4g3A/tiAw==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz",
|
||||
"integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==",
|
||||
"dependencies": {
|
||||
"icss-utils": "^5.1.0",
|
||||
"postcss": "^8.4.33",
|
||||
|
@ -4812,9 +4797,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.11.tgz",
|
||||
"integrity": "sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.0.tgz",
|
||||
"integrity": "sha512-yoU4rhgPKCo+p5UrWWWNKiIq+ToGqmVVhk0PmMYBK4kRsR3/qhemNFL8f6CFmBd4gMwm3F4T7HBoydP5uY07fA=="
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "3.1.0",
|
||||
|
@ -4857,9 +4842,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.727",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.727.tgz",
|
||||
"integrity": "sha512-brpv4KTeC4g0Fx2FeIKytLd4UGn1zBQq5Lauy7zEWT9oqkaj5mgsxblEZIAOf1HHLlXxzr6adGViiBy5Z39/CA=="
|
||||
"version": "1.4.736",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz",
|
||||
"integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q=="
|
||||
},
|
||||
"node_modules/elkjs": {
|
||||
"version": "0.9.2",
|
||||
|
@ -4911,9 +4896,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/envinfo": {
|
||||
"version": "7.11.1",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
|
||||
"integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz",
|
||||
"integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==",
|
||||
"bin": {
|
||||
"envinfo": "dist/cli.js"
|
||||
},
|
||||
|
@ -5689,9 +5674,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-regexp": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.4.0.tgz",
|
||||
"integrity": "sha512-OL2S6VPjQhs9s/NclQ0qattVq1J0GU8ox70/HIVy5Dxw+qbbdd7KQkyucsez2clEQjvdtDe12DTnPphFFUyXFg==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.5.0.tgz",
|
||||
"integrity": "sha512-I7vKcP0o75WS5SHiVNXN+Eshq49sbrweMQIuqSL3AId9AwDe9Dhbfug65vw64LxmOd4v+yf5l5Xt41y9puiq0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
|
@ -5785,9 +5770,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "9.24.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz",
|
||||
"integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==",
|
||||
"version": "9.24.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.1.tgz",
|
||||
"integrity": "sha512-wk3SuwmS1pZdcuJlokGYEi/buDOwD6KltvhIZyOnpJ/378dcQ4zchu9PAMbbLAaydCz1iYc5AozszcOOgZIIOg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
|
@ -5803,7 +5788,7 @@
|
|||
"node": "^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
|
||||
"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue-scoped-css": {
|
||||
|
@ -5833,9 +5818,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-wc": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.0.4.tgz",
|
||||
"integrity": "sha512-ORu7MBv0hXIvq894EJad70m+AvHGbmrDdKT6lcgtCVVhEbuIAyxg0ilfqqqHOmsh8PfcUBeEae3y7CElKvm1KQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.1.0.tgz",
|
||||
"integrity": "sha512-s/BGOtmpgQ2yifR6EC1OM9t0DwYLgg4ZAL07Kw4eXvBb5TYaPafI+65tswvnZvhH8FqcjERLbBZPPvYsvinkfg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-valid-element-name": "^1.0.0",
|
||||
|
@ -6594,9 +6579,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/happy-dom": {
|
||||
"version": "14.5.0",
|
||||
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.5.0.tgz",
|
||||
"integrity": "sha512-KvOtCq7eamc7cjihM0F1wj6FptuXzooc3Typa7Vgu6ns2uKGXC4BIFlK80SdH2w8zcW0gtxpBVI/sUqbYtljDA==",
|
||||
"version": "14.7.1",
|
||||
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.7.1.tgz",
|
||||
"integrity": "sha512-v60Q0evZ4clvMcrAh5/F8EdxDdfHdFrtffz/CNe10jKD+nFweZVxM91tW+UyY2L4AtpgIaXdZ7TQmiO1pfcwbg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"entities": "^4.5.0",
|
||||
|
@ -9381,12 +9366,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.42.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz",
|
||||
"integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
|
||||
"integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright-core": "1.42.1"
|
||||
"playwright-core": "1.43.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
@ -9399,9 +9384,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.42.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz",
|
||||
"integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
|
||||
"integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
|
@ -11241,9 +11226,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/swagger-ui-dist": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.13.0.tgz",
|
||||
"integrity": "sha512-uaWhh6j18IIs5tOX0arvIBnVINAzpTXaQXkr7qAk8zoupegJVg0UU/5+S/FgsgVCnzVsJ9d7QLjIxkswEeTg0Q=="
|
||||
"version": "5.15.1",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.15.1.tgz",
|
||||
"integrity": "sha512-Et/WY0NFdKj8sUBOyEx5P3VybsvGl7bo/y9JvgQ22TkH1a/KscQ0ZiQST2YeJ3cwCrIjYTbHbt165fkku0y1Ig=="
|
||||
},
|
||||
"node_modules/sync-fetch": {
|
||||
"version": "0.4.5",
|
||||
|
@ -11379,17 +11364,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/temporal-polyfill": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.3.tgz",
|
||||
"integrity": "sha512-7ZJRc7wq/1XjrOQYkkNpgo2qfE9XLrUU8D/DS+LAC/T0bYqZ46rW6dow0sOTXTPZS4bwer8bD/0OyuKQBfA3yw==",
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.4.tgz",
|
||||
"integrity": "sha512-WA5p0CjQTkMjF9m8sP4wSYgpqI8m2d4q7wPUyaJOWhy4bI9mReLb2yGvTV4qf/DPMTe6H6M/Dig5KmTMB7ev6Q==",
|
||||
"dependencies": {
|
||||
"temporal-spec": "^0.2.0"
|
||||
"temporal-spec": "^0.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/temporal-spec": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.0.tgz",
|
||||
"integrity": "sha512-r1AT0XdEp8TMQ13FLvOt8mOtAxDQsRt2QU5rSWCA7YfshddU651Y1NHVrceLANvixKdf9fYO8B/S9fXHodB7HQ=="
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.4.tgz",
|
||||
"integrity": "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ=="
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.30.3",
|
||||
|
@ -11749,9 +11734,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"devOptional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
|
@ -11855,9 +11840,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/updates": {
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/updates/-/updates-16.0.0.tgz",
|
||||
"integrity": "sha512-Ra3QUu/rfbSCsG83zNNvoRQt0FVT3qULBSALYTlwTDX6oyz7R5GQAYwqJoIG/RDjYAXpwr3usrInoyHHTP6cag==",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/updates/-/updates-16.0.1.tgz",
|
||||
"integrity": "sha512-If3NQKzGcA3aVgz2VyOXqQ+4uqYjPUPqh2PeZPtD+OKT4CTmxRYqoyFO+T3nwfccy4SiWy5AabWrBXXhVQ89Aw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"updates": "dist/updates.js"
|
||||
|
@ -12003,9 +11988,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite-node": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz",
|
||||
"integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.0.tgz",
|
||||
"integrity": "sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cac": "^6.7.14",
|
||||
|
@ -12051,9 +12036,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite/node_modules/rollup": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz",
|
||||
"integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==",
|
||||
"version": "4.14.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.2.tgz",
|
||||
"integrity": "sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.5"
|
||||
|
@ -12066,35 +12051,35 @@
|
|||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.14.0",
|
||||
"@rollup/rollup-android-arm64": "4.14.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.14.0",
|
||||
"@rollup/rollup-darwin-x64": "4.14.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.14.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.14.0",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.14.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.14.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.14.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.14.0",
|
||||
"@rollup/rollup-android-arm-eabi": "4.14.2",
|
||||
"@rollup/rollup-android-arm64": "4.14.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.14.2",
|
||||
"@rollup/rollup-darwin-x64": "4.14.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.14.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.14.2",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.14.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.14.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.14.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.14.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.14.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.14.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.14.2",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz",
|
||||
"integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.0.tgz",
|
||||
"integrity": "sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/expect": "1.4.0",
|
||||
"@vitest/runner": "1.4.0",
|
||||
"@vitest/snapshot": "1.4.0",
|
||||
"@vitest/spy": "1.4.0",
|
||||
"@vitest/utils": "1.4.0",
|
||||
"@vitest/expect": "1.5.0",
|
||||
"@vitest/runner": "1.5.0",
|
||||
"@vitest/snapshot": "1.5.0",
|
||||
"@vitest/spy": "1.5.0",
|
||||
"@vitest/utils": "1.5.0",
|
||||
"acorn-walk": "^8.3.2",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
|
@ -12106,9 +12091,9 @@
|
|||
"std-env": "^3.5.0",
|
||||
"strip-literal": "^2.0.0",
|
||||
"tinybench": "^2.5.1",
|
||||
"tinypool": "^0.8.2",
|
||||
"tinypool": "^0.8.3",
|
||||
"vite": "^5.0.0",
|
||||
"vite-node": "1.4.0",
|
||||
"vite-node": "1.5.0",
|
||||
"why-is-node-running": "^2.2.2"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -12123,8 +12108,8 @@
|
|||
"peerDependencies": {
|
||||
"@edge-runtime/vm": "*",
|
||||
"@types/node": "^18.0.0 || >=20.0.0",
|
||||
"@vitest/browser": "1.4.0",
|
||||
"@vitest/ui": "1.4.0",
|
||||
"@vitest/browser": "1.5.0",
|
||||
"@vitest/ui": "1.5.0",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
},
|
||||
|
@ -12191,9 +12176,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vue-chartjs": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.0.tgz",
|
||||
"integrity": "sha512-8XqX0JU8vFZ+WA2/knz4z3ThClduni2Nm0BMe2u0mXgTfd9pXrmJ07QBI+WAij5P/aPmPMX54HCE1seWL37ZdQ==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz",
|
||||
"integrity": "sha512-rZjqcHBxKiHrBl0CIvcOlVEBwRhpWAVf6rDU3vUfa7HuSRmGtCslc0Oc8m16oAVuk0erzc1FCtH1VCriHsrz+A==",
|
||||
"peerDependencies": {
|
||||
"chart.js": "^4.1.1",
|
||||
"vue": "^3.0.0-0 || ^2.7.0"
|
||||
|
|
24
package.json
24
package.json
|
@ -20,7 +20,7 @@
|
|||
"chartjs-adapter-dayjs-4": "1.0.4",
|
||||
"chartjs-plugin-zoom": "2.0.1",
|
||||
"clippie": "4.0.7",
|
||||
"css-loader": "7.0.0",
|
||||
"css-loader": "7.1.1",
|
||||
"dayjs": "1.11.10",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.18.0",
|
||||
|
@ -43,9 +43,9 @@
|
|||
"postcss-nesting": "12.1.1",
|
||||
"pretty-ms": "9.0.0",
|
||||
"sortablejs": "1.15.2",
|
||||
"swagger-ui-dist": "5.13.0",
|
||||
"swagger-ui-dist": "5.15.1",
|
||||
"tailwindcss": "3.4.3",
|
||||
"temporal-polyfill": "0.2.3",
|
||||
"temporal-polyfill": "0.2.4",
|
||||
"throttle-debounce": "5.0.0",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tippy.js": "6.3.7",
|
||||
|
@ -55,7 +55,7 @@
|
|||
"vanilla-colorful": "0.7.2",
|
||||
"vue": "3.4.21",
|
||||
"vue-bar-graph": "2.0.0",
|
||||
"vue-chartjs": "5.3.0",
|
||||
"vue-chartjs": "5.3.1",
|
||||
"vue-loader": "17.4.2",
|
||||
"vue3-calendar-heatmap": "2.0.5",
|
||||
"webpack": "5.91.0",
|
||||
|
@ -63,8 +63,8 @@
|
|||
"wrap-ansi": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
|
||||
"@playwright/test": "1.42.1",
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
|
||||
"@playwright/test": "1.43.1",
|
||||
"@stoplight/spectral-cli": "6.11.1",
|
||||
"@stylistic/eslint-plugin-js": "1.7.0",
|
||||
"@stylistic/stylelint-plugin": "2.1.1",
|
||||
|
@ -76,15 +76,15 @@
|
|||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-no-jquery": "2.7.0",
|
||||
"eslint-plugin-no-use-extend-native": "0.5.0",
|
||||
"eslint-plugin-regexp": "2.4.0",
|
||||
"eslint-plugin-regexp": "2.5.0",
|
||||
"eslint-plugin-sonarjs": "0.25.1",
|
||||
"eslint-plugin-unicorn": "52.0.0",
|
||||
"eslint-plugin-vitest": "0.4.1",
|
||||
"eslint-plugin-vitest-globals": "1.5.0",
|
||||
"eslint-plugin-vue": "9.24.0",
|
||||
"eslint-plugin-vue": "9.24.1",
|
||||
"eslint-plugin-vue-scoped-css": "2.8.0",
|
||||
"eslint-plugin-wc": "2.0.4",
|
||||
"happy-dom": "14.5.0",
|
||||
"eslint-plugin-wc": "2.1.0",
|
||||
"happy-dom": "14.7.1",
|
||||
"markdownlint-cli": "0.39.0",
|
||||
"postcss-html": "1.6.0",
|
||||
"stylelint": "16.3.1",
|
||||
|
@ -92,9 +92,9 @@
|
|||
"stylelint-declaration-strict-value": "1.10.4",
|
||||
"stylelint-value-no-unknown-custom-properties": "6.0.1",
|
||||
"svgo": "3.2.0",
|
||||
"updates": "16.0.0",
|
||||
"updates": "16.0.1",
|
||||
"vite-string-plugin": "1.1.5",
|
||||
"vitest": "1.4.0"
|
||||
"vitest": "1.5.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults"
|
||||
|
|
|
@ -113,13 +113,13 @@ six = ">=1.13.0"
|
|||
|
||||
[[package]]
|
||||
name = "json5"
|
||||
version = "0.9.24"
|
||||
version = "0.9.25"
|
||||
description = "A Python implementation of the JSON5 data format."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "json5-0.9.24-py3-none-any.whl", hash = "sha256:4ca101fd5c7cb47960c055ef8f4d0e31e15a7c6c48c3b6f1473fc83b6c462a13"},
|
||||
{file = "json5-0.9.24.tar.gz", hash = "sha256:0c638399421da959a20952782800e5c1a78c14e08e1dc9738fa10d8ec14d58c8"},
|
||||
{file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"},
|
||||
{file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -29,9 +29,7 @@ func NodeInfo(ctx *context.APIContext) {
|
|||
|
||||
nodeInfoUsage := structs.NodeInfoUsage{}
|
||||
if setting.Federation.ShareUserStatistics {
|
||||
var cached bool
|
||||
nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage)
|
||||
|
||||
cached, _ := ctx.Cache.GetJSON(cacheKeyNodeInfoUsage, &nodeInfoUsage)
|
||||
if !cached {
|
||||
usersTotal := int(user_model.CountUsers(ctx, nil))
|
||||
now := time.Now()
|
||||
|
@ -53,7 +51,7 @@ func NodeInfo(ctx *context.APIContext) {
|
|||
LocalComments: int(allComments),
|
||||
}
|
||||
|
||||
if err := ctx.Cache.Put(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil {
|
||||
if err := ctx.Cache.PutJSON(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -195,14 +194,15 @@ func NewProjectPost(ctx *context.Context) {
|
|||
|
||||
// ChangeProjectStatus updates the status of a project between "open" and "close"
|
||||
func ChangeProjectStatus(ctx *context.Context) {
|
||||
toClose := false
|
||||
var toClose bool
|
||||
switch ctx.Params(":action") {
|
||||
case "open":
|
||||
toClose = false
|
||||
case "close":
|
||||
toClose = true
|
||||
default:
|
||||
ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects")
|
||||
ctx.JSONRedirect(ctx.ContextUser.HomeLink() + "/-/projects")
|
||||
return
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
|
@ -210,7 +210,7 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
|
||||
}
|
||||
|
||||
// DeleteProject delete a project
|
||||
|
|
|
@ -3318,7 +3318,6 @@ func ChangeIssueReaction(ctx *context.Context) {
|
|||
}
|
||||
|
||||
html, err := ctx.RenderToHTML(tplReactions, map[string]any{
|
||||
"ctxData": ctx.Data,
|
||||
"ActionURL": fmt.Sprintf("%s/issues/%d/reactions", ctx.Repo.RepoLink, issue.Index),
|
||||
"Reactions": issue.Reactions.GroupByType(),
|
||||
})
|
||||
|
@ -3425,7 +3424,6 @@ func ChangeCommentReaction(ctx *context.Context) {
|
|||
}
|
||||
|
||||
html, err := ctx.RenderToHTML(tplReactions, map[string]any{
|
||||
"ctxData": ctx.Data,
|
||||
"ActionURL": fmt.Sprintf("%s/comments/%d/reactions", ctx.Repo.RepoLink, comment.ID),
|
||||
"Reactions": comment.Reactions.GroupByType(),
|
||||
})
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -181,14 +180,10 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", err)
|
||||
} else {
|
||||
ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err)
|
||||
}
|
||||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
|
||||
}
|
||||
|
||||
// DeleteProject delete a project
|
||||
|
|
|
@ -20,7 +20,7 @@ func TestCreateAuthorizationToken(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, "", token)
|
||||
claims := jwt.MapClaims{}
|
||||
_, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (interface{}, error) {
|
||||
_, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) {
|
||||
return setting.GetGeneralTokenSigningSecret(), nil
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
session_module "code.gitea.io/gitea/modules/session"
|
||||
|
||||
chiSession "gitea.com/go-chi/session"
|
||||
"github.com/gorilla/sessions"
|
||||
|
@ -65,7 +66,7 @@ func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *s
|
|||
chiStore := chiSession.GetSession(r)
|
||||
|
||||
if session.IsNew {
|
||||
_, _ = chiSession.RegenerateSession(w, r)
|
||||
_, _ = session_module.RegenerateSession(w, r)
|
||||
session.IsNew = false
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
mc "code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/httpcache"
|
||||
|
@ -21,15 +21,13 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
web_types "code.gitea.io/gitea/modules/web/types"
|
||||
|
||||
"gitea.com/go-chi/cache"
|
||||
)
|
||||
|
||||
// APIContext is a specific context for API service
|
||||
type APIContext struct {
|
||||
*Base
|
||||
|
||||
Cache cache.Cache
|
||||
Cache cache.StringCache
|
||||
|
||||
Doer *user_model.User // current signed-in user
|
||||
IsSigned bool
|
||||
|
@ -217,7 +215,7 @@ func APIContexter() func(http.Handler) http.Handler {
|
|||
base, baseCleanUp := NewBaseContext(w, req)
|
||||
ctx := &APIContext{
|
||||
Base: base,
|
||||
Cache: mc.GetCache(),
|
||||
Cache: cache.GetCache(),
|
||||
Repo: &Repository{PullRequest: &PullRequest{}},
|
||||
Org: &APIOrganization{},
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func GetImageCaptcha() *captcha.Captcha {
|
|||
cpt = captcha.NewCaptcha(captcha.Options{
|
||||
SubURL: setting.AppSubURL,
|
||||
})
|
||||
cpt.Store = cache.GetCache()
|
||||
cpt.Store = cache.GetCache().ChiCache()
|
||||
})
|
||||
return cpt
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
mc "code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/httpcache"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -27,7 +27,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
web_types "code.gitea.io/gitea/modules/web/types"
|
||||
|
||||
"gitea.com/go-chi/cache"
|
||||
"gitea.com/go-chi/session"
|
||||
)
|
||||
|
||||
|
@ -46,7 +45,7 @@ type Context struct {
|
|||
Render Render
|
||||
PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData`
|
||||
|
||||
Cache cache.Cache
|
||||
Cache cache.StringCache
|
||||
Csrf CSRFProtector
|
||||
Flash *middleware.Flash
|
||||
Session session.Store
|
||||
|
@ -102,6 +101,7 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext {
|
|||
tmplCtx := NewTemplateContext(ctx)
|
||||
tmplCtx["Locale"] = ctx.Base.Locale
|
||||
tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
|
||||
tmplCtx["RootData"] = ctx.Data
|
||||
return tmplCtx
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ func NewWebContext(base *Base, render Render, session session.Store) *Context {
|
|||
Render: render,
|
||||
Session: session,
|
||||
|
||||
Cache: mc.GetCache(),
|
||||
Cache: cache.GetCache(),
|
||||
Link: setting.AppSubURL + strings.TrimSuffix(base.Req.URL.EscapedPath(), "/"),
|
||||
Repo: &Repository{PullRequest: &PullRequest{}},
|
||||
Org: &Organization{},
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
giturl "code.gitea.io/gitea/modules/git/url"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/lfs"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -30,10 +31,15 @@ const gitShortEmptySha = "0000000"
|
|||
|
||||
// UpdateAddress writes new address to Git repository and database
|
||||
func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error {
|
||||
u, err := giturl.Parse(addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid addr: %v", err)
|
||||
}
|
||||
|
||||
remoteName := m.GetRemoteName()
|
||||
repoPath := m.GetRepository(ctx).RepoPath()
|
||||
// Remove old remote
|
||||
_, _, err := git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
|
||||
_, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||
return err
|
||||
}
|
||||
|
@ -70,7 +76,9 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
|
|||
}
|
||||
}
|
||||
|
||||
m.Repo.OriginalURL = addr
|
||||
// erase authentication before storing in database
|
||||
u.User = nil
|
||||
m.Repo.OriginalURL = u.String()
|
||||
return repo_model.UpdateRepositoryCols(ctx, m.Repo, "original_url")
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/queue"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
notify_service "code.gitea.io/gitea/services/notify"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
|
@ -119,17 +120,15 @@ func getDivergenceCacheKey(repoID int64, branchName string) string {
|
|||
|
||||
// getDivergenceFromCache gets the divergence from cache
|
||||
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
|
||||
data := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
|
||||
data, ok := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
|
||||
res := git.DivergeObject{
|
||||
Ahead: -1,
|
||||
Behind: -1,
|
||||
}
|
||||
s, ok := data.([]byte)
|
||||
if !ok || len(s) == 0 {
|
||||
if !ok || data == "" {
|
||||
return &res, false
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(s, &res); err != nil {
|
||||
if err := json.Unmarshal(util.UnsafeStringToBytes(data), &res); err != nil {
|
||||
log.Error("json.UnMarshal failed: %v", err)
|
||||
return &res, false
|
||||
}
|
||||
|
@ -141,7 +140,7 @@ func putDivergenceFromCache(repoID int64, branchName string, divergence *git.Div
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), bs, 30*24*60*60)
|
||||
return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), util.UnsafeBytesToString(bs), 30*24*60*60)
|
||||
}
|
||||
|
||||
func DelDivergenceFromCache(repoID int64, branchName string) error {
|
||||
|
|
|
@ -34,7 +34,7 @@ type commitStatusCacheValue struct {
|
|||
|
||||
func getCommitStatusCache(repoID int64, branchName string) *commitStatusCacheValue {
|
||||
c := cache.GetCache()
|
||||
statusStr, ok := c.Get(getCacheKey(repoID, branchName)).(string)
|
||||
statusStr, ok := c.Get(getCacheKey(repoID, branchName))
|
||||
if ok && statusStr != "" {
|
||||
var cv commitStatusCacheValue
|
||||
err := json.Unmarshal([]byte(statusStr), &cv)
|
||||
|
|
|
@ -17,13 +17,12 @@ import (
|
|||
"code.gitea.io/gitea/models/avatars"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"gitea.com/go-chi/cache"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -79,13 +78,13 @@ func findLastSundayBeforeDate(dateStr string) (string, error) {
|
|||
}
|
||||
|
||||
// GetContributorStats returns contributors stats for git commits for given revision or default branch
|
||||
func GetContributorStats(ctx context.Context, cache cache.Cache, repo *repo_model.Repository, revision string) (map[string]*ContributorData, error) {
|
||||
func GetContributorStats(ctx context.Context, cache cache.StringCache, repo *repo_model.Repository, revision string) (map[string]*ContributorData, error) {
|
||||
// as GetContributorStats is resource intensive we cache the result
|
||||
cacheKey := fmt.Sprintf(contributorStatsCacheKey, repo.FullName(), revision)
|
||||
if !cache.IsExist(cacheKey) {
|
||||
genReady := make(chan struct{})
|
||||
|
||||
// dont start multible async generations
|
||||
// dont start multiple async generations
|
||||
_, run := generateLock.Load(cacheKey)
|
||||
if run {
|
||||
return nil, ErrAwaitGeneration
|
||||
|
@ -104,15 +103,11 @@ func GetContributorStats(ctx context.Context, cache cache.Cache, repo *repo_mode
|
|||
}
|
||||
}
|
||||
// TODO: renew timeout of cache cache.UpdateTimeout(cacheKey, contributorStatsCacheTimeout)
|
||||
|
||||
switch v := cache.Get(cacheKey).(type) {
|
||||
case error:
|
||||
return nil, v
|
||||
case map[string]*ContributorData:
|
||||
return v, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type in cache detected")
|
||||
var res map[string]*ContributorData
|
||||
if _, cacheErr := cache.GetJSON(cacheKey, &res); cacheErr != nil {
|
||||
return nil, fmt.Errorf("cached error: %w", cacheErr.ToError())
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// getExtendedCommitStats return the list of *ExtendedCommitStats for the given revision
|
||||
|
@ -205,13 +200,12 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
|
|||
return extendedCommitStats, nil
|
||||
}
|
||||
|
||||
func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey string, repo *repo_model.Repository, revision string) {
|
||||
func generateContributorStats(genDone chan struct{}, cache cache.StringCache, cacheKey string, repo *repo_model.Repository, revision string) {
|
||||
ctx := graceful.GetManager().HammerContext()
|
||||
|
||||
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("OpenRepository: %w", err)
|
||||
_ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
|
||||
_ = cache.PutJSON(cacheKey, fmt.Errorf("OpenRepository: %w", err), contributorStatsCacheTimeout)
|
||||
return
|
||||
}
|
||||
defer closer.Close()
|
||||
|
@ -221,13 +215,11 @@ func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey
|
|||
}
|
||||
extendedCommitStats, err := getExtendedCommitStats(gitRepo, revision)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("ExtendedCommitStats: %w", err)
|
||||
_ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
|
||||
_ = cache.PutJSON(cacheKey, fmt.Errorf("ExtendedCommitStats: %w", err), contributorStatsCacheTimeout)
|
||||
return
|
||||
}
|
||||
if len(extendedCommitStats) == 0 {
|
||||
err := fmt.Errorf("no commit stats returned for revision '%s'", revision)
|
||||
_ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
|
||||
_ = cache.PutJSON(cacheKey, fmt.Errorf("no commit stats returned for revision '%s'", revision), contributorStatsCacheTimeout)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -309,7 +301,7 @@ func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey
|
|||
total.TotalCommits++
|
||||
}
|
||||
|
||||
_ = cache.Put(cacheKey, contributorsCommitStats, contributorStatsCacheTimeout)
|
||||
_ = cache.PutJSON(cacheKey, contributorsCommitStats, contributorStatsCacheTimeout)
|
||||
generateLock.Delete(cacheKey)
|
||||
if genDone != nil {
|
||||
genDone <- struct{}{}
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"gitea.com/go-chi/cache"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -20,20 +20,18 @@ func TestRepository_ContributorsGraph(t *testing.T) {
|
|||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
assert.NoError(t, repo.LoadOwner(db.DefaultContext))
|
||||
mockCache, err := cache.NewCacher(cache.Options{
|
||||
Adapter: "memory",
|
||||
Interval: 24 * 60,
|
||||
})
|
||||
mockCache, err := cache.NewStringCache(setting.Cache{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
generateContributorStats(nil, mockCache, "key", repo, "404ref")
|
||||
err, isErr := mockCache.Get("key").(error)
|
||||
assert.True(t, isErr)
|
||||
assert.ErrorAs(t, err, &git.ErrNotExist{})
|
||||
var data map[string]*ContributorData
|
||||
_, getErr := mockCache.GetJSON("key", &data)
|
||||
assert.NotNil(t, getErr)
|
||||
assert.ErrorContains(t, getErr.ToError(), "object does not exist")
|
||||
|
||||
generateContributorStats(nil, mockCache, "key2", repo, "master")
|
||||
data, isData := mockCache.Get("key2").(map[string]*ContributorData)
|
||||
assert.True(t, isData)
|
||||
exist, _ := mockCache.GetJSON("key2", &data)
|
||||
assert.True(t, exist)
|
||||
var keys []string
|
||||
for k := range data {
|
||||
keys = append(keys, k)
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui small teal button" id="delete-selection" data-link="{{.Link}}/delete" data-redirect="?page={{.Page.Paginater.Current}}">
|
||||
<button class="ui small button" id="delete-selection" data-link="{{.Link}}/delete" data-redirect="?page={{.Page.Paginater.Current}}">
|
||||
<span class="text">{{ctx.Locale.Tr "admin.notices.delete_selected"}}</span>
|
||||
</button>
|
||||
</th>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="q" value="{{$.Keyword}}">
|
||||
<input type="hidden" name="page" value="{{$.CurrentPage}}">
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}}
|
||||
{{template "base/modal_actions_confirm"}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{{/*
|
||||
Two buttons (negative, positive):
|
||||
* ModalButtonTypes: "yes" (default) or "confirm"
|
||||
* ModalButtonColors: "primary" (default) / "blue" / "yellow"
|
||||
* ModalButtonCancelText
|
||||
* ModalButtonOkText
|
||||
|
||||
|
@ -22,14 +21,7 @@ The ".ok.button" and ".cancel.button" selectors are also used by Fomantic Modal
|
|||
{{end}}
|
||||
{{if .ModalButtonCancelText}}{{$textNegitive = .ModalButtonCancelText}}{{end}}
|
||||
{{if .ModalButtonOkText}}{{$textPositive = .ModalButtonOkText}}{{end}}
|
||||
|
||||
{{$stylePositive := "primary"}}
|
||||
{{if eq .ModalButtonColors "blue"}}
|
||||
{{$stylePositive = "blue"}}
|
||||
{{else if eq .ModalButtonColors "yellow"}}
|
||||
{{$stylePositive = "yellow"}}
|
||||
{{end}}
|
||||
<button class="ui cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button>
|
||||
<button class="ui {{$stylePositive}} ok button">{{svg "octicon-check"}} {{$textPositive}}</button>
|
||||
<button class="ui primary ok button">{{svg "octicon-check"}} {{$textPositive}}</button>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
{{template "base/head" .}}
|
||||
<div class="page-content devtest ui container">
|
||||
{{template "base/alert" .}}
|
||||
<div class="modal-buttons flex-text-block tw-flex-wrap"></div>
|
||||
<script type="module">
|
||||
for (const el of $('.ui.modal')) {
|
||||
const $btn = $('<button class="ui button">').text(`${el.id}`).on('click', () => {
|
||||
$(el).modal({onApprove() {alert('confirmed')}}).modal('show');
|
||||
});
|
||||
$('.modal-buttons').append($btn);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="test-modal-form-1" class="ui mini modal">
|
||||
<div class="header">Form dialog (layout 1)</div>
|
||||
|
@ -54,33 +63,11 @@
|
|||
{{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}}
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm modal" id="test-modal-blue">
|
||||
<div class="header">Blue dialog</div>
|
||||
<div class="content">hello, this is the modal dialog content</div>
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonColors" "blue")}}
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm modal" id="test-modal-yellow">
|
||||
<div class="header">yellow dialog</div>
|
||||
<div class="content">hello, this is the modal dialog content</div>
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}}
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm modal" id="test-modal-danger">
|
||||
{{svg "octicon-x" 16 "inside close"}}
|
||||
<div class="header">dangerous action dialog</div>
|
||||
<div class="content">hello, this is the modal dialog content, this is a dangerous operation</div>
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonDangerText" "I know and must do this is dangerous operation")}}
|
||||
</div>
|
||||
|
||||
<div class="modal-buttons flex-text-block tw-flex-wrap"></div>
|
||||
<script type="module">
|
||||
for (const el of $('.ui.modal')) {
|
||||
const $btn = $('<button>').text(`${el.id}`).on('click', () => {
|
||||
$(el).modal({onApprove() {alert('confirmed')}}).modal('show');
|
||||
});
|
||||
$('.modal-buttons').append($btn);
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
@ -29,41 +29,13 @@
|
|||
<button class="ui basic button">Basic Unclassed</button>
|
||||
<button class="ui primary button">Primary</button>
|
||||
<button class="ui basic primary button">Basic Primary</button>
|
||||
<button class="ui negative button">Negative</button>
|
||||
<button class="ui basic negative button">Basic Negative</button>
|
||||
<button class="ui positive button">Positive</button>
|
||||
<button class="ui basic positive button">Basic Positive</button>
|
||||
</li>
|
||||
<li class="sample-group">
|
||||
<h2>Recommended colors:</h2>
|
||||
<button class="ui red button">Red</button>
|
||||
<button class="ui basic red button">Basic Red</button>
|
||||
<button class="ui primary button">Green</button>
|
||||
<button class="ui basic primary button">Basic Green</button>
|
||||
<button class="ui blue button">Blue</button>
|
||||
<button class="ui basic blue button">Basic Blue</button>
|
||||
<button class="ui orange button">Orange</button>
|
||||
<button class="ui basic orange button">Basic Orange</button>
|
||||
<button class="ui yellow button">Yellow</button>
|
||||
<button class="ui basic yellow button">Basic Yellow</button>
|
||||
</li>
|
||||
<li class="sample-group">
|
||||
<h2>Supported but not recommended:</h2>
|
||||
<p>Do not use if there is no strong requirement. Do not use grey/black buttons, they don't work well with dark theme.</p>
|
||||
<button class="ui secondary button">Secondary</button>
|
||||
<button class="ui basic secondary button">Basic Secondary</button>
|
||||
<button class="ui olive button">Olive</button>
|
||||
<button class="ui basic olive button">Basic Olive</button>
|
||||
<button class="ui teal button">Teal</button>
|
||||
<button class="ui basic teal button">Basic Teal</button>
|
||||
<button class="ui violet button">Violet</button>
|
||||
<button class="ui basic violet button">Basic Violet</button>
|
||||
<button class="ui purple button">Purple</button>
|
||||
<button class="ui basic purple button">Basic Purple</button>
|
||||
<button class="ui pink button">Pink</button>
|
||||
<button class="ui basic pink button">Basic Pink</button>
|
||||
<button class="ui brown button">Brown</button>
|
||||
<button class="ui basic brown button">Basic Brown</button>
|
||||
<button class="ui green button">Green</button>
|
||||
<button class="ui basic green button">Basic Green</button>
|
||||
</li>
|
||||
<li class="sample-group">
|
||||
<h2>Inline / Plain:</h2>
|
||||
|
@ -198,7 +170,7 @@
|
|||
<button class="ui basic button">labeled button</button>
|
||||
<a class="ui basic label">123</a>
|
||||
</div>
|
||||
<button class="ui yellow button">{{svg "octicon-x" 16}} button with very very very very very very very very long text</button>
|
||||
<button class="ui button">{{svg "octicon-x" 16}} button with very very very very very very very very long text</button>
|
||||
</div>
|
||||
|
||||
<h2>Input with SVG</h2>
|
||||
|
@ -271,10 +243,6 @@
|
|||
<span class="text">button dropdown</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui dropdown large button">
|
||||
<span class="text">large dropdown</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -290,10 +258,6 @@
|
|||
<span class="text">button compact</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui dropdown large compact button">
|
||||
<span class="text">large compact</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
{{template "base/head" .}}
|
||||
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/devtest.css?v={{AssetVersion}}">
|
||||
<div class="page-content devtest ui container">
|
||||
<div>
|
||||
<h1>Label</h1>
|
||||
<div class="flex-text-block tw-my-2">
|
||||
<span class="ui label">simple label</span>
|
||||
<span class="ui red label">red label</span>
|
||||
<span class="ui green label">green label</span>
|
||||
</div>
|
||||
<div class="flex-text-block tw-my-2">
|
||||
<span class="ui basic label">basic label</span>
|
||||
<span class="ui basic red label">basic red label</span>
|
||||
<span class="ui basic green label">basic green label</span>
|
||||
</div>
|
||||
<div class="flex-text-block tw-my-2">
|
||||
<span class="ui label">long content must be in a non-flex "gt-ellipsis" element, otherwise it won't get ellipsis. very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong label</span>
|
||||
</div>
|
||||
<div class="flex-text-block tw-my-2">
|
||||
<span class="ui label"><span class="gt-ellipsis">very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong label</span></span>
|
||||
</div>
|
||||
<div class="tw-my-2">
|
||||
<span class="ui label tw-max-w-full"><span class="gt-ellipsis">very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong label</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
|
@ -79,7 +79,7 @@
|
|||
</div>
|
||||
{{if .IsOrganizationOwner}}
|
||||
<div class="ui bottom attached segment">
|
||||
<a class="ui teal small button" href="{{.OrgLink}}/teams/{{.Team.LowerName | PathEscape}}/edit">{{svg "octicon-gear"}} {{ctx.Locale.Tr "org.teams.settings"}}</a>
|
||||
<a class="ui small button" href="{{.OrgLink}}/teams/{{.Team.LowerName | PathEscape}}/edit">{{svg "octicon-gear"}} {{ctx.Locale.Tr "org.teams.settings"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{{$branchLink := HTMLFormat `<a href="%s/src/branch/%s">%s</a>` $.RepoLink (PathEscapeSegments .Name) .Name}}
|
||||
{{ctx.Locale.Tr "repo.pulls.recently_pushed_new_branches" $branchLink $timeSince}}
|
||||
</div>
|
||||
<a role="button" class="ui compact positive button tw-m-0" href="{{$.Repository.ComposeBranchCompareURL $.Repository.BaseRepo .Name}}">
|
||||
<a role="button" class="ui compact green button tw-m-0" href="{{$.Repository.ComposeBranchCompareURL $.Repository.BaseRepo .Name}}">
|
||||
{{ctx.Locale.Tr "repo.pulls.compare_changes"}}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $.root "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/context_menu" dict "ctxData" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,7 +68,7 @@
|
|||
</div>
|
||||
{{$reactions := .Reactions.GroupByType}}
|
||||
{{if $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ctxData" $.root "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -184,23 +184,15 @@
|
|||
{{end}}
|
||||
{{else if and .PageIsComparePull (gt .CommitCount 0)}}
|
||||
{{if .HasPullRequest}}
|
||||
<div class="ui segment grid title">
|
||||
<div class="twelve wide column issue-title">
|
||||
{{ctx.Locale.Tr "repo.pulls.has_pull_request" (print $.RepoLink "/pulls/" .PullRequest.Issue.Index) $.RepoRelPath .PullRequest.Index}}
|
||||
<h1>
|
||||
<span id="issue-title">{{RenderIssueTitle $.Context .PullRequest.Issue.Title ($.Repository.ComposeMetas ctx)}}</span>
|
||||
<span class="index">#{{.PullRequest.Issue.Index}}</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="four wide column middle aligned text right">
|
||||
{{- if .PullRequest.HasMerged -}}
|
||||
<a href="{{$.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button purple show-form">{{svg "octicon-git-merge" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
|
||||
{{else if .Issue.IsClosed}}
|
||||
<a href="{{$.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button red show-form">{{svg "octicon-issue-closed" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
|
||||
{{else}}
|
||||
<a href="{{$.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button primary show-form">{{svg "octicon-git-pull-request" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
|
||||
{{end}}
|
||||
<div class="ui segment flex-text-block tw-gap-4">
|
||||
{{template "shared/issueicon" .}}
|
||||
<div class="issue-title tw-break-anywhere">
|
||||
{{RenderIssueTitle $.Context .PullRequest.Issue.Title ($.Repository.ComposeMetas ctx) | RenderCodeBlock}}
|
||||
<span class="index">#{{.PullRequest.Issue.Index}}</span>
|
||||
</div>
|
||||
<a href="{{$.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui compact button primary">
|
||||
{{ctx.Locale.Tr "repo.pulls.view"}}
|
||||
</a>
|
||||
</div>
|
||||
{{else}}
|
||||
{{if and $.IsSigned (not .Repository.IsArchived)}}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<div class="comment-header-right actions tw-flex tw-items-center">
|
||||
{{template "repo/issue/view_content/show_role" dict "ShowRole" .Issue.ShowRole "IgnorePoster" true}}
|
||||
{{if not $.Repository.IsArchived}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
|
||||
{{end}}
|
||||
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}}
|
||||
</div>
|
||||
|
@ -67,7 +67,7 @@
|
|||
</div>
|
||||
{{$reactions := .Issue.Reactions.GroupByType}}
|
||||
{{if $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
{{if .ctxData.IsSigned}}
|
||||
{{if ctx.RootData.IsSigned}}
|
||||
<div class="item action ui dropdown jump pointing top right select-reaction" data-action-url="{{.ActionURL}}">
|
||||
<a class="add-reaction muted">
|
||||
{{svg "octicon-smiley"}}
|
||||
</a>
|
||||
<div class="menu reactions-menu">
|
||||
<a class="muted">{{svg "octicon-smiley"}}</a>
|
||||
<div class="menu">
|
||||
{{range $value := AllowedReactions}}
|
||||
<a class="item reaction" data-tooltip-content="{{$value}}" aria-label="{{$value}}" data-reaction-content="{{$value}}">{{ReactionToEmoji $value}}</a>
|
||||
<a class="item emoji comment-reaction-button" data-tooltip-content="{{$value}}" aria-label="{{$value}}" data-reaction-content="{{$value}}">{{ReactionToEmoji $value}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<div class="comment-header-right actions tw-flex tw-items-center">
|
||||
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
|
||||
{{if not $.Repository.IsArchived}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{end}}
|
||||
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
|
||||
</div>
|
||||
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
{{$reactions := .Reactions.GroupByType}}
|
||||
{{if $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -173,11 +173,11 @@
|
|||
<span class="text grey muted-links">
|
||||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{if and .AddedLabels (not .RemovedLabels)}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink) $createdStr}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels ctx ctx.Locale .AddedLabels $.RepoLink .Issue) $createdStr}}
|
||||
{{else if and (not .AddedLabels) .RemovedLabels}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink) $createdStr}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels ctx ctx.Locale .RemovedLabels $.RepoLink .Issue) $createdStr}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink) (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink) $createdStr}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels ctx ctx.Locale .AddedLabels $.RepoLink .Issue) (RenderLabels ctx ctx.Locale .RemovedLabels $.RepoLink .Issue) $createdStr}}
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -427,7 +427,7 @@
|
|||
<div class="comment-header-right actions tw-flex tw-items-center">
|
||||
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
|
||||
{{if not $.Repository.IsArchived}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -448,7 +448,7 @@
|
|||
</div>
|
||||
{{$reactions := .Reactions.GroupByType}}
|
||||
{{if $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
<div class="ui comments tw-mb-0">
|
||||
{{range .comments}}
|
||||
{{$createdSubStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
<div class="comment code-comment tw-pb-4" id="{{.HashTag}}">
|
||||
<div class="content">
|
||||
<div class="comment code-comment" id="{{.HashTag}}">
|
||||
<div class="content comment-container">
|
||||
<div class="header comment-header">
|
||||
<div class="comment-header-left tw-flex tw-items-center">
|
||||
{{if not .OriginalAuthor}}
|
||||
|
@ -82,7 +82,7 @@
|
|||
<div class="comment-header-right actions tw-flex tw-items-center">
|
||||
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
|
||||
{{if not $.Repository.IsArchived}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -103,7 +103,7 @@
|
|||
</div>
|
||||
{{$reactions := .Reactions.GroupByType}}
|
||||
{{if $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="ui attached segment reactions" data-action-url="{{$.ActionURL}}">
|
||||
<div class="bottom-reactions" data-action-url="{{$.ActionURL}}">
|
||||
{{range $key, $value := .Reactions}}
|
||||
{{$hasReacted := $value.HasUser $.ctxData.SignedUserID}}
|
||||
<a role="button" class="ui label basic{{if $hasReacted}} primary{{end}}{{if not $.ctxData.IsSigned}} disabled{{end}} comment-reaction-button"
|
||||
{{$hasReacted := $value.HasUser ctx.RootData.SignedUserID}}
|
||||
<a role="button" class="ui label basic{{if $hasReacted}} primary{{end}}{{if not ctx.RootData.IsSigned}} disabled{{end}} comment-reaction-button"
|
||||
data-tooltip-content
|
||||
title="{{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
|
||||
aria-label="{{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
|
||||
|
@ -12,6 +12,6 @@
|
|||
</a>
|
||||
{{end}}
|
||||
{{if AllowedReactions}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ctxData" $.ctxData "ActionURL" .ActionURL}}
|
||||
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" .ActionURL}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -572,7 +572,7 @@
|
|||
</form>
|
||||
{{end}}
|
||||
|
||||
<button class="tw-mt-1 fluid ui show-modal button {{if .Issue.IsLocked}} negative {{end}}" data-modal="#lock">
|
||||
<button class="tw-mt-1 fluid ui show-modal button{{if .Issue.IsLocked}} red{{end}}" data-modal="#lock">
|
||||
{{if .Issue.IsLocked}}
|
||||
{{svg "octicon-key"}}
|
||||
{{ctx.Locale.Tr "repo.issues.unlock"}}
|
||||
|
|
|
@ -25,12 +25,14 @@
|
|||
<div class="column">
|
||||
{{if gt .Activity.ActivePRCount 0}}
|
||||
<div class="stats-table">
|
||||
<a href="#merged-pull-requests" class="table-cell tiny background purple" style="width: {{.Activity.MergedPRPerc}}{{if ne .Activity.MergedPRPerc 0}}%{{end}}"></a>
|
||||
<a href="#proposed-pull-requests" class="table-cell tiny background green"></a>
|
||||
{{if gt .Activity.MergedPRPerc 0}}
|
||||
<a href="#merged-pull-requests" class="table-cell tiny tw-bg-purple" style="width: {{.Activity.MergedPRPerc}}%"></a>
|
||||
{{end}}
|
||||
<a href="#proposed-pull-requests" class="table-cell tiny tw-bg-green"></a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="stats-table">
|
||||
<a class="table-cell tiny background light grey"></a>
|
||||
<a class="table-cell tiny tw-bg-grey"></a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ctx.Locale.TrN .Activity.ActivePRCount "repo.activity.active_prs_count_1" "repo.activity.active_prs_count_n" .Activity.ActivePRCount}}
|
||||
|
@ -40,8 +42,10 @@
|
|||
<div class="column">
|
||||
{{if gt .Activity.ActiveIssueCount 0}}
|
||||
<div class="stats-table">
|
||||
<a href="#closed-issues" class="table-cell tiny background red" style="width: {{.Activity.ClosedIssuePerc}}{{if ne .Activity.ClosedIssuePerc 0}}%{{end}}"></a>
|
||||
<a href="#new-issues" class="table-cell tiny background green"></a>
|
||||
{{if gt .Activity.ClosedIssuePerc 0}}
|
||||
<a href="#closed-issues" class="table-cell tiny tw-bg-red" style="width: {{.Activity.ClosedIssuePerc}}%"></a>
|
||||
{{end}}
|
||||
<a href="#new-issues" class="table-cell tiny tw-bg-green"></a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="stats-table">
|
||||
|
@ -108,7 +112,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.PublishedReleaseCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="published-releases">
|
||||
<h4 class="divider divider-text" id="published-releases">
|
||||
{{svg "octicon-tag" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.Tr "repo.activity.title.releases_published_by"
|
||||
(ctx.Locale.TrN .Activity.PublishedReleaseCount "repo.activity.title.releases_1" "repo.activity.title.releases_n" .Activity.PublishedReleaseCount)
|
||||
|
@ -130,7 +134,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.MergedPRCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="merged-pull-requests">
|
||||
<h4 class="divider divider-text" id="merged-pull-requests">
|
||||
{{svg "octicon-git-pull-request" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.Tr "repo.activity.title.prs_merged_by"
|
||||
(ctx.Locale.TrN .Activity.MergedPRCount "repo.activity.title.prs_1" "repo.activity.title.prs_n" .Activity.MergedPRCount)
|
||||
|
@ -149,7 +153,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.OpenedPRCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="proposed-pull-requests">
|
||||
<h4 class="divider divider-text" id="proposed-pull-requests">
|
||||
{{svg "octicon-git-branch" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.Tr "repo.activity.title.prs_opened_by"
|
||||
(ctx.Locale.TrN .Activity.OpenedPRCount "repo.activity.title.prs_1" "repo.activity.title.prs_n" .Activity.OpenedPRCount)
|
||||
|
@ -168,7 +172,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.ClosedIssueCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="closed-issues">
|
||||
<h4 class="divider divider-text" id="closed-issues">
|
||||
{{svg "octicon-issue-closed" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.Tr "repo.activity.title.issues_closed_from"
|
||||
(ctx.Locale.TrN .Activity.ClosedIssueCount "repo.activity.title.issues_1" "repo.activity.title.issues_n" .Activity.ClosedIssueCount)
|
||||
|
@ -187,7 +191,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.OpenedIssueCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="new-issues">
|
||||
<h4 class="divider divider-text" id="new-issues">
|
||||
{{svg "octicon-issue-opened" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.Tr "repo.activity.title.issues_created_by"
|
||||
(ctx.Locale.TrN .Activity.OpenedIssueCount "repo.activity.title.issues_1" "repo.activity.title.issues_n" .Activity.OpenedIssueCount)
|
||||
|
@ -206,7 +210,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if gt .Activity.UnresolvedIssueCount 0}}
|
||||
<h4 class="divider divider-text tw-normal-case" id="unresolved-conversations" data-tooltip-content="{{ctx.Locale.Tr "repo.activity.unresolved_conv_desc"}}">
|
||||
<h4 class="divider divider-text" id="unresolved-conversations" data-tooltip-content="{{ctx.Locale.Tr "repo.activity.unresolved_conv_desc"}}">
|
||||
{{svg "octicon-comment-discussion" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.TrN .Activity.UnresolvedIssueCount "repo.activity.title.unresolved_conv_1" "repo.activity.title.unresolved_conv_n" .Activity.UnresolvedIssueCount}}
|
||||
</h4>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</p>
|
||||
<form class="ui form" action="{{$.Link}}/delete/{{.Oid}}" method="post">
|
||||
{{$.CsrfTokenHtml}}
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}}
|
||||
{{template "base/modal_actions_confirm"}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a {{if and .Exists .InRepo}}href="{{$.LFSFilesLink}}/show/{{.Oid}}" rel="nofollow" target="_blank"{{end}} title="{{.Oid}}" class="ui brown button tw-font-mono">
|
||||
<a {{if and .Exists .InRepo}}href="{{$.LFSFilesLink}}/show/{{.Oid}}" rel="nofollow" target="_blank"{{end}} title="{{.Oid}}" class="ui button tw-font-mono">
|
||||
{{ShortSha .Oid}}
|
||||
</a>
|
||||
</td>
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
<label for="interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label>
|
||||
<input id="interval" name="interval" value="{{.PullMirror.Interval}}">
|
||||
</div>
|
||||
{{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName false}}
|
||||
{{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName}}
|
||||
<div class="field {{if .Err_MirrorAddress}}error{{end}}">
|
||||
<label for="mirror_address">{{ctx.Locale.Tr "repo.mirror_address"}}</label>
|
||||
<input id="mirror_address" name="mirror_address" value="{{$address.Address}}" required>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="ui right">
|
||||
<!-- the button is wrapped with a span because the tooltip doesn't show on hover if we put data-tooltip-content directly on the button -->
|
||||
<span data-tooltip-content="{{if or $isNew .Webhook.IsActive}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc"}}{{else}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc_disabled"}}{{end}}">
|
||||
<button class="ui teal tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test" data-redirect="{{.Link}}">
|
||||
<button class="ui tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test" data-redirect="{{.Link}}">
|
||||
<span class="text">{{ctx.Locale.Tr "repo.settings.webhook.test_delivery"}}</span>
|
||||
</button>
|
||||
</span>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
{{template "base/head" .}}
|
||||
<div role="main" aria-label="{{.Title}}" class="page-content dashboard feeds">
|
||||
{{template "user/dashboard/navbar" .}}
|
||||
<div class="ui container">
|
||||
<div class="ui container flex-container">
|
||||
{{template "base/alert" .}}
|
||||
<div class="ui mobile reversed stackable grid">
|
||||
<div class="ui container ten wide column">
|
||||
{{template "user/heatmap" .}}
|
||||
{{template "user/dashboard/feeds" .}}
|
||||
</div>
|
||||
{{template "user/dashboard/repolist" .}}
|
||||
<div class="flex-container-main">
|
||||
{{template "user/heatmap" .}}
|
||||
{{template "user/dashboard/feeds" .}}
|
||||
</div>
|
||||
{{template "user/dashboard/repolist" .}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
@ -56,4 +56,4 @@ data.organizationId = {{.ContextUser.ID}};
|
|||
window.config.pageData.dashboardRepoList = data;
|
||||
</script>
|
||||
|
||||
<div id="dashboard-repo-list" class="six wide column"></div>
|
||||
<div id="dashboard-repo-list" class="flex-container-sidebar"></div>
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
<div class="content">
|
||||
<p>{{ctx.Locale.Tr "settings.access_token_deletion_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}}
|
||||
{{template "base/modal_actions_confirm"}}
|
||||
</div>
|
||||
|
||||
{{template "user/settings/layout_footer" .}}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
export default {
|
||||
exclude: [
|
||||
'@mcaptcha/vanilla-glue', // breaking changes in rc versions need to be handled
|
||||
'eslint', // need to migrate to eslint flat config first
|
||||
'eslint-plugin-array-func', // need to migrate to eslint flat config first
|
||||
'eslint-plugin-vitest', // need to migrate to eslint flat config first
|
||||
],
|
||||
};
|
||||
|
|
|
@ -319,27 +319,6 @@ a.label,
|
|||
background-color: var(--color-label-bg);
|
||||
}
|
||||
|
||||
.ui.menu {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ui.menu,
|
||||
.ui.vertical.menu {
|
||||
background: var(--color-menu);
|
||||
border-color: var(--color-secondary);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ui.menu .item {
|
||||
color: var(--color-text);
|
||||
user-select: auto;
|
||||
line-height: var(--line-height-default); /* fomantic uses "1" which causes overflow problems because "1" doesn't consider the descent part */
|
||||
}
|
||||
|
||||
.ui.menu .item > .svg {
|
||||
margin-right: 0.35em;
|
||||
}
|
||||
|
||||
.ui.menu .dropdown.item:hover,
|
||||
.ui.menu a.item:hover,
|
||||
.ui.menu details.item summary:hover {
|
||||
|
@ -347,42 +326,6 @@ a.label,
|
|||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
.ui.menu .active.item,
|
||||
.ui.menu .active.item:hover,
|
||||
.ui.vertical.menu .active.item,
|
||||
.ui.vertical.menu .active.item:hover {
|
||||
color: var(--color-text);
|
||||
background: var(--color-active);
|
||||
}
|
||||
|
||||
.ui.menu a.item:active {
|
||||
color: var(--color-text);
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ui.ui.menu .item.disabled {
|
||||
color: var(--color-text-light-3);
|
||||
}
|
||||
|
||||
.ui.menu .item::before, .ui.vertical.menu .item::before {
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
|
||||
/* sub menu of vertical menu */
|
||||
.ui.vertical.menu .item .menu .item {
|
||||
color: var(--color-text-light-2);
|
||||
text-indent: 16px;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu .item:hover,
|
||||
.ui.vertical.menu .item .menu a.item:hover {
|
||||
color: var(--color-text-light-1);
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu .active.item {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* slightly more contrast for filters on issue list */
|
||||
.ui.ui.menu .dropdown.item.disabled {
|
||||
color: var(--color-text-light-2);
|
||||
|
@ -441,11 +384,6 @@ a.label,
|
|||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown .menu > .selected.item {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-hover) !important;
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .message:not(.ui) {
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
@ -462,58 +400,6 @@ a.label,
|
|||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
||||
/* replace item margin on secondary menu items with gap and remove both the
|
||||
negative margins on the menu as well as margin on the items */
|
||||
.ui.secondary.menu {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
gap: .35714286em;
|
||||
}
|
||||
.ui.secondary.menu .item {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .dropdown.item:hover,
|
||||
.ui.secondary.menu a.item:hover {
|
||||
color: var(--color-text);
|
||||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
.ui.secondary.menu .active.item,
|
||||
.ui.secondary.menu .active.item:hover {
|
||||
color: var(--color-text);
|
||||
background: var(--color-active);
|
||||
}
|
||||
|
||||
.ui.secondary.menu.tight .item {
|
||||
padding-left: 0.85714286em;
|
||||
padding-right: 0.85714286em;
|
||||
}
|
||||
|
||||
/* remove the menu clearfix so that it won't add undesired gaps when using "gap" */
|
||||
.ui.menu::after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
.ui.menu .dropdown.item .menu {
|
||||
background: var(--color-body);
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown .menu > .item {
|
||||
color: var(--color-text) !important;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown .menu > .item:hover {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-hover) !important;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown .menu > .active.item {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-active) !important;
|
||||
}
|
||||
|
||||
.ui.form textarea:not([rows]) {
|
||||
height: var(--min-height-textarea); /* override fomantic default 12em */
|
||||
min-height: var(--min-height-textarea); /* override fomantic default 8em */
|
||||
|
@ -606,11 +492,6 @@ img.ui.avatar,
|
|||
margin-top: calc(var(--page-spacing) - 1rem);
|
||||
}
|
||||
|
||||
.ui.pagination.menu .active.item {
|
||||
color: var(--color-text);
|
||||
background: var(--color-active);
|
||||
}
|
||||
|
||||
.ui.form .fields.error .field textarea,
|
||||
.ui.form .fields.error .field select,
|
||||
.ui.form .fields.error .field input:not([type]),
|
||||
|
@ -782,11 +663,7 @@ input:-webkit-autofill:active,
|
|||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.ui.form .ui.button {
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
/* replace fomantic popover box shadows */
|
||||
/* popover box shadows */
|
||||
.ui.dropdown .menu,
|
||||
.ui.upward.dropdown > .menu,
|
||||
.ui.menu .dropdown.item .menu,
|
||||
|
@ -804,22 +681,6 @@ input:-webkit-autofill:active,
|
|||
background: var(--color-overlay-backdrop);
|
||||
}
|
||||
|
||||
/* Override semantic selector '.ui.menu:not(.vertical) .item > .button' */
|
||||
/* This fixes the commit graph button on the commits page */
|
||||
/* modal svg icons, copied from fomantic except width and height */
|
||||
/* center text in fomantic modal dialogs */
|
||||
.ui .menu:not(.vertical) .item > .button.compact {
|
||||
padding: 0.58928571em 1.125em;
|
||||
}
|
||||
|
||||
.ui .menu:not(.vertical) .item > .button.small {
|
||||
font-size: 0.92857143rem;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown.item .menu .item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .header {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
@ -1010,24 +871,6 @@ input:-webkit-autofill:active,
|
|||
border-color: var(--color-gold) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.ui.pagination.menu .item:not(.active,.navigation),
|
||||
.ui.pagination.menu .item.navigation span.navigation_label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui.pagination.menu.narrow .item {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
min-width: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ui.pagination.menu.narrow .item .icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ui.floating.dropdown .overflow.menu .scrolling.menu.items {
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
|
@ -1149,11 +992,6 @@ overflow-menu .ui.label {
|
|||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.ui.menu .item > .label {
|
||||
background: var(--color-label-bg);
|
||||
color: var(--color-label-text);
|
||||
}
|
||||
|
||||
.lines-blame-btn {
|
||||
padding: 0 0 0 5px;
|
||||
display: flex;
|
||||
|
@ -1366,8 +1204,7 @@ table th[data-sortt-desc] .svg {
|
|||
box-shadow: 0 0 0 1px var(--color-secondary) inset;
|
||||
}
|
||||
|
||||
.emoji,
|
||||
.reaction {
|
||||
.emoji {
|
||||
font-size: 1.25em;
|
||||
line-height: var(--line-height-default);
|
||||
font-style: normal !important;
|
||||
|
@ -1375,8 +1212,7 @@ table th[data-sortt-desc] .svg {
|
|||
vertical-align: -0.075em;
|
||||
}
|
||||
|
||||
.emoji img,
|
||||
.reaction img {
|
||||
.emoji img {
|
||||
border-width: 0 !important;
|
||||
margin: 0 !important;
|
||||
width: 1em !important;
|
||||
|
@ -1384,26 +1220,6 @@ table th[data-sortt-desc] .svg {
|
|||
vertical-align: -0.15em;
|
||||
}
|
||||
|
||||
.ui.tabular.menu {
|
||||
border-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.ui.tabular.menu .active.item,
|
||||
.ui.tabular.menu .active.item:hover {
|
||||
background: var(--color-body);
|
||||
border-color: var(--color-secondary);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui.segment .ui.tabular.menu .active.item,
|
||||
.ui.segment .ui.tabular.menu .active.item:hover {
|
||||
background: var(--color-box-body);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu {
|
||||
border-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.ui.tabular.menu .item,
|
||||
.ui.secondary.pointing.menu .item {
|
||||
padding: 11.55px 12px !important; /* match .dashboard-navbar in height */
|
||||
|
@ -1415,12 +1231,6 @@ table th[data-sortt-desc] .svg {
|
|||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .active.item,
|
||||
.ui.secondary.pointing.menu .active.item:hover,
|
||||
.ui.secondary.pointing.menu .dropdown.item:hover {
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.ui.tabular.menu .active.item,
|
||||
.ui.secondary.pointing.menu .active.item,
|
||||
.resize-for-semibold::before {
|
||||
|
@ -1531,10 +1341,7 @@ table th[data-sortt-desc] .svg {
|
|||
align-items: center;
|
||||
gap: .25rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ui.ui.button {
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.ui.dropdown .ui.label .svg {
|
||||
|
@ -1551,6 +1358,7 @@ table th[data-sortt-desc] .svg {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
gap: .25rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* to override Fomantic's default display: block for ".menu .item", and use a slightly larger gap for menu item content */
|
||||
|
@ -1558,4 +1366,5 @@ table th[data-sortt-desc] .svg {
|
|||
display: flex !important;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
.dashboard.feeds .context.user.menu .ui.header,
|
||||
.dashboard.issues .context.user.menu .ui.header {
|
||||
font-size: 1rem;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.dashboard.feeds .filter.menu,
|
||||
|
|
|
@ -52,6 +52,9 @@ only use:
|
|||
*/
|
||||
.tw-hidden.tw-hidden { display: none !important; }
|
||||
|
||||
/* proposed class from https://github.com/tailwindlabs/tailwindcss/pull/12128 */
|
||||
.tw-break-anywhere { overflow-wrap: anywhere !important; }
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
/* double selector so it wins over .tw-flex (old .gt-df) etc */
|
||||
.not-mobile.not-mobile {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
@import "./modules/list.css";
|
||||
@import "./modules/segment.css";
|
||||
@import "./modules/grid.css";
|
||||
@import "./modules/menu.css";
|
||||
@import "./modules/message.css";
|
||||
@import "./modules/table.css";
|
||||
@import "./modules/card.css";
|
||||
|
@ -62,6 +63,7 @@
|
|||
@import "./repo/linebutton.css";
|
||||
@import "./repo/wiki.css";
|
||||
@import "./repo/header.css";
|
||||
@import "./repo/reactions.css";
|
||||
|
||||
@import "./editor/fileeditor.css";
|
||||
@import "./editor/combomarkdowneditor.css";
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,7 @@
|
|||
.ui.comments .comment {
|
||||
position: relative;
|
||||
background: none;
|
||||
margin: 0.5em 0 0;
|
||||
margin: 3px 0 0;
|
||||
padding: 0.5em 0 0;
|
||||
border: none;
|
||||
border-top: none;
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
margin: 10px 0;
|
||||
height: 0;
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text);
|
||||
font-size: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h4.divider {
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.divider:not(.divider-text) {
|
||||
border-top: 1px solid var(--color-secondary);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
margin-top: var(--page-spacing);
|
||||
}
|
||||
|
||||
/* small options menu on the left, used in settings/admin pages */
|
||||
.flex-container-nav {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
/* wide sidebar on the right, used in frontpage */
|
||||
.flex-container-sidebar {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.flex-container-main {
|
||||
flex: 1;
|
||||
min-width: 0; /* make the "text truncate" work, otherwise the flex axis is not limited and the text just overflows */
|
||||
|
@ -19,7 +25,9 @@
|
|||
.flex-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex-container-nav {
|
||||
.flex-container-nav,
|
||||
.flex-container-sidebar {
|
||||
order: -1;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
font-family: var(--fonts-regular);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.28571429;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.ui.header:first-child {
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .25rem;
|
||||
min-width: 0;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
background: var(--color-label-bg);
|
||||
color: var(--color-label-text);
|
||||
padding: 0.3em 0.5em;
|
||||
text-transform: none;
|
||||
font-size: 0.85714286rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
border: 0 solid transparent;
|
||||
|
|
|
@ -0,0 +1,802 @@
|
|||
.ui.menu {
|
||||
display: flex;
|
||||
margin: 1rem 0;
|
||||
font-family: var(--fonts-regular);
|
||||
font-weight: var(--font-weight-normal);
|
||||
background: var(--color-menu);
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-radius: 0.28571429rem;
|
||||
min-height: 2.85714286em;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.ui.menu:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.ui.menu:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ui.menu .menu {
|
||||
margin: 0;
|
||||
}
|
||||
.ui.menu:not(.vertical) > .menu {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ui.menu:not(.vertical) .item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ui.menu .item {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
line-height: var(--line-height-default);
|
||||
text-decoration: none;
|
||||
flex: 0 0 auto;
|
||||
background: none;
|
||||
padding: 0.92857143em 1.14285714em;
|
||||
color: var(--color-text);
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
.ui.menu > .item:first-child {
|
||||
border-radius: 0.28571429rem 0 0 0.28571429rem;
|
||||
}
|
||||
|
||||
.ui.menu .item::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
|
||||
.ui.menu .item > .svg {
|
||||
margin-right: 0.35em;
|
||||
}
|
||||
|
||||
.ui.menu .item > a:not(.ui),
|
||||
.ui.menu .item > p:only-child {
|
||||
line-height: 1.3;
|
||||
}
|
||||
.ui.menu .item > p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.ui.menu .item > p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ui.menu .item > i.icon {
|
||||
opacity: 0.9;
|
||||
float: none;
|
||||
margin: 0 0.35714286em 0 0;
|
||||
}
|
||||
|
||||
.ui.menu:not(.vertical) .item > .button {
|
||||
position: relative;
|
||||
top: 0;
|
||||
margin: -0.5em 0;
|
||||
padding: 0.58928571em 1.125em;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.ui.menu > .grid,
|
||||
.ui.menu > .container {
|
||||
display: flex;
|
||||
align-items: inherit;
|
||||
flex-direction: inherit;
|
||||
}
|
||||
|
||||
.ui.menu .item > .input {
|
||||
width: 100%;
|
||||
}
|
||||
.ui.menu:not(.vertical) .item > .input {
|
||||
position: relative;
|
||||
top: 0;
|
||||
margin: -0.5em 0;
|
||||
}
|
||||
.ui.menu .item > .input input {
|
||||
font-size: 1em;
|
||||
padding-top: 0.57142857em;
|
||||
padding-bottom: 0.57142857em;
|
||||
}
|
||||
|
||||
.ui.menu .header.item,
|
||||
.ui.vertical.menu .header.item {
|
||||
margin: 0;
|
||||
font-size: 1.1em;
|
||||
background: var(--color-box-header);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
.ui.vertical.menu .item > .header:not(.ui) {
|
||||
margin: 0 0 0.5em;
|
||||
font-size: 1em;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.ui.menu .item > i.dropdown.icon {
|
||||
padding: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.ui.menu .dropdown.item .menu {
|
||||
min-width: calc(100% - 1px);
|
||||
border-radius: 0 0 0.28571429rem 0.28571429rem;
|
||||
background: var(--color-body);
|
||||
margin: 0;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown .menu > .item {
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
font-size: 1em !important;
|
||||
padding: 0.78571429em 1.14285714em !important;
|
||||
background: transparent !important;
|
||||
color: var(--color-text) !important;
|
||||
font-weight: var(--font-weight-normal) !important;
|
||||
}
|
||||
.ui.menu .ui.dropdown .menu > .item:hover {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-hover) !important;
|
||||
}
|
||||
.ui.menu .ui.dropdown .menu > .selected.item {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-hover) !important;
|
||||
}
|
||||
.ui.menu .ui.dropdown .menu > .active.item {
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-active) !important;
|
||||
font-weight: var(--font-weight-medium) !important;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown.item .menu .item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui.menu .ui.dropdown.item .menu .item:not(.filtered) {
|
||||
display: block;
|
||||
}
|
||||
.ui.menu .ui.dropdown .menu > .item > i.icon:not(.dropdown) {
|
||||
display: inline-block;
|
||||
font-size: 1em !important;
|
||||
float: none;
|
||||
margin: 0 0.75em 0 0 !important;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .dropdown.item > .menu {
|
||||
border-radius: 0.28571429rem;
|
||||
margin-top: 0.35714286em;
|
||||
}
|
||||
|
||||
.ui.menu .pointing.dropdown.item .menu {
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
|
||||
.ui.menu .item > .label:not(.floating) {
|
||||
margin-left: 1em;
|
||||
padding: 0.3em 0.78571429em;
|
||||
}
|
||||
.ui.vertical.menu .item > .label {
|
||||
margin-top: -0.15em;
|
||||
margin-bottom: -0.15em;
|
||||
padding: 0.3em 0.78571429em;
|
||||
float: right;
|
||||
text-align: center;
|
||||
}
|
||||
.ui.menu .item > .floating.label {
|
||||
padding: 0.3em 0.78571429em;
|
||||
}
|
||||
.ui.menu .item > .label {
|
||||
background: var(--color-label-bg);
|
||||
color: var(--color-label-text);
|
||||
}
|
||||
.ui.menu .item > .image.label img {
|
||||
margin: -0.2833em 0.8em -0.2833em -0.8em;
|
||||
height: 1.5666em;
|
||||
}
|
||||
|
||||
.ui.menu .item > img:not(.ui) {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: -0.3em 0;
|
||||
width: 2.5em;
|
||||
}
|
||||
.ui.vertical.menu .item > img:not(.ui):only-child {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.ui.menu .list .item::before {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.ui.menu > .ui.container {
|
||||
width: 100% !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ui.menu .dropdown.item:hover,
|
||||
.ui.menu a.item:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui.menu a.item:active {
|
||||
color: var(--color-text);
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ui.menu .active.item {
|
||||
color: var(--color-text);
|
||||
background: var(--color-active);
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
.ui.menu .active.item > i.icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ui.ui.menu .item.disabled {
|
||||
cursor: default;
|
||||
background-color: transparent;
|
||||
pointer-events: none;
|
||||
opacity: var(--opacity-disabled);
|
||||
}
|
||||
|
||||
.ui.menu:not(.vertical) .left.item,
|
||||
.ui.menu:not(.vertical) .left.menu {
|
||||
display: flex;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
.ui.menu:not(.vertical) .right.item,
|
||||
.ui.menu:not(.vertical) .right.menu {
|
||||
display: flex;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
.ui.menu:not(.vertical) :not(.dropdown) > .left.menu,
|
||||
.ui.menu:not(.vertical) :not(.dropdown) > .right.menu {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.ui.menu:not(.vertical) .center.item {
|
||||
display: flex;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
.ui.menu .right.item::before,
|
||||
.ui.menu .right.menu > .item::before {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ui.menu .center.item:last-child::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.vertical.menu {
|
||||
display: block;
|
||||
flex-direction: column;
|
||||
background: var(--color-menu);
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item {
|
||||
display: block;
|
||||
background: none;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
}
|
||||
.ui.vertical.menu > .item:first-child {
|
||||
border-radius: 0.28571429rem 0.28571429rem 0 0;
|
||||
}
|
||||
.ui.vertical.menu > .item:last-child {
|
||||
border-radius: 0 0 0.28571429rem 0.28571429rem;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item > i.icon {
|
||||
width: 1.18em;
|
||||
float: right;
|
||||
margin: 0 0 0 0.5em;
|
||||
}
|
||||
.ui.vertical.menu .item > .label + i.icon {
|
||||
float: none;
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
.ui.vertical.menu .item:first-child::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item > .menu {
|
||||
margin: 0.5em -1.14285714em 0;
|
||||
}
|
||||
.ui.vertical.menu .menu .item {
|
||||
background: none;
|
||||
padding: 0.5em 1.33333333em;
|
||||
font-size: 0.85714286em;
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu .item {
|
||||
color: var(--color-text-light-2);
|
||||
text-indent: 16px;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu .item:hover,
|
||||
.ui.vertical.menu .item .menu a.item:hover {
|
||||
color: var(--color-text-light-1);
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu .active.item {
|
||||
background-color: transparent;
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui.vertical.menu .item .menu a.item:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
.ui.vertical.menu .menu .item::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .active.item {
|
||||
border-radius: 0;
|
||||
}
|
||||
.ui.vertical.menu > .active.item:first-child {
|
||||
border-radius: 0.28571429rem 0.28571429rem 0 0;
|
||||
}
|
||||
.ui.vertical.menu > .active.item:last-child {
|
||||
border-radius: 0 0 0.28571429rem 0.28571429rem;
|
||||
}
|
||||
.ui.vertical.menu > .active.item:only-child {
|
||||
border-radius: 0.28571429rem;
|
||||
}
|
||||
.ui.vertical.menu .active.item .menu .active.item {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.ui.tabular.menu {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: none transparent;
|
||||
border-bottom: 1px solid var(--color-secondary);
|
||||
}
|
||||
.ui.tabular.fluid.menu {
|
||||
width: calc(100% + 2px) !important;
|
||||
}
|
||||
.ui.tabular.menu .item {
|
||||
background: transparent;
|
||||
border-bottom: none;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
border-top: 2px solid transparent;
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
.ui.tabular.menu .item::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.tabular.menu .item:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.ui.tabular.menu .active.item,
|
||||
.ui.tabular.menu .active.item:hover {
|
||||
background: var(--color-body);
|
||||
border-top-width: 1px;
|
||||
border-color: var(--color-secondary);
|
||||
font-weight: var(--font-weight-medium);
|
||||
margin-bottom: -1px;
|
||||
border-radius: 0.28571429rem 0.28571429rem 0 0 !important;
|
||||
}
|
||||
|
||||
.ui.tabular.menu + .attached:not(.top).segment,
|
||||
.ui.tabular.menu + .attached:not(.top).segment + .attached:not(.top).segment {
|
||||
border-top: none;
|
||||
margin-left: 0;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui.tabular.menu .active.dropdown.item {
|
||||
margin-bottom: 0;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
border-top: 2px solid transparent;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.ui.pagination.menu {
|
||||
margin: 0;
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ui.pagination.menu .item:last-child {
|
||||
border-radius: 0 0.28571429rem 0.28571429rem 0;
|
||||
}
|
||||
.ui.compact.menu .item:last-child {
|
||||
border-radius: 0 0.28571429rem 0.28571429rem 0;
|
||||
}
|
||||
.ui.pagination.menu .item:last-child::before {
|
||||
display: none;
|
||||
}
|
||||
.ui.pagination.menu .item {
|
||||
min-width: 3em;
|
||||
text-align: center;
|
||||
}
|
||||
.ui.pagination.menu .icon.item i.icon {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.ui.pagination.menu .active.item,
|
||||
.ui.pagination.menu .active.item:hover {
|
||||
border-top: none;
|
||||
padding-top: 0.92857143em;
|
||||
color: var(--color-text);
|
||||
background: var(--color-active);
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.ui.pagination.menu .item:not(.active,.navigation),
|
||||
.ui.pagination.menu .item.navigation span.navigation_label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui.pagination.menu.narrow .item {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
min-width: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ui.pagination.menu.narrow .item .icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ui.secondary.menu {
|
||||
background: none;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
gap: .35714286em;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .item {
|
||||
align-self: center;
|
||||
border: none;
|
||||
padding: 0.78571429em 0.92857143em;
|
||||
margin: 0;
|
||||
background: none;
|
||||
border-radius: 0.28571429rem;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .item::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .header.item {
|
||||
border-radius: 0;
|
||||
border-right: none;
|
||||
background: none transparent;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .item > img:not(.ui) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ui.secondary.menu .dropdown.item:hover,
|
||||
.ui.secondary.menu a.item:hover {
|
||||
color: var(--color-text);
|
||||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
.ui.secondary.menu .active.item,
|
||||
.ui.secondary.menu .active.item:hover {
|
||||
color: var(--color-text-dark);
|
||||
background: var(--color-active);
|
||||
border-radius: 0.28571429rem;
|
||||
}
|
||||
|
||||
.ui.secondary.item.menu {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.ui.secondary.item.menu .item:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ui.vertical.secondary.menu .item:not(.dropdown) > .menu {
|
||||
margin: 0 -0.92857143em;
|
||||
}
|
||||
.ui.vertical.secondary.menu .item:not(.dropdown) > .menu > .item {
|
||||
margin: 0;
|
||||
padding: 0.5em 1.33333333em;
|
||||
}
|
||||
.ui.secondary.vertical.menu > .item {
|
||||
border: none;
|
||||
margin: 0 0 0.35714286em;
|
||||
border-radius: 0.28571429rem !important;
|
||||
}
|
||||
.ui.secondary.vertical.menu > .header.item {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.ui.vertical.secondary.menu .item > .menu .item {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
border-bottom: 2px solid var(--color-secondary);
|
||||
}
|
||||
.ui.secondary.pointing.menu .item {
|
||||
border-bottom-color: transparent;
|
||||
border-bottom-style: solid;
|
||||
border-radius: 0;
|
||||
align-self: flex-end;
|
||||
margin: 0 0 -2px;
|
||||
padding: 0.85714286em 1.14285714em;
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
.ui.secondary.pointing.menu .ui.dropdown .menu .item {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
.ui.secondary.pointing.menu .item > .label:not(.floating) {
|
||||
margin-top: -0.3em;
|
||||
margin-bottom: -0.3em;
|
||||
}
|
||||
.ui.secondary.pointing.menu .item > .circular.label {
|
||||
margin-top: -0.5em;
|
||||
margin-bottom: -0.5em;
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .header.item {
|
||||
color: var(--color-text) !important;
|
||||
}
|
||||
.ui.secondary.pointing.menu .item::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .dropdown.item:hover,
|
||||
.ui.secondary.pointing.menu a.item:hover {
|
||||
background-color: transparent;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .dropdown.item:active,
|
||||
.ui.secondary.pointing.menu a.item:active {
|
||||
background-color: transparent;
|
||||
border-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .active.item {
|
||||
background-color: transparent;
|
||||
border-color: currentcolor;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .active.item,
|
||||
.ui.secondary.pointing.menu .active.item:hover,
|
||||
.ui.secondary.pointing.menu .dropdown.item:hover {
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.ui.secondary.pointing.menu .active.dropdown.item {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.ui.stackable.menu {
|
||||
flex-direction: column;
|
||||
}
|
||||
.ui.stackable.menu .item {
|
||||
width: 100% !important;
|
||||
}
|
||||
.ui.stackable.menu .left.menu,
|
||||
.ui.stackable.menu .left.item {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.ui.stackable.menu .right.menu,
|
||||
.ui.stackable.menu .right.item {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.ui.stackable.menu .center.item {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.ui.stackable.menu .right.menu,
|
||||
.ui.stackable.menu .left.menu {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.ui.floated.menu {
|
||||
float: left;
|
||||
margin: 0 0.5rem 0 0;
|
||||
}
|
||||
.ui.floated.menu .item:last-child::before {
|
||||
display: none;
|
||||
}
|
||||
.ui.right.floated.menu {
|
||||
float: right;
|
||||
margin: 0 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.ui.borderless.menu .item::before,
|
||||
.ui.borderless.menu .item .menu .item::before,
|
||||
.ui.menu .borderless.item::before {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.ui.compact.menu {
|
||||
display: inline-flex;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ui.compact.vertical.menu {
|
||||
display: inline-block;
|
||||
width: auto !important;
|
||||
}
|
||||
.ui.compact.menu:not(.secondary) .item:last-child {
|
||||
border-radius: 0 0.28571429rem 0.28571429rem 0;
|
||||
}
|
||||
.ui.compact.menu .item:last-child::before {
|
||||
display: none;
|
||||
}
|
||||
.ui.compact.vertical.menu .item:last-child::before {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui.menu.fluid,
|
||||
.ui.vertical.menu.fluid {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.ui.item.menu,
|
||||
.ui.item.menu .item {
|
||||
width: 100%;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.ui.attached.item.menu:not(.tabular) {
|
||||
margin: 0 -1px !important;
|
||||
}
|
||||
.ui.item.menu .item:last-child::before {
|
||||
display: none;
|
||||
}
|
||||
.ui.menu.two.item .item {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.ui.pointing.menu .item::after {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%) rotate(45deg);
|
||||
background: none;
|
||||
margin: 0.5px 0 0;
|
||||
width: 0.57142857em;
|
||||
height: 0.57142857em;
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--color-secondary);
|
||||
border-right: 1px solid var(--color-secondary);
|
||||
z-index: 2;
|
||||
}
|
||||
.ui.pointing.menu .ui.dropdown .menu .item::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.pointing.menu .active.item::after {
|
||||
visibility: visible;
|
||||
}
|
||||
.ui.pointing.menu .active.dropdown.item::after {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.ui.pointing.menu .dropdown.active.item::after,
|
||||
.ui.pointing.menu .active.item .menu .active.item::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui.pointing.menu .active.item::after,
|
||||
.ui.pointing.menu .active.item:hover::after {
|
||||
background-color: var(--color-active);
|
||||
}
|
||||
|
||||
.ui.attached.menu {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-radius: 0;
|
||||
margin: 0 -1px;
|
||||
width: calc(100% + 2px);
|
||||
max-width: calc(100% + 2px);
|
||||
}
|
||||
.ui.attached + .ui.attached.menu:not(.top) {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.ui[class*="top attached"].menu {
|
||||
bottom: 0;
|
||||
margin-bottom: 0;
|
||||
top: 0;
|
||||
margin-top: 1rem;
|
||||
border-radius: 0.28571429rem 0.28571429rem 0 0;
|
||||
}
|
||||
.ui.menu[class*="top attached"]:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.ui.top.attached.menu > .item:first-child {
|
||||
border-radius: 0.28571429rem 0 0;
|
||||
}
|
||||
|
||||
.ui.attached.menu:not(.tabular) {
|
||||
border: 1px solid var(--color-secondary);
|
||||
}
|
||||
.ui.attached.tabular.menu {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui.mini.menu,
|
||||
.ui.mini.menu .dropdown,
|
||||
.ui.mini.menu .dropdown .menu > .item {
|
||||
font-size: 0.78571429rem;
|
||||
}
|
||||
.ui.mini.vertical.menu:not(.icon) {
|
||||
width: 9rem;
|
||||
}
|
||||
.ui.tiny.menu,
|
||||
.ui.tiny.menu .dropdown,
|
||||
.ui.tiny.menu .dropdown .menu > .item {
|
||||
font-size: 0.85714286rem;
|
||||
}
|
||||
.ui.tiny.vertical.menu:not(.icon) {
|
||||
width: 11rem;
|
||||
}
|
||||
.ui.small.menu,
|
||||
.ui.small.menu .dropdown,
|
||||
.ui.small.menu .dropdown .menu > .item {
|
||||
font-size: 0.92857143rem;
|
||||
}
|
||||
.ui.small.vertical.menu:not(.icon) {
|
||||
width: 13rem;
|
||||
}
|
||||
|
||||
.ui .menu:not(.vertical) .item > .button.small {
|
||||
font-size: 0.92857143rem;
|
||||
}
|
||||
|
||||
.ui.segment .ui.tabular.menu .active.item,
|
||||
.ui.segment .ui.tabular.menu .active.item:hover {
|
||||
background: var(--color-box-body);
|
||||
}
|
|
@ -10,6 +10,10 @@
|
|||
top: 1.2em;
|
||||
}
|
||||
|
||||
.ui.modal > .close.inside {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.ui.modal > .close.icon[height="16"] {
|
||||
top: 0.7em; /* fomantic uses absolute layout, so if we have special icon size, it needs this trick to align vertically */
|
||||
color: var(--color-text-dark);
|
||||
|
|
|
@ -654,15 +654,15 @@ td .commit-summary {
|
|||
padding: 2px .5rem;
|
||||
}
|
||||
|
||||
.repository.view.issue .issue-title .index {
|
||||
.issue-title .index {
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
||||
.repository.view.issue .issue-title .label {
|
||||
.issue-title .label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.repository.view.issue .issue-title .edit-zone {
|
||||
.issue-title .edit-zone {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
@ -913,6 +913,9 @@ td .commit-summary {
|
|||
|
||||
.repository.view.issue .comment-list .ui.comments {
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment > .content > div:first-child {
|
||||
|
@ -928,6 +931,11 @@ td .commit-summary {
|
|||
.repository.view.issue .comment-list .comment .comment-container {
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
background: var(--color-box-body);
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .conversation-holder .comment .comment-container {
|
||||
border: none;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
|
@ -1042,30 +1050,6 @@ td .commit-summary {
|
|||
margin-left: 42px;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment-code-cloud .segment.reactions {
|
||||
margin-top: 16px !important;
|
||||
margin-bottom: -8px !important;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label {
|
||||
border: 1px solid;
|
||||
padding: 5px 8px !important;
|
||||
margin: 0 2px;
|
||||
border-radius: var(--border-radius);
|
||||
border-color: var(--color-secondary-dark-1) !important;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label.basic.primary {
|
||||
background-color: var(--color-reaction-active-bg) !important;
|
||||
border-color: var(--color-primary-alpha-80) !important;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label.basic.primary:hover {
|
||||
background-color: var(--color-reaction-hover-bg) !important;
|
||||
border-color: var(--color-primary-alpha-80) !important;
|
||||
}
|
||||
|
||||
.repository.view.issue .comment-list .comment-code-cloud button.comment-form-reply {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -1180,14 +1164,6 @@ td .commit-summary {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
.repository.compare.pull .title .issue-title {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.repository.compare.pull .title .issue-title .index {
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
||||
.repository .ui.dropdown.filter > .menu {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
@ -1902,98 +1878,6 @@ td .commit-summary {
|
|||
border-bottom: 1px solid var(--color-warning-border);
|
||||
}
|
||||
|
||||
.repository .segment.reactions.dropdown .menu,
|
||||
.repository .select-reaction.dropdown .menu {
|
||||
right: 0 !important;
|
||||
left: auto !important;
|
||||
min-width: 170px;
|
||||
}
|
||||
|
||||
.repository .segment.reactions.dropdown .menu > .header,
|
||||
.repository .select-reaction.dropdown .menu > .header {
|
||||
margin: 0.75rem 0 0.5rem;
|
||||
}
|
||||
|
||||
.repository .segment.reactions.dropdown .menu > .item,
|
||||
.repository .select-reaction.dropdown .menu > .item {
|
||||
float: left;
|
||||
margin: 4px;
|
||||
font-size: 20px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
min-height: 0 !important;
|
||||
border-radius: var(--border-radius);
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.repository .segment.reactions {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
border: none !important;
|
||||
border-top: 1px solid var(--color-secondary) !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||
}
|
||||
|
||||
.repository .segment.reactions .ui.label {
|
||||
max-height: 40px;
|
||||
padding: 8px 16px !important;
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
border-right: 1px solid;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
font-weight: var(--font-weight-normal);
|
||||
border-color: var(--color-secondary) !important;
|
||||
background: var(--color-reaction-bg);
|
||||
}
|
||||
|
||||
.repository .segment.reactions .ui.label:first-of-type {
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .ui.label.disabled {
|
||||
cursor: default;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .ui.label.basic.primary {
|
||||
color: var(--color-primary) !important;
|
||||
background-color: var(--color-reaction-active-bg) !important;
|
||||
border-color: var(--color-secondary-dark-1) !important;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .ui.label.basic:hover {
|
||||
background-color: var(--color-reaction-hover-bg) !important;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .reaction-count {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .select-reaction {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .select-reaction a {
|
||||
padding: 0 14px;
|
||||
}
|
||||
|
||||
.repository .segment.reactions .select-reaction:not(.active) a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.repository .segment.reactions:hover .select-reaction a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.repository .ui.fluid.action.input .ui.search.action.input {
|
||||
flex: auto;
|
||||
}
|
||||
|
@ -2187,11 +2071,6 @@ td .commit-summary {
|
|||
padding: 10px 0 0;
|
||||
}
|
||||
|
||||
.ui.vertical.menu .header.item {
|
||||
font-size: 1.1em;
|
||||
background: var(--color-box-header);
|
||||
}
|
||||
|
||||
.comment:target .comment-container {
|
||||
border-color: var(--color-primary) !important;
|
||||
box-shadow: 0 0 0 3px var(--color-primary-alpha-30) !important;
|
||||
|
@ -2304,6 +2183,8 @@ td .commit-summary {
|
|||
.stats-table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin: 6px 0;
|
||||
border-spacing: 2px;
|
||||
}
|
||||
|
||||
.stats-table .table-cell {
|
||||
|
@ -2311,7 +2192,17 @@ td .commit-summary {
|
|||
}
|
||||
|
||||
.stats-table .table-cell.tiny {
|
||||
height: 0.5em;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.stats-table .table-cell:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
.stats-table .table-cell:last-child {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
.labels-list {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
.bottom-reactions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin: 0 1em 1em;
|
||||
}
|
||||
|
||||
.timeline-item .conversation-holder .bottom-reactions {
|
||||
margin: 1em 0 0 36px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label {
|
||||
padding: 5px 8px;
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label.primary {
|
||||
background-color: var(--color-reaction-active-bg) !important;
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label:hover {
|
||||
background-color: var(--color-reaction-hover-bg) !important;
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label.disabled {
|
||||
cursor: default;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label .reaction {
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bottom-reactions .ui.label .reaction img {
|
||||
height: 16px;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.bottom-reactions .reaction-count {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.ui.dropdown.select-reaction .menu {
|
||||
min-width: 170px; /* item-outer-width * 4 */
|
||||
}
|
||||
|
||||
.ui.dropdown.select-reaction .menu > .item {
|
||||
float: left;
|
||||
margin: 4px;
|
||||
font-size: 20px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: var(--border-radius);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bottom-reactions .select-reaction {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.bottom-reactions .select-reaction:not(.active) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.bottom-reactions:hover .select-reaction {
|
||||
visibility: visible;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -22,11 +22,9 @@
|
|||
"admin": false,
|
||||
"components": [
|
||||
"api",
|
||||
"button",
|
||||
"dimmer",
|
||||
"dropdown",
|
||||
"form",
|
||||
"menu",
|
||||
"modal",
|
||||
"search",
|
||||
"tab"
|
||||
|
|
|
@ -138,7 +138,7 @@ export default {
|
|||
|
||||
<div v-if="!showActionForm" class="tw-flex">
|
||||
<!-- the merge button -->
|
||||
<div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'primary' : 'red']" @click="toggleActionForm(true)">
|
||||
<div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? '' : mergeForm.allOverridableChecksOk ? 'primary' : 'red']" @click="toggleActionForm(true)">
|
||||
<button class="ui button">
|
||||
<svg-icon name="octicon-git-merge"/>
|
||||
<span class="button-text">
|
||||
|
|
|
@ -1,38 +1,36 @@
|
|||
import $ from 'jquery';
|
||||
import {POST} from '../../modules/fetch.js';
|
||||
|
||||
export function initCompReactionSelector($parent) {
|
||||
$parent.find(`.select-reaction .item.reaction, .comment-reaction-button`).on('click', async function (e) {
|
||||
e.preventDefault();
|
||||
export function initCompReactionSelector() {
|
||||
for (const container of document.querySelectorAll('.issue-content, .diff-file-body')) {
|
||||
container.addEventListener('click', async (e) => {
|
||||
// there are 2 places for the "reaction" buttons, one is the top-right reaction menu, one is the bottom of the comment
|
||||
const target = e.target.closest('.comment-reaction-button');
|
||||
if (!target) return;
|
||||
e.preventDefault();
|
||||
|
||||
if (this.classList.contains('disabled')) return;
|
||||
if (target.classList.contains('disabled')) return;
|
||||
|
||||
const actionUrl = this.closest('[data-action-url]')?.getAttribute('data-action-url');
|
||||
const reactionContent = this.getAttribute('data-reaction-content');
|
||||
const hasReacted = this.closest('.ui.segment.reactions')?.querySelector(`a[data-reaction-content="${reactionContent}"]`)?.getAttribute('data-has-reacted') === 'true';
|
||||
const actionUrl = target.closest('[data-action-url]').getAttribute('data-action-url');
|
||||
const reactionContent = target.getAttribute('data-reaction-content');
|
||||
|
||||
const res = await POST(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, {
|
||||
data: new URLSearchParams({content: reactionContent}),
|
||||
const commentContainer = target.closest('.comment-container');
|
||||
|
||||
const bottomReactions = commentContainer.querySelector('.bottom-reactions'); // may not exist if there is no reaction
|
||||
const bottomReactionBtn = bottomReactions?.querySelector(`a[data-reaction-content="${CSS.escape(reactionContent)}"]`);
|
||||
const hasReacted = bottomReactionBtn?.getAttribute('data-has-reacted') === 'true';
|
||||
|
||||
const res = await POST(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, {
|
||||
data: new URLSearchParams({content: reactionContent}),
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
bottomReactions?.remove();
|
||||
if (data.html) {
|
||||
commentContainer.insertAdjacentHTML('beforeend', data.html);
|
||||
const bottomReactionsDropdowns = commentContainer.querySelectorAll('.bottom-reactions .dropdown.select-reaction');
|
||||
$(bottomReactionsDropdowns).dropdown(); // re-init the dropdown
|
||||
}
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (data && (data.html || data.empty)) {
|
||||
const $content = $(this).closest('.content');
|
||||
let $react = $content.find('.segment.reactions');
|
||||
if ((!data.empty || data.html === '') && $react.length > 0) {
|
||||
$react.remove();
|
||||
}
|
||||
if (!data.empty) {
|
||||
const $attachments = $content.find('.segment.bottom:first');
|
||||
$react = $(data.html);
|
||||
if ($attachments.length > 0) {
|
||||
$react.insertBefore($attachments);
|
||||
} else {
|
||||
$react.appendTo($content);
|
||||
}
|
||||
$react.find('.dropdown').dropdown();
|
||||
initCompReactionSelector($react);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ function initRepoDiffConversationForm() {
|
|||
el.classList.add('tw-invisible');
|
||||
}
|
||||
$newConversationHolder.find('.dropdown').dropdown();
|
||||
initCompReactionSelector($newConversationHolder);
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
showErrorToast(i18n.network_error);
|
||||
|
|
|
@ -449,12 +449,10 @@ export function initRepoPullRequestReview() {
|
|||
offset += $('.diff-detail-box').outerHeight() + $(diffHeader).outerHeight();
|
||||
}
|
||||
|
||||
document.getElementById(`show-outdated-${id}`).classList.add('tw-hidden');
|
||||
document.getElementById(`code-comments-${id}`).classList.remove('tw-hidden');
|
||||
document.getElementById(`code-preview-${id}`).classList.remove('tw-hidden');
|
||||
document.getElementById(`hide-outdated-${id}`).classList.remove('tw-hidden');
|
||||
hideElem(`#show-outdated-${id}`);
|
||||
showElem(`#code-comments-${id}, #code-preview-${id}, #hide-outdated-${id}`);
|
||||
// if the comment box is folded, expand it
|
||||
if (ancestorDiffBox.getAttribute('data-folded') === 'true') {
|
||||
if (ancestorDiffBox?.getAttribute('data-folded') === 'true') {
|
||||
setFileFolding(ancestorDiffBox, ancestorDiffBox.querySelector('.fold-file'), false);
|
||||
}
|
||||
|
||||
|
|
|
@ -393,7 +393,7 @@ export function initRepository() {
|
|||
initRepoIssueDependencyDelete();
|
||||
initRepoIssueCodeCommentCancel();
|
||||
initRepoPullRequestUpdate();
|
||||
initCompReactionSelector($(document));
|
||||
initCompReactionSelector();
|
||||
|
||||
initRepoPullRequestMergeForm();
|
||||
initRepoPullRequestCommitStatus();
|
||||
|
|
Loading…
Reference in New Issue