Skip to content

Commit

Permalink
Implement client-side with Stimulus
Browse files Browse the repository at this point in the history
Depend on [@hotwired/stimulus][] on the client-side. Add the client-side
dependency for `@hotwired/stimulus` to the `package.json`, , then
scaffold out the changes to the `application.js` and
`controllers/index.js` modules.

Next, migrate the jQuery-powered code into controllers: the `select`
controller to integrate with `selectize.js` and the `table` controller
to manage `<table>` elements.

Finally, render each necessary field (`belongs_to`, `has_many`,
`polymorphic`, `select`) with the `[data-controller="select"]` attribute
(powered by a new `Field#html_controller` method.

[@hotwired/stimulus]: https://stimulus.hotwired.dev
  • Loading branch information
seanpdoyle committed Feb 2, 2024
1 parent 2a1bf79 commit b0bccc4
Show file tree
Hide file tree
Showing 28 changed files with 2,669 additions and 122 deletions.
2,632 changes: 2,542 additions & 90 deletions app/assets/builds/administrate/application.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions app/assets/builds/administrate/application.js.map

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions app/assets/javascripts/administrate/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@ import "./add_jquery";
import {} from "jquery-ujs";
import "selectize/dist/js/selectize.min.js";

import "./components/associative";
import "./components/select";
import "./components/table";
import "./controllers";
5 changes: 0 additions & 5 deletions app/assets/javascripts/administrate/components/associative.js

This file was deleted.

3 changes: 0 additions & 3 deletions app/assets/javascripts/administrate/components/select.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Application } from "@hotwired/stimulus";

const application = Application.start();

// Configure Stimulus development experience
application.debug = false;
window.Stimulus = application;

export { application };
9 changes: 9 additions & 0 deletions app/assets/javascripts/administrate/controllers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Import and register all your controllers from the importmap under controllers/*

import { application } from "./application";

import SelectController from "./select_controller";
import TableController from "./table_controller";

application.register("select", SelectController);
application.register("table", TableController);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Controller } from "@hotwired/stimulus";
import $ from "jquery";

export default class extends Controller {
connect() {
$(this.element).selectize({});
}
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
$(function() {
var keycodes = { space: 32, enter: 13 };
import { Controller } from "@hotwired/stimulus";
import $ from "jquery";

var visitDataUrl = function(event) {
var keycodes = { space: 32, enter: 13 };

export default class extends Controller {
visitDataUrl(event) {
if (event.type == "click" ||
event.keyCode == keycodes.space ||
event.keyCode == keycodes.enter) {
Expand All @@ -16,8 +19,5 @@ $(function() {
window.location = window.location.protocol + '//' + window.location.host + dataUrl;
}
}
};

$("table").on("click", ".js-table-row", visitDataUrl);
$("table").on("keydown", ".js-table-row", visitDataUrl);
});
}
};
2 changes: 1 addition & 1 deletion app/views/administrate/application/_collection.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ to display a collection of resources in an HTML table.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
%>

<table aria-labelledby="<%= table_title %>">
<table aria-labelledby="<%= table_title %>" data-controller="table" data-action="click->table#visitDataUrl keydown->table#visitDataUrl">
<thead>
<tr>
<% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
Expand Down
3 changes: 2 additions & 1 deletion app/views/fields/belongs_to/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ that displays all possible records to associate with.
<div class="field-unit__field">
<%= f.select(field.permitted_attribute,
options_for_select(field.associated_resource_options, field.selected_option),
include_blank: field.include_blank_option) %>
{include_blank: field.include_blank_option},
data: {controller: field.html_controller}) %>
</div>
2 changes: 1 addition & 1 deletion app/views/fields/has_many/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ and is augmented with [Selectize].
<%= f.label field.attribute, for: "#{f.object_name}_#{field.attribute_key}" %>
</div>
<div class="field-unit__field">
<%= f.select(field.attribute_key, nil, {}, multiple: true) do %>
<%= f.select(field.attribute_key, nil, {}, multiple: true, data: {controller: field.html_controller}) do %>
<%= options_for_select(field.associated_resource_options, field.selected_options) %>
<% end %>
</div>
2 changes: 1 addition & 1 deletion app/views/fields/polymorphic/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This partial renders an input element for polymorphic relationships.

<div class="field-unit__field">
<%= pf.hidden_field(:type, value: field.class.name) %>
<%= pf.select(:value) do %>
<%= pf.select(:value, {}, data: {controller: field.html_controller}) do %>
<%= grouped_options_for_select(field.associated_resource_grouped_options, field.selected_global_id, prompt: true) %>
<% end %>
</div>
Expand Down
3 changes: 2 additions & 1 deletion app/views/fields/select/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ to be displayed on a resource's edit form page.
field.selectable_options,
field.data,
),
include_blank: field.include_blank_option
{include_blank: field.include_blank_option},
data: {controller: field.html_controller}
)
%>
</div>
4 changes: 4 additions & 0 deletions lib/administrate/field/associative.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def associated_class_name
end
end

def html_controller
"select"
end

private

def associated_dashboard
Expand Down
4 changes: 4 additions & 0 deletions lib/administrate/field/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def html_class
self.class.html_class
end

def html_controller
nil
end

def name
attribute.to_s
end
Expand Down
4 changes: 4 additions & 0 deletions lib/administrate/field/has_one.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def linkable?
data.try(:persisted?)
end

def html_controller
"select"
end

private

def resolver
Expand Down
4 changes: 4 additions & 0 deletions lib/administrate/field/select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def active_record_enum?
def active_record_enum_values
resource.class.defined_enums[attribute.to_s].map(&:first)
end

def html_controller
"select"
end
end
end
end
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"lint:css": "stylelint app/assets/stylesheets/administrate/**/*.scss"
},
"dependencies": {
"@hotwired/stimulus": "^3.2.2",
"esbuild": "^0.18.11",
"jquery": "^3.7.0",
"jquery-ujs": "^1.2.3",
Expand Down
1 change: 1 addition & 0 deletions spec/administrate/views/fields/has_many/_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
has_many = double(
attribute_key: :associated_object_ids,
attribute: :associated_objects,
html_controller: "select",
)

render(
Expand Down
6 changes: 4 additions & 2 deletions spec/administrate/views/fields/select/_edit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
data: false,
selectable_options: [true, false, nil],
include_blank_option: false,
html_controller: "select",
)

render(
Expand All @@ -18,7 +19,7 @@
)

expect(rendered).to have_css(
%{select[name="customer[email_subscriber]"]
%{select[name="customer[email_subscriber]"][data-controller~=select]
option[value="false"][selected="selected"]},
)
end
Expand All @@ -31,6 +32,7 @@
data: "Yes",
selectable_options: ["Yes", "No"],
include_blank_option: "Unknown",
html_controller: "select",
)

render(
Expand All @@ -39,7 +41,7 @@
)

expect(rendered).to have_css(
%{select[name="customer[email_subscriber]"] option[value=""]},
%{select[name="customer[email_subscriber]"][data-controller~="select"] option[value=""]},
text: "Unknown",
)
end
Expand Down
2 changes: 1 addition & 1 deletion spec/example_app/spec/features/log_search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ def have_records_table(rows:)
end

def submit_search
page.execute_script("$('.search').submit()")
page.find_field("Search").send_keys(:enter)
end
end
2 changes: 1 addition & 1 deletion spec/features/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def page_params
end

def submit_search
page.execute_script("$('.search').submit()")
page.find_field("Search").send_keys(:enter)
end

def order_row_match(order)
Expand Down
12 changes: 12 additions & 0 deletions spec/lib/fields/belongs_to_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
)
end

describe "#html_controller" do
it "returns select" do
page = :show
owner = double
field = Administrate::Field::BelongsTo.new(:owner, owner, page)

html_controller = field.html_controller

expect(html_controller).to eq("select")
end
end

describe "#to_partial_path" do
it "returns a partial based on the page being rendered" do
page = :show
Expand Down
12 changes: 12 additions & 0 deletions spec/lib/fields/has_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
require "support/mock_relation"

describe Administrate::Field::HasMany do
describe "#html_controller" do
it "returns select" do
page = :show
items = double
field = Administrate::Field::HasMany.new(:items, items, page)

html_controller = field.html_controller

expect(html_controller).to eq("select")
end
end

describe "#to_partial_path" do
it "returns a partial based on the page being rendered" do
page = :show
Expand Down
11 changes: 11 additions & 0 deletions spec/lib/fields/polymorphic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
describe Administrate::Field::Polymorphic do
include FieldMatchers

describe "#html_controller" do
it "returns select" do
page = :show
field = Administrate::Field::Polymorphic.new(:foo, "hello", page)

html_controller = field.html_controller

expect(html_controller).to eq("select")
end
end

describe "#to_partial_path" do
it "returns a partial based on the page being rendered" do
page = :show
Expand Down
17 changes: 17 additions & 0 deletions spec/lib/fields/select_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
require "administrate/field/select"

describe Administrate::Field::Select do
describe "#html_controller" do
it "returns select" do
customer = create(:customer)
field = described_class.new(
:email_subscriber,
"yes",
:_page_,
resource: customer,
collection: ["no", "yes", "absolutely"],
)

html_controller = field.html_controller

expect(html_controller).to eq("select")
end
end

describe "#selectable_options" do
it "works when :collection is an array" do
customer = create(:customer)
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz#6526c7e1b40d5b9f0a222c6b767c22f6fb97aa57"
integrity sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==

"@hotwired/stimulus@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==

"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
Expand Down

0 comments on commit b0bccc4

Please sign in to comment.