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
@@ -1,27 +0,0 @@
|
|
1
|
-
main .login-form {
|
2
|
-
padding-top: 10px;
|
3
|
-
|
4
|
-
& label {
|
5
|
-
display: block;
|
6
|
-
font-weight: bold;
|
7
|
-
margin-bottom: 8px;
|
8
|
-
font-size: 1.2em;
|
9
|
-
color: var(--text-color);
|
10
|
-
}
|
11
|
-
|
12
|
-
& ul {
|
13
|
-
margin: 0px;
|
14
|
-
padding: 0px;
|
15
|
-
margin-top: 30px;
|
16
|
-
list-style-position: inside;
|
17
|
-
list-style-type: disc;
|
18
|
-
color: var(--border-color);
|
19
|
-
line-height: 1.5;
|
20
|
-
|
21
|
-
& li {
|
22
|
-
margin: 0px;
|
23
|
-
padding: 0px;
|
24
|
-
font-size: 1.2em;
|
25
|
-
}
|
26
|
-
}
|
27
|
-
}
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Admin
|
4
|
-
class CategoriesController < Admin::AdminController
|
5
|
-
before_action :find_category, only: %i[show edit update destroy]
|
6
|
-
|
7
|
-
def index
|
8
|
-
@categories = Category.all
|
9
|
-
end
|
10
|
-
|
11
|
-
def show
|
12
|
-
redirect_to edit_admin_category_url(@category)
|
13
|
-
end
|
14
|
-
|
15
|
-
def new
|
16
|
-
@category = Category.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def edit; end
|
20
|
-
|
21
|
-
def create
|
22
|
-
@category = Category.create(category_params)
|
23
|
-
if @category.valid?
|
24
|
-
flash[:notice] = t("pages_core.categories_controller.created")
|
25
|
-
redirect_to admin_pages_url(content_locale)
|
26
|
-
else
|
27
|
-
render action: :new
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def update
|
32
|
-
if @category.update(category_params)
|
33
|
-
flash[:notice] = t("pages_core.categories_controller.updated")
|
34
|
-
redirect_to admin_pages_url(content_locale)
|
35
|
-
else
|
36
|
-
render action: :edit
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def destroy
|
41
|
-
@category.destroy
|
42
|
-
flash[:notice] = t("pages_core.categories_controller.deleted")
|
43
|
-
redirect_to admin_pages_url(content_locale)
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
def category_params
|
49
|
-
params.require(:category).permit(:name, :slug, :position)
|
50
|
-
end
|
51
|
-
|
52
|
-
def find_category
|
53
|
-
@category = Category.find(params[:id])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module PagesCore
|
4
|
-
module Admin
|
5
|
-
module PersistentParams
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
included do
|
9
|
-
before_action :restore_persistent_params
|
10
|
-
after_action :save_persistent_params
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
# Loads persistent params from user model and merges with session.
|
16
|
-
def restore_persistent_params
|
17
|
-
return unless current_user&.persistent_data?
|
18
|
-
|
19
|
-
session[:persistent_params] ||= {}
|
20
|
-
session[:persistent_params] = current_user.persistent_data.merge(
|
21
|
-
session[:persistent_params]
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Saves persistent params from session to User model if applicable.
|
26
|
-
def save_persistent_params
|
27
|
-
return unless current_user && session[:persistent_params]
|
28
|
-
|
29
|
-
current_user.persistent_data = session[:persistent_params]
|
30
|
-
current_user.save
|
31
|
-
end
|
32
|
-
|
33
|
-
def persistent_params(namespace)
|
34
|
-
session[:persistent_params] ||= {}
|
35
|
-
session[:persistent_params][namespace] ||= {}
|
36
|
-
session[:persistent_params][namespace]
|
37
|
-
end
|
38
|
-
|
39
|
-
def coerce_persistent_param(value)
|
40
|
-
case value
|
41
|
-
when "true"
|
42
|
-
true
|
43
|
-
when "false"
|
44
|
-
false
|
45
|
-
else
|
46
|
-
value
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def get_persistent_param(namespace, key, default)
|
51
|
-
if params.key?(key)
|
52
|
-
params[key]
|
53
|
-
elsif persistent_params(namespace).key?(key)
|
54
|
-
persistent_params(namespace)[key]
|
55
|
-
else
|
56
|
-
default
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Get a persistent param
|
61
|
-
def persistent_param(key, default = nil, options = {})
|
62
|
-
key = key.to_s
|
63
|
-
namespace = options[:namespace] || self.class.to_s
|
64
|
-
|
65
|
-
value = coerce_persistent_param(
|
66
|
-
get_persistent_param(namespace, key, default)
|
67
|
-
)
|
68
|
-
|
69
|
-
persistent_params(namespace)[key] = value unless value.nil?
|
70
|
-
|
71
|
-
value
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module PagesCore
|
4
|
-
module Admin
|
5
|
-
module PageBlocksHelper
|
6
|
-
def page_block_field(form, block_name, block_options)
|
7
|
-
labelled_field(
|
8
|
-
if block_options[:type] == :select
|
9
|
-
page_block_select(form, block_name, block_options)
|
10
|
-
else
|
11
|
-
page_block_text_field(form, block_name, block_options)
|
12
|
-
end,
|
13
|
-
block_options[:title],
|
14
|
-
errors: form.object.errors[block_name],
|
15
|
-
description: block_options[:description]
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def page_block_select(form, block_name, block_options)
|
20
|
-
opts = localize_page_select_options(form, block_options)
|
21
|
-
opts = opts.call if opts.is_a?(Proc)
|
22
|
-
opts = opts.map { |v| [v, v] } unless nested_array?(opts)
|
23
|
-
opts = ([["", nil]] + opts).uniq
|
24
|
-
|
25
|
-
value = form.object.send(block_name)
|
26
|
-
opts << [value, value] unless opts.map(&:last).include?(value)
|
27
|
-
|
28
|
-
form.send(:select, block_name, opts)
|
29
|
-
end
|
30
|
-
|
31
|
-
def page_block_text_field(form, block_name, block_options)
|
32
|
-
form.send(
|
33
|
-
block_options[:size] == :field ? :text_field : :rich_text_area,
|
34
|
-
block_name,
|
35
|
-
page_block_field_options(block_options)
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def localize_page_select_options(form, block_options)
|
42
|
-
if block_options[:options].is_a?(Hash)
|
43
|
-
block_options[:options][form.object.locale.to_sym]
|
44
|
-
else
|
45
|
-
block_options[:options]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def page_block_classes(class_name, block_options = {})
|
50
|
-
[class_name, block_options[:class]].join(" ").strip
|
51
|
-
end
|
52
|
-
|
53
|
-
def page_block_field_options(block_options = {})
|
54
|
-
opts = { placeholder: block_options[:placeholder] }
|
55
|
-
if block_options[:size] == :field
|
56
|
-
opts.merge(class: page_block_classes("rich", block_options))
|
57
|
-
else
|
58
|
-
opts.merge(
|
59
|
-
class: page_block_classes("rich", block_options),
|
60
|
-
rows: (block_options[:size] == :large ? 15 : 5)
|
61
|
-
)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module PagesCore
|
4
|
-
module Admin
|
5
|
-
module PageJsonHelper
|
6
|
-
def page_json(page)
|
7
|
-
{ id: page.id, param: page.to_param,
|
8
|
-
name: page.name,
|
9
|
-
parent_page_id: page.parent_page_id,
|
10
|
-
locale: page.locale, status: page.status,
|
11
|
-
news_page: page.news_page,
|
12
|
-
published_at: page.published_at,
|
13
|
-
pinned: page.pinned?, starts_at: page.starts_at,
|
14
|
-
permissions: page_permissions(page) }
|
15
|
-
end
|
16
|
-
|
17
|
-
def page_permissions(page)
|
18
|
-
[(:edit if policy(page).edit?),
|
19
|
-
(:create if policy(page).edit?)].compact
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,225 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import PropTypes from "prop-types";
|
3
|
-
|
4
|
-
export default class DateRangeSelect extends React.Component {
|
5
|
-
constructor(props) {
|
6
|
-
super(props);
|
7
|
-
this.state = {
|
8
|
-
startsAt: this.parseDate(props.startsAt) || this.defaultDate(),
|
9
|
-
endsAt: this.parseDate(props.endsAt) || this.defaultDate(60),
|
10
|
-
startTime: "",
|
11
|
-
endTime: ""
|
12
|
-
};
|
13
|
-
this.state.startTime = this.timeToString(this.state.startsAt);
|
14
|
-
this.state.endTime = this.timeToString(this.state.endsAt);
|
15
|
-
|
16
|
-
this.changeStartsAt = this.changeStartsAt.bind(this);
|
17
|
-
this.changeEndsAt = this.changeEndsAt.bind(this);
|
18
|
-
}
|
19
|
-
|
20
|
-
changeStartsAt(options = {}) {
|
21
|
-
let newDate = this.modifyDate(this.state.startsAt, options);
|
22
|
-
this.setDates(
|
23
|
-
newDate,
|
24
|
-
new Date(this.state.endsAt.getTime() + (newDate - this.state.startsAt))
|
25
|
-
);
|
26
|
-
}
|
27
|
-
|
28
|
-
changeEndsAt(options = {}) {
|
29
|
-
let newDate = this.modifyDate(this.state.endsAt, options);
|
30
|
-
this.setDates(this.state.startsAt, newDate);
|
31
|
-
}
|
32
|
-
|
33
|
-
defaultDate(offset = 0) {
|
34
|
-
let coeff = 1000 * 60 * 60;
|
35
|
-
return new Date(
|
36
|
-
Math.round(new Date().getTime() / coeff) * coeff +
|
37
|
-
coeff +
|
38
|
-
1000 * 60 * offset
|
39
|
-
);
|
40
|
-
}
|
41
|
-
|
42
|
-
modifyDate(original, options = {}) {
|
43
|
-
var newDate = new Date(original);
|
44
|
-
if (Object.prototype.hasOwnProperty.call(options, "year")) {
|
45
|
-
newDate.setFullYear(options.year);
|
46
|
-
}
|
47
|
-
if (Object.prototype.hasOwnProperty.call(options, "month")) {
|
48
|
-
newDate.setMonth(options.month);
|
49
|
-
}
|
50
|
-
if (Object.prototype.hasOwnProperty.call(options, "date")) {
|
51
|
-
newDate.setDate(options.date);
|
52
|
-
}
|
53
|
-
if (
|
54
|
-
Object.prototype.hasOwnProperty.call(options, "time") &&
|
55
|
-
options.time.match(/^[\d]{1,2}(:[\d]{1,2})?$/)
|
56
|
-
) {
|
57
|
-
newDate.setHours(options.time.split(":")[0]);
|
58
|
-
newDate.setMinutes(options.time.split(":")[1] || 0);
|
59
|
-
}
|
60
|
-
return newDate;
|
61
|
-
}
|
62
|
-
|
63
|
-
parseDate(str) {
|
64
|
-
if (!str) {
|
65
|
-
return;
|
66
|
-
}
|
67
|
-
return new Date(str);
|
68
|
-
}
|
69
|
-
|
70
|
-
setDates(start, end) {
|
71
|
-
if (end < start) {
|
72
|
-
end = start;
|
73
|
-
}
|
74
|
-
this.setState({
|
75
|
-
startsAt: start,
|
76
|
-
endsAt: end,
|
77
|
-
startTime: this.timeToString(start),
|
78
|
-
endTime: this.timeToString(end)
|
79
|
-
});
|
80
|
-
}
|
81
|
-
|
82
|
-
startsAtToString() {
|
83
|
-
if (this.props.disabled) {
|
84
|
-
return "";
|
85
|
-
}
|
86
|
-
return this.state.startsAt.toJSON();
|
87
|
-
}
|
88
|
-
|
89
|
-
endsAtToString() {
|
90
|
-
if (this.props.disabled) {
|
91
|
-
return "";
|
92
|
-
}
|
93
|
-
return this.state.endsAt.toJSON();
|
94
|
-
}
|
95
|
-
|
96
|
-
renderDateSelect(key, date, handleChange) {
|
97
|
-
return (
|
98
|
-
<div className="date-select">
|
99
|
-
<select
|
100
|
-
value={date.getMonth()}
|
101
|
-
onChange={(e) => handleChange({ month: e.target.value })}
|
102
|
-
disabled={this.props.disabled}>
|
103
|
-
{this.monthOptions().map((m, i) => (
|
104
|
-
<option key={key + "-month-" + i} value={i}>
|
105
|
-
{m}
|
106
|
-
</option>
|
107
|
-
))}
|
108
|
-
</select>
|
109
|
-
<select
|
110
|
-
value={date.getDate()}
|
111
|
-
onChange={(e) => handleChange({ date: e.target.value })}
|
112
|
-
disabled={this.props.disabled}>
|
113
|
-
{this.dayOptions().map((d) => (
|
114
|
-
<option key={key + "-date-" + d} value={d}>
|
115
|
-
{d}
|
116
|
-
</option>
|
117
|
-
))}
|
118
|
-
</select>
|
119
|
-
<select
|
120
|
-
value={date.getFullYear()}
|
121
|
-
onChange={(e) => handleChange({ year: e.target.value })}
|
122
|
-
disabled={this.props.disabled}>
|
123
|
-
{this.yearOptions().map((y) => (
|
124
|
-
<option key={key + "-year-" + y} value={y}>
|
125
|
-
{y}
|
126
|
-
</option>
|
127
|
-
))}
|
128
|
-
</select>
|
129
|
-
</div>
|
130
|
-
);
|
131
|
-
}
|
132
|
-
|
133
|
-
render() {
|
134
|
-
return (
|
135
|
-
<div className="date-range-select">
|
136
|
-
<input
|
137
|
-
type="hidden"
|
138
|
-
name={this.props.objectName + "[starts_at]"}
|
139
|
-
value={this.startsAtToString()}
|
140
|
-
/>
|
141
|
-
<input
|
142
|
-
type="hidden"
|
143
|
-
name={this.props.objectName + "[ends_at]"}
|
144
|
-
value={this.endsAtToString()}
|
145
|
-
/>
|
146
|
-
<div className="date">
|
147
|
-
{this.renderDateSelect(
|
148
|
-
"starts-at",
|
149
|
-
this.state.startsAt,
|
150
|
-
this.changeStartsAt
|
151
|
-
)}
|
152
|
-
{!this.props.disableTime && (
|
153
|
-
<input
|
154
|
-
type="text"
|
155
|
-
size="5"
|
156
|
-
value={this.state.startTime}
|
157
|
-
disabled={this.props.disabled}
|
158
|
-
onChange={(e) => this.setState({ startTime: e.target.value })}
|
159
|
-
onBlur={(e) => this.changeStartsAt({ time: e.target.value })}
|
160
|
-
/>
|
161
|
-
)}
|
162
|
-
</div>
|
163
|
-
<span className="to">to</span>
|
164
|
-
<div className="date">
|
165
|
-
{this.renderDateSelect(
|
166
|
-
"ends-at",
|
167
|
-
this.state.endsAt,
|
168
|
-
this.changeEndsAt
|
169
|
-
)}
|
170
|
-
{!this.props.disableTime && (
|
171
|
-
<input
|
172
|
-
type="text"
|
173
|
-
size="5"
|
174
|
-
value={this.state.endTime}
|
175
|
-
disabled={this.props.disabled}
|
176
|
-
onChange={(e) => this.setState({ endTime: e.target.value })}
|
177
|
-
onBlur={(e) => this.changeEndsAt({ time: e.target.value })}
|
178
|
-
/>
|
179
|
-
)}
|
180
|
-
</div>
|
181
|
-
</div>
|
182
|
-
);
|
183
|
-
}
|
184
|
-
|
185
|
-
timeToString(time) {
|
186
|
-
return time.toTimeString().slice(0, 5);
|
187
|
-
}
|
188
|
-
|
189
|
-
// Returns an array with years from 2000 to 10 years from now.
|
190
|
-
yearOptions() {
|
191
|
-
let start = 2000;
|
192
|
-
return Array.apply(null, Array(new Date().getFullYear() - start + 11)).map(
|
193
|
-
(_, i) => i + start
|
194
|
-
);
|
195
|
-
}
|
196
|
-
|
197
|
-
monthOptions() {
|
198
|
-
return [
|
199
|
-
"January",
|
200
|
-
"February",
|
201
|
-
"March",
|
202
|
-
"April",
|
203
|
-
"May",
|
204
|
-
"June",
|
205
|
-
"July",
|
206
|
-
"August",
|
207
|
-
"September",
|
208
|
-
"October",
|
209
|
-
"November",
|
210
|
-
"December"
|
211
|
-
];
|
212
|
-
}
|
213
|
-
|
214
|
-
dayOptions() {
|
215
|
-
return Array.apply(null, Array(31)).map((_, i) => i + 1);
|
216
|
-
}
|
217
|
-
}
|
218
|
-
|
219
|
-
DateRangeSelect.propTypes = {
|
220
|
-
startsAt: PropTypes.string,
|
221
|
-
endsAt: PropTypes.string,
|
222
|
-
disabled: PropTypes.bool,
|
223
|
-
disableTime: PropTypes.bool,
|
224
|
-
objectName: PropTypes.string
|
225
|
-
};
|
@@ -1,73 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import PropTypes from "prop-types";
|
3
|
-
import DateRangeSelect from "./DateRangeSelect";
|
4
|
-
|
5
|
-
export default class PageDates extends React.Component {
|
6
|
-
constructor(props) {
|
7
|
-
super(props);
|
8
|
-
this.state = {
|
9
|
-
has_dates: props.starts_at ? true : false,
|
10
|
-
all_day: !!props.all_day
|
11
|
-
};
|
12
|
-
|
13
|
-
this.toggleAllDay = this.toggleAllDay.bind(this);
|
14
|
-
this.toggleHasDates = this.toggleHasDates.bind(this);
|
15
|
-
}
|
16
|
-
|
17
|
-
toggleHasDates() {
|
18
|
-
this.setState({ has_dates: !this.state.has_dates });
|
19
|
-
}
|
20
|
-
|
21
|
-
toggleAllDay() {
|
22
|
-
this.setState({ all_day: !this.state.all_day });
|
23
|
-
}
|
24
|
-
|
25
|
-
timeToString(time) {
|
26
|
-
return time.toTimeString().slice(0, 5);
|
27
|
-
}
|
28
|
-
|
29
|
-
render() {
|
30
|
-
return (
|
31
|
-
<div className="page-dates field">
|
32
|
-
<input
|
33
|
-
type="hidden"
|
34
|
-
name="page[all_day]"
|
35
|
-
value={this.state.has_dates && this.state.all_day ? "1" : "0"}
|
36
|
-
/>
|
37
|
-
<label>Dates</label>
|
38
|
-
<div className="toggles">
|
39
|
-
<label className="has-dates-toggle">
|
40
|
-
<input
|
41
|
-
type="checkbox"
|
42
|
-
checked={this.state.has_dates}
|
43
|
-
onChange={this.toggleHasDates}
|
44
|
-
/>
|
45
|
-
Enabled
|
46
|
-
</label>
|
47
|
-
<label className={!this.state.has_dates && "disabled"}>
|
48
|
-
<input
|
49
|
-
type="checkbox"
|
50
|
-
disabled={!this.state.has_dates}
|
51
|
-
checked={this.state.all_day}
|
52
|
-
onChange={this.toggleAllDay}
|
53
|
-
/>
|
54
|
-
All day event
|
55
|
-
</label>
|
56
|
-
</div>
|
57
|
-
<DateRangeSelect
|
58
|
-
objectName="page"
|
59
|
-
startsAt={this.props.starts_at}
|
60
|
-
endsAt={this.props.ends_at}
|
61
|
-
disabled={!this.state.has_dates}
|
62
|
-
disableTime={this.state.all_day}
|
63
|
-
/>
|
64
|
-
</div>
|
65
|
-
);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
PageDates.propTypes = {
|
70
|
-
starts_at: PropTypes.string,
|
71
|
-
ends_at: PropTypes.string,
|
72
|
-
all_day: PropTypes.bool
|
73
|
-
};
|
@@ -1,25 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import PropTypes from "prop-types";
|
3
|
-
import Attachments from "./Attachments";
|
4
|
-
|
5
|
-
export default class PageFiles extends React.Component {
|
6
|
-
render() {
|
7
|
-
return (
|
8
|
-
<div className="page-files">
|
9
|
-
<Attachments
|
10
|
-
attribute="page[page_files_attributes]"
|
11
|
-
showEmbed={true}
|
12
|
-
locale={this.props.locale}
|
13
|
-
locales={this.props.locales}
|
14
|
-
records={this.props.records}
|
15
|
-
/>
|
16
|
-
</div>
|
17
|
-
);
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
PageFiles.propTypes = {
|
22
|
-
locale: PropTypes.string,
|
23
|
-
locales: PropTypes.object,
|
24
|
-
records: PropTypes.array
|
25
|
-
};
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import { TreeNode } from "../../lib/Tree";
|
2
|
-
|
3
|
-
export type Attributes = Record<string, unknown>;
|
4
|
-
|
5
|
-
export interface PageNode extends TreeNode {
|
6
|
-
id: number | null;
|
7
|
-
children: PageNode[];
|
8
|
-
editing: boolean;
|
9
|
-
locale: string;
|
10
|
-
name: string;
|
11
|
-
param: string;
|
12
|
-
permissions: string[];
|
13
|
-
published_at: string;
|
14
|
-
status: string;
|
15
|
-
}
|
@@ -1,28 +0,0 @@
|
|
1
|
-
export type DraggableRecord = Record<string, unknown>;
|
2
|
-
|
3
|
-
export interface Draggable {
|
4
|
-
record: DraggableRecord;
|
5
|
-
ref: React.MutableRefObject<HTMLDivElement>;
|
6
|
-
rect: DOMRect | null;
|
7
|
-
handle: string;
|
8
|
-
}
|
9
|
-
|
10
|
-
export interface DragCollectionAction {
|
11
|
-
type: string;
|
12
|
-
payload?: Draggable[] | Draggable | null;
|
13
|
-
}
|
14
|
-
|
15
|
-
export interface DragCollection {
|
16
|
-
ref: React.MutableRefObject<HTMLDivElement>;
|
17
|
-
draggables: Draggable[];
|
18
|
-
dispatch: (DragCollectionAction) => void;
|
19
|
-
}
|
20
|
-
|
21
|
-
export interface Position {
|
22
|
-
x: number | null;
|
23
|
-
y: number | null;
|
24
|
-
}
|
25
|
-
|
26
|
-
export interface DragState extends Position {
|
27
|
-
dragging: Draggable | false;
|
28
|
-
}
|
@@ -1,22 +0,0 @@
|
|
1
|
-
import { Controller } from "@hotwired/stimulus";
|
2
|
-
|
3
|
-
export default class EditPageController extends Controller<HTMLFormElement> {
|
4
|
-
declare readonly formTarget: HTMLFormElement;
|
5
|
-
|
6
|
-
static get targets() {
|
7
|
-
return ["form"];
|
8
|
-
}
|
9
|
-
|
10
|
-
preview() {
|
11
|
-
const form = this.formTarget;
|
12
|
-
const prevAction = form.action;
|
13
|
-
const prevTarget = form.target;
|
14
|
-
|
15
|
-
form.target = "_blank";
|
16
|
-
form.action = form.dataset.previewUrl;
|
17
|
-
form.submit();
|
18
|
-
|
19
|
-
form.action = prevAction;
|
20
|
-
form.target = prevTarget;
|
21
|
-
}
|
22
|
-
}
|