loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'Refactor grouped forms to semantic HTML' (#4995) from fnetx/refactor-grouped-forms into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4995
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>

Otto 3b8ac438 0c70e11d

+296 -216
+1 -1
Makefile
··· 154 154 GO_DIRS := build cmd models modules routers services tests 155 155 WEB_DIRS := web_src/js web_src/css 156 156 157 - ESLINT_FILES := web_src/js tools *.js tests/e2e 157 + ESLINT_FILES := web_src/js tools *.js tests/e2e/*.js tests/e2e/shared/*.js 158 158 STYLELINT_FILES := web_src/css web_src/js/components/*.vue 159 159 SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(wildcard *.go *.js *.md *.yml *.yaml *.toml) 160 160
+22
package-lock.json
··· 60 60 "wrap-ansi": "9.0.0" 61 61 }, 62 62 "devDependencies": { 63 + "@axe-core/playwright": "4.9.1", 63 64 "@eslint-community/eslint-plugin-eslint-comments": "4.4.0", 64 65 "@playwright/test": "1.46.1", 65 66 "@stoplight/spectral-cli": "6.11.1", ··· 134 135 "license": "Apache-2.0", 135 136 "dependencies": { 136 137 "@types/json-schema": "^7.0.11" 138 + } 139 + }, 140 + "node_modules/@axe-core/playwright": { 141 + "version": "4.9.1", 142 + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.9.1.tgz", 143 + "integrity": "sha512-8m4WZbZq7/aq7ZY5IG8GqV+ZdvtGn/iJdom+wBg+iv/3BAOBIfNQtIu697a41438DzEEyptXWmC3Xl5Kx/o9/g==", 144 + "dev": true, 145 + "dependencies": { 146 + "axe-core": "~4.9.1" 147 + }, 148 + "peerDependencies": { 149 + "playwright-core": ">= 1.0.0" 150 + } 151 + }, 152 + "node_modules/@axe-core/playwright/node_modules/axe-core": { 153 + "version": "4.9.1", 154 + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", 155 + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", 156 + "dev": true, 157 + "engines": { 158 + "node": ">=4" 137 159 } 138 160 }, 139 161 "node_modules/@babel/code-frame": {
+1
package.json
··· 59 59 "wrap-ansi": "9.0.0" 60 60 }, 61 61 "devDependencies": { 62 + "@axe-core/playwright": "4.9.1", 62 63 "@eslint-community/eslint-plugin-eslint-comments": "4.4.0", 63 64 "@playwright/test": "1.46.1", 64 65 "@stoplight/spectral-cli": "6.11.1",
+46 -67
templates/org/team/new.tmpl
··· 25 25 <span class="help">{{ctx.Locale.Tr "org.team_desc_helper"}}</span> 26 26 </div> 27 27 {{if not (eq .Team.LowerName "owners")}} 28 - <div class="grouped field"> 29 - <label>{{ctx.Locale.Tr "org.team_access_desc"}}</label> 30 - <br> 31 - <div class="field"> 32 - <div class="ui radio checkbox"> 33 - <input type="radio" name="repo_access" value="specific" {{if not .Team.IncludesAllRepositories}}checked{{end}}> 34 - <label>{{ctx.Locale.Tr "org.teams.specific_repositories"}}</label> 35 - <span class="help">{{ctx.Locale.Tr "org.teams.specific_repositories_helper"}}</span> 36 - </div> 37 - </div> 38 - <div class="field"> 39 - <div class="ui radio checkbox"> 40 - <input type="radio" name="repo_access" value="all" {{if .Team.IncludesAllRepositories}}checked{{end}}> 41 - <label>{{ctx.Locale.Tr "org.teams.all_repositories"}}</label> 42 - <span class="help">{{ctx.Locale.Tr "org.teams.all_repositories_helper"}}</span> 43 - </div> 44 - </div> 28 + <fieldset> 29 + <legend>{{ctx.Locale.Tr "org.team_access_desc"}}</legend> 30 + <label> 31 + <input type="radio" name="repo_access" value="specific" {{if not .Team.IncludesAllRepositories}}checked{{end}}> 32 + {{ctx.Locale.Tr "org.teams.specific_repositories"}} 33 + <span class="help">{{ctx.Locale.Tr "org.teams.specific_repositories_helper"}}</span> 34 + </label> 35 + <label> 36 + <input type="radio" name="repo_access" value="all" {{if .Team.IncludesAllRepositories}}checked{{end}}> 37 + {{ctx.Locale.Tr "org.teams.all_repositories"}} 38 + <span class="help">{{ctx.Locale.Tr "org.teams.all_repositories_helper"}}</span> 39 + </label> 45 40 46 - <div class="field"> 47 - <div class="ui checkbox"> 48 - <label for="can_create_org_repo">{{ctx.Locale.Tr "org.teams.can_create_org_repo"}}</label> 49 - <input id="can_create_org_repo" name="can_create_org_repo" type="checkbox" {{if .Team.CanCreateOrgRepo}}checked{{end}}> 50 - <span class="help">{{ctx.Locale.Tr "org.teams.can_create_org_repo_helper"}}</span> 51 - </div> 52 - </div> 53 - </div> 54 - <div class="grouped field"> 55 - <label>{{ctx.Locale.Tr "org.team_permission_desc"}}</label> 56 - <br> 57 - <div class="field"> 58 - <div class="ui radio checkbox"> 59 - <input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}> 60 - <label>{{ctx.Locale.Tr "org.teams.general_access"}}</label> 61 - <span class="help">{{ctx.Locale.Tr "org.teams.general_access_helper"}}</span> 62 - </div> 63 - </div> 64 - <div class="field"> 65 - <div class="ui radio checkbox"> 66 - <input type="radio" name="permission" value="admin" {{if eq .Team.AccessMode 3}}checked{{end}}> 67 - <label>{{ctx.Locale.Tr "org.teams.admin_access"}}</label> 68 - <span class="help">{{ctx.Locale.Tr "org.teams.admin_access_helper"}}</span> 69 - </div> 70 - </div> 71 - </div> 72 - <div class="divider"></div> 41 + <label> 42 + <input name="can_create_org_repo" type="checkbox" {{if .Team.CanCreateOrgRepo}}checked{{end}}> 43 + {{ctx.Locale.Tr "org.teams.can_create_org_repo"}} 44 + <span class="help">{{ctx.Locale.Tr "org.teams.can_create_org_repo_helper"}}</span> 45 + </label> 46 + </fieldset> 47 + <fieldset> 48 + <legend>{{ctx.Locale.Tr "org.team_permission_desc"}}</legend> 49 + <label> 50 + <input type="radio" name="permission" value="admin" {{if eq .Team.AccessMode 3}}checked{{end}}> 51 + {{ctx.Locale.Tr "org.teams.admin_access"}} 52 + <span class="help">{{ctx.Locale.Tr "org.teams.admin_access_helper"}}</span> 53 + </label> 54 + <label> 55 + <input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}> 56 + {{ctx.Locale.Tr "org.teams.general_access"}} 57 + <span class="help">{{ctx.Locale.Tr "org.teams.general_access_helper"}}</span> 58 + </label> 59 + </fieldset> 73 60 74 - <div class="team-units required grouped field {{if eq .Team.AccessMode 3}}tw-hidden{{end}}"> 61 + <div class="team-units required field {{if eq .Team.AccessMode 3}}tw-hidden{{end}}"> 75 62 <label>{{ctx.Locale.Tr "org.team_unit_desc"}}</label> 76 63 <table class="ui celled table"> 77 64 <thead> ··· 90 77 {{if ge $unit.MaxPerm 2}} 91 78 <tr> 92 79 <td> 93 - <div {{if $unit.Type.UnitGlobalDisabled}}class="field" data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{- else -}}class="field"{{end}}> 94 - <div> 95 - <label>{{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}}</label> 96 - <span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span> 97 - </div> 98 - </div> 80 + <label {{if $unit.Type.UnitGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}> 81 + {{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}} 82 + <span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span> 83 + </label> 99 84 </td> 100 85 <td class="center aligned"> 101 - <div class="ui radio checkbox"> 102 - <input type="radio" name="unit_{{$unit.Type.Value}}" value="0"{{if or ($unit.Type.UnitGlobalDisabled) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 0)}} checked{{end}} title="{{ctx.Locale.Tr "org.teams.none_access"}}"> 103 - </div> 86 + <input type="radio" name="unit_{{$unit.Type.Value}}" value="0"{{if or ($unit.Type.UnitGlobalDisabled) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 0)}} checked{{end}} title="{{ctx.Locale.Tr "org.teams.none_access"}}"> 104 87 </td> 105 88 <td class="center aligned"> 106 - <div class="ui radio checkbox"> 107 - <input type="radio" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{ctx.Locale.Tr "org.teams.read_access"}}"> 108 - </div> 89 + <input type="radio" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{ctx.Locale.Tr "org.teams.read_access"}}"> 109 90 </td> 110 91 <td class="center aligned"> 111 - <div class="ui radio checkbox"> 112 - <input type="radio" name="unit_{{$unit.Type.Value}}" value="2"{{if (ge ($.Team.UnitAccessMode $.Context $unit.Type) 2)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{ctx.Locale.Tr "org.teams.write_access"}}"> 113 - </div> 92 + <input type="radio" name="unit_{{$unit.Type.Value}}" value="2"{{if (ge ($.Team.UnitAccessMode $.Context $unit.Type) 2)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{ctx.Locale.Tr "org.teams.write_access"}}"> 114 93 </td> 115 94 </tr> 116 95 {{end}} 117 96 {{end}} 118 97 </tbody> 119 98 </table> 99 + <fieldset> 120 100 {{range $t, $unit := $.Units}} 121 101 {{if lt $unit.MaxPerm 2}} 122 - <div {{if $unit.Type.UnitGlobalDisabled}}class="field" data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{else}}class="field"{{end}}> 123 - <div class="ui checkbox"> 124 - <input type="checkbox" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}}> 125 - <label>{{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}}</label> 126 - <span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span> 127 - </div> 128 - </div> 102 + <label {{if $unit.Type.UnitGlobalDisabled}}data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}> 103 + <input type="checkbox" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}}> 104 + {{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}} 105 + <span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span> 106 + </label> 129 107 {{end}} 130 108 {{end}} 109 + </fieldset> 131 110 </div> 132 111 {{end}} 133 112
+89 -110
templates/repo/settings/protected_branch.tmpl
··· 1 1 {{template "repo/settings/layout_head" (dict "ctxData" . "pageClass" "repository settings branches")}} 2 2 <div class="repo-setting-content"> 3 - <form class="ui form" action="{{.Link}}" method="post"> 4 - <h4 class="ui top attached header"> 5 - {{ctx.Locale.Tr "repo.settings.branch_protection" .Rule.RuleName}} 6 - </h4> 7 - <div class="ui attached segment branch-protection"> 8 - <h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.protect_patterns"}}</h5> 9 - <div class="field"> 10 - <label>{{ctx.Locale.Tr "repo.settings.protect_branch_name_pattern"}}</label> 3 + <h4 class="ui top attached header"> 4 + {{ctx.Locale.Tr "repo.settings.branch_protection" .Rule.RuleName}} 5 + </h4> 6 + <form class="ui form attached segment" action="{{.Link}}" method="post"> 7 + {{.CsrfTokenHtml}} 8 + <input name="rule_id" type="hidden" value="{{.Rule.ID}}"> 9 + <fieldset class="branch-protection"> 10 + <legend>{{ctx.Locale.Tr "repo.settings.protect_patterns"}}</legend> 11 + <label>{{ctx.Locale.Tr "repo.settings.protect_branch_name_pattern"}} 11 12 <input name="rule_name" type="text" value="{{.Rule.RuleName}}"> 12 - <input name="rule_id" type="hidden" value="{{.Rule.ID}}"> 13 - <p class="help tw-ml-0">{{ctx.Locale.Tr "repo.settings.protect_branch_name_pattern_desc"}}</p> 14 - </div> 15 - <div class="field"> 16 - <label>{{ctx.Locale.Tr "repo.settings.protect_protected_file_patterns"}}</label> 13 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_branch_name_pattern_desc"}}</span> 14 + </label> 15 + <label>{{ctx.Locale.Tr "repo.settings.protect_protected_file_patterns"}} 17 16 <input name="protected_file_patterns" type="text" value="{{.Rule.ProtectedFilePatterns}}"> 18 - <p class="help tw-ml-0">{{ctx.Locale.Tr "repo.settings.protect_protected_file_patterns_desc"}}</p> 19 - </div> 20 - <div class="field"> 21 - <label>{{ctx.Locale.Tr "repo.settings.protect_unprotected_file_patterns"}}</label> 17 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_protected_file_patterns_desc"}}</span> 18 + </label> 19 + <label>{{ctx.Locale.Tr "repo.settings.protect_unprotected_file_patterns"}} 22 20 <input name="unprotected_file_patterns" type="text" value="{{.Rule.UnprotectedFilePatterns}}"> 23 - <p class="help tw-ml-0">{{ctx.Locale.Tr "repo.settings.protect_unprotected_file_patterns_desc"}}</p> 24 - </div> 21 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_unprotected_file_patterns_desc"}}</span> 22 + </label> 23 + </fieldset> 25 24 26 - {{.CsrfTokenHtml}} 27 - <h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_push"}}</h5> 28 - <div class="field"> 29 - <div class="ui radio checkbox"> 30 - <input name="enable_push" type="radio" value="none" class="toggle-target-disabled" data-target="#whitelist_box" {{if not .Rule.CanPush}}checked{{end}}> 31 - <label>{{ctx.Locale.Tr "repo.settings.protect_disable_push"}}</label> 32 - <p class="help">{{ctx.Locale.Tr "repo.settings.protect_disable_push_desc"}}</p> 33 - </div> 34 - </div> 35 - <div class="field"> 36 - <div class="ui radio checkbox"> 37 - <input name="enable_push" type="radio" value="all" class="toggle-target-disabled" data-target="#whitelist_box" {{if and (.Rule.CanPush) (not .Rule.EnableWhitelist)}}checked{{end}}> 38 - <label>{{ctx.Locale.Tr "repo.settings.protect_enable_push"}}</label> 39 - <p class="help">{{ctx.Locale.Tr "repo.settings.protect_enable_push_desc"}}</p> 40 - </div> 41 - </div> 42 - <div class="grouped fields"> 43 - <div class="field"> 44 - <div class="ui radio checkbox"> 45 - <input name="enable_push" type="radio" value="whitelist" class="toggle-target-enabled" data-target="#whitelist_box" {{if and (.Rule.CanPush) (.Rule.EnableWhitelist)}}checked{{end}}> 46 - <label>{{ctx.Locale.Tr "repo.settings.protect_whitelist_committers"}}</label> 47 - <p class="help">{{ctx.Locale.Tr "repo.settings.protect_whitelist_committers_desc"}}</p> 48 - </div> 49 - </div> 25 + <fieldset> 26 + <legend>{{ctx.Locale.Tr "repo.settings.event_push"}}</legend> 27 + <label> 28 + <input name="enable_push" type="radio" value="none" class="toggle-target-disabled" data-target="#whitelist_box" {{if not .Rule.CanPush}}checked{{end}}> 29 + {{ctx.Locale.Tr "repo.settings.protect_disable_push"}} 30 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_disable_push_desc"}}</span> 31 + </label> 32 + <label> 33 + <input name="enable_push" type="radio" value="all" class="toggle-target-disabled" data-target="#whitelist_box" {{if and (.Rule.CanPush) (not .Rule.EnableWhitelist)}}checked{{end}}> 34 + {{ctx.Locale.Tr "repo.settings.protect_enable_push"}} 35 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_enable_push_desc"}}</span> 36 + </label> 37 + <label> 38 + <input name="enable_push" type="radio" value="whitelist" class="toggle-target-enabled" data-target="#whitelist_box" {{if and (.Rule.CanPush) (.Rule.EnableWhitelist)}}checked{{end}}> 39 + {{ctx.Locale.Tr "repo.settings.protect_whitelist_committers"}} 40 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_whitelist_committers_desc"}}</span> 41 + </label> 50 42 <div id="whitelist_box" class="grouped fields {{if not .Rule.EnableWhitelist}}disabled{{end}}"> 51 43 <div class="checkbox-sub-item field"> 52 44 <label>{{ctx.Locale.Tr "repo.settings.protect_whitelist_users"}}</label> ··· 86 78 </div> 87 79 </div> 88 80 </div> 89 - </div> 90 - <div class="field"> 91 - <div class="ui checkbox"> 92 - <input name="require_signed_commits" type="checkbox" {{if .Rule.RequireSignedCommits}}checked{{end}}> 93 - <label>{{ctx.Locale.Tr "repo.settings.require_signed_commits"}}</label> 94 - <p class="help">{{ctx.Locale.Tr "repo.settings.require_signed_commits_desc"}}</p> 95 - </div> 96 - </div> 97 - <h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_pull_request_approvals"}}</h5> 98 - <div class="field"> 99 - <label>{{ctx.Locale.Tr "repo.settings.protect_required_approvals"}}</label> 81 + <label> 82 + <input name="require_signed_commits" type="checkbox" {{if .Rule.RequireSignedCommits}}checked{{end}}> 83 + {{ctx.Locale.Tr "repo.settings.require_signed_commits"}} 84 + <span class="help">{{ctx.Locale.Tr "repo.settings.require_signed_commits_desc"}}</span> 85 + </label> 86 + </fieldset> 87 + <fieldset> 88 + <legend>{{ctx.Locale.Tr "repo.settings.event_pull_request_approvals"}}</legend> 89 + <label> 90 + {{ctx.Locale.Tr "repo.settings.protect_required_approvals"}} 100 91 <input name="required_approvals" type="number" value="{{.Rule.RequiredApprovals}}"> 101 - <p class="help tw-ml-0">{{ctx.Locale.Tr "repo.settings.protect_required_approvals_desc"}}</p> 102 - </div> 103 - <div class="grouped fields"> 104 - <div class="field"> 105 - <div class="ui checkbox"> 106 - <input name="enable_approvals_whitelist" type="checkbox" class="toggle-target-enabled" data-target="#approvals_whitelist_box" {{if .Rule.EnableApprovalsWhitelist}}checked{{end}}> 107 - <label>{{ctx.Locale.Tr "repo.settings.protect_approvals_whitelist_enabled"}}</label> 108 - <p class="help">{{ctx.Locale.Tr "repo.settings.protect_approvals_whitelist_enabled_desc"}}</p> 109 - </div> 110 - </div> 92 + <span class="help tw-ml-0">{{ctx.Locale.Tr "repo.settings.protect_required_approvals_desc"}}</span> 93 + </label> 94 + <fieldset> 95 + <label> 96 + <input name="enable_approvals_whitelist" type="checkbox" class="toggle-target-enabled" data-target="#approvals_whitelist_box" {{if .Rule.EnableApprovalsWhitelist}}checked{{end}}> 97 + {{ctx.Locale.Tr "repo.settings.protect_approvals_whitelist_enabled"}} 98 + <span class="help">{{ctx.Locale.Tr "repo.settings.protect_approvals_whitelist_enabled_desc"}}</span> 99 + </label> 111 100 <div id="approvals_whitelist_box" class="grouped fields {{if not .Rule.EnableApprovalsWhitelist}}disabled{{end}}"> 112 101 <div class="checkbox-sub-item field"> 113 102 <label>{{ctx.Locale.Tr "repo.settings.protect_approvals_whitelist_users"}}</label> ··· 141 130 </div> 142 131 {{end}} 143 132 </div> 144 - </div> 145 - <div class="field"> 146 - <div class="ui checkbox"> 147 - <input id="dismiss_stale_approvals" name="dismiss_stale_approvals" type="checkbox" {{if .Rule.DismissStaleApprovals}}checked{{end}}> 148 - <label>{{ctx.Locale.Tr "repo.settings.dismiss_stale_approvals"}}</label> 149 - <p class="help">{{ctx.Locale.Tr "repo.settings.dismiss_stale_approvals_desc"}}</p> 150 - </div> 151 - </div> 133 + </fieldset> 134 + <label> 135 + <input id="dismiss_stale_approvals" name="dismiss_stale_approvals" type="checkbox" {{if .Rule.DismissStaleApprovals}}checked{{end}}> 136 + {{ctx.Locale.Tr "repo.settings.dismiss_stale_approvals"}} 137 + <span class="help">{{ctx.Locale.Tr "repo.settings.dismiss_stale_approvals_desc"}}</span> 138 + </label> 152 139 <div id="ignore_stale_approvals_box" class="field {{if .Rule.DismissStaleApprovals}}disabled{{end}}"> 153 140 <div class="ui checkbox"> 154 141 <input id="ignore_stale_approvals" name="ignore_stale_approvals" type="checkbox" {{if .Rule.IgnoreStaleApprovals}}checked{{end}}> ··· 156 143 <p class="help">{{ctx.Locale.Tr "repo.settings.ignore_stale_approvals_desc"}}</p> 157 144 </div> 158 145 </div> 159 - <div class="grouped fields"> 146 + <fieldset> 160 147 <div class="field"> 161 148 <div class="ui checkbox"> 162 149 <input name="enable_status_check" type="checkbox" class="toggle-target-enabled" data-target="#statuscheck_contexts_box" {{if .Rule.EnableStatusCheck}}checked{{end}}> ··· 188 175 </tbody> 189 176 </table> 190 177 </div> 191 - </div> 192 - <h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_pull_request_merge"}}</h5> 178 + </fieldset> 179 + </fieldset> 180 + <fieldset> 181 + <legend>{{ctx.Locale.Tr "repo.settings.event_pull_request_merge"}}</legend> 193 182 <div class="grouped fields"> 194 183 <div class="field"> 195 184 <div class="ui radio checkbox"> ··· 239 228 {{end}} 240 229 </div> 241 230 </div> 242 - <div class="field"> 243 - <div class="ui checkbox"> 244 - <input name="block_on_rejected_reviews" type="checkbox" {{if .Rule.BlockOnRejectedReviews}}checked{{end}}> 245 - <label>{{ctx.Locale.Tr "repo.settings.block_rejected_reviews"}}</label> 246 - <p class="help">{{ctx.Locale.Tr "repo.settings.block_rejected_reviews_desc"}}</p> 247 - </div> 248 - </div> 249 - <div class="field"> 250 - <div class="ui checkbox"> 251 - <input name="block_on_official_review_requests" type="checkbox" {{if .Rule.BlockOnOfficialReviewRequests}}checked{{end}}> 252 - <label>{{ctx.Locale.Tr "repo.settings.block_on_official_review_requests"}}</label> 253 - <p class="help">{{ctx.Locale.Tr "repo.settings.block_on_official_review_requests_desc"}}</p> 254 - </div> 255 - </div> 256 - <div class="field"> 257 - <div class="ui checkbox"> 258 - <input name="block_on_outdated_branch" type="checkbox" {{if .Rule.BlockOnOutdatedBranch}}checked{{end}}> 259 - <label>{{ctx.Locale.Tr "repo.settings.block_outdated_branch"}}</label> 260 - <p class="help">{{ctx.Locale.Tr "repo.settings.block_outdated_branch_desc"}}</p> 261 - </div> 262 - </div> 263 - <h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_pull_request_enforcement"}}</h5> 264 - <div class="field"> 265 - <div class="ui checkbox"> 266 - <input name="apply_to_admins" type="checkbox" {{if .Rule.ApplyToAdmins}}checked{{end}}> 267 - <label>{{ctx.Locale.Tr "repo.settings.enforce_on_admins"}}</label> 268 - <p class="help">{{ctx.Locale.Tr "repo.settings.enforce_on_admins_desc"}}</p> 269 - </div> 270 - </div> 271 - <div class="divider"></div> 272 - 273 - <div class="field"> 274 - <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.protected_branch.save_rule"}}</button> 275 - </div> 276 - </div> 231 + <label> 232 + <input name="block_on_rejected_reviews" type="checkbox" {{if .Rule.BlockOnRejectedReviews}}checked{{end}}> 233 + {{ctx.Locale.Tr "repo.settings.block_rejected_reviews"}} 234 + <span class="help">{{ctx.Locale.Tr "repo.settings.block_rejected_reviews_desc"}}</span> 235 + </label> 236 + <label> 237 + <input name="block_on_official_review_requests" type="checkbox" {{if .Rule.BlockOnOfficialReviewRequests}}checked{{end}}> 238 + {{ctx.Locale.Tr "repo.settings.block_on_official_review_requests"}} 239 + <span class="help">{{ctx.Locale.Tr "repo.settings.block_on_official_review_requests_desc"}}</span> 240 + </label> 241 + <label> 242 + <input name="block_on_outdated_branch" type="checkbox" {{if .Rule.BlockOnOutdatedBranch}}checked{{end}}> 243 + {{ctx.Locale.Tr "repo.settings.block_outdated_branch"}} 244 + <span class="help">{{ctx.Locale.Tr "repo.settings.block_outdated_branch_desc"}}</span> 245 + </label> 246 + </fieldset> 247 + <fieldset> 248 + <legend>{{ctx.Locale.Tr "repo.settings.event_pull_request_enforcement"}}</legend> 249 + <label> 250 + <input name="apply_to_admins" type="checkbox" {{if .Rule.ApplyToAdmins}}checked{{end}}> 251 + {{ctx.Locale.Tr "repo.settings.enforce_on_admins"}} 252 + <span class="help">{{ctx.Locale.Tr "repo.settings.enforce_on_admins_desc"}}</span> 253 + </label> 254 + </fieldset> 255 + <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.protected_branch.save_rule"}}</button> 277 256 </form> 278 257 </div> 279 258 {{template "repo/settings/layout_footer" .}}
+20 -28
templates/webhook/shared-settings.tmpl
··· 1 1 {{$isNew:=or .PageIsSettingsHooksNew .PageIsAdminDefaultHooksNew .PageIsAdminSystemHooksNew}} 2 2 <div class="field"> 3 - <h4>{{ctx.Locale.Tr "repo.settings.event_desc"}}</h4> 4 - <div class="grouped event type fields"> 5 - <div class="field"> 6 - <div class="ui radio non-events checkbox"> 7 - <input name="events" type="radio" value="push_only" {{if or $isNew .Webhook.PushOnly}}checked{{end}}> 8 - <label>{{ctx.Locale.Tr "repo.settings.event_push_only"}}</label> 9 - </div> 10 - </div> 11 - <div class="field"> 12 - <div class="ui radio non-events checkbox"> 13 - <input name="events" type="radio" value="send_everything" {{if .Webhook.SendEverything}}checked{{end}}> 14 - <label>{{ctx.Locale.Tr "repo.settings.event_send_everything"}}</label> 15 - </div> 16 - </div> 17 - <div class="field"> 18 - <div class="ui radio events checkbox"> 19 - <input name="events" type="radio" value="choose_events" {{if .Webhook.ChooseEvents}}checked{{end}}> 20 - <label>{{ctx.Locale.Tr "repo.settings.event_choose"}}</label> 21 - </div> 22 - </div> 23 - </div> 3 + <fieldset class="event type"> 4 + <legend>{{ctx.Locale.Tr "repo.settings.event_desc"}}</legend> 5 + <label class="non-events"> 6 + <input name="events" type="radio" value="push_only" {{if or $isNew .Webhook.PushOnly}}checked{{end}}> 7 + {{ctx.Locale.Tr "repo.settings.event_push_only"}} 8 + </label> 9 + <label class="non-events"> 10 + <input name="events" type="radio" value="send_everything" {{if .Webhook.SendEverything}}checked{{end}}> 11 + {{ctx.Locale.Tr "repo.settings.event_send_everything"}} 12 + </label> 13 + <label class="events"> 14 + <input name="events" type="radio" value="choose_events" {{if .Webhook.ChooseEvents}}checked{{end}}> 15 + {{ctx.Locale.Tr "repo.settings.event_choose"}} 16 + </label> 17 + </fieldset> 24 18 25 19 <div class="events fields ui grid {{if not .Webhook.ChooseEvents}}tw-hidden{{end}}"> 26 20 <!-- Repository Events --> ··· 270 264 271 265 <div class="divider"></div> 272 266 273 - <div class="inline field"> 274 - <div class="ui checkbox"> 267 + <fieldset> 268 + <label> 275 269 <input name="active" type="checkbox" {{if or $isNew .Webhook.IsActive}}checked{{end}}> 276 - <label>{{ctx.Locale.Tr "repo.settings.active"}}</label> 270 + {{ctx.Locale.Tr "repo.settings.active"}} 277 271 <span class="help">{{ctx.Locale.Tr "repo.settings.active_helper"}}</span> 278 - </div> 279 - </div> 280 - <div class="field"> 272 + </label> 281 273 {{if $isNew}} 282 274 <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_webhook"}}</button> 283 275 {{else}} 284 276 <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_webhook"}}</button> 285 277 <a class="ui red delete-button button" data-url="{{.BaseLink}}/delete" data-id="{{.Webhook.ID}}">{{ctx.Locale.Tr "repo.settings.delete_webhook"}}</a> 286 278 {{end}} 287 - </div> 279 + </fieldset> 288 280 289 281 {{template "repo/settings/webhook/delete_modal" .}}
+1 -6
tests/e2e/issue-sidebar.test.e2e.js
··· 1 1 // @ts-check 2 2 import {expect} from '@playwright/test'; 3 - import {test, login_user, load_logged_in_context} from './utils_e2e.js'; 3 + import {test, login_user, login} from './utils_e2e.js'; 4 4 5 5 test.beforeAll(async ({browser}, workerInfo) => { 6 6 await login_user(browser, workerInfo, 'user2'); 7 7 }); 8 - 9 - async function login({browser}, workerInfo) { 10 - const context = await load_logged_in_context(browser, workerInfo, 'user2'); 11 - return await context.newPage(); 12 - } 13 8 14 9 // belongs to test: Pull: Toggle WIP 15 10 const prTitle = 'pull5';
+25
tests/e2e/org-settings.test.e2e.js
··· 1 + // @ts-check 2 + import {expect} from '@playwright/test'; 3 + import {test, login_user, login} from './utils_e2e.js'; 4 + import {validate_form} from './shared/forms.js'; 5 + 6 + test.beforeAll(async ({browser}, workerInfo) => { 7 + await login_user(browser, workerInfo, 'user2'); 8 + }); 9 + 10 + test('org team settings', async ({browser}, workerInfo) => { 11 + test.skip(workerInfo.project.name === 'Mobile Safari', 'Cannot get it to work - as usual'); 12 + const page = await login({browser}, workerInfo); 13 + const response = await page.goto('/org/org3/teams/team1/edit'); 14 + await expect(response?.status()).toBe(200); 15 + 16 + await page.locator('input[name="permission"][value="admin"]').click(); 17 + await expect(page.locator('.team-units')).toBeHidden(); 18 + 19 + // we are validating the form here, because the now hidden part has accessibility issues anyway 20 + // this should be moved up or down once they are fixed. 21 + await validate_form({page}); 22 + 23 + await page.locator('input[name="permission"][value="read"]').click(); 24 + await expect(page.locator('.team-units')).toBeVisible(); 25 + });
+37
tests/e2e/repo-settings.test.e2e.js
··· 1 + // @ts-check 2 + import {expect} from '@playwright/test'; 3 + import {test, login_user, login} from './utils_e2e.js'; 4 + import {validate_form} from './shared/forms.js'; 5 + 6 + test.beforeAll(async ({browser}, workerInfo) => { 7 + await login_user(browser, workerInfo, 'user2'); 8 + }); 9 + 10 + test('repo webhook settings', async ({browser}, workerInfo) => { 11 + test.skip(workerInfo.project.name === 'Mobile Safari', 'Cannot get it to work - as usual'); 12 + const page = await login({browser}, workerInfo); 13 + const response = await page.goto('/user2/repo1/settings/hooks/forgejo/new'); 14 + await expect(response?.status()).toBe(200); 15 + 16 + await page.locator('input[name="events"][value="choose_events"]').click(); 17 + await expect(page.locator('.events.fields')).toBeVisible(); 18 + 19 + await page.locator('input[name="events"][value="push_only"]').click(); 20 + await expect(page.locator('.events.fields')).toBeHidden(); 21 + await page.locator('input[name="events"][value="send_everything"]').click(); 22 + await expect(page.locator('.events.fields')).toBeHidden(); 23 + 24 + // restrict to improved semantic HTML, the rest of the page fails the accessibility check 25 + // only execute when the ugly part is hidden - would benefit from refactoring, too 26 + await validate_form({page}, 'fieldset'); 27 + }); 28 + 29 + test('repo branch protection settings', async ({browser}, workerInfo) => { 30 + test.skip(workerInfo.project.name === 'Mobile Safari', 'Cannot get it to work - as usual'); 31 + const page = await login({browser}, workerInfo); 32 + const response = await page.goto('/user2/repo1/settings/branches/edit'); 33 + await expect(response?.status()).toBe(200); 34 + 35 + // not yet accessible :( 36 + // await validate_form({page}, 'fieldset'); 37 + });
+16
tests/e2e/shared/forms.js
··· 1 + import {expect} from '@playwright/test'; 2 + import AxeBuilder from '@axe-core/playwright'; 3 + 4 + export async function validate_form({page}, scope) { 5 + scope ??= 'form'; 6 + const accessibilityScanResults = await new AxeBuilder({page}).include(scope).analyze(); 7 + expect(accessibilityScanResults.violations).toEqual([]); 8 + 9 + // assert CSS properties that needed to be overriden for forms (ensure they remain active) 10 + const boxes = page.getByRole('checkbox').or(page.getByRole('radio')); 11 + for (const b of await boxes.all()) { 12 + await expect(b).toHaveCSS('margin-left', '0px'); 13 + await expect(b).toHaveCSS('margin-top', '0px'); 14 + await expect(b).toHaveCSS('vertical-align', 'baseline'); 15 + } 16 + }
+5
tests/e2e/utils_e2e.js
··· 58 58 return context; 59 59 } 60 60 61 + export async function login({browser}, workerInfo) { 62 + const context = await load_logged_in_context(browser, workerInfo, 'user2'); 63 + return await context.newPage(); 64 + } 65 + 61 66 export async function save_visual(page) { 62 67 // Optionally include visual testing 63 68 if (process.env.VISUAL_TEST) {
+31 -2
web_src/css/form.css
··· 1 + fieldset { 2 + margin: 0.5em 0 1em; 3 + padding: 0; 4 + } 5 + 6 + fieldset legend { 7 + font-weight: var(--font-weight-medium); 8 + margin-bottom: 0.75em; 9 + } 10 + 11 + fieldset label { 12 + display: block; 13 + } 14 + 15 + form fieldset label .help { 16 + font-weight: var(--font-weight-normal); 17 + display: block !important; /* overrides another rule in this file, remove when obsolete */ 18 + } 19 + 20 + fieldset input[type="checkbox"], 21 + fieldset input[type="radio"] { 22 + margin-right: 0.75em; 23 + vertical-align: initial !important; /* overrides a semantic.css rule, remove when obsolete */ 24 + } 25 + 26 + fieldset label:has(input[type="text"]), 27 + fieldset label:has(input[type="number"]) { 28 + font-weight: var(--font-weight-medium); 29 + } 30 + 1 31 .ui.input textarea, 2 32 .ui.form textarea, 3 33 .ui.form input:not([type]), ··· 98 128 color: var(--color-text); 99 129 } 100 130 101 - .ui.form .required.fields:not(.grouped) > .field > label::after, 102 - .ui.form .required.fields.grouped > label::after, 131 + .ui.form .required.fields > .field > label::after, 103 132 .ui.form .required.field > label::after, 104 133 .ui.form label.required::after { 105 134 color: var(--color-red);
+2 -2
web_src/js/features/comp/WebHookEditor.js
··· 6 6 return; 7 7 } 8 8 9 - for (const input of document.querySelectorAll('.events.checkbox input')) { 9 + for (const input of document.querySelectorAll('label.events input')) { 10 10 input.addEventListener('change', function () { 11 11 if (this.checked) { 12 12 showElem('.events.fields'); ··· 14 14 }); 15 15 } 16 16 17 - for (const input of document.querySelectorAll('.non-events.checkbox input')) { 17 + for (const input of document.querySelectorAll('label.non-events input')) { 18 18 input.addEventListener('change', function () { 19 19 if (this.checked) { 20 20 hideElem('.events.fields');