Implement CSS-only input toggling, refactor related forms

UX/Translation changes:

- new teams: remove redundant tooltips that don't add meaningful information
  - move general information to table fieldset
- new teams: rename "general" to "custom" access for clarity
- new teams: show labels beside options on mobile

Accessibility:

- semantic form elements allow easier navigation (fieldset, mostly)
- improve better labelling of new teams table
- fix accessibility scan issues
- TODO: the parts that "disable" form elements were not yet touched and
  are not really accessible to screenreaders

Technical:

- replace two JavaScript solutions with one CSS standard
- implement a simpler grid (.simple-grid)
- simplify markup
- remove some webhook settings specific CSS

Testing:

- check more form content for accessibility issues
- but exclude tooltips from the scan :(
- reuse existing form tests from previous PR
This commit is contained in:
Otto Richter 2024-08-19 23:35:37 +02:00
parent c20c534b90
commit 83d2b3b7fa
12 changed files with 210 additions and 310 deletions

View file

@ -2861,13 +2861,11 @@ teams.leave.detail = Are you sure you want to leave team "%s"?
teams.can_create_org_repo = Create repositories teams.can_create_org_repo = Create repositories
teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository. teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository.
teams.none_access = No access teams.none_access = No access
teams.none_access_helper = Members cannot view or do any other action on this unit. It has no effect for public repositories. teams.none_access_helper = The "no access" option only has effect on private repositories.
teams.general_access = General access teams.general_access = Custom access
teams.general_access_helper = Members permissions will be decided by below permission table. teams.general_access_helper = Members permissions will be decided by below permission table.
teams.read_access = Read teams.read_access = Read
teams.read_access_helper = Members can view and clone team repositories.
teams.write_access = Write teams.write_access = Write
teams.write_access_helper = Members can read and push to team repositories.
teams.admin_access = Administrator access teams.admin_access = Administrator access
teams.admin_access_helper = Members can pull and push to team repositories and add collaborators to them. teams.admin_access_helper = Members can pull and push to team repositories and add collaborators to them.
teams.no_desc = This team has no description teams.no_desc = This team has no description

View file

@ -56,58 +56,65 @@
{{ctx.Locale.Tr "org.teams.general_access"}} {{ctx.Locale.Tr "org.teams.general_access"}}
<span class="help">{{ctx.Locale.Tr "org.teams.general_access_helper"}}</span> <span class="help">{{ctx.Locale.Tr "org.teams.general_access_helper"}}</span>
</label> </label>
</fieldset> <fieldset class="hide-unless-checked">
<legend>{{ctx.Locale.Tr "org.team_unit_desc"}}
<div class="team-units required field {{if eq .Team.AccessMode 3}}tw-hidden{{end}}"> <span class="help">{{ctx.Locale.Tr "org.teams.none_access_helper"}}</span>
<label>{{ctx.Locale.Tr "org.team_unit_desc"}}</label> </legend>
<table class="ui celled table"> <table class="ui table optionmatrix">
<thead> <thead>
<tr> <tr>
<th>{{ctx.Locale.Tr "units.unit"}}</th> <th>{{ctx.Locale.Tr "units.unit"}}</th>
<th class="center aligned">{{ctx.Locale.Tr "org.teams.none_access"}} <th id="access_none">{{ctx.Locale.Tr "org.teams.none_access"}}</th>
<span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.none_access_helper"}}">{{svg "octicon-question" 16 "tw-ml-1"}}</span></th> <th id="access_read">{{ctx.Locale.Tr "org.teams.read_access"}}</th>
<th class="center aligned">{{ctx.Locale.Tr "org.teams.read_access"}} <th id="access_write">{{ctx.Locale.Tr "org.teams.write_access"}}</th>
<span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.read_access_helper"}}">{{svg "octicon-question" 16 "tw-ml-1"}}</span></th> </tr>
<th class="center aligned">{{ctx.Locale.Tr "org.teams.write_access"}} </thead>
<span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.write_access_helper"}}">{{svg "octicon-question" 16 "tw-ml-1"}}</span></th> <tbody>
</tr> {{range $t, $unit := $.Units}}
</thead> {{if ge $unit.MaxPerm 2}}
<tbody> <tr>
{{range $t, $unit := $.Units}} <td>
{{if ge $unit.MaxPerm 2}} <label {{if $unit.Type.UnitGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
<tr> {{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}}
<td> <span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span>
<label {{if $unit.Type.UnitGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}> </label>
{{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}} </td>
<span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span> <td>
</label> <label>
</td> <input aria-labelledby="access_none" type="radio" name="unit_{{$unit.Type.Value}}" value="0"{{if or ($unit.Type.UnitGlobalDisabled) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 0)}} checked{{end}}>
<td class="center aligned"> <span class="only-mobile">{{ctx.Locale.Tr "org.teams.none_access"}}</span>
<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"}}"> </label>
</td> </td>
<td class="center aligned"> <td>
<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"}}"> <label>
</td> <input aria-labelledby="access_read" 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}}>
<td class="center aligned"> <span class="only-mobile">{{ctx.Locale.Tr "org.teams.read_access"}}</span>
<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"}}"> </label>
</td> </td>
</tr> <td>
<label>
<input aria-labelledby="access_write" 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}}>
<span class="only-mobile">{{ctx.Locale.Tr "org.teams.write_access"}}</span>
</label>
</td>
</tr>
{{end}}
{{end}} {{end}}
</tbody>
</table>
<fieldset>
{{range $t, $unit := $.Units}}
{{if lt $unit.MaxPerm 2}}
<label {{if $unit.Type.UnitGlobalDisabled}}data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
<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}}>
{{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}}
<span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span>
</label>
{{end}} {{end}}
</tbody>
</table>
<fieldset>
{{range $t, $unit := $.Units}}
{{if lt $unit.MaxPerm 2}}
<label {{if $unit.Type.UnitGlobalDisabled}}data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
<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}}>
{{ctx.Locale.Tr $unit.NameKey}}{{if $unit.Type.UnitGlobalDisabled}} {{ctx.Locale.Tr "org.team_unit_disabled"}}{{end}}
<span class="help">{{ctx.Locale.Tr $unit.DescKey}}</span>
</label>
{{end}} {{end}}
{{end}} </fieldset>
</fieldset> </fieldset>
</div> </fieldset>
{{end}} {{end}}
<div class="field"> <div class="field">

View file

@ -2,247 +2,159 @@
<div class="field"> <div class="field">
<fieldset class="event type"> <fieldset class="event type">
<legend>{{ctx.Locale.Tr "repo.settings.event_desc"}}</legend> <legend>{{ctx.Locale.Tr "repo.settings.event_desc"}}</legend>
<label class="non-events"> <label>
<input name="events" type="radio" value="push_only" {{if or $isNew .Webhook.PushOnly}}checked{{end}}> <input name="events" type="radio" value="push_only" {{if or $isNew .Webhook.PushOnly}}checked{{end}}>
{{ctx.Locale.Tr "repo.settings.event_push_only"}} {{ctx.Locale.Tr "repo.settings.event_push_only"}}
</label> </label>
<label class="non-events"> <label>
<input name="events" type="radio" value="send_everything" {{if .Webhook.SendEverything}}checked{{end}}> <input name="events" type="radio" value="send_everything" {{if .Webhook.SendEverything}}checked{{end}}>
{{ctx.Locale.Tr "repo.settings.event_send_everything"}} {{ctx.Locale.Tr "repo.settings.event_send_everything"}}
</label> </label>
<label class="events"> <label>
<input name="events" type="radio" value="choose_events" {{if .Webhook.ChooseEvents}}checked{{end}}> <input name="events" type="radio" value="choose_events" {{if .Webhook.ChooseEvents}}checked{{end}}>
{{ctx.Locale.Tr "repo.settings.event_choose"}} {{ctx.Locale.Tr "repo.settings.event_choose"}}
</label> </label>
</fieldset> <fieldset class="hide-unless-checked">
<!-- Repository Events -->
<div class="events fields ui grid {{if not .Webhook.ChooseEvents}}tw-hidden{{end}}"> <fieldset class="simple-grid grid-2">
<!-- Repository Events --> <legend>{{ctx.Locale.Tr "repo.settings.event_header_repository"}}</legend>
<div class="fourteen wide column"> <!-- Create -->
<label>{{ctx.Locale.Tr "repo.settings.event_header_repository"}}</label> <label>
</div>
<!-- Create -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="create" type="checkbox" {{if .Webhook.Create}}checked{{end}}> <input name="create" type="checkbox" {{if .Webhook.Create}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_create"}}</label> {{ctx.Locale.Tr "repo.settings.event_create"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_create_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_create_desc"}}</span>
</div> </label>
</div> <!-- Delete -->
</div> <label>
<!-- Delete -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="delete" type="checkbox" {{if .Webhook.Delete}}checked{{end}}> <input name="delete" type="checkbox" {{if .Webhook.Delete}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_delete"}}</label> {{ctx.Locale.Tr "repo.settings.event_delete"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_delete_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_delete_desc"}}</span>
</div> </label>
</div> <!-- Fork -->
</div> <label>
<!-- Fork -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="fork" type="checkbox" {{if .Webhook.Fork}}checked{{end}}> <input name="fork" type="checkbox" {{if .Webhook.Fork}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_fork"}}</label> {{ctx.Locale.Tr "repo.settings.event_fork"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_fork_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_fork_desc"}}</span>
</div> </label>
</div> <!-- Push -->
</div> <label>
<!-- Push -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="push" type="checkbox" {{if .Webhook.Push}}checked{{end}}> <input name="push" type="checkbox" {{if .Webhook.Push}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_push"}}</label> {{ctx.Locale.Tr "repo.settings.event_push"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_push_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_push_desc"}}</span>
</div> </label>
</div> <!-- Repository -->
</div> <label>
<!-- Repository -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="repository" type="checkbox" {{if .Webhook.Repository}}checked{{end}}> <input name="repository" type="checkbox" {{if .Webhook.Repository}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_repository"}}</label> {{ctx.Locale.Tr "repo.settings.event_repository"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_repository_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_repository_desc"}}</span>
</div> </label>
</div> <!-- Release -->
</div> <label>
<!-- Release -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="release" type="checkbox" {{if .Webhook.Release}}checked{{end}}> <input name="release" type="checkbox" {{if .Webhook.Release}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_release"}}</label> {{ctx.Locale.Tr "repo.settings.event_release"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_release_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_release_desc"}}</span>
</div> </label>
</div> <!-- Package -->
</div> <label>
<!-- Package -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="package" type="checkbox" {{if .Webhook.Package}}checked{{end}}> <input name="package" type="checkbox" {{if .Webhook.Package}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_package"}}</label> {{ctx.Locale.Tr "repo.settings.event_package"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_package_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_package_desc"}}</span>
</div> </label>
</div> <!-- Wiki -->
</div> <label>
<!-- Wiki -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .Webhook.Wiki}}checked{{end}}> <input name="wiki" type="checkbox" {{if .Webhook.Wiki}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_wiki"}}</label> {{ctx.Locale.Tr "repo.settings.event_wiki"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_wiki_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_wiki_desc"}}</span>
</div> </label>
</div> </fieldset>
</div> <!-- Issue Events -->
<fieldset class="simple-grid grid-2">
<!-- Issue Events --> <legend>{{ctx.Locale.Tr "repo.settings.event_header_issue"}}</legend>
<div class="fourteen wide column"> <!-- Issues -->
<label>{{ctx.Locale.Tr "repo.settings.event_header_issue"}}</label> <label>
</div>
<!-- Issues -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .Webhook.Issues}}checked{{end}}> <input name="issues" type="checkbox" {{if .Webhook.Issues}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_issues"}}</label> {{ctx.Locale.Tr "repo.settings.event_issues"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_issues_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_issues_desc"}}</span>
</div> </label>
</div> <!-- Issue Assign -->
</div> <label>
<!-- Issue Assign -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="issue_assign" type="checkbox" {{if .Webhook.IssueAssign}}checked{{end}}> <input name="issue_assign" type="checkbox" {{if .Webhook.IssueAssign}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_issue_assign"}}</label> {{ctx.Locale.Tr "repo.settings.event_issue_assign"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_assign_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_assign_desc"}}</span>
</div> </label>
</div> <!-- Issue Label -->
</div> <label>
<!-- Issue Label -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="issue_label" type="checkbox" {{if .Webhook.IssueLabel}}checked{{end}}> <input name="issue_label" type="checkbox" {{if .Webhook.IssueLabel}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_issue_label"}}</label> {{ctx.Locale.Tr "repo.settings.event_issue_label"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_label_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_label_desc"}}</span>
</div> </label>
</div> <!-- Issue Milestone -->
</div> <label>
<!-- Issue Milestone -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="issue_milestone" type="checkbox" {{if .Webhook.IssueMilestone}}checked{{end}}> <input name="issue_milestone" type="checkbox" {{if .Webhook.IssueMilestone}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_issue_milestone"}}</label> {{ctx.Locale.Tr "repo.settings.event_issue_milestone"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_milestone_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_milestone_desc"}}</span>
</div> </label>
</div> <!-- Issue Comment -->
</div> <label>
<!-- Issue Comment -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="issue_comment" type="checkbox" {{if .Webhook.IssueComment}}checked{{end}}> <input name="issue_comment" type="checkbox" {{if .Webhook.IssueComment}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_issue_comment"}}</label> {{ctx.Locale.Tr "repo.settings.event_issue_comment"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_comment_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_issue_comment_desc"}}</span>
</div> </label>
</div> </fieldset>
</div> <!-- Pull Request Events -->
<fieldset class="simple-grid grid-2">
<!-- Pull Request Events --> <legend>{{ctx.Locale.Tr "repo.settings.event_header_pull_request"}}</legend>
<div class="fourteen wide column"> <!-- Pull Request -->
<label>{{ctx.Locale.Tr "repo.settings.event_header_pull_request"}}</label> <label>
</div>
<!-- Pull Request -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request" type="checkbox" {{if .Webhook.PullRequest}}checked{{end}}> <input name="pull_request" type="checkbox" {{if .Webhook.PullRequest}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Assign -->
</div> <label>
<!-- Pull Request Assign -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_assign" type="checkbox" {{if .Webhook.PullRequestAssign}}checked{{end}}> <input name="pull_request_assign" type="checkbox" {{if .Webhook.PullRequestAssign}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_assign"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_assign"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_assign_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_assign_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Label -->
</div> <label>
<!-- Pull Request Label -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_label" type="checkbox" {{if .Webhook.PullRequestLabel}}checked{{end}}> <input name="pull_request_label" type="checkbox" {{if .Webhook.PullRequestLabel}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_label"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_label"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_label_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_label_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Milestone -->
</div> <label>
<!-- Pull Request Milestone -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_milestone" type="checkbox" {{if .Webhook.PullRequestMilestone}}checked{{end}}> <input name="pull_request_milestone" type="checkbox" {{if .Webhook.PullRequestMilestone}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_milestone"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_milestone"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_milestone_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_milestone_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Comment -->
</div> <label>
<!-- Pull Request Comment -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_comment" type="checkbox" {{if .Webhook.PullRequestComment}}checked{{end}}> <input name="pull_request_comment" type="checkbox" {{if .Webhook.PullRequestComment}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_comment"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_comment"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_comment_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_comment_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Review -->
</div> <label>
<!-- Pull Request Review -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_review" type="checkbox" {{if .Webhook.PullRequestReview}}checked{{end}}> <input name="pull_request_review" type="checkbox" {{if .Webhook.PullRequestReview}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_review"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_review"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_review_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_review_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Sync -->
</div> <label>
<!-- Pull Request Sync -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_sync" type="checkbox" {{if .Webhook.PullRequestSync}}checked{{end}}> <input name="pull_request_sync" type="checkbox" {{if .Webhook.PullRequestSync}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_sync"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_sync"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_sync_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_sync_desc"}}</span>
</div> </label>
</div> <!-- Pull Request Review Request -->
</div> <label>
<!-- Pull Request Review Request -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input name="pull_request_review_request" type="checkbox" {{if .Webhook.PullRequestReviewRequest}}checked{{end}}> <input name="pull_request_review_request" type="checkbox" {{if .Webhook.PullRequestReviewRequest}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.event_pull_request_review_request"}}</label> {{ctx.Locale.Tr "repo.settings.event_pull_request_review_request"}}
<span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_review_request_desc"}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.event_pull_request_review_request_desc"}}</span>
</div> </label>
</div> </fieldset>
</div> </fieldset>
</div> </fieldset>
</div> </div>
<!-- Branch filter --> <!-- Branch filter -->

View file

@ -14,12 +14,11 @@ test('org team settings', async ({browser}, workerInfo) => {
await expect(response?.status()).toBe(200); await expect(response?.status()).toBe(200);
await page.locator('input[name="permission"][value="admin"]').click(); await page.locator('input[name="permission"][value="admin"]').click();
await expect(page.locator('.team-units')).toBeHidden(); await expect(page.locator('.hide-unless-checked')).toBeHidden();
// we are validating the form here, because the now hidden part has accessibility issues anyway
// this should be moved up or down once they are fixed.
await validate_form({page});
await page.locator('input[name="permission"][value="read"]').click(); await page.locator('input[name="permission"][value="read"]').click();
await expect(page.locator('.team-units')).toBeVisible(); await expect(page.locator('.hide-unless-checked')).toBeVisible();
// we are validating the form here to include the part that could be hidden
await validate_form({page});
}); });

View file

@ -14,16 +14,15 @@ test('repo webhook settings', async ({browser}, workerInfo) => {
await expect(response?.status()).toBe(200); await expect(response?.status()).toBe(200);
await page.locator('input[name="events"][value="choose_events"]').click(); await page.locator('input[name="events"][value="choose_events"]').click();
await expect(page.locator('.events.fields')).toBeVisible(); await expect(page.locator('.hide-unless-checked')).toBeVisible();
// check accessibility including the custom events (now visible) part
await validate_form({page}, 'fieldset');
await page.locator('input[name="events"][value="push_only"]').click(); await page.locator('input[name="events"][value="push_only"]').click();
await expect(page.locator('.events.fields')).toBeHidden(); await expect(page.locator('.hide-unless-checked')).toBeHidden();
await page.locator('input[name="events"][value="send_everything"]').click(); await page.locator('input[name="events"][value="send_everything"]').click();
await expect(page.locator('.events.fields')).toBeHidden(); await expect(page.locator('.hide-unless-checked')).toBeHidden();
// restrict to improved semantic HTML, the rest of the page fails the accessibility check
// only execute when the ugly part is hidden - would benefit from refactoring, too
await validate_form({page}, 'fieldset');
}); });
test('repo branch protection settings', async ({browser}, workerInfo) => { test('repo branch protection settings', async ({browser}, workerInfo) => {

View file

@ -3,7 +3,11 @@ import AxeBuilder from '@axe-core/playwright';
export async function validate_form({page}, scope) { export async function validate_form({page}, scope) {
scope ??= 'form'; scope ??= 'form';
const accessibilityScanResults = await new AxeBuilder({page}).include(scope).analyze(); const accessibilityScanResults = await new AxeBuilder({page})
.include(scope)
// exclude automated tooltips from accessibility scan, remove when fixed
.exclude('span[data-tooltip-content')
.analyze();
expect(accessibilityScanResults.violations).toEqual([]); expect(accessibilityScanResults.violations).toEqual([]);
// assert CSS properties that needed to be overriden for forms (ensure they remain active) // assert CSS properties that needed to be overriden for forms (ensure they remain active)

View file

@ -12,7 +12,12 @@ fieldset label {
display: block; display: block;
} }
form fieldset label .help { fieldset label:has(input[type="text"]),
fieldset label:has(input[type="number"]) {
font-weight: var(--font-weight-medium);
}
fieldset .help {
font-weight: var(--font-weight-normal); font-weight: var(--font-weight-normal);
display: block !important; /* overrides another rule in this file, remove when obsolete */ display: block !important; /* overrides another rule in this file, remove when obsolete */
} }
@ -23,9 +28,22 @@ fieldset input[type="radio"] {
vertical-align: initial !important; /* overrides a semantic.css rule, remove when obsolete */ vertical-align: initial !important; /* overrides a semantic.css rule, remove when obsolete */
} }
fieldset label:has(input[type="text"]), @media (min-width: 768px) {
fieldset label:has(input[type="number"]) { .optionmatrix input[type="radio"] {
font-weight: var(--font-weight-medium); margin: 0;
}
/* center columns except first */
.optionmatrix td + td, .optionmatrix th + th {
min-width: 10em;
text-align: center !important; /* overrides table.css "inherit" rule */
}
}
/* if an element with class "hide-unless-checked" follows a label
* that has no checked input, it will be hidden.*/
label:not(:has(input:checked)) + .hide-unless-checked {
display: none;
} }
.ui.input textarea, .ui.input textarea,
@ -495,14 +513,6 @@ textarea:focus,
min-width: 14em; /* matches the default min width */ min-width: 14em; /* matches the default min width */
} }
.new.webhook form .help {
margin-left: 25px;
}
.new.webhook .events.fields .column {
padding-left: 40px;
}
.githook textarea { .githook textarea {
font-family: var(--fonts-monospace); font-family: var(--fonts-monospace);
} }

View file

@ -1,3 +1,14 @@
.simple-grid {
display: grid;
gap: 1em 2em;
}
@media (min-width: 30em) {
.simple-grid.grid-2 {
grid-template-columns: repeat(2, 1fr);
}
}
/* based on Fomantic UI grid module, with just the parts extracted that we use. If you find any /* based on Fomantic UI grid module, with just the parts extracted that we use. If you find any
unused rules here after refactoring, please remove them. */ unused rules here after refactoring, please remove them. */

View file

@ -1805,16 +1805,6 @@ td .commit-summary {
font-style: italic; font-style: italic;
} }
.repository.settings.webhook .events .column {
padding-bottom: 0;
}
.repository.settings.webhook .events .help {
font-size: 13px;
margin-left: 26px;
padding-top: 0;
}
.repository .ui.attached.isSigned.isWarning { .repository .ui.attached.isSigned.isWarning {
border-left: 1px solid var(--color-error-border); border-left: 1px solid var(--color-error-border);
border-right: 1px solid var(--color-error-border); border-right: 1px solid var(--color-error-border);

View file

@ -1,27 +1,11 @@
import {POST} from '../../modules/fetch.js'; import {POST} from '../../modules/fetch.js';
import {hideElem, showElem, toggleElem} from '../../utils/dom.js'; import {toggleElem} from '../../utils/dom.js';
export function initCompWebHookEditor() { export function initCompWebHookEditor() {
if (!document.querySelectorAll('.new.webhook').length) { if (!document.querySelectorAll('.new.webhook').length) {
return; return;
} }
for (const input of document.querySelectorAll('label.events input')) {
input.addEventListener('change', function () {
if (this.checked) {
showElem('.events.fields');
}
});
}
for (const input of document.querySelectorAll('label.non-events input')) {
input.addEventListener('change', function () {
if (this.checked) {
hideElem('.events.fields');
}
});
}
// some webhooks (like Gitea) allow to set the request method (GET/POST), and it would toggle the "Content Type" field // some webhooks (like Gitea) allow to set the request method (GET/POST), and it would toggle the "Content Type" field
const httpMethodInput = document.getElementById('http_method'); const httpMethodInput = document.getElementById('http_method');
if (httpMethodInput) { if (httpMethodInput) {

View file

@ -1,20 +1,7 @@
import $ from 'jquery'; import $ from 'jquery';
import {hideElem, showElem} from '../utils/dom.js';
const {appSubUrl} = window.config; const {appSubUrl} = window.config;
export function initOrgTeamSettings() {
// Change team access mode
$('.organization.new.team input[name=permission]').on('change', () => {
const val = $('input[name=permission]:checked', '.organization.new.team').val();
if (val === 'admin') {
hideElem('.organization.new.team .team-units');
} else {
showElem('.organization.new.team .team-units');
}
});
}
export function initOrgTeamSearchRepoBox() { export function initOrgTeamSearchRepoBox() {
const $searchRepoBox = $('#search-repo-box'); const $searchRepoBox = $('#search-repo-box');
$searchRepoBox.search({ $searchRepoBox.search({

View file

@ -60,7 +60,7 @@ import {
initRepoSettingSearchTeamBox, initRepoSettingSearchTeamBox,
} from './features/repo-settings.js'; } from './features/repo-settings.js';
import {initRepoDiffView} from './features/repo-diff.js'; import {initRepoDiffView} from './features/repo-diff.js';
import {initOrgTeamSearchRepoBox, initOrgTeamSettings} from './features/org-team.js'; import {initOrgTeamSearchRepoBox} from './features/org-team.js';
import {initUserAuthWebAuthn, initUserAuthWebAuthnRegister} from './features/user-auth-webauthn.js'; import {initUserAuthWebAuthn, initUserAuthWebAuthnRegister} from './features/user-auth-webauthn.js';
import {initRepoRelease, initRepoReleaseNew} from './features/repo-release.js'; import {initRepoRelease, initRepoReleaseNew} from './features/repo-release.js';
import {initRepoEditor} from './features/repo-editor.js'; import {initRepoEditor} from './features/repo-editor.js';
@ -138,7 +138,6 @@ onDomReady(() => {
initNotificationsTable(); initNotificationsTable();
initOrgTeamSearchRepoBox(); initOrgTeamSearchRepoBox();
initOrgTeamSettings();
initRepoActivityTopAuthorsChart(); initRepoActivityTopAuthorsChart();
initRepoArchiveLinks(); initRepoArchiveLinks();