Skip to content

Commit 01e72ae

Browse files
committed
Use turbo frame and stream to create element
By responding with a turbo-stream instead of js.erb, we can replace the old Rail-UJS data-remote with a turbo-frame.
1 parent cfb4c5c commit 01e72ae

File tree

11 files changed

+87
-75
lines changed

11 files changed

+87
-75
lines changed

app/controllers/alchemy/admin/elements_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ def create
4141
end
4242
end
4343
if @element.save
44-
render :create
44+
render :create, status: :created
4545
else
4646
@element.page_version = @page_version
4747
@elements = @page.available_element_definitions
4848
load_clipboard_items
49-
render :new
49+
render :new, status: :unprocessable_entity
5050
end
5151
end
5252

app/javascript/alchemy_admin/components/element_editor.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ export class ElementEditor extends HTMLElement {
4040
return
4141
}
4242

43+
// When newly created, focus the element and refresh the preview
44+
if (this.hasAttribute("created")) {
45+
this.focusElement()
46+
this.previewWindow?.refresh().then(() => {
47+
this.focusElementPreview()
48+
})
49+
this.removeAttribute("created")
50+
}
51+
4352
// Init GUI elements
4453
ImageLoader.init(this)
4554
fileEditors(

app/javascript/alchemy_admin/dialog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export class Dialog {
163163
})
164164

165165
// Automatically close dialog on successful turbo submit
166-
form.addEventListener("turbo:submit-end", (event) => {
166+
form?.addEventListener("turbo:submit-end", (event) => {
167167
if (event.detail.success) {
168168
this.close()
169169
}

app/views/alchemy/admin/elements/_add_nested_element_form.html.erb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
(nestable_element = element.nestable_elements.first) &&
44
Alchemy::Element.all_from_clipboard_for_parent_element(get_clipboard("elements"), element).none?
55
%>
6-
<%= form_for [:admin, Alchemy::Element.new(name: nestable_element)],
7-
remote: true, html: { class: 'add-nested-element-form', id: nil } do |f| %>
8-
<%= f.hidden_field :name %>
9-
<%= f.hidden_field :page_version_id, value: element.page_version_id %>
10-
<%= f.hidden_field :parent_element_id, value: element.id %>
11-
<button class="add-nestable-element-button" is="alchemy-button" data-turbo="false">
12-
<%= Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) %>
13-
</button>
6+
<%= turbo_frame_tag("new_nested_element_#{element.id}") do %>
7+
<%= form_for [:admin, Alchemy::Element.new(name: nestable_element)], html: { class: 'add-nested-element-form', id: nil } do |f| %>
8+
<%= f.hidden_field :name %>
9+
<%= f.hidden_field :page_version_id, value: element.page_version_id %>
10+
<%= f.hidden_field :parent_element_id, value: element.id %>
11+
<button class="add-nestable-element-button" is="alchemy-button">
12+
<%= Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) %>
13+
</button>
14+
<% end %>
1415
<% end %>
1516
<% else %>
1617
<%= link_to_dialog (nestable_element ? Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) : Alchemy.t("New Element")),
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<%= render Alchemy::Admin::ToolbarButton.new(
2+
url: alchemy.admin_clipboard_path(remarkable_type: "elements"),
3+
label: Alchemy.t("Show clipboard"),
4+
icon: :clipboard,
5+
icon_style: clipboard_empty?("elements") ? "line" : "fill",
6+
dialog_options: {
7+
title: Alchemy.t("Clipboard"),
8+
size: "400x305"
9+
},
10+
link_options: {
11+
id: "clipboard_button"
12+
},
13+
if_permitted_to: [:index, :alchemy_admin_clipboard]
14+
) %>

app/views/alchemy/admin/elements/_element.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
data-element-name="<%= element.name %>"
55
class="<%= element.css_classes.join(" ") %>"
66
<%= element.compact? ? "compact" : nil %>
7+
<%= local_assigns[:created] ? "created" : nil %>
78
<%= element.fixed? ? "fixed" : nil %>
89
>
910
<% unless element.fixed? %>
@@ -68,6 +69,7 @@
6869
<% if element.nestable_elements.any? %>
6970
<div class="nestable-elements">
7071
<%= content_tag :div,
72+
id: "element_#{element.id}_nested_elements",
7173
class: "nested-elements", data: {
7274
'droppable-elements' => element.nestable_elements.join(' '),
7375
'element-name' => element.name

app/views/alchemy/admin/elements/_form.html.erb

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
<%= Alchemy.t(:no_more_elements_to_add) %>
44
<% end %>
55
<%- else -%>
6-
<%= alchemy_form_for [:admin, @element] do |form| %>
7-
<%= form.hidden_field :page_version_id %>
8-
<%= form.input :name,
9-
label: Alchemy.t(:element_of_type),
10-
collection: elements_for_select(@elements),
11-
prompt: Alchemy.t(:select_element),
12-
selected: (@elements.first if @elements.count == 1),
13-
input_html: {is: 'alchemy-select', autofocus: true} %>
14-
<% if @elements.count == 1 %>
15-
<%= form.hidden_field :name, value: @elements.first[:name] %>
16-
<% end %>
17-
<%= form.hidden_field :parent_element_id, value: @parent_element.try(:id) %>
18-
<%= form.submit Alchemy.t(:add) %>
6+
<%= turbo_frame_tag @element do %>
7+
<%= alchemy_form_for [:admin, @element], remote: false do |form| %>
8+
<%= form.hidden_field :page_version_id %>
9+
<%= form.input :name,
10+
label: Alchemy.t(:element_of_type),
11+
collection: elements_for_select(@elements),
12+
prompt: Alchemy.t(:select_element),
13+
selected: (@elements.first if @elements.count == 1),
14+
input_html: {is: 'alchemy-select', autofocus: true} %>
15+
<% if @elements.count == 1 %>
16+
<%= form.hidden_field :name, value: @elements.first[:name] %>
17+
<% end %>
18+
<%= form.hidden_field :parent_element_id, value: @parent_element.try(:id) %>
19+
<%= form.submit Alchemy.t(:add) %>
20+
<%- end -%>
1921
<%- end -%>
2022
<%- end -%>

app/views/alchemy/admin/elements/create.js.erb

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<% opts = {
2+
partial: "alchemy/admin/elements/element",
3+
locals: {
4+
element: Alchemy::ElementEditor.new(@element),
5+
created: true
6+
}
7+
} %>
8+
9+
<% if @element.fixed? %>
10+
<% target = "fixed_element_#{@element.id}" %>
11+
<% elsif @element.parent_element %>
12+
<% target = "element_#{@element.parent_element_id}_nested_elements" %>
13+
<% else %>
14+
<% target = "main-content-elements" %>
15+
<% end %>
16+
17+
<%- if @cut_element_id -%>
18+
<%= turbo_stream.remove "element_#{@cut_element_id}" %>
19+
<% end %>
20+
21+
<% if @insert_at_top %>
22+
<%= turbo_stream.prepend target, **opts %>
23+
<% else %>
24+
<%= turbo_stream.append target, **opts %>
25+
<% end %>
26+
27+
<%= turbo_stream.replace "clipboard_button",
28+
partial: "alchemy/admin/elements/clipboard_button" %>
29+
30+
<alchemy-growl>
31+
<%= Alchemy.t(:successfully_added_element) %>
32+
</alchemy-growl>

app/views/alchemy/admin/elements/index.html.erb

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,7 @@
1212
},
1313
if_permitted_to: [:create, Alchemy::Element]
1414
) %>
15-
<%= render Alchemy::Admin::ToolbarButton.new(
16-
url: alchemy.admin_clipboard_path(remarkable_type: "elements"),
17-
label: Alchemy.t("Show clipboard"),
18-
icon: :clipboard,
19-
icon_style: clipboard_empty?("elements") ? "line" : "fill",
20-
dialog_options: {
21-
title: Alchemy.t("Clipboard"),
22-
size: "400x305"
23-
},
24-
link_options: {
25-
id: "clipboard_button"
26-
},
27-
if_permitted_to: [:index, :alchemy_admin_clipboard]
28-
) %>
15+
<%= render "alchemy/admin/elements/clipboard_button" %>
2916
<sl-tooltip content="<%= Alchemy.t("Collapse all elements") %>" placement="top-end" class="right">
3017
<button id="collapse-all-elements-button" class="icon_button">
3118
<alchemy-icon name="contract-up-down"></alchemy-icon>
@@ -53,7 +40,7 @@
5340
<%= render @elements.map { |element| Alchemy::ElementEditor.new(element) } %>
5441
</sl-tab-panel>
5542
<% @fixed_elements.each do |element| %>
56-
<sl-tab-panel name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
43+
<sl-tab-panel id="fixed_element_<%= element.id %>" name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
5744
<%= render Alchemy::ElementEditor.new(element) %>
5845
</sl-tab-panel>
5946
<% end %>

spec/controllers/alchemy/admin/elements_controller_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ module Alchemy
147147

148148
it "should create an element from clipboard" do
149149
post :create, params: {paste_from_clipboard: element_in_clipboard.id, element: {page_version_id: page_version.id}}, xhr: true
150-
expect(response.status).to eq(200)
150+
expect(response.status).to eq(201)
151151
expect(response.body).to match(/Successfully added new element/)
152152
end
153153

0 commit comments

Comments
 (0)