Skip to content

Commit

Permalink
Merge pull request #2699 from sascha-karnatz/node-tab-in-page-configu…
Browse files Browse the repository at this point in the history
…ration

Add nodes to page dialog
  • Loading branch information
tvdeyen authored Feb 5, 2024
2 parents 9efa7cc + 061afe6 commit 5d4c6d5
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 7 deletions.
5 changes: 2 additions & 3 deletions app/assets/stylesheets/alchemy/forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ form {
}

.inline-input {
@include clearfix;
align-items: center;
display: flex;
margin: 0 -1 * $default-margin;

.left-column,
Expand All @@ -179,12 +180,10 @@ form {

.left-column {
width: $form-right-width;
float: left;
}

.right-column {
width: $form-left-width;
float: right;
}

button,
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/alchemy/admin/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def leave

# Disable layout rendering for xhr requests.
def set_layout
request.xhr? ? false : "alchemy/admin"
(request.xhr? || turbo_frame_request?) ? false : "alchemy/admin"
end

# Handles exceptions
Expand Down
26 changes: 26 additions & 0 deletions app/controllers/alchemy/admin/nodes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,32 @@ def new
)
end

def create
if turbo_frame_request?
@page = Alchemy::Page.find(resource_params[:page_id])
@node = @page.nodes.build(resource_params)
if @node.valid?
@node.save
flash_notice_for_resource_action(:create)
else
flash[:error] = @node.errors.full_messages.join(", ")
end
else
super
end
end

def destroy
if turbo_frame_request?
@node = Alchemy::Node.find(params[:id])
@page = @node.page
@page.nodes.destroy(@node)
flash_notice_for_resource_action(:destroy)
else
super
end
end

private

def resource_params
Expand Down
1 change: 1 addition & 0 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import "alchemy_admin/components/clipboard_button"
import "alchemy_admin/components/datepicker"
import "alchemy_admin/components/dialog_link"
import "alchemy_admin/components/element_editor"
import "alchemy_admin/components/growl"
import "alchemy_admin/components/ingredient_group"
import "alchemy_admin/components/link_buttons"
import "alchemy_admin/components/node_select"
Expand Down
10 changes: 10 additions & 0 deletions app/javascript/alchemy_admin/components/growl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Growl extends HTMLElement {
connectedCallback() {
Alchemy.growl(
this.getAttribute("message"),
this.getAttribute("type") || "notice"
)
}
}

customElements.define("alchemy-growl", Growl)
1 change: 1 addition & 0 deletions app/views/alchemy/admin/nodes/_label.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(<%= count %>) <%= Alchemy::Node.model_name.human(count: count) %>
48 changes: 48 additions & 0 deletions app/views/alchemy/admin/nodes/_page_nodes.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<%= turbo_frame_tag("page_nodes") do %>
<table class="list">
<tr>
<th class="name">
<%= Alchemy::Node.model_name.human %>
</th>
<th class="tools"></th>
</tr>
<% nodes = @page.nodes.select(&:persisted?) %>
<% if nodes.length > 0 %>
<% nodes.each do |node| %>
<tr class="even">
<td><%= "#{node.ancestors.map(&:name).join(" / ")} / #{node.name}" %></td>
<td class="tools">
<sl-tooltip content="<%= Alchemy.t("delete_node") %>">
<%= link_to render_icon(:minus),
admin_node_path(node),
class: "icon_button",
data: { turbo_method: :delete, turbo_confirm: Alchemy.t('confirm_to_delete_node') } %>
</sl-tooltip>
</td>
</tr>
<% end %>
<% else %>
<tr class="even">
<td><%= Alchemy.t('No menu node for this page found') %></td>
<td class="tools"></td>
</tr>
<% end %>
</table>

<fieldset>
<legend><%= Alchemy.t('Create node on parent:') %></legend>

<%= alchemy_form_for([:admin, @page.nodes.build], id: "new_node_form") do |f| %>
<%= f.hidden_field :page_id, value: @page.id %>
<%= f.hidden_field :language_id, value: @page.language_id %>

<%= render Alchemy::Admin::NodeSelect.new(nil, url: alchemy.api_nodes_path(language_id: @page.language_id, include: :ancestors)) do %>
<%= f.text_field :parent_id, class: 'alchemy_selectbox full_width' %>
<% end %>

<div class="submit">
<button is="alchemy-button"><%= Alchemy.t(:create_node) %></button>
</div>
<% end %>
</fieldset>
<% end %>
9 changes: 9 additions & 0 deletions app/views/alchemy/admin/nodes/_update.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<% key = flash.keys.first %>
<alchemy-growl message="<%= flash[key] %>" type="<%= key %>"></alchemy-growl>

<%= turbo_stream.replace "page_nodes" do %>
<%= render "page_nodes" %>
<% end %>
<%= turbo_stream.update_all '[panel="nodes"]' do %>
<%= render('alchemy/admin/nodes/label', count: @page.nodes.select(&:persisted?).length) %>
<% end %>
1 change: 1 addition & 0 deletions app/views/alchemy/admin/nodes/create.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= render "update" %>
1 change: 1 addition & 0 deletions app/views/alchemy/admin/nodes/destroy.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= render "update" %>
6 changes: 6 additions & 0 deletions app/views/alchemy/admin/pages/configure.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
<sl-tab slot="nav" panel="page_properties">
<%= Alchemy.t('Properties') %>
</sl-tab>
<sl-tab slot="nav" panel="nodes">
<%= render 'alchemy/admin/nodes/label', count: @page.nodes.size %>
</sl-tab>
<sl-tab slot="nav" panel="legacy_urls" id="legacy_urls_label">
<%= render 'alchemy/admin/legacy_page_urls/label', count: @page.legacy_urls.size %>
</sl-tab>
<sl-tab-panel name="page_properties">
<%= render 'form' %>
</sl-tab-panel>
<sl-tab-panel name="nodes">
<%= render 'alchemy/admin/nodes/page_nodes' %>
</sl-tab-panel>
<sl-tab-panel name="legacy_urls">
<%= render 'legacy_urls' %>
</sl-tab-panel>
Expand Down
3 changes: 3 additions & 0 deletions config/locales/alchemy.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ en:
"Confirm new password": "Confirm new password"
"Copy": "Copy"
"Could not load Adobe Flash® Plugin!": "Could not load Adobe Flash® Plugin!"
"Create node on parent:": "Create node on parent:"
"Currently locked pages": "Currently locked pages"
"Default language has to be public": "Default language has to be public"
"Delete image": "Delete image"
Expand Down Expand Up @@ -286,6 +287,7 @@ en:
"New": "New"
"New Element": "New element"
"New page": "New page"
"No menu node for this page found": "No menu node for this page found"
"No page links for this page found": "No page links for this page found"
"New password": "New password"
"New Tag": "New tag"
Expand Down Expand Up @@ -411,6 +413,7 @@ en:
delete_node: "Delete this menu node"
delete_page: "Delete this page"
delete_tag: "Delete tag"
search_node: "Search menu node"
document: "File"
download_csv: "Download CSV"
download_file: "Download file '%{filename}'"
Expand Down
2 changes: 1 addition & 1 deletion spec/components/alchemy/admin/node_select_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
end

it "should have the default placeholder" do
expect(page).to have_selector("alchemy-node-select[placeholder='Search node']")
expect(page).to have_selector("alchemy-node-select[placeholder='Search menu node']")
end

it "should have the default node api - url" do
Expand Down
24 changes: 24 additions & 0 deletions spec/controllers/alchemy/admin/nodes_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,29 @@ module Alchemy
end
end
end

describe "#destroy" do
let(:node) { create(:alchemy_node) }

context "as default call" do
it "removes node and redirects to index" do
expect {
delete :destroy, params: {id: node.id}
}.to change { Alchemy::Node.count }.by(0)
expect(response).to redirect_to(admin_nodes_path)
end
end

context "as turbo stream call", type: :request do
let!(:page) { create(:alchemy_page, nodes: [node]) }

it "removes node and returns the new frame" do
expect(Alchemy::Node.count).to eq(1)
delete admin_node_path(node), as: :turbo_stream
expect(Alchemy::Node.count).to eq(0)
expect(response.code).to eq("302")
end
end
end
end
end
70 changes: 70 additions & 0 deletions spec/features/admin/nodes_management_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe "Nodes management", type: :system, js: true do
before do
authorize_user(:as_admin)
end

let!(:a_page) { create(:alchemy_page) }
let!(:a_menu) { create(:alchemy_node, name: "Menu") }

def open_page_properties
visit admin_pages_path
expect(page.find("alchemy-overlay").style("display")["display"]).to have_content("none")
page.find("a[href='#{configure_admin_page_path(a_page)}']", wait: 10).click
find("[panel='nodes']").click
end

def add_menu_item
find("#new_node_form .select2-choice").click
find(".select2-result:first-child").click

click_button "Add a menu node"
end

it "lets a user add a menu node" do
open_page_properties
add_menu_item

within "#page_nodes table" do
expect(page).to have_content("Menu node Menu / A Page 1")
end
within "[panel='nodes']" do
expect(page).to have_content("(1) Menu node")
end
end

context "without parent id" do
it "displays error message" do
open_page_properties

click_button "Add a menu node"
within ".flash.error" do
expect(page).to have_content("Menu Type can't be blank")
end
end
end

context "with menu node present" do
before do
open_page_properties
add_menu_item
end

it "lets a user remove a menu node" do
page.accept_alert "Do you really want to delete this menu node?" do
click_link_with_tooltip("Delete this menu node")
end

within "#page_nodes table" do
expect(page).to_not have_content("Menu node Menu / A Page 1")
expect(page).to have_content(Alchemy.t("No menu node for this page found"))
end
within "[panel='nodes']" do
expect(page).to have_content("(0) Menu nodes")
end
end
end
end
4 changes: 2 additions & 2 deletions spec/features/admin/page_editing_feature_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
it "saves the name" do
within(".alchemy-dialog.modal") do
find("input#page_name").set("name with some %!x^)'([@!{}]|/?:# characters")
find(".submit button").click
find(".edit_page .submit button").click
end
expect(page).to_not have_selector(".alchemy-dialog-overlay.open")
expect(page).to have_selector("#sitemap a.sitemap_pagename_link", text: "name with some %!x^)'([@!{}]|/?:# characters")
Expand All @@ -240,7 +240,7 @@
within(".alchemy-dialog.modal") do
expect(page).to have_css("#s2id_page_parent_id")
select2_search(new_parent.name, from: "Parent")
find(".submit button").click
find(".edit_page .submit button").click
end
expect(page).to_not have_selector(".alchemy-dialog-overlay.open")
expect(page).to have_selector("#sitemap .sitemap_url", text: "/#{new_parent.urlname}/#{a_page.urlname}")
Expand Down

0 comments on commit 5d4c6d5

Please sign in to comment.