pages_core 3.12.4 → 3.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/app/assets/builds/pages_core/admin-dist.js +8 -43
- data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
- data/app/assets/builds/pages_core/admin.css +264 -133
- data/app/assets/stylesheets/pages_core/admin/components/attachments.css +3 -4
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +17 -16
- data/app/assets/stylesheets/pages_core/admin/components/image_editor.css +8 -4
- data/app/assets/stylesheets/pages_core/admin/components/image_grid.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/components/list_table.css +11 -3
- data/app/assets/stylesheets/pages_core/admin/components/modal.css +9 -5
- data/app/assets/stylesheets/pages_core/admin/components/page_tree.css +5 -1
- data/app/assets/stylesheets/pages_core/admin/components/toast.css +2 -2
- data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +4 -2
- data/app/assets/stylesheets/pages_core/admin/vars.css +2 -1
- data/app/controllers/admin/calendars_controller.rb +2 -2
- data/app/controllers/admin/categories_controller.rb +3 -3
- data/app/controllers/admin/news_controller.rb +6 -6
- data/app/controllers/admin/pages_controller.rb +12 -11
- data/app/controllers/admin/users_controller.rb +1 -1
- data/app/controllers/concerns/pages_core/preview_pages_controller.rb +15 -17
- data/app/controllers/pages_core/admin_controller.rb +2 -2
- data/app/controllers/pages_core/base_controller.rb +1 -8
- data/app/controllers/pages_core/frontend/pages_controller.rb +13 -5
- data/app/controllers/pages_core/frontend_controller.rb +12 -7
- data/app/helpers/admin/menu_helper.rb +2 -0
- data/app/helpers/admin/pages_helper.rb +1 -4
- data/app/helpers/pages_core/admin/admin_helper.rb +0 -1
- data/app/helpers/pages_core/admin/content_tabs_helper.rb +9 -2
- data/app/helpers/pages_core/application_helper.rb +2 -3
- data/app/helpers/pages_core/frontend_helper.rb +1 -1
- data/app/helpers/pages_core/head_tags_helper.rb +15 -46
- data/app/helpers/pages_core/images_helper.rb +76 -21
- data/app/helpers/pages_core/locales_helper.rb +9 -0
- data/app/helpers/pages_core/open_graph_tags_helper.rb +3 -5
- data/app/helpers/pages_core/page_path_helper.rb +1 -1
- data/app/javascript/components/Attachments/Attachment.tsx +55 -52
- data/app/javascript/components/Attachments/AttachmentEditor.tsx +45 -50
- data/app/javascript/components/Attachments/Placeholder.tsx +1 -2
- data/app/javascript/components/Attachments.jsx +69 -57
- data/app/javascript/components/DateRangeSelect.jsx +94 -54
- data/app/javascript/components/EditableImage.tsx +20 -16
- data/app/javascript/components/FileUploadButton.tsx +12 -12
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +22 -20
- data/app/javascript/components/ImageCropper/Image.tsx +20 -16
- data/app/javascript/components/ImageCropper/Toolbar.tsx +35 -27
- data/app/javascript/components/ImageCropper/useCrop.ts +105 -91
- data/app/javascript/components/ImageCropper.tsx +34 -25
- data/app/javascript/components/ImageEditor/Form.tsx +32 -43
- data/app/javascript/components/ImageEditor.tsx +29 -21
- data/app/javascript/components/ImageGrid/DragElement.tsx +6 -4
- data/app/javascript/components/ImageGrid/GridImage.tsx +56 -52
- data/app/javascript/components/ImageGrid/Placeholder.tsx +1 -1
- data/app/javascript/components/ImageGrid.jsx +132 -101
- data/app/javascript/components/ImageUploader.tsx +59 -55
- data/app/javascript/components/Modal.tsx +2 -4
- data/app/javascript/components/PageDates.jsx +25 -20
- data/app/javascript/components/PageFiles.jsx +7 -5
- data/app/javascript/components/PageImages.tsx +9 -7
- data/app/javascript/components/PageTree/Draggable.tsx +46 -40
- data/app/javascript/components/PageTree/Node.tsx +111 -95
- data/app/javascript/components/PageTree/types.ts +9 -9
- data/app/javascript/components/PageTree.tsx +44 -29
- data/app/javascript/components/RichTextArea.jsx +51 -37
- data/app/javascript/components/RichTextToolbarButton.tsx +8 -5
- data/app/javascript/components/TagEditor/AddTagForm.tsx +11 -10
- data/app/javascript/components/TagEditor/Tag.tsx +10 -8
- data/app/javascript/components/TagEditor.tsx +15 -10
- data/app/javascript/components/Toast.tsx +3 -7
- data/app/javascript/components/drag/draggedOrder.ts +16 -15
- data/app/javascript/components/drag/types.ts +12 -12
- data/app/javascript/components/drag/useDragCollection.ts +36 -42
- data/app/javascript/components/drag/useDragUploader.ts +3 -2
- data/app/javascript/components/drag.ts +5 -4
- data/app/javascript/controllers/LoginController.ts +0 -1
- data/app/javascript/controllers/MainController.ts +6 -2
- data/app/javascript/controllers/PageOptionsController.js +7 -2
- data/app/javascript/features/RichText.tsx +9 -7
- data/app/javascript/index.ts +5 -3
- data/app/javascript/lib/Tree.ts +27 -24
- data/app/javascript/lib/copyToClipboard.ts +5 -4
- data/app/javascript/lib/readyHandler.ts +4 -4
- data/app/javascript/lib/request.ts +7 -3
- data/app/javascript/stores/useModalStore.ts +3 -3
- data/app/javascript/stores/useToastStore.ts +14 -12
- data/app/javascript/types.ts +22 -22
- data/app/models/concerns/pages_core/page_model/templateable.rb +1 -1
- data/app/views/admin/calendars/show.html.erb +1 -1
- data/app/views/admin/news/index.html.erb +1 -1
- data/app/views/admin/pages/_edit_files.html.erb +1 -1
- data/app/views/admin/pages/_edit_images.html.erb +1 -1
- data/app/views/admin/pages/_list_item.html.erb +1 -1
- data/app/views/admin/pages/_search_bar.html.erb +1 -1
- data/app/views/admin/pages/deleted.html.erb +2 -2
- data/app/views/admin/pages/edit.html.erb +3 -3
- data/app/views/admin/pages/index.html.erb +4 -4
- data/app/views/admin/pages/new.html.erb +1 -1
- data/app/views/admin/pages/search.html.erb +3 -3
- data/app/views/feeds/pages.rss.builder +2 -2
- data/app/views/layouts/admin/_page_header.html.erb +4 -4
- data/app/views/layouts/admin.html.erb +1 -2
- data/config/locales/en.yml +1 -0
- data/lib/pages_core/pages_plugin.rb +5 -3
- data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +15 -13
- data/lib/tasks/pages/reports.rake +26 -0
- metadata +32 -4
- data/app/helpers/pages_core/admin/deprecated_admin_helper.rb +0 -40
- data/app/views/pages_core/_google_analytics.html.erb +0 -8
|
@@ -6,8 +6,8 @@ export default class PageDates extends React.Component {
|
|
|
6
6
|
constructor(props) {
|
|
7
7
|
super(props);
|
|
8
8
|
this.state = {
|
|
9
|
-
has_dates:
|
|
10
|
-
all_day:
|
|
9
|
+
has_dates: props.starts_at ? true : false,
|
|
10
|
+
all_day: !!props.all_day
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
this.toggleAllDay = this.toggleAllDay.bind(this);
|
|
@@ -29,32 +29,37 @@ export default class PageDates extends React.Component {
|
|
|
29
29
|
render() {
|
|
30
30
|
return (
|
|
31
31
|
<div className="page-dates field">
|
|
32
|
-
<input
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
</label>
|
|
32
|
+
<input
|
|
33
|
+
type="hidden"
|
|
34
|
+
name="page[all_day]"
|
|
35
|
+
value={this.state.has_dates && this.state.all_day ? "1" : "0"}
|
|
36
|
+
/>
|
|
37
|
+
<label>Dates</label>
|
|
38
38
|
<div className="toggles">
|
|
39
39
|
<label className="has-dates-toggle">
|
|
40
|
-
<input
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
<input
|
|
41
|
+
type="checkbox"
|
|
42
|
+
checked={this.state.has_dates}
|
|
43
|
+
onChange={this.toggleHasDates}
|
|
44
|
+
/>
|
|
43
45
|
Enabled
|
|
44
46
|
</label>
|
|
45
47
|
<label className={!this.state.has_dates && "disabled"}>
|
|
46
|
-
<input
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
<input
|
|
49
|
+
type="checkbox"
|
|
50
|
+
disabled={!this.state.has_dates}
|
|
51
|
+
checked={this.state.all_day}
|
|
52
|
+
onChange={this.toggleAllDay}
|
|
53
|
+
/>
|
|
50
54
|
All day event
|
|
51
55
|
</label>
|
|
52
56
|
</div>
|
|
53
|
-
<DateRangeSelect
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
<DateRangeSelect
|
|
58
|
+
objectName="page"
|
|
59
|
+
startsAt={this.props.starts_at}
|
|
60
|
+
endsAt={this.props.ends_at}
|
|
61
|
+
disabled={!this.state.has_dates}
|
|
62
|
+
disableTime={this.state.all_day}
|
|
58
63
|
/>
|
|
59
64
|
</div>
|
|
60
65
|
);
|
|
@@ -6,11 +6,13 @@ export default class PageFiles extends React.Component {
|
|
|
6
6
|
render() {
|
|
7
7
|
return (
|
|
8
8
|
<div className="page-files">
|
|
9
|
-
<Attachments
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
<Attachments
|
|
10
|
+
attribute="page[page_files_attributes]"
|
|
11
|
+
showEmbed={true}
|
|
12
|
+
locale={this.props.locale}
|
|
13
|
+
locales={this.props.locales}
|
|
14
|
+
records={this.props.records}
|
|
15
|
+
/>
|
|
14
16
|
</div>
|
|
15
17
|
);
|
|
16
18
|
}
|
|
@@ -3,26 +3,28 @@ import { ImageResource, Locale } from "../types";
|
|
|
3
3
|
import ImageGrid from "./ImageGrid";
|
|
4
4
|
|
|
5
5
|
interface PageImage {
|
|
6
|
-
id: number | null
|
|
7
|
-
image: ImageResource
|
|
6
|
+
id: number | null;
|
|
7
|
+
image: ImageResource;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
interface PageImagesProps {
|
|
11
|
-
locale: string
|
|
12
|
-
locales: { [index: string]: Locale }
|
|
13
|
-
records: PageImage[]
|
|
11
|
+
locale: string;
|
|
12
|
+
locales: { [index: string]: Locale };
|
|
13
|
+
records: PageImage[];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export default function PageImages(props: PageImagesProps) {
|
|
17
17
|
return (
|
|
18
18
|
<div className="page-images">
|
|
19
|
-
<ImageGrid
|
|
19
|
+
<ImageGrid
|
|
20
|
+
attribute="page[page_images_attributes]"
|
|
20
21
|
primaryAttribute="page[image_id]"
|
|
21
22
|
enablePrimary={true}
|
|
22
23
|
showEmbed={true}
|
|
23
24
|
locale={props.locale}
|
|
24
25
|
locales={props.locales}
|
|
25
|
-
records={props.records}
|
|
26
|
+
records={props.records}
|
|
27
|
+
/>
|
|
26
28
|
</div>
|
|
27
29
|
);
|
|
28
30
|
}
|
|
@@ -31,32 +31,35 @@ import { Attributes, PageNode } from "./types";
|
|
|
31
31
|
import Node from "./Node";
|
|
32
32
|
|
|
33
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
|
|
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
41
|
}
|
|
42
42
|
|
|
43
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
|
|
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
53
|
}
|
|
54
54
|
|
|
55
55
|
interface DraggableState {
|
|
56
|
-
dragging: DragState
|
|
56
|
+
dragging: DragState;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export default class Draggable extends Component<
|
|
59
|
+
export default class Draggable extends Component<
|
|
60
|
+
DraggableProps,
|
|
61
|
+
DraggableState
|
|
62
|
+
> {
|
|
60
63
|
_dragListener: (evt: MouseEvent) => void;
|
|
61
64
|
_dragEndListener: () => void;
|
|
62
65
|
_startX: number;
|
|
@@ -98,9 +101,9 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
98
101
|
return (
|
|
99
102
|
<div className="draggable" style={draggingStyles}>
|
|
100
103
|
<Node
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
tree={tree}
|
|
105
|
+
index={draggingIndex}
|
|
106
|
+
paddingLeft={this.props.paddingLeft}
|
|
104
107
|
/>
|
|
105
108
|
</div>
|
|
106
109
|
);
|
|
@@ -114,11 +117,7 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
114
117
|
const dragging = this.state.dragging;
|
|
115
118
|
|
|
116
119
|
if (!tree) {
|
|
117
|
-
return (
|
|
118
|
-
<div className="page-tree">
|
|
119
|
-
{this.getDraggingDom()}
|
|
120
|
-
</div>
|
|
121
|
-
);
|
|
120
|
+
return <div className="page-tree">{this.getDraggingDom()}</div>;
|
|
122
121
|
} else {
|
|
123
122
|
const root = tree.getIndex(1);
|
|
124
123
|
return (
|
|
@@ -129,13 +128,14 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
129
128
|
index={root}
|
|
130
129
|
key={root.id}
|
|
131
130
|
paddingLeft={this.props.paddingLeft}
|
|
132
|
-
addChild={id => this.addChild(id)}
|
|
131
|
+
addChild={(id) => this.addChild(id)}
|
|
133
132
|
onDragStart={(id, dom, e) => this.dragStart(id, dom, e)}
|
|
134
|
-
onCollapse={nodeId => this.toggleCollapse(nodeId)}
|
|
133
|
+
onCollapse={(nodeId) => this.toggleCollapse(nodeId)}
|
|
135
134
|
updatePage={(idx, attrs) => this.updatePage(idx, attrs)}
|
|
136
135
|
dragging={dragging && dragging.id}
|
|
137
136
|
dir={dir}
|
|
138
|
-
locale={locale}
|
|
137
|
+
locale={locale}
|
|
138
|
+
/>
|
|
139
139
|
</div>
|
|
140
140
|
);
|
|
141
141
|
}
|
|
@@ -171,7 +171,7 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
171
171
|
if (
|
|
172
172
|
parentNodes.indexOf(pointer) == -1 &&
|
|
173
173
|
!pointer.node.collapsed &&
|
|
174
|
-
pointer.node.children.filter(p => p.status != 4).length > 0
|
|
174
|
+
pointer.node.children.filter((p) => p.status != 4).length > 0
|
|
175
175
|
) {
|
|
176
176
|
count += 1;
|
|
177
177
|
}
|
|
@@ -191,8 +191,9 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
191
191
|
|
|
192
192
|
drag(e: MouseEvent) {
|
|
193
193
|
if (this._start) {
|
|
194
|
-
const distance =
|
|
195
|
-
|
|
194
|
+
const distance =
|
|
195
|
+
Math.abs(e.clientX - this._offsetX) +
|
|
196
|
+
Math.abs(e.clientY - this._offsetY);
|
|
196
197
|
if (distance >= 15) {
|
|
197
198
|
this.setState({
|
|
198
199
|
dragging: this.dragging
|
|
@@ -222,8 +223,11 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
222
223
|
dragging.x = pos.x;
|
|
223
224
|
dragging.y = pos.y;
|
|
224
225
|
|
|
225
|
-
const diffX = dragging.x - paddingLeft/2 - (index.left-2) * paddingLeft;
|
|
226
|
-
const diffY =
|
|
226
|
+
const diffX = dragging.x - paddingLeft / 2 - (index.left - 2) * paddingLeft;
|
|
227
|
+
const diffY =
|
|
228
|
+
dragging.y -
|
|
229
|
+
dragging.h / 2 -
|
|
230
|
+
(index.top - 2 + this.prevAddButtonCount(tree, index)) * dragging.h;
|
|
227
231
|
|
|
228
232
|
if (diffX < 0) {
|
|
229
233
|
// left
|
|
@@ -247,15 +251,15 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
247
251
|
dragging.id = newIndex.id;
|
|
248
252
|
}
|
|
249
253
|
|
|
250
|
-
if (diffY <
|
|
254
|
+
if (diffY < 0 - dragging.h * 0.5) {
|
|
251
255
|
// up
|
|
252
|
-
const above = tree.getNodeByTop(index.top-1);
|
|
256
|
+
const above = tree.getNodeByTop(index.top - 1);
|
|
253
257
|
newIndex = tree.move(index.id, above.id, "before");
|
|
254
258
|
} else if (diffY > dragging.h * 1.5) {
|
|
255
259
|
// down
|
|
256
|
-
const below = index.next
|
|
257
|
-
|
|
258
|
-
|
|
260
|
+
const below = index.next
|
|
261
|
+
? tree.getIndex(index.next)
|
|
262
|
+
: tree.getNodeByTop(index.top + index.height);
|
|
259
263
|
|
|
260
264
|
if (below && below.parent !== index.id) {
|
|
261
265
|
if (below.children && below.children.length && !below.node.collapsed) {
|
|
@@ -296,7 +300,9 @@ export default class Draggable extends Component<DraggableProps, DraggableState>
|
|
|
296
300
|
this._offsetY = e.clientY;
|
|
297
301
|
this._start = true;
|
|
298
302
|
|
|
299
|
-
this._dragListener = (e: Event) => {
|
|
303
|
+
this._dragListener = (e: Event) => {
|
|
304
|
+
this.drag(e);
|
|
305
|
+
};
|
|
300
306
|
this._dragEndListener = () => this.dragEnd();
|
|
301
307
|
|
|
302
308
|
window.addEventListener("mousemove", this._dragListener);
|
|
@@ -30,26 +30,26 @@ import Tree, { TreeId, TreeIndex } from "../../lib/Tree";
|
|
|
30
30
|
import { Attributes, PageNode } from "./types";
|
|
31
31
|
|
|
32
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
|
|
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
43
|
}
|
|
44
44
|
|
|
45
45
|
interface NodeState {
|
|
46
|
-
newName: string
|
|
46
|
+
newName: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
interface ButtonOptions {
|
|
50
|
-
icon: string
|
|
51
|
-
className: string
|
|
52
|
-
onClick: (evt: Event) => void
|
|
50
|
+
icon: string;
|
|
51
|
+
className: string;
|
|
52
|
+
onClick: (evt: Event) => void;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export default class Node extends Component<NodeProps, NodeState> {
|
|
@@ -62,13 +62,14 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
permitted(action: string): boolean {
|
|
65
|
-
return
|
|
66
|
-
|
|
65
|
+
return (
|
|
66
|
+
this.node().permissions && this.node().permissions.indexOf(action) != -1
|
|
67
|
+
);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
actions() {
|
|
70
|
-
const statusLabel =
|
|
71
|
-
const statusIcon =
|
|
71
|
+
const statusLabel = this.node().status != 2 ? "Publish" : "Hide";
|
|
72
|
+
const statusIcon = this.node().status != 2 ? "check" : "ban";
|
|
72
73
|
|
|
73
74
|
if (this.node().editing) {
|
|
74
75
|
return null;
|
|
@@ -77,9 +78,10 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
77
78
|
if (this.props.index.id === 1) {
|
|
78
79
|
return (
|
|
79
80
|
<span className="actions">
|
|
80
|
-
<button
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
<button
|
|
82
|
+
type="button"
|
|
83
|
+
className="add"
|
|
84
|
+
onClick={() => this.props.addChild(this.props.index)}>
|
|
83
85
|
<i className="fa-solid fa-plus icon" />
|
|
84
86
|
Add child
|
|
85
87
|
</button>
|
|
@@ -88,29 +90,33 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
88
90
|
} else {
|
|
89
91
|
return (
|
|
90
92
|
<span className="actions">
|
|
91
|
-
{this.permitted("edit") &&
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
93
|
+
{this.permitted("edit") &&
|
|
94
|
+
this.button(statusLabel, {
|
|
95
|
+
className: "toggle-status",
|
|
96
|
+
icon: statusIcon,
|
|
97
|
+
onClick: () => this.toggleStatus()
|
|
98
|
+
})}
|
|
99
|
+
|
|
100
|
+
{this.permitted("edit") &&
|
|
101
|
+
this.button("Rename", {
|
|
102
|
+
className: "edit",
|
|
103
|
+
icon: "pencil",
|
|
104
|
+
onClick: () => this.edit()
|
|
105
|
+
})}
|
|
106
|
+
|
|
107
|
+
{this.permitted("edit") &&
|
|
108
|
+
this.button("Delete", {
|
|
109
|
+
className: "delete",
|
|
110
|
+
icon: "trash",
|
|
111
|
+
onClick: () => this.deletePage()
|
|
112
|
+
})}
|
|
113
|
+
|
|
114
|
+
{this.permitted("create") &&
|
|
115
|
+
this.button("Add child", {
|
|
116
|
+
className: "add",
|
|
117
|
+
icon: "plus",
|
|
118
|
+
onClick: () => this.props.addChild(this.props.index)
|
|
119
|
+
})}
|
|
114
120
|
</span>
|
|
115
121
|
);
|
|
116
122
|
}
|
|
@@ -124,25 +130,26 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
124
130
|
}
|
|
125
131
|
};
|
|
126
132
|
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
);
|
|
133
|
+
if (
|
|
134
|
+
!node.collapsed &&
|
|
135
|
+
this.permitted("create") &&
|
|
136
|
+
(node.root || this.visibleChildren().length > 0)
|
|
137
|
+
) {
|
|
138
|
+
return this.button("Add page here", {
|
|
139
|
+
className: "add add-inline",
|
|
140
|
+
icon: "plus",
|
|
141
|
+
onClick: handleClick
|
|
142
|
+
});
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
button(label: string, options: ButtonOptions) {
|
|
141
147
|
const icon = "fa-solid fa-" + options.icon + " icon";
|
|
142
148
|
return (
|
|
143
|
-
<button
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
<button
|
|
150
|
+
type="button"
|
|
151
|
+
className={options.className}
|
|
152
|
+
onClick={options.onClick}>
|
|
146
153
|
<i className={icon} />
|
|
147
154
|
{label}
|
|
148
155
|
</button>
|
|
@@ -175,7 +182,8 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
175
182
|
onDragStart={this.props.onDragStart}
|
|
176
183
|
updatePage={this.props.updatePage}
|
|
177
184
|
dir={dir}
|
|
178
|
-
locale={locale}
|
|
185
|
+
locale={locale}
|
|
186
|
+
/>
|
|
179
187
|
);
|
|
180
188
|
})}
|
|
181
189
|
</div>
|
|
@@ -212,9 +220,13 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
212
220
|
}
|
|
213
221
|
|
|
214
222
|
return (
|
|
215
|
-
<i
|
|
216
|
-
|
|
217
|
-
|
|
223
|
+
<i
|
|
224
|
+
className={classnames}
|
|
225
|
+
onMouseDown={function (e) {
|
|
226
|
+
e.stopPropagation();
|
|
227
|
+
}}
|
|
228
|
+
onClick={handleCollapse}
|
|
229
|
+
/>
|
|
218
230
|
);
|
|
219
231
|
}
|
|
220
232
|
|
|
@@ -222,10 +234,12 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
222
234
|
}
|
|
223
235
|
|
|
224
236
|
collapsedLabel() {
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
237
|
+
if (
|
|
238
|
+
this.node().collapsed &&
|
|
239
|
+
this.node().children &&
|
|
240
|
+
this.node().children.length > 0
|
|
241
|
+
) {
|
|
242
|
+
const pluralized = this.node().children.length == 1 ? "item" : "items";
|
|
229
243
|
return (
|
|
230
244
|
<span className="collapsed-label">
|
|
231
245
|
({this.node().children.length} {pluralized})
|
|
@@ -238,16 +252,16 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
238
252
|
|
|
239
253
|
deletePage() {
|
|
240
254
|
if (confirm("Are you sure you want to delete this page?")) {
|
|
241
|
-
this.updatePage({status: 4});
|
|
255
|
+
this.updatePage({ status: 4 });
|
|
242
256
|
}
|
|
243
257
|
}
|
|
244
258
|
|
|
245
259
|
edit() {
|
|
246
|
-
this.updatePage({editing: true});
|
|
260
|
+
this.updatePage({ editing: true });
|
|
247
261
|
}
|
|
248
262
|
|
|
249
263
|
editUrl(page: PageNode) {
|
|
250
|
-
return
|
|
264
|
+
return `/admin/${page.locale}/pages/${page.param}/edit`;
|
|
251
265
|
}
|
|
252
266
|
|
|
253
267
|
node(): PageNode {
|
|
@@ -257,9 +271,8 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
257
271
|
pageName() {
|
|
258
272
|
const name = this.node().name || <i className="untitled">Untitled</i>;
|
|
259
273
|
|
|
260
|
-
return(
|
|
261
|
-
<span dir={this.props.dir}
|
|
262
|
-
lang={this.props.locale}>
|
|
274
|
+
return (
|
|
275
|
+
<span dir={this.props.dir} lang={this.props.locale}>
|
|
263
276
|
{name}
|
|
264
277
|
</span>
|
|
265
278
|
);
|
|
@@ -287,9 +300,10 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
287
300
|
if (this.node().status != 4) {
|
|
288
301
|
return (
|
|
289
302
|
<div className={classnames}>
|
|
290
|
-
<div
|
|
291
|
-
|
|
292
|
-
|
|
303
|
+
<div
|
|
304
|
+
className="inner"
|
|
305
|
+
ref={this.innerRef}
|
|
306
|
+
onMouseDown={handleMouseDown}>
|
|
293
307
|
{this.collapseArrow()}
|
|
294
308
|
{node}
|
|
295
309
|
</div>
|
|
@@ -326,21 +340,23 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
326
340
|
<div className="page edit">
|
|
327
341
|
<i className="fa-regular fa-file icon"></i>
|
|
328
342
|
<form onSubmit={performEdit}>
|
|
329
|
-
<input
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
343
|
+
<input
|
|
344
|
+
type="text"
|
|
345
|
+
value={this.state.newName}
|
|
346
|
+
dir={dir}
|
|
347
|
+
lang={locale}
|
|
348
|
+
autoFocus
|
|
349
|
+
onChange={handleNameChange}
|
|
350
|
+
/>
|
|
335
351
|
<button className="save" type="submit">
|
|
336
352
|
<i className="fa-solid fa-cloud icon"></i>
|
|
337
353
|
Save
|
|
338
354
|
</button>
|
|
339
355
|
{this.button("Cancel", {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
356
|
+
className: "cancel",
|
|
357
|
+
icon: "ban",
|
|
358
|
+
onClick: cancelEdit
|
|
359
|
+
})}
|
|
344
360
|
</form>
|
|
345
361
|
</div>
|
|
346
362
|
);
|
|
@@ -355,14 +371,16 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
355
371
|
|
|
356
372
|
let iconClass = "fa-regular fa-file icon";
|
|
357
373
|
|
|
358
|
-
if (typeof
|
|
374
|
+
if (typeof node.status != "undefined") {
|
|
359
375
|
className = `page status-${this.node().status}`;
|
|
360
376
|
}
|
|
361
377
|
|
|
362
378
|
if (node.id && node.locale && this.permitted("edit")) {
|
|
363
|
-
pageName =
|
|
364
|
-
{this.
|
|
365
|
-
|
|
379
|
+
pageName = (
|
|
380
|
+
<a href={this.editUrl(node)} className="name">
|
|
381
|
+
{this.pageName()}
|
|
382
|
+
</a>
|
|
383
|
+
);
|
|
366
384
|
}
|
|
367
385
|
|
|
368
386
|
if (node.news_page) {
|
|
@@ -384,11 +402,9 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
384
402
|
|
|
385
403
|
statusLabel() {
|
|
386
404
|
const labels = ["Draft", "Reviewed", "Published", "Hidden", "Deleted"];
|
|
387
|
-
if (typeof
|
|
405
|
+
if (typeof this.node().status != "undefined" && this.node().status != 2) {
|
|
388
406
|
return (
|
|
389
|
-
<span className="status-label">
|
|
390
|
-
({labels[this.node().status]})
|
|
391
|
-
</span>
|
|
407
|
+
<span className="status-label">({labels[this.node().status]})</span>
|
|
392
408
|
);
|
|
393
409
|
} else {
|
|
394
410
|
return "";
|
|
@@ -397,9 +413,9 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
397
413
|
|
|
398
414
|
toggleStatus() {
|
|
399
415
|
if (this.node().status != 2) {
|
|
400
|
-
this.updatePage({status: 2});
|
|
416
|
+
this.updatePage({ status: 2 });
|
|
401
417
|
} else {
|
|
402
|
-
this.updatePage({status: 3});
|
|
418
|
+
this.updatePage({ status: 3 });
|
|
403
419
|
}
|
|
404
420
|
}
|
|
405
421
|
|
|
@@ -411,7 +427,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
|
411
427
|
|
|
412
428
|
visibleChildren(): PageNode[] {
|
|
413
429
|
if (this.node().children) {
|
|
414
|
-
return this.node().children.filter(p => p.status != 4);
|
|
430
|
+
return this.node().children.filter((p) => p.status != 4);
|
|
415
431
|
} else {
|
|
416
432
|
return [];
|
|
417
433
|
}
|
|
@@ -3,13 +3,13 @@ import { TreeNode } from "../../lib/Tree";
|
|
|
3
3
|
export type Attributes = Record<string, unknown>;
|
|
4
4
|
|
|
5
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
|
|
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
15
|
}
|