pages_core 3.12.0 → 3.12.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }