pages_core 3.13.0 → 3.15.0
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 +19 -8
- data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
- data/app/assets/builds/pages_core/admin.css +704 -388
- data/app/assets/fonts/Inter-Black.woff2 +0 -0
- data/app/assets/fonts/Inter-BlackItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Bold.woff2 +0 -0
- data/app/assets/fonts/Inter-BoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraBold.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraLight.woff2 +0 -0
- data/app/assets/fonts/Inter-ExtraLightItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Italic.woff2 +0 -0
- data/app/assets/fonts/Inter-Light.woff2 +0 -0
- data/app/assets/fonts/Inter-LightItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Medium.woff2 +0 -0
- data/app/assets/fonts/Inter-MediumItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Regular.woff2 +0 -0
- data/app/assets/fonts/Inter-SemiBold.woff2 +0 -0
- data/app/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
- data/app/assets/fonts/Inter-Thin.woff2 +0 -0
- data/app/assets/fonts/Inter-ThinItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Black.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-BlackItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Bold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-BoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraBold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraBoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraLight.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ExtraLightItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Italic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Light.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-LightItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Medium.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-MediumItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Regular.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-SemiBold.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-SemiBoldItalic.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-Thin.woff2 +0 -0
- data/app/assets/fonts/InterDisplay-ThinItalic.woff2 +0 -0
- data/app/assets/fonts/InterVariable-Italic.woff2 +0 -0
- data/app/assets/fonts/InterVariable.woff2 +0 -0
- data/app/assets/stylesheets/pages_core/admin/components/archive.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/components/attachments.css +22 -34
- data/app/assets/stylesheets/pages_core/admin/components/base.css +1 -68
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +107 -48
- data/app/assets/stylesheets/pages_core/admin/components/header.css +56 -58
- data/app/assets/stylesheets/pages_core/admin/components/image_editor.css +35 -24
- data/app/assets/stylesheets/pages_core/admin/components/image_grid.css +28 -27
- data/app/assets/stylesheets/pages_core/admin/components/image_uploader.css +5 -5
- data/app/assets/stylesheets/pages_core/admin/components/layout.css +7 -1
- data/app/assets/stylesheets/pages_core/admin/components/list_table.css +24 -15
- data/app/assets/stylesheets/pages_core/admin/components/page_tree.css +63 -104
- data/app/assets/stylesheets/pages_core/admin/components/pagination.css +12 -13
- data/app/assets/stylesheets/pages_core/admin/components/search.css +1 -16
- data/app/assets/stylesheets/pages_core/admin/components/sidebar.css +5 -11
- data/app/assets/stylesheets/pages_core/admin/components/tag_editor.css +22 -36
- data/app/assets/stylesheets/pages_core/admin/components/toast.css +1 -2
- data/app/assets/stylesheets/pages_core/admin/components/toolbar.css +10 -10
- data/app/assets/stylesheets/pages_core/admin/components/totp.css +26 -0
- data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +37 -51
- data/app/assets/stylesheets/pages_core/admin/global/fonts.css +271 -0
- data/app/assets/stylesheets/pages_core/admin/global/typography.css +109 -0
- data/app/assets/stylesheets/pages_core/admin/vars.css +1 -3
- data/app/assets/stylesheets/pages_core/admin.postcss.css +1 -0
- data/app/controllers/admin/account_recoveries_controller.rb +87 -0
- data/app/controllers/admin/invites_controller.rb +3 -2
- data/app/controllers/admin/otp_secrets_controller.rb +45 -0
- data/app/controllers/admin/pages_controller.rb +22 -42
- data/app/controllers/admin/recovery_codes_controller.rb +32 -0
- data/app/controllers/admin/sessions_controller.rb +65 -0
- data/app/controllers/admin/users_controller.rb +2 -8
- data/app/controllers/concerns/pages_core/authentication.rb +12 -10
- data/app/controllers/concerns/pages_core/error_reporting.rb +1 -1
- data/app/controllers/concerns/pages_core/page_parameters.rb +29 -0
- data/app/controllers/concerns/pages_core/policies_helper.rb +1 -1
- data/app/controllers/concerns/pages_core/preview_pages_controller.rb +20 -20
- data/app/controllers/pages_core/admin_controller.rb +1 -3
- data/app/controllers/pages_core/frontend/pages_controller.rb +2 -6
- data/app/formatters/pages_core/html_formatter.rb +2 -4
- data/app/helpers/admin/menu_helper.rb +5 -4
- data/app/helpers/admin/pages_helper.rb +1 -21
- data/app/helpers/pages_core/admin/admin_helper.rb +13 -3
- data/app/helpers/pages_core/admin/content_tabs_helper.rb +1 -2
- data/app/helpers/pages_core/admin/labelled_field_helper.rb +1 -1
- data/app/helpers/pages_core/frontend_helper.rb +1 -1
- data/app/helpers/pages_core/images_helper.rb +10 -8
- data/app/helpers/pages_core/labelled_form_builder.rb +2 -7
- data/app/helpers/pages_core/page_path_helper.rb +1 -1
- data/app/javascript/components/Attachments/Attachment.tsx +20 -18
- data/app/javascript/components/Attachments/AttachmentEditor.tsx +11 -9
- data/app/javascript/components/{Attachments.jsx → Attachments/List.tsx} +58 -63
- data/app/javascript/components/Attachments/useAttachments.ts +15 -0
- data/app/javascript/components/Attachments.tsx +14 -0
- data/app/javascript/components/DateRangeSelect.tsx +105 -0
- data/app/javascript/components/DateTimeSelect.tsx +136 -0
- data/app/javascript/components/EditableImage.tsx +11 -9
- data/app/javascript/components/FileUploadButton.tsx +7 -7
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +9 -12
- data/app/javascript/components/ImageCropper/Image.tsx +10 -8
- data/app/javascript/components/ImageCropper/Toolbar.tsx +11 -12
- data/app/javascript/components/ImageCropper/useCrop.ts +24 -53
- data/app/javascript/components/ImageCropper.tsx +10 -15
- data/app/javascript/components/ImageEditor/Form.tsx +12 -8
- data/app/javascript/components/ImageEditor.tsx +12 -7
- data/app/javascript/components/ImageGrid/DragElement.tsx +9 -12
- data/app/javascript/components/{ImageGrid.jsx → ImageGrid/Grid.tsx} +62 -71
- data/app/javascript/components/ImageGrid/GridImage.tsx +22 -23
- data/app/javascript/components/ImageGrid/Placeholder.tsx +2 -2
- data/app/javascript/components/ImageGrid/useImageGrid.ts +26 -0
- data/app/javascript/components/ImageGrid.tsx +15 -0
- data/app/javascript/components/ImageUploader.tsx +35 -22
- data/app/javascript/components/LabelledField.tsx +34 -0
- data/app/javascript/components/Modal.tsx +2 -2
- data/app/javascript/components/PageForm/Block.tsx +81 -0
- data/app/javascript/components/PageForm/Content.tsx +54 -0
- data/app/javascript/components/PageForm/Dates.tsx +66 -0
- data/app/javascript/components/PageForm/Files.tsx +28 -0
- data/app/javascript/components/PageForm/Form.tsx +41 -0
- data/app/javascript/components/PageForm/Images.tsx +28 -0
- data/app/javascript/components/PageForm/LocaleLinks.tsx +36 -0
- data/app/javascript/components/PageForm/Metadata.tsx +67 -0
- data/app/javascript/components/PageForm/Options.tsx +180 -0
- data/app/javascript/components/PageForm/PageDescription.tsx +48 -0
- data/app/javascript/components/PageForm/PathSegment.tsx +65 -0
- data/app/javascript/components/PageForm/TabPanel.tsx +21 -0
- data/app/javascript/components/PageForm/Tabs.tsx +33 -0
- data/app/javascript/components/PageForm/UnconfiguredContent.tsx +42 -0
- data/app/javascript/components/PageForm/pageParams.ts +95 -0
- data/app/javascript/components/PageForm/preview.ts +23 -0
- data/app/javascript/components/PageForm/usePage.ts +169 -0
- data/app/javascript/components/PageForm/useTabs.ts +46 -0
- data/app/javascript/components/PageForm.tsx +163 -0
- data/app/javascript/components/PageImages.tsx +7 -9
- data/app/javascript/components/PageTree/Draggable.tsx +40 -39
- data/app/javascript/components/PageTree/Node.tsx +62 -56
- data/app/javascript/components/PageTree/PageName.tsx +28 -0
- data/app/javascript/components/PageTree.tsx +65 -53
- data/app/javascript/components/{RichTextArea.jsx → RichTextArea.tsx} +98 -79
- data/app/javascript/components/RichTextToolbarButton.tsx +4 -6
- data/app/javascript/components/TagEditor/AddTagForm.tsx +19 -12
- data/app/javascript/components/TagEditor/Editor.tsx +32 -0
- data/app/javascript/components/TagEditor/Tag.tsx +6 -4
- data/app/javascript/components/TagEditor/useTags.ts +58 -0
- data/app/javascript/components/TagEditor.tsx +8 -58
- data/app/javascript/components/Toast.tsx +3 -3
- data/app/javascript/components/drag/draggedOrder.ts +22 -14
- data/app/javascript/components/drag/useDragCollection.ts +35 -30
- data/app/javascript/components/drag/useDragUploader.ts +32 -21
- data/app/javascript/components/drag/useDraggable.ts +7 -6
- data/app/javascript/components/drag.ts +0 -1
- data/app/javascript/components.ts +1 -3
- data/app/javascript/features/RichText.tsx +2 -3
- data/app/javascript/features/contentTabs.ts +79 -0
- data/app/javascript/index.ts +5 -14
- data/app/javascript/lib/Tree.ts +31 -45
- data/app/javascript/lib/request.ts +11 -11
- data/app/javascript/stores/useToastStore.ts +1 -1
- data/app/javascript/types/Attachments.ts +29 -0
- data/app/javascript/types/Crop.ts +36 -0
- data/app/javascript/types/Drag.ts +34 -0
- data/app/javascript/types/Images.ts +47 -0
- data/app/javascript/types/PageEditor.ts +26 -0
- data/app/javascript/types/Pages.ts +75 -0
- data/app/javascript/types/Tags.ts +9 -0
- data/app/javascript/types/Template.ts +24 -0
- data/app/javascript/types/Trees.ts +19 -0
- data/app/javascript/types.ts +2 -25
- data/app/mailers/admin_mailer.rb +2 -2
- data/app/models/attachment.rb +1 -1
- data/app/models/concerns/pages_core/authenticable_user.rb +63 -0
- data/app/models/concerns/pages_core/emailable.rb +16 -0
- data/app/models/concerns/pages_core/page_model/templateable.rb +2 -16
- data/app/models/invite.rb +2 -6
- data/app/models/otp_secret.rb +101 -0
- data/app/models/page.rb +0 -3
- data/app/models/user.rb +2 -68
- data/app/policies/page_policy.rb +6 -2
- data/app/policies/user_policy.rb +4 -0
- data/app/resources/admin/page_resource.rb +95 -0
- data/app/resources/admin/page_tree_resource.rb +27 -0
- data/app/resources/admin/template_configuration_resource.rb +50 -0
- data/app/views/admin/account_recoveries/new.html.erb +22 -0
- data/app/views/admin/account_recoveries/show.html.erb +37 -0
- data/app/views/admin/invites/show.html.erb +1 -1
- data/app/views/admin/news/_sidebar.html.erb +2 -4
- data/app/views/admin/news/index.html.erb +0 -1
- data/app/views/admin/otp_secrets/create.html.erb +7 -0
- data/app/views/admin/otp_secrets/new.html.erb +60 -0
- data/app/views/admin/pages/_form.html.erb +10 -30
- data/app/views/admin/pages/_search_bar.html.erb +1 -1
- data/app/views/admin/pages/edit.html.erb +1 -57
- data/app/views/admin/pages/index.html.erb +1 -1
- data/app/views/admin/pages/new.html.erb +1 -44
- data/app/views/admin/recovery_codes/_codes.html.erb +14 -0
- data/app/views/admin/recovery_codes/create.html.erb +7 -0
- data/app/views/admin/recovery_codes/new.html.erb +11 -0
- data/app/views/admin/sessions/_otp_form.html.erb +13 -0
- data/app/views/admin/sessions/new.html.erb +31 -0
- data/app/views/admin/sessions/verify_otp.html.erb +19 -0
- data/app/views/admin/users/_access_control.html.erb +5 -1
- data/app/views/admin/users/_list.html.erb +12 -7
- data/app/views/admin/users/edit.html.erb +31 -1
- data/app/views/admin/users/new.html.erb +1 -1
- data/app/views/admin_mailer/account_recovery.text.erb +10 -0
- data/app/views/layouts/admin/_header.html.erb +3 -5
- data/app/views/layouts/admin/_page_header.html.erb +1 -2
- data/app/views/layouts/admin/_toast.html.erb +12 -0
- data/app/views/layouts/admin.html.erb +2 -2
- data/config/locales/en.yml +11 -7
- data/config/routes.rb +13 -12
- data/db/migrate/20240126160700_add_2fa_fields.rb +26 -0
- data/db/migrate/20240129201300_remove_password_reset_tokens.rb +13 -0
- data/db/migrate/20240131140700_change_email_to_citext.rb +18 -0
- data/db/migrate/20240201160700_remove_persistent_data.rb +7 -0
- data/db/migrate/20240508145300_remove_categories.rb +21 -0
- data/lib/pages_core/configuration/base.rb +2 -2
- data/lib/pages_core/templates/configuration.rb +1 -1
- data/lib/pages_core/templates/configuration_proxy.rb +2 -2
- data/lib/pages_core/templates/template_configuration.rb +11 -1
- data/lib/pages_core/templates.rb +6 -4
- data/lib/pages_core/version.rb +1 -1
- data/lib/pages_core.rb +6 -0
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/gridOverlay.ts +6 -7
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/responsiveEmbeds.ts +17 -12
- data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +0 -2
- data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +3 -4
- metadata +143 -35
- data/app/assets/stylesheets/pages_core/admin/components/login.css +0 -33
- data/app/controllers/admin/categories_controller.rb +0 -56
- data/app/controllers/admin/password_resets_controller.rb +0 -85
- data/app/controllers/concerns/pages_core/admin/persistent_params.rb +0 -75
- data/app/controllers/sessions_controller.rb +0 -27
- data/app/helpers/pages_core/admin/page_blocks_helper.rb +0 -66
- data/app/helpers/pages_core/admin/page_json_helper.rb +0 -23
- data/app/javascript/components/DateRangeSelect.jsx +0 -225
- data/app/javascript/components/PageDates.jsx +0 -73
- data/app/javascript/components/PageFiles.jsx +0 -25
- data/app/javascript/components/PageTree/types.ts +0 -15
- data/app/javascript/components/drag/types.ts +0 -28
- data/app/javascript/controllers/EditPageController.ts +0 -22
- data/app/javascript/controllers/LoginController.ts +0 -32
- data/app/javascript/controllers/MainController.ts +0 -74
- data/app/javascript/controllers/PageOptionsController.js +0 -67
- data/app/models/category.rb +0 -22
- data/app/models/page_category.rb +0 -6
- data/app/models/password_reset_token.rb +0 -34
- data/app/views/admin/pages/_edit_content.html.erb +0 -19
- data/app/views/admin/pages/_edit_files.html.erb +0 -4
- data/app/views/admin/pages/_edit_images.html.erb +0 -4
- data/app/views/admin/pages/_edit_metadata.html.erb +0 -35
- data/app/views/admin/pages/_edit_options.html.erb +0 -91
- data/app/views/admin/password_resets/show.html.erb +0 -21
- data/app/views/admin/users/login.html.erb +0 -65
- data/app/views/admin_mailer/password_reset.text.erb +0 -11
- data/lib/rails/generators/pages_core/rspec/templates/mailer_macros.rb +0 -11
@@ -26,12 +26,15 @@
|
|
26
26
|
*/
|
27
27
|
|
28
28
|
import React, { Component } from "react";
|
29
|
-
|
30
|
-
import
|
29
|
+
|
30
|
+
import Tree from "../../lib/Tree";
|
31
|
+
import * as Trees from "../../types/Trees";
|
32
|
+
import * as Pages from "../../types/Pages";
|
33
|
+
|
31
34
|
import Node from "./Node";
|
32
35
|
|
33
36
|
interface DragState {
|
34
|
-
id
|
37
|
+
id?: Trees.Id;
|
35
38
|
x: number | null;
|
36
39
|
y: number | null;
|
37
40
|
w: number | null;
|
@@ -40,35 +43,35 @@ interface DragState {
|
|
40
43
|
scrollLeft: number | null;
|
41
44
|
}
|
42
45
|
|
43
|
-
interface
|
44
|
-
addChild: (
|
46
|
+
interface Props {
|
47
|
+
addChild: (id: Trees.Id, attrs: Pages.TreeNode) => void;
|
45
48
|
dir: string;
|
46
49
|
locale: string;
|
47
|
-
movedPage: (id:
|
48
|
-
paddingLeft
|
49
|
-
toggleCollapsed: (id:
|
50
|
-
tree: Tree<
|
51
|
-
updatePage: (id:
|
50
|
+
movedPage: (id: Trees.Id) => void;
|
51
|
+
paddingLeft?: number;
|
52
|
+
toggleCollapsed: (id: Trees.Id) => void;
|
53
|
+
tree: Tree<Pages.TreeNode>;
|
54
|
+
updatePage: (id: Trees.Id, attributes: Partial<Pages.TreeItem>) => void;
|
52
55
|
updateTree: (Tree) => void;
|
53
56
|
}
|
54
57
|
|
55
|
-
interface
|
58
|
+
interface State {
|
56
59
|
dragging: DragState;
|
57
60
|
}
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
> {
|
62
|
+
const defaultPadding = 20;
|
63
|
+
|
64
|
+
export default class Draggable extends Component<Props, State> {
|
63
65
|
_dragListener: (evt: MouseEvent) => void;
|
64
66
|
_dragEndListener: () => void;
|
67
|
+
_start: boolean;
|
65
68
|
_startX: number;
|
66
69
|
_startY: number;
|
67
70
|
_offsetX: number;
|
68
71
|
_offsetY: number;
|
69
72
|
dragging: DragState;
|
70
73
|
|
71
|
-
constructor(props:
|
74
|
+
constructor(props: Props) {
|
72
75
|
super(props);
|
73
76
|
this.state = {
|
74
77
|
dragging: this.initDragging()
|
@@ -103,7 +106,8 @@ export default class Draggable extends Component<
|
|
103
106
|
<Node
|
104
107
|
tree={tree}
|
105
108
|
index={draggingIndex}
|
106
|
-
|
109
|
+
locale={this.props.locale}
|
110
|
+
paddingLeft={this.props.paddingLeft || defaultPadding}
|
107
111
|
/>
|
108
112
|
</div>
|
109
113
|
);
|
@@ -127,9 +131,9 @@ export default class Draggable extends Component<
|
|
127
131
|
tree={tree}
|
128
132
|
index={root}
|
129
133
|
key={root.id}
|
130
|
-
paddingLeft={this.props.paddingLeft}
|
131
|
-
addChild={(
|
132
|
-
onDragStart={
|
134
|
+
paddingLeft={this.props.paddingLeft || defaultPadding}
|
135
|
+
addChild={(idx: Trees.Index<Pages.TreeNode>) => this.addChild(idx)}
|
136
|
+
onDragStart={this.dragStart}
|
133
137
|
onCollapse={(nodeId) => this.toggleCollapse(nodeId)}
|
134
138
|
updatePage={(idx, attrs) => this.updatePage(idx, attrs)}
|
135
139
|
dragging={dragging && dragging.id}
|
@@ -141,21 +145,21 @@ export default class Draggable extends Component<
|
|
141
145
|
}
|
142
146
|
}
|
143
147
|
|
144
|
-
addChild(parent:
|
145
|
-
const newNode = {
|
146
|
-
name: "",
|
148
|
+
addChild(parent: Trees.Index<Pages.TreeNode>) {
|
149
|
+
const newNode: Pages.TreeNode = {
|
150
|
+
blocks: { name: { [this.props.locale]: "" } },
|
147
151
|
status: 0,
|
148
152
|
editing: true,
|
149
153
|
children: [],
|
150
154
|
published_at: new Date(),
|
151
155
|
pinned: false,
|
152
|
-
|
153
|
-
|
156
|
+
parent_page_id: parent.node.id,
|
157
|
+
collapsed: false
|
154
158
|
};
|
155
159
|
this.props.addChild(parent.id, newNode);
|
156
160
|
}
|
157
161
|
|
158
|
-
prevAddButtonCount(tree: Tree, index:
|
162
|
+
prevAddButtonCount(tree: Tree, index: Trees.Index) {
|
159
163
|
let count = 0;
|
160
164
|
const parentNodes = [];
|
161
165
|
let pointer = tree.getIndex(index.parent);
|
@@ -171,7 +175,8 @@ export default class Draggable extends Component<
|
|
171
175
|
if (
|
172
176
|
parentNodes.indexOf(pointer) == -1 &&
|
173
177
|
!pointer.node.collapsed &&
|
174
|
-
pointer.node.children.filter((p) => p.status != 4)
|
178
|
+
pointer.node.children.filter((p: Pages.TreeNode) => p.status != 4)
|
179
|
+
.length > 0
|
175
180
|
) {
|
176
181
|
count += 1;
|
177
182
|
}
|
@@ -206,8 +211,8 @@ export default class Draggable extends Component<
|
|
206
211
|
|
207
212
|
const tree = this.props.tree;
|
208
213
|
const dragging = this.state.dragging;
|
209
|
-
const paddingLeft = this.props.paddingLeft;
|
210
|
-
let newIndex:
|
214
|
+
const paddingLeft = this.props.paddingLeft || defaultPadding;
|
215
|
+
let newIndex: Trees.Index<Pages.TreeNode> = null;
|
211
216
|
let index = tree.getIndex(dragging.id);
|
212
217
|
const collapsed = index.node.collapsed;
|
213
218
|
|
@@ -239,7 +244,7 @@ export default class Draggable extends Component<
|
|
239
244
|
if ("prev" in index) {
|
240
245
|
const prev = tree.getIndex(index.prev);
|
241
246
|
|
242
|
-
if (!prev.node.
|
247
|
+
if (!prev.node.collapsed) {
|
243
248
|
newIndex = tree.move(index.id, index.prev, "append");
|
244
249
|
}
|
245
250
|
}
|
@@ -278,7 +283,7 @@ export default class Draggable extends Component<
|
|
278
283
|
this.setState({ dragging: dragging });
|
279
284
|
}
|
280
285
|
|
281
|
-
dragStart(id:
|
286
|
+
dragStart = (id: Trees.Id, dom: HTMLDivElement, e: React.MouseEvent) => {
|
282
287
|
// Only drag on left click
|
283
288
|
if (e.button !== 0) {
|
284
289
|
return;
|
@@ -300,14 +305,14 @@ export default class Draggable extends Component<
|
|
300
305
|
this._offsetY = e.clientY;
|
301
306
|
this._start = true;
|
302
307
|
|
303
|
-
this._dragListener = (e:
|
308
|
+
this._dragListener = (e: MouseEvent) => {
|
304
309
|
this.drag(e);
|
305
310
|
};
|
306
311
|
this._dragEndListener = () => this.dragEnd();
|
307
312
|
|
308
313
|
window.addEventListener("mousemove", this._dragListener);
|
309
314
|
window.addEventListener("mouseup", this._dragEndListener);
|
310
|
-
}
|
315
|
+
};
|
311
316
|
|
312
317
|
dragEnd() {
|
313
318
|
if (!this._start) {
|
@@ -323,15 +328,11 @@ export default class Draggable extends Component<
|
|
323
328
|
window.removeEventListener("mouseup", this._dragEndListener);
|
324
329
|
}
|
325
330
|
|
326
|
-
toggleCollapse(nodeId:
|
331
|
+
toggleCollapse(nodeId: Trees.Id) {
|
327
332
|
this.props.toggleCollapsed(nodeId);
|
328
333
|
}
|
329
334
|
|
330
|
-
updatePage(index:
|
335
|
+
updatePage(index: Trees.Index, attributes: Partial<Pages.TreeItem>) {
|
331
336
|
this.props.updatePage(index.id, attributes);
|
332
337
|
}
|
333
338
|
}
|
334
|
-
|
335
|
-
Draggable.defaultProps = {
|
336
|
-
paddingLeft: 15
|
337
|
-
};
|
@@ -25,39 +25,54 @@
|
|
25
25
|
SOFTWARE.
|
26
26
|
*/
|
27
27
|
|
28
|
-
import React, {
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
import React, {
|
29
|
+
createRef,
|
30
|
+
ChangeEvent,
|
31
|
+
Component,
|
32
|
+
CSSProperties,
|
33
|
+
FormEvent,
|
34
|
+
MouseEvent,
|
35
|
+
RefObject
|
36
|
+
} from "react";
|
37
|
+
|
38
|
+
import Tree from "../../lib/Tree";
|
39
|
+
import * as Trees from "../../types/Trees";
|
40
|
+
import * as Pages from "../../types/Pages";
|
41
|
+
|
42
|
+
import PageName from "./PageName";
|
43
|
+
|
44
|
+
interface Props {
|
45
|
+
index: Trees.Index<Pages.TreeNode>;
|
40
46
|
paddingLeft: number;
|
41
|
-
tree: Tree<
|
42
|
-
|
47
|
+
tree: Tree<Pages.TreeNode>;
|
48
|
+
addChild?: (index: Trees.Index<Pages.TreeNode>) => void;
|
49
|
+
dir?: string;
|
50
|
+
dragging?: Trees.Id;
|
51
|
+
locale: string;
|
52
|
+
onCollapse?: (id: Trees.Id) => void;
|
53
|
+
onDragStart?: (id: number, element: HTMLDivElement, evt: MouseEvent) => void;
|
54
|
+
updatePage?: (
|
55
|
+
index: Trees.Index<Pages.TreeNode>,
|
56
|
+
attributes: Partial<Pages.TreeItem>
|
57
|
+
) => void;
|
43
58
|
}
|
44
59
|
|
45
|
-
interface
|
60
|
+
interface State {
|
46
61
|
newName: string;
|
47
62
|
}
|
48
63
|
|
49
64
|
interface ButtonOptions {
|
50
65
|
icon: string;
|
51
66
|
className: string;
|
52
|
-
onClick: (evt:
|
67
|
+
onClick: (evt: MouseEvent) => void;
|
53
68
|
}
|
54
69
|
|
55
|
-
export default class Node extends Component<
|
70
|
+
export default class Node extends Component<Props, State> {
|
56
71
|
innerRef: RefObject<HTMLDivElement>;
|
57
72
|
|
58
|
-
constructor(props:
|
73
|
+
constructor(props: Props) {
|
59
74
|
super(props);
|
60
|
-
this.state = { newName:
|
75
|
+
this.state = { newName: this.pageName() };
|
61
76
|
this.innerRef = createRef<HTMLDivElement>();
|
62
77
|
}
|
63
78
|
|
@@ -136,7 +151,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
136
151
|
(node.root || this.visibleChildren().length > 0)
|
137
152
|
) {
|
138
153
|
return this.button("Add page here", {
|
139
|
-
className: "add add-inline",
|
154
|
+
className: "add add-inline transparent",
|
140
155
|
icon: "plus",
|
141
156
|
onClick: handleClick
|
142
157
|
});
|
@@ -160,7 +175,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
160
175
|
const { index, tree, dragging, dir, locale } = this.props;
|
161
176
|
|
162
177
|
if (index.children && index.children.length && !index.node.collapsed) {
|
163
|
-
const childrenStyles = {};
|
178
|
+
const childrenStyles: CSSProperties = {};
|
164
179
|
if (index.node.collapsed) {
|
165
180
|
childrenStyles.display = "none";
|
166
181
|
}
|
@@ -201,7 +216,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
201
216
|
return null;
|
202
217
|
}
|
203
218
|
|
204
|
-
const handleCollapse = (e:
|
219
|
+
const handleCollapse = (e: MouseEvent) => {
|
205
220
|
e.stopPropagation();
|
206
221
|
const nodeId = this.props.index.id;
|
207
222
|
if (this.props.onCollapse) {
|
@@ -211,17 +226,17 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
211
226
|
|
212
227
|
if (this.visibleChildren().length > 0) {
|
213
228
|
const collapsed = index.node.collapsed;
|
214
|
-
|
229
|
+
const classnames = ["collapse fa-solid fa-caret-right"];
|
215
230
|
|
216
231
|
if (collapsed) {
|
217
|
-
classnames
|
232
|
+
classnames.push("collapsed");
|
218
233
|
} else {
|
219
|
-
classnames
|
234
|
+
classnames.push("open");
|
220
235
|
}
|
221
236
|
|
222
237
|
return (
|
223
238
|
<i
|
224
|
-
className={classnames}
|
239
|
+
className={classnames.join(" ")}
|
225
240
|
onMouseDown={function (e) {
|
226
241
|
e.stopPropagation();
|
227
242
|
}}
|
@@ -260,22 +275,16 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
260
275
|
this.updatePage({ editing: true });
|
261
276
|
}
|
262
277
|
|
263
|
-
editUrl(page:
|
264
|
-
return `/admin/${
|
278
|
+
editUrl(page: Pages.TreeNode) {
|
279
|
+
return `/admin/${this.props.locale}/pages/${page.id}/edit`;
|
265
280
|
}
|
266
281
|
|
267
|
-
node():
|
282
|
+
node(): Pages.TreeNode {
|
268
283
|
return this.props.index.node;
|
269
284
|
}
|
270
285
|
|
271
286
|
pageName() {
|
272
|
-
|
273
|
-
|
274
|
-
return (
|
275
|
-
<span dir={this.props.dir} lang={this.props.locale}>
|
276
|
-
{name}
|
277
|
-
</span>
|
278
|
-
);
|
287
|
+
return this.node().blocks.name[this.props.locale];
|
279
288
|
}
|
280
289
|
|
281
290
|
render() {
|
@@ -291,7 +300,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
291
300
|
classnames = "node placeholder";
|
292
301
|
}
|
293
302
|
|
294
|
-
const handleMouseDown = (e:
|
303
|
+
const handleMouseDown = (e: MouseEvent) => {
|
295
304
|
if (this.permitted("edit") && !editing && props.onDragStart) {
|
296
305
|
props.onDragStart(props.index.id, this.innerRef.current, e);
|
297
306
|
}
|
@@ -323,24 +332,25 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
323
332
|
this.setState({ newName: event.target.value });
|
324
333
|
};
|
325
334
|
|
326
|
-
const performEdit = (event:
|
335
|
+
const performEdit = (event: FormEvent) => {
|
327
336
|
event.preventDefault();
|
328
337
|
this.updatePage({
|
329
|
-
name: this.state.newName,
|
338
|
+
blocks: { name: { [locale]: this.state.newName } },
|
330
339
|
editing: false
|
331
340
|
});
|
332
341
|
};
|
333
342
|
|
334
343
|
const cancelEdit = () => {
|
335
|
-
this.setState({ newName: this.
|
344
|
+
this.setState({ newName: this.pageName() });
|
336
345
|
this.updatePage({ editing: false });
|
337
346
|
};
|
338
347
|
|
339
348
|
return (
|
340
349
|
<div className="page edit">
|
341
350
|
<i className="fa-regular fa-file icon"></i>
|
342
|
-
<form onSubmit={performEdit}>
|
351
|
+
<form className="edit-name" onSubmit={performEdit}>
|
343
352
|
<input
|
353
|
+
className="tight"
|
344
354
|
type="text"
|
345
355
|
value={this.state.newName}
|
346
356
|
dir={dir}
|
@@ -348,7 +358,7 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
348
358
|
autoFocus
|
349
359
|
onChange={handleNameChange}
|
350
360
|
/>
|
351
|
-
<button className="save" type="submit">
|
361
|
+
<button className="save primary" type="submit">
|
352
362
|
<i className="fa-solid fa-cloud icon"></i>
|
353
363
|
Save
|
354
364
|
</button>
|
@@ -366,7 +376,6 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
366
376
|
const index = this.props.index;
|
367
377
|
const node = index.node;
|
368
378
|
|
369
|
-
let pageName = <span className="name">{this.pageName()}</span>;
|
370
379
|
let className = "page";
|
371
380
|
|
372
381
|
let iconClass = "fa-regular fa-file icon";
|
@@ -375,24 +384,21 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
375
384
|
className = `page status-${this.node().status}`;
|
376
385
|
}
|
377
386
|
|
378
|
-
if (node.id && node.locale && this.permitted("edit")) {
|
379
|
-
pageName = (
|
380
|
-
<a href={this.editUrl(node)} className="name">
|
381
|
-
{this.pageName()}
|
382
|
-
</a>
|
383
|
-
);
|
384
|
-
}
|
385
|
-
|
386
387
|
if (node.news_page) {
|
387
|
-
iconClass = "fa-regular fa-file-lines icon";
|
388
|
+
iconClass = "fa-regular fa-file-lines page-icon";
|
388
389
|
} else if (node.pinned) {
|
389
|
-
iconClass = "fa-regular fa-flag icon";
|
390
|
+
iconClass = "fa-regular fa-flag page-icon";
|
390
391
|
}
|
391
392
|
|
392
393
|
return (
|
393
394
|
<div className={className}>
|
394
395
|
<i className={iconClass}></i>
|
395
|
-
|
396
|
+
<PageName
|
397
|
+
name={this.pageName()}
|
398
|
+
dir={this.props.dir}
|
399
|
+
locale={this.props.locale}
|
400
|
+
editUrl={node.id && this.permitted("edit") && this.editUrl(node)}
|
401
|
+
/>
|
396
402
|
{this.statusLabel()}
|
397
403
|
{this.collapsedLabel()}
|
398
404
|
{this.actions()}
|
@@ -419,13 +425,13 @@ export default class Node extends Component<NodeProps, NodeState> {
|
|
419
425
|
}
|
420
426
|
}
|
421
427
|
|
422
|
-
updatePage(attributes:
|
428
|
+
updatePage(attributes: Partial<Pages.TreeItem>) {
|
423
429
|
if (this.props.updatePage) {
|
424
430
|
return this.props.updatePage(this.props.index, attributes);
|
425
431
|
}
|
426
432
|
}
|
427
433
|
|
428
|
-
visibleChildren():
|
434
|
+
visibleChildren(): Pages.TreeNode[] {
|
429
435
|
if (this.node().children) {
|
430
436
|
return this.node().children.filter((p) => p.status != 4);
|
431
437
|
} else {
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import React from "react";
|
2
|
+
|
3
|
+
interface Props {
|
4
|
+
name: string;
|
5
|
+
locale: string;
|
6
|
+
dir?: string;
|
7
|
+
editUrl?: string;
|
8
|
+
}
|
9
|
+
|
10
|
+
export default function PageName(props: Props) {
|
11
|
+
const { name, locale, dir, editUrl } = props;
|
12
|
+
|
13
|
+
const span = (
|
14
|
+
<span dir={dir} lang={locale}>
|
15
|
+
{name || <i className="untitled">Untitled</i>}
|
16
|
+
</span>
|
17
|
+
);
|
18
|
+
|
19
|
+
if (editUrl) {
|
20
|
+
return (
|
21
|
+
<a href={editUrl} className="name">
|
22
|
+
{span}
|
23
|
+
</a>
|
24
|
+
);
|
25
|
+
} else {
|
26
|
+
return <span className="name">{span}</span>;
|
27
|
+
}
|
28
|
+
}
|