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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/app/assets/builds/fonts/661557ef.ttf +0 -0
- data/app/assets/builds/fonts/a18fc2d2.woff2 +0 -0
- data/app/assets/builds/fonts/b2c7b78f.woff2 +0 -0
- data/app/assets/builds/fonts/ceddc204.ttf +0 -0
- data/app/assets/builds/pages_core/admin-dist.js +60 -14
- data/app/assets/builds/pages_core/admin-dist.js.map +7 -0
- data/app/assets/builds/pages_core/admin.css +9272 -0
- data/app/assets/images/pages/admin/angle-down-solid.svg +1 -0
- data/app/assets/images/pages/admin/icon.svg +1 -0
- data/app/assets/stylesheets/pages_core/admin/components/archive.css +6 -0
- data/app/assets/stylesheets/{pages/admin/components/attachments.scss → pages_core/admin/components/attachments.css} +35 -28
- data/app/assets/stylesheets/{pages/admin.scss → pages_core/admin/components/base.css} +125 -123
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +223 -0
- data/app/assets/stylesheets/{pages/admin/components/header.scss → pages_core/admin/components/header.css} +76 -46
- data/app/assets/stylesheets/{pages/admin/components/image_editor.scss → pages_core/admin/components/image_editor.css} +42 -31
- data/app/assets/stylesheets/{pages/admin/components/image_grid.scss → pages_core/admin/components/image_grid.css} +76 -64
- data/app/assets/stylesheets/{pages/admin/components/image_uploader.scss → pages_core/admin/components/image_uploader.css} +12 -12
- data/app/assets/stylesheets/{pages/admin/components/layout.scss → pages_core/admin/components/layout.css} +13 -9
- data/app/assets/stylesheets/pages_core/admin/components/links.css +40 -0
- data/app/assets/stylesheets/pages_core/admin/components/list_table.css +66 -0
- data/app/assets/stylesheets/{pages/admin/components/login.scss → pages_core/admin/components/login.css} +6 -5
- data/app/assets/stylesheets/{pages/admin/components/modal.scss → pages_core/admin/components/modal.css} +10 -12
- data/app/assets/stylesheets/{pages/admin/components/page_tree.scss → pages_core/admin/components/page_tree.css} +54 -55
- data/app/assets/stylesheets/{pages/admin/components/pagination.scss → pages_core/admin/components/pagination.css} +17 -17
- data/app/assets/stylesheets/pages_core/admin/components/search.css +27 -0
- data/app/assets/stylesheets/{pages/admin/components/sidebar.scss → pages_core/admin/components/sidebar.css} +8 -7
- data/app/assets/stylesheets/{pages/admin/components/tag_editor.scss → pages_core/admin/components/tag_editor.css} +10 -15
- data/app/assets/stylesheets/{pages/admin/components/textarea.scss → pages_core/admin/components/textarea.css} +1 -1
- data/app/assets/stylesheets/{pages/admin/components/toast.scss → pages_core/admin/components/toast.css} +5 -3
- data/app/assets/stylesheets/{pages/admin/components/toolbar.scss → pages_core/admin/components/toolbar.css} +56 -29
- data/app/assets/stylesheets/{pages/admin/controllers/pages.scss → pages_core/admin/controllers/pages.css} +69 -52
- data/app/assets/stylesheets/pages_core/admin/controllers/users.css +3 -0
- data/app/assets/stylesheets/pages_core/admin/vars.css +34 -0
- data/app/assets/stylesheets/pages_core/admin.postcss.css +9 -0
- data/app/controllers/admin/pages_controller.rb +12 -11
- data/app/controllers/concerns/pages_core/rss_controller.rb +17 -1
- data/app/controllers/pages_core/admin_controller.rb +6 -0
- data/app/controllers/pages_core/frontend/pages_controller.rb +9 -5
- data/app/controllers/pages_core/sitemaps_controller.rb +3 -5
- data/app/formatters/pages_core/image_embedder.rb +5 -27
- data/app/helpers/admin/calendars_helper.rb +8 -0
- data/app/helpers/admin/news_helper.rb +13 -0
- data/app/helpers/admin/pages_helper.rb +32 -0
- data/app/helpers/pages_core/admin/admin_helper.rb +11 -54
- data/app/helpers/pages_core/admin/deprecated_admin_helper.rb +40 -0
- data/app/helpers/pages_core/images_helper.rb +37 -0
- data/app/javascript/admin-dist.ts +2 -0
- data/app/javascript/components/Attachments/{Attachment.jsx → Attachment.tsx} +44 -35
- data/app/javascript/components/Attachments/{AttachmentEditor.jsx → AttachmentEditor.tsx} +23 -23
- data/app/javascript/components/{EditableImage.jsx → EditableImage.tsx} +28 -25
- data/app/javascript/components/{FileUploadButton.jsx → FileUploadButton.tsx} +15 -16
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +94 -0
- data/app/javascript/components/ImageCropper/{Image.jsx → Image.tsx} +13 -14
- data/app/javascript/components/ImageCropper/{Toolbar.jsx → Toolbar.tsx} +19 -15
- data/app/javascript/components/ImageCropper/{useCrop.js → useCrop.ts} +80 -37
- data/app/javascript/components/{ImageCropper.jsx → ImageCropper.tsx} +17 -15
- data/app/javascript/components/ImageEditor/{Form.jsx → Form.tsx} +24 -23
- data/app/javascript/components/{ImageEditor.jsx → ImageEditor.tsx} +17 -15
- data/app/javascript/components/ImageGrid/{DragElement.jsx → DragElement.tsx} +12 -10
- data/app/javascript/components/ImageGrid/{GridImage.jsx → GridImage.tsx} +40 -30
- data/app/javascript/components/ImageGrid/{Placeholder.jsx → Placeholder.tsx} +5 -6
- data/app/javascript/components/ImageGrid.jsx +3 -4
- data/app/javascript/components/{ImageUploader.jsx → ImageUploader.tsx} +46 -41
- data/app/javascript/components/Modal.tsx +48 -0
- data/app/javascript/components/PageImages.tsx +28 -0
- data/app/javascript/components/{PageTreeDraggable.jsx → PageTree/Draggable.tsx} +79 -57
- data/app/javascript/components/{PageTreeNode.jsx → PageTree/Node.tsx} +86 -77
- data/app/javascript/components/PageTree/types.ts +15 -0
- data/app/javascript/components/PageTree.tsx +206 -0
- data/app/javascript/components/RichTextToolbarButton.tsx +17 -0
- data/app/javascript/components/TagEditor/{AddTagForm.jsx → AddTagForm.tsx} +9 -10
- data/app/javascript/components/TagEditor/{Tag.jsx → Tag.tsx} +8 -9
- data/app/javascript/components/{TagEditor.jsx → TagEditor.tsx} +12 -13
- data/app/javascript/components/Toast.tsx +61 -0
- data/app/javascript/components/drag/{draggedOrder.js → draggedOrder.ts} +22 -12
- data/app/javascript/components/drag/types.ts +28 -0
- data/app/javascript/components/drag/{useDragCollection.js → useDragCollection.ts} +40 -22
- data/app/javascript/components/drag/{useDragUploader.js → useDragUploader.ts} +34 -25
- data/app/javascript/components/drag/useDraggable.ts +21 -0
- data/app/javascript/components/{drag.js → drag.ts} +1 -0
- data/app/javascript/controllers/{EditPageController.js → EditPageController.ts} +3 -1
- data/app/javascript/controllers/{LoginController.js → LoginController.ts} +7 -3
- data/app/javascript/controllers/{MainController.js → MainController.ts} +19 -14
- data/app/javascript/{index.js → index.ts} +8 -7
- data/app/javascript/lib/{Tree.js → Tree.ts} +106 -85
- data/app/javascript/lib/{copyToClipboard.js → copyToClipboard.ts} +1 -1
- data/app/javascript/lib/{readyHandler.js → readyHandler.ts} +4 -2
- data/app/javascript/lib/{request.js → request.ts} +11 -5
- data/app/javascript/stores/useModalStore.ts +15 -0
- data/app/javascript/stores/useToastStore.ts +26 -0
- data/app/javascript/stores.ts +2 -0
- data/app/javascript/types.ts +30 -0
- data/app/mailers/admin_mailer.rb +1 -0
- data/app/models/invite.rb +8 -0
- data/app/policies/page_policy.rb +4 -0
- data/app/views/admin/calendars/_sidebar.html.erb +50 -0
- data/app/views/admin/calendars/show.html.erb +15 -53
- data/app/views/admin/invites/new.html.erb +2 -8
- data/app/views/admin/invites/show.html.erb +2 -4
- data/app/views/admin/news/_sidebar.html.erb +51 -0
- data/app/views/admin/news/index.html.erb +21 -56
- data/app/views/admin/pages/_list_item.html.erb +4 -22
- data/app/views/admin/pages/_search_bar.html.erb +12 -0
- data/app/views/admin/pages/deleted.html.erb +10 -8
- data/app/views/admin/pages/edit.html.erb +20 -11
- data/app/views/admin/pages/index.html.erb +10 -8
- data/app/views/admin/pages/new.html.erb +10 -14
- data/app/views/admin/pages/search.html.erb +54 -0
- data/app/views/admin/password_resets/show.html.erb +3 -5
- data/app/views/admin/users/deactivated.html.erb +6 -7
- data/app/views/admin/users/edit.html.erb +7 -9
- data/app/views/admin/users/index.html.erb +3 -6
- data/app/views/admin/users/login.html.erb +4 -5
- data/app/views/admin/users/new.html.erb +2 -4
- data/app/views/admin/users/new_password.html.erb +4 -5
- data/app/views/admin/users/show.html.erb +11 -9
- data/app/views/errors/401.html.erb +2 -1
- data/app/views/errors/403.html.erb +2 -1
- data/app/views/errors/404.html.erb +1 -3
- data/app/views/errors/405.html.erb +2 -1
- data/app/views/errors/422.html.erb +2 -1
- data/app/views/errors/500.html.erb +2 -3
- data/app/views/feeds/pages.rss.builder +3 -9
- data/app/views/layouts/admin/_header.html.erb +1 -2
- data/app/views/layouts/admin/_page_header.html.erb +4 -4
- data/app/views/layouts/admin.html.erb +3 -3
- data/app/views/layouts/errors.html.erb +127 -4
- data/config/routes.rb +1 -0
- data/lib/pages_core/configuration/pages.rb +0 -1
- data/lib/pages_core/engine.rb +4 -3
- data/lib/pages_core.rb +0 -1
- data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +33 -17
- data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +0 -1
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +40 -0
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +68 -0
- data/lib/rails/generators/pages_core/frontend/templates/postcss.config.js +17 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.postcss.css +4 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.css +24 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/layout.css +21 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.css +5 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/animation.css +5 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.css +18 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/fonts.css +6 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/grid.css +65 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.css +131 -0
- data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +0 -3
- metadata +104 -255
- data/app/assets/images/pages/admin/icon.png +0 -0
- data/app/assets/images/pages/admin/image-editor-bg.png +0 -0
- data/app/assets/images/pages/admin/list-table-pin-blue.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-disabled.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-green.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-red.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-yellow.gif +0 -0
- data/app/assets/images/pages/admin/loading-modal.gif +0 -0
- data/app/assets/images/pages/feed-icon-14x14.png +0 -0
- data/app/assets/stylesheets/pages/admin/components/archive.scss +0 -6
- data/app/assets/stylesheets/pages/admin/components/buttons.scss +0 -23
- data/app/assets/stylesheets/pages/admin/components/forms.scss +0 -169
- data/app/assets/stylesheets/pages/admin/components/links.scss +0 -43
- data/app/assets/stylesheets/pages/admin/components/list_table.scss +0 -61
- data/app/assets/stylesheets/pages/admin/controllers/users.scss +0 -3
- data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +0 -21
- data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +0 -7
- data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +0 -7
- data/app/assets/stylesheets/pages/admin/vars.scss +0 -30
- data/app/assets/stylesheets/pages/errors.css +0 -128
- data/app/javascript/admin-dist.js +0 -2
- data/app/javascript/components/ImageCropper/FocalPoint.jsx +0 -93
- data/app/javascript/components/Modal.jsx +0 -59
- data/app/javascript/components/PageImages.jsx +0 -25
- data/app/javascript/components/PageTree.jsx +0 -196
- data/app/javascript/components/RichTextToolbarButton.jsx +0 -20
- data/app/javascript/components/Toast.jsx +0 -72
- data/app/javascript/components/drag/useDraggable.js +0 -17
- data/app/javascript/stores/ModalStore.jsx +0 -12
- data/app/javascript/stores/ToastStore.jsx +0 -14
- data/app/javascript/stores.js +0 -2
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/GridOverlay.js +0 -66
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/ResponsiveEmbeds.js +0 -72
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.sass.scss +0 -15
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.scss +0 -12
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.scss +0 -26
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/breakpoints.scss +0 -42
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/clearfix.scss +0 -7
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/fonts.scss +0 -32
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid.scss +0 -168
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid_overlay.scss +0 -44
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.scss +0 -8
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.scss +0 -90
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/vendor/normalize.css +0 -349
- data/vendor/assets/stylesheets/ReactCrop.css +0 -167
- /data/app/assets/stylesheets/{pages/admin/components/tabs.scss → pages_core/admin/components/tabs.css} +0 -0
- /data/app/javascript/components/Attachments/{Placeholder.jsx → Placeholder.tsx} +0 -0
- /data/app/javascript/components/ImageGrid/{FilePlaceholder.jsx → FilePlaceholder.tsx} +0 -0
- /data/app/javascript/{components.js → components.ts} +0 -0
- /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
|
|
30
|
-
import
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
88
|
+
const tree = this.props.tree;
|
|
89
|
+
const dragging = this.state.dragging;
|
|
55
90
|
if (dragging && dragging.id) {
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
123
|
+
const root = tree.getIndex(1);
|
|
89
124
|
return (
|
|
90
125
|
<div className="page-tree">
|
|
91
126
|
{this.getDraggingDom()}
|
|
92
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
213
|
+
const _startX = this._startX;
|
|
214
|
+
const _startY = this._startY;
|
|
215
|
+
const _offsetX = this._offsetX;
|
|
216
|
+
const _offsetY = this._offsetY;
|
|
182
217
|
|
|
183
|
-
|
|
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
|
-
|
|
191
|
-
|
|
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
|
|
201
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
265
|
-
this.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
32
|
-
|
|
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 =
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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
|
-
|
|
156
|
+
const childrenStyles = {};
|
|
132
157
|
if (index.node.collapsed) {
|
|
133
158
|
childrenStyles.display = "none";
|
|
134
159
|
}
|
|
135
|
-
childrenStyles["paddingLeft"] = this.props.paddingLeft
|
|
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
|
-
|
|
165
|
+
const childIndex = tree.getIndex(child);
|
|
141
166
|
return (
|
|
142
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
196
|
+
const handleCollapse = (e: Event) => {
|
|
173
197
|
e.stopPropagation();
|
|
174
|
-
|
|
175
|
-
if (
|
|
176
|
-
|
|
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
|
-
|
|
182
|
-
|
|
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
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
let
|
|
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
|
-
|
|
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
|
-
|
|
259
|
-
if (
|
|
260
|
-
props.onDragStart(props.index.id,
|
|
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
|
-
|
|
287
|
-
|
|
308
|
+
const handleNameChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
309
|
+
this.setState({ newName: event.target.value });
|
|
288
310
|
};
|
|
289
311
|
|
|
290
|
-
|
|
312
|
+
const performEdit = (event: Event) => {
|
|
291
313
|
event.preventDefault();
|
|
292
|
-
|
|
293
|
-
name:
|
|
314
|
+
this.updatePage({
|
|
315
|
+
name: this.state.newName,
|
|
294
316
|
editing: false
|
|
295
317
|
});
|
|
296
318
|
};
|
|
297
319
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
|
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
|
-
|
|
329
|
-
|
|
350
|
+
const index = this.props.index;
|
|
351
|
+
const node = index.node;
|
|
330
352
|
|
|
331
|
-
|
|
332
|
-
|
|
353
|
+
let pageName = <span className="name">{this.pageName()}</span>;
|
|
354
|
+
let className = "page";
|
|
333
355
|
|
|
334
|
-
|
|
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-
|
|
369
|
+
iconClass = "fa-regular fa-file-lines icon";
|
|
348
370
|
} else if (node.pinned) {
|
|
349
|
-
iconClass = "fa fa-flag
|
|
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
|
-
|
|
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
|
+
}
|