Skip to content

Commit c37047b

Browse files
authored
Merge branch 'main' into dependabot/bundler/rubocop-1.75.4
2 parents e7f4c82 + 6417119 commit c37047b

File tree

71 files changed

+4311
-3418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4311
-3418
lines changed

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ group :test do
106106
# # Easy installation and use of chromedriver to run system tests with Chrome
107107
# gem 'webdrivers'
108108
# RuboCop RSpec for RSpec-specific code analysis
109+
gem 'rubocop-capybara'
110+
gem 'rubocop-factory_bot'
111+
gem 'rubocop-rails'
109112
gem 'rubocop-rspec'
113+
gem 'rubocop-rspec_rails'
110114
# RSpec for unit testing
111115
gem 'rspec'
112116
# RSpec Rails integration

Gemfile.lock

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ PATH
4949
premailer-rails
5050
pundit (>= 2.1, < 2.6)
5151
pundit-resources
52+
rack-attack
5253
rack-cors (>= 1.1.1, < 2.1.0)
5354
rack-mini-profiler
5455
rails (>= 5.2.2, < 7.2.0)
@@ -165,18 +166,18 @@ GEM
165166
unf
166167
ast (2.4.3)
167168
aws-eventstream (1.3.2)
168-
aws-partitions (1.1093.0)
169-
aws-sdk-core (3.222.3)
169+
aws-partitions (1.1103.0)
170+
aws-sdk-core (3.224.0)
170171
aws-eventstream (~> 1, >= 1.3.0)
171172
aws-partitions (~> 1, >= 1.992.0)
172173
aws-sigv4 (~> 1.9)
173174
base64
174175
jmespath (~> 1, >= 1.6.1)
175176
logger
176-
aws-sdk-kms (1.99.0)
177+
aws-sdk-kms (1.101.0)
177178
aws-sdk-core (~> 3, >= 3.216.0)
178179
aws-sigv4 (~> 1.5)
179-
aws-sdk-s3 (1.184.0)
180+
aws-sdk-s3 (1.186.1)
180181
aws-sdk-core (~> 3, >= 3.216.0)
181182
aws-sdk-kms (~> 1)
182183
aws-sigv4 (~> 1.5)
@@ -197,7 +198,7 @@ GEM
197198
bindex (0.8.1)
198199
binding_of_caller (1.0.1)
199200
debug_inspector (>= 1.2.0)
200-
bootsnap (1.18.4)
201+
bootsnap (1.18.6)
201202
msgpack (~> 1.2)
202203
bootstrap (5.3.5)
203204
popper_js (>= 2.11.8, < 3)
@@ -226,7 +227,7 @@ GEM
226227
coercible (1.0.0)
227228
descendants_tracker (~> 0.0.1)
228229
concurrent-ruby (1.3.5)
229-
connection_pool (2.5.2)
230+
connection_pool (2.5.3)
230231
coveralls_reborn (0.28.0)
231232
simplecov (~> 0.22.0)
232233
term-ansicolor (~> 1.7)
@@ -244,7 +245,7 @@ GEM
244245
tilt
245246
database_cleaner (2.1.0)
246247
database_cleaner-active_record (>= 2, < 3)
247-
database_cleaner-active_record (2.2.0)
248+
database_cleaner-active_record (2.2.1)
248249
activerecord (>= 5.a)
249250
database_cleaner-core (~> 2.0.0)
250251
database_cleaner-core (2.0.1)
@@ -354,8 +355,8 @@ GEM
354355
google-protobuf (4.30.2-x86_64-linux)
355356
bigdecimal
356357
rake (>= 13)
357-
groupdate (6.5.1)
358-
activesupport (>= 7)
358+
groupdate (6.6.0)
359+
activesupport (>= 7.1)
359360
hashie (5.0.0)
360361
highline (3.1.2)
361362
reline
@@ -427,7 +428,7 @@ GEM
427428
rb-fsevent (~> 0.10, >= 0.10.3)
428429
rb-inotify (~> 0.9, >= 0.9.10)
429430
logger (1.7.0)
430-
loofah (2.24.0)
431+
loofah (2.24.1)
431432
crass (~> 1.0.2)
432433
nokogiri (>= 1.12.0)
433434
mail (2.8.1)
@@ -454,7 +455,7 @@ GEM
454455
mobility-actiontext (1.1.1)
455456
actiontext (>= 6.0)
456457
mobility (~> 1.2)
457-
msgpack (1.7.2)
458+
msgpack (1.8.0)
458459
multi_json (1.15.0)
459460
multipart-post (2.4.1)
460461
mutex_m (0.3.0)
@@ -497,7 +498,7 @@ GEM
497498
pry (0.15.2)
498499
coderay (~> 1.1)
499500
method_source (~> 1.0)
500-
psych (5.2.3)
501+
psych (5.2.6)
501502
date
502503
stringio
503504
public_suffix (6.0.1)
@@ -506,7 +507,9 @@ GEM
506507
pundit (2.5.0)
507508
activesupport (>= 3.0.0)
508509
racc (1.8.1)
509-
rack (3.1.13)
510+
rack (3.1.14)
511+
rack-attack (6.7.0)
512+
rack (>= 1.0, < 4)
510513
rack-cors (2.0.2)
511514
rack (>= 2.0.0)
512515
rack-mini-profiler (3.3.1)
@@ -515,7 +518,7 @@ GEM
515518
base64 (>= 0.1.0)
516519
logger (>= 1.6.0)
517520
rack (>= 3.0.0, < 4)
518-
rack-session (2.1.0)
521+
rack-session (2.1.1)
519522
base64 (>= 0.1.0)
520523
rack (>= 3.0.0)
521524
rack-test (2.2.0)
@@ -645,9 +648,25 @@ GEM
645648
rubocop-ast (1.44.1)
646649
parser (>= 3.3.7.2)
647650
prism (~> 1.4)
651+
rubocop-capybara (2.22.1)
652+
lint_roller (~> 1.1)
653+
rubocop (~> 1.72, >= 1.72.1)
654+
rubocop-factory_bot (2.27.1)
655+
lint_roller (~> 1.1)
656+
rubocop (~> 1.72, >= 1.72.1)
657+
rubocop-rails (2.30.3)
658+
activesupport (>= 4.2.0)
659+
lint_roller (~> 1.1)
660+
rack (>= 1.1)
661+
rubocop (>= 1.72.1, < 2.0)
662+
rubocop-ast (>= 1.38.0, < 2.0)
648663
rubocop-rspec (3.6.0)
649664
lint_roller (~> 1.1)
650665
rubocop (~> 1.72, >= 1.72.1)
666+
rubocop-rspec_rails (2.31.0)
667+
lint_roller (~> 1.1)
668+
rubocop (~> 1.72, >= 1.72.1)
669+
rubocop-rspec (~> 3.5)
651670
ruby-openai (8.1.0)
652671
event_stream_parser (>= 0.3.0, < 2.0.0)
653672
faraday (>= 1)
@@ -664,16 +683,16 @@ GEM
664683
sassc-embedded (1.80.4)
665684
sass-embedded (~> 1.80)
666685
securerandom (0.4.1)
667-
selenium-webdriver (4.31.0)
686+
selenium-webdriver (4.32.0)
668687
base64 (~> 0.2)
669688
logger (~> 1.4)
670689
rexml (~> 3.2, >= 3.2.5)
671690
rubyzip (>= 1.2.2, < 3.0)
672691
websocket (~> 1.0)
673-
sentry-rails (5.23.0)
692+
sentry-rails (5.24.0)
674693
railties (>= 5.0)
675-
sentry-ruby (~> 5.23.0)
676-
sentry-ruby (5.23.0)
694+
sentry-ruby (~> 5.24.0)
695+
sentry-ruby (5.24.0)
677696
bigdecimal
678697
concurrent-ruby (~> 1.0, >= 1.0.2)
679698
shoulda-callback-matchers (1.1.4)
@@ -804,7 +823,11 @@ DEPENDENCIES
804823
rspec-rails
805824
rswag
806825
rubocop
826+
rubocop-capybara
827+
rubocop-factory_bot
828+
rubocop-rails
807829
rubocop-rspec
830+
rubocop-rspec_rails
808831
selenium-webdriver
809832
sentry-rails
810833
sentry-ruby

app/assets/stylesheets/better_together/forms.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,7 @@ input[type="range"]::-ms-thumb {
110110
trix-toolbar .trix-input--dialog {
111111
color: $light-background-text-color;
112112
}
113+
114+
.ss-content.form-select {
115+
overflow-y: auto;
116+
}

app/controllers/better_together/resource_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ def resource_instance(attrs = {})
7474
instance_variable_set("@#{resource_name}", @resource)
7575
end
7676

77+
def resource_instance_collection
78+
resource_collection
79+
end
80+
7781
def resource_name(plural: false)
7882
name = resource_class.name.demodulize
7983
name = name.pluralize if plural
@@ -86,7 +90,7 @@ def resource_params
8690
end
8791

8892
def set_resource_instance
89-
@resource = resource_collection.find(id_param)
93+
@resource = resource_instance_collection.find(id_param)
9094
instance_variable_set("@#{resource_name}", @resource)
9195
end
9296

app/helpers/better_together/form_helper.rb

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,53 @@
22

33
module BetterTogether
44
# Facilitates building forms by pulling out reusable components and logic
5-
module FormHelper
5+
module FormHelper # rubocop:todo Metrics/ModuleLength
6+
def class_field_required(klass, field)
7+
klass.validators_on(field).any? { |v| v.kind == :presence }
8+
end
9+
10+
# rubocop:todo Metrics/MethodLength
11+
def label_select_field(form) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
12+
# rubocop:todo Metrics/BlockLength
13+
content_tag(:div, class: 'label-select', data: { controller: 'better_together--dependent-fields' }) do
14+
field_label = required_label(
15+
form,
16+
:label,
17+
class: 'form-label'
18+
)
19+
20+
label_select_id = dom_id(form.object, :label).split('-').first
21+
select_field = form.select(
22+
:select_label,
23+
form.object.class.label_options,
24+
{ prompt: 'Select Label', required: true },
25+
class: 'form-select',
26+
id: label_select_id,
27+
'data-better_together--dependent-fields-target' => 'controlField'
28+
)
29+
30+
other_text_field = content_tag(
31+
:div,
32+
class: "other-label #{dom_class(form.object, :label_text_field)}",
33+
data: {
34+
'dependent-fields-control' => label_select_id
35+
},
36+
'data-better_together--dependent-fields-target' => 'dependentField',
37+
"data-show-if-control_#{label_select_id}" => 'other'
38+
) do
39+
form.text_field(
40+
:text_label,
41+
class: 'form-control mt-3',
42+
placeholder: t('better_together.labelable.custom-label-placeholder')
43+
)
44+
end
45+
46+
field_label + select_field + other_text_field
47+
end
48+
# rubocop:enable Metrics/BlockLength
49+
end
50+
# rubocop:enable Metrics/MethodLength
51+
652
def language_select_field(form: nil, field_name: :locale, selected_locale: I18n.locale, options: {},
753
html_options: {})
854
# Merge default options with the provided options
@@ -85,7 +131,7 @@ def required_label(form_or_object, field, **options) # rubocop:todo Metrics/AbcS
85131
# Use the provided class_name for validation check if present, otherwise use the object's class
86132
end
87133
klass = class_name ? class_name.constantize : object.class
88-
is_required = klass.validators_on(field).any? { |v| v.kind == :presence }
134+
is_required = class_field_required(klass, field)
89135

90136
# Append asterisk for required fields
91137
label_text += " <span class='required-indicator'>*</span>" if is_required

app/helpers/better_together/navigation_items_helper.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ def render_platform_header_nav_items
109109

110110
def route_names_for_select(nav_item = nil)
111111
options_for_select(
112-
BetterTogether::NavigationItem.route_names.map { |name, route| [I18n.t("route_names.#{name}"), route] },
112+
BetterTogether::NavigationItem.route_names.map do |name, route|
113+
[I18n.t("better_together.navigation_items.route_names.#{name}"), route]
114+
end,
113115
(nav_item ? nav_item.route_name : nil)
114116
)
115117
end

app/javascript/controllers/better_together/tabs_controller.js

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,10 @@ export default class extends Controller {
77
static targets = ["tab"];
88

99
connect() {
10-
// this.initializeFirstTabs();
1110
this.activateTabFromHash();
1211
this.setupTabChangeListener();
1312
}
1413

15-
// initializeFirstTabs() {
16-
// // Ensure the first tab in each group is active and shown
17-
// const tabGroups = this.element.querySelectorAll('[data-bs-target]');
18-
// tabGroups.forEach((tab) => {
19-
// // Skip tabs inside the localized-fields class
20-
// if (tab.closest('.localized-fields')) return;
21-
22-
// const tabPane = this.element.querySelector(tab.dataset.bsTarget);
23-
// if (tabPane) {
24-
// const nestedTabs = tabPane.querySelectorAll('[data-bs-target]');
25-
// if (nestedTabs.length > 0) {
26-
// const firstNestedTab = nestedTabs[0];
27-
// const firstNestedTabTarget = tabPane.querySelector(firstNestedTab.dataset.bsTarget);
28-
29-
// nestedTabs.forEach((nestedTab) => {
30-
// nestedTab.classList.remove('active');
31-
// });
32-
// firstNestedTab.classList.add('active');
33-
34-
// if (firstNestedTabTarget) {
35-
// const nestedTabPanes = tabPane.querySelectorAll('.tab-pane');
36-
// nestedTabPanes.forEach((nestedPane) => {
37-
// nestedPane.classList.remove('active');
38-
// nestedPane.classList.remove('show');
39-
// });
40-
41-
// firstNestedTabTarget.classList.add('active');
42-
// firstNestedTabTarget.classList.add('show');
43-
// }
44-
// }
45-
// }
46-
// });
47-
// }
48-
4914
activateTabFromHash() {
5015
const hash = window.location.hash;
5116
if (hash) {
@@ -70,29 +35,6 @@ export default class extends Controller {
7035
if (tabTarget) {
7136
tabTarget.classList.add('active');
7237
tabTarget.classList.add('show');
73-
74-
// // Activate the first tab inside the activated tab pane
75-
// const nestedTabs = tabTarget.querySelectorAll('[data-bs-target]');
76-
// if (nestedTabs.length > 0) {
77-
// const firstNestedTab = nestedTabs[0];
78-
// const firstNestedTabTarget = tabTarget.querySelector(firstNestedTab.dataset.bsTarget);
79-
80-
// nestedTabs.forEach((nestedTab) => {
81-
// nestedTab.classList.remove('active');
82-
// });
83-
// firstNestedTab.classList.add('active');
84-
85-
// if (firstNestedTabTarget) {
86-
// const nestedTabPanes = tabTarget.querySelectorAll('.tab-pane');
87-
// nestedTabPanes.forEach((nestedPane) => {
88-
// nestedPane.classList.remove('active');
89-
// nestedPane.classList.remove('show');
90-
// });
91-
92-
// firstNestedTabTarget.classList.add('active');
93-
// firstNestedTabTarget.classList.add('show');
94-
// }
95-
// }
9638
}
9739

9840
// Check if the selected tab is nested and activate its parent tab
@@ -108,13 +50,14 @@ export default class extends Controller {
10850
}
10951

11052
setupTabChangeListener() {
111-
const tabLinks = this.tabTargets;
112-
tabLinks.forEach((link) => {
113-
// Skip tabs inside the localized-fields class
53+
this.tabTargets.forEach((link) => {
11454
if (link.closest('.localized-fields')) return;
11555

11656
link.addEventListener("shown.bs.tab", (event) => {
117-
history.pushState({}, "", event.target.getAttribute("data-bs-target"))
57+
const targetHash = event.target.getAttribute("data-bs-target");
58+
if (targetHash) {
59+
history.pushState({}, "", targetHash); // Add the hash to the address bar
60+
}
11861
});
11962
});
12063
}

0 commit comments

Comments
 (0)