panda_cms 0.5.10 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/Rakefile +0 -1
- data/app/assets/builds/panda_cms.css +2432 -1
- data/app/assets/config/panda_cms_manifest.js +3 -0
- data/app/assets/stylesheets/panda_cms/application.tailwind.css +3 -27
- data/app/builders/panda_cms/form_builder.rb +1 -1
- data/app/components/panda_cms/admin/button_component.rb +6 -3
- data/app/components/panda_cms/admin/flash_message_component.rb +1 -1
- data/app/components/panda_cms/admin/tag_component.rb +1 -1
- data/app/components/panda_cms/code_component.rb +62 -0
- 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 +12 -8
- data/app/components/panda_cms/page_menu_component.rb +24 -13
- data/app/components/panda_cms/rich_text_component.html.erb +6 -38
- data/app/components/panda_cms/rich_text_component.rb +32 -7
- data/app/components/panda_cms/text_component.rb +25 -22
- data/app/controllers/panda_cms/admin/block_contents_controller.rb +1 -1
- data/app/controllers/panda_cms/admin/dashboard_controller.rb +14 -6
- data/app/controllers/panda_cms/admin/menus_controller.rb +1 -54
- data/app/controllers/panda_cms/admin/pages_controller.rb +2 -1
- data/app/controllers/panda_cms/admin/sessions_controller.rb +13 -6
- data/app/controllers/panda_cms/application_controller.rb +1 -1
- data/app/controllers/panda_cms/pages_controller.rb +1 -1
- data/app/controllers/panda_cms/posts_controller.rb +1 -1
- data/app/helpers/panda_cms/application_helper.rb +2 -2
- data/app/javascript/panda_cms/@editorjs--editorjs.js +2577 -0
- data/app/javascript/panda_cms/@hotwired--stimulus.js +4 -0
- data/app/javascript/panda_cms/@hotwired--turbo.js +160 -0
- data/app/javascript/panda_cms/@rails--actioncable--src.js +4 -0
- data/app/javascript/panda_cms/application_panda_cms.js +4 -0
- data/app/javascript/panda_cms/controllers/dashboard_controller.js +7 -0
- data/app/javascript/panda_cms/controllers/editor_controller.js +247 -0
- data/app/javascript/panda_cms/controllers/index.js +45 -0
- data/app/javascript/panda_cms/controllers/slug_controller.js +48 -0
- 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/javascript/panda_cms/tailwindcss-stimulus-components.js +4 -0
- data/app/lib/panda_cms/demo_site_generator.rb +1 -3
- 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/lib/panda_cms/slug.rb +1 -1
- data/app/models/panda_cms/block.rb +2 -2
- data/app/models/panda_cms/block_content.rb +12 -2
- data/app/models/panda_cms/page.rb +9 -3
- data/app/models/panda_cms/post.rb +1 -1
- data/app/models/panda_cms/template.rb +4 -2
- data/app/models/panda_cms/user.rb +9 -1
- data/app/views/panda_cms/admin/dashboard/show.html.erb +11 -9
- data/app/views/panda_cms/admin/forms/new.html.erb +6 -7
- data/app/views/panda_cms/admin/menus/index.html.erb +0 -2
- data/app/views/panda_cms/admin/pages/edit.html.erb +22 -19
- data/app/views/panda_cms/admin/pages/new.html.erb +6 -7
- data/app/views/panda_cms/admin/posts/_form.html.erb +4 -4
- data/app/views/panda_cms/admin/sessions/new.html.erb +1 -2
- data/app/views/panda_cms/admin/shared/_sidebar.html.erb +12 -16
- data/app/views/panda_cms/shared/_header.html.erb +13 -14
- data/app/views/panda_cms/shared/_importmap.html.erb +32 -0
- data/config/importmap.rb +13 -10
- data/config/initializers/panda_cms.rb +57 -55
- data/config/routes.rb +9 -9
- data/config/tailwind.config.js +1 -0
- data/db/migrate/20240205223709_create_panda_cms_pages.rb +6 -4
- data/db/migrate/20240315125411_add_status_to_panda_cms_pages.rb +9 -0
- data/db/migrate/20241031205109_add_cached_content_to_panda_cms_block_contents.rb +5 -0
- data/db/seeds.rb +1 -0
- data/lib/generators/panda_cms/install_generator.rb +3 -0
- data/lib/panda_cms/engine.rb +42 -29
- data/lib/panda_cms/version.rb +1 -1
- data/lib/panda_cms.rb +58 -10
- data/lib/tasks/panda_cms.rake +41 -57
- data/public/panda-cms-assets/rich_text_editor.css +568 -0
- metadata +228 -304
- data/app/javascript/base.js +0 -37
- data/app/javascript/controllers/menu_controller.js +0 -19
- data/app/javascript/controllers/text_controller.js +0 -78
- data/app/javascript/controllers/text_field_update_controller.js +0 -51
- data/app/javascript/vendor/stimulus-components-rails-nested-form.js +0 -2
- data/app/javascript/vendor/tailwindcss-stimulus-components.js +0 -2
- data/app/views/panda_cms/admin/menus/_form.html.erb +0 -21
- data/app/views/panda_cms/admin/menus/_menu_item_fields.html.erb +0 -7
- data/app/views/panda_cms/admin/menus/edit.html.erb +0 -58
- data/app/views/panda_cms/admin/menus/new.html.erb +0 -5
- data/db/migrate/20240804110225_add_status_to_panda_cms_pages.rb +0 -7
- data/public/panda-cms-assets/javascripts/base.js +0 -37
- data/public/panda-cms-assets/javascripts/controllers/menu_controller.js +0 -19
- data/public/panda-cms-assets/javascripts/controllers/text_field_update_controller.js +0 -23
- data/public/panda-cms-assets/javascripts/embed/editable.js +0 -358
- data/public/panda-cms-assets/javascripts/embed/rich_text.css +0 -1294
- data/public/panda-cms-assets/javascripts/vendor/stimulus-components-rails-nested-form.js +0 -2
- data/public/panda-cms-assets/javascripts/vendor/stimulus-loading.js +0 -113
- data/public/panda-cms-assets/javascripts/vendor/tailwindcss-stimulus-components.js +0 -2
@@ -1,7 +1,6 @@
|
|
1
1
|
<nav class="flex flex-col flex-1">
|
2
2
|
<ul role="list" class="flex flex-col flex-1">
|
3
|
-
<a class="block p-0 mt-4 mb-4 ml-2 text-xl font-medium text-white"><%= PandaCms.title %></a>
|
4
|
-
|
3
|
+
<a class="block p-0 mt-4 mb-4 ml-2 text-xl font-medium text-white"><%= PandaCms.config.title %></a>
|
5
4
|
<% [
|
6
5
|
{ path: admin_dashboard_path, text: "Dashboard", icon: "fa-house", matcher: :exact },
|
7
6
|
{ path: admin_pages_path, text: "Pages", icon: "fa-page", matcher: :starts_with },
|
@@ -10,32 +9,29 @@
|
|
10
9
|
{ path: admin_menus_path, text: "Menus", icon: "fa-list-dropdown", matcher: :starts_with },
|
11
10
|
{ path: admin_settings_path, text: "Settings", icon: "fa-cog", matcher: :starts_with },
|
12
11
|
].each do |link| %>
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
<li>
|
13
|
+
<%= link_to link[:path], class: "#{active_link?(link[:path], match: link[:matcher]) ? selected_nav_highlight_colour_classes(request) : nav_highlight_colour_classes(request)}" do %>
|
14
|
+
<span class="text-center"><i class="fa-regular <%= link[:icon] %> text-xl fa-fw"></i></span>
|
15
|
+
<span class="mt-1"><%= link[:text] %></span>
|
16
|
+
<% end %>
|
17
|
+
</li>
|
19
18
|
<% end %>
|
20
19
|
<li>
|
21
|
-
<%= button_to admin_logout_path, method: :delete, data: { turbo: false }, class: nav_highlight_colour_classes(request) + " w-full" do %>
|
20
|
+
<%= button_to admin_logout_path, method: :delete, id: "logout-link", data: { turbo: false }, class: nav_highlight_colour_classes(request) + " w-full" do %>
|
22
21
|
<span class="text-center"><i class="text-xl fa-regular fa-door-open fa-fw"></i></span>
|
23
|
-
<span class="mt-1">
|
22
|
+
<span class="mt-1">Logout</span>
|
24
23
|
<% end %>
|
25
24
|
</li>
|
26
|
-
|
27
25
|
<li class="mt-auto">
|
28
26
|
<%= button_to '#', data: { turbo: false }, class: nav_highlight_colour_classes(request) + " w-full" do %>
|
29
|
-
<% if !current_user.image_url.empty? %>
|
30
|
-
|
27
|
+
<% if !current_user.image_url.to_s.empty? %>
|
28
|
+
<span class="text-center"><img src="<%= current_user.image_url %>" class="w-auto h-7 rounded-full"></span>
|
31
29
|
<% else %>
|
32
|
-
|
30
|
+
<span class="text-center"><i class="text-xl fa-regular fa-circle-user fa-fw"></i></span>
|
33
31
|
<% end %>
|
34
|
-
|
35
32
|
<span class="mt-0.5"><%= current_user.firstname %> <%= current_user.lastname %></span>
|
36
33
|
<% end %>
|
37
34
|
</li>
|
38
|
-
|
39
35
|
<li class="">
|
40
36
|
<img src="/panda-cms-assets/panda-nav.png" class="inline py-2 mr-1 ml-0.5 w-auto h-14">
|
41
37
|
<span class="text-xs text-white">v<%= PandaCms::VERSION %> | <span class="font-semibold">License:</span> Perpetual</span>
|
@@ -1,16 +1,15 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html data-theme="default" class="<%= html_class ||= "" %>">
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
</head>
|
14
|
-
|
15
|
-
|
16
|
-
<%= render "panda_cms/admin/shared/flash" %>
|
3
|
+
<head>
|
4
|
+
<title><%= title_tag %></title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<script src="https://kit.fontawesome.com/7835d81e75.js" defer="true" crossorigin="anonymous"></script>
|
8
|
+
<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js" defer="true" crossorigin="anonymous"></script>
|
9
|
+
<%= stylesheet_link_tag "panda_cms", "data-turbo-track": "reload", media: "all" %>
|
10
|
+
<%= render "panda_cms/shared/importmap" %>
|
11
|
+
<%= render "panda_cms/shared/favicons" %>
|
12
|
+
<%= yield :head %>
|
13
|
+
</head>
|
14
|
+
<body class="overflow-hidden h-full">
|
15
|
+
<%= render "panda_cms/admin/shared/flash" %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<%#= javascript_importmap_tags "application_panda_cms" %>
|
2
|
+
<script type="importmap" data-turbo-track="reload">
|
3
|
+
<%=
|
4
|
+
# This ended up being the best solution to not drag in the importmap from the host app when we're editing the site
|
5
|
+
JSON.pretty_generate({
|
6
|
+
imports: {
|
7
|
+
# Main loader
|
8
|
+
"application_panda_cms": asset_path("panda_cms/application_panda_cms.js"),
|
9
|
+
# Vendored
|
10
|
+
"@hotwired/turbo": asset_path("panda_cms/@hotwired--turbo.js"),
|
11
|
+
"@hotwired/stimulus": asset_path("panda_cms/@hotwired--stimulus.js"),
|
12
|
+
"@hotwired/stimulus-loading": asset_path("stimulus-loading.js"),
|
13
|
+
"@editorjs/editorjs": asset_path("panda_cms/@editorjs--editorjs.js"),
|
14
|
+
"tailwindcss-stimulus-components": asset_path("panda_cms/tailwindcss-stimulus-components.js"),
|
15
|
+
# Our controllers
|
16
|
+
"panda_cms_controllers/dashboard_controller": asset_path("panda_cms/controllers/dashboard_controller.js"),
|
17
|
+
"panda_cms_controllers/slug_controller": asset_path("panda_cms/controllers/slug_controller.js"),
|
18
|
+
# Add other controllers here
|
19
|
+
# Our page editor
|
20
|
+
"panda_cms_controllers/editor_controller": asset_path("panda_cms/controllers/editor_controller.js"),
|
21
|
+
"panda_cms_editor/plain_text_editor": asset_path("panda_cms/editor/plain_text_editor.js"),
|
22
|
+
"panda_cms_editor/rich_text_editor": asset_path("panda_cms/editor/rich_text_editor.js"),
|
23
|
+
"panda_cms_editor/resource_loader": asset_path("panda_cms/editor/resource_loader.js"),
|
24
|
+
# Main controller loader
|
25
|
+
"controllers": asset_path("panda_cms/controllers/index.js"),
|
26
|
+
}
|
27
|
+
}).html_safe
|
28
|
+
%>
|
29
|
+
</script>
|
30
|
+
<script type="module">
|
31
|
+
import "application_panda_cms"
|
32
|
+
</script>
|
data/config/importmap.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
pin "
|
2
|
-
pin "@hotwired/stimulus-loading", to: "/panda-cms-assets/javascripts/vendor/stimulus-loading.js" # 3.2.2
|
3
|
-
pin "@hotwired/turbo-rails", to: "turbo.min.js"
|
4
|
-
pin "@rails/activestorage", to: "https://ga.jspm.io/npm:@rails/activestorage@7.2.0/app/assets/javascripts/activestorage.esm.js"
|
1
|
+
pin "application_panda_cms", to: "panda_cms/application_panda_cms.js", preload: true
|
5
2
|
|
6
|
-
pin "
|
7
|
-
pin "
|
8
|
-
pin "
|
9
|
-
pin "
|
10
|
-
pin "
|
11
|
-
pin "
|
3
|
+
pin "@hotwired/turbo", to: "@hotwired--turbo.js", preload: true # @8.0.12
|
4
|
+
pin "@rails/actioncable/src", to: "@rails--actioncable--src.js", preload: true # @7.2.101
|
5
|
+
pin "@hotwired/stimulus", to: "@hotwired--stimulus.js" # @3.2.2
|
6
|
+
pin "@hotwired/stimulus-loading", to: "panda_cms/stimulus-loading.js", preload: true
|
7
|
+
pin "tailwindcss-stimulus-components" # @6.1.2
|
8
|
+
pin "@editorjs/editorjs", to: "@editorjs--editorjs.js" # @2.30.6
|
9
|
+
|
10
|
+
# pin "@rails/activestorage", to: "@rails--activestorage.js" # @7.2.100
|
11
|
+
# pin "@rails/actioncable", to: "@rails--actioncable.js" # @7.2.100
|
12
|
+
|
13
|
+
pin_all_from PandaCms::Engine.root.join("app/javascript/panda_cms/controllers"), under: "panda_cms_controllers", to: "panda_cms/controllers"
|
14
|
+
pin_all_from PandaCms::Engine.root.join("app/javascript/panda_cms/editor"), under: "editor", to: "panda_cms/editor"
|
@@ -1,58 +1,60 @@
|
|
1
|
-
|
2
|
-
# The
|
3
|
-
|
4
|
-
|
5
|
-
# The
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
1
|
+
PandaCms.configure do |config|
|
2
|
+
# The main title of your website
|
3
|
+
# The default is "Demo Site"
|
4
|
+
config.title = "Demo Site"
|
5
|
+
# The path to the administration panel, which must start with a /
|
6
|
+
# The default is "/admin"
|
7
|
+
config.admin_path = "/admin"
|
8
|
+
# Is login required to access the site? (Else, show maintenance page)
|
9
|
+
config.require_login_to_view = false
|
10
|
+
# Authentication providers
|
11
|
+
config.authentication = {
|
12
|
+
microsoft: {
|
13
|
+
enabled: true,
|
14
|
+
# Setup at the following URL:
|
15
|
+
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
|
16
|
+
client_id: Rails.application.credentials.dig(:microsoft, :client_id),
|
17
|
+
client_secret: Rails.application.credentials.dig(:microsoft, :client_secret),
|
18
|
+
# Don't change this or the sky will fall on your head
|
19
|
+
# https://github.com/synth/omniauth-microsoft_graph/tree/main?tab=readme-ov-file#domain-verification
|
20
|
+
skip_domain_verification: false,
|
21
|
+
# If your application is single-tenanted, replace "common" with your tenant (directory) ID
|
22
|
+
# from https://portal.azure.com/#settings/directory, otherwise you'll likely want to leave
|
23
|
+
# these settings unchanged
|
24
|
+
client_options: {
|
25
|
+
site: "https://login.microsoftonline.com/",
|
26
|
+
token_url: "common/oauth2/v2.0/token",
|
27
|
+
authorize_url: "common/oauth2/v2.0/authorize"
|
28
|
+
},
|
29
|
+
# If you assign specific users or groups, you will likely want to set this to true to enable
|
30
|
+
# auto-provisioning
|
31
|
+
create_account_on_first_login: false,
|
32
|
+
redirect_uri: Rails.application.credentials.dig(:microsoft, :redirect_uri)
|
27
33
|
},
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
google: {
|
35
|
+
enabled: true,
|
36
|
+
create_account_on_first_login: false,
|
37
|
+
create_admin_account_on_first_login: false,
|
38
|
+
# client_id: Rails.application.credentials.dig(:google, :client_id),
|
39
|
+
# client_secret: Rails.application.credentials.dig(:google, :client_secret),
|
40
|
+
client_id: "552337866923-o1jd9ushva70su79c2ke8ftnu623chsl.apps.googleusercontent.com", # Will only work on localhost
|
41
|
+
client_secret: "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", # Will only work on localhost
|
42
|
+
redirect_uri: Rails.application.credentials.dig(:google, :redirect_uri)
|
43
|
+
},
|
44
|
+
github: {
|
45
|
+
enabled: true,
|
46
|
+
create_account_on_first_login: false,
|
47
|
+
create_admin_account_on_first_login: false,
|
48
|
+
# client_id: Rails.application.credentials.dig(:github, :client_id),
|
49
|
+
# client_secret: Rails.application.credentials.dig(:github, :client_secret),
|
50
|
+
client_id: "Ov23li9k0LpMXtq8FShb", # Will only work on localhost
|
51
|
+
client_secret: "07233b63472b7f287ac11854e627670ddc096a22", # Will only work on localhost
|
52
|
+
redirect_uri: Rails.application.credentials.dig(:github, :redirect_uri)
|
53
|
+
}
|
54
|
+
}
|
55
|
+
# Blog
|
56
|
+
config.posts = {
|
44
57
|
enabled: true,
|
45
|
-
|
46
|
-
create_admin_account_on_first_login: false,
|
47
|
-
# client_id: Rails.application.credentials.dig(:github, :client_id),
|
48
|
-
# client_secret: Rails.application.credentials.dig(:github, :client_secret),
|
49
|
-
client_id: "Ov23li9k0LpMXtq8FShb", # Will only work on localhost
|
50
|
-
client_secret: "07233b63472b7f287ac11854e627670ddc096a22", # Will only work on localhost
|
51
|
-
redirect_uri: Rails.application.credentials.dig(:github, :redirect_uri)
|
58
|
+
prefix: "blog"
|
52
59
|
}
|
53
|
-
|
54
|
-
# Blog
|
55
|
-
PandaCms.posts = {
|
56
|
-
enabled: true,
|
57
|
-
prefix: "blog"
|
58
|
-
}
|
60
|
+
end
|
data/config/routes.rb
CHANGED
@@ -2,7 +2,7 @@ require_relative "../app/constraints/panda_cms/admin_constraint"
|
|
2
2
|
|
3
3
|
PandaCms::Engine.routes.draw do
|
4
4
|
constraints PandaCms::AdminConstraint.new(&:present?) do
|
5
|
-
namespace PandaCms.
|
5
|
+
namespace PandaCms.route_namespace, as: :admin, module: :admin do
|
6
6
|
resources :files
|
7
7
|
resources :forms, only: %i[index show]
|
8
8
|
resources :menus
|
@@ -22,24 +22,24 @@ PandaCms::Engine.routes.draw do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
get PandaCms.
|
25
|
+
get PandaCms.route_namespace, to: "admin/dashboard#show", as: :admin_dashboard
|
26
26
|
end
|
27
27
|
|
28
28
|
### PUBLIC ROUTES ###
|
29
29
|
|
30
30
|
# Authentication routes
|
31
|
-
get PandaCms.
|
31
|
+
get PandaCms.route_namespace, to: "admin/sessions#new", as: :admin_login
|
32
32
|
# Get and post options here are for OmniAuth coming back in, not going out
|
33
|
-
match "#{PandaCms.
|
34
|
-
match "#{PandaCms.
|
35
|
-
# OmniAuth additionally adds a GET route for "#{PandaCms.
|
36
|
-
delete PandaCms.
|
33
|
+
match "#{PandaCms.route_namespace}/auth/:provider/callback", to: "admin/sessions#create", as: :admin_login_callback, via: %i[get post]
|
34
|
+
match "#{PandaCms.route_namespace}/auth/failure", to: "admin/sessions#failure", as: :admin_login_failure, via: %i[get post]
|
35
|
+
# OmniAuth additionally adds a GET route for "#{PandaCms.route_namespace}/auth/:provider" but doesn't name it
|
36
|
+
delete PandaCms.route_namespace, to: "admin/sessions#destroy", as: :admin_logout
|
37
37
|
|
38
|
-
if PandaCms.posts
|
38
|
+
if PandaCms.config.posts[:enabled]
|
39
39
|
# TODO: Allow multiple types of post in future
|
40
40
|
# TODO: This now requires a page to be created, make it explicit (with a rendering posts helper?)
|
41
41
|
# get PandaCms.posts[:prefix], to: "posts#index", as: :posts
|
42
|
-
get "#{PandaCms.posts[:prefix]}/:slug", to: "posts#show", as: :post
|
42
|
+
get "#{PandaCms.config.posts[:prefix]}/:slug", to: "posts#show", as: :post
|
43
43
|
end
|
44
44
|
|
45
45
|
### APPENDED ROUTES ###
|
data/config/tailwind.config.js
CHANGED
@@ -23,6 +23,7 @@ module.exports = {
|
|
23
23
|
dark: "rgb(var(--color-dark) / <alpha-value>)",
|
24
24
|
highlight: "rgb(var(--color-highlight) / <alpha-value>)",
|
25
25
|
active: "rgb(var(--color-active) / <alpha-value>)",
|
26
|
+
inactive: "rgb(var(--color-active) / <alpha-value>)",
|
26
27
|
warning: "rgb(var(--color-warning) / <alpha-value>)",
|
27
28
|
error: "rgb(var(--color-error) / <alpha-value>)",
|
28
29
|
},
|
@@ -1,9 +1,11 @@
|
|
1
1
|
class CreatePandaCmsPages < ActiveRecord::Migration[7.1]
|
2
2
|
def change
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
unless table_exists?(:panda_cms_pages)
|
4
|
+
create_table :panda_cms_pages, id: :uuid do |t|
|
5
|
+
t.string :title
|
6
|
+
t.string :path
|
7
|
+
t.timestamps
|
8
|
+
end
|
7
9
|
end
|
8
10
|
end
|
9
11
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class AddStatusToPandaCmsPages < ActiveRecord::Migration[7.1]
|
2
|
+
def change
|
3
|
+
unless column_exists?(:panda_cms_pages, :status)
|
4
|
+
create_enum :panda_cms_page_status, ["active", "draft", "hidden", "archived"]
|
5
|
+
add_column :panda_cms_pages, :status, :panda_cms_page_status, default: "active", null: false
|
6
|
+
add_index :panda_cms_pages, :status
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/db/seeds.rb
CHANGED
data/lib/panda_cms/engine.rb
CHANGED
@@ -1,22 +1,16 @@
|
|
1
|
-
require "groupdate"
|
2
1
|
require "importmap-rails"
|
3
|
-
require "
|
2
|
+
require "turbo-rails"
|
3
|
+
require "stimulus-rails"
|
4
4
|
require "view_component"
|
5
|
-
require "lookbook"
|
6
|
-
|
7
|
-
require "omniauth"
|
8
|
-
require "omniauth/rails_csrf_protection"
|
9
|
-
require "omniauth/strategies/microsoft_graph"
|
10
|
-
require "omniauth/strategies/google_oauth2"
|
11
|
-
require "omniauth/strategies/github"
|
12
|
-
|
13
|
-
require "panda_cms/exceptions_app"
|
14
5
|
|
15
6
|
module PandaCms
|
16
7
|
class Engine < ::Rails::Engine
|
17
8
|
isolate_namespace PandaCms
|
18
9
|
engine_name "panda_cms"
|
19
10
|
|
11
|
+
initializer "panda_cms" do |app|
|
12
|
+
end
|
13
|
+
|
20
14
|
config.to_prepare do
|
21
15
|
ApplicationController.helper(::ApplicationHelper)
|
22
16
|
end
|
@@ -30,19 +24,27 @@ module PandaCms
|
|
30
24
|
g.templates.unshift File.expand_path("../../templates", __FILE__)
|
31
25
|
end
|
32
26
|
|
33
|
-
# Make files in public available to the main app (e.g. favicon.ico)
|
27
|
+
# Make files in public available to the main app (e.g. /panda-cms-assets/favicon.ico)
|
34
28
|
config.app_middleware.use(
|
35
29
|
Rack::Static,
|
36
30
|
urls: ["/panda-cms-assets"],
|
37
31
|
root: PandaCms::Engine.root.join("public")
|
38
32
|
)
|
39
33
|
|
40
|
-
|
34
|
+
# Custom error handling
|
35
|
+
# config.exceptions_app = PandaCms::ExceptionsApp.new(exceptions_app: routes)
|
36
|
+
|
37
|
+
initializer "panda_cms.assets" do |app|
|
38
|
+
if Rails.configuration.respond_to?(:assets)
|
39
|
+
app.config.assets.paths << root.join("app/javascript")
|
40
|
+
app.config.assets.precompile += %w[panda_cms_manifest]
|
41
|
+
end
|
42
|
+
end
|
41
43
|
|
42
|
-
#
|
44
|
+
# Add importmap paths from the engine
|
43
45
|
initializer "panda_cms.importmap", before: "importmap" do |app|
|
44
|
-
app.config.importmap.
|
45
|
-
app.config.importmap.
|
46
|
+
app.config.importmap.paths << root.join("config/importmap.rb")
|
47
|
+
app.config.importmap.cache_sweepers << root.join("app/javascript")
|
46
48
|
end
|
47
49
|
|
48
50
|
config.after_initialize do |app|
|
@@ -54,6 +56,9 @@ module PandaCms
|
|
54
56
|
get "/*path", to: "panda_cms/pages#show", as: :panda_cms_page
|
55
57
|
root to: "panda_cms/pages#root"
|
56
58
|
end
|
59
|
+
|
60
|
+
# Ensure we don't have any missing blocks from new templates
|
61
|
+
PandaCms::Template.generate_missing_blocks
|
57
62
|
end
|
58
63
|
|
59
64
|
# Add the migrations to the main app
|
@@ -67,13 +72,13 @@ module PandaCms
|
|
67
72
|
|
68
73
|
# Set up ViewComponent and Lookbook
|
69
74
|
# config.view_component.component_parent_class = "PandaCms::BaseComponent"
|
70
|
-
config.view_component.view_component_path = PandaCms::Engine.root.join("lib/components").to_s
|
71
|
-
config.eager_load_paths << PandaCms::Engine.root.join("lib/components").to_s
|
72
|
-
config.view_component.generate.sidecar = true
|
73
|
-
config.view_component.generate.preview = true
|
74
|
-
config.view_component.preview_paths ||= []
|
75
|
-
config.view_component.preview_paths << PandaCms::Engine.root.join("lib/component_previews").to_s
|
76
|
-
config.view_component.generate.preview_path = "lib/component_previews"
|
75
|
+
# config.view_component.view_component_path = PandaCms::Engine.root.join("lib/components").to_s
|
76
|
+
# config.eager_load_paths << PandaCms::Engine.root.join("lib/components").to_s
|
77
|
+
# config.view_component.generate.sidecar = true
|
78
|
+
# config.view_component.generate.preview = true
|
79
|
+
# config.view_component.preview_paths ||= []
|
80
|
+
# config.view_component.preview_paths << PandaCms::Engine.root.join("lib/component_previews").to_s
|
81
|
+
# config.view_component.generate.preview_path = "lib/component_previews"
|
77
82
|
|
78
83
|
# Set up authentication
|
79
84
|
initializer "panda_cms.omniauth", before: "omniauth" do |app|
|
@@ -82,11 +87,11 @@ module PandaCms
|
|
82
87
|
app.config.middleware.use ActionDispatch::Session::CookieStore, app.config.session_options
|
83
88
|
|
84
89
|
OmniAuth.config.logger = Rails.logger
|
85
|
-
auth_path = "#{PandaCms.admin_path}/auth"
|
86
|
-
callback_path = "/callback"
|
87
90
|
|
88
91
|
# TODO: Move this to somewhere more sensible
|
89
92
|
# Define the mapping of our provider "names" to the OmniAuth strategies and configuration
|
93
|
+
auth_path = "#{PandaCms.route_namespace}/auth"
|
94
|
+
callback_path = "/callback"
|
90
95
|
available_providers = {
|
91
96
|
microsoft: {
|
92
97
|
strategy: :microsoft_graph,
|
@@ -157,13 +162,17 @@ module PandaCms
|
|
157
162
|
}
|
158
163
|
|
159
164
|
available_providers.each do |provider, options|
|
160
|
-
if PandaCms.authentication.dig(provider, :enabled)
|
165
|
+
if PandaCms.config.authentication.dig(provider, :enabled)
|
166
|
+
auth_path = auth_path.starts_with?("/") ? auth_path : "/#{auth_path}"
|
161
167
|
options[:defaults][:path_prefix] = auth_path
|
162
|
-
options[:defaults][:redirect_uri] = "#{PandaCms.url}#{auth_path}/#{provider}#{callback_path}"
|
163
168
|
|
164
|
-
|
169
|
+
options[:defaults][:redirect_uri] = if Rails.env.test?
|
170
|
+
"#{Capybara.app_host}#{auth_path}/#{provider}#{callback_path}"
|
171
|
+
else
|
172
|
+
"#{PandaCms.config.url}#{auth_path}/#{provider}#{callback_path}"
|
173
|
+
end
|
165
174
|
|
166
|
-
|
175
|
+
provider_config = options[:defaults].merge(PandaCms.config.authentication[provider])
|
167
176
|
|
168
177
|
app.config.middleware.use OmniAuth::Builder do
|
169
178
|
provider options[:strategy], provider_config
|
@@ -172,4 +181,8 @@ module PandaCms
|
|
172
181
|
end
|
173
182
|
end
|
174
183
|
end
|
184
|
+
|
185
|
+
class MissingBlockError < StandardError; end
|
186
|
+
|
187
|
+
class BlockError < StandardError; end
|
175
188
|
end
|
data/lib/panda_cms/version.rb
CHANGED
data/lib/panda_cms.rb
CHANGED
@@ -1,15 +1,63 @@
|
|
1
|
-
require "
|
1
|
+
require "dry-configurable"
|
2
|
+
require "importmap-rails"
|
3
|
+
require "lookbook"
|
4
|
+
require "omniauth"
|
5
|
+
require "omniauth/rails_csrf_protection"
|
6
|
+
require "omniauth/strategies/microsoft_graph"
|
7
|
+
require "omniauth/strategies/google_oauth2"
|
8
|
+
require "omniauth/strategies/github"
|
9
|
+
require "paper_trail"
|
10
|
+
require "view_component"
|
11
|
+
|
12
|
+
require "panda_cms/exceptions_app"
|
13
|
+
|
2
14
|
require "panda_cms/engine"
|
15
|
+
require "panda_cms/version"
|
3
16
|
|
4
17
|
module PandaCms
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
extend Dry::Configurable
|
19
|
+
|
20
|
+
setting :admin_path, default: "/admin"
|
21
|
+
setting :authentication, default: {}
|
22
|
+
setting :posts, default: {}
|
23
|
+
setting :title, default: "Demo Site"
|
24
|
+
setting :url, default: "http://localhost:3000"
|
25
|
+
setting :require_login_to_view, default: false
|
26
|
+
setting :error_reporting do
|
27
|
+
setting :sentry do
|
28
|
+
setting :enabled, default: false
|
29
|
+
setting :dsn
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Defines the namespace for the admin routes
|
35
|
+
#
|
36
|
+
# @return [Symbol] The namespace for the admin routes
|
37
|
+
# @visibility public
|
38
|
+
# @example
|
39
|
+
# "/admin" => :admin
|
40
|
+
def self.route_namespace
|
41
|
+
PandaCms.config.admin_path.delete_prefix("/").to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Returns the root path for the admin routes
|
46
|
+
#
|
47
|
+
# @return [Symbol] The root path for the admin routes
|
48
|
+
# @visibility public
|
49
|
+
# @example "/admin"
|
50
|
+
def self.root_path
|
51
|
+
PandaCms.config.admin_path
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Returns the title for the website
|
56
|
+
#
|
57
|
+
# @return [Symbol] The title for the website
|
58
|
+
# @visibility public
|
59
|
+
# @example "Demo Site"
|
60
|
+
def self.title
|
61
|
+
PandaCms.config.title
|
14
62
|
end
|
15
63
|
end
|