panda_cms 0.6.0 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/builds/panda_cms.css +17 -0
- data/app/assets/config/panda_cms_manifest.js +1 -0
- data/app/components/panda_cms/code_component.rb +3 -1
- data/app/components/panda_cms/menu_component.html.erb +3 -0
- data/app/components/panda_cms/menu_component.rb +8 -1
- data/app/components/panda_cms/page_menu_component.html.erb +7 -5
- data/app/components/panda_cms/page_menu_component.rb +3 -1
- data/app/components/panda_cms/rich_text_component.html.erb +2 -2
- data/app/components/panda_cms/rich_text_component.rb +12 -4
- data/app/components/panda_cms/text_component.rb +1 -1
- data/app/controllers/panda_cms/admin/block_contents_controller.rb +1 -1
- data/app/javascript/panda_cms/@editorjs--editorjs.js +2577 -0
- data/app/javascript/panda_cms/controllers/editor_controller.js +247 -0
- data/app/javascript/panda_cms/controllers/index.js +10 -7
- data/app/javascript/panda_cms/editor/plain_text_editor.js +102 -0
- data/app/javascript/panda_cms/editor/resource_loader.js +69 -0
- data/app/javascript/panda_cms/editor/rich_text_editor.js +89 -0
- data/app/lib/panda_cms/demo_site_generator.rb +8 -9
- data/app/lib/panda_cms/editor_js/blocks/alert.rb +32 -0
- data/app/lib/panda_cms/editor_js/blocks/base.rb +28 -0
- data/app/lib/panda_cms/editor_js/blocks/header.rb +13 -0
- data/app/lib/panda_cms/editor_js/blocks/image.rb +34 -0
- data/app/lib/panda_cms/editor_js/blocks/list.rb +30 -0
- data/app/lib/panda_cms/editor_js/blocks/paragraph.rb +13 -0
- data/app/lib/panda_cms/editor_js/blocks/quote.rb +27 -0
- data/app/lib/panda_cms/editor_js/blocks/table.rb +48 -0
- data/app/lib/panda_cms/editor_js/renderer.rb +120 -0
- data/app/models/panda_cms/block_content.rb +12 -2
- data/app/views/panda_cms/admin/pages/edit.html.erb +10 -9
- data/app/views/panda_cms/shared/_header.html.erb +2 -3
- data/app/views/panda_cms/shared/_importmap.html.erb +13 -3
- data/config/importmap.rb +3 -1
- data/db/migrate/20240315125411_add_status_to_panda_cms_pages.rb +5 -3
- data/db/migrate/20241031205109_add_cached_content_to_panda_cms_block_contents.rb +5 -0
- data/db/seeds.rb +1 -0
- data/lib/panda_cms/engine.rb +44 -8
- data/lib/panda_cms/version.rb +1 -1
- metadata +89 -103
- data/app/javascript/panda_cms/panda_cms_editable.js +0 -248
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 785a3596f68d157ff6e6363a95c507f536554f276fec85626e488cb3e3ca167f
|
4
|
+
data.tar.gz: 8847bd7ffd2b09a6e42a2fc7d4444de20f38e42e91616620092caf558ffafe3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf0a5477ebf5c79bd379275f63bbdb0da9e80896ac81372b976f4dc8a02c9635e2799ff6da1325efe4bdb0368e96a4ffef1271c0340344e52dd3e8a3456e61c5
|
7
|
+
data.tar.gz: 0bf5912db2be52720903d71be1ab9fba53b873aad9723caf1b3d4b6b9fe1f372cb81eb54b29d3f33874bfea12ecbc072f67497fb359054ac72efa59352c17693
|
@@ -879,6 +879,10 @@ a.block-link:after {
|
|
879
879
|
visibility: visible;
|
880
880
|
}
|
881
881
|
|
882
|
+
.collapse {
|
883
|
+
visibility: collapse;
|
884
|
+
}
|
885
|
+
|
882
886
|
.static {
|
883
887
|
position: static;
|
884
888
|
}
|
@@ -1167,6 +1171,10 @@ a.block-link:after {
|
|
1167
1171
|
display: grid;
|
1168
1172
|
}
|
1169
1173
|
|
1174
|
+
.contents {
|
1175
|
+
display: contents;
|
1176
|
+
}
|
1177
|
+
|
1170
1178
|
.hidden {
|
1171
1179
|
display: none;
|
1172
1180
|
}
|
@@ -1341,6 +1349,10 @@ a.block-link:after {
|
|
1341
1349
|
cursor: pointer;
|
1342
1350
|
}
|
1343
1351
|
|
1352
|
+
.resize {
|
1353
|
+
resize: both;
|
1354
|
+
}
|
1355
|
+
|
1344
1356
|
.list-disc {
|
1345
1357
|
list-style-type: disc;
|
1346
1358
|
}
|
@@ -2026,6 +2038,11 @@ a.block-link:after {
|
|
2026
2038
|
--tw-ring-offset-width: 2px;
|
2027
2039
|
}
|
2028
2040
|
|
2041
|
+
.blur {
|
2042
|
+
--tw-blur: blur(8px);
|
2043
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
2044
|
+
}
|
2045
|
+
|
2029
2046
|
.filter {
|
2030
2047
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
2031
2048
|
}
|
@@ -15,6 +15,8 @@ module PandaCms
|
|
15
15
|
@options = options || {}
|
16
16
|
@options[:id] ||= "code-#{key.to_s.dasherize}"
|
17
17
|
@editable = editable
|
18
|
+
|
19
|
+
raise BlockError.new("Key 'code' is not allowed for CodeComponent") if key == :code
|
18
20
|
end
|
19
21
|
|
20
22
|
def call
|
@@ -22,7 +24,7 @@ module PandaCms
|
|
22
24
|
block = PandaCms::Block.find_by(kind: KIND, key: @key, panda_cms_template_id: Current.page.panda_cms_template_id)
|
23
25
|
|
24
26
|
if block.nil?
|
25
|
-
raise PandaCms::MissingBlockError("Block with key #{@key} not found") unless Rails.env.production?
|
27
|
+
raise PandaCms::MissingBlockError.new("Block with key #{@key} not found for page #{Current.page.title}") unless Rails.env.production?
|
26
28
|
return false
|
27
29
|
end
|
28
30
|
|
@@ -1,3 +1,6 @@
|
|
1
1
|
<% @menu_items.each do |menu_item| %>
|
2
2
|
<a href="<%= menu_item.resolved_link %>" class="<%= menu_item.css_classes %>"><%= menu_item.text %></a>
|
3
|
+
<% if @render_page_menu && menu_item.page %>
|
4
|
+
<%= render PandaCms::PageMenuComponent.new(page: menu_item.page, start_depth: 1, styles: @page_menu_styles, show_heading: false) %>
|
5
|
+
<% end %>
|
3
6
|
<% end %>
|
@@ -12,12 +12,13 @@ module PandaCms
|
|
12
12
|
# The "default" key is applied to all menu items. "inactive" and "active" are set based on the
|
13
13
|
# current path.
|
14
14
|
# @return [void]
|
15
|
-
def initialize(name:, current_path: "", styles: {})
|
15
|
+
def initialize(name:, current_path: "", styles: {}, render_page_menu: false, page_menu_styles: {})
|
16
16
|
@menu = PandaCms::Menu.find_by(name: name)
|
17
17
|
@menu_items = @menu.menu_items
|
18
18
|
@menu_items = @menu_items.where("depth <= ?", @menu.depth) if @menu.depth
|
19
19
|
@menu_items = @menu_items.order(:lft)
|
20
20
|
@current_path = current_path.to_s
|
21
|
+
@render_page_menu = render_page_menu
|
21
22
|
|
22
23
|
@menu_items = @menu_items.order(:lft).map do |menu_item|
|
23
24
|
if is_active?(menu_item)
|
@@ -28,6 +29,12 @@ module PandaCms
|
|
28
29
|
|
29
30
|
menu_item
|
30
31
|
end
|
32
|
+
|
33
|
+
# TODO: Surely don't need this but Current.page isn't working in the component
|
34
|
+
if @render_page_menu
|
35
|
+
@current_page = PandaCms::Page.find_by(path: @current_path)
|
36
|
+
@page_menu_styles = page_menu_styles
|
37
|
+
end
|
31
38
|
end
|
32
39
|
|
33
40
|
def is_active?(menu_item)
|
@@ -1,10 +1,12 @@
|
|
1
1
|
<nav class="<%= styles[:container] %>">
|
2
2
|
<ul role="list" class="p-0 m-0">
|
3
|
-
|
4
|
-
<
|
5
|
-
<%= menu_item.
|
6
|
-
|
7
|
-
|
3
|
+
<% if @show_heading %>
|
4
|
+
<li>
|
5
|
+
<a href="<%= menu_item.page.path %>" class="<%= menu_item.page == PandaCms::Current.page ? styles[:current_page_active] : styles[:current_page_inactive] %>">
|
6
|
+
<%= menu_item.text %>
|
7
|
+
</a>
|
8
|
+
</li>
|
9
|
+
<% end %>
|
8
10
|
<ul>
|
9
11
|
<% PandaCms::MenuItem.includes(:page).each_with_level(menu_item.descendants) do |submenu_item, level| %>
|
10
12
|
<% next if PandaCms::Current.page == menu_item.page && level > 1 # If we're on the "top" menu item, only show its direct ancestors %>
|
@@ -6,7 +6,7 @@ module PandaCms
|
|
6
6
|
attr_accessor :menu_item
|
7
7
|
attr_accessor :styles
|
8
8
|
|
9
|
-
def initialize(page:, start_depth:, styles: {})
|
9
|
+
def initialize(page:, start_depth:, styles: {}, show_heading: true)
|
10
10
|
@page = page
|
11
11
|
|
12
12
|
unless @page.nil?
|
@@ -21,6 +21,8 @@ module PandaCms
|
|
21
21
|
|
22
22
|
@menu_item = menu.menu_items.order(:lft)&.first
|
23
23
|
|
24
|
+
@show_heading = show_heading
|
25
|
+
|
24
26
|
# Set some default styles for sanity
|
25
27
|
@styles = styles
|
26
28
|
@styles[:indent_with] ||= "pl-2"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% if @editable %>
|
2
|
-
<
|
3
|
-
|
2
|
+
<div class="panda-cms-content" data-editable-previous-data="<%= @content.to_json %>" id="editor-<%= @options[:id] %>" data-editable-kind="rich_text" data-editable-block-content-id="<%= @options[:id] %>" data-editable-page-id="<%= @options[:data][:page_id] %>" style="border: 1px dashed #ccc; outline: none; cursor: pointer; transition: background 500ms linear; background-color: inherit;">
|
3
|
+
</div>
|
4
4
|
<% else %>
|
5
5
|
<div class="panda-cms-content"><%= @content %></div>
|
6
6
|
<% end %>
|
@@ -25,15 +25,23 @@ module PandaCms
|
|
25
25
|
@editable &&= params[:embed_id].present? && params[:embed_id] == Current.page.id && Current.user.admin?
|
26
26
|
block = PandaCms::Block.find_by(kind: "rich_text", key: @key, panda_cms_template_id: Current.page.panda_cms_template_id)
|
27
27
|
block_content = block.block_contents.find_by(panda_cms_page_id: Current.page.id)
|
28
|
-
|
28
|
+
if block_content.nil?
|
29
|
+
block_content = PandaCms::BlockContent.create(block: block, panda_cms_page_id: Current.page.id, content: "")
|
30
|
+
end
|
29
31
|
|
30
|
-
@
|
32
|
+
@content = block_content.cached_content || block_content.content
|
33
|
+
@options[:id] = block_content.id
|
31
34
|
|
32
35
|
if @editable
|
33
36
|
@options[:data] = {
|
34
|
-
|
35
|
-
mode: "
|
37
|
+
page_id: Current.page.id,
|
38
|
+
mode: "rich_text"
|
36
39
|
}
|
40
|
+
|
41
|
+
@content = block_content.content
|
42
|
+
elsif @content.is_a?(Hash)
|
43
|
+
renderer = PandaCms::EditorJs::Renderer.new(@content)
|
44
|
+
@content = renderer.render
|
37
45
|
else
|
38
46
|
@content = @content.html_safe
|
39
47
|
end
|
@@ -24,7 +24,7 @@ module PandaCms
|
|
24
24
|
content_tag(:span, @content, @options, false) # Don't escape the content
|
25
25
|
rescue
|
26
26
|
if !Rails.env.production? || is_defined?(Sentry)
|
27
|
-
raise PandaCms::MissingBlockError("Block with key #{@key} not found")
|
27
|
+
raise PandaCms::MissingBlockError.new("Block with key #{@key} not found for page #{Current.page.title}")
|
28
28
|
else
|
29
29
|
false
|
30
30
|
end
|
@@ -11,7 +11,7 @@ module PandaCms
|
|
11
11
|
# @type PATCH/PUT
|
12
12
|
# @return
|
13
13
|
def update
|
14
|
-
if @block_content.update(
|
14
|
+
if @block_content.update!(content: params[:content])
|
15
15
|
@block_content.page.touch # Update the page's updated_at
|
16
16
|
render json: @block_content, status: :ok
|
17
17
|
else
|