Skip to content

Commit

Permalink
Use turbo frame and stream to create element
Browse files Browse the repository at this point in the history
By responding with a turbo-stream instead of js.erb,
we can replace the old Rail-UJS data-remote with a
turbo-frame.
  • Loading branch information
tvdeyen committed Sep 26, 2024
1 parent cfb4c5c commit 01e72ae
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 75 deletions.
4 changes: 2 additions & 2 deletions app/controllers/alchemy/admin/elements_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ def create
end
end
if @element.save
render :create
render :create, status: :created
else
@element.page_version = @page_version
@elements = @page.available_element_definitions
load_clipboard_items
render :new
render :new, status: :unprocessable_entity
end
end

Expand Down
9 changes: 9 additions & 0 deletions app/javascript/alchemy_admin/components/element_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ export class ElementEditor extends HTMLElement {
return
}

// When newly created, focus the element and refresh the preview
if (this.hasAttribute("created")) {
this.focusElement()
this.previewWindow?.refresh().then(() => {
this.focusElementPreview()
})
this.removeAttribute("created")
}

// Init GUI elements
ImageLoader.init(this)
fileEditors(
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/alchemy_admin/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class Dialog {
})

// Automatically close dialog on successful turbo submit
form.addEventListener("turbo:submit-end", (event) => {
form?.addEventListener("turbo:submit-end", (event) => {
if (event.detail.success) {
this.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
(nestable_element = element.nestable_elements.first) &&
Alchemy::Element.all_from_clipboard_for_parent_element(get_clipboard("elements"), element).none?
%>
<%= form_for [:admin, Alchemy::Element.new(name: nestable_element)],
remote: true, html: { class: 'add-nested-element-form', id: nil } do |f| %>
<%= f.hidden_field :name %>
<%= f.hidden_field :page_version_id, value: element.page_version_id %>
<%= f.hidden_field :parent_element_id, value: element.id %>
<button class="add-nestable-element-button" is="alchemy-button" data-turbo="false">
<%= Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) %>
</button>
<%= turbo_frame_tag("new_nested_element_#{element.id}") do %>
<%= form_for [:admin, Alchemy::Element.new(name: nestable_element)], html: { class: 'add-nested-element-form', id: nil } do |f| %>
<%= f.hidden_field :name %>
<%= f.hidden_field :page_version_id, value: element.page_version_id %>
<%= f.hidden_field :parent_element_id, value: element.id %>
<button class="add-nestable-element-button" is="alchemy-button">
<%= Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) %>
</button>
<% end %>
<% end %>
<% else %>
<%= link_to_dialog (nestable_element ? Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) : Alchemy.t("New Element")),
Expand Down
14 changes: 14 additions & 0 deletions app/views/alchemy/admin/elements/_clipboard_button.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<%= render Alchemy::Admin::ToolbarButton.new(
url: alchemy.admin_clipboard_path(remarkable_type: "elements"),
label: Alchemy.t("Show clipboard"),
icon: :clipboard,
icon_style: clipboard_empty?("elements") ? "line" : "fill",
dialog_options: {
title: Alchemy.t("Clipboard"),
size: "400x305"
},
link_options: {
id: "clipboard_button"
},
if_permitted_to: [:index, :alchemy_admin_clipboard]
) %>
2 changes: 2 additions & 0 deletions app/views/alchemy/admin/elements/_element.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
data-element-name="<%= element.name %>"
class="<%= element.css_classes.join(" ") %>"
<%= element.compact? ? "compact" : nil %>
<%= local_assigns[:created] ? "created" : nil %>
<%= element.fixed? ? "fixed" : nil %>
>
<% unless element.fixed? %>
Expand Down Expand Up @@ -68,6 +69,7 @@
<% if element.nestable_elements.any? %>
<div class="nestable-elements">
<%= content_tag :div,
id: "element_#{element.id}_nested_elements",
class: "nested-elements", data: {
'droppable-elements' => element.nestable_elements.join(' '),
'element-name' => element.name
Expand Down
28 changes: 15 additions & 13 deletions app/views/alchemy/admin/elements/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
<%= Alchemy.t(:no_more_elements_to_add) %>
<% end %>
<%- else -%>
<%= alchemy_form_for [:admin, @element] do |form| %>
<%= form.hidden_field :page_version_id %>
<%= form.input :name,
label: Alchemy.t(:element_of_type),
collection: elements_for_select(@elements),
prompt: Alchemy.t(:select_element),
selected: (@elements.first if @elements.count == 1),
input_html: {is: 'alchemy-select', autofocus: true} %>
<% if @elements.count == 1 %>
<%= form.hidden_field :name, value: @elements.first[:name] %>
<% end %>
<%= form.hidden_field :parent_element_id, value: @parent_element.try(:id) %>
<%= form.submit Alchemy.t(:add) %>
<%= turbo_frame_tag @element do %>
<%= alchemy_form_for [:admin, @element], remote: false do |form| %>
<%= form.hidden_field :page_version_id %>
<%= form.input :name,
label: Alchemy.t(:element_of_type),
collection: elements_for_select(@elements),
prompt: Alchemy.t(:select_element),
selected: (@elements.first if @elements.count == 1),
input_html: {is: 'alchemy-select', autofocus: true} %>
<% if @elements.count == 1 %>
<%= form.hidden_field :name, value: @elements.first[:name] %>
<% end %>
<%= form.hidden_field :parent_element_id, value: @parent_element.try(:id) %>
<%= form.submit Alchemy.t(:add) %>
<%- end -%>
<%- end -%>
<%- end -%>
35 changes: 0 additions & 35 deletions app/views/alchemy/admin/elements/create.js.erb

This file was deleted.

32 changes: 32 additions & 0 deletions app/views/alchemy/admin/elements/create.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<% opts = {
partial: "alchemy/admin/elements/element",
locals: {
element: Alchemy::ElementEditor.new(@element),
created: true
}
} %>
<% if @element.fixed? %>
<% target = "fixed_element_#{@element.id}" %>
<% elsif @element.parent_element %>
<% target = "element_#{@element.parent_element_id}_nested_elements" %>
<% else %>
<% target = "main-content-elements" %>
<% end %>
<%- if @cut_element_id -%>
<%= turbo_stream.remove "element_#{@cut_element_id}" %>
<% end %>
<% if @insert_at_top %>
<%= turbo_stream.prepend target, **opts %>
<% else %>
<%= turbo_stream.append target, **opts %>
<% end %>
<%= turbo_stream.replace "clipboard_button",
partial: "alchemy/admin/elements/clipboard_button" %>

<alchemy-growl>
<%= Alchemy.t(:successfully_added_element) %>
</alchemy-growl>
17 changes: 2 additions & 15 deletions app/views/alchemy/admin/elements/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,7 @@
},
if_permitted_to: [:create, Alchemy::Element]
) %>
<%= render Alchemy::Admin::ToolbarButton.new(
url: alchemy.admin_clipboard_path(remarkable_type: "elements"),
label: Alchemy.t("Show clipboard"),
icon: :clipboard,
icon_style: clipboard_empty?("elements") ? "line" : "fill",
dialog_options: {
title: Alchemy.t("Clipboard"),
size: "400x305"
},
link_options: {
id: "clipboard_button"
},
if_permitted_to: [:index, :alchemy_admin_clipboard]
) %>
<%= render "alchemy/admin/elements/clipboard_button" %>
<sl-tooltip content="<%= Alchemy.t("Collapse all elements") %>" placement="top-end" class="right">
<button id="collapse-all-elements-button" class="icon_button">
<alchemy-icon name="contract-up-down"></alchemy-icon>
Expand Down Expand Up @@ -53,7 +40,7 @@
<%= render @elements.map { |element| Alchemy::ElementEditor.new(element) } %>
</sl-tab-panel>
<% @fixed_elements.each do |element| %>
<sl-tab-panel name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
<sl-tab-panel id="fixed_element_<%= element.id %>" name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
<%= render Alchemy::ElementEditor.new(element) %>
</sl-tab-panel>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion spec/controllers/alchemy/admin/elements_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ module Alchemy

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

Expand Down

0 comments on commit 01e72ae

Please sign in to comment.