Skip to content

Commit 6a9a180

Browse files
authored
Merge pull request #19250 from opf/feature/64234-introduce-account-setting-to-disable-keyboard-shortcuts-for-accessibility
[64234] Introduce account setting to disable keyboard shortcuts (for accessibility)
2 parents bf68334 + 2dbeb00 commit 6a9a180

File tree

36 files changed

+442
-46
lines changed

36 files changed

+442
-46
lines changed

app/components/projects/settings/general/show_component.html.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
3333
settings_primer_form_with(model: project, url: project_settings_general_path(project)) do |f|
3434
concat(
3535
render(Primer::Beta::Subhead.new) do |component|
36-
component.with_heading(tag: :h2, size: :medium) { I18n.t("projects.settings.header_details") }
36+
component.with_heading(tag: :h3, size: :medium) { I18n.t("projects.settings.header_details") }
3737
end
3838
)
3939
concat(
@@ -52,7 +52,7 @@ See COPYRIGHT and LICENSE files for more details.
5252
settings_primer_form_with(model: project, url: project_settings_general_path(project)) do |f|
5353
concat(
5454
render(Primer::Beta::Subhead.new) do |component|
55-
component.with_heading(tag: :h2, size: :medium) { I18n.t("projects.settings.header_status") }
55+
component.with_heading(tag: :h3, size: :medium) { I18n.t("projects.settings.header_status") }
5656
end
5757
)
5858
concat(
@@ -71,7 +71,7 @@ See COPYRIGHT and LICENSE files for more details.
7171
settings_primer_form_with(model: project, url: project_settings_general_path(project)) do |f|
7272
concat(
7373
render(Primer::Beta::Subhead.new) do |component|
74-
component.with_heading(tag: :h2, size: :medium) { I18n.t("projects.settings.header_relations") }
74+
component.with_heading(tag: :h3, size: :medium) { I18n.t("projects.settings.header_relations") }
7575
end
7676
)
7777
concat(

app/controllers/my_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class MyController < ApplicationController
4545
no_authorization_required! :account,
4646
:update_account,
4747
:settings,
48+
:interface,
4849
:update_settings,
4950
:password,
5051
:change_password,
@@ -60,6 +61,7 @@ class MyController < ApplicationController
6061

6162
menu_item :account, only: [:account]
6263
menu_item :settings, only: [:settings]
64+
menu_item :interface, only: [:interface]
6365
menu_item :password, only: [:password]
6466
menu_item :access_token, only: [:access_token]
6567
menu_item :notifications, only: [:notifications]
@@ -77,6 +79,8 @@ def update_settings
7779
write_settings
7880
end
7981

82+
def interface; end
83+
8084
# Manage user's password
8185
def password
8286
@username = @user.login

app/forms/my/alerts_form.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
class My::AlertsForm < ApplicationForm
32+
form do |f|
33+
f.check_box name: :warn_on_leaving_unsaved,
34+
label: I18n.t("activerecord.attributes.user_preference.warn_on_leaving_unsaved")
35+
36+
f.check_box name: :auto_hide_popups,
37+
label: I18n.t("activerecord.attributes.user_preference.auto_hide_popups")
38+
39+
f.submit(name: :submit, label: I18n.t("activerecord.attributes.user_preference.button_update_alerts"), scheme: :default)
40+
end
41+
end

app/forms/my/look_and_feel_form.rb

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
class My::LookAndFeelForm < ApplicationForm
32+
include ApplicationHelper
33+
form do |f|
34+
f.select_list(
35+
name: :theme,
36+
label: I18n.t("activerecord.attributes.user_preference.theme"),
37+
caption: I18n.t("activerecord.attributes.user_preference.mode_guideline"),
38+
required: true,
39+
include_blank: false,
40+
input_width: :small
41+
) do |select|
42+
theme_options_for_select.each do |theme|
43+
select.option(
44+
value: theme[1],
45+
label: theme[0]
46+
)
47+
end
48+
end
49+
50+
f.select_list(
51+
name: :comments_sorting,
52+
label: I18n.t("activerecord.attributes.user_preference.comments_sorting"),
53+
required: true,
54+
include_blank: false,
55+
input_width: :small
56+
) do |select|
57+
comment_sort_order_options.each do |theme|
58+
select.option(
59+
value: theme[1],
60+
label: theme[0]
61+
)
62+
end
63+
end
64+
65+
f.check_box name: :disable_keyboard_shortcuts,
66+
label: I18n.t("activerecord.attributes.user_preference.disable_keyboard_shortcuts"),
67+
caption: I18n.t("activerecord.attributes.user_preference.disable_keyboard_shortcuts_caption_html",
68+
href: OpenProject::Static::Links.links[:shortcuts][:href]).html_safe
69+
70+
f.submit(name: :submit,
71+
label: I18n.t("activerecord.attributes.user_preference.button_update_look_and_feel"),
72+
scheme: :default)
73+
end
74+
end

app/helpers/application_helper.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,17 @@ def all_lang_options_for_select
286286

287287
def theme_options_for_select
288288
[
289-
[t("themes.light"), "light"],
290-
[t("themes.light_high_contrast"), "light_high_contrast"],
291-
[t("themes.dark"), "dark"]
289+
[I18n.t("themes.light"), "light"],
290+
[I18n.t("themes.light_high_contrast"), "light_high_contrast"],
291+
[I18n.t("themes.dark"), "dark"]
292292
]
293293
end
294294

295+
def comment_sort_order_options
296+
[[I18n.t("activities.work_packages.activity_tab.label_sort_asc"), "asc"],
297+
[I18n.t("activities.work_packages.activity_tab.label_sort_desc"), "desc"]]
298+
end
299+
295300
def body_data_attributes(local_assigns)
296301
{
297302
controller: "application hover-card-trigger",

app/models/permitted_params.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ def wiki_page
264264
end
265265

266266
def pref
267-
params.fetch(:pref, {}).permit(:time_zone, :theme,
268-
:comments_sorting, :warn_on_leaving_unsaved,
267+
params.fetch(:pref, {}).permit(:time_zone,
268+
:theme,
269+
:comments_sorting,
270+
:disable_keyboard_shortcuts,
271+
:warn_on_leaving_unsaved,
269272
:auto_hide_popups)
270273
end
271274

app/models/user_preference.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ def comments_in_reverse_order?
8686
comments_sorting == "desc"
8787
end
8888

89+
def disable_keyboard_shortcuts?
90+
settings.fetch(:disable_keyboard_shortcuts) { Setting.disable_keyboard_shortcuts? }
91+
end
92+
93+
def disable_keyboard_shortcuts=(value)
94+
settings[:disable_keyboard_shortcuts] = to_boolean(value)
95+
end
96+
8997
def diff_type
9098
settings.fetch(:diff_type, "inline")
9199
end
@@ -110,6 +118,7 @@ def warn_on_leaving_unsaved=(value)
110118
alias :comments_in_reverse_order :comments_in_reverse_order?
111119
alias :warn_on_leaving_unsaved :warn_on_leaving_unsaved?
112120
alias :auto_hide_popups :auto_hide_popups?
121+
alias :disable_keyboard_shortcuts :disable_keyboard_shortcuts?
113122

114123
def comments_in_reverse_order=(value)
115124
settings[:comments_sorting] = to_boolean(value) ? "desc" : "asc"

app/views/my/interface.html.erb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<%#-- copyright
2+
OpenProject is an open source project management software.
3+
Copyright (C) the OpenProject GmbH
4+
5+
This program is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU General Public License version 3.
7+
8+
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
9+
Copyright (C) 2006-2013 Jean-Philippe Lang
10+
Copyright (C) 2010-2013 the ChiliProject Team
11+
12+
This program is free software; you can redistribute it and/or
13+
modify it under the terms of the GNU General Public License
14+
as published by the Free Software Foundation; either version 2
15+
of the License, or (at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program; if not, write to the Free Software
24+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25+
26+
See COPYRIGHT and LICENSE files for more details.
27+
28+
++#%>
29+
30+
<% html_title(t(:label_my_account), t(:label_interface)) %>
31+
32+
<%=
33+
render(Primer::OpenProject::PageHeader.new) do |header|
34+
header.with_title { t(:label_interface) }
35+
header.with_breadcrumbs(
36+
[{ href: my_account_path, text: t(:label_my_account) },
37+
t(:label_interface)]
38+
)
39+
end
40+
%>
41+
42+
<%= error_messages_for "user" %>
43+
44+
<%=
45+
render(Primer::Beta::Subhead.new) do |component|
46+
component.with_heading(tag: :h3, size: :medium) { I18n.t("activerecord.attributes.user_preference.header_look_and_feel") }
47+
end
48+
%>
49+
<%=
50+
settings_primer_form_with(model: @user.pref, scope: :pref, url: { action: "update_settings" }, method: :patch, data: { turbo: false }) do |form|
51+
render(My::LookAndFeelForm.new(form))
52+
end
53+
%>
54+
55+
<%=
56+
render(Primer::Beta::Subhead.new(mt: 3)) do |component|
57+
component.with_heading(tag: :h3, size: :medium) { I18n.t("activerecord.attributes.user_preference.header_alerts") }
58+
end
59+
%>
60+
<%=
61+
settings_primer_form_with(model: @user.pref, scope: :pref, url: { action: "update_settings" }, data: { turbo: false }) do |form|
62+
render(My::AlertsForm.new(form))
63+
end
64+
%>
65+
66+
<%= call_hook(:view_my_settings, user: @user) %>

app/views/my/settings.html.erb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,17 @@ See COPYRIGHT and LICENSE files for more details.
4444
lang: current_language,
4545
html: { id: "my_account_form", class: "form -wide-labels" } do |f| %>
4646
<fieldset class="form--fieldset">
47-
<div class="form--field"><%= f.select :language, lang_options_for_select, container_class: "-middle" %></div>
48-
<%= render partial: "users/preferences", locals: { input_size: :middle } %>
47+
<div class="form--field">
48+
<%= f.select :language, lang_options_for_select, container_class: "-middle" %>
49+
</div>
50+
<%= fields_for :pref, @user.pref, builder: TabularFormBuilder, lang: current_language do |pref_fields| %>
51+
<%= render Settings::TimeZoneSettingComponent.new(
52+
"time_zone",
53+
form: pref_fields,
54+
include_blank: false,
55+
container_class: "-middle"
56+
) %>
57+
<% end %>
4958
</fieldset>
50-
<%= call_hook(:view_my_settings, user: @user, form: f) %>
5159
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
5260
<% end %>

app/views/users/_general.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ See COPYRIGHT and LICENSE files for more details.
4848
},
4949
data: {
5050
controller: "admin--users",
51+
turbo: false,
5152
"admin--users-password-auth-selected-value": @user.ldap_auth_source_id.blank?
5253
},
5354
as: :user do |f| %>

app/views/users/_preferences.html.erb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,20 @@ See COPYRIGHT and LICENSE files for more details.
3434
container_class: defined?(input_size) ? "-#{input_size}" : "-wide"
3535
) %>
3636
<div class="form--field">
37-
<%= pref_fields.select :theme, theme_options_for_select, container_class: "-middle" %>
37+
<%= pref_fields.select :theme, theme_options_for_select, container_class: "-middle" %> <!-- TODO -->
3838
<div class="form--field-instructions">
3939
<%= I18n.t("activerecord.attributes.user_preference.mode_guideline") %>
4040
</div>
4141
</div>
42+
4243
<div class="form--field">
43-
<%= pref_fields.select :comments_sorting,
44-
[[t("activities.work_packages.activity_tab.label_sort_asc"), "asc"],
45-
[t("activities.work_packages.activity_tab.label_sort_desc"), "desc"]],
46-
container_class: defined?(input_size) ? "-#{input_size}" : "" %>
44+
<%= pref_fields.check_box :disable_keyboard_shortcuts,
45+
label: I18n.t("activerecord.attributes.user_preference.disable_keyboard_shortcuts") %>
46+
<span class="form--field-instructions">
47+
<%= I18n.t(
48+
"activerecord.attributes.user_preference.disable_keyboard_shortcuts_caption_html",
49+
href: OpenProject::Static::Links.links[:shortcuts][:href]
50+
).html_safe %>
51+
</span>
4752
</div>
48-
<div class="form--field"><%= pref_fields.check_box :warn_on_leaving_unsaved %></div>
49-
<div class="form--field"><%= pref_fields.check_box :auto_hide_popups %></div>
5053
<% end %>

app/views/users/new.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ See COPYRIGHT and LICENSE files for more details.
4848
html: { class: nil, autocomplete: "off" },
4949
data: {
5050
controller: "admin--users",
51+
turbo: false,
5152
"admin--users-password-auth-selected-value": @user.ldap_auth_source_id.blank?
5253
},
5354
as: :user do |f| %>

config/constants/settings/definition.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,10 @@ class Definition
333333
description: "Default sort order for activities",
334334
default: "asc"
335335
},
336+
disable_keyboard_shortcuts: {
337+
description: "Whether keyboard short cuts should be disabled (e.g. for better screen reader support)",
338+
default: false
339+
},
336340
default_language: {
337341
default: "en",
338342
allowed: -> { Redmine::I18n.all_languages }

config/initializers/menus.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@
203203
{ controller: "/my", action: "settings" },
204204
caption: :label_setting_plural,
205205
icon: "gear"
206+
menu.push :interface,
207+
{ controller: "/my", action: "interface" },
208+
caption: :label_interface,
209+
icon: "device-desktop"
206210
menu.push :password,
207211
{ controller: "/my", action: "password" },
208212
caption: :button_change_password,

0 commit comments

Comments
 (0)