pages_core 3.14.0 → 3.15.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/VERSION +1 -1
- data/app/assets/builds/pages_core/admin-dist.js +19 -8
- data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
- data/app/assets/builds/pages_core/admin.css +672 -379
- data/app/assets/fonts/Inter-Black.woff2 +0 -0
- data/app/assets/fonts/Inter-BlackItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Bold.woff2 +0 -0
- data/app/assets/fonts/Inter-BoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraBold.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraLight.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraLightItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Italic.woff2 +0 -0
- data/app/assets/fonts/Inter-Light.woff2 +0 -0
- data/app/assets/fonts/Inter-LightItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Medium.woff2 +0 -0
- data/app/assets/fonts/Inter-MediumItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Regular.woff2 +0 -0
- data/app/assets/fonts/Inter-SemiBold.woff2 +0 -0
- data/app/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Thin.woff2 +0 -0
- data/app/assets/fonts/Inter-ThinItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Black.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-BlackItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Bold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-BoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraBold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraBoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraLight.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraLightItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Italic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Light.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-LightItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Medium.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-MediumItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Regular.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-SemiBold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-SemiBoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Thin.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ThinItalic.woff2 +0 -0
- data/app/assets/fonts/InterVariable-Italic.woff2 +0 -0
- data/app/assets/fonts/InterVariable.woff2 +0 -0
- data/app/assets/stylesheets/pages_core/admin/components/archive.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/components/attachments.css +22 -34
- data/app/assets/stylesheets/pages_core/admin/components/base.css +1 -68
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +107 -48
- data/app/assets/stylesheets/pages_core/admin/components/header.css +56 -58
- data/app/assets/stylesheets/pages_core/admin/components/image_editor.css +35 -24
- data/app/assets/stylesheets/pages_core/admin/components/image_grid.css +28 -27
- data/app/assets/stylesheets/pages_core/admin/components/image_uploader.css +5 -5
- data/app/assets/stylesheets/pages_core/admin/components/layout.css +7 -1
- data/app/assets/stylesheets/pages_core/admin/components/list_table.css +24 -15
- data/app/assets/stylesheets/pages_core/admin/components/page_tree.css +63 -104
- data/app/assets/stylesheets/pages_core/admin/components/pagination.css +12 -13
- data/app/assets/stylesheets/pages_core/admin/components/search.css +1 -16
- data/app/assets/stylesheets/pages_core/admin/components/sidebar.css +5 -11
- data/app/assets/stylesheets/pages_core/admin/components/tag_editor.css +22 -36
- data/app/assets/stylesheets/pages_core/admin/components/toast.css +1 -2
- data/app/assets/stylesheets/pages_core/admin/components/toolbar.css +10 -10
- data/app/assets/stylesheets/pages_core/admin/components/totp.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +37 -51
- data/app/assets/stylesheets/pages_core/admin/global/fonts.css +271 -0
- data/app/assets/stylesheets/pages_core/admin/global/typography.css +109 -0
- data/app/assets/stylesheets/pages_core/admin/vars.css +1 -3
- data/app/assets/stylesheets/pages_core/admin.postcss.css +1 -0
- data/app/controllers/admin/account_recoveries_controller.rb +2 -2
- data/app/controllers/admin/pages_controller.rb +22 -42
- data/app/controllers/concerns/pages_core/error_reporting.rb +1 -1
- data/app/controllers/concerns/pages_core/page_parameters.rb +29 -0
- data/app/controllers/concerns/pages_core/policies_helper.rb +1 -1
- data/app/controllers/concerns/pages_core/preview_pages_controller.rb +20 -20
- data/app/controllers/pages_core/admin_controller.rb +0 -2
- data/app/controllers/pages_core/frontend/pages_controller.rb +2 -6
- data/app/formatters/pages_core/html_formatter.rb +2 -4
- data/app/helpers/admin/menu_helper.rb +5 -4
- data/app/helpers/admin/pages_helper.rb +1 -21
- data/app/helpers/pages_core/admin/admin_helper.rb +2 -3
- data/app/helpers/pages_core/admin/content_tabs_helper.rb +1 -2
- data/app/helpers/pages_core/admin/labelled_field_helper.rb +1 -1
- data/app/helpers/pages_core/frontend_helper.rb +1 -1
- data/app/helpers/pages_core/images_helper.rb +10 -8
- data/app/helpers/pages_core/labelled_form_builder.rb +2 -7
- data/app/helpers/pages_core/page_path_helper.rb +1 -1
- data/app/javascript/components/Attachments/Attachment.tsx +20 -18
- data/app/javascript/components/Attachments/AttachmentEditor.tsx +11 -9
- data/app/javascript/components/{Attachments.jsx → Attachments/List.tsx} +58 -63
- data/app/javascript/components/Attachments/useAttachments.ts +15 -0
- data/app/javascript/components/Attachments.tsx +14 -0
- data/app/javascript/components/DateRangeSelect.tsx +105 -0
- data/app/javascript/components/DateTimeSelect.tsx +136 -0
- data/app/javascript/components/EditableImage.tsx +11 -9
- data/app/javascript/components/FileUploadButton.tsx +7 -7
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +9 -12
- data/app/javascript/components/ImageCropper/Image.tsx +10 -8
- data/app/javascript/components/ImageCropper/Toolbar.tsx +11 -12
- data/app/javascript/components/ImageCropper/useCrop.ts +24 -53
- data/app/javascript/components/ImageCropper.tsx +10 -15
- data/app/javascript/components/ImageEditor/Form.tsx +12 -8
- data/app/javascript/components/ImageEditor.tsx +12 -7
- data/app/javascript/components/ImageGrid/DragElement.tsx +9 -12
- data/app/javascript/components/{ImageGrid.jsx → ImageGrid/Grid.tsx} +62 -71
- data/app/javascript/components/ImageGrid/GridImage.tsx +22 -23
- data/app/javascript/components/ImageGrid/Placeholder.tsx +2 -2
- data/app/javascript/components/ImageGrid/useImageGrid.ts +26 -0
- data/app/javascript/components/ImageGrid.tsx +15 -0
- data/app/javascript/components/ImageUploader.tsx +35 -22
- data/app/javascript/components/LabelledField.tsx +34 -0
- data/app/javascript/components/Modal.tsx +2 -2
- data/app/javascript/components/PageForm/Block.tsx +81 -0
- data/app/javascript/components/PageForm/Content.tsx +54 -0
- data/app/javascript/components/PageForm/Dates.tsx +66 -0
- data/app/javascript/components/PageForm/Files.tsx +28 -0
- data/app/javascript/components/PageForm/Form.tsx +41 -0
- data/app/javascript/components/PageForm/Images.tsx +28 -0
- data/app/javascript/components/PageForm/LocaleLinks.tsx +36 -0
- data/app/javascript/components/PageForm/Metadata.tsx +67 -0
- data/app/javascript/components/PageForm/Options.tsx +180 -0
- data/app/javascript/components/PageForm/PageDescription.tsx +48 -0
- data/app/javascript/components/PageForm/PathSegment.tsx +65 -0
- data/app/javascript/components/PageForm/TabPanel.tsx +21 -0
- data/app/javascript/components/PageForm/Tabs.tsx +33 -0
- data/app/javascript/components/PageForm/UnconfiguredContent.tsx +42 -0
- data/app/javascript/components/PageForm/pageParams.ts +95 -0
- data/app/javascript/components/PageForm/preview.ts +23 -0
- data/app/javascript/components/PageForm/usePage.ts +169 -0
- data/app/javascript/components/PageForm/useTabs.ts +46 -0
- data/app/javascript/components/PageForm.tsx +163 -0
- data/app/javascript/components/PageImages.tsx +7 -9
- data/app/javascript/components/PageTree/Draggable.tsx +40 -39
- data/app/javascript/components/PageTree/Node.tsx +62 -56
- data/app/javascript/components/PageTree/PageName.tsx +28 -0
- data/app/javascript/components/PageTree.tsx +65 -53
- data/app/javascript/components/{RichTextArea.jsx → RichTextArea.tsx} +98 -79
- data/app/javascript/components/RichTextToolbarButton.tsx +4 -6
- data/app/javascript/components/TagEditor/AddTagForm.tsx +19 -12
- data/app/javascript/components/TagEditor/Editor.tsx +32 -0
- data/app/javascript/components/TagEditor/Tag.tsx +6 -4
- data/app/javascript/components/TagEditor/useTags.ts +58 -0
- data/app/javascript/components/TagEditor.tsx +8 -58
- data/app/javascript/components/Toast.tsx +3 -3
- data/app/javascript/components/drag/draggedOrder.ts +22 -14
- data/app/javascript/components/drag/useDragCollection.ts +35 -30
- data/app/javascript/components/drag/useDragUploader.ts +32 -21
- data/app/javascript/components/drag/useDraggable.ts +7 -6
- data/app/javascript/components/drag.ts +0 -1
- data/app/javascript/components.ts +1 -3
- data/app/javascript/features/RichText.tsx +2 -3
- data/app/javascript/features/contentTabs.ts +79 -0
- data/app/javascript/index.ts +5 -12
- data/app/javascript/lib/Tree.ts +31 -45
- data/app/javascript/lib/request.ts +11 -11
- data/app/javascript/stores/useToastStore.ts +1 -1
- data/app/javascript/types/Attachments.ts +29 -0
- data/app/javascript/types/Crop.ts +36 -0
- data/app/javascript/types/Drag.ts +34 -0
- data/app/javascript/types/Images.ts +47 -0
- data/app/javascript/types/PageEditor.ts +26 -0
- data/app/javascript/types/Pages.ts +75 -0
- data/app/javascript/types/Tags.ts +9 -0
- data/app/javascript/types/Template.ts +24 -0
- data/app/javascript/types/Trees.ts +19 -0
- data/app/javascript/types.ts +2 -25
- data/app/models/attachment.rb +1 -1
- data/app/models/concerns/pages_core/authenticable_user.rb +63 -0
- data/app/models/concerns/pages_core/emailable.rb +16 -0
- data/app/models/concerns/pages_core/page_model/templateable.rb +2 -16
- data/app/models/invite.rb +2 -6
- data/app/models/otp_secret.rb +4 -4
- data/app/models/page.rb +0 -3
- data/app/models/user.rb +2 -46
- data/app/policies/page_policy.rb +6 -2
- data/app/resources/admin/page_resource.rb +95 -0
- data/app/resources/admin/page_tree_resource.rb +27 -0
- data/app/resources/admin/template_configuration_resource.rb +50 -0
- data/app/views/admin/news/_sidebar.html.erb +2 -4
- data/app/views/admin/news/index.html.erb +0 -1
- data/app/views/admin/pages/_form.html.erb +10 -30
- data/app/views/admin/pages/_search_bar.html.erb +1 -1
- data/app/views/admin/pages/edit.html.erb +1 -57
- data/app/views/admin/pages/index.html.erb +1 -1
- data/app/views/admin/pages/new.html.erb +1 -44
- data/app/views/admin/sessions/new.html.erb +9 -11
- data/app/views/admin/users/_access_control.html.erb +5 -1
- data/app/views/admin/users/_list.html.erb +12 -7
- data/app/views/layouts/admin/_header.html.erb +2 -4
- data/app/views/layouts/admin/_page_header.html.erb +1 -2
- data/app/views/layouts/admin.html.erb +1 -1
- data/config/locales/en.yml +0 -4
- data/config/routes.rb +3 -7
- data/db/migrate/20240126160700_add_2fa_fields.rb +5 -1
- data/db/migrate/20240131140700_change_email_to_citext.rb +18 -0
- data/db/migrate/20240201160700_remove_persistent_data.rb +7 -0
- data/db/migrate/20240508145300_remove_categories.rb +21 -0
- data/lib/pages_core/configuration/base.rb +2 -2
- data/lib/pages_core/templates/configuration.rb +1 -1
- data/lib/pages_core/templates/configuration_proxy.rb +2 -2
- data/lib/pages_core/templates/template_configuration.rb +11 -1
- data/lib/pages_core/templates.rb +6 -4
- data/lib/pages_core/version.rb +1 -1
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +6 -7
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +17 -12
- data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +0 -2
- data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +3 -4
- metadata +95 -29
- data/app/assets/stylesheets/pages_core/admin/components/login.css +0 -27
- data/app/controllers/admin/categories_controller.rb +0 -56
- data/app/controllers/concerns/pages_core/admin/persistent_params.rb +0 -75
- data/app/helpers/pages_core/admin/page_blocks_helper.rb +0 -66
- data/app/helpers/pages_core/admin/page_json_helper.rb +0 -23
- data/app/javascript/components/DateRangeSelect.jsx +0 -225
- data/app/javascript/components/PageDates.jsx +0 -73
- data/app/javascript/components/PageFiles.jsx +0 -25
- data/app/javascript/components/PageTree/types.ts +0 -15
- data/app/javascript/components/drag/types.ts +0 -28
- data/app/javascript/controllers/EditPageController.ts +0 -22
- data/app/javascript/controllers/MainController.ts +0 -74
- data/app/javascript/controllers/PageOptionsController.js +0 -67
- data/app/models/category.rb +0 -22
- data/app/models/concerns/pages_core/has_otp.rb +0 -27
- data/app/models/page_category.rb +0 -6
- data/app/views/admin/pages/_edit_content.html.erb +0 -19
- data/app/views/admin/pages/_edit_files.html.erb +0 -4
- data/app/views/admin/pages/_edit_images.html.erb +0 -4
- data/app/views/admin/pages/_edit_metadata.html.erb +0 -35
- data/app/views/admin/pages/_edit_options.html.erb +0 -91
- data/lib/rails/generators/pages_core/rspec/templates/mailer_macros.rb +0 -11
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
module Admin
|
4
4
|
class PagesController < Admin::AdminController
|
5
|
-
include PagesCore::
|
5
|
+
include PagesCore::PageParameters
|
6
6
|
|
7
|
-
before_action :find_categories
|
8
7
|
before_action :find_page, only: %i[show edit update destroy move]
|
9
8
|
|
10
9
|
require_authorization
|
@@ -39,26 +38,26 @@ module Admin
|
|
39
38
|
def edit; end
|
40
39
|
|
41
40
|
def create
|
42
|
-
@page = build_page(content_locale, page_params
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
@page = build_page(content_locale, page_params).tap(&:save)
|
42
|
+
|
43
|
+
respond_with_page(@page) do
|
44
|
+
if @page.valid?
|
46
45
|
redirect_to(edit_admin_page_url(content_locale, @page))
|
46
|
+
else
|
47
|
+
render action: :new
|
47
48
|
end
|
48
|
-
else
|
49
|
-
render action: :new
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
53
52
|
def update
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
@page.update(page_params)
|
54
|
+
respond_with_page(@page) do
|
55
|
+
if @page.valid?
|
57
56
|
flash[:notice] = t("pages_core.changes_saved")
|
58
57
|
redirect_to edit_admin_page_url(content_locale, @page)
|
58
|
+
else
|
59
|
+
render action: :edit
|
59
60
|
end
|
60
|
-
else
|
61
|
-
render action: :edit
|
62
61
|
end
|
63
62
|
end
|
64
63
|
|
@@ -75,53 +74,34 @@ module Admin
|
|
75
74
|
|
76
75
|
private
|
77
76
|
|
78
|
-
def build_page(locale, attributes = nil
|
77
|
+
def build_page(locale, attributes = nil)
|
79
78
|
Page.new.localize(locale).tap do |page|
|
80
79
|
page.author = default_author || current_user
|
81
80
|
page.attributes = attributes if attributes
|
82
|
-
page.categories = categories if categories
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
86
84
|
def default_author
|
87
|
-
User.
|
88
|
-
end
|
89
|
-
|
90
|
-
def page_attributes
|
91
|
-
%i[template user_id status feed_enabled published_at redirect_to
|
92
|
-
image_link news_page unique_name pinned parent_page_id serialized_tags
|
93
|
-
meta_image_id starts_at ends_at all_day image_id path_segment
|
94
|
-
meta_title meta_description open_graph_title open_graph_description]
|
85
|
+
User.find_by(email: PagesCore.config.default_author)
|
95
86
|
end
|
96
87
|
|
97
88
|
def page_params
|
98
|
-
params.require(:page).permit(
|
99
|
-
PagesCore::Templates::TemplateConfiguration.all_blocks +
|
100
|
-
page_attributes,
|
101
|
-
page_images_attributes: %i[id position image_id primary _destroy],
|
102
|
-
page_files_attributes: %i[id position attachment_id _destroy]
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
def param_categories
|
107
|
-
return [] unless params[:category]
|
108
|
-
|
109
|
-
params.permit(category: {})[:category].to_hash
|
110
|
-
.map { |id, _| Category.find(id) }
|
89
|
+
params.require(:page).permit(page_content_attributes)
|
111
90
|
end
|
112
91
|
|
113
92
|
def find_page
|
114
93
|
@page = Page.find(params[:id]).localize(content_locale)
|
115
94
|
end
|
116
95
|
|
117
|
-
def find_categories
|
118
|
-
@categories = Category.order("name")
|
119
|
-
end
|
120
|
-
|
121
96
|
def respond_with_page(page, &block)
|
122
97
|
respond_to do |format|
|
123
|
-
format.html
|
124
|
-
format.json
|
98
|
+
format.html(&block)
|
99
|
+
format.json do
|
100
|
+
render json: ::Admin::PageResource.new(
|
101
|
+
page,
|
102
|
+
params: { user: current_user }
|
103
|
+
)
|
104
|
+
end
|
125
105
|
end
|
126
106
|
end
|
127
107
|
end
|
@@ -11,7 +11,7 @@ module PagesCore
|
|
11
11
|
protected
|
12
12
|
|
13
13
|
def configure_sentry_scope
|
14
|
-
return if Rails.env.test? || !Object.const_defined?(
|
14
|
+
return if Rails.env.test? || !Object.const_defined?(:Sentry)
|
15
15
|
|
16
16
|
Sentry.set_context("params", params.to_unsafe_h)
|
17
17
|
Sentry.set_tags(locale: params[:locale] || I18n.default_locale.to_s)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PagesCore
|
4
|
+
module PageParameters
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def page_attachment_attributes
|
8
|
+
{ page_images_attributes: %i[id position image_id primary _destroy],
|
9
|
+
page_files_attributes: %i[id position attachment_id _destroy] }
|
10
|
+
end
|
11
|
+
|
12
|
+
def page_content_attributes
|
13
|
+
locales = PagesCore.config.locales&.keys || [I18n.default_locale]
|
14
|
+
[page_static_attributes,
|
15
|
+
PagesCore::Templates::TemplateConfiguration.all_blocks,
|
16
|
+
:path_segment,
|
17
|
+
(PagesCore::Templates::TemplateConfiguration
|
18
|
+
.localized_blocks + %i[path_segment])
|
19
|
+
.index_with { locales },
|
20
|
+
page_attachment_attributes]
|
21
|
+
end
|
22
|
+
|
23
|
+
def page_static_attributes
|
24
|
+
%i[template user_id status feed_enabled published_at redirect_to
|
25
|
+
news_page unique_name pinned parent_page_id serialized_tags
|
26
|
+
meta_image_id starts_at ends_at all_day]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -3,11 +3,27 @@
|
|
3
3
|
module PagesCore
|
4
4
|
module PreviewPagesController
|
5
5
|
extend ActiveSupport::Concern
|
6
|
+
include PagesCore::PageParameters
|
7
|
+
|
8
|
+
included do
|
9
|
+
before_action :disable_xss_protection, only: %i[preview]
|
10
|
+
end
|
6
11
|
|
7
12
|
def preview?
|
8
13
|
@preview || false
|
9
14
|
end
|
10
15
|
|
16
|
+
def preview
|
17
|
+
render_error 403 unless logged_in?
|
18
|
+
|
19
|
+
@preview = true
|
20
|
+
@page = Page.find_by(id: params[:page_id]) || Page.new
|
21
|
+
@page.readonly!
|
22
|
+
@page.assign_attributes(preview_page_params)
|
23
|
+
|
24
|
+
render_page
|
25
|
+
end
|
26
|
+
|
11
27
|
private
|
12
28
|
|
13
29
|
def disable_xss_protection
|
@@ -17,31 +33,15 @@ module PagesCore
|
|
17
33
|
response.headers["X-XSS-Protection"] = "0"
|
18
34
|
end
|
19
35
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def page_params
|
27
|
-
params.require(:page).permit(
|
28
|
-
Page.localized_attributes + permitted_page_attributes
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def preview_page(page)
|
33
|
-
redirect_to(page_url(content_locale, page)) && return unless logged_in?
|
34
|
-
|
35
|
-
disable_xss_protection
|
36
|
-
|
37
|
-
@preview = true
|
38
|
-
page.attributes = page_params.merge(
|
36
|
+
def preview_page_params
|
37
|
+
ActionController::Parameters.new(
|
38
|
+
JSON.parse(params.require(:preview_page))
|
39
|
+
).permit(:id, page_content_attributes).merge(
|
39
40
|
status: 2,
|
40
41
|
published_at: Time.zone.now,
|
41
42
|
locale: content_locale,
|
42
43
|
redirect_to: nil
|
43
44
|
)
|
44
|
-
render_page
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -12,8 +12,8 @@ module PagesCore
|
|
12
12
|
|
13
13
|
before_action :load_root_pages
|
14
14
|
before_action :find_page_by_path, only: [:show]
|
15
|
-
before_action :find_page, only: %i[show
|
16
|
-
before_action :require_page, only: %i[show
|
15
|
+
before_action :find_page, only: %i[show]
|
16
|
+
before_action :require_page, only: %i[show]
|
17
17
|
before_action :canonicalize_url, only: [:show]
|
18
18
|
static_cache :index, :show
|
19
19
|
|
@@ -27,10 +27,6 @@ module PagesCore
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def preview
|
31
|
-
preview_page(@page)
|
32
|
-
end
|
33
|
-
|
34
30
|
def show
|
35
31
|
respond_to do |format|
|
36
32
|
format.html { render_published_page(@page) }
|
@@ -38,8 +38,7 @@ module PagesCore
|
|
38
38
|
def find_attachments(str)
|
39
39
|
str.match(attachment_expression)[1]
|
40
40
|
.split(",")
|
41
|
-
.
|
42
|
-
.compact
|
41
|
+
.filter_map { |id| find_attachment(id) }
|
43
42
|
end
|
44
43
|
|
45
44
|
def find_file(id)
|
@@ -51,8 +50,7 @@ module PagesCore
|
|
51
50
|
def find_files(str)
|
52
51
|
str.match(file_expression)[1]
|
53
52
|
.split(",")
|
54
|
-
.
|
55
|
-
.compact
|
53
|
+
.filter_map { |id| find_file(id) }
|
56
54
|
end
|
57
55
|
|
58
56
|
def fix_markup(str)
|
@@ -5,12 +5,13 @@ module Admin
|
|
5
5
|
include PagesCore::LocalesHelper
|
6
6
|
|
7
7
|
def header_tabs(group)
|
8
|
+
return unless menu_items_for(group).any?
|
9
|
+
|
8
10
|
tag.ul(class: group.to_s) do
|
9
11
|
safe_join(menu_items_for(group).map do |item|
|
10
12
|
tag.li do
|
11
13
|
path = instance_eval(&item.path)
|
12
|
-
link_to(item.label,
|
13
|
-
path,
|
14
|
+
link_to(item.label, path,
|
14
15
|
class: (current_menu_item?(item) ? "current" : ""))
|
15
16
|
end
|
16
17
|
end)
|
@@ -24,9 +25,9 @@ module Admin
|
|
24
25
|
.select { |_, routing| routing[:controller] == params[:controller] }
|
25
26
|
end
|
26
27
|
|
27
|
-
def find_menu_candidate(&
|
28
|
+
def find_menu_candidate(&)
|
28
29
|
menu_item_candidates
|
29
|
-
.select
|
30
|
+
.select(&)
|
30
31
|
.try(&:first)
|
31
32
|
.try(&:first)
|
32
33
|
end
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
module Admin
|
4
4
|
module PagesHelper
|
5
|
-
include PagesCore::Admin::PageBlocksHelper
|
6
|
-
|
7
5
|
def autopublish_notice(page)
|
8
6
|
return unless page.autopublish?
|
9
7
|
|
@@ -13,22 +11,8 @@ module Admin
|
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
16
|
-
def available_templates_for_select
|
17
|
-
PagesCore::Templates.names.collect do |template|
|
18
|
-
if template == "index"
|
19
|
-
["[Default]", "index"]
|
20
|
-
else
|
21
|
-
[template.humanize, template]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def file_embed_code(file)
|
27
|
-
"[file:#{file.id}]"
|
28
|
-
end
|
29
|
-
|
30
14
|
def news_section_name(page, news_pages)
|
31
|
-
if news_pages.
|
15
|
+
if news_pages.count { |p| p.name == page.name } > 1
|
32
16
|
page_name(page, include_parents: true)
|
33
17
|
else
|
34
18
|
page_name(page)
|
@@ -83,10 +67,6 @@ module Admin
|
|
83
67
|
|
84
68
|
private
|
85
69
|
|
86
|
-
def nested_array?(array)
|
87
|
-
array.present? && array.first.is_a?(Array)
|
88
|
-
end
|
89
|
-
|
90
70
|
def page_name_with_fallback(page)
|
91
71
|
if page.name?
|
92
72
|
page.name.to_s
|
@@ -7,7 +7,6 @@ module PagesCore
|
|
7
7
|
include PagesCore::Admin::DateRangeHelper
|
8
8
|
include PagesCore::Admin::ImageUploadsHelper
|
9
9
|
include PagesCore::Admin::LocalesHelper
|
10
|
-
include PagesCore::Admin::PageJsonHelper
|
11
10
|
include PagesCore::Admin::LabelledFieldHelper
|
12
11
|
include PagesCore::Admin::TagEditorHelper
|
13
12
|
|
@@ -18,12 +17,12 @@ module PagesCore
|
|
18
17
|
value: content))
|
19
18
|
end
|
20
19
|
|
21
|
-
def locale_links
|
20
|
+
def locale_links
|
22
21
|
return unless PagesCore.config.localizations?
|
23
22
|
|
24
23
|
safe_join(
|
25
24
|
PagesCore.config.locales.map do |locale, name|
|
26
|
-
link_to(name,
|
25
|
+
link_to(name, yield(locale),
|
27
26
|
class: ("current" if locale == params[:locale].to_sym))
|
28
27
|
end
|
29
28
|
)
|
@@ -28,7 +28,8 @@ module PagesCore
|
|
28
28
|
# * <tt>:ratio</tt>: Ratio to constrain image by.
|
29
29
|
# * <tt>:size</tt>: Max size for image.
|
30
30
|
def image_figure(image, opts = {})
|
31
|
-
class_name = ["image", image_class_name(image
|
31
|
+
class_name = ["image", image_class_name(image, ratio: opts[:ratio]),
|
32
|
+
opts[:class_name]].compact
|
32
33
|
image_tag = image_figure_image_tag(image,
|
33
34
|
size: opts[:size],
|
34
35
|
ratio: opts[:ratio])
|
@@ -47,7 +48,8 @@ module PagesCore
|
|
47
48
|
# * <tt>:ratio</tt>: Ratio to constrain image by.
|
48
49
|
# * <tt>:sizes</tt>: Sizes attribute for image tag, default: "100vw".
|
49
50
|
def picture(image, opts = {})
|
50
|
-
class_name = ["image", image_class_name(image
|
51
|
+
class_name = ["image", image_class_name(image, ratio: opts[:ratio]),
|
52
|
+
opts[:class_name]].compact
|
51
53
|
pict = picture_tag(image, ratio: opts[:ratio], sizes: opts[:sizes])
|
52
54
|
content = opts[:link] ? image_link_to(pict, opts[:link]) : pict
|
53
55
|
tag.figure(content + image_caption(image, caption: opts[:caption]),
|
@@ -95,9 +97,11 @@ module PagesCore
|
|
95
97
|
Vector2d.new(v.y * ratio, v.y).fit(v)
|
96
98
|
end
|
97
99
|
|
98
|
-
def image_class_name(image)
|
99
|
-
|
100
|
-
|
100
|
+
def image_class_name(image, ratio: nil)
|
101
|
+
size = ratio ? fit_ratio(image.size, ratio) : image.size
|
102
|
+
|
103
|
+
return "square" if size.x == size.y
|
104
|
+
return "landscape" if size.x > size.y
|
101
105
|
|
102
106
|
"portrait"
|
103
107
|
end
|
@@ -120,9 +124,7 @@ module PagesCore
|
|
120
124
|
end
|
121
125
|
|
122
126
|
def image_widths(image)
|
123
|
-
[233, 350, 700, 1050, 1400, 2100, 2800].select
|
124
|
-
image.size.x >= w
|
125
|
-
end
|
127
|
+
[233, 350, 700, 1050, 1400, 2100, 2800].select { |w| image.size.x >= w }
|
126
128
|
end
|
127
129
|
|
128
130
|
def srcset(image, ratio: nil, format: nil)
|
@@ -30,15 +30,10 @@ module PagesCore
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def labelled_country_select(
|
33
|
-
attr, label = nil,
|
33
|
+
attr, label = nil, opts = {}, html_opts = {}
|
34
34
|
)
|
35
|
-
if priority.is_a?(Hash)
|
36
|
-
return labelled_field(attr, label, priority) do |options|
|
37
|
-
country_select(attr, options, opts, html_opts)
|
38
|
-
end
|
39
|
-
end
|
40
35
|
labelled_field(attr, label, opts) do |options|
|
41
|
-
country_select(attr,
|
36
|
+
country_select(attr, options, html_opts)
|
42
37
|
end
|
43
38
|
end
|
44
39
|
|
@@ -1,32 +1,31 @@
|
|
1
|
-
import React from "react";
|
1
|
+
import React, { MouseEvent } from "react";
|
2
2
|
import copyToClipboard from "../../lib/copyToClipboard";
|
3
3
|
import AttachmentEditor from "./AttachmentEditor";
|
4
4
|
import useModalStore from "../../stores/useModalStore";
|
5
5
|
import useToastStore from "../../stores/useToastStore";
|
6
|
-
import
|
6
|
+
import * as Attachments from "../../types/Attachments";
|
7
|
+
import * as Drag from "../../types/Drag";
|
8
|
+
import { Locale } from "../../types";
|
7
9
|
|
8
|
-
import { useDraggable
|
10
|
+
import { useDraggable } from "../drag";
|
9
11
|
|
10
|
-
interface
|
11
|
-
id: number | null;
|
12
|
-
attachment: AttachmentResource;
|
13
|
-
uploading: boolean;
|
14
|
-
}
|
15
|
-
|
16
|
-
interface AttachmentProps {
|
12
|
+
interface Props {
|
17
13
|
attributeName: string;
|
18
14
|
placeholder: boolean;
|
19
|
-
draggable:
|
15
|
+
draggable: Drag.Draggable<Attachments.Record>;
|
20
16
|
locale: string;
|
21
17
|
locales: { [index: string]: Locale };
|
22
18
|
deleteRecord: () => void;
|
23
19
|
showEmbed: boolean;
|
24
20
|
position: number;
|
25
|
-
onUpdate: (
|
26
|
-
startDrag: (
|
21
|
+
onUpdate: (attachment: Partial<Attachments.Resource>) => void;
|
22
|
+
startDrag: (
|
23
|
+
evt: MouseEvent,
|
24
|
+
draggable: Drag.Draggable<Attachments.Record>
|
25
|
+
) => void;
|
27
26
|
}
|
28
27
|
|
29
|
-
export default function Attachment(props:
|
28
|
+
export default function Attachment(props: Props) {
|
30
29
|
const { attributeName, draggable, locales, locale } = props;
|
31
30
|
const { record } = draggable;
|
32
31
|
const { attachment, uploading } = record;
|
@@ -34,15 +33,18 @@ export default function Attachment(props: AttachmentProps) {
|
|
34
33
|
const openModal = useModalStore((state) => state.open);
|
35
34
|
const notice = useToastStore((state) => state.notice);
|
36
35
|
|
37
|
-
const listeners = useDraggable(
|
36
|
+
const listeners = useDraggable<Attachments.Record>(
|
37
|
+
draggable,
|
38
|
+
props.startDrag
|
39
|
+
);
|
38
40
|
|
39
|
-
const copyEmbed = (evt:
|
41
|
+
const copyEmbed = (evt: MouseEvent) => {
|
40
42
|
evt.preventDefault();
|
41
43
|
copyToClipboard(`[attachment:${attachment.id}]`);
|
42
44
|
notice("Embed code copied to clipboard");
|
43
45
|
};
|
44
46
|
|
45
|
-
const deleteRecord = (evt:
|
47
|
+
const deleteRecord = (evt: MouseEvent) => {
|
46
48
|
evt.preventDefault();
|
47
49
|
if (props.deleteRecord) {
|
48
50
|
props.deleteRecord();
|
@@ -63,7 +65,7 @@ export default function Attachment(props: AttachmentProps) {
|
|
63
65
|
return null;
|
64
66
|
};
|
65
67
|
|
66
|
-
const editAttachment = (evt:
|
68
|
+
const editAttachment = (evt: MouseEvent) => {
|
67
69
|
evt.preventDefault();
|
68
70
|
openModal(
|
69
71
|
<AttachmentEditor
|
@@ -1,18 +1,19 @@
|
|
1
|
-
import React, { ChangeEvent, useState } from "react";
|
1
|
+
import React, { ChangeEvent, MouseEvent, useState } from "react";
|
2
2
|
import copyToClipboard, { copySupported } from "../../lib/copyToClipboard";
|
3
3
|
import useModalStore from "../../stores/useModalStore";
|
4
4
|
import useToastStore from "../../stores/useToastStore";
|
5
|
-
import { AttachmentResource, Locale } from "../../types";
|
6
5
|
import { putJson } from "../../lib/request";
|
6
|
+
import * as Attachments from "../../types/Attachments";
|
7
|
+
import { Locale } from "../../types";
|
7
8
|
|
8
|
-
interface
|
9
|
-
attachment:
|
9
|
+
interface Props {
|
10
|
+
attachment: Attachments.Resource;
|
10
11
|
locale: string;
|
11
12
|
locales: { [index: string]: Locale };
|
12
|
-
onUpdate: (
|
13
|
+
onUpdate: (attachment: Partial<Attachments.Resource>) => void;
|
13
14
|
}
|
14
15
|
|
15
|
-
export default function AttachmentEditor(props:
|
16
|
+
export default function AttachmentEditor(props: Props) {
|
16
17
|
const { attachment, locales } = props;
|
17
18
|
|
18
19
|
const [locale, setLocale] = useState(props.locale);
|
@@ -25,20 +26,21 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
|
|
25
26
|
const closeModal = useModalStore((state) => state.close);
|
26
27
|
|
27
28
|
const updateLocalization =
|
28
|
-
(name: "name" | "description") =>
|
29
|
+
(name: "name" | "description") =>
|
30
|
+
(evt: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) => {
|
29
31
|
setLocalizations({
|
30
32
|
...localizations,
|
31
33
|
[name]: { ...localizations[name], [locale]: evt.target.value }
|
32
34
|
});
|
33
35
|
};
|
34
36
|
|
35
|
-
const copyEmbedCode = (evt:
|
37
|
+
const copyEmbedCode = (evt: MouseEvent) => {
|
36
38
|
evt.preventDefault();
|
37
39
|
copyToClipboard(`[attachment:${attachment.id}]`);
|
38
40
|
notice("Embed code copied to clipboard");
|
39
41
|
};
|
40
42
|
|
41
|
-
const save = (evt:
|
43
|
+
const save = (evt: MouseEvent) => {
|
42
44
|
evt.preventDefault();
|
43
45
|
evt.stopPropagation();
|
44
46
|
|