pages_core 3.15.3 → 3.15.5

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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/assets/builds/pages_core/admin-dist.js +1 -1
  4. data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
  5. data/app/assets/builds/pages_core/admin.css +378 -253
  6. data/app/assets/builds/pages_core/mailer.css +41 -6
  7. data/app/assets/builds/pages_core_fonts/121b837e.woff2 +0 -0
  8. data/app/assets/builds/pages_core_fonts/216e5c23.woff2 +0 -0
  9. data/app/assets/builds/pages_core_fonts/3017b52f.woff2 +0 -0
  10. data/app/assets/builds/pages_core_fonts/489746b9.woff2 +0 -0
  11. data/app/assets/builds/pages_core_fonts/49775483.woff2 +0 -0
  12. data/app/assets/builds/pages_core_fonts/49c9e472.woff2 +0 -0
  13. data/app/assets/builds/pages_core_fonts/4a119645.woff2 +0 -0
  14. data/app/assets/builds/pages_core_fonts/5d56d7a8.woff2 +0 -0
  15. data/app/assets/builds/pages_core_fonts/61ea75a6.woff2 +0 -0
  16. data/app/assets/builds/pages_core_fonts/62cbb778.woff2 +0 -0
  17. data/app/assets/builds/pages_core_fonts/647d26c.woff2 +0 -0
  18. data/app/assets/builds/pages_core_fonts/67764053.woff2 +0 -0
  19. data/app/assets/builds/pages_core_fonts/6bb0fd00.woff2 +0 -0
  20. data/app/assets/builds/pages_core_fonts/6c0194a2.woff2 +0 -0
  21. data/app/assets/builds/pages_core_fonts/71423409.woff2 +0 -0
  22. data/app/assets/builds/pages_core_fonts/7584e61d.woff2 +0 -0
  23. data/app/assets/builds/pages_core_fonts/77bcfa1c.woff2 +0 -0
  24. data/app/assets/builds/pages_core_fonts/7aca0cc5.woff2 +0 -0
  25. data/app/assets/builds/pages_core_fonts/9a09533f.woff2 +0 -0
  26. data/app/assets/builds/pages_core_fonts/a51f5bc8.woff2 +0 -0
  27. data/app/assets/builds/pages_core_fonts/a80b2975.woff2 +0 -0
  28. data/app/assets/builds/pages_core_fonts/a891f617.woff2 +0 -0
  29. data/app/assets/builds/pages_core_fonts/ad6083f3.woff2 +0 -0
  30. data/app/assets/builds/pages_core_fonts/b29a61ff.woff2 +0 -0
  31. data/app/assets/builds/{fonts/6569749d.ttf → pages_core_fonts/b30b0656.ttf} +0 -0
  32. data/app/assets/builds/pages_core_fonts/b3a5f48c.woff2 +0 -0
  33. data/app/assets/builds/pages_core_fonts/bc73ee06.woff2 +0 -0
  34. data/app/assets/builds/pages_core_fonts/c38c6d45.woff2 +0 -0
  35. data/app/assets/builds/pages_core_fonts/c5ce0b1f.woff2 +0 -0
  36. data/app/assets/builds/pages_core_fonts/c8d53904.woff2 +0 -0
  37. data/app/assets/builds/pages_core_fonts/ce13c169.woff2 +0 -0
  38. data/app/assets/builds/pages_core_fonts/d43bd0d5.woff2 +0 -0
  39. data/app/assets/builds/pages_core_fonts/e1c7d368.woff2 +0 -0
  40. data/app/assets/builds/pages_core_fonts/e1e8175d.woff2 +0 -0
  41. data/app/assets/builds/pages_core_fonts/e318f796.woff2 +0 -0
  42. data/app/assets/builds/{fonts/ee32bc60.ttf → pages_core_fonts/e7acb7d9.ttf} +0 -0
  43. data/app/assets/builds/pages_core_fonts/ee5514c6.woff2 +0 -0
  44. data/app/assets/builds/pages_core_fonts/f4e495e2.woff2 +0 -0
  45. data/app/assets/builds/pages_core_fonts/f736ec65.woff2 +0 -0
  46. data/app/assets/builds/pages_core_fonts/f741c7ba.woff2 +0 -0
  47. data/app/assets/builds/pages_core_fonts/f7767345.woff2 +0 -0
  48. data/app/assets/builds/pages_core_fonts/fe9eb751.woff2 +0 -0
  49. data/app/assets/stylesheets/pages_core/admin/components/forms.css +2 -2
  50. data/app/assets/stylesheets/pages_core/admin/components/header.css +1 -1
  51. data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +1 -1
  52. data/app/assets/stylesheets/pages_core/admin/global/fonts.css +38 -38
  53. data/app/controllers/{pages_core → admin}/admin_controller.rb +1 -3
  54. data/app/controllers/attachments_controller.rb +40 -0
  55. data/app/controllers/concerns/pages_core/document_title_controller.rb +16 -0
  56. data/app/controllers/concerns/pages_core/page_parameters.rb +1 -1
  57. data/app/controllers/concerns/pages_core/pages/preview_controller.rb +49 -0
  58. data/app/controllers/concerns/pages_core/pages/rss_controller.rb +43 -0
  59. data/app/controllers/errors_controller.rb +2 -0
  60. data/app/controllers/images_controller.rb +13 -0
  61. data/app/controllers/pages_core/frontend/pages_controller.rb +3 -4
  62. data/app/controllers/pages_core/frontend_controller.rb +6 -1
  63. data/app/controllers/pages_core/sitemaps_controller.rb +21 -52
  64. data/app/helpers/pages_core/admin/image_uploads_helper.rb +1 -1
  65. data/app/helpers/pages_core/application_helper.rb +0 -3
  66. data/app/helpers/pages_core/attachments_helper.rb +0 -10
  67. data/app/helpers/pages_core/feed_tags_helper.rb +31 -0
  68. data/app/helpers/pages_core/frontend_helper.rb +3 -0
  69. data/app/helpers/pages_core/head_tags_helper.rb +80 -70
  70. data/app/helpers/pages_core/page_path_helper.rb +1 -12
  71. data/app/javascript/components/Attachments/Attachment.tsx +3 -3
  72. data/app/javascript/components/Attachments/AttachmentEditor.tsx +5 -5
  73. data/app/javascript/components/Attachments/Deleted.tsx +28 -0
  74. data/app/javascript/components/Attachments/List.tsx +11 -24
  75. data/app/javascript/components/Attachments/Placeholder.tsx +0 -2
  76. data/app/javascript/components/Attachments.tsx +2 -3
  77. data/app/javascript/components/DateRangeSelect.tsx +13 -10
  78. data/app/javascript/components/DateTimeSelect.tsx +11 -11
  79. data/app/javascript/components/EditableImage.tsx +3 -3
  80. data/app/javascript/components/FileUploadButton.tsx +3 -3
  81. data/app/javascript/components/ImageCropper/FocalPoint.tsx +10 -14
  82. data/app/javascript/components/ImageCropper/Image.tsx +19 -25
  83. data/app/javascript/components/ImageCropper/Toolbar.tsx +27 -26
  84. data/app/javascript/components/ImageCropper/useContainerSize.ts +25 -0
  85. data/app/javascript/components/ImageCropper/useCrop.ts +28 -13
  86. data/app/javascript/components/ImageCropper/useImageCropperContext.ts +13 -0
  87. data/app/javascript/components/ImageCropper.tsx +24 -83
  88. data/app/javascript/components/ImageEditor/Form.tsx +25 -28
  89. data/app/javascript/components/ImageEditor/useImageEditor.ts +63 -0
  90. data/app/javascript/components/ImageEditor/useImageEditorContext.ts +14 -0
  91. data/app/javascript/components/ImageEditor.tsx +28 -42
  92. data/app/javascript/components/ImageGrid/Deleted.tsx +28 -0
  93. data/app/javascript/components/ImageGrid/DragElement.tsx +5 -5
  94. data/app/javascript/components/ImageGrid/FilePlaceholder.tsx +0 -2
  95. data/app/javascript/components/ImageGrid/Grid.tsx +15 -24
  96. data/app/javascript/components/ImageGrid/GridImage.tsx +4 -4
  97. data/app/javascript/components/ImageGrid/Placeholder.tsx +2 -4
  98. data/app/javascript/components/ImageGrid.tsx +2 -4
  99. data/app/javascript/components/ImageUploader.tsx +5 -5
  100. data/app/javascript/components/LabelledField.tsx +6 -6
  101. data/app/javascript/components/Modal.tsx +16 -13
  102. data/app/javascript/components/PageForm/Block.tsx +3 -3
  103. data/app/javascript/components/PageForm/Content.tsx +11 -15
  104. data/app/javascript/components/PageForm/Dates.tsx +3 -11
  105. data/app/javascript/components/PageForm/Files.tsx +2 -4
  106. data/app/javascript/components/PageForm/Form.tsx +3 -9
  107. data/app/javascript/components/PageForm/Images.tsx +2 -4
  108. data/app/javascript/components/PageForm/LocaleLinks.tsx +4 -11
  109. data/app/javascript/components/PageForm/Metadata.tsx +8 -13
  110. data/app/javascript/components/PageForm/Options.tsx +28 -11
  111. data/app/javascript/components/PageForm/PageDescription.tsx +7 -14
  112. data/app/javascript/components/PageForm/PathSegment.tsx +5 -10
  113. data/app/javascript/components/PageForm/TabPanel.tsx +3 -6
  114. data/app/javascript/components/PageForm/Tabs.tsx +2 -4
  115. data/app/javascript/components/PageForm/UnconfiguredContent.tsx +7 -12
  116. data/app/javascript/components/PageForm/pageParams.ts +3 -2
  117. data/app/javascript/components/PageForm/usePage.ts +1 -46
  118. data/app/javascript/components/PageForm/usePageFormContext.ts +8 -0
  119. data/app/javascript/components/PageForm/useTabs.ts +1 -1
  120. data/app/javascript/components/PageForm/utils.ts +49 -0
  121. data/app/javascript/components/PageForm.tsx +52 -48
  122. data/app/javascript/components/PageImages.tsx +1 -3
  123. data/app/javascript/components/PageTree/Button.tsx +25 -0
  124. data/app/javascript/components/PageTree/CollapseArrow.tsx +34 -0
  125. data/app/javascript/components/PageTree/CollapsedLabel.tsx +21 -0
  126. data/app/javascript/components/PageTree/EditPageName.tsx +68 -0
  127. data/app/javascript/components/PageTree/Node.tsx +143 -413
  128. data/app/javascript/components/PageTree/PageName.tsx +6 -4
  129. data/app/javascript/components/PageTree/StatusLabel.tsx +10 -0
  130. data/app/javascript/components/PageTree/tree.ts +268 -0
  131. data/app/javascript/components/PageTree/usePageTree.ts +268 -0
  132. data/app/javascript/components/PageTree/usePageTreeContext.ts +13 -0
  133. data/app/javascript/components/PageTree.tsx +194 -214
  134. data/app/javascript/components/{RichTextToolbarButton.tsx → RichTextArea/ToolbarButton.tsx} +3 -5
  135. data/app/javascript/components/RichTextArea/actions.ts +106 -0
  136. data/app/javascript/components/RichTextArea/useMaybeControlledValue.ts +14 -0
  137. data/app/javascript/components/RichTextArea.tsx +91 -209
  138. data/app/javascript/components/TagEditor/AddTagForm.tsx +2 -2
  139. data/app/javascript/components/TagEditor/Editor.tsx +3 -5
  140. data/app/javascript/components/TagEditor/Tag.tsx +3 -5
  141. data/app/javascript/components/TagEditor/useTags.ts +7 -4
  142. data/app/javascript/components/TagEditor.tsx +2 -4
  143. data/app/javascript/components/Toast.tsx +5 -5
  144. data/app/javascript/components/drag/draggedOrder.ts +6 -6
  145. data/app/javascript/components/drag/useDragCollection.ts +21 -25
  146. data/app/javascript/components/drag/useDragUploader.ts +20 -18
  147. data/app/javascript/components/drag/useDraggable.ts +3 -3
  148. data/app/javascript/features/RichText.tsx +0 -1
  149. data/app/javascript/features/contentTabs.ts +2 -2
  150. data/app/javascript/stores/useModalStore.ts +1 -1
  151. data/app/javascript/stores/useToastStore.ts +2 -2
  152. data/app/javascript/types/Attachments.ts +11 -11
  153. data/app/javascript/types/Crop.ts +16 -12
  154. data/app/javascript/types/Drag.ts +21 -23
  155. data/app/javascript/types/Images.ts +8 -8
  156. data/app/javascript/types/PageEditor.ts +11 -4
  157. data/app/javascript/types/Pages.ts +22 -27
  158. data/app/javascript/types/Tags.ts +5 -6
  159. data/app/javascript/types/Template.ts +4 -4
  160. data/app/javascript/types.ts +2 -2
  161. data/app/models/attachment.rb +5 -9
  162. data/app/models/autopublisher.rb +1 -1
  163. data/app/models/concerns/pages_core/page_model/redirectable.rb +1 -2
  164. data/app/models/concerns/pages_core/page_model/searchable.rb +1 -1
  165. data/app/models/concerns/pages_core/page_model/status.rb +2 -4
  166. data/app/models/concerns/pages_core/searchable_document.rb +2 -4
  167. data/app/models/image.rb +0 -15
  168. data/app/models/page_builder.rb +4 -6
  169. data/app/resources/admin/page_resource.rb +2 -2
  170. data/app/resources/export/page_resource.rb +1 -1
  171. data/app/services/pages_core/invite_service.rb +1 -2
  172. data/app/views/layouts/admin.html.erb +1 -0
  173. data/app/views/pages_core/sitemaps/index.xml.builder +10 -0
  174. data/config/routes.rb +4 -3
  175. data/db/migrate/20240917142300_add_skip_index_to_pages.rb +7 -0
  176. data/lib/pages_core/engine.rb +15 -17
  177. data/lib/pages_core/sitemap.rb +58 -0
  178. data/lib/pages_core/templates/configuration_proxy.rb +3 -3
  179. data/lib/pages_core.rb +7 -4
  180. data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +2 -2
  181. data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +13 -5
  182. data/lib/rails/generators/pages_core/frontend/templates/postcss.config.js +2 -6
  183. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.css +3 -1
  184. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.css +2 -3
  185. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/animation.css +1 -1
  186. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.css +6 -5
  187. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/fonts.css +1 -1
  188. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/grid.css +9 -6
  189. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.css +42 -26
  190. data/lib/rails/generators/pages_core/install/templates/application_controller.rb +0 -6
  191. data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +1 -1
  192. metadata +81 -49
  193. data/app/assets/builds/fonts/7b7db107.woff2 +0 -0
  194. data/app/assets/builds/fonts/921961e9.woff2 +0 -0
  195. data/app/controller_dummies/admin/admin_controller.rb +0 -6
  196. data/app/controller_dummies/application_controller.rb +0 -6
  197. data/app/controller_dummies/attachments_controller.rb +0 -4
  198. data/app/controller_dummies/frontend_controller.rb +0 -4
  199. data/app/controller_dummies/images_controller.rb +0 -4
  200. data/app/controller_dummies/page_files_controller.rb +0 -4
  201. data/app/controller_dummies/pages_controller.rb +0 -4
  202. data/app/controller_dummies/sitemaps_controller.rb +0 -4
  203. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +0 -47
  204. data/app/controllers/concerns/pages_core/rss_controller.rb +0 -41
  205. data/app/controllers/pages_core/attachments_controller.rb +0 -42
  206. data/app/controllers/pages_core/frontend/page_files_controller.rb +0 -25
  207. data/app/controllers/pages_core/images_controller.rb +0 -15
  208. data/app/helpers/pages_core/meta_tags_helper.rb +0 -96
  209. data/app/helpers/pages_core/open_graph_tags_helper.rb +0 -49
  210. data/app/javascript/components/PageTree/Draggable.tsx +0 -338
  211. data/app/javascript/lib/Tree.ts +0 -305
  212. data/app/javascript/types/Trees.ts +0 -19
  213. data/app/views/sitemaps/show.xml.builder +0 -11
@@ -1,16 +1,8 @@
1
- import React from "react";
2
-
3
- import * as PageEditor from "../../types/PageEditor";
4
-
5
1
  import DateRangeSelect from "../DateRangeSelect";
2
+ import usePageFormContext from "./usePageFormContext";
6
3
 
7
- interface Props {
8
- state: PageEditor.State;
9
- dispatch: (action: PageEditor.Action) => void;
10
- }
11
-
12
- export default function Dates(props: Props) {
13
- const { state, dispatch } = props;
4
+ export default function Dates() {
5
+ const { state, dispatch } = usePageFormContext();
14
6
  const { datesEnabled, page } = state;
15
7
 
16
8
  const toggleAllDay = () => {
@@ -1,15 +1,13 @@
1
- import React from "react";
2
-
3
1
  import * as Attachments from "../../types/Attachments";
4
2
  import { Locale } from "../../types";
5
3
 
6
4
  import List from "../Attachments/List";
7
5
 
8
- interface Props {
6
+ type Props = {
9
7
  locale: string;
10
8
  locales: { [index: string]: Locale };
11
9
  state: Attachments.State;
12
- }
10
+ };
13
11
 
14
12
  export default function Files(props: Props) {
15
13
  const { locale, locales, state } = props;
@@ -1,12 +1,6 @@
1
- import React from "react";
2
-
3
1
  import { csrfToken } from "../../lib/request";
4
2
  import * as PageEditor from "../../types/PageEditor";
5
-
6
- interface FormProps {
7
- state: PageEditor.State;
8
- children: React.ReactNode;
9
- }
3
+ import usePageFormContext from "./usePageFormContext";
10
4
 
11
5
  function pageUrl(state: PageEditor.State): string {
12
6
  if (state.page.id) {
@@ -16,8 +10,8 @@ function pageUrl(state: PageEditor.State): string {
16
10
  }
17
11
  }
18
12
 
19
- export default function Form(props: FormProps) {
20
- const { state, children } = props;
13
+ export default function Form({ children }: React.PropsWithChildren) {
14
+ const { state } = usePageFormContext();
21
15
  const { page } = state;
22
16
 
23
17
  return (
@@ -1,15 +1,13 @@
1
- import React from "react";
2
-
3
1
  import { GridState } from "../../types/Images";
4
2
  import { Locale } from "../../types";
5
3
 
6
4
  import Grid from "../ImageGrid/Grid";
7
5
 
8
- interface Props {
6
+ type Props = {
9
7
  locale: string;
10
8
  locales: { [index: string]: Locale };
11
9
  state: GridState;
12
- }
10
+ };
13
11
 
14
12
  export default function Images(props: Props) {
15
13
  return (
@@ -1,14 +1,7 @@
1
- import React from "react";
1
+ import usePageFormContext from "./usePageFormContext";
2
2
 
3
- import * as PageEditor from "../../types/PageEditor";
4
-
5
- interface Props {
6
- state: PageEditor.State;
7
- dispatch: (action: PageEditor.Action) => void;
8
- }
9
-
10
- export default function LocaleLinks(props: Props) {
11
- const { state, dispatch } = props;
3
+ export default function LocaleLinks() {
4
+ const { state, dispatch } = usePageFormContext();
12
5
  const { locale, locales } = state;
13
6
 
14
7
  const handleClick = (newLocale: string) => (evt: React.MouseEvent) => {
@@ -17,7 +10,7 @@ export default function LocaleLinks(props: Props) {
17
10
  };
18
11
 
19
12
  if (!locales) {
20
- return "";
13
+ return;
21
14
  }
22
15
 
23
16
  return (
@@ -1,22 +1,17 @@
1
- import React from "react";
1
+ import { Fragment } from "react";
2
2
 
3
- import * as PageEditor from "../../types/PageEditor";
4
3
  import * as Pages from "../../types/Pages";
5
4
  import { MaybeLocalizedValue } from "../../types";
6
5
 
7
- import { blockValue, errorsOn } from "./usePage";
6
+ import { blockValue, errorsOn } from "./utils";
7
+ import usePageFormContext from "./usePageFormContext";
8
8
  import Block from "./Block";
9
9
  import PathSegment from "./PathSegment";
10
10
  import LabelledField from "../LabelledField";
11
11
  import ImageUploader from "../ImageUploader";
12
12
 
13
- interface Props {
14
- state: PageEditor.State;
15
- dispatch: (action: PageEditor.Action) => void;
16
- }
17
-
18
- export default function Metadata(props: Props) {
19
- const { state, dispatch } = props;
13
+ export default function Metadata() {
14
+ const { state, dispatch } = usePageFormContext();
20
15
 
21
16
  const { page, locale, locales, inputDir, templateConfig } = state;
22
17
 
@@ -29,8 +24,8 @@ export default function Metadata(props: Props) {
29
24
  };
30
25
 
31
26
  return (
32
- <React.Fragment>
33
- <PathSegment state={state} dispatch={dispatch} />
27
+ <Fragment>
28
+ <PathSegment />
34
29
  <LabelledField
35
30
  htmlFor="page_meta_image_id"
36
31
  label="Image"
@@ -62,6 +57,6 @@ export default function Metadata(props: Props) {
62
57
  value={blockValue(state, b)}
63
58
  />
64
59
  ))}
65
- </React.Fragment>
60
+ </Fragment>
66
61
  );
67
62
  }
@@ -1,20 +1,18 @@
1
- import React, { useState, ChangeEvent } from "react";
1
+ import { Fragment, useState, ChangeEvent } from "react";
2
2
 
3
- import * as PageEditor from "../../types/PageEditor";
4
3
  import * as Pages from "../../types/Pages";
5
4
  import LabelledField from "../LabelledField";
6
5
  import DateTimeSelect from "../DateTimeSelect";
7
- import { errorsOn } from "./usePage";
6
+ import { errorsOn } from "./utils";
7
+ import usePageFormContext from "./usePageFormContext";
8
8
 
9
- interface OptionsProps {
10
- state: PageEditor.State;
11
- dispatch: (action: PageEditor.Action) => void;
9
+ type Props = {
12
10
  authors: Pages.Author[];
13
11
  statuses: Pages.StatusLabels;
14
- }
12
+ };
15
13
 
16
- export default function Options(props: OptionsProps) {
17
- const { state, dispatch, authors, statuses } = props;
14
+ export default function Options({ authors, statuses }: Props) {
15
+ const { state, dispatch } = usePageFormContext();
18
16
 
19
17
  const { page, locale, templates } = state;
20
18
 
@@ -44,6 +42,10 @@ export default function Options(props: OptionsProps) {
44
42
  setShowAdvanced(!showAdvanced);
45
43
  };
46
44
 
45
+ const toggleSkipIndex = (evt: React.ChangeEvent<HTMLInputElement>) => {
46
+ dispatch({ type: "update", payload: { skip_index: evt.target.checked } });
47
+ };
48
+
47
49
  return (
48
50
  <div className="page-options">
49
51
  <LabelledField
@@ -123,7 +125,7 @@ export default function Options(props: OptionsProps) {
123
125
  </a>
124
126
  </p>
125
127
  {showAdvanced && (
126
- <React.Fragment>
128
+ <Fragment>
127
129
  <LabelledField label="Subpages">
128
130
  <label className="check-box">
129
131
  <input
@@ -144,6 +146,21 @@ export default function Options(props: OptionsProps) {
144
146
  Show in news
145
147
  </label>
146
148
  </LabelledField>
149
+ <LabelledField
150
+ htmlFor="page_skip_index"
151
+ label="Search"
152
+ errors={errorsOn(page, "skip_index")}>
153
+ <label className="check-box">
154
+ <input
155
+ id="page_skip_index"
156
+ name="page[skip_index]"
157
+ type="checkbox"
158
+ checked={page.skip_index}
159
+ onChange={toggleSkipIndex}
160
+ />{" "}
161
+ Disable search indexing
162
+ </label>
163
+ </LabelledField>
147
164
  <LabelledField
148
165
  htmlFor="page_unique_name"
149
166
  label="Unique name"
@@ -168,7 +185,7 @@ export default function Options(props: OptionsProps) {
168
185
  onChange={handleChange("redirect_to")}
169
186
  />
170
187
  </LabelledField>
171
- </React.Fragment>
188
+ </Fragment>
172
189
  )}
173
190
  {url && (
174
191
  <LabelledField label="Page link">
@@ -1,16 +1,9 @@
1
- import React from "react";
2
-
3
- import * as PageEditor from "../../types/PageEditor";
1
+ import { Fragment } from "react";
4
2
  import * as Pages from "../../types/Pages";
3
+ import usePageFormContext from "./usePageFormContext";
5
4
 
6
5
  import LocaleLinks from "./LocaleLinks";
7
6
 
8
- interface PageDescriptionProps {
9
- state: PageEditor.State;
10
- dispatch: (action: PageEditor.Action) => void;
11
- children: React.ReactNode;
12
- }
13
-
14
7
  function editLink(locale: string, page: Pages.Ancestor | Pages.Resource) {
15
8
  return (
16
9
  <a href={`/admin/${locale}/pages/${page.id}/edit`}>
@@ -26,19 +19,19 @@ function pageName(locale: string, page: Pages.Ancestor | Pages.Resource) {
26
19
  return page.blocks.name[locale] || <i>Untitled</i>;
27
20
  }
28
21
 
29
- export default function PageDescription(props: PageDescriptionProps) {
30
- const { state, dispatch, children } = props;
22
+ export default function PageDescription({ children }: React.PropsWithChildren) {
23
+ const { state } = usePageFormContext();
31
24
  const { locale, page } = state;
32
25
 
33
26
  return (
34
27
  <div className="page-description with_content_tabs">
35
- <LocaleLinks state={state} dispatch={dispatch} />
28
+ <LocaleLinks />
36
29
  <h3>
37
30
  {page.ancestors.map((p) => (
38
- <React.Fragment key={p.id}>
31
+ <Fragment key={p.id}>
39
32
  {editLink(locale, p)}
40
33
  {" » "}
41
- </React.Fragment>
34
+ </Fragment>
42
35
  ))}
43
36
  {page.id ? editLink(locale, page) : "New Page"}
44
37
  </h3>
@@ -1,17 +1,12 @@
1
- import React, { ChangeEvent } from "react";
1
+ import { ChangeEvent } from "react";
2
2
 
3
- import * as PageEditor from "../../types/PageEditor";
4
3
  import * as Pages from "../../types/Pages";
5
4
  import { LocalizedValue } from "../../types";
6
5
 
7
- import { errorsOn } from "./usePage";
6
+ import { errorsOn } from "./utils";
7
+ import usePageFormContext from "./usePageFormContext";
8
8
  import LabelledField from "../LabelledField";
9
9
 
10
- interface Props {
11
- state: PageEditor.State;
12
- dispatch: (action: PageEditor.Action) => void;
13
- }
14
-
15
10
  function missingPathSegment(ancestors: Pages.Ancestor[], locale: string) {
16
11
  for (let i = 0; i < ancestors.length; i++) {
17
12
  if (!ancestors[i].path_segment[locale]) {
@@ -21,8 +16,8 @@ function missingPathSegment(ancestors: Pages.Ancestor[], locale: string) {
21
16
  return null;
22
17
  }
23
18
 
24
- export default function PathSegment(props: Props) {
25
- const { state, dispatch } = props;
19
+ export default function PathSegment() {
20
+ const { state, dispatch } = usePageFormContext();
26
21
  const { page, locale } = state;
27
22
 
28
23
  const value = (page.path_segment as LocalizedValue)[locale];
@@ -1,11 +1,8 @@
1
- import React from "react";
2
-
3
- interface TabPanelProps {
1
+ type Props = {
4
2
  active: boolean;
5
- children: React.ReactNode;
6
- }
3
+ };
7
4
 
8
- export default function TabPanel(props: TabPanelProps) {
5
+ export default function TabPanel(props: React.PropsWithChildren<Props>) {
9
6
  const { active, children } = props;
10
7
 
11
8
  const classNames = ["content-tab"];
@@ -1,12 +1,10 @@
1
- import React from "react";
2
-
3
1
  import * as PageEditor from "../../types/PageEditor";
4
2
 
5
- interface Props {
3
+ type Props = {
6
4
  tab: string;
7
5
  tabs: PageEditor.Tab[];
8
6
  setTab: (tab: string) => void;
9
- }
7
+ };
10
8
 
11
9
  export default function Tabs(props: Props) {
12
10
  const { tab, tabs, setTab } = props;
@@ -1,18 +1,13 @@
1
- import React from "react";
1
+ import { Fragment } from "react";
2
2
 
3
- import * as PageEditor from "../../types/PageEditor";
4
3
  import { MaybeLocalizedValue } from "../../types";
5
- import { blockValue, errorsOn, unconfiguredBlocks } from "./usePage";
4
+ import { blockValue, errorsOn, unconfiguredBlocks } from "./utils";
5
+ import usePageFormContext from "./usePageFormContext";
6
6
 
7
7
  import Block from "./Block";
8
8
 
9
- interface Props {
10
- state: PageEditor.State;
11
- dispatch: (action: PageEditor.Action) => void;
12
- }
13
-
14
- export default function UnconfiguredContent(props: Props) {
15
- const { state, dispatch } = props;
9
+ export default function UnconfiguredContent() {
10
+ const { state, dispatch } = usePageFormContext();
16
11
 
17
12
  const { page, locale, inputDir } = state;
18
13
 
@@ -21,7 +16,7 @@ export default function UnconfiguredContent(props: Props) {
21
16
  };
22
17
 
23
18
  return (
24
- <React.Fragment>
19
+ <Fragment>
25
20
  <p>
26
21
  This page has additional content fields not enabled by the selected
27
22
  template.
@@ -37,6 +32,6 @@ export default function UnconfiguredContent(props: Props) {
37
32
  value={blockValue(state, b)}
38
33
  />
39
34
  ))}
40
- </React.Fragment>
35
+ </Fragment>
41
36
  );
42
37
  }
@@ -4,11 +4,11 @@ import * as PageEditor from "../../types/PageEditor";
4
4
  import * as Images from "../../types/Images";
5
5
  import * as Tags from "../../types/Tags";
6
6
 
7
- interface Options {
7
+ type Options = {
8
8
  files: Attachments.State;
9
9
  images: Images.GridState;
10
10
  tags: Tags.State;
11
- }
11
+ };
12
12
 
13
13
  function dates(state: PageEditor.State) {
14
14
  if (state.datesEnabled) {
@@ -89,6 +89,7 @@ export default function pageParams(state: PageEditor.State, options: Options) {
89
89
  path_segment: page.path_segment,
90
90
  meta_image_id: page.meta_image.image && page.meta_image.image.id,
91
91
  parent_page_id: page.parent_page_id,
92
+ skip_index: page.skip_index,
92
93
  page_files_attributes: pageFiles(files),
93
94
  page_images_attributes: pageImages(images)
94
95
  };
@@ -5,51 +5,6 @@ import * as Pages from "../../types/Pages";
5
5
  import * as Template from "../../types/Template";
6
6
  import { LocalizedValue, MaybeLocalizedValue } from "../../types";
7
7
 
8
- export function blockValue(
9
- state: PageEditor.State,
10
- block: Template.Block
11
- ): string {
12
- if (block.localized) {
13
- const value: LocalizedValue =
14
- (state.page.blocks[block.name] as LocalizedValue) || {};
15
-
16
- return value[state.locale] || "";
17
- } else {
18
- return (state.page.blocks[block.name] as string) || "";
19
- }
20
- }
21
-
22
- export function errorsOn(page: Pages.Resource, attribute: string): string[] {
23
- return page.errors
24
- .filter((e) => e.attribute === attribute)
25
- .map((e) => e.message);
26
- }
27
-
28
- export function unconfiguredBlocks(state: PageEditor.State): Template.Block[] {
29
- const allBlocks: Record<string, Template.Block> = state.templates
30
- .flatMap((t) => t.blocks)
31
- .reduce((bs, b) => ({ [b.name]: b, ...bs }), {});
32
-
33
- const anyValue = (v: MaybeLocalizedValue) => {
34
- if (typeof v === "string") {
35
- return v ? true : false;
36
- } else {
37
- return Object.values(v).filter((v) => v).length > 0;
38
- }
39
- };
40
-
41
- const hasValue = Object.keys(allBlocks).filter((k) => {
42
- const value = state.page.blocks[k] || "";
43
- return anyValue(value);
44
- });
45
-
46
- const enabled = state.templateConfig.blocks.map((b) => b.name);
47
-
48
- return hasValue
49
- .filter((b) => enabled.indexOf(b) === -1)
50
- .map((n) => allBlocks[n]);
51
- }
52
-
53
8
  function parseDate(str: string): Date | null {
54
9
  if (!str) {
55
10
  return null;
@@ -163,7 +118,7 @@ function updatePage(
163
118
 
164
119
  export default function usePage(
165
120
  initialState: PageEditor.State<Pages.SerializedResource>
166
- ): [PageEditor.State, (action: PageEditor.Action) => void] {
121
+ ): PageEditor.Return {
167
122
  const [state, dispatch] = useReducer(reducer, prepare(initialState));
168
123
  return [derivedState(state), dispatch];
169
124
  }
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from "react";
2
+ import * as PageEditor from "../../types/PageEditor";
3
+
4
+ export const PageFormContext = createContext<PageEditor.Context>(null);
5
+
6
+ export default function usePageFormContext() {
7
+ return useContext(PageFormContext);
8
+ }
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
 
3
3
  import * as PageEditor from "../../types/PageEditor";
4
- import { unconfiguredBlocks } from "./usePage";
4
+ import { unconfiguredBlocks } from "./utils";
5
5
 
6
6
  function tabsList(state: PageEditor.State): PageEditor.Tab[] {
7
7
  const { templates, templateConfig } = state;
@@ -0,0 +1,49 @@
1
+ import * as PageEditor from "../../types/PageEditor";
2
+ import * as Pages from "../../types/Pages";
3
+ import * as Template from "../../types/Template";
4
+ import { LocalizedValue, MaybeLocalizedValue } from "../../types";
5
+
6
+ export function blockValue(
7
+ state: PageEditor.State,
8
+ block: Template.Block
9
+ ): string {
10
+ if (block.localized) {
11
+ const value: LocalizedValue =
12
+ (state.page.blocks[block.name] as LocalizedValue) || {};
13
+
14
+ return value[state.locale] || "";
15
+ } else {
16
+ return (state.page.blocks[block.name] as string) || "";
17
+ }
18
+ }
19
+
20
+ export function errorsOn(page: Pages.Resource, attribute: string): string[] {
21
+ return page.errors
22
+ .filter((e) => e.attribute === attribute)
23
+ .map((e) => e.message);
24
+ }
25
+
26
+ export function unconfiguredBlocks(state: PageEditor.State): Template.Block[] {
27
+ const allBlocks: Record<string, Template.Block> = state.templates
28
+ .flatMap((t) => t.blocks)
29
+ .reduce((bs, b) => ({ [b.name]: b, ...bs }), {});
30
+
31
+ const anyValue = (v: MaybeLocalizedValue) => {
32
+ if (typeof v === "string") {
33
+ return v ? true : false;
34
+ } else {
35
+ return Object.values(v).filter((v) => v).length > 0;
36
+ }
37
+ };
38
+
39
+ const hasValue = Object.keys(allBlocks).filter((k) => {
40
+ const value = state.page.blocks[k] || "";
41
+ return anyValue(value);
42
+ });
43
+
44
+ const enabled = state.templateConfig.blocks.map((b) => b.name);
45
+
46
+ return hasValue
47
+ .filter((b) => enabled.indexOf(b) === -1)
48
+ .map((n) => allBlocks[n]);
49
+ }