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.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/assets/builds/pages_core/admin-dist.js +19 -8
  4. data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
  5. data/app/assets/builds/pages_core/admin.css +672 -379
  6. data/app/assets/fonts/Inter-Black.woff2 +0 -0
  7. data/app/assets/fonts/Inter-BlackItalic.woff2 +0 -0
  8. data/app/assets/fonts/Inter-Bold.woff2 +0 -0
  9. data/app/assets/fonts/Inter-BoldItalic.woff2 +0 -0
  10. data/app/assets/fonts/Inter-ExtraBold.woff2 +0 -0
  11. data/app/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
  12. data/app/assets/fonts/Inter-ExtraLight.woff2 +0 -0
  13. data/app/assets/fonts/Inter-ExtraLightItalic.woff2 +0 -0
  14. data/app/assets/fonts/Inter-Italic.woff2 +0 -0
  15. data/app/assets/fonts/Inter-Light.woff2 +0 -0
  16. data/app/assets/fonts/Inter-LightItalic.woff2 +0 -0
  17. data/app/assets/fonts/Inter-Medium.woff2 +0 -0
  18. data/app/assets/fonts/Inter-MediumItalic.woff2 +0 -0
  19. data/app/assets/fonts/Inter-Regular.woff2 +0 -0
  20. data/app/assets/fonts/Inter-SemiBold.woff2 +0 -0
  21. data/app/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
  22. data/app/assets/fonts/Inter-Thin.woff2 +0 -0
  23. data/app/assets/fonts/Inter-ThinItalic.woff2 +0 -0
  24. data/app/assets/fonts/InterDisplay-Black.woff2 +0 -0
  25. data/app/assets/fonts/InterDisplay-BlackItalic.woff2 +0 -0
  26. data/app/assets/fonts/InterDisplay-Bold.woff2 +0 -0
  27. data/app/assets/fonts/InterDisplay-BoldItalic.woff2 +0 -0
  28. data/app/assets/fonts/InterDisplay-ExtraBold.woff2 +0 -0
  29. data/app/assets/fonts/InterDisplay-ExtraBoldItalic.woff2 +0 -0
  30. data/app/assets/fonts/InterDisplay-ExtraLight.woff2 +0 -0
  31. data/app/assets/fonts/InterDisplay-ExtraLightItalic.woff2 +0 -0
  32. data/app/assets/fonts/InterDisplay-Italic.woff2 +0 -0
  33. data/app/assets/fonts/InterDisplay-Light.woff2 +0 -0
  34. data/app/assets/fonts/InterDisplay-LightItalic.woff2 +0 -0
  35. data/app/assets/fonts/InterDisplay-Medium.woff2 +0 -0
  36. data/app/assets/fonts/InterDisplay-MediumItalic.woff2 +0 -0
  37. data/app/assets/fonts/InterDisplay-Regular.woff2 +0 -0
  38. data/app/assets/fonts/InterDisplay-SemiBold.woff2 +0 -0
  39. data/app/assets/fonts/InterDisplay-SemiBoldItalic.woff2 +0 -0
  40. data/app/assets/fonts/InterDisplay-Thin.woff2 +0 -0
  41. data/app/assets/fonts/InterDisplay-ThinItalic.woff2 +0 -0
  42. data/app/assets/fonts/InterVariable-Italic.woff2 +0 -0
  43. data/app/assets/fonts/InterVariable.woff2 +0 -0
  44. data/app/assets/stylesheets/pages_core/admin/components/archive.css +1 -1
  45. data/app/assets/stylesheets/pages_core/admin/components/attachments.css +22 -34
  46. data/app/assets/stylesheets/pages_core/admin/components/base.css +1 -68
  47. data/app/assets/stylesheets/pages_core/admin/components/forms.css +107 -48
  48. data/app/assets/stylesheets/pages_core/admin/components/header.css +56 -58
  49. data/app/assets/stylesheets/pages_core/admin/components/image_editor.css +35 -24
  50. data/app/assets/stylesheets/pages_core/admin/components/image_grid.css +28 -27
  51. data/app/assets/stylesheets/pages_core/admin/components/image_uploader.css +5 -5
  52. data/app/assets/stylesheets/pages_core/admin/components/layout.css +7 -1
  53. data/app/assets/stylesheets/pages_core/admin/components/list_table.css +24 -15
  54. data/app/assets/stylesheets/pages_core/admin/components/page_tree.css +63 -104
  55. data/app/assets/stylesheets/pages_core/admin/components/pagination.css +12 -13
  56. data/app/assets/stylesheets/pages_core/admin/components/search.css +1 -16
  57. data/app/assets/stylesheets/pages_core/admin/components/sidebar.css +5 -11
  58. data/app/assets/stylesheets/pages_core/admin/components/tag_editor.css +22 -36
  59. data/app/assets/stylesheets/pages_core/admin/components/toast.css +1 -2
  60. data/app/assets/stylesheets/pages_core/admin/components/toolbar.css +10 -10
  61. data/app/assets/stylesheets/pages_core/admin/components/totp.css +1 -1
  62. data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +37 -51
  63. data/app/assets/stylesheets/pages_core/admin/global/fonts.css +271 -0
  64. data/app/assets/stylesheets/pages_core/admin/global/typography.css +109 -0
  65. data/app/assets/stylesheets/pages_core/admin/vars.css +1 -3
  66. data/app/assets/stylesheets/pages_core/admin.postcss.css +1 -0
  67. data/app/controllers/admin/account_recoveries_controller.rb +2 -2
  68. data/app/controllers/admin/pages_controller.rb +22 -42
  69. data/app/controllers/concerns/pages_core/error_reporting.rb +1 -1
  70. data/app/controllers/concerns/pages_core/page_parameters.rb +29 -0
  71. data/app/controllers/concerns/pages_core/policies_helper.rb +1 -1
  72. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +20 -20
  73. data/app/controllers/pages_core/admin_controller.rb +0 -2
  74. data/app/controllers/pages_core/frontend/pages_controller.rb +2 -6
  75. data/app/formatters/pages_core/html_formatter.rb +2 -4
  76. data/app/helpers/admin/menu_helper.rb +5 -4
  77. data/app/helpers/admin/pages_helper.rb +1 -21
  78. data/app/helpers/pages_core/admin/admin_helper.rb +2 -3
  79. data/app/helpers/pages_core/admin/content_tabs_helper.rb +1 -2
  80. data/app/helpers/pages_core/admin/labelled_field_helper.rb +1 -1
  81. data/app/helpers/pages_core/frontend_helper.rb +1 -1
  82. data/app/helpers/pages_core/images_helper.rb +10 -8
  83. data/app/helpers/pages_core/labelled_form_builder.rb +2 -7
  84. data/app/helpers/pages_core/page_path_helper.rb +1 -1
  85. data/app/javascript/components/Attachments/Attachment.tsx +20 -18
  86. data/app/javascript/components/Attachments/AttachmentEditor.tsx +11 -9
  87. data/app/javascript/components/{Attachments.jsx → Attachments/List.tsx} +58 -63
  88. data/app/javascript/components/Attachments/useAttachments.ts +15 -0
  89. data/app/javascript/components/Attachments.tsx +14 -0
  90. data/app/javascript/components/DateRangeSelect.tsx +105 -0
  91. data/app/javascript/components/DateTimeSelect.tsx +136 -0
  92. data/app/javascript/components/EditableImage.tsx +11 -9
  93. data/app/javascript/components/FileUploadButton.tsx +7 -7
  94. data/app/javascript/components/ImageCropper/FocalPoint.tsx +9 -12
  95. data/app/javascript/components/ImageCropper/Image.tsx +10 -8
  96. data/app/javascript/components/ImageCropper/Toolbar.tsx +11 -12
  97. data/app/javascript/components/ImageCropper/useCrop.ts +24 -53
  98. data/app/javascript/components/ImageCropper.tsx +10 -15
  99. data/app/javascript/components/ImageEditor/Form.tsx +12 -8
  100. data/app/javascript/components/ImageEditor.tsx +12 -7
  101. data/app/javascript/components/ImageGrid/DragElement.tsx +9 -12
  102. data/app/javascript/components/{ImageGrid.jsx → ImageGrid/Grid.tsx} +62 -71
  103. data/app/javascript/components/ImageGrid/GridImage.tsx +22 -23
  104. data/app/javascript/components/ImageGrid/Placeholder.tsx +2 -2
  105. data/app/javascript/components/ImageGrid/useImageGrid.ts +26 -0
  106. data/app/javascript/components/ImageGrid.tsx +15 -0
  107. data/app/javascript/components/ImageUploader.tsx +35 -22
  108. data/app/javascript/components/LabelledField.tsx +34 -0
  109. data/app/javascript/components/Modal.tsx +2 -2
  110. data/app/javascript/components/PageForm/Block.tsx +81 -0
  111. data/app/javascript/components/PageForm/Content.tsx +54 -0
  112. data/app/javascript/components/PageForm/Dates.tsx +66 -0
  113. data/app/javascript/components/PageForm/Files.tsx +28 -0
  114. data/app/javascript/components/PageForm/Form.tsx +41 -0
  115. data/app/javascript/components/PageForm/Images.tsx +28 -0
  116. data/app/javascript/components/PageForm/LocaleLinks.tsx +36 -0
  117. data/app/javascript/components/PageForm/Metadata.tsx +67 -0
  118. data/app/javascript/components/PageForm/Options.tsx +180 -0
  119. data/app/javascript/components/PageForm/PageDescription.tsx +48 -0
  120. data/app/javascript/components/PageForm/PathSegment.tsx +65 -0
  121. data/app/javascript/components/PageForm/TabPanel.tsx +21 -0
  122. data/app/javascript/components/PageForm/Tabs.tsx +33 -0
  123. data/app/javascript/components/PageForm/UnconfiguredContent.tsx +42 -0
  124. data/app/javascript/components/PageForm/pageParams.ts +95 -0
  125. data/app/javascript/components/PageForm/preview.ts +23 -0
  126. data/app/javascript/components/PageForm/usePage.ts +169 -0
  127. data/app/javascript/components/PageForm/useTabs.ts +46 -0
  128. data/app/javascript/components/PageForm.tsx +163 -0
  129. data/app/javascript/components/PageImages.tsx +7 -9
  130. data/app/javascript/components/PageTree/Draggable.tsx +40 -39
  131. data/app/javascript/components/PageTree/Node.tsx +62 -56
  132. data/app/javascript/components/PageTree/PageName.tsx +28 -0
  133. data/app/javascript/components/PageTree.tsx +65 -53
  134. data/app/javascript/components/{RichTextArea.jsx → RichTextArea.tsx} +98 -79
  135. data/app/javascript/components/RichTextToolbarButton.tsx +4 -6
  136. data/app/javascript/components/TagEditor/AddTagForm.tsx +19 -12
  137. data/app/javascript/components/TagEditor/Editor.tsx +32 -0
  138. data/app/javascript/components/TagEditor/Tag.tsx +6 -4
  139. data/app/javascript/components/TagEditor/useTags.ts +58 -0
  140. data/app/javascript/components/TagEditor.tsx +8 -58
  141. data/app/javascript/components/Toast.tsx +3 -3
  142. data/app/javascript/components/drag/draggedOrder.ts +22 -14
  143. data/app/javascript/components/drag/useDragCollection.ts +35 -30
  144. data/app/javascript/components/drag/useDragUploader.ts +32 -21
  145. data/app/javascript/components/drag/useDraggable.ts +7 -6
  146. data/app/javascript/components/drag.ts +0 -1
  147. data/app/javascript/components.ts +1 -3
  148. data/app/javascript/features/RichText.tsx +2 -3
  149. data/app/javascript/features/contentTabs.ts +79 -0
  150. data/app/javascript/index.ts +5 -12
  151. data/app/javascript/lib/Tree.ts +31 -45
  152. data/app/javascript/lib/request.ts +11 -11
  153. data/app/javascript/stores/useToastStore.ts +1 -1
  154. data/app/javascript/types/Attachments.ts +29 -0
  155. data/app/javascript/types/Crop.ts +36 -0
  156. data/app/javascript/types/Drag.ts +34 -0
  157. data/app/javascript/types/Images.ts +47 -0
  158. data/app/javascript/types/PageEditor.ts +26 -0
  159. data/app/javascript/types/Pages.ts +75 -0
  160. data/app/javascript/types/Tags.ts +9 -0
  161. data/app/javascript/types/Template.ts +24 -0
  162. data/app/javascript/types/Trees.ts +19 -0
  163. data/app/javascript/types.ts +2 -25
  164. data/app/models/attachment.rb +1 -1
  165. data/app/models/concerns/pages_core/authenticable_user.rb +63 -0
  166. data/app/models/concerns/pages_core/emailable.rb +16 -0
  167. data/app/models/concerns/pages_core/page_model/templateable.rb +2 -16
  168. data/app/models/invite.rb +2 -6
  169. data/app/models/otp_secret.rb +4 -4
  170. data/app/models/page.rb +0 -3
  171. data/app/models/user.rb +2 -46
  172. data/app/policies/page_policy.rb +6 -2
  173. data/app/resources/admin/page_resource.rb +95 -0
  174. data/app/resources/admin/page_tree_resource.rb +27 -0
  175. data/app/resources/admin/template_configuration_resource.rb +50 -0
  176. data/app/views/admin/news/_sidebar.html.erb +2 -4
  177. data/app/views/admin/news/index.html.erb +0 -1
  178. data/app/views/admin/pages/_form.html.erb +10 -30
  179. data/app/views/admin/pages/_search_bar.html.erb +1 -1
  180. data/app/views/admin/pages/edit.html.erb +1 -57
  181. data/app/views/admin/pages/index.html.erb +1 -1
  182. data/app/views/admin/pages/new.html.erb +1 -44
  183. data/app/views/admin/sessions/new.html.erb +9 -11
  184. data/app/views/admin/users/_access_control.html.erb +5 -1
  185. data/app/views/admin/users/_list.html.erb +12 -7
  186. data/app/views/layouts/admin/_header.html.erb +2 -4
  187. data/app/views/layouts/admin/_page_header.html.erb +1 -2
  188. data/app/views/layouts/admin.html.erb +1 -1
  189. data/config/locales/en.yml +0 -4
  190. data/config/routes.rb +3 -7
  191. data/db/migrate/20240126160700_add_2fa_fields.rb +5 -1
  192. data/db/migrate/20240131140700_change_email_to_citext.rb +18 -0
  193. data/db/migrate/20240201160700_remove_persistent_data.rb +7 -0
  194. data/db/migrate/20240508145300_remove_categories.rb +21 -0
  195. data/lib/pages_core/configuration/base.rb +2 -2
  196. data/lib/pages_core/templates/configuration.rb +1 -1
  197. data/lib/pages_core/templates/configuration_proxy.rb +2 -2
  198. data/lib/pages_core/templates/template_configuration.rb +11 -1
  199. data/lib/pages_core/templates.rb +6 -4
  200. data/lib/pages_core/version.rb +1 -1
  201. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +6 -7
  202. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +17 -12
  203. data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +0 -2
  204. data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +3 -4
  205. metadata +95 -29
  206. data/app/assets/stylesheets/pages_core/admin/components/login.css +0 -27
  207. data/app/controllers/admin/categories_controller.rb +0 -56
  208. data/app/controllers/concerns/pages_core/admin/persistent_params.rb +0 -75
  209. data/app/helpers/pages_core/admin/page_blocks_helper.rb +0 -66
  210. data/app/helpers/pages_core/admin/page_json_helper.rb +0 -23
  211. data/app/javascript/components/DateRangeSelect.jsx +0 -225
  212. data/app/javascript/components/PageDates.jsx +0 -73
  213. data/app/javascript/components/PageFiles.jsx +0 -25
  214. data/app/javascript/components/PageTree/types.ts +0 -15
  215. data/app/javascript/components/drag/types.ts +0 -28
  216. data/app/javascript/controllers/EditPageController.ts +0 -22
  217. data/app/javascript/controllers/MainController.ts +0 -74
  218. data/app/javascript/controllers/PageOptionsController.js +0 -67
  219. data/app/models/category.rb +0 -22
  220. data/app/models/concerns/pages_core/has_otp.rb +0 -27
  221. data/app/models/page_category.rb +0 -6
  222. data/app/views/admin/pages/_edit_content.html.erb +0 -19
  223. data/app/views/admin/pages/_edit_files.html.erb +0 -4
  224. data/app/views/admin/pages/_edit_images.html.erb +0 -4
  225. data/app/views/admin/pages/_edit_metadata.html.erb +0 -35
  226. data/app/views/admin/pages/_edit_options.html.erb +0 -91
  227. 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
- }