pages_core 3.12.0 → 3.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/assets/builds/fonts/661557ef.ttf +0 -0
  4. data/app/assets/builds/fonts/a18fc2d2.woff2 +0 -0
  5. data/app/assets/builds/fonts/b2c7b78f.woff2 +0 -0
  6. data/app/assets/builds/fonts/ceddc204.ttf +0 -0
  7. data/app/assets/builds/pages_core/admin-dist.js +60 -14
  8. data/app/assets/builds/pages_core/admin-dist.js.map +7 -0
  9. data/app/assets/builds/pages_core/admin.css +9272 -0
  10. data/app/assets/images/pages/admin/angle-down-solid.svg +1 -0
  11. data/app/assets/images/pages/admin/icon.svg +1 -0
  12. data/app/assets/stylesheets/pages_core/admin/components/archive.css +6 -0
  13. data/app/assets/stylesheets/{pages/admin/components/attachments.scss → pages_core/admin/components/attachments.css} +35 -28
  14. data/app/assets/stylesheets/{pages/admin.scss → pages_core/admin/components/base.css} +125 -123
  15. data/app/assets/stylesheets/pages_core/admin/components/forms.css +223 -0
  16. data/app/assets/stylesheets/{pages/admin/components/header.scss → pages_core/admin/components/header.css} +76 -46
  17. data/app/assets/stylesheets/{pages/admin/components/image_editor.scss → pages_core/admin/components/image_editor.css} +42 -31
  18. data/app/assets/stylesheets/{pages/admin/components/image_grid.scss → pages_core/admin/components/image_grid.css} +76 -64
  19. data/app/assets/stylesheets/{pages/admin/components/image_uploader.scss → pages_core/admin/components/image_uploader.css} +12 -12
  20. data/app/assets/stylesheets/{pages/admin/components/layout.scss → pages_core/admin/components/layout.css} +13 -9
  21. data/app/assets/stylesheets/pages_core/admin/components/links.css +40 -0
  22. data/app/assets/stylesheets/pages_core/admin/components/list_table.css +66 -0
  23. data/app/assets/stylesheets/{pages/admin/components/login.scss → pages_core/admin/components/login.css} +6 -5
  24. data/app/assets/stylesheets/{pages/admin/components/modal.scss → pages_core/admin/components/modal.css} +10 -12
  25. data/app/assets/stylesheets/{pages/admin/components/page_tree.scss → pages_core/admin/components/page_tree.css} +54 -55
  26. data/app/assets/stylesheets/{pages/admin/components/pagination.scss → pages_core/admin/components/pagination.css} +17 -17
  27. data/app/assets/stylesheets/pages_core/admin/components/search.css +27 -0
  28. data/app/assets/stylesheets/{pages/admin/components/sidebar.scss → pages_core/admin/components/sidebar.css} +8 -7
  29. data/app/assets/stylesheets/{pages/admin/components/tag_editor.scss → pages_core/admin/components/tag_editor.css} +10 -15
  30. data/app/assets/stylesheets/{pages/admin/components/textarea.scss → pages_core/admin/components/textarea.css} +1 -1
  31. data/app/assets/stylesheets/{pages/admin/components/toast.scss → pages_core/admin/components/toast.css} +5 -3
  32. data/app/assets/stylesheets/{pages/admin/components/toolbar.scss → pages_core/admin/components/toolbar.css} +56 -29
  33. data/app/assets/stylesheets/{pages/admin/controllers/pages.scss → pages_core/admin/controllers/pages.css} +69 -52
  34. data/app/assets/stylesheets/pages_core/admin/controllers/users.css +3 -0
  35. data/app/assets/stylesheets/pages_core/admin/vars.css +34 -0
  36. data/app/assets/stylesheets/pages_core/admin.postcss.css +9 -0
  37. data/app/controllers/admin/pages_controller.rb +12 -11
  38. data/app/controllers/concerns/pages_core/rss_controller.rb +17 -1
  39. data/app/controllers/pages_core/admin_controller.rb +6 -0
  40. data/app/controllers/pages_core/frontend/pages_controller.rb +9 -5
  41. data/app/controllers/pages_core/sitemaps_controller.rb +3 -5
  42. data/app/formatters/pages_core/image_embedder.rb +5 -27
  43. data/app/helpers/admin/calendars_helper.rb +8 -0
  44. data/app/helpers/admin/news_helper.rb +13 -0
  45. data/app/helpers/admin/pages_helper.rb +32 -0
  46. data/app/helpers/pages_core/admin/admin_helper.rb +11 -54
  47. data/app/helpers/pages_core/admin/deprecated_admin_helper.rb +40 -0
  48. data/app/helpers/pages_core/images_helper.rb +37 -0
  49. data/app/javascript/admin-dist.ts +2 -0
  50. data/app/javascript/components/Attachments/{Attachment.jsx → Attachment.tsx} +44 -35
  51. data/app/javascript/components/Attachments/{AttachmentEditor.jsx → AttachmentEditor.tsx} +23 -23
  52. data/app/javascript/components/{EditableImage.jsx → EditableImage.tsx} +28 -25
  53. data/app/javascript/components/{FileUploadButton.jsx → FileUploadButton.tsx} +15 -16
  54. data/app/javascript/components/ImageCropper/FocalPoint.tsx +94 -0
  55. data/app/javascript/components/ImageCropper/{Image.jsx → Image.tsx} +13 -14
  56. data/app/javascript/components/ImageCropper/{Toolbar.jsx → Toolbar.tsx} +19 -15
  57. data/app/javascript/components/ImageCropper/{useCrop.js → useCrop.ts} +80 -37
  58. data/app/javascript/components/{ImageCropper.jsx → ImageCropper.tsx} +17 -15
  59. data/app/javascript/components/ImageEditor/{Form.jsx → Form.tsx} +24 -23
  60. data/app/javascript/components/{ImageEditor.jsx → ImageEditor.tsx} +17 -15
  61. data/app/javascript/components/ImageGrid/{DragElement.jsx → DragElement.tsx} +12 -10
  62. data/app/javascript/components/ImageGrid/{GridImage.jsx → GridImage.tsx} +40 -30
  63. data/app/javascript/components/ImageGrid/{Placeholder.jsx → Placeholder.tsx} +5 -6
  64. data/app/javascript/components/ImageGrid.jsx +3 -4
  65. data/app/javascript/components/{ImageUploader.jsx → ImageUploader.tsx} +46 -41
  66. data/app/javascript/components/Modal.tsx +48 -0
  67. data/app/javascript/components/PageImages.tsx +28 -0
  68. data/app/javascript/components/{PageTreeDraggable.jsx → PageTree/Draggable.tsx} +79 -57
  69. data/app/javascript/components/{PageTreeNode.jsx → PageTree/Node.tsx} +86 -77
  70. data/app/javascript/components/PageTree/types.ts +15 -0
  71. data/app/javascript/components/PageTree.tsx +206 -0
  72. data/app/javascript/components/RichTextToolbarButton.tsx +17 -0
  73. data/app/javascript/components/TagEditor/{AddTagForm.jsx → AddTagForm.tsx} +9 -10
  74. data/app/javascript/components/TagEditor/{Tag.jsx → Tag.tsx} +8 -9
  75. data/app/javascript/components/{TagEditor.jsx → TagEditor.tsx} +12 -13
  76. data/app/javascript/components/Toast.tsx +61 -0
  77. data/app/javascript/components/drag/{draggedOrder.js → draggedOrder.ts} +22 -12
  78. data/app/javascript/components/drag/types.ts +28 -0
  79. data/app/javascript/components/drag/{useDragCollection.js → useDragCollection.ts} +40 -22
  80. data/app/javascript/components/drag/{useDragUploader.js → useDragUploader.ts} +34 -25
  81. data/app/javascript/components/drag/useDraggable.ts +21 -0
  82. data/app/javascript/components/{drag.js → drag.ts} +1 -0
  83. data/app/javascript/controllers/{EditPageController.js → EditPageController.ts} +3 -1
  84. data/app/javascript/controllers/{LoginController.js → LoginController.ts} +7 -3
  85. data/app/javascript/controllers/{MainController.js → MainController.ts} +19 -14
  86. data/app/javascript/{index.js → index.ts} +8 -7
  87. data/app/javascript/lib/{Tree.js → Tree.ts} +106 -85
  88. data/app/javascript/lib/{copyToClipboard.js → copyToClipboard.ts} +1 -1
  89. data/app/javascript/lib/{readyHandler.js → readyHandler.ts} +4 -2
  90. data/app/javascript/lib/{request.js → request.ts} +11 -5
  91. data/app/javascript/stores/useModalStore.ts +15 -0
  92. data/app/javascript/stores/useToastStore.ts +26 -0
  93. data/app/javascript/stores.ts +2 -0
  94. data/app/javascript/types.ts +30 -0
  95. data/app/mailers/admin_mailer.rb +1 -0
  96. data/app/models/invite.rb +8 -0
  97. data/app/policies/page_policy.rb +4 -0
  98. data/app/views/admin/calendars/_sidebar.html.erb +50 -0
  99. data/app/views/admin/calendars/show.html.erb +15 -53
  100. data/app/views/admin/invites/new.html.erb +2 -8
  101. data/app/views/admin/invites/show.html.erb +2 -4
  102. data/app/views/admin/news/_sidebar.html.erb +51 -0
  103. data/app/views/admin/news/index.html.erb +21 -56
  104. data/app/views/admin/pages/_list_item.html.erb +4 -22
  105. data/app/views/admin/pages/_search_bar.html.erb +12 -0
  106. data/app/views/admin/pages/deleted.html.erb +10 -8
  107. data/app/views/admin/pages/edit.html.erb +20 -11
  108. data/app/views/admin/pages/index.html.erb +10 -8
  109. data/app/views/admin/pages/new.html.erb +10 -14
  110. data/app/views/admin/pages/search.html.erb +54 -0
  111. data/app/views/admin/password_resets/show.html.erb +3 -5
  112. data/app/views/admin/users/deactivated.html.erb +6 -7
  113. data/app/views/admin/users/edit.html.erb +7 -9
  114. data/app/views/admin/users/index.html.erb +3 -6
  115. data/app/views/admin/users/login.html.erb +4 -5
  116. data/app/views/admin/users/new.html.erb +2 -4
  117. data/app/views/admin/users/new_password.html.erb +4 -5
  118. data/app/views/admin/users/show.html.erb +11 -9
  119. data/app/views/errors/401.html.erb +2 -1
  120. data/app/views/errors/403.html.erb +2 -1
  121. data/app/views/errors/404.html.erb +1 -3
  122. data/app/views/errors/405.html.erb +2 -1
  123. data/app/views/errors/422.html.erb +2 -1
  124. data/app/views/errors/500.html.erb +2 -3
  125. data/app/views/feeds/pages.rss.builder +3 -9
  126. data/app/views/layouts/admin/_header.html.erb +1 -2
  127. data/app/views/layouts/admin/_page_header.html.erb +4 -4
  128. data/app/views/layouts/admin.html.erb +3 -3
  129. data/app/views/layouts/errors.html.erb +127 -4
  130. data/config/routes.rb +1 -0
  131. data/lib/pages_core/configuration/pages.rb +0 -1
  132. data/lib/pages_core/engine.rb +4 -3
  133. data/lib/pages_core.rb +0 -1
  134. data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +33 -17
  135. data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +0 -1
  136. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +40 -0
  137. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +68 -0
  138. data/lib/rails/generators/pages_core/frontend/templates/postcss.config.js +17 -0
  139. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.postcss.css +4 -0
  140. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.css +24 -0
  141. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/layout.css +21 -0
  142. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.css +5 -0
  143. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/animation.css +5 -0
  144. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.css +18 -0
  145. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/fonts.css +6 -0
  146. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/grid.css +65 -0
  147. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.css +131 -0
  148. data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +0 -3
  149. metadata +104 -255
  150. data/app/assets/images/pages/admin/icon.png +0 -0
  151. data/app/assets/images/pages/admin/image-editor-bg.png +0 -0
  152. data/app/assets/images/pages/admin/list-table-pin-blue.gif +0 -0
  153. data/app/assets/images/pages/admin/list-table-pin-disabled.gif +0 -0
  154. data/app/assets/images/pages/admin/list-table-pin-green.gif +0 -0
  155. data/app/assets/images/pages/admin/list-table-pin-red.gif +0 -0
  156. data/app/assets/images/pages/admin/list-table-pin-yellow.gif +0 -0
  157. data/app/assets/images/pages/admin/loading-modal.gif +0 -0
  158. data/app/assets/images/pages/feed-icon-14x14.png +0 -0
  159. data/app/assets/stylesheets/pages/admin/components/archive.scss +0 -6
  160. data/app/assets/stylesheets/pages/admin/components/buttons.scss +0 -23
  161. data/app/assets/stylesheets/pages/admin/components/forms.scss +0 -169
  162. data/app/assets/stylesheets/pages/admin/components/links.scss +0 -43
  163. data/app/assets/stylesheets/pages/admin/components/list_table.scss +0 -61
  164. data/app/assets/stylesheets/pages/admin/controllers/users.scss +0 -3
  165. data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +0 -21
  166. data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +0 -7
  167. data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +0 -7
  168. data/app/assets/stylesheets/pages/admin/vars.scss +0 -30
  169. data/app/assets/stylesheets/pages/errors.css +0 -128
  170. data/app/javascript/admin-dist.js +0 -2
  171. data/app/javascript/components/ImageCropper/FocalPoint.jsx +0 -93
  172. data/app/javascript/components/Modal.jsx +0 -59
  173. data/app/javascript/components/PageImages.jsx +0 -25
  174. data/app/javascript/components/PageTree.jsx +0 -196
  175. data/app/javascript/components/RichTextToolbarButton.jsx +0 -20
  176. data/app/javascript/components/Toast.jsx +0 -72
  177. data/app/javascript/components/drag/useDraggable.js +0 -17
  178. data/app/javascript/stores/ModalStore.jsx +0 -12
  179. data/app/javascript/stores/ToastStore.jsx +0 -14
  180. data/app/javascript/stores.js +0 -2
  181. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/GridOverlay.js +0 -66
  182. data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/ResponsiveEmbeds.js +0 -72
  183. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.sass.scss +0 -15
  184. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.scss +0 -12
  185. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.scss +0 -26
  186. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/breakpoints.scss +0 -42
  187. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/clearfix.scss +0 -7
  188. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/fonts.scss +0 -32
  189. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid.scss +0 -168
  190. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid_overlay.scss +0 -44
  191. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.scss +0 -8
  192. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.scss +0 -90
  193. data/lib/rails/generators/pages_core/frontend/templates/stylesheets/vendor/normalize.css +0 -349
  194. data/vendor/assets/stylesheets/ReactCrop.css +0 -167
  195. /data/app/assets/stylesheets/{pages/admin/components/tabs.scss → pages_core/admin/components/tabs.css} +0 -0
  196. /data/app/javascript/components/Attachments/{Placeholder.jsx → Placeholder.tsx} +0 -0
  197. /data/app/javascript/components/ImageGrid/{FilePlaceholder.jsx → FilePlaceholder.tsx} +0 -0
  198. /data/app/javascript/{components.js → components.ts} +0 -0
  199. /data/app/javascript/{hooks.js → hooks.ts} +0 -0
@@ -25,19 +25,54 @@
25
25
  SOFTWARE.
26
26
  */
27
27
 
28
- import React from "react";
29
- import PropTypes from "prop-types";
30
- import PageTreeNode from "./PageTreeNode";
28
+ import React, { Component } from "react";
29
+ import Tree, { TreeId, TreeIndex } from "../../lib/Tree";
30
+ import { Attributes, PageNode } from "./types";
31
+ import Node from "./Node";
32
+
33
+ interface DragState {
34
+ id: number | null,
35
+ x: number | null,
36
+ y: number | null,
37
+ w: number | null,
38
+ h: number | null,
39
+ scrollTop: number | null,
40
+ scrollLeft: number | null
41
+ }
42
+
43
+ interface DraggableProps {
44
+ addChild: (index: TreeIndex) => void,
45
+ dir: string,
46
+ locale: string,
47
+ movedPage: (id: TreeId) => void,
48
+ paddingLeft: number,
49
+ toggleCollapsed: (id: TreeId) => void,
50
+ tree: Tree<PageNode>,
51
+ updatePage: (id: TreeId, attributes: Attributes) => void,
52
+ updateTree: (Tree) => void
53
+ }
54
+
55
+ interface DraggableState {
56
+ dragging: DragState
57
+ }
58
+
59
+ export default class Draggable extends Component<DraggableProps, DraggableState> {
60
+ _dragListener: (evt: MouseEvent) => void;
61
+ _dragEndListener: () => void;
62
+ _startX: number;
63
+ _startY: number;
64
+ _offsetX: number;
65
+ _offsetY: number;
66
+ dragging: DragState;
31
67
 
32
- export default class PageTreeDraggable extends React.Component {
33
- constructor(props) {
68
+ constructor(props: DraggableProps) {
34
69
  super(props);
35
70
  this.state = {
36
71
  dragging: this.initDragging()
37
72
  };
38
73
  }
39
74
 
40
- initDragging() {
75
+ initDragging(): DragState {
41
76
  return {
42
77
  id: null,
43
78
  x: null,
@@ -50,11 +85,11 @@ export default class PageTreeDraggable extends React.Component {
50
85
  }
51
86
 
52
87
  getDraggingDom() {
53
- var tree = this.props.tree;
54
- var dragging = this.state.dragging;
88
+ const tree = this.props.tree;
89
+ const dragging = this.state.dragging;
55
90
  if (dragging && dragging.id) {
56
- var draggingIndex = tree.getIndex(dragging.id);
57
- var draggingStyles = {
91
+ const draggingIndex = tree.getIndex(dragging.id);
92
+ const draggingStyles = {
58
93
  top: dragging.y,
59
94
  left: dragging.x,
60
95
  width: dragging.w
@@ -62,7 +97,7 @@ export default class PageTreeDraggable extends React.Component {
62
97
 
63
98
  return (
64
99
  <div className="draggable" style={draggingStyles}>
65
- <PageTreeNode
100
+ <Node
66
101
  tree={tree}
67
102
  index={draggingIndex}
68
103
  paddingLeft={this.props.paddingLeft}
@@ -76,7 +111,7 @@ export default class PageTreeDraggable extends React.Component {
76
111
 
77
112
  render() {
78
113
  const { tree, dir, locale } = this.props;
79
- var dragging = this.state.dragging;
114
+ const dragging = this.state.dragging;
80
115
 
81
116
  if (!tree) {
82
117
  return (
@@ -85,11 +120,11 @@ export default class PageTreeDraggable extends React.Component {
85
120
  </div>
86
121
  );
87
122
  } else {
88
- var root = tree.getIndex(1);
123
+ const root = tree.getIndex(1);
89
124
  return (
90
125
  <div className="page-tree">
91
126
  {this.getDraggingDom()}
92
- <PageTreeNode
127
+ <Node
93
128
  tree={tree}
94
129
  index={root}
95
130
  key={root.id}
@@ -106,8 +141,8 @@ export default class PageTreeDraggable extends React.Component {
106
141
  }
107
142
  }
108
143
 
109
- addChild(parent) {
110
- let newNode = {
144
+ addChild(parent: TreeIndex<PageNode>) {
145
+ const newNode = {
111
146
  name: "",
112
147
  status: 0,
113
148
  editing: true,
@@ -120,9 +155,9 @@ export default class PageTreeDraggable extends React.Component {
120
155
  this.props.addChild(parent.id, newNode);
121
156
  }
122
157
 
123
- prevAddButtonCount(tree, index) {
158
+ prevAddButtonCount(tree: Tree, index: TreeIndex) {
124
159
  let count = 0;
125
- let parentNodes = [];
160
+ const parentNodes = [];
126
161
  let pointer = tree.getIndex(index.parent);
127
162
  while (pointer) {
128
163
  parentNodes.push(pointer);
@@ -147,16 +182,16 @@ export default class PageTreeDraggable extends React.Component {
147
182
  }
148
183
 
149
184
  scrollOffset() {
150
- let dragging = this.state.dragging;
185
+ const dragging = this.state.dragging;
151
186
  return {
152
187
  top: document.body.scrollTop - dragging.scrollTop,
153
188
  left: document.body.scrollLeft - dragging.scrollLeft
154
189
  };
155
190
  }
156
191
 
157
- drag(e) {
192
+ drag(e: MouseEvent) {
158
193
  if (this._start) {
159
- var distance = Math.abs(e.clientX - this._offsetX) +
194
+ const distance = Math.abs(e.clientX - this._offsetX) +
160
195
  Math.abs(e.clientY - this._offsetY);
161
196
  if (distance >= 15) {
162
197
  this.setState({
@@ -168,27 +203,27 @@ export default class PageTreeDraggable extends React.Component {
168
203
  }
169
204
  }
170
205
 
171
- var tree = this.props.tree;
172
- var dragging = this.state.dragging;
173
- var paddingLeft = this.props.paddingLeft;
174
- var newIndex = null;
175
- var index = tree.getIndex(dragging.id);
176
- var collapsed = index.node.collapsed;
206
+ const tree = this.props.tree;
207
+ const dragging = this.state.dragging;
208
+ const paddingLeft = this.props.paddingLeft;
209
+ let newIndex: TreeIndex = null;
210
+ let index = tree.getIndex(dragging.id);
211
+ const collapsed = index.node.collapsed;
177
212
 
178
- var _startX = this._startX;
179
- var _startY = this._startY;
180
- var _offsetX = this._offsetX;
181
- var _offsetY = this._offsetY;
213
+ const _startX = this._startX;
214
+ const _startY = this._startY;
215
+ const _offsetX = this._offsetX;
216
+ const _offsetY = this._offsetY;
182
217
 
183
- var pos = {
218
+ const pos = {
184
219
  x: _startX + e.clientX - _offsetX + this.scrollOffset().left,
185
220
  y: _startY + e.clientY - _offsetY + this.scrollOffset().top
186
221
  };
187
222
  dragging.x = pos.x;
188
223
  dragging.y = pos.y;
189
224
 
190
- var diffX = dragging.x - paddingLeft/2 - (index.left-2) * paddingLeft;
191
- var diffY = dragging.y - dragging.h/2 - (index.top-2 + this.prevAddButtonCount(tree, index)) * dragging.h;
225
+ const diffX = dragging.x - paddingLeft/2 - (index.left-2) * paddingLeft;
226
+ const diffY = dragging.y - dragging.h/2 - (index.top-2 + this.prevAddButtonCount(tree, index)) * dragging.h;
192
227
 
193
228
  if (diffX < 0) {
194
229
  // left
@@ -197,8 +232,8 @@ export default class PageTreeDraggable extends React.Component {
197
232
  }
198
233
  } else if (diffX > paddingLeft) {
199
234
  // right
200
- if (index.prev) {
201
- var prev = tree.getIndex(index.prev);
235
+ if ("prev" in index) {
236
+ const prev = tree.getIndex(index.prev);
202
237
 
203
238
  if (!prev.node.leaf && !prev.node.collapsed) {
204
239
  newIndex = tree.move(index.id, index.prev, "append");
@@ -214,11 +249,11 @@ export default class PageTreeDraggable extends React.Component {
214
249
 
215
250
  if (diffY < (0 - dragging.h * 0.5)) {
216
251
  // up
217
- var above = tree.getNodeByTop(index.top-1);
252
+ const above = tree.getNodeByTop(index.top-1);
218
253
  newIndex = tree.move(index.id, above.id, "before");
219
254
  } else if (diffY > dragging.h * 1.5) {
220
255
  // down
221
- let below = index.next ?
256
+ const below = index.next ?
222
257
  tree.getIndex(index.next) :
223
258
  tree.getNodeByTop(index.top + index.height);
224
259
 
@@ -239,7 +274,7 @@ export default class PageTreeDraggable extends React.Component {
239
274
  this.setState({ dragging: dragging });
240
275
  }
241
276
 
242
- dragStart(id, dom, e) {
277
+ dragStart(id: TreeId, dom: HTMLDivElement, e: MouseEvent) {
243
278
  // Only drag on left click
244
279
  if (e.button !== 0) {
245
280
  return;
@@ -261,9 +296,8 @@ export default class PageTreeDraggable extends React.Component {
261
296
  this._offsetY = e.clientY;
262
297
  this._start = true;
263
298
 
264
- var self = this;
265
- this._dragListener = (e) => self.drag(e);
266
- this._dragEndListener = () => self.dragEnd();
299
+ this._dragListener = (e: Event) => { this.drag(e); };
300
+ this._dragEndListener = () => this.dragEnd();
267
301
 
268
302
  window.addEventListener("mousemove", this._dragListener);
269
303
  window.addEventListener("mouseup", this._dragEndListener);
@@ -283,27 +317,15 @@ export default class PageTreeDraggable extends React.Component {
283
317
  window.removeEventListener("mouseup", this._dragEndListener);
284
318
  }
285
319
 
286
- toggleCollapse(nodeId) {
320
+ toggleCollapse(nodeId: TreeId) {
287
321
  this.props.toggleCollapsed(nodeId);
288
322
  }
289
323
 
290
- updatePage(index, attributes) {
324
+ updatePage(index: TreeIndex, attributes: Attributes) {
291
325
  this.props.updatePage(index.id, attributes);
292
326
  }
293
327
  }
294
328
 
295
- PageTreeDraggable.defaultProps = {
329
+ Draggable.defaultProps = {
296
330
  paddingLeft: 15
297
331
  };
298
-
299
- PageTreeDraggable.propTypes = {
300
- tree: PropTypes.object,
301
- addChild: PropTypes.func,
302
- movedPage: PropTypes.func,
303
- toggleCollapsed: PropTypes.func,
304
- paddingLeft: PropTypes.number,
305
- updatePage: PropTypes.func,
306
- updateTree: PropTypes.func,
307
- locale: PropTypes.string,
308
- dir: PropTypes.string
309
- };
@@ -25,24 +25,50 @@
25
25
  SOFTWARE.
26
26
  */
27
27
 
28
- import React from "react";
29
- import PropTypes from "prop-types";
28
+ import React, { createRef, ChangeEvent, Component, RefObject } from "react";
29
+ import Tree, { TreeId, TreeIndex } from "../../lib/Tree";
30
+ import { Attributes, PageNode } from "./types";
31
+
32
+ interface NodeProps {
33
+ addChild: (index: TreeIndex) => void,
34
+ dir: string,
35
+ dragging: number,
36
+ index: TreeIndex<PageNode>,
37
+ locale: string,
38
+ onCollapse: (id: TreeId) => void,
39
+ onDragStart: (id: number, element: HTMLDivElement, evt: Event) => void,
40
+ paddingLeft: number,
41
+ tree: Tree<PageNode>,
42
+ updatePage: (index: TreeIndex, attributes: Attributes) => void
43
+ }
44
+
45
+ interface NodeState {
46
+ newName: string
47
+ }
30
48
 
31
- export default class PageTreeNode extends React.Component {
32
- constructor(props) {
49
+ interface ButtonOptions {
50
+ icon: string,
51
+ className: string,
52
+ onClick: (evt: Event) => void
53
+ }
54
+
55
+ export default class Node extends Component<NodeProps, NodeState> {
56
+ innerRef: RefObject<HTMLDivElement>;
57
+
58
+ constructor(props: NodeProps) {
33
59
  super(props);
34
60
  this.state = { newName: props.index.node.name };
35
- this.innerRef = React.createRef();
61
+ this.innerRef = createRef<HTMLDivElement>();
36
62
  }
37
63
 
38
- permitted(action) {
64
+ permitted(action: string): boolean {
39
65
  return this.node().permissions &&
40
66
  this.node().permissions.indexOf(action) != -1;
41
67
  }
42
68
 
43
69
  actions() {
44
- let statusLabel = (this.node().status != 2) ? "Publish" : "Hide";
45
- let statusIcon = (this.node().status != 2) ? "check" : "ban";
70
+ const statusLabel = (this.node().status != 2) ? "Publish" : "Hide";
71
+ const statusIcon = (this.node().status != 2) ? "check" : "ban";
46
72
 
47
73
  if (this.node().editing) {
48
74
  return null;
@@ -54,7 +80,7 @@ export default class PageTreeNode extends React.Component {
54
80
  <button type="button"
55
81
  className="add"
56
82
  onClick={() => this.props.addChild(this.props.index)}>
57
- <i className="fa fa-plus icon" />
83
+ <i className="fa-solid fa-plus icon" />
58
84
  Add child
59
85
  </button>
60
86
  </span>
@@ -91,11 +117,10 @@ export default class PageTreeNode extends React.Component {
91
117
  }
92
118
 
93
119
  addButton() {
94
- let self = this;
95
- let node = this.node();
96
- let handleClick = function () {
97
- if (self.props.addChild) {
98
- self.props.addChild(self.props.index);
120
+ const node = this.node();
121
+ const handleClick = () => {
122
+ if (this.props.addChild) {
123
+ this.props.addChild(this.props.index);
99
124
  }
100
125
  };
101
126
 
@@ -112,8 +137,8 @@ export default class PageTreeNode extends React.Component {
112
137
  }
113
138
  }
114
139
 
115
- button(label, options) {
116
- let icon = "fa fa-" + options.icon + " icon";
140
+ button(label: string, options: ButtonOptions) {
141
+ const icon = "fa-solid fa-" + options.icon + " icon";
117
142
  return (
118
143
  <button type="button"
119
144
  className={options.className}
@@ -128,18 +153,18 @@ export default class PageTreeNode extends React.Component {
128
153
  const { index, tree, dragging, dir, locale } = this.props;
129
154
 
130
155
  if (index.children && index.children.length && !index.node.collapsed) {
131
- var childrenStyles = {};
156
+ const childrenStyles = {};
132
157
  if (index.node.collapsed) {
133
158
  childrenStyles.display = "none";
134
159
  }
135
- childrenStyles["paddingLeft"] = this.props.paddingLeft + "px";
160
+ childrenStyles["paddingLeft"] = `${this.props.paddingLeft}px`;
136
161
 
137
162
  return (
138
163
  <div className="children" style={childrenStyles}>
139
164
  {index.children.map((child) => {
140
- var childIndex = tree.getIndex(child);
165
+ const childIndex = tree.getIndex(child);
141
166
  return (
142
- <PageTreeNode
167
+ <Node
143
168
  tree={tree}
144
169
  index={childIndex}
145
170
  key={childIndex.id}
@@ -161,30 +186,29 @@ export default class PageTreeNode extends React.Component {
161
186
  }
162
187
 
163
188
  collapseArrow() {
164
- let index = this.props.index;
165
- let self = this;
189
+ const index = this.props.index;
166
190
 
167
191
  // Don't collapse the root node
168
192
  if (!index.parent) {
169
193
  return null;
170
194
  }
171
195
 
172
- let handleCollapse = function (e) {
196
+ const handleCollapse = (e: Event) => {
173
197
  e.stopPropagation();
174
- let nodeId = self.props.index.id;
175
- if (self.props.onCollapse) {
176
- self.props.onCollapse(nodeId);
198
+ const nodeId = this.props.index.id;
199
+ if (this.props.onCollapse) {
200
+ this.props.onCollapse(nodeId);
177
201
  }
178
202
  };
179
203
 
180
204
  if (this.visibleChildren().length > 0) {
181
- let collapsed = index.node.collapsed;
182
- var classnames = null;
205
+ const collapsed = index.node.collapsed;
206
+ let classnames = "";
183
207
 
184
208
  if (collapsed) {
185
- classnames = "collapse fa fa-caret-right";
209
+ classnames = "collapse fa-solid fa-caret-right";
186
210
  } else {
187
- classnames = "collapse fa fa-caret-down";
211
+ classnames = "collapse fa-solid fa-caret-down";
188
212
  }
189
213
 
190
214
  return (
@@ -201,7 +225,7 @@ export default class PageTreeNode extends React.Component {
201
225
  if (this.node().collapsed &&
202
226
  this.node().children &&
203
227
  this.node().children.length > 0) {
204
- let pluralized = (this.node().children.length == 1) ? "item" : "items";
228
+ const pluralized = (this.node().children.length == 1) ? "item" : "items";
205
229
  return (
206
230
  <span className="collapsed-label">
207
231
  ({this.node().children.length} {pluralized})
@@ -222,11 +246,11 @@ export default class PageTreeNode extends React.Component {
222
246
  this.updatePage({editing: true});
223
247
  }
224
248
 
225
- editUrl(page) {
249
+ editUrl(page: PageNode) {
226
250
  return(`/admin/${page.locale}/pages/${page.param}/edit`);
227
251
  }
228
252
 
229
- node() {
253
+ node(): PageNode {
230
254
  return this.props.index.node;
231
255
  }
232
256
 
@@ -242,22 +266,21 @@ export default class PageTreeNode extends React.Component {
242
266
  }
243
267
 
244
268
  render() {
245
- let self = this;
246
- let props = this.props;
247
- let index = props.index;
248
- let dragging = props.dragging;
249
- let editing = this.node().editing;
250
- var classnames = "node";
269
+ const props = this.props;
270
+ const index = props.index;
271
+ const dragging = props.dragging;
272
+ const editing = this.node().editing;
273
+ let classnames = "node";
251
274
 
252
- var node = editing ? this.renderEditNode() : this.renderNode();
275
+ const node = editing ? this.renderEditNode() : this.renderNode();
253
276
 
254
277
  if (index.id === dragging) {
255
278
  classnames = "node placeholder";
256
279
  }
257
280
 
258
- let handleMouseDown = function (e) {
259
- if (self.permitted("edit") && !editing && props.onDragStart) {
260
- props.onDragStart(props.index.id, self.innerRef.current, e);
281
+ const handleMouseDown = (e: Event) => {
282
+ if (this.permitted("edit") && !editing && props.onDragStart) {
283
+ props.onDragStart(props.index.id, this.innerRef.current, e);
261
284
  }
262
285
  };
263
286
 
@@ -281,28 +304,27 @@ export default class PageTreeNode extends React.Component {
281
304
 
282
305
  renderEditNode() {
283
306
  const { dir, locale } = this.props;
284
- let self = this;
285
307
 
286
- let handleNameChange = function(event) {
287
- self.setState({newName: event.target.value});
308
+ const handleNameChange = (event: ChangeEvent<HTMLInputElement>) => {
309
+ this.setState({ newName: event.target.value });
288
310
  };
289
311
 
290
- let performEdit = function(event) {
312
+ const performEdit = (event: Event) => {
291
313
  event.preventDefault();
292
- self.updatePage({
293
- name: self.state.newName,
314
+ this.updatePage({
315
+ name: this.state.newName,
294
316
  editing: false
295
317
  });
296
318
  };
297
319
 
298
- let cancelEdit = function() {
299
- self.setState({newName: self.node().name});
300
- self.updatePage({editing: false});
320
+ const cancelEdit = () => {
321
+ this.setState({ newName: this.node().name });
322
+ this.updatePage({ editing: false });
301
323
  };
302
324
 
303
325
  return (
304
326
  <div className="page edit">
305
- <i className="fa fa-file-o icon"></i>
327
+ <i className="fa-regular fa-file icon"></i>
306
328
  <form onSubmit={performEdit}>
307
329
  <input type="text"
308
330
  value={this.state.newName}
@@ -311,7 +333,7 @@ export default class PageTreeNode extends React.Component {
311
333
  autoFocus
312
334
  onChange={handleNameChange} />
313
335
  <button className="save" type="submit">
314
- <i className="fa fa-cloud icon"></i>
336
+ <i className="fa-solid fa-cloud icon"></i>
315
337
  Save
316
338
  </button>
317
339
  {this.button("Cancel", {
@@ -325,13 +347,13 @@ export default class PageTreeNode extends React.Component {
325
347
  }
326
348
 
327
349
  renderNode() {
328
- let index = this.props.index;
329
- let node = index.node;
350
+ const index = this.props.index;
351
+ const node = index.node;
330
352
 
331
- var pageName = <span className="name">{this.pageName()}</span>;
332
- var className = "page";
353
+ let pageName = <span className="name">{this.pageName()}</span>;
354
+ let className = "page";
333
355
 
334
- var iconClass = "fa fa-file-o icon";
356
+ let iconClass = "fa-regular fa-file icon";
335
357
 
336
358
  if (typeof(node.status) != "undefined") {
337
359
  className = `page status-${this.node().status}`;
@@ -344,9 +366,9 @@ export default class PageTreeNode extends React.Component {
344
366
  }
345
367
 
346
368
  if (node.news_page) {
347
- iconClass = "fa fa-newspaper-o icon";
369
+ iconClass = "fa-regular fa-file-lines icon";
348
370
  } else if (node.pinned) {
349
- iconClass = "fa fa-flag-o icon";
371
+ iconClass = "fa-regular fa-flag icon";
350
372
  }
351
373
 
352
374
  return (
@@ -361,7 +383,7 @@ export default class PageTreeNode extends React.Component {
361
383
  }
362
384
 
363
385
  statusLabel() {
364
- let labels = ["Draft", "Reviewed", "Published", "Hidden", "Deleted"];
386
+ const labels = ["Draft", "Reviewed", "Published", "Hidden", "Deleted"];
365
387
  if (typeof(this.node().status) != "undefined" && this.node().status != 2) {
366
388
  return (
367
389
  <span className="status-label">
@@ -381,13 +403,13 @@ export default class PageTreeNode extends React.Component {
381
403
  }
382
404
  }
383
405
 
384
- updatePage(attributes) {
406
+ updatePage(attributes: Attributes) {
385
407
  if (this.props.updatePage) {
386
408
  return this.props.updatePage(this.props.index, attributes);
387
409
  }
388
410
  }
389
411
 
390
- visibleChildren() {
412
+ visibleChildren(): PageNode[] {
391
413
  if (this.node().children) {
392
414
  return this.node().children.filter(p => p.status != 4);
393
415
  } else {
@@ -395,16 +417,3 @@ export default class PageTreeNode extends React.Component {
395
417
  }
396
418
  }
397
419
  }
398
-
399
- PageTreeNode.propTypes = {
400
- addChild: PropTypes.func,
401
- dragging: PropTypes.number,
402
- index: PropTypes.object,
403
- onCollapse: PropTypes.func,
404
- onDragStart: PropTypes.func,
405
- paddingLeft: PropTypes.number,
406
- tree: PropTypes.object,
407
- updatePage: PropTypes.func,
408
- locale: PropTypes.string,
409
- dir: PropTypes.string,
410
- };
@@ -0,0 +1,15 @@
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
+ }