pages_core 3.12.0 → 3.12.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,20 +1,24 @@
|
|
1
1
|
import { useEffect, useState } from "react";
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
import { Draggable, DragCollection, DragState, Position } from "./types";
|
4
|
+
|
5
|
+
function containsFiles(evt: Event) {
|
6
|
+
if ("dataTransfer" in evt) {
|
7
|
+
const dataTransfer: DataTransfer = evt.dataTransfer;
|
8
|
+
if ("types" in dataTransfer) {
|
9
|
+
const types = dataTransfer.types;
|
10
|
+
for (let i = 0; i < types.length; i++) {
|
11
|
+
if (types[i] === "Files" || types[i] === "application/x-moz-file") {
|
12
|
+
return true;
|
13
|
+
}
|
14
|
+
}
|
11
15
|
}
|
12
16
|
}
|
13
17
|
return false;
|
14
18
|
}
|
15
19
|
|
16
|
-
function getFiles(dt) {
|
17
|
-
|
20
|
+
function getFiles(dt: DataTransfer): File[] {
|
21
|
+
const files: File[] = [];
|
18
22
|
if (dt.items) {
|
19
23
|
for (let i = 0; i < dt.items.length; i++) {
|
20
24
|
if (dt.items[i].kind == "file") {
|
@@ -29,36 +33,41 @@ function getFiles(dt) {
|
|
29
33
|
return files;
|
30
34
|
}
|
31
35
|
|
32
|
-
function mousePosition(evt) {
|
33
|
-
|
34
|
-
if (evt.type == "touchmove") {
|
36
|
+
function mousePosition(evt: TouchEvent | MouseEvent): Position {
|
37
|
+
let x: number | null, y: number | null;
|
38
|
+
if ("touches" in evt && evt.type == "touchmove") {
|
35
39
|
x = evt.touches[0].clientX;
|
36
40
|
y = evt.touches[0].clientY;
|
37
|
-
} else {
|
41
|
+
} else if (evt instanceof MouseEvent) {
|
38
42
|
x = evt.clientX;
|
39
43
|
y = evt.clientY;
|
40
44
|
}
|
41
45
|
return { x: x, y: y };
|
42
46
|
}
|
43
47
|
|
44
|
-
export default function useDragUploader(
|
45
|
-
|
48
|
+
export default function useDragUploader(
|
49
|
+
collections: DragCollection[],
|
50
|
+
onDragEnd: (dragState: DragState, files: File[]) => void
|
51
|
+
) {
|
52
|
+
const initialState: DragState = {
|
46
53
|
dragging: false,
|
47
54
|
x: null, y: null
|
48
|
-
}
|
55
|
+
};
|
56
|
+
|
57
|
+
const [dragState, setDragState] = useState(initialState);
|
49
58
|
|
50
|
-
const updatePositions = (dragging) => {
|
59
|
+
const updatePositions = (dragging: Draggable | null) => {
|
51
60
|
collections.forEach(c => {
|
52
61
|
c.dispatch({ type: "updatePositions", payload: dragging });
|
53
62
|
});
|
54
63
|
};
|
55
64
|
|
56
|
-
const startDrag = (evt, draggable) => {
|
65
|
+
const startDrag = (evt: Event, draggable: Draggable) => {
|
57
66
|
updatePositions(draggable);
|
58
67
|
setDragState({ dragging: draggable, ...mousePosition(evt) });
|
59
68
|
};
|
60
69
|
|
61
|
-
const drag = (evt) => {
|
70
|
+
const drag = (evt: Event) => {
|
62
71
|
if (dragState.dragging) {
|
63
72
|
evt.stopPropagation();
|
64
73
|
evt.preventDefault();
|
@@ -70,13 +79,13 @@ export default function useDragUploader(collections, onDragEnd) {
|
|
70
79
|
}
|
71
80
|
};
|
72
81
|
|
73
|
-
const dragEnd = (evt) => {
|
82
|
+
const dragEnd = (evt: Event) => {
|
74
83
|
if (dragState.dragging) {
|
75
84
|
const prevDragState = dragState;
|
76
|
-
|
77
|
-
evt.preventDefault();
|
85
|
+
let files: File[] = [];
|
78
86
|
evt.stopPropagation();
|
79
|
-
|
87
|
+
evt.preventDefault();
|
88
|
+
if ("dataTransfer" in evt && dragState.dragging == "Files") {
|
80
89
|
files = getFiles(evt.dataTransfer);
|
81
90
|
}
|
82
91
|
setDragState({ dragging: false, x: null, y: null });
|
@@ -85,7 +94,7 @@ export default function useDragUploader(collections, onDragEnd) {
|
|
85
94
|
}
|
86
95
|
};
|
87
96
|
|
88
|
-
const dragLeave = (evt) => {
|
97
|
+
const dragLeave = (evt: Event) => {
|
89
98
|
if (dragState.dragging === "Files") {
|
90
99
|
evt.preventDefault();
|
91
100
|
evt.stopPropagation();
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
2
|
+
import { Draggable } from "./types";
|
3
|
+
|
4
|
+
export default function useDraggable(
|
5
|
+
draggable: Draggable,
|
6
|
+
startDrag: (evt: React.MouseEvent, draggable: Draggable) => void
|
7
|
+
) {
|
8
|
+
const ref = useRef<HTMLDivElement>(null);
|
9
|
+
|
10
|
+
const handleDrag = (evt: Event) => {
|
11
|
+
evt.preventDefault();
|
12
|
+
evt.stopPropagation();
|
13
|
+
startDrag(evt, draggable);
|
14
|
+
};
|
15
|
+
|
16
|
+
useEffect(() => {
|
17
|
+
draggable.ref.current = ref.current;
|
18
|
+
}, []);
|
19
|
+
|
20
|
+
return { ref: ref, onDragStart: handleDrag, draggable: true };
|
21
|
+
}
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
|
-
export default class EditPageController extends Controller {
|
3
|
+
export default class EditPageController extends Controller<HTMLFormElement> {
|
4
|
+
readonly formTarget: HTMLFormElement;
|
5
|
+
|
4
6
|
static get targets() {
|
5
7
|
return ["form"];
|
6
8
|
}
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
3
|
export default class LoginController extends Controller {
|
4
|
+
readonly tabTargets: HTMLDivElement[];
|
5
|
+
|
4
6
|
static get targets() {
|
5
7
|
return ["tab"];
|
6
8
|
}
|
@@ -12,12 +14,14 @@ export default class LoginController extends Controller {
|
|
12
14
|
}
|
13
15
|
|
14
16
|
|
15
|
-
changeTab(evt) {
|
17
|
+
changeTab(evt: Event) {
|
16
18
|
evt.preventDefault();
|
17
|
-
|
19
|
+
if ("dataset" in evt.target && "tab" in evt.target.dataset) {
|
20
|
+
this.showTab(evt.target.dataset.tab);
|
21
|
+
}
|
18
22
|
}
|
19
23
|
|
20
|
-
showTab(tab) {
|
24
|
+
showTab(tab: string) {
|
21
25
|
this.tabTargets.forEach((t) => {
|
22
26
|
if (t.dataset.tab == tab) {
|
23
27
|
t.classList.remove("hidden");
|
@@ -1,18 +1,21 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
3
|
export default class MainController extends Controller {
|
4
|
+
readonly linkTargets: HTMLLinkElement[];
|
5
|
+
readonly tabTargets: HTMLDivElement[];
|
6
|
+
|
4
7
|
static get targets() {
|
5
8
|
return ["tab", "link"];
|
6
9
|
}
|
7
10
|
|
8
11
|
connect() {
|
9
|
-
|
12
|
+
const tabs = this.tabNames();
|
10
13
|
if (tabs.length > 0) {
|
11
|
-
let initTab = null;
|
14
|
+
let initTab: string = null;
|
12
15
|
const tabExpression = /#(.*)$/;
|
13
16
|
|
14
17
|
if (document.location.toString().match(tabExpression)) {
|
15
|
-
|
18
|
+
const id = document.location.toString().match(tabExpression)[1];
|
16
19
|
if (tabs.indexOf(id) !== -1) {
|
17
20
|
initTab = id;
|
18
21
|
}
|
@@ -21,27 +24,29 @@ export default class MainController extends Controller {
|
|
21
24
|
this.showTab(initTab || tabs[0]);
|
22
25
|
}
|
23
26
|
|
24
|
-
window.addEventListener("popstate", this.stateHandler
|
27
|
+
window.addEventListener("popstate", this.stateHandler);
|
25
28
|
}
|
26
29
|
|
27
30
|
disconnect() {
|
28
|
-
window.removeEventListener("popstate", this.stateHandler
|
31
|
+
window.removeEventListener("popstate", this.stateHandler);
|
29
32
|
}
|
30
33
|
|
31
|
-
stateHandler(evt) {
|
32
|
-
if (
|
34
|
+
stateHandler = (evt: Event) => {
|
35
|
+
if ("state" in evt && "tabId" in evt.state) {
|
33
36
|
this.showTab(evt.state.tabId);
|
34
37
|
}
|
35
|
-
}
|
38
|
+
};
|
36
39
|
|
37
|
-
changeTab(evt) {
|
40
|
+
changeTab(evt: Event) {
|
38
41
|
evt.preventDefault();
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
if ("dataset" in evt.target && "tab" in evt.target.dataset) {
|
43
|
+
const tab = evt.target.dataset.tab as string;
|
44
|
+
this.showTab(tab);
|
45
|
+
history.pushState({ tabId: tab }, "", `${window.location.pathname}#${tab}`);
|
46
|
+
}
|
42
47
|
}
|
43
48
|
|
44
|
-
showTab(tab) {
|
49
|
+
showTab(tab: string | null) {
|
45
50
|
this.linkTargets.forEach((l) => {
|
46
51
|
if (l.dataset.tab == tab) {
|
47
52
|
l.classList.add("current");
|
@@ -59,7 +64,7 @@ export default class MainController extends Controller {
|
|
59
64
|
});
|
60
65
|
}
|
61
66
|
|
62
|
-
tabNames () {
|
67
|
+
tabNames (): string[] {
|
63
68
|
return this.linkTargets.map((l) => l.dataset.tab);
|
64
69
|
}
|
65
70
|
}
|
@@ -1,6 +1,7 @@
|
|
1
|
-
import
|
1
|
+
import { start as startRails } from "@rails/ujs";
|
2
2
|
import { Application } from "@hotwired/stimulus";
|
3
|
-
|
3
|
+
import "react_ujs";
|
4
|
+
import { FC } from "react";
|
4
5
|
|
5
6
|
import * as Components from "./components";
|
6
7
|
|
@@ -11,14 +12,14 @@ import PageOptionsController from "./controllers/PageOptionsController";
|
|
11
12
|
|
12
13
|
import RichText from "./features/RichText";
|
13
14
|
|
14
|
-
export function registerComponent(name, component) {
|
15
|
+
export function registerComponent(name: string, component: FC) {
|
15
16
|
window[name] = component;
|
16
17
|
}
|
17
18
|
|
18
19
|
export default function startPages () {
|
19
|
-
|
20
|
-
for (
|
21
|
-
registerComponent(name, Components[name]);
|
20
|
+
startRails();
|
21
|
+
for (const name in Components) {
|
22
|
+
registerComponent(name, Components[name] as FC);
|
22
23
|
}
|
23
24
|
RichText.start();
|
24
25
|
|
@@ -33,6 +34,6 @@ export * from "./components";
|
|
33
34
|
export * from "./hooks";
|
34
35
|
export * from "./stores";
|
35
36
|
|
36
|
-
export * from "./lib/request
|
37
|
+
export * from "./lib/request";
|
37
38
|
export { default as copyToClipboard,
|
38
39
|
copySupported } from "./lib/copyToClipboard";
|
@@ -48,43 +48,65 @@
|
|
48
48
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
49
49
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
50
50
|
SOFTWARE.
|
51
|
-
*/
|
51
|
+
*/
|
52
52
|
|
53
|
-
export
|
54
|
-
|
53
|
+
export type TreeId = number | string;
|
54
|
+
type MovePlacement = "before" | "after" | "prepend" | "append";
|
55
|
+
|
56
|
+
export interface TreeNode {
|
57
|
+
children: TreeNode[],
|
58
|
+
collapsed: boolean
|
59
|
+
}
|
60
|
+
|
61
|
+
export interface TreeIndex<T extends TreeNode = TreeNode> {
|
62
|
+
id: number,
|
63
|
+
node: T,
|
64
|
+
children: TreeIndex<T>[],
|
65
|
+
parent: TreeIndex<T>
|
66
|
+
next: TreeIndex<T> | null,
|
67
|
+
prev: TreeIndex<T> | null,
|
68
|
+
top: number,
|
69
|
+
height: number
|
70
|
+
}
|
71
|
+
|
72
|
+
function indexName(id: number | string): string {
|
73
|
+
return `${id}`;
|
74
|
+
}
|
75
|
+
|
76
|
+
export default class Tree<N extends TreeNode = TreeNode> {
|
77
|
+
cnt: number;
|
78
|
+
obj: N;
|
79
|
+
indexes: Record<string, TreeIndex<N>>;
|
80
|
+
|
81
|
+
constructor(obj: N) {
|
55
82
|
this.cnt = 1;
|
56
83
|
this.obj = obj || { children: [] };
|
57
84
|
this.indexes = {};
|
58
85
|
this.build(this.obj);
|
59
86
|
}
|
60
87
|
|
61
|
-
build(obj) {
|
62
|
-
|
63
|
-
|
64
|
-
var self = this;
|
88
|
+
build(obj: N): TreeIndex<N> {
|
89
|
+
const indexes = this.indexes;
|
90
|
+
const startId = this.cnt;
|
65
91
|
|
66
|
-
|
67
|
-
indexes[this.cnt
|
92
|
+
const index = { id: startId, node: obj };
|
93
|
+
indexes[indexName(this.cnt)] = index;
|
68
94
|
this.cnt++;
|
69
95
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
var children = [];
|
76
|
-
objs.forEach(function(obj) {
|
77
|
-
var index = {};
|
78
|
-
index.id = self.cnt;
|
96
|
+
const walk = (objs: TreeIndex<N>[], parent: TreeIndex<N>) => {
|
97
|
+
const children: TreeIndex<N>[] = [];
|
98
|
+
objs.forEach((obj) => {
|
99
|
+
const index: TreeIndex<N> = {};
|
100
|
+
index.id = this.cnt;
|
79
101
|
index.node = obj;
|
80
102
|
|
81
103
|
if (parent) {
|
82
104
|
index.parent = parent.id;
|
83
105
|
}
|
84
106
|
|
85
|
-
indexes[
|
86
|
-
children.push(
|
87
|
-
|
107
|
+
indexes[indexName(this.cnt)] = index;
|
108
|
+
children.push(this.cnt);
|
109
|
+
this.cnt++;
|
88
110
|
|
89
111
|
if (obj.children && obj.children.length) {
|
90
112
|
walk(obj.children, index);
|
@@ -93,7 +115,7 @@ export default class Tree {
|
|
93
115
|
parent.children = children;
|
94
116
|
|
95
117
|
children.forEach(function(id, i) {
|
96
|
-
|
118
|
+
const index = indexes[indexName(id)];
|
97
119
|
if (i > 0) {
|
98
120
|
index.prev = children[i - 1];
|
99
121
|
}
|
@@ -101,56 +123,54 @@ export default class Tree {
|
|
101
123
|
index.next = children[i+1];
|
102
124
|
}
|
103
125
|
});
|
126
|
+
};
|
127
|
+
|
128
|
+
if (obj.children && obj.children.length) {
|
129
|
+
walk(obj.children, index);
|
104
130
|
}
|
105
131
|
|
106
132
|
return index;
|
107
133
|
}
|
108
134
|
|
109
|
-
getIndex(id) {
|
110
|
-
|
111
|
-
if (index) {
|
112
|
-
return index;
|
113
|
-
}
|
135
|
+
getIndex(id: TreeId): TreeIndex<N> {
|
136
|
+
return this.indexes[indexName(id)];
|
114
137
|
}
|
115
138
|
|
116
|
-
removeIndex(index) {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
function del(index) {
|
121
|
-
delete self.indexes[index.id + ""];
|
139
|
+
removeIndex(index: TreeIndex<N>) {
|
140
|
+
const del = (index: TreeIndex<N>) => {
|
141
|
+
delete this.indexes[indexName(index.id)];
|
122
142
|
if (index.children && index.children.length) {
|
123
|
-
index.children.forEach(
|
124
|
-
del(
|
143
|
+
index.children.forEach((child) => {
|
144
|
+
del(this.getIndex(child));
|
125
145
|
});
|
126
146
|
}
|
127
|
-
}
|
147
|
+
};
|
148
|
+
del(index);
|
128
149
|
}
|
129
150
|
|
130
|
-
get(id) {
|
131
|
-
|
132
|
-
if (index && index.node) {
|
133
|
-
return index.node;
|
134
|
-
}
|
135
|
-
return null;
|
151
|
+
get(id: TreeId): N {
|
152
|
+
return this.getIndex(id).node;
|
136
153
|
}
|
137
154
|
|
138
|
-
remove(id) {
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
155
|
+
remove(id: TreeId): N {
|
156
|
+
const index = this.getIndex(id);
|
157
|
+
const node = this.get(id);
|
158
|
+
|
159
|
+
const parentIndex = this.getIndex(index.parent);
|
160
|
+
const parentNode = this.get(index.parent);
|
161
|
+
|
143
162
|
parentNode.children.splice(parentNode.children.indexOf(node), 1);
|
144
163
|
parentIndex.children.splice(parentIndex.children.indexOf(id), 1);
|
164
|
+
|
145
165
|
this.removeIndex(index);
|
146
166
|
this.updateChildren(parentIndex.children);
|
147
167
|
|
148
168
|
return node;
|
149
169
|
}
|
150
170
|
|
151
|
-
updateChildren(children) {
|
152
|
-
children.forEach(
|
153
|
-
|
171
|
+
updateChildren(children: TreeIndex<N>[]) {
|
172
|
+
children.forEach((id, i) => {
|
173
|
+
const index = this.getIndex(id);
|
154
174
|
index.prev = index.next = null;
|
155
175
|
if (i > 0) {
|
156
176
|
index.prev = children[i-1];
|
@@ -158,14 +178,14 @@ export default class Tree {
|
|
158
178
|
if (i < children.length-1) {
|
159
179
|
index.next = children[i+1];
|
160
180
|
}
|
161
|
-
}
|
181
|
+
});
|
162
182
|
}
|
163
183
|
|
164
|
-
insert(obj, parentId, i) {
|
165
|
-
|
166
|
-
|
184
|
+
insert(obj: N, parentId: TreeId, i: number): TreeIndex<N> {
|
185
|
+
const parentIndex = this.getIndex(parentId);
|
186
|
+
const parentNode = this.get(parentId);
|
167
187
|
|
168
|
-
|
188
|
+
const index = this.build(obj);
|
169
189
|
index.parent = parentId;
|
170
190
|
|
171
191
|
parentNode.children = parentNode.children || [];
|
@@ -182,26 +202,26 @@ export default class Tree {
|
|
182
202
|
return index;
|
183
203
|
}
|
184
204
|
|
185
|
-
insertBefore(obj, destId) {
|
186
|
-
|
187
|
-
|
188
|
-
|
205
|
+
insertBefore(obj: N, destId: TreeId): TreeIndex<N> {
|
206
|
+
const destIndex = this.getIndex(destId);
|
207
|
+
const parentId = destIndex.parent;
|
208
|
+
const i = this.getIndex(parentId).children.indexOf(destId);
|
189
209
|
return this.insert(obj, parentId, i);
|
190
210
|
}
|
191
211
|
|
192
|
-
insertAfter(obj, destId) {
|
193
|
-
|
194
|
-
|
195
|
-
|
212
|
+
insertAfter(obj: N, destId: TreeId): TreeIndex<N> {
|
213
|
+
const destIndex = this.getIndex(destId);
|
214
|
+
const parentId = destIndex.parent;
|
215
|
+
const i = this.getIndex(parentId).children.indexOf(destId);
|
196
216
|
return this.insert(obj, parentId, i+1);
|
197
217
|
}
|
198
218
|
|
199
|
-
prepend(obj, destId) {
|
219
|
+
prepend(obj: N, destId: TreeId): TreeIndex<N> {
|
200
220
|
return this.insert(obj, destId, 0);
|
201
221
|
}
|
202
222
|
|
203
|
-
append(obj, destId) {
|
204
|
-
|
223
|
+
append(obj: N, destId: TreeId): TreeIndex<N> {
|
224
|
+
const destIndex = this.getIndex(destId);
|
205
225
|
destIndex.children = destIndex.children || [];
|
206
226
|
return this.insert(obj, destId, destIndex.children.length);
|
207
227
|
}
|
@@ -209,22 +229,19 @@ export default class Tree {
|
|
209
229
|
// react-ui-tree methods
|
210
230
|
|
211
231
|
updateNodesPosition() {
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
var self = this;
|
232
|
+
let top = 1;
|
233
|
+
let left = 1;
|
234
|
+
const root = this.getIndex(1);
|
216
235
|
|
217
236
|
root.top = top++;
|
218
237
|
root.left = left++;
|
219
238
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
children.forEach(function(id) {
|
227
|
-
var node = self.getIndex(id);
|
239
|
+
const walk = (
|
240
|
+
children: TreeIndex<N>[], parent: TreeIndex<N>, left: number, collapsed: boolean
|
241
|
+
) => {
|
242
|
+
let height = 1;
|
243
|
+
children.forEach((id: TreeId) => {
|
244
|
+
const node = this.getIndex(id);
|
228
245
|
if (collapsed) {
|
229
246
|
node.top = null;
|
230
247
|
node.left = null;
|
@@ -249,16 +266,20 @@ export default class Tree {
|
|
249
266
|
if(parent.node.collapsed) parent.height = 1;
|
250
267
|
else parent.height = height;
|
251
268
|
return parent.height;
|
269
|
+
};
|
270
|
+
|
271
|
+
if (root.children && root.children.length) {
|
272
|
+
walk(root.children, root, left, root.node.collapsed);
|
252
273
|
}
|
253
274
|
}
|
254
275
|
|
255
|
-
move(fromId, toId, placement) {
|
276
|
+
move(fromId: TreeId, toId: TreeId, placement: MovePlacement): TreeIndex<N> {
|
256
277
|
if (fromId === toId || toId === 1) {
|
257
278
|
return;
|
258
279
|
}
|
259
280
|
|
260
|
-
|
261
|
-
|
281
|
+
const obj = this.remove(fromId);
|
282
|
+
let index: TreeIndex<N>;
|
262
283
|
|
263
284
|
if (placement === "before") {
|
264
285
|
index = this.insertBefore(obj, toId);
|
@@ -275,16 +296,16 @@ export default class Tree {
|
|
275
296
|
return index;
|
276
297
|
}
|
277
298
|
|
278
|
-
getParent(id) {
|
279
|
-
|
299
|
+
getParent(id: string) {
|
300
|
+
const indexes = this.indexes;
|
280
301
|
if (Object.prototype.hasOwnProperty.call(indexes, id)) {
|
281
302
|
return this.getIndex(indexes[id].parent);
|
282
303
|
}
|
283
304
|
}
|
284
305
|
|
285
306
|
getNodeByTop(top) {
|
286
|
-
|
287
|
-
for(
|
307
|
+
const indexes = this.indexes;
|
308
|
+
for(const id in indexes) {
|
288
309
|
if (Object.prototype.hasOwnProperty.call(indexes, id)) {
|
289
310
|
if(indexes[id].top === top) {
|
290
311
|
return indexes[id];
|
@@ -3,7 +3,7 @@ export function copySupported () {
|
|
3
3
|
document.queryCommandSupported("copy");
|
4
4
|
}
|
5
5
|
|
6
|
-
export default function copyToClipboard (str) {
|
6
|
+
export default function copyToClipboard (str: string) {
|
7
7
|
const el = document.createElement("textarea");
|
8
8
|
el.value = str;
|
9
9
|
document.body.appendChild(el);
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
type ReadyHandlerFunc = () => void;
|
2
|
+
|
3
|
+
const readyHandlers: ReadyHandlerFunc[] = [];
|
2
4
|
|
3
5
|
const handleState = () => {
|
4
6
|
if (["interactive", "complete"].indexOf(document.readyState) > -1) {
|
@@ -13,7 +15,7 @@ class ReadyHandler {
|
|
13
15
|
document.onreadystatechange = handleState;
|
14
16
|
}
|
15
17
|
|
16
|
-
ready (handler) {
|
18
|
+
ready (handler: ReadyHandlerFunc) {
|
17
19
|
readyHandlers.push(handler);
|
18
20
|
handleState();
|
19
21
|
}
|
@@ -1,5 +1,11 @@
|
|
1
|
-
export function csrfToken() {
|
2
|
-
|
1
|
+
export function csrfToken(): string {
|
2
|
+
const elem = document.querySelector("[name=csrf-token]");
|
3
|
+
|
4
|
+
if (!elem) {
|
5
|
+
return "";
|
6
|
+
}
|
7
|
+
|
8
|
+
return elem.getAttribute("content") || "";
|
3
9
|
}
|
4
10
|
|
5
11
|
function jsonFetchOptions() {
|
@@ -8,7 +14,7 @@ function jsonFetchOptions() {
|
|
8
14
|
"X-CSRF-Token": csrfToken() } });
|
9
15
|
}
|
10
16
|
|
11
|
-
export async function postJson(url, data) {
|
17
|
+
export async function postJson(url: string, data: Record<string, unknown>) {
|
12
18
|
const options = { ...jsonFetchOptions(), method: "POST" };
|
13
19
|
if (data) {
|
14
20
|
options.body = JSON.stringify(data);
|
@@ -17,7 +23,7 @@ export async function postJson(url, data) {
|
|
17
23
|
return response.json();
|
18
24
|
}
|
19
25
|
|
20
|
-
export async function putJson(url, data) {
|
26
|
+
export async function putJson(url: string, data: Record<string, unknown>) {
|
21
27
|
const options = { ...jsonFetchOptions(), method: "PUT" };
|
22
28
|
if (data) {
|
23
29
|
options.body = JSON.stringify(data);
|
@@ -26,7 +32,7 @@ export async function putJson(url, data) {
|
|
26
32
|
return response.json();
|
27
33
|
}
|
28
34
|
|
29
|
-
export async function post(url, data) {
|
35
|
+
export async function post(url: string, data: Record<string, unknown>) {
|
30
36
|
const response = await fetch(url, {
|
31
37
|
method: "POST",
|
32
38
|
body: data,
|