pages_core 3.12.0 → 3.12.2
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/fonts/661557ef.ttf +0 -0
- data/app/assets/builds/fonts/a18fc2d2.woff2 +0 -0
- data/app/assets/builds/fonts/b2c7b78f.woff2 +0 -0
- data/app/assets/builds/fonts/ceddc204.ttf +0 -0
- data/app/assets/builds/pages_core/admin-dist.js +60 -14
- data/app/assets/builds/pages_core/admin-dist.js.map +7 -0
- data/app/assets/builds/pages_core/admin.css +9272 -0
- data/app/assets/images/pages/admin/angle-down-solid.svg +1 -0
- data/app/assets/images/pages/admin/icon.svg +1 -0
- data/app/assets/stylesheets/pages_core/admin/components/archive.css +6 -0
- data/app/assets/stylesheets/{pages/admin/components/attachments.scss → pages_core/admin/components/attachments.css} +35 -28
- data/app/assets/stylesheets/{pages/admin.scss → pages_core/admin/components/base.css} +125 -123
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +223 -0
- data/app/assets/stylesheets/{pages/admin/components/header.scss → pages_core/admin/components/header.css} +76 -46
- data/app/assets/stylesheets/{pages/admin/components/image_editor.scss → pages_core/admin/components/image_editor.css} +42 -31
- data/app/assets/stylesheets/{pages/admin/components/image_grid.scss → pages_core/admin/components/image_grid.css} +76 -64
- data/app/assets/stylesheets/{pages/admin/components/image_uploader.scss → pages_core/admin/components/image_uploader.css} +12 -12
- data/app/assets/stylesheets/{pages/admin/components/layout.scss → pages_core/admin/components/layout.css} +13 -9
- data/app/assets/stylesheets/pages_core/admin/components/links.css +40 -0
- data/app/assets/stylesheets/pages_core/admin/components/list_table.css +66 -0
- data/app/assets/stylesheets/{pages/admin/components/login.scss → pages_core/admin/components/login.css} +6 -5
- data/app/assets/stylesheets/{pages/admin/components/modal.scss → pages_core/admin/components/modal.css} +10 -12
- data/app/assets/stylesheets/{pages/admin/components/page_tree.scss → pages_core/admin/components/page_tree.css} +54 -55
- data/app/assets/stylesheets/{pages/admin/components/pagination.scss → pages_core/admin/components/pagination.css} +17 -17
- data/app/assets/stylesheets/pages_core/admin/components/search.css +27 -0
- data/app/assets/stylesheets/{pages/admin/components/sidebar.scss → pages_core/admin/components/sidebar.css} +8 -7
- data/app/assets/stylesheets/{pages/admin/components/tag_editor.scss → pages_core/admin/components/tag_editor.css} +10 -15
- data/app/assets/stylesheets/{pages/admin/components/textarea.scss → pages_core/admin/components/textarea.css} +1 -1
- data/app/assets/stylesheets/{pages/admin/components/toast.scss → pages_core/admin/components/toast.css} +5 -3
- data/app/assets/stylesheets/{pages/admin/components/toolbar.scss → pages_core/admin/components/toolbar.css} +56 -29
- data/app/assets/stylesheets/{pages/admin/controllers/pages.scss → pages_core/admin/controllers/pages.css} +69 -52
- data/app/assets/stylesheets/pages_core/admin/controllers/users.css +3 -0
- data/app/assets/stylesheets/pages_core/admin/vars.css +34 -0
- data/app/assets/stylesheets/pages_core/admin.postcss.css +9 -0
- data/app/controllers/admin/pages_controller.rb +12 -11
- data/app/controllers/concerns/pages_core/rss_controller.rb +17 -1
- data/app/controllers/pages_core/admin_controller.rb +6 -0
- data/app/controllers/pages_core/frontend/pages_controller.rb +9 -5
- data/app/controllers/pages_core/sitemaps_controller.rb +3 -5
- data/app/formatters/pages_core/image_embedder.rb +5 -27
- data/app/helpers/admin/calendars_helper.rb +8 -0
- data/app/helpers/admin/news_helper.rb +13 -0
- data/app/helpers/admin/pages_helper.rb +32 -0
- data/app/helpers/pages_core/admin/admin_helper.rb +11 -54
- data/app/helpers/pages_core/admin/deprecated_admin_helper.rb +40 -0
- data/app/helpers/pages_core/images_helper.rb +37 -0
- data/app/javascript/admin-dist.ts +2 -0
- data/app/javascript/components/Attachments/{Attachment.jsx → Attachment.tsx} +44 -35
- data/app/javascript/components/Attachments/{AttachmentEditor.jsx → AttachmentEditor.tsx} +23 -23
- data/app/javascript/components/{EditableImage.jsx → EditableImage.tsx} +28 -25
- data/app/javascript/components/{FileUploadButton.jsx → FileUploadButton.tsx} +15 -16
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +94 -0
- data/app/javascript/components/ImageCropper/{Image.jsx → Image.tsx} +13 -14
- data/app/javascript/components/ImageCropper/{Toolbar.jsx → Toolbar.tsx} +19 -15
- data/app/javascript/components/ImageCropper/{useCrop.js → useCrop.ts} +80 -37
- data/app/javascript/components/{ImageCropper.jsx → ImageCropper.tsx} +17 -15
- data/app/javascript/components/ImageEditor/{Form.jsx → Form.tsx} +24 -23
- data/app/javascript/components/{ImageEditor.jsx → ImageEditor.tsx} +17 -15
- data/app/javascript/components/ImageGrid/{DragElement.jsx → DragElement.tsx} +12 -10
- data/app/javascript/components/ImageGrid/{GridImage.jsx → GridImage.tsx} +40 -30
- data/app/javascript/components/ImageGrid/{Placeholder.jsx → Placeholder.tsx} +5 -6
- data/app/javascript/components/ImageGrid.jsx +3 -4
- data/app/javascript/components/{ImageUploader.jsx → ImageUploader.tsx} +46 -41
- data/app/javascript/components/Modal.tsx +48 -0
- data/app/javascript/components/PageImages.tsx +28 -0
- data/app/javascript/components/{PageTreeDraggable.jsx → PageTree/Draggable.tsx} +79 -57
- data/app/javascript/components/{PageTreeNode.jsx → PageTree/Node.tsx} +86 -77
- data/app/javascript/components/PageTree/types.ts +15 -0
- data/app/javascript/components/PageTree.tsx +206 -0
- data/app/javascript/components/RichTextToolbarButton.tsx +17 -0
- data/app/javascript/components/TagEditor/{AddTagForm.jsx → AddTagForm.tsx} +9 -10
- data/app/javascript/components/TagEditor/{Tag.jsx → Tag.tsx} +8 -9
- data/app/javascript/components/{TagEditor.jsx → TagEditor.tsx} +12 -13
- data/app/javascript/components/Toast.tsx +61 -0
- data/app/javascript/components/drag/{draggedOrder.js → draggedOrder.ts} +22 -12
- data/app/javascript/components/drag/types.ts +28 -0
- data/app/javascript/components/drag/{useDragCollection.js → useDragCollection.ts} +40 -22
- data/app/javascript/components/drag/{useDragUploader.js → useDragUploader.ts} +34 -25
- data/app/javascript/components/drag/useDraggable.ts +21 -0
- data/app/javascript/components/{drag.js → drag.ts} +1 -0
- data/app/javascript/controllers/{EditPageController.js → EditPageController.ts} +3 -1
- data/app/javascript/controllers/{LoginController.js → LoginController.ts} +7 -3
- data/app/javascript/controllers/{MainController.js → MainController.ts} +19 -14
- data/app/javascript/{index.js → index.ts} +8 -7
- data/app/javascript/lib/{Tree.js → Tree.ts} +106 -85
- data/app/javascript/lib/{copyToClipboard.js → copyToClipboard.ts} +1 -1
- data/app/javascript/lib/{readyHandler.js → readyHandler.ts} +4 -2
- data/app/javascript/lib/{request.js → request.ts} +11 -5
- data/app/javascript/stores/useModalStore.ts +15 -0
- data/app/javascript/stores/useToastStore.ts +26 -0
- data/app/javascript/stores.ts +2 -0
- data/app/javascript/types.ts +30 -0
- data/app/mailers/admin_mailer.rb +1 -0
- data/app/models/invite.rb +8 -0
- data/app/policies/page_policy.rb +4 -0
- data/app/views/admin/calendars/_sidebar.html.erb +50 -0
- data/app/views/admin/calendars/show.html.erb +15 -53
- data/app/views/admin/invites/new.html.erb +2 -8
- data/app/views/admin/invites/show.html.erb +2 -4
- data/app/views/admin/news/_sidebar.html.erb +51 -0
- data/app/views/admin/news/index.html.erb +21 -56
- data/app/views/admin/pages/_list_item.html.erb +4 -22
- data/app/views/admin/pages/_search_bar.html.erb +12 -0
- data/app/views/admin/pages/deleted.html.erb +10 -8
- data/app/views/admin/pages/edit.html.erb +20 -11
- data/app/views/admin/pages/index.html.erb +10 -8
- data/app/views/admin/pages/new.html.erb +10 -14
- data/app/views/admin/pages/search.html.erb +54 -0
- data/app/views/admin/password_resets/show.html.erb +3 -5
- data/app/views/admin/users/deactivated.html.erb +6 -7
- data/app/views/admin/users/edit.html.erb +7 -9
- data/app/views/admin/users/index.html.erb +3 -6
- data/app/views/admin/users/login.html.erb +4 -5
- data/app/views/admin/users/new.html.erb +2 -4
- data/app/views/admin/users/new_password.html.erb +4 -5
- data/app/views/admin/users/show.html.erb +11 -9
- data/app/views/errors/401.html.erb +2 -1
- data/app/views/errors/403.html.erb +2 -1
- data/app/views/errors/404.html.erb +1 -3
- data/app/views/errors/405.html.erb +2 -1
- data/app/views/errors/422.html.erb +2 -1
- data/app/views/errors/500.html.erb +2 -3
- data/app/views/feeds/pages.rss.builder +3 -9
- data/app/views/layouts/admin/_header.html.erb +1 -2
- data/app/views/layouts/admin/_page_header.html.erb +4 -4
- data/app/views/layouts/admin.html.erb +3 -3
- data/app/views/layouts/errors.html.erb +127 -4
- data/config/routes.rb +1 -0
- data/lib/pages_core/configuration/pages.rb +0 -1
- data/lib/pages_core/engine.rb +4 -3
- data/lib/pages_core.rb +0 -1
- data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +33 -17
- data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +0 -1
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +40 -0
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +68 -0
- data/lib/rails/generators/pages_core/frontend/templates/postcss.config.js +17 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.postcss.css +4 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.css +24 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/layout.css +21 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.css +5 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/animation.css +5 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.css +18 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/fonts.css +6 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/grid.css +65 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.css +131 -0
- data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +0 -3
- metadata +104 -255
- data/app/assets/images/pages/admin/icon.png +0 -0
- data/app/assets/images/pages/admin/image-editor-bg.png +0 -0
- data/app/assets/images/pages/admin/list-table-pin-blue.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-disabled.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-green.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-red.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-yellow.gif +0 -0
- data/app/assets/images/pages/admin/loading-modal.gif +0 -0
- data/app/assets/images/pages/feed-icon-14x14.png +0 -0
- data/app/assets/stylesheets/pages/admin/components/archive.scss +0 -6
- data/app/assets/stylesheets/pages/admin/components/buttons.scss +0 -23
- data/app/assets/stylesheets/pages/admin/components/forms.scss +0 -169
- data/app/assets/stylesheets/pages/admin/components/links.scss +0 -43
- data/app/assets/stylesheets/pages/admin/components/list_table.scss +0 -61
- data/app/assets/stylesheets/pages/admin/controllers/users.scss +0 -3
- data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +0 -21
- data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +0 -7
- data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +0 -7
- data/app/assets/stylesheets/pages/admin/vars.scss +0 -30
- data/app/assets/stylesheets/pages/errors.css +0 -128
- data/app/javascript/admin-dist.js +0 -2
- data/app/javascript/components/ImageCropper/FocalPoint.jsx +0 -93
- data/app/javascript/components/Modal.jsx +0 -59
- data/app/javascript/components/PageImages.jsx +0 -25
- data/app/javascript/components/PageTree.jsx +0 -196
- data/app/javascript/components/RichTextToolbarButton.jsx +0 -20
- data/app/javascript/components/Toast.jsx +0 -72
- data/app/javascript/components/drag/useDraggable.js +0 -17
- data/app/javascript/stores/ModalStore.jsx +0 -12
- data/app/javascript/stores/ToastStore.jsx +0 -14
- data/app/javascript/stores.js +0 -2
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/GridOverlay.js +0 -66
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/ResponsiveEmbeds.js +0 -72
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.sass.scss +0 -15
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.scss +0 -12
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.scss +0 -26
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/breakpoints.scss +0 -42
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/clearfix.scss +0 -7
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/fonts.scss +0 -32
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid.scss +0 -168
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid_overlay.scss +0 -44
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.scss +0 -8
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.scss +0 -90
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/vendor/normalize.css +0 -349
- data/vendor/assets/stylesheets/ReactCrop.css +0 -167
- /data/app/assets/stylesheets/{pages/admin/components/tabs.scss → pages_core/admin/components/tabs.css} +0 -0
- /data/app/javascript/components/Attachments/{Placeholder.jsx → Placeholder.tsx} +0 -0
- /data/app/javascript/components/ImageGrid/{FilePlaceholder.jsx → FilePlaceholder.tsx} +0 -0
- /data/app/javascript/{components.js → components.ts} +0 -0
- /data/app/javascript/{hooks.js → hooks.ts} +0 -0
|
@@ -20,7 +20,10 @@ module PagesCore
|
|
|
20
20
|
def index
|
|
21
21
|
respond_to do |format|
|
|
22
22
|
format.html { render_published_page(root_pages.try(&:first)) }
|
|
23
|
-
format.rss
|
|
23
|
+
format.rss do
|
|
24
|
+
render_rss(all_feed_items.paginate(per_page: per_page_rss_param,
|
|
25
|
+
page: page_param))
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
26
29
|
|
|
@@ -28,10 +31,7 @@ module PagesCore
|
|
|
28
31
|
respond_to do |format|
|
|
29
32
|
format.html { render_published_page(@page) }
|
|
30
33
|
format.json { render json: PageResource.new(@page) }
|
|
31
|
-
format.rss
|
|
32
|
-
render_rss(@page.pages.limit(20).includes(:image, :author),
|
|
33
|
-
title: @page.name)
|
|
34
|
-
end
|
|
34
|
+
format.rss { render_page_rss(@page, page_param) }
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -64,6 +64,10 @@ module PagesCore
|
|
|
64
64
|
super
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
def page_param
|
|
68
|
+
params[:page].is_a?(String) ? params[:page] : 1
|
|
69
|
+
end
|
|
70
|
+
|
|
67
71
|
def page_template(page)
|
|
68
72
|
if PagesCore::Templates.names.include?(page.template)
|
|
69
73
|
page.template
|
|
@@ -20,10 +20,8 @@ module PagesCore
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def format_record(record)
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
lastmod: format_time(record.updated_at)
|
|
26
|
-
}
|
|
23
|
+
{ loc: record_url(record),
|
|
24
|
+
lastmod: format_time(record.updated_at) }
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
def formatted_entries
|
|
@@ -46,7 +44,7 @@ module PagesCore
|
|
|
46
44
|
([Page.root.try(:localize, I18n.default_locale)] +
|
|
47
45
|
locales.flat_map do |locale|
|
|
48
46
|
Page.published.localized(locale).includes(:parent)
|
|
49
|
-
end).compact
|
|
47
|
+
end).compact
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def page_record_url(record)
|
|
@@ -21,12 +21,10 @@ module PagesCore
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def embed_image(id, size:, class_name:, link:)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
tag.figure((link ? link_to(image_tag, link) : image_tag) +
|
|
29
|
-
image_caption(image), class: class_name)
|
|
24
|
+
image_figure(
|
|
25
|
+
Image.find(id).localize(I18n.locale),
|
|
26
|
+
size: size, class_name: class_name, link: link
|
|
27
|
+
)
|
|
30
28
|
rescue ActiveRecord::RecordNotFound
|
|
31
29
|
nil
|
|
32
30
|
end
|
|
@@ -35,30 +33,10 @@ module PagesCore
|
|
|
35
33
|
if str =~ /size="(\d*x\d*)"/
|
|
36
34
|
Regexp.last_match(1)
|
|
37
35
|
else
|
|
38
|
-
|
|
36
|
+
default_image_size
|
|
39
37
|
end
|
|
40
38
|
end
|
|
41
39
|
|
|
42
|
-
def image_caption(image)
|
|
43
|
-
return unless image.caption?
|
|
44
|
-
|
|
45
|
-
tag.figcaption(image.caption)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def image_class_name(image)
|
|
49
|
-
if image.size.x == image.size.y
|
|
50
|
-
"square"
|
|
51
|
-
elsif image.size.x > image.size.y
|
|
52
|
-
"landscape"
|
|
53
|
-
else
|
|
54
|
-
"portrait"
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def link_to(content, href)
|
|
59
|
-
tag.a(content, href: href)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
40
|
def parse_image(str)
|
|
63
41
|
id = str.match(image_expression)[1]
|
|
64
42
|
options = str.match(image_expression)[2]
|
|
@@ -8,6 +8,14 @@ module Admin
|
|
|
8
8
|
).in_locale(locale)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def calendar_page_options(locale)
|
|
12
|
+
options_for_select(
|
|
13
|
+
calendar_pages(locale).map do |p|
|
|
14
|
+
[page_name(p, include_parents: true).gsub("»", "»"), p.id]
|
|
15
|
+
end
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
11
19
|
def calendar_years_with_count
|
|
12
20
|
calendar_counts.each_with_object({}) do |entry, obj|
|
|
13
21
|
obj[entry[:year]] ||= 0
|
|
@@ -4,6 +4,15 @@ module Admin
|
|
|
4
4
|
module PagesHelper
|
|
5
5
|
include PagesCore::Admin::PageBlocksHelper
|
|
6
6
|
|
|
7
|
+
def autopublish_notice(page)
|
|
8
|
+
return unless page.autopublish?
|
|
9
|
+
|
|
10
|
+
tag.div(class: "autopublish-notice") do
|
|
11
|
+
safe_join(["This page will be published",
|
|
12
|
+
tag.b(publish_time(page.published_at))], " ")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
7
16
|
def available_templates_for_select
|
|
8
17
|
PagesCore::Templates.names.collect do |template|
|
|
9
18
|
if template == "index"
|
|
@@ -30,6 +39,14 @@ module Admin
|
|
|
30
39
|
([page.author] + User.activated).uniq
|
|
31
40
|
end
|
|
32
41
|
|
|
42
|
+
def page_list_row(page, &block)
|
|
43
|
+
classes = [page.status_label.downcase]
|
|
44
|
+
classes << "autopublish" if page.autopublish?
|
|
45
|
+
classes << "pinned" if page.pinned?
|
|
46
|
+
|
|
47
|
+
tag.tr(capture(&block), class: classes.join(" "))
|
|
48
|
+
end
|
|
49
|
+
|
|
33
50
|
def page_name(page, options = {})
|
|
34
51
|
page_names = if options[:include_parents]
|
|
35
52
|
page.self_and_ancestors.reverse
|
|
@@ -42,6 +59,21 @@ module Admin
|
|
|
42
59
|
)
|
|
43
60
|
end
|
|
44
61
|
|
|
62
|
+
def page_published_status(page)
|
|
63
|
+
return page_published_date(page) if page.published?
|
|
64
|
+
return tag.em("Not published") if page.status_label == "Published"
|
|
65
|
+
|
|
66
|
+
tag.em(page.status_label)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def page_published_date(page)
|
|
70
|
+
if page.published_at.year == Time.zone.now.year
|
|
71
|
+
l(page.published_at, format: :pages_date)
|
|
72
|
+
else
|
|
73
|
+
l(page.published_at, format: :pages_full)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
45
77
|
def publish_time(time)
|
|
46
78
|
if time.year != Time.zone.now.year
|
|
47
79
|
time.strftime("on %b %d %Y at %H:%M")
|
|
@@ -4,6 +4,7 @@ module PagesCore
|
|
|
4
4
|
module Admin
|
|
5
5
|
module AdminHelper
|
|
6
6
|
include PagesCore::Admin::ContentTabsHelper
|
|
7
|
+
include PagesCore::Admin::DeprecatedAdminHelper
|
|
7
8
|
include PagesCore::Admin::DateRangeHelper
|
|
8
9
|
include PagesCore::Admin::ImageUploadsHelper
|
|
9
10
|
include PagesCore::Admin::LocalesHelper
|
|
@@ -11,20 +12,6 @@ module PagesCore
|
|
|
11
12
|
include PagesCore::Admin::LabelledFieldHelper
|
|
12
13
|
include PagesCore::Admin::TagEditorHelper
|
|
13
14
|
|
|
14
|
-
attr_writer :page_title, :page_description, :page_description_class,
|
|
15
|
-
:page_description_links
|
|
16
|
-
|
|
17
|
-
def add_body_class(class_name)
|
|
18
|
-
@body_classes ||= []
|
|
19
|
-
@body_classes << class_name
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def body_classes
|
|
23
|
-
classes = @body_classes || []
|
|
24
|
-
classes << "with_notice" if flash[:notice]
|
|
25
|
-
classes
|
|
26
|
-
end
|
|
27
|
-
|
|
28
15
|
def rich_text_area_tag(name, content = nil, options = {})
|
|
29
16
|
react_component("RichTextArea",
|
|
30
17
|
options.merge(id: sanitize_to_id(name),
|
|
@@ -32,50 +19,20 @@ module PagesCore
|
|
|
32
19
|
value: content))
|
|
33
20
|
end
|
|
34
21
|
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def deprecate_page_description_args(string = nil, class_name = nil)
|
|
40
|
-
if class_name
|
|
41
|
-
ActiveSupport::Deprecation.warn("Setting class through " \
|
|
42
|
-
"page_description is deprecated, " \
|
|
43
|
-
"use page_description_class=")
|
|
44
|
-
end
|
|
45
|
-
return unless string
|
|
22
|
+
def locale_links(&block)
|
|
23
|
+
return unless PagesCore.config.localizations?
|
|
46
24
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def page_description(string = nil, class_name = nil)
|
|
53
|
-
deprecate_page_description_args(string, class_name)
|
|
54
|
-
@page_description_class = class_name if class_name
|
|
55
|
-
if string
|
|
56
|
-
@page_description = string
|
|
57
|
-
else
|
|
58
|
-
@page_description
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def page_description_links(links = nil)
|
|
63
|
-
return @page_description_links unless links
|
|
64
|
-
|
|
65
|
-
ActiveSupport::Deprecation.warn(
|
|
66
|
-
"Setting page description_links with page_description_links " \
|
|
67
|
-
"is deprecated, use page_description_links="
|
|
25
|
+
safe_join(
|
|
26
|
+
PagesCore.config.locales.map do |locale, name|
|
|
27
|
+
link_to(name, block.call(locale),
|
|
28
|
+
class: ("current" if locale == params[:locale].to_sym))
|
|
29
|
+
end
|
|
68
30
|
)
|
|
69
|
-
@page_description_links = links
|
|
70
31
|
end
|
|
71
32
|
|
|
72
|
-
def
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ActiveSupport::Deprecation.warn(
|
|
76
|
-
"Setting page title with page_title is deprecated, use page_title="
|
|
77
|
-
)
|
|
78
|
-
@page_title = title
|
|
33
|
+
def month_name(month)
|
|
34
|
+
%w[January February March April May June July August September October
|
|
35
|
+
November December][month - 1]
|
|
79
36
|
end
|
|
80
37
|
end
|
|
81
38
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PagesCore
|
|
4
|
+
module Admin
|
|
5
|
+
module DeprecatedAdminHelper
|
|
6
|
+
def link_separator
|
|
7
|
+
ActiveSupport::Deprecation.warn("link_separator is deprecated")
|
|
8
|
+
|
|
9
|
+
safe_join [" ", tag.span("|", class: "separator"), " "]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def page_description=(description)
|
|
13
|
+
ActiveSupport::Deprecation.warn(content_helper_deprecation)
|
|
14
|
+
content_for(:page_description, description.html_safe)
|
|
15
|
+
end
|
|
16
|
+
alias page_description page_description=
|
|
17
|
+
|
|
18
|
+
def page_description_links=(links)
|
|
19
|
+
ActiveSupport::Deprecation.warn(content_helper_deprecation)
|
|
20
|
+
content_for(:page_description_links, links.html_safe)
|
|
21
|
+
end
|
|
22
|
+
alias page_description_links page_description_links=
|
|
23
|
+
|
|
24
|
+
def page_title=(title)
|
|
25
|
+
ActiveSupport::Deprecation.warn(content_helper_deprecation)
|
|
26
|
+
content_for(:page_title, title)
|
|
27
|
+
end
|
|
28
|
+
alias page_title page_title=
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def content_helper_deprecation
|
|
33
|
+
name = caller_locations(1, 1)[0].label
|
|
34
|
+
replacement = name.gsub(/=$/, "")
|
|
35
|
+
|
|
36
|
+
"The #{name} helper is deprecated, use content_for(:#{replacement})"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -11,6 +11,25 @@ module PagesCore
|
|
|
11
11
|
)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def image_caption(image, caption: nil)
|
|
15
|
+
return if caption == false
|
|
16
|
+
|
|
17
|
+
caption = image.caption unless caption.is_a?(String)
|
|
18
|
+
return if caption.blank?
|
|
19
|
+
|
|
20
|
+
tag.figcaption(caption)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def image_figure(image, size: nil, class_name: nil, link: nil, caption: nil)
|
|
24
|
+
class_name = ["image", image_class_name(image), class_name].compact
|
|
25
|
+
size ||= default_image_size
|
|
26
|
+
image_tag = dynamic_image_tag(image,
|
|
27
|
+
size: size, crop: false, upscale: false)
|
|
28
|
+
tag.figure((link ? image_link_to(image_tag, link) : image_tag) +
|
|
29
|
+
image_caption(image, caption: caption),
|
|
30
|
+
class: class_name)
|
|
31
|
+
end
|
|
32
|
+
|
|
14
33
|
def original_dynamic_image_tag(record_or_array, options = {})
|
|
15
34
|
super(
|
|
16
35
|
record_or_array,
|
|
@@ -27,11 +46,29 @@ module PagesCore
|
|
|
27
46
|
|
|
28
47
|
private
|
|
29
48
|
|
|
49
|
+
def default_image_size
|
|
50
|
+
"2000x2000"
|
|
51
|
+
end
|
|
52
|
+
|
|
30
53
|
def extract_alt_text(record_or_array)
|
|
31
54
|
record = extract_dynamic_image_record(record_or_array)
|
|
32
55
|
return {} unless record.alternative?
|
|
33
56
|
|
|
34
57
|
{ alt: record.alternative }
|
|
35
58
|
end
|
|
59
|
+
|
|
60
|
+
def image_class_name(image)
|
|
61
|
+
if image.size.x == image.size.y
|
|
62
|
+
"square"
|
|
63
|
+
elsif image.size.x > image.size.y
|
|
64
|
+
"landscape"
|
|
65
|
+
else
|
|
66
|
+
"portrait"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def image_link_to(content, href)
|
|
71
|
+
tag.a(content, href: href)
|
|
72
|
+
end
|
|
36
73
|
end
|
|
37
74
|
end
|
|
@@ -1,28 +1,48 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
2
|
import copyToClipboard from "../../lib/copyToClipboard";
|
|
4
3
|
import AttachmentEditor from "./AttachmentEditor";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
4
|
+
import useModalStore from "../../stores/useModalStore";
|
|
5
|
+
import useToastStore from "../../stores/useToastStore";
|
|
6
|
+
import { AttachmentResource, Locale } from "../../types";
|
|
7
7
|
|
|
8
|
-
import { useDraggable } from "../drag";
|
|
8
|
+
import { useDraggable, Draggable } from "../drag";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface Record {
|
|
11
|
+
id: number | null,
|
|
12
|
+
attachment: AttachmentResource,
|
|
13
|
+
uploading: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface AttachmentProps {
|
|
17
|
+
attributeName: string,
|
|
18
|
+
placeholder: boolean,
|
|
19
|
+
draggable: { record: Record },
|
|
20
|
+
locale: string,
|
|
21
|
+
locales: { [index: string]: Locale },
|
|
22
|
+
deleteRecord: () => void,
|
|
23
|
+
showEmbed: boolean,
|
|
24
|
+
position: number,
|
|
25
|
+
onUpdate: (localizations: Record<string, Record<string, string>>) => void,
|
|
26
|
+
startDrag: (evt: Event, draggable: Draggable) => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default function Attachment(props: AttachmentProps) {
|
|
11
30
|
const { attributeName, draggable, locales, locale } = props;
|
|
12
31
|
const { record } = draggable;
|
|
13
32
|
const { attachment, uploading } = record;
|
|
14
33
|
|
|
34
|
+
const openModal = useModalStore((state) => state.open);
|
|
35
|
+
const notice = useToastStore((state) => state.notice);
|
|
36
|
+
|
|
15
37
|
const listeners = useDraggable(draggable, props.startDrag);
|
|
16
38
|
|
|
17
|
-
const copyEmbed = (evt) => {
|
|
39
|
+
const copyEmbed = (evt: Event) => {
|
|
18
40
|
evt.preventDefault();
|
|
19
41
|
copyToClipboard(`[attachment:${attachment.id}]`);
|
|
20
|
-
|
|
21
|
-
type: "NOTICE", message: "Embed code copied to clipboard"
|
|
22
|
-
});
|
|
42
|
+
notice("Embed code copied to clipboard");
|
|
23
43
|
};
|
|
24
44
|
|
|
25
|
-
const deleteRecord = (evt) => {
|
|
45
|
+
const deleteRecord = (evt: Event) => {
|
|
26
46
|
evt.preventDefault();
|
|
27
47
|
if (props.deleteRecord) {
|
|
28
48
|
props.deleteRecord();
|
|
@@ -43,15 +63,15 @@ export default function Attachment(props) {
|
|
|
43
63
|
return null;
|
|
44
64
|
};
|
|
45
65
|
|
|
46
|
-
const editAttachment = (evt) => {
|
|
66
|
+
const editAttachment = (evt: Event) => {
|
|
47
67
|
evt.preventDefault();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
openModal(
|
|
69
|
+
<AttachmentEditor
|
|
70
|
+
attachment={attachment}
|
|
71
|
+
locale={locale}
|
|
72
|
+
locales={locales}
|
|
73
|
+
onUpdate={props.onUpdate} />
|
|
74
|
+
);
|
|
55
75
|
};
|
|
56
76
|
|
|
57
77
|
const classes = ["attachment"];
|
|
@@ -62,9 +82,12 @@ export default function Attachment(props) {
|
|
|
62
82
|
classes.push("uploading");
|
|
63
83
|
}
|
|
64
84
|
|
|
65
|
-
const icon = uploading ? "cloud-
|
|
85
|
+
const icon = uploading ? "cloud-arrow-up" : "paperclip";
|
|
66
86
|
|
|
67
|
-
|
|
87
|
+
let localeDir = "ltr";
|
|
88
|
+
if (locale in locales && locales[locale].dir) {
|
|
89
|
+
localeDir = locales[locale].dir;
|
|
90
|
+
}
|
|
68
91
|
|
|
69
92
|
return (
|
|
70
93
|
<div className={classes.join(" ")}
|
|
@@ -95,7 +118,7 @@ export default function Attachment(props) {
|
|
|
95
118
|
{attachment &&
|
|
96
119
|
<div className="attachment-info">
|
|
97
120
|
<h3>
|
|
98
|
-
<i className={`fa fa-${icon} icon`} />
|
|
121
|
+
<i className={`fa-solid fa-${icon} icon`} />
|
|
99
122
|
{name() || <em>Untitled</em>}<br />
|
|
100
123
|
</h3>
|
|
101
124
|
{!uploading &&
|
|
@@ -108,17 +131,3 @@ export default function Attachment(props) {
|
|
|
108
131
|
</div>
|
|
109
132
|
);
|
|
110
133
|
}
|
|
111
|
-
|
|
112
|
-
Attachment.propTypes = {
|
|
113
|
-
locale: PropTypes.string,
|
|
114
|
-
locales: PropTypes.object,
|
|
115
|
-
draggable: PropTypes.object,
|
|
116
|
-
deleteRecord: PropTypes.func,
|
|
117
|
-
startDrag: PropTypes.func,
|
|
118
|
-
showEmbed: PropTypes.bool,
|
|
119
|
-
onUpdate: PropTypes.func,
|
|
120
|
-
attributeName: PropTypes.string,
|
|
121
|
-
placeholder: PropTypes.bool,
|
|
122
|
-
position: PropTypes.number,
|
|
123
|
-
ref: PropTypes.object
|
|
124
|
-
};
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
1
|
+
import React, { ChangeEvent, useState } from "react";
|
|
3
2
|
import copyToClipboard, { copySupported } from "../../lib/copyToClipboard";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import useModalStore from "../../stores/useModalStore";
|
|
4
|
+
import useToastStore from "../../stores/useToastStore";
|
|
5
|
+
import { AttachmentResource, Locale } from "../../types";
|
|
6
6
|
import { putJson } from "../../lib/request";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface AttachmentEditorProps {
|
|
9
|
+
attachment: AttachmentResource,
|
|
10
|
+
locale: string,
|
|
11
|
+
locales: { [index: string]: Locale },
|
|
12
|
+
onUpdate: (localizations: Record<string, Record<string, string>>) => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function AttachmentEditor(props: AttachmentEditorProps) {
|
|
9
16
|
const { attachment, locales } = props;
|
|
10
17
|
|
|
11
18
|
const [locale, setLocale] = useState(props.locale);
|
|
@@ -14,7 +21,10 @@ export default function AttachmentEditor(props) {
|
|
|
14
21
|
description: attachment.description || {},
|
|
15
22
|
});
|
|
16
23
|
|
|
17
|
-
const
|
|
24
|
+
const notice = useToastStore((state) => state.notice);
|
|
25
|
+
const closeModal = useModalStore((state) => state.close);
|
|
26
|
+
|
|
27
|
+
const updateLocalization = (name: "name" | "description") => (evt: ChangeEvent<HTMLInputElement>) => {
|
|
18
28
|
setLocalizations({
|
|
19
29
|
...localizations,
|
|
20
30
|
[name]: { ...localizations[name],
|
|
@@ -22,27 +32,24 @@ export default function AttachmentEditor(props) {
|
|
|
22
32
|
});
|
|
23
33
|
};
|
|
24
34
|
|
|
25
|
-
const copyEmbedCode = (evt) => {
|
|
35
|
+
const copyEmbedCode = (evt: Event) => {
|
|
26
36
|
evt.preventDefault();
|
|
27
37
|
copyToClipboard(`[attachment:${attachment.id}]`);
|
|
28
|
-
|
|
29
|
-
type: "NOTICE", message: "Embed code copied to clipboard"
|
|
30
|
-
});
|
|
38
|
+
notice("Embed code copied to clipboard");
|
|
31
39
|
};
|
|
32
40
|
|
|
33
|
-
const save = (evt) => {
|
|
41
|
+
const save = (evt: Event) => {
|
|
34
42
|
evt.preventDefault();
|
|
35
43
|
evt.stopPropagation();
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
const data = { ...localizations };
|
|
38
46
|
|
|
39
|
-
putJson(`/admin/attachments/${attachment.id}`,
|
|
40
|
-
{ attachment: data });
|
|
47
|
+
void putJson(`/admin/attachments/${attachment.id}`, { attachment: data });
|
|
41
48
|
|
|
42
49
|
if (props.onUpdate) {
|
|
43
50
|
props.onUpdate(data);
|
|
44
51
|
}
|
|
45
|
-
|
|
52
|
+
closeModal();
|
|
46
53
|
};
|
|
47
54
|
|
|
48
55
|
const inputDir = (locales && locales[locale] && locales[locale].dir) || "ltr";
|
|
@@ -106,7 +113,7 @@ export default function AttachmentEditor(props) {
|
|
|
106
113
|
<button onClick={save}>
|
|
107
114
|
Save
|
|
108
115
|
</button>
|
|
109
|
-
<button onClick={
|
|
116
|
+
<button onClick={closeModal}>
|
|
110
117
|
Cancel
|
|
111
118
|
</button>
|
|
112
119
|
</div>
|
|
@@ -114,10 +121,3 @@ export default function AttachmentEditor(props) {
|
|
|
114
121
|
</div>
|
|
115
122
|
);
|
|
116
123
|
}
|
|
117
|
-
|
|
118
|
-
AttachmentEditor.propTypes = {
|
|
119
|
-
attachment: PropTypes.object,
|
|
120
|
-
locale: PropTypes.string,
|
|
121
|
-
locales: PropTypes.object,
|
|
122
|
-
onUpdate: PropTypes.func
|
|
123
|
-
};
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
2
|
import ImageEditor from "./ImageEditor";
|
|
4
|
-
import
|
|
3
|
+
import useModalStore from "../stores/useModalStore";
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
import { Locale, ImageResource } from "../types";
|
|
6
|
+
|
|
7
|
+
interface EditableImageProps {
|
|
8
|
+
image: ImageResource,
|
|
9
|
+
src: string,
|
|
10
|
+
caption: boolean,
|
|
11
|
+
locale: string,
|
|
12
|
+
locales: Record<string, Locale>,
|
|
13
|
+
width: number,
|
|
14
|
+
onUpdate?: (newImage: ImageResource, src: string) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function EditableImage(props: EditableImageProps) {
|
|
7
18
|
const [image, setImage] = useState(props.image);
|
|
8
19
|
const [src, setSrc] = useState(props.src);
|
|
9
20
|
|
|
21
|
+
const openModal = useModalStore((state) => state.open);
|
|
22
|
+
|
|
10
23
|
const height = () => {
|
|
11
24
|
const width = image.crop_width || image.real_width;
|
|
12
25
|
const height = image.crop_height || image.real_height;
|
|
13
26
|
return Math.round((height / width) * props.width);
|
|
14
27
|
};
|
|
15
28
|
|
|
16
|
-
const updateImage = (updatedImage, src) => {
|
|
17
|
-
|
|
29
|
+
const updateImage = (updatedImage: ImageResource, src: string) => {
|
|
30
|
+
const newImage = { ...image, ...updatedImage };
|
|
18
31
|
setSrc(src);
|
|
19
32
|
setImage(newImage);
|
|
20
33
|
if (props.onUpdate) {
|
|
@@ -22,16 +35,16 @@ export default function EditableImage(props) {
|
|
|
22
35
|
}
|
|
23
36
|
};
|
|
24
37
|
|
|
25
|
-
const handleClick = (evt) => {
|
|
38
|
+
const handleClick = (evt: Event) => {
|
|
26
39
|
evt.preventDefault();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
openModal(
|
|
41
|
+
<ImageEditor
|
|
42
|
+
image={image}
|
|
43
|
+
caption={props.caption}
|
|
44
|
+
locale={props.locale}
|
|
45
|
+
locales={props.locales}
|
|
46
|
+
onUpdate={updateImage} />
|
|
47
|
+
);
|
|
35
48
|
};
|
|
36
49
|
|
|
37
50
|
const altWarning = !image.alternative[props.locale];
|
|
@@ -40,7 +53,7 @@ export default function EditableImage(props) {
|
|
|
40
53
|
<div className="editable-image">
|
|
41
54
|
{altWarning &&
|
|
42
55
|
<span className="alt-warning" title="Alternative text is missing">
|
|
43
|
-
<i className="fa fa-exclamation
|
|
56
|
+
<i className="fa-solid fa-triangle-exclamation icon" />
|
|
44
57
|
</span>}
|
|
45
58
|
<img src={src}
|
|
46
59
|
width={props.width}
|
|
@@ -49,13 +62,3 @@ export default function EditableImage(props) {
|
|
|
49
62
|
</div>
|
|
50
63
|
);
|
|
51
64
|
}
|
|
52
|
-
|
|
53
|
-
EditableImage.propTypes = {
|
|
54
|
-
image: PropTypes.object,
|
|
55
|
-
src: PropTypes.string,
|
|
56
|
-
caption: PropTypes.bool,
|
|
57
|
-
locale: PropTypes.string,
|
|
58
|
-
locales: PropTypes.object,
|
|
59
|
-
width: PropTypes.number,
|
|
60
|
-
onUpdate: PropTypes.func
|
|
61
|
-
};
|