Skip to content

Commit

Permalink
Merge pull request #3054 from AlchemyCMS/page-update-turbo-stream
Browse files Browse the repository at this point in the history
Use turbo streams to update page from configure dialog
  • Loading branch information
tvdeyen authored Sep 27, 2024
2 parents 34f8313 + 5fac280 commit 8d4c097
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 108 deletions.
7 changes: 4 additions & 3 deletions app/controllers/alchemy/admin/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,12 @@ def render_errors_or_redirect(object, redirect_url, flash_notice)
#
def do_redirect_to(url_or_path)
respond_to do |format|
format.js {
format.js do
@redirect_url = url_or_path
render :redirect
}
format.html { redirect_to url_or_path }
end
format.turbo_stream { redirect_to(url_or_path) }
format.html { redirect_to(url_or_path) }
end
end

Expand Down
1 change: 1 addition & 0 deletions app/controllers/alchemy/admin/layoutpages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def update
@page = Page.find(params[:id])
if @page.update(page_params)
@notice = Alchemy.t("Page saved", name: @page.name)
@while_page_edit = request.referer.include?("edit")
render "alchemy/admin/pages/update"
else
render :edit, status: :unprocessable_entity
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/alchemy/admin/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PagesController < ResourcesController
unless: -> { @page_root },
only: [:index]

before_action :set_view, only: [:index]
before_action :set_view, only: [:index, :update]

before_action :set_page_version, only: [:show, :edit]

Expand Down Expand Up @@ -131,6 +131,10 @@ def update
@notice = Alchemy.t("Page saved", name: @page.name)
@while_page_edit = request.referer.include?("edit")

if @view == "list"
flash[:notice] = @notice
end

unless @while_page_edit
@tree = serialized_page_tree
end
Expand Down
12 changes: 0 additions & 12 deletions app/javascript/alchemy_admin/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,7 @@ export class Dialog {

// Initializes the Dialog body
init() {
const turbo_frame = this.dialog_body[0].querySelector("turbo-frame")

Hotkeys(this.dialog_body)

// Re-render dialog body if turbo frame render returned error
if (turbo_frame) {
turbo_frame.addEventListener("turbo:frame-render", (event) => {
if (!event.detail.fetchResponse.ok) {
this.watch_remote_forms()
}
})
}

this.watch_remote_forms()
}

Expand Down
12 changes: 7 additions & 5 deletions app/views/alchemy/admin/layoutpages/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<%= alchemy_form_for [:admin, @page], url: alchemy.admin_layoutpage_path(@page), class: 'edit_page' do |f| %>
<%= f.input :name, autofocus: true %>
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
<%= turbo_frame_tag @page do %>
<%= alchemy_form_for [:admin, @page], url: alchemy.admin_layoutpage_path(@page), class: 'edit_page', remote: false do |f| %>
<%= f.input :name, autofocus: true %>
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
<% end %>
<%= f.submit Alchemy.t(:save) %>
<% end %>
<%= f.submit Alchemy.t(:save) %>
<% end %>
2 changes: 1 addition & 1 deletion app/views/alchemy/admin/pages/_current_page.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="page_status_and_name" id="page_<%= current_page.id %>_status">
<div class="page_status_and_name" id="locked_page_<%= current_page.id %>">
<%= render 'alchemy/admin/pages/page_infos', page: current_page %>
<%= render 'alchemy/admin/pages/page_status', page: current_page %>
</div>
83 changes: 43 additions & 40 deletions app/views/alchemy/admin/pages/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,55 +1,58 @@
<%= alchemy_form_for [:admin, @page], class: 'edit_page' do |f| %>
<% unless @page.language_root? || @page.layoutpage %>
<%= render Alchemy::Admin::PageSelect.new(@page.parent) do %>
<%= f.input :parent_id, required: true %>
<%= turbo_frame_tag @page do %>
<%= alchemy_form_for [:admin, @page], class: 'edit_page', remote: false do |f| %>
<% unless @page.language_root? || @page.layoutpage %>
<%= render Alchemy::Admin::PageSelect.new(@page.parent) do %>
<%= f.input :parent_id, required: true %>
<% end %>
<% end %>
<% end %>

<div class="input check_boxes">
<label class="control-label"><%= Alchemy.t(:page_status) %></label>
<div class="control_group">
<%= render 'alchemy/admin/pages/publication_fields' %>
<%= page_status_checkbox(@page, :restricted) %>
<% if configuration(:sitemap)['show_flag'] %>
<%= page_status_checkbox(@page, :sitemap) %>
<% end %>
<div class="input check_boxes">
<label class="control-label"><%= Alchemy.t(:page_status) %></label>
<div class="control_group">
<%= render 'alchemy/admin/pages/publication_fields' %>
<%= page_status_checkbox(@page, :restricted) %>
<% if configuration(:sitemap)['show_flag'] %>
<%= page_status_checkbox(@page, :sitemap) %>
<% end %>
</div>
</div>
</div>

<%= f.input :name, autofocus: true %>
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug}, label: Alchemy::Page.human_attribute_name(:slug) %>
<alchemy-char-counter max-chars="60">
<%= f.input :title %>
</alchemy-char-counter>
<%= f.input :name, autofocus: true %>
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug}, label: Alchemy::Page.human_attribute_name(:slug) %>
<alchemy-char-counter max-chars="60">
<%= f.input :title %>
</alchemy-char-counter>

<% if Alchemy.enable_searchable %>
<div class="input check_boxes">
<label class="control-label"><%= Alchemy.t(:fulltext_search) %></label>
<div class="control_group">
<%= page_status_checkbox(@page, :searchable) %>
</div>
</div>
<% end %>

<% if Alchemy.enable_searchable %>
<div class="input check_boxes">
<label class="control-label"><%= Alchemy.t(:fulltext_search) %></label>
<label class="control-label"><%= Alchemy.t(:search_engines) %></label>
<div class="control_group">
<%= page_status_checkbox(@page, :searchable) %>
<%= page_status_checkbox(@page, :robot_index) %>
<%= page_status_checkbox(@page, :robot_follow) %>
</div>
</div>
<% end %>

<div class="input check_boxes">
<label class="control-label"><%= Alchemy.t(:search_engines) %></label>
<div class="control_group">
<%= page_status_checkbox(@page, :robot_index) %>
<%= page_status_checkbox(@page, :robot_follow) %>
</div>
</div>
<alchemy-char-counter max-chars="160">
<%= f.input :meta_description, as: 'text' %>
</alchemy-char-counter>

<alchemy-char-counter max-chars="160">
<%= f.input :meta_description, as: 'text' %>
</alchemy-char-counter>
<%= f.input :meta_keywords,
as: 'text',
hint: Alchemy.t('pages.update.comma_seperated') %>
<%= f.input :meta_keywords,
as: 'text',
hint: Alchemy.t('pages.update.comma_seperated') %>
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
<% end %>
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
<%= hidden_field_tag :view, params[:view] %>
<%= f.submit Alchemy.t(:save) %>
<% end %>
<%= f.submit Alchemy.t(:save) %>
<% end %>
2 changes: 1 addition & 1 deletion app/views/alchemy/admin/pages/_locked_page.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% if @page == locked_page %>
<% if action_name == "edit" && @page == locked_page %>
<%= render 'alchemy/admin/pages/current_page', current_page: @page %>
<% else %>
<div class="locked_page wide" id="locked_page_<%= locked_page.id %>">
Expand Down
2 changes: 1 addition & 1 deletion app/views/alchemy/admin/pages/_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<% table.with_action :configure, Alchemy.t(:edit_page_properties) do |page| %>
<%= link_to_dialog(
render_icon(:cog),
alchemy.configure_admin_page_path(page),
alchemy.configure_admin_page_path(page, view: "list"),
{
title: Alchemy.t(:edit_page_properties),
size: '450x680'
Expand Down
43 changes: 0 additions & 43 deletions app/views/alchemy/admin/pages/update.js.erb

This file was deleted.

39 changes: 39 additions & 0 deletions app/views/alchemy/admin/pages/update.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<alchemy-growl><%= @notice %></alchemy-action>
<alchemy-action name="closeCurrentDialog"></alchemy-action>

<% if @while_page_edit -%>
<%= turbo_stream.replace "locked_page_#{@page.id}" do %>
<%= render("alchemy/admin/pages/current_page", current_page: @page) %>
<% end %>
<alchemy-action name="reloadPreview"></alchemy-action>
<% else %>
<%= turbo_stream.replace "locked_page_#{@page.id}" do %>
<%= render("alchemy/admin/pages/locked_page", locked_page: @page) %>
<% end %>
<% if @view == "list" %>
<turbo-stream action="refresh"></turbo-stream>
<% elsif @page.parent_id != @old_parent_id -%>
<%= turbo_stream.append "sitemap" do %>
<script type="module">
Alchemy.currentSitemap.load(<%= @page.get_language_root.id %>);
</script>
<% end %>
<% else -%>
<% if @page.layoutpage %>
<%= turbo_stream.replace "page_#{@page.id}" do %>
<%= render("alchemy/admin/layoutpages/layoutpage", layoutpage: @page) %>
<% end %>
<% else %>
<%= turbo_stream.append "sitemap" do %>
<script type="module">
const page = document.getElementById('page_<%= @page.id %>');
const page_html = "<%= j render('page', page: @page) %>".replace(/__ID__/g, "<%= @page.id %>");
const compiler = Handlebars.compile(page_html);
const tree = <%== @tree.to_json %>;
page.outerHTML = compiler(tree.pages[0]);
</script>
<% end %>
<% end %>
<% end -%>
<% end %>
10 changes: 9 additions & 1 deletion spec/controllers/alchemy/admin/layoutpages_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,15 @@ module Alchemy
let(:page) { create(:alchemy_page, :layoutpage) }

context "with passing validations" do
subject { put :update, params: {id: page.id, page: {name: "New Name"}}, format: :js }
subject do
put :update, params: {id: page.id, page: {name: "New Name"}}, format: :turbo_stream
end

before do
allow_any_instance_of(ActionDispatch::Request).to receive(:referer) do
"/admin/pages/edit/#{page.id}"
end
end

it "renders update template" do
is_expected.to render_template("alchemy/admin/pages/update")
Expand Down
28 changes: 28 additions & 0 deletions spec/requests/alchemy/admin/pages_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,34 @@ module Alchemy
end
end

describe "#update" do
let(:page) { create(:alchemy_page) }

before do
allow_any_instance_of(ActionDispatch::Request).to receive(:referer) do
"/admin/pages/edit/#{page.id}"
end
end

context "with valid params" do
let(:page_params) do
{
name: "New Name"
}
end

context "in list view" do
subject! do
patch admin_page_path(page, page: page_params, view: "list", format: :turbo_stream)
end

it "sets a flash notice" do
expect(flash[:notice]).to eq("New Name saved")
end
end
end
end

describe "#create" do
subject { post admin_pages_path(page: page_params) }

Expand Down

0 comments on commit 8d4c097

Please sign in to comment.