katalyst-navigation 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +29 -5
- data/app/assets/builds/katalyst/navigation.esm.js +911 -0
- data/app/assets/builds/katalyst/navigation.js +911 -0
- data/app/assets/builds/katalyst/navigation.min.js +2 -0
- data/app/assets/builds/katalyst/navigation.min.js.map +1 -0
- data/app/assets/config/katalyst-navigation.js +1 -1
- data/app/components/katalyst/navigation/editor/base_component.rb +48 -0
- data/app/components/katalyst/navigation/editor/errors_component.html.erb +12 -0
- data/app/components/katalyst/navigation/editor/errors_component.rb +15 -0
- data/app/components/katalyst/navigation/editor/item_component.html.erb +27 -0
- data/app/components/katalyst/navigation/editor/item_component.rb +30 -0
- data/app/components/katalyst/navigation/editor/item_editor_component.rb +51 -0
- data/app/components/katalyst/navigation/editor/new_item_component.html.erb +14 -0
- data/app/components/katalyst/navigation/editor/new_item_component.rb +49 -0
- data/app/components/katalyst/navigation/editor/new_items_component.html.erb +3 -0
- data/app/components/katalyst/navigation/editor/new_items_component.rb +20 -0
- data/app/{views/katalyst/navigation/menus/_list_item.html.erb → components/katalyst/navigation/editor/row_component.html.erb} +1 -1
- data/{lib/katalyst/navigation/version.rb → app/components/katalyst/navigation/editor/row_component.rb} +4 -1
- data/app/{helpers/katalyst/navigation/editor/status_bar.rb → components/katalyst/navigation/editor/status_bar_component.rb} +17 -13
- data/app/components/katalyst/navigation/editor/table_component.html.erb +11 -0
- data/app/components/katalyst/navigation/editor/table_component.rb +36 -0
- data/app/components/katalyst/navigation/editor_component.html.erb +9 -0
- data/app/components/katalyst/navigation/editor_component.rb +47 -0
- data/app/controllers/concerns/katalyst/navigation/has_navigation.rb +5 -14
- data/app/controllers/katalyst/navigation/items_controller.rb +24 -12
- data/app/controllers/katalyst/navigation/menus_controller.rb +25 -13
- data/app/helpers/katalyst/navigation/frontend_helper.rb +7 -7
- data/app/javascript/navigation/application.js +30 -0
- data/app/{assets/javascripts/controllers → javascript}/navigation/editor/item_controller.js +1 -1
- data/app/{assets/javascripts/utils → javascript}/navigation/editor/menu.js +1 -1
- data/app/{assets/javascripts/controllers → javascript}/navigation/editor/menu_controller.js +3 -3
- data/app/models/katalyst/navigation/menu.rb +2 -0
- data/app/models/katalyst/navigation/types/nodes_type.rb +2 -2
- data/app/views/katalyst/navigation/items/_button.html.erb +6 -0
- data/app/views/katalyst/navigation/items/_form_errors.html.erb +5 -0
- data/app/views/katalyst/navigation/items/_heading.html.erb +1 -0
- data/app/views/katalyst/navigation/items/_link.html.erb +11 -0
- data/app/views/katalyst/navigation/items/edit.html.erb +4 -3
- data/app/views/katalyst/navigation/items/edit.turbo_stream.erb +3 -0
- data/app/views/katalyst/navigation/items/new.html.erb +1 -1
- data/app/views/katalyst/navigation/items/update.turbo_stream.erb +2 -5
- data/app/views/katalyst/navigation/menus/edit.html.erb +1 -1
- data/app/views/katalyst/navigation/menus/index.html.erb +1 -1
- data/app/views/katalyst/navigation/menus/show.html.erb +3 -13
- data/config/importmap.rb +1 -4
- data/db/migrate/20230727025052_update_target_syntax.rb +1 -1
- data/lib/katalyst/navigation/config.rb +4 -0
- data/lib/katalyst/navigation/engine.rb +1 -1
- data/lib/katalyst/navigation.rb +6 -1
- data/spec/factories/katalyst/navigation/menus.rb +1 -1
- metadata +93 -27
- data/app/controllers/katalyst/navigation/base_controller.rb +0 -12
- data/app/helpers/katalyst/navigation/editor/base.rb +0 -41
- data/app/helpers/katalyst/navigation/editor/errors.rb +0 -24
- data/app/helpers/katalyst/navigation/editor/item.rb +0 -62
- data/app/helpers/katalyst/navigation/editor/list.rb +0 -41
- data/app/helpers/katalyst/navigation/editor/menu.rb +0 -47
- data/app/helpers/katalyst/navigation/editor/new_item.rb +0 -53
- data/app/helpers/katalyst/navigation/editor_helper.rb +0 -52
- data/app/views/katalyst/navigation/menus/_item.html.erb +0 -15
- data/app/views/katalyst/navigation/menus/_new_item.html.erb +0 -3
- data/app/views/katalyst/navigation/menus/_new_items.html.erb +0 -5
- /data/app/{assets/javascripts/utils → javascript}/navigation/editor/item.js +0 -0
- /data/app/{assets/javascripts/controllers → javascript}/navigation/editor/list_controller.js +0 -0
- /data/app/{assets/javascripts/controllers → javascript}/navigation/editor/new_item_controller.js +0 -0
- /data/app/{assets/javascripts/utils → javascript}/navigation/editor/rules-engine.js +0 -0
- /data/app/{assets/javascripts/controllers → javascript}/navigation/editor/status_bar_controller.js +0 -0
@@ -2,24 +2,27 @@
|
|
2
2
|
|
3
3
|
module Katalyst
|
4
4
|
module Navigation
|
5
|
-
class ItemsController <
|
6
|
-
before_action :set_menu
|
5
|
+
class ItemsController < ApplicationController
|
6
|
+
before_action :set_menu, only: %i[new create]
|
7
7
|
before_action :set_item, except: %i[new create]
|
8
8
|
|
9
|
+
attr_reader :menu, :item, :editor
|
10
|
+
|
11
|
+
layout nil
|
12
|
+
|
9
13
|
def new
|
10
|
-
|
14
|
+
render_editor
|
11
15
|
end
|
12
16
|
|
13
17
|
def edit
|
14
|
-
|
18
|
+
render_editor
|
15
19
|
end
|
16
20
|
|
17
21
|
def create
|
18
|
-
item = @menu.items.build(item_params)
|
19
22
|
if item.save
|
20
|
-
render :update, locals: {
|
23
|
+
render :update, locals: { editor:, item:, previous: @menu.items.build(type: item.type) }
|
21
24
|
else
|
22
|
-
|
25
|
+
render_editor status: :unprocessable_entity
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
@@ -29,16 +32,17 @@ module Katalyst
|
|
29
32
|
if @item.valid?
|
30
33
|
previous = @item
|
31
34
|
@item = @item.dup.tap(&:save!)
|
32
|
-
|
35
|
+
|
36
|
+
render locals: { editor:, item:, previous: }
|
33
37
|
else
|
34
|
-
|
38
|
+
render_editor status: :unprocessable_entity
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
38
42
|
private
|
39
43
|
|
40
44
|
def new_item_params
|
41
|
-
params[:type] || Link.name
|
45
|
+
{ type: params[:type] || Link.name }
|
42
46
|
end
|
43
47
|
|
44
48
|
def item_params_type
|
@@ -55,11 +59,19 @@ module Katalyst
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def set_menu
|
58
|
-
@menu
|
62
|
+
@menu = Menu.find(params[:menu_id])
|
63
|
+
@item = @menu.items.build(item_params)
|
64
|
+
@editor = Katalyst::Navigation::EditorComponent.new(menu:, item:)
|
59
65
|
end
|
60
66
|
|
61
67
|
def set_item
|
62
|
-
@item =
|
68
|
+
@item = Item.find(params[:id])
|
69
|
+
@menu = @item.menu
|
70
|
+
@editor = Katalyst::Navigation::EditorComponent.new(menu:, item:)
|
71
|
+
end
|
72
|
+
|
73
|
+
def render_editor(**)
|
74
|
+
render(:edit, locals: { item_editor: editor.item_editor(item:) }, **)
|
63
75
|
end
|
64
76
|
end
|
65
77
|
end
|
@@ -2,55 +2,67 @@
|
|
2
2
|
|
3
3
|
module Katalyst
|
4
4
|
module Navigation
|
5
|
-
class MenusController <
|
5
|
+
class MenusController < Katalyst::Navigation.config.base_controller.constantize
|
6
|
+
include Katalyst::Tables::Backend
|
7
|
+
|
6
8
|
def index
|
7
9
|
collection = Katalyst::Tables::Collection::Base.new(sorting: :title).with_params(params).apply(Menu.all)
|
8
|
-
table = Katalyst::Turbo::TableComponent.new(collection
|
10
|
+
table = Katalyst::Turbo::TableComponent.new(collection:,
|
9
11
|
id: "index-table",
|
10
12
|
class: "index-table",
|
11
13
|
caption: true)
|
12
14
|
|
13
15
|
respond_to do |format|
|
14
16
|
format.turbo_stream { render(table) } if self_referred?
|
15
|
-
format.html { render :index, locals: { table:
|
17
|
+
format.html { render :index, locals: { table: } }
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
def show
|
20
|
-
menu
|
22
|
+
menu = Menu.find(params[:id])
|
23
|
+
editor = Katalyst::Navigation::EditorComponent.new(menu:)
|
21
24
|
|
22
|
-
render locals: { menu:
|
25
|
+
render locals: { menu:, editor: }
|
23
26
|
end
|
24
27
|
|
25
28
|
def new
|
26
|
-
|
29
|
+
menu = Menu.new
|
30
|
+
editor = Katalyst::Navigation::EditorComponent.new(menu:)
|
31
|
+
|
32
|
+
render locals: { menu:, editor: }
|
27
33
|
end
|
28
34
|
|
29
35
|
def edit
|
30
|
-
menu
|
36
|
+
menu = Menu.find(params[:id])
|
37
|
+
editor = Katalyst::Navigation::EditorComponent.new(menu:)
|
31
38
|
|
32
|
-
render locals: { menu:
|
39
|
+
render locals: { menu:, editor: }
|
33
40
|
end
|
34
41
|
|
35
42
|
def create
|
36
43
|
@menu = Menu.new(menu_params)
|
44
|
+
editor = Katalyst::Navigation::EditorComponent.new(menu: @menu)
|
37
45
|
|
38
46
|
if @menu.save
|
39
|
-
|
47
|
+
@menu.build_draft_version
|
48
|
+
@menu.save!
|
49
|
+
redirect_to @menu, status: :see_other
|
40
50
|
else
|
41
|
-
render :new, locals: { menu: @menu }, status: :unprocessable_entity
|
51
|
+
render :new, locals: { menu: @menu, editor: }, status: :unprocessable_entity
|
42
52
|
end
|
43
53
|
end
|
44
54
|
|
45
55
|
# PATCH /admins/navigation_menus/:slug
|
46
56
|
def update
|
47
57
|
menu = Menu.find(params[:id])
|
58
|
+
editor = Katalyst::Navigation::EditorComponent.new(menu:)
|
48
59
|
|
49
60
|
menu.attributes = menu_params
|
50
61
|
|
51
62
|
unless menu.valid?
|
52
|
-
return
|
53
|
-
|
63
|
+
return respond_to do |format|
|
64
|
+
format.turbo_stream { render editor.errors, status: :unprocessable_entity }
|
65
|
+
end
|
54
66
|
end
|
55
67
|
|
56
68
|
case params[:commit]
|
@@ -62,7 +74,7 @@ module Katalyst
|
|
62
74
|
when "revert"
|
63
75
|
menu.revert!
|
64
76
|
end
|
65
|
-
redirect_to menu
|
77
|
+
redirect_to menu, status: :see_other
|
66
78
|
end
|
67
79
|
|
68
80
|
def destroy
|
@@ -11,14 +11,14 @@ module Katalyst
|
|
11
11
|
#
|
12
12
|
# @param(menu: Katalyst::Navigation::Menu)
|
13
13
|
# @return Structured HTML containing top level + nested navigation links
|
14
|
-
def navigation_menu_with(menu:, **
|
15
|
-
builder = navigation_builder(**
|
14
|
+
def navigation_menu_with(menu:, **)
|
15
|
+
builder = navigation_builder(**)
|
16
16
|
menu = navigation_menu_for(menu) if menu.is_a?(Symbol)
|
17
17
|
|
18
|
-
return if menu
|
18
|
+
return if menu.blank?
|
19
19
|
|
20
|
-
cache menu
|
21
|
-
concat builder.render(menu.published_tree)
|
20
|
+
cache menu do
|
21
|
+
concat builder.render(menu.published_tree) if menu.published_version.present?
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -26,8 +26,8 @@ module Katalyst
|
|
26
26
|
#
|
27
27
|
# @param(items: [Katalyst::Navigation::Item])
|
28
28
|
# @return Structured HTML containing top level + nested navigation links
|
29
|
-
def navigation_items_with(items:, **
|
30
|
-
builder = navigation_builder(**
|
29
|
+
def navigation_items_with(items:, **)
|
30
|
+
builder = navigation_builder(**)
|
31
31
|
|
32
32
|
capture do
|
33
33
|
items.each do |item|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import MenuController from "./editor/menu_controller";
|
2
|
+
import ItemController from "./editor/item_controller";
|
3
|
+
import ListController from "./editor/list_controller";
|
4
|
+
import NewItemController from "./editor/new_item_controller";
|
5
|
+
import StatusBarController from "./editor/status_bar_controller";
|
6
|
+
|
7
|
+
const Definitions = [
|
8
|
+
{
|
9
|
+
identifier: "navigation--editor--menu",
|
10
|
+
controllerConstructor: MenuController,
|
11
|
+
},
|
12
|
+
{
|
13
|
+
identifier: "navigation--editor--item",
|
14
|
+
controllerConstructor: ItemController,
|
15
|
+
},
|
16
|
+
{
|
17
|
+
identifier: "navigation--editor--list",
|
18
|
+
controllerConstructor: ListController,
|
19
|
+
},
|
20
|
+
{
|
21
|
+
identifier: "navigation--editor--new-item",
|
22
|
+
controllerConstructor: NewItemController,
|
23
|
+
},
|
24
|
+
{
|
25
|
+
identifier: "navigation--editor--status-bar",
|
26
|
+
controllerConstructor: StatusBarController,
|
27
|
+
},
|
28
|
+
];
|
29
|
+
|
30
|
+
export { Definitions as default };
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
|
-
import Item from "
|
4
|
-
import Menu from "
|
5
|
-
import RulesEngine from "
|
3
|
+
import Item from "./item";
|
4
|
+
import Menu from "./menu";
|
5
|
+
import RulesEngine from "./rules-engine";
|
6
6
|
|
7
7
|
export default class MenuController extends Controller {
|
8
8
|
static targets = ["menu"];
|
@@ -43,6 +43,8 @@ module Katalyst
|
|
43
43
|
inverse_of: :menu,
|
44
44
|
validate: true
|
45
45
|
|
46
|
+
scope :published, -> { where.not(published_version_id: nil) }
|
47
|
+
|
46
48
|
validates :title, :slug, presence: true
|
47
49
|
validates :slug, uniqueness: true
|
48
50
|
validates :depth, numericality: { greater_than: 0, only_integer: true, allow_nil: true }
|
@@ -27,13 +27,13 @@ module Katalyst
|
|
27
27
|
# Deserialize a params-style array, e.g. "0" => { ... }
|
28
28
|
def deserialize_params(value)
|
29
29
|
value.map do |index, attributes|
|
30
|
-
Node.new(index
|
30
|
+
Node.new(index:, **attributes)
|
31
31
|
end.select(&:id).sort_by(&:index)
|
32
32
|
end
|
33
33
|
|
34
34
|
def deserialize_array(value)
|
35
35
|
value.map.with_index do |attributes, index|
|
36
|
-
Node.new(index
|
36
|
+
Node.new(index:, **attributes)
|
37
37
|
end.select(&:id).sort_by(&:index)
|
38
38
|
end
|
39
39
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<%= form_with model: item, scope: :item, url: path do |form| %>
|
2
2
|
<%= form.hidden_field :type %>
|
3
|
+
<%= render "form_errors", form: %>
|
3
4
|
|
4
5
|
<div class="input">
|
5
6
|
<%= form.label :title %>
|
@@ -16,6 +17,11 @@
|
|
16
17
|
<%= form.select :http_method, Katalyst::Navigation::Button::HTTP_METHODS %>
|
17
18
|
</div>
|
18
19
|
|
20
|
+
<div class="field">
|
21
|
+
<%= form.label :target %>
|
22
|
+
<%= form.select :target, Katalyst::Navigation::Button::TARGETS %>
|
23
|
+
</div>
|
24
|
+
|
19
25
|
<div class="input">
|
20
26
|
<%= form.check_box :visible %>
|
21
27
|
<%= form.label :visible %>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<%= form_with model: item, scope: :item, url: path do |form| %>
|
2
2
|
<%= form.hidden_field :type %>
|
3
|
+
<%= render "form_errors", form: %>
|
3
4
|
|
4
5
|
<div class="field">
|
5
6
|
<%= form.label :title %>
|
@@ -11,6 +12,16 @@
|
|
11
12
|
<%= form.text_field :url %>
|
12
13
|
</div>
|
13
14
|
|
15
|
+
<div class="input">
|
16
|
+
<%= form.label :http_method %>
|
17
|
+
<%= form.select :http_method, Katalyst::Navigation::Link::HTTP_METHODS %>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<div class="field">
|
21
|
+
<%= form.label :target %>
|
22
|
+
<%= form.select :target, Katalyst::Navigation::Link::TARGETS %>
|
23
|
+
</div>
|
24
|
+
|
14
25
|
<div class="field">
|
15
26
|
<%= form.label :visible %>
|
16
27
|
<%= form.check_box :visible %>
|
@@ -1,4 +1,5 @@
|
|
1
|
-
<%=
|
2
|
-
|
3
|
-
|
1
|
+
<%= render Kpop::FrameComponent.new do %>
|
2
|
+
<%= render Kpop::ModalComponent.new(title: item_editor.title, layout: "side-panel") do %>
|
3
|
+
<%= render item_editor %>
|
4
|
+
<% end %>
|
4
5
|
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<%= turbo_frame_tag "navigation--editor--item-frame" do %>
|
2
2
|
<h3 class="heading-three">New <%= item.model_name.human.downcase %></h3>
|
3
|
-
<%= render item.model_name.param_key, item
|
3
|
+
<%= render item.model_name.param_key, item:, path: menu_items_path(item.menu) %>
|
4
4
|
<% end %>
|
@@ -1,7 +1,4 @@
|
|
1
|
-
<%= turbo_stream.
|
2
|
-
<%= render "katalyst/navigation/menus/new_items", menu: item.menu %>
|
3
|
-
<% end %>
|
4
|
-
|
1
|
+
<%= turbo_stream.kpop.dismiss %>
|
5
2
|
<%= turbo_stream.replace dom_id(previous) do %>
|
6
|
-
<%= render
|
3
|
+
<%= render editor.item(item:) %>
|
7
4
|
<% end %>
|
@@ -20,6 +20,6 @@
|
|
20
20
|
<%= form.submit :save %>
|
21
21
|
<%= link_to "Delete", url_for(action: :show),
|
22
22
|
class: "button button-secondary",
|
23
|
-
data:
|
23
|
+
data: { turbo_method: :delete, turbo_confirm: "Are you sure?" } %>
|
24
24
|
</div>
|
25
25
|
<% end %>
|
@@ -1,15 +1,5 @@
|
|
1
1
|
<% content_for :title, menu.title %>
|
2
2
|
|
3
|
-
<%=
|
4
|
-
|
5
|
-
<%=
|
6
|
-
<div role="rowheader">
|
7
|
-
<h4>Title</h4>
|
8
|
-
<h4>Url</h4>
|
9
|
-
<h4>Actions</h4>
|
10
|
-
</div>
|
11
|
-
|
12
|
-
<%= navigation_editor_list menu: menu %>
|
13
|
-
<% end %>
|
14
|
-
|
15
|
-
<%= render "katalyst/navigation/menus/new_items", menu: menu %>
|
3
|
+
<%= render editor.status_bar %>
|
4
|
+
<%= render editor %>
|
5
|
+
<%= render editor.new_items %>
|
data/config/importmap.rb
CHANGED
@@ -1,5 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
pin_all_from Katalyst::Navigation::Engine.root.join("app/assets/javascripts"),
|
4
|
-
# preload in tests so that we don't start clicking before controllers load
|
5
|
-
preload: Rails.env.test?
|
2
|
+
pin "@katalyst/navigation", to: "katalyst/navigation.js"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Ensures that all navigation items have a valid target and http_method.
|
4
4
|
class UpdateTargetSyntax < ActiveRecord::Migration[7.0]
|
5
5
|
def change
|
6
|
-
Katalyst::Navigation::Item.where(http_method: nil).update_all(
|
6
|
+
Katalyst::Navigation::Item.where(http_method: nil).update_all(http_method: "get")
|
7
7
|
Katalyst::Navigation::Item.where(target: nil).update_all(target: "self")
|
8
8
|
Katalyst::Navigation::Item.where(target: "_blank").update_all(target: "blank")
|
9
9
|
Katalyst::Navigation::Item.where(target: "_top").update_all(target: "top")
|
@@ -18,7 +18,7 @@ module Katalyst
|
|
18
18
|
initializer "katalyst-navigation.importmap", before: "importmap" do |app|
|
19
19
|
if app.config.respond_to?(:importmap)
|
20
20
|
app.config.importmap.paths << root.join("config/importmap.rb")
|
21
|
-
app.config.importmap.cache_sweepers << root.join("app/assets/
|
21
|
+
app.config.importmap.cache_sweepers << root.join("app/assets/builds")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
data/lib/katalyst/navigation.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support"
|
4
|
+
require "katalyst/html_attributes"
|
5
|
+
require "katalyst/kpop"
|
6
|
+
require "katalyst/tables"
|
7
|
+
require "view_component"
|
8
|
+
|
3
9
|
require "katalyst/navigation/config"
|
4
10
|
require "katalyst/navigation/engine"
|
5
|
-
require "katalyst/navigation/version"
|
6
11
|
|
7
12
|
module Katalyst
|
8
13
|
module Navigation # :nodoc:
|
@@ -10,7 +10,7 @@ FactoryBot.define do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
after(:create) do |menu, _context|
|
13
|
-
menu.items_attributes = menu.items.map.with_index { |item, index| { id: item.id, index
|
13
|
+
menu.items_attributes = menu.items.map.with_index { |item, index| { id: item.id, index:, depth: 0 } }
|
14
14
|
menu.publish!
|
15
15
|
end
|
16
16
|
end
|