mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-17 00:01:00 -04:00
Compare commits
9 Commits
9c62ca5689
...
323c6cba20
Author | SHA1 | Date | |
---|---|---|---|
|
323c6cba20 | ||
|
b8253607fe | ||
|
77e449f0be | ||
|
083818cb85 | ||
|
5eeddfde10 | ||
|
8e6a114317 | ||
|
cc1d61f1f5 | ||
|
71446eee99 | ||
|
be47015229 |
@ -88,7 +88,7 @@ func main() {
|
||||
}
|
||||
|
||||
func runEnvironmentToIni(c *cli.Context) error {
|
||||
setting.InitWorkPathAndCommonConfig(os.Getenv, setting.ArgWorkPathAndCustomConf{
|
||||
setting.InitWorkPathAndCfgProvider(os.Getenv, setting.ArgWorkPathAndCustomConf{
|
||||
WorkPath: c.String("work-path"),
|
||||
CustomPath: c.String("custom-path"),
|
||||
CustomConf: c.String("config"),
|
||||
|
2
go.mod
2
go.mod
@ -122,7 +122,7 @@ require (
|
||||
mvdan.cc/xurls/v2 v2.4.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.12
|
||||
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e
|
||||
xorm.io/xorm v1.3.3-0.20230623150031-18f8e7a86c75
|
||||
)
|
||||
|
||||
require (
|
||||
|
4
go.sum
4
go.sum
@ -1923,5 +1923,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
||||
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e h1:d5PY6mwuQK5/7T6VKfFswaKMzLmGTHkJ/ZS7+cUIAjk=
|
||||
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
||||
xorm.io/xorm v1.3.3-0.20230623150031-18f8e7a86c75 h1:ReBAlO50dCIXCWF8Gbi0ZRa62AGAwCJNCPaUNUa7JSg=
|
||||
xorm.io/xorm v1.3.3-0.20230623150031-18f8e7a86c75/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
||||
|
@ -123,7 +123,10 @@ func newXORMEngine() (*xorm.Engine, error) {
|
||||
|
||||
// SyncAllTables sync the schemas of all tables, is required by unit test code
|
||||
func SyncAllTables() error {
|
||||
return x.StoreEngine("InnoDB").Sync2(tables...)
|
||||
_, err := x.StoreEngine("InnoDB").SyncWithOptions(xorm.SyncOptions{
|
||||
WarnIfDatabaseColumnMissed: true,
|
||||
}, tables...)
|
||||
return err
|
||||
}
|
||||
|
||||
// InitEngine initializes the xorm.Engine and sets it as db.DefaultContext
|
||||
|
@ -229,39 +229,41 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (issues IssueList) getProjectIDs() []int64 {
|
||||
ids := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
ids.Add(issue.ProjectID())
|
||||
}
|
||||
return ids.Values()
|
||||
}
|
||||
func (issues IssueList) LoadProjects(ctx context.Context) error {
|
||||
issueIDs := issues.getIssueIDs()
|
||||
projectMaps := make(map[int64]*project_model.Project, len(issues))
|
||||
left := len(issueIDs)
|
||||
|
||||
func (issues IssueList) loadProjects(ctx context.Context) error {
|
||||
projectIDs := issues.getProjectIDs()
|
||||
if len(projectIDs) == 0 {
|
||||
return nil
|
||||
type projectWithIssueID struct {
|
||||
*project_model.Project `xorm:"extends"`
|
||||
IssueID int64
|
||||
}
|
||||
|
||||
projectMaps := make(map[int64]*project_model.Project, len(projectIDs))
|
||||
left := len(projectIDs)
|
||||
for left > 0 {
|
||||
limit := db.DefaultMaxInSize
|
||||
if left < limit {
|
||||
limit = left
|
||||
}
|
||||
|
||||
projects := make([]*projectWithIssueID, 0, limit)
|
||||
err := db.GetEngine(ctx).
|
||||
In("id", projectIDs[:limit]).
|
||||
Find(&projectMaps)
|
||||
Table("project").
|
||||
Select("project.*, project_issue.issue_id").
|
||||
Join("INNER", "project_issue", "project.id = project_issue.project_id").
|
||||
In("project_issue.issue_id", issueIDs[:limit]).
|
||||
Find(&projects)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, project := range projects {
|
||||
projectMaps[project.IssueID] = project.Project
|
||||
}
|
||||
left -= limit
|
||||
projectIDs = projectIDs[limit:]
|
||||
issueIDs = issueIDs[limit:]
|
||||
}
|
||||
|
||||
for _, issue := range issues {
|
||||
issue.Project = projectMaps[issue.ProjectID()]
|
||||
issue.Project = projectMaps[issue.ID]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -541,7 +543,7 @@ func (issues IssueList) loadAttributes(ctx context.Context) error {
|
||||
return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err)
|
||||
}
|
||||
|
||||
if err := issues.loadProjects(ctx); err != nil {
|
||||
if err := issues.LoadProjects(ctx); err != nil {
|
||||
return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err)
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,12 @@ func TestIssueList_LoadAttributes(t *testing.T) {
|
||||
}
|
||||
if issue.ID == int64(1) {
|
||||
assert.Equal(t, int64(400), issue.TotalTrackedTime)
|
||||
assert.NotNil(t, issue.Project)
|
||||
} else if issue.ID == int64(2) {
|
||||
assert.Equal(t, int64(3682), issue.TotalTrackedTime)
|
||||
assert.Nil(t, issue.Project)
|
||||
} else {
|
||||
assert.Nil(t, issue.Project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,6 @@ func (issue *Issue) LoadProject(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// ProjectID return project id if issue was assigned to one
|
||||
func (issue *Issue) ProjectID() int64 {
|
||||
return issue.projectID(db.DefaultContext)
|
||||
}
|
||||
|
||||
func (issue *Issue) projectID(ctx context.Context) int64 {
|
||||
var ip project_model.ProjectIssue
|
||||
has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
|
||||
|
@ -89,6 +89,12 @@ func (s *stringWithDefault) Set(v string) {
|
||||
|
||||
// InitWorkPathAndCommonConfig will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf and load common settings,
|
||||
func InitWorkPathAndCommonConfig(getEnvFn func(name string) string, args ArgWorkPathAndCustomConf) {
|
||||
InitWorkPathAndCfgProvider(getEnvFn, args)
|
||||
LoadCommonSettings()
|
||||
}
|
||||
|
||||
// InitWorkPathAndCfgProvider will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf
|
||||
func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkPathAndCustomConf) {
|
||||
tryAbsPath := func(paths ...string) string {
|
||||
s := paths[len(paths)-1]
|
||||
for i := len(paths) - 2; i >= 0; i-- {
|
||||
@ -186,6 +192,4 @@ func InitWorkPathAndCommonConfig(getEnvFn func(name string) string, args ArgWork
|
||||
AppWorkPath = tmpWorkPath.Value
|
||||
CustomPath = tmpCustomPath.Value
|
||||
CustomConf = tmpCustomConf.Value
|
||||
|
||||
LoadCommonSettings()
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplProjectsView)
|
||||
}
|
||||
|
||||
func getActionIssues(ctx *context.Context) []*issues_model.Issue {
|
||||
func getActionIssues(ctx *context.Context) issues_model.IssueList {
|
||||
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
||||
if len(commaSeparatedIssueIDs) == 0 {
|
||||
return nil
|
||||
@ -429,9 +429,14 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := issues.LoadProjects(ctx); err != nil {
|
||||
ctx.ServerError("LoadProjects", err)
|
||||
return
|
||||
}
|
||||
|
||||
projectID := ctx.FormInt64("id")
|
||||
for _, issue := range issues {
|
||||
oldProjectID := issue.ProjectID()
|
||||
oldProjectID := issue.Project.ID
|
||||
if oldProjectID == projectID {
|
||||
continue
|
||||
}
|
||||
|
@ -1984,7 +1984,7 @@ func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) {
|
||||
}
|
||||
}
|
||||
|
||||
func getActionIssues(ctx *context.Context) []*issues_model.Issue {
|
||||
func getActionIssues(ctx *context.Context) issues_model.IssueList {
|
||||
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
||||
if len(commaSeparatedIssueIDs) == 0 {
|
||||
return nil
|
||||
@ -2749,7 +2749,7 @@ func UpdateIssueStatus(ctx *context.Context) {
|
||||
log.Warn("Unrecognized action: %s", action)
|
||||
}
|
||||
|
||||
if _, err := issues_model.IssueList(issues).LoadRepositories(ctx); err != nil {
|
||||
if _, err := issues.LoadRepositories(ctx); err != nil {
|
||||
ctx.ServerError("LoadRepositories", err)
|
||||
return
|
||||
}
|
||||
|
@ -378,9 +378,14 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := issues.LoadProjects(ctx); err != nil {
|
||||
ctx.ServerError("LoadProjects", err)
|
||||
return
|
||||
}
|
||||
|
||||
projectID := ctx.FormInt64("id")
|
||||
for _, issue := range issues {
|
||||
oldProjectID := issue.ProjectID()
|
||||
oldProjectID := issue.Project.ID
|
||||
if oldProjectID == projectID {
|
||||
continue
|
||||
}
|
||||
|
@ -11,16 +11,16 @@
|
||||
</a>
|
||||
|
||||
<!-- mobile right menu, it must be here because in mobile view, each item is a flex column, the first item is a full row column -->
|
||||
<div class="ui secondary menu item navbar-mobile-right gt-gap-2">
|
||||
<div class="ui secondary menu item navbar-mobile-right">
|
||||
{{if .IsSigned}}
|
||||
<a class="item mobile-right-item gt-mr-2 gt-p-3" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{.locale.Tr "notifications"}}" aria-label="{{.locale.Tr "notifications"}}">
|
||||
<a id="mobile-notifications-icon" class="item gt-w-auto gt-p-3" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{.locale.Tr "notifications"}}" aria-label="{{.locale.Tr "notifications"}}">
|
||||
<div class="gt-relative">
|
||||
{{svg "octicon-bell"}}
|
||||
<span class="notification_count{{if not $notificationUnreadCount}} gt-hidden{{end}}">{{$notificationUnreadCount}}</span>
|
||||
</div>
|
||||
</a>
|
||||
{{end}}
|
||||
<button class="item mobile-right-item ui icon mini button gt-p-3 gt-m-0" id="navbar-expand-toggle">{{svg "octicon-three-bars"}}</button>
|
||||
<button class="item gt-w-auto ui icon mini button gt-p-3 gt-m-0" id="navbar-expand-toggle">{{svg "octicon-three-bars"}}</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -165,13 +165,6 @@
|
||||
<div class="item">item</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui button dropdown">
|
||||
<span class="text">button dropdown</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="item">item</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui search selection dropdown">
|
||||
<span class="text">search ...</span>
|
||||
<input name="value" class="search">
|
||||
@ -212,18 +205,39 @@
|
||||
|
||||
<div>
|
||||
<div class="ui dropdown mini button">
|
||||
<span class="text">small dropdown</span>
|
||||
{{svg "octicon-triangle-down" 12 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="item">item</div>
|
||||
</div>
|
||||
<span class="text">mini dropdown</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui dropdown tiny button">
|
||||
<span class="text">tiny dropdown</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui button dropdown">
|
||||
<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" 18 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="item">item</div>
|
||||
</div>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="ui dropdown mini compact button">
|
||||
<span class="text">mini compact</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui dropdown tiny compact button">
|
||||
<span class="text">tiny compact</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</div>
|
||||
<div class="ui button compact dropdown">
|
||||
<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>
|
||||
|
@ -54,9 +54,9 @@
|
||||
{{$description := .DescriptionHTML $.Context}}
|
||||
{{if $description}}<p>{{$description}}</p>{{end}}
|
||||
{{if .Topics}}
|
||||
<div class="ui tags">
|
||||
<div class="gt-df gt-fw gt-gap-2 gt-mb-3">
|
||||
{{range .Topics}}
|
||||
{{if ne . ""}}<a href="{{AppSubUrl}}/explore/repos?q={{.}}&topic=1"><div class="ui small label topic">{{.}}</div></a>{{end}}
|
||||
{{if ne . ""}}<a class="ui label" href="{{AppSubUrl}}/explore/repos?q={{.}}&topic=1">{{.}}</a>{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -26,7 +26,8 @@
|
||||
{{.locale.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
{{if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}{{- /* */ -}}
|
||||
<div class="ui primary tiny floating dropdown icon button">{{.locale.Tr "repo.commit.operations"}}
|
||||
<div class="ui dropdown primary tiny button">
|
||||
{{.locale.Tr "repo.commit.operations"}}
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="ui header">{{.locale.Tr "repo.commit.operations"}}</div>
|
||||
|
@ -49,7 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script id="diff-data-script" type="module">
|
||||
const diffDataFiles = [{{range $i, $file := .Diff.Files}}{Name:"{{$file.Name}}",NameHash:"{{$file.NameHash}}",Type:{{$file.Type}},IsBin:{{$file.IsBin}},Addition:{{$file.Addition}},Deletion:{{$file.Deletion}}},{{end}}];
|
||||
const diffDataFiles = [{{range $i, $file := .Diff.Files}}{Name:"{{$file.Name}}",NameHash:"{{$file.NameHash}}",Type:{{$file.Type}},IsBin:{{$file.IsBin}},Addition:{{$file.Addition}},Deletion:{{$file.Deletion}},IsViewed:{{$file.IsViewed}}},{{end}}];
|
||||
const diffData = {
|
||||
isIncomplete: {{.Diff.IsIncomplete}},
|
||||
tooManyFilesMessage: "{{$.locale.Tr "repo.diff.too_many_files"}}",
|
||||
|
@ -192,9 +192,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui select-project list">
|
||||
<span class="no-select item {{if .Issue.ProjectID}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
|
||||
<span class="no-select item {{if .Issue.Project}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
|
||||
<div class="selected">
|
||||
{{if .Issue.ProjectID}}
|
||||
{{if .Issue.Project}}
|
||||
<a class="item muted sidebar-item-link" href="{{.Issue.Project.Link}}">
|
||||
{{svg .Issue.Project.IconName 18 "gt-mr-3"}}{{.Issue.Project.Title}}
|
||||
</a>
|
||||
|
@ -1,3 +1,5 @@
|
||||
{{/* No account links, no way to add account links: Menu will not be shown. */}}
|
||||
{{if or .AccountLinks .OrderedOAuth2Names}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.locale.Tr "settings.manage_account_links"}}
|
||||
{{if .OrderedOAuth2Names}}
|
||||
@ -23,20 +25,18 @@
|
||||
<div class="item">
|
||||
{{.locale.Tr "settings.manage_account_links_desc"}}
|
||||
</div>
|
||||
{{if .AccountLinks}}
|
||||
{{range $loginSource, $provider := .AccountLinks}}
|
||||
<div class="item gt-df gt-ac">
|
||||
<div class="gt-f1">
|
||||
<span data-tooltip-content="{{$provider}}">
|
||||
{{$loginSource.Name}}
|
||||
{{if $loginSource.IsActive}}<span class="text primary">{{$.locale.Tr "repo.settings.active"}}</span>{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<button class="ui red tiny button delete-button" data-modal-id="delete-account-link" data-url="{{AppSubUrl}}/user/settings/security/account_link" data-id="{{$loginSource.ID}}">
|
||||
{{$.locale.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
{{range $loginSource, $provider := .AccountLinks}}
|
||||
<div class="item gt-df gt-ac">
|
||||
<div class="gt-f1">
|
||||
<span data-tooltip-content="{{$provider}}">
|
||||
{{$loginSource.Name}}
|
||||
{{if $loginSource.IsActive}}<span class="text primary">{{$.locale.Tr "repo.settings.active"}}</span>{{end}}
|
||||
</span>
|
||||
</div>
|
||||
{{end}}
|
||||
<button class="ui red tiny button delete-button" data-modal-id="delete-account-link" data-url="{{AppSubUrl}}/user/settings/security/account_link" data-id="{{$loginSource.ID}}">
|
||||
{{$.locale.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@ -51,3 +51,4 @@
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -2192,6 +2192,17 @@ table th[data-sortt-desc] .svg {
|
||||
- "> .ui.label > .delete.icon": the "x" icon for removing a label item in multiple selection dropdown
|
||||
*/
|
||||
|
||||
.ui.dropdown.mini.button,
|
||||
.ui.dropdown.tiny.button {
|
||||
padding-right: 20px;
|
||||
}
|
||||
.ui.dropdown.button {
|
||||
padding-right: 22px;
|
||||
}
|
||||
.ui.dropdown.large.button {
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
/* Gitea uses SVG images instead of Fomantic builtin "<i>" font icons, so we need to reset the icon styles */
|
||||
.ui.ui.dropdown > .icon.icon {
|
||||
position: initial; /* plain dropdown and button dropdown use flex layout for icons */
|
||||
|
@ -32,10 +32,6 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ui.repository.list .item .ui.tags {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.ui.repository.list .repo-title .labels {
|
||||
word-break: normal;
|
||||
flex-shrink: 0;
|
||||
|
@ -75,6 +75,7 @@ Gitea's private styles use `g-` prefix.
|
||||
.gt-self-start { align-self: flex-start !important; }
|
||||
.gt-self-end { align-self: flex-end !important; }
|
||||
.gt-no-underline { text-decoration-line: none !important; }
|
||||
.gt-w-auto { width: auto !important; }
|
||||
|
||||
.gt-overflow-x-auto { overflow-x: auto !important; }
|
||||
.gt-overflow-x-scroll { overflow-x: scroll !important; }
|
||||
|
@ -34,6 +34,10 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#navbar .dropdown .item {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
#navbar a.item:hover,
|
||||
#navbar button.item:hover {
|
||||
background: var(--color-nav-hover-bg);
|
||||
@ -85,19 +89,19 @@
|
||||
#navbar.navbar-menu-open .item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
#navbar.navbar-menu-open .navbar-left #navbar-logo {
|
||||
justify-content: flex-start;
|
||||
width: 50%;
|
||||
min-height: 48px;
|
||||
width: auto;
|
||||
}
|
||||
#navbar.navbar-menu-open .navbar-left .navbar-mobile-right {
|
||||
justify-content: flex-end;
|
||||
width: 50%;
|
||||
min-height: 48px;
|
||||
}
|
||||
#navbar.navbar-menu-open .mobile-right-item {
|
||||
width: auto !important;
|
||||
#navbar #mobile-notifications-icon {
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
/>
|
||||
<a
|
||||
v-if="item.isFile"
|
||||
class="file gt-ellipsis"
|
||||
:class="['file gt-ellipsis', {'viewed': item.file.IsViewed}]"
|
||||
:href="item.isFile ? '#diff-' + item.file.NameHash : ''"
|
||||
>{{ item.name }}</a>
|
||||
<SvgIcon
|
||||
@ -148,4 +148,8 @@ a:hover {
|
||||
text-decoration: none;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
a.file.viewed {
|
||||
color: var(--color-text-light-3);
|
||||
}
|
||||
</style>
|
||||
|
@ -395,8 +395,6 @@ function initGlobalShowModal() {
|
||||
if (colorPickers.length > 0) {
|
||||
initCompColorPicker(); // FIXME: this might cause duplicate init
|
||||
}
|
||||
// all non-"ok" buttons which do not have "type" should not submit the form, should not be triggered by "Enter"
|
||||
$modal.find('form button:not(.ok):not([type])').attr('type', 'button');
|
||||
$modal.modal('setting', {
|
||||
onApprove: () => {
|
||||
// "form-fetch-action" can handle network errors gracefully,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import {diffTreeStore} from '../modules/stores.js';
|
||||
import {setFileFolding} from './file-fold.js';
|
||||
|
||||
const {csrfToken, pageData} = window.config;
|
||||
@ -53,9 +54,17 @@ export function initViewedCheckboxListenerFor() {
|
||||
const hasChangedLabel = form.parentNode.querySelector('.changed-since-last-review');
|
||||
hasChangedLabel?.remove();
|
||||
|
||||
const fileName = checkbox.getAttribute('name');
|
||||
|
||||
// check if the file is in our difftreestore and if we find it -> change the IsViewed status
|
||||
const fileInPageData = diffTreeStore().files.find((x) => x.Name === fileName);
|
||||
if (fileInPageData) {
|
||||
fileInPageData.IsViewed = this.checked;
|
||||
}
|
||||
|
||||
// Unfortunately, actual forms cause too many problems, hence another approach is needed
|
||||
const files = {};
|
||||
files[checkbox.getAttribute('name')] = this.checked;
|
||||
files[fileName] = this.checked;
|
||||
const data = {files};
|
||||
const headCommitSHA = form.getAttribute('data-headcommit');
|
||||
if (headCommitSHA) data.headCommitSHA = headCommitSHA;
|
||||
|
Loading…
x
Reference in New Issue
Block a user