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
|
@@ -25,8 +25,7 @@ function hideDraggable(draggable: Draggable | null, callback: () => void) {
|
|
|
25
25
|
const result = callback();
|
|
26
26
|
draggable.ref.current.style.display = prevDisplay;
|
|
27
27
|
return result;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
28
|
+
} else {
|
|
30
29
|
return callback();
|
|
31
30
|
}
|
|
32
31
|
}
|
|
@@ -36,67 +35,62 @@ function insertFiles(state: Draggable[], files: Draggable[]): Draggable[] {
|
|
|
36
35
|
if (index === -1 || !files) {
|
|
37
36
|
return state;
|
|
38
37
|
} else {
|
|
39
|
-
return [
|
|
40
|
-
...state.slice(0, index),
|
|
41
|
-
...files,
|
|
42
|
-
...state.slice(index + 1)
|
|
43
|
-
];
|
|
38
|
+
return [...state.slice(0, index), ...files, ...state.slice(index + 1)];
|
|
44
39
|
}
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
function dragCollectionReducer(
|
|
48
|
-
state: Draggable[],
|
|
43
|
+
state: Draggable[],
|
|
44
|
+
action: DragCollectionAction
|
|
49
45
|
): Draggable[] {
|
|
50
46
|
switch (action.type) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
case "updatePositions":
|
|
62
|
-
return hideDraggable(action.payload, () => {
|
|
63
|
-
return state.map(d => {
|
|
64
|
-
return { ...d, rect: getPosition(d) };
|
|
47
|
+
case "append":
|
|
48
|
+
return [...state, ...(action.payload as Draggable[])];
|
|
49
|
+
case "prepend":
|
|
50
|
+
return [...(action.payload as Draggable[]), ...state];
|
|
51
|
+
case "insertFiles":
|
|
52
|
+
return insertFiles(state, action.payload);
|
|
53
|
+
case "update":
|
|
54
|
+
return state.map((d) => {
|
|
55
|
+
return d.handle === action.payload.handle ? action.payload : d;
|
|
65
56
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
57
|
+
case "updatePositions":
|
|
58
|
+
return hideDraggable(action.payload, () => {
|
|
59
|
+
return state.map((d) => {
|
|
60
|
+
return { ...d, rect: getPosition(d) };
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
case "remove":
|
|
64
|
+
return state.filter((d) => d.handle !== action.payload.handle);
|
|
65
|
+
case "replace":
|
|
66
|
+
return action.payload;
|
|
67
|
+
case "reorder":
|
|
68
|
+
return action.payload;
|
|
69
|
+
default:
|
|
70
|
+
return state;
|
|
75
71
|
}
|
|
76
72
|
}
|
|
77
73
|
|
|
78
74
|
export function createDraggable(record: Record<string, unknown>): Draggable {
|
|
79
|
-
return {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
return {
|
|
76
|
+
record: record,
|
|
77
|
+
rect: null,
|
|
78
|
+
ref: createRef(),
|
|
79
|
+
handle: uniqueId("draggable")
|
|
80
|
+
};
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
export default function useDragCollection(
|
|
86
84
|
records: DraggableRecord[]
|
|
87
85
|
): DragCollection {
|
|
88
86
|
const containerRef = useRef<HTMLElement>(null);
|
|
89
|
-
const [draggables, dispatch] = useReducer(
|
|
90
|
-
|
|
91
|
-
[],
|
|
92
|
-
() => records.map(r => createDraggable(r))
|
|
87
|
+
const [draggables, dispatch] = useReducer(dragCollectionReducer, [], () =>
|
|
88
|
+
records.map((r) => createDraggable(r))
|
|
93
89
|
) as [Draggables, (Draggables) => Draggable[]];
|
|
94
90
|
|
|
95
91
|
useEffect(() => {
|
|
96
92
|
dispatch({ type: "updatePositions" });
|
|
97
93
|
}, []);
|
|
98
94
|
|
|
99
|
-
return { ref: containerRef,
|
|
100
|
-
draggables: draggables,
|
|
101
|
-
dispatch: dispatch };
|
|
95
|
+
return { ref: containerRef, draggables: draggables, dispatch: dispatch };
|
|
102
96
|
}
|
|
@@ -51,13 +51,14 @@ export default function useDragUploader(
|
|
|
51
51
|
) {
|
|
52
52
|
const initialState: DragState = {
|
|
53
53
|
dragging: false,
|
|
54
|
-
x: null,
|
|
54
|
+
x: null,
|
|
55
|
+
y: null
|
|
55
56
|
};
|
|
56
57
|
|
|
57
58
|
const [dragState, setDragState] = useState(initialState);
|
|
58
59
|
|
|
59
60
|
const updatePositions = (dragging: Draggable | null) => {
|
|
60
|
-
collections.forEach(c => {
|
|
61
|
+
collections.forEach((c) => {
|
|
61
62
|
c.dispatch({ type: "updatePositions", payload: dragging });
|
|
62
63
|
});
|
|
63
64
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { Draggable, DragState } from "./drag/types";
|
|
2
|
-
export {
|
|
3
|
-
|
|
2
|
+
export {
|
|
3
|
+
default as useDragCollection,
|
|
4
|
+
createDraggable
|
|
5
|
+
} from "./drag/useDragCollection";
|
|
4
6
|
export { default as useDragUploader } from "./drag/useDragUploader";
|
|
5
7
|
export { default as useDraggable } from "./drag/useDraggable";
|
|
6
|
-
export { default as draggedOrder,
|
|
7
|
-
collectionOrder } from "./drag/draggedOrder";
|
|
8
|
+
export { default as draggedOrder, collectionOrder } from "./drag/draggedOrder";
|
|
@@ -42,7 +42,11 @@ export default class MainController extends Controller {
|
|
|
42
42
|
if ("dataset" in evt.target && "tab" in evt.target.dataset) {
|
|
43
43
|
const tab = evt.target.dataset.tab as string;
|
|
44
44
|
this.showTab(tab);
|
|
45
|
-
history.pushState(
|
|
45
|
+
history.pushState(
|
|
46
|
+
{ tabId: tab },
|
|
47
|
+
"",
|
|
48
|
+
`${window.location.pathname}#${tab}`
|
|
49
|
+
);
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -64,7 +68,7 @@ export default class MainController extends Controller {
|
|
|
64
68
|
});
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
tabNames
|
|
71
|
+
tabNames(): string[] {
|
|
68
72
|
return this.linkTargets.map((l) => l.dataset.tab);
|
|
69
73
|
}
|
|
70
74
|
}
|
|
@@ -2,7 +2,12 @@ import { Controller } from "@hotwired/stimulus";
|
|
|
2
2
|
|
|
3
3
|
export default class PageOptionsController extends Controller {
|
|
4
4
|
static get targets() {
|
|
5
|
-
return [
|
|
5
|
+
return [
|
|
6
|
+
"advancedOptions",
|
|
7
|
+
"autoPublishNotice",
|
|
8
|
+
"published",
|
|
9
|
+
"publishedDate"
|
|
10
|
+
];
|
|
6
11
|
}
|
|
7
12
|
|
|
8
13
|
connect() {
|
|
@@ -32,7 +37,7 @@ export default class PageOptionsController extends Controller {
|
|
|
32
37
|
};
|
|
33
38
|
return new Date(
|
|
34
39
|
lookup("year"),
|
|
35
|
-
|
|
40
|
+
lookup("month") - 1,
|
|
36
41
|
lookup("day"),
|
|
37
42
|
lookup("hour"),
|
|
38
43
|
lookup("minute")
|
|
@@ -4,27 +4,29 @@ import RichTextArea from "../components/RichTextArea";
|
|
|
4
4
|
import readyHandler from "../lib/readyHandler";
|
|
5
5
|
|
|
6
6
|
class RichText {
|
|
7
|
-
apply
|
|
7
|
+
apply() {
|
|
8
8
|
const elems = document.querySelectorAll("textarea.rich");
|
|
9
9
|
elems.forEach((elem) => {
|
|
10
10
|
this.enhance(elem);
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
enhance
|
|
14
|
+
enhance(elem: HTMLTextAreaElement) {
|
|
15
15
|
const container = document.createElement("div");
|
|
16
16
|
elem.parentNode.appendChild(container);
|
|
17
17
|
createRoot(container).render(
|
|
18
|
-
<RichTextArea
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
<RichTextArea
|
|
19
|
+
value={elem.value}
|
|
20
|
+
name={elem.name}
|
|
21
|
+
rows={elem.rows}
|
|
22
|
+
id={elem.id}
|
|
23
|
+
/>,
|
|
22
24
|
container
|
|
23
25
|
);
|
|
24
26
|
elem.parentNode.removeChild(elem);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
start
|
|
29
|
+
start() {
|
|
28
30
|
readyHandler.ready(() => {
|
|
29
31
|
this.apply();
|
|
30
32
|
});
|
data/app/javascript/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ export function registerComponent(name: string, component: FC) {
|
|
|
16
16
|
window[name] = component;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export default function startPages
|
|
19
|
+
export default function startPages() {
|
|
20
20
|
startRails();
|
|
21
21
|
for (const name in Components) {
|
|
22
22
|
registerComponent(name, Components[name] as FC);
|
|
@@ -35,5 +35,7 @@ export * from "./hooks";
|
|
|
35
35
|
export * from "./stores";
|
|
36
36
|
|
|
37
37
|
export * from "./lib/request";
|
|
38
|
-
export {
|
|
39
|
-
|
|
38
|
+
export {
|
|
39
|
+
default as copyToClipboard,
|
|
40
|
+
copySupported
|
|
41
|
+
} from "./lib/copyToClipboard";
|
data/app/javascript/lib/Tree.ts
CHANGED
|
@@ -54,19 +54,19 @@ export type TreeId = number | string;
|
|
|
54
54
|
type MovePlacement = "before" | "after" | "prepend" | "append";
|
|
55
55
|
|
|
56
56
|
export interface TreeNode {
|
|
57
|
-
children: TreeNode[]
|
|
58
|
-
collapsed: boolean
|
|
57
|
+
children: TreeNode[];
|
|
58
|
+
collapsed: boolean;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
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
|
|
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
70
|
}
|
|
71
71
|
|
|
72
72
|
function indexName(id: number | string): string {
|
|
@@ -114,13 +114,13 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
114
114
|
});
|
|
115
115
|
parent.children = children;
|
|
116
116
|
|
|
117
|
-
children.forEach(function(id, i) {
|
|
117
|
+
children.forEach(function (id, i) {
|
|
118
118
|
const index = indexes[indexName(id)];
|
|
119
119
|
if (i > 0) {
|
|
120
120
|
index.prev = children[i - 1];
|
|
121
121
|
}
|
|
122
|
-
if (i < children.length-1) {
|
|
123
|
-
index.next = children[i+1];
|
|
122
|
+
if (i < children.length - 1) {
|
|
123
|
+
index.next = children[i + 1];
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
};
|
|
@@ -173,10 +173,10 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
173
173
|
const index = this.getIndex(id);
|
|
174
174
|
index.prev = index.next = null;
|
|
175
175
|
if (i > 0) {
|
|
176
|
-
index.prev = children[i-1];
|
|
176
|
+
index.prev = children[i - 1];
|
|
177
177
|
}
|
|
178
|
-
if (i < children.length-1) {
|
|
179
|
-
index.next = children[i+1];
|
|
178
|
+
if (i < children.length - 1) {
|
|
179
|
+
index.next = children[i + 1];
|
|
180
180
|
}
|
|
181
181
|
});
|
|
182
182
|
}
|
|
@@ -213,7 +213,7 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
213
213
|
const destIndex = this.getIndex(destId);
|
|
214
214
|
const parentId = destIndex.parent;
|
|
215
215
|
const i = this.getIndex(parentId).children.indexOf(destId);
|
|
216
|
-
return this.insert(obj, parentId, i+1);
|
|
216
|
+
return this.insert(obj, parentId, i + 1);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
prepend(obj: N, destId: TreeId): TreeIndex<N> {
|
|
@@ -237,7 +237,10 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
237
237
|
root.left = left++;
|
|
238
238
|
|
|
239
239
|
const walk = (
|
|
240
|
-
children: TreeIndex<N>[],
|
|
240
|
+
children: TreeIndex<N>[],
|
|
241
|
+
parent: TreeIndex<N>,
|
|
242
|
+
left: number,
|
|
243
|
+
collapsed: boolean
|
|
241
244
|
) => {
|
|
242
245
|
let height = 1;
|
|
243
246
|
children.forEach((id: TreeId) => {
|
|
@@ -254,7 +257,7 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
254
257
|
height += walk(
|
|
255
258
|
node.children,
|
|
256
259
|
node,
|
|
257
|
-
left+1,
|
|
260
|
+
left + 1,
|
|
258
261
|
collapsed || node.node.collapsed
|
|
259
262
|
);
|
|
260
263
|
} else {
|
|
@@ -263,7 +266,7 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
263
266
|
}
|
|
264
267
|
});
|
|
265
268
|
|
|
266
|
-
if(parent.node.collapsed) parent.height = 1;
|
|
269
|
+
if (parent.node.collapsed) parent.height = 1;
|
|
267
270
|
else parent.height = height;
|
|
268
271
|
return parent.height;
|
|
269
272
|
};
|
|
@@ -285,9 +288,9 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
285
288
|
index = this.insertBefore(obj, toId);
|
|
286
289
|
} else if (placement === "after") {
|
|
287
290
|
index = this.insertAfter(obj, toId);
|
|
288
|
-
} else if(placement === "prepend") {
|
|
291
|
+
} else if (placement === "prepend") {
|
|
289
292
|
index = this.prepend(obj, toId);
|
|
290
|
-
} else if(placement === "append") {
|
|
293
|
+
} else if (placement === "append") {
|
|
291
294
|
index = this.append(obj, toId);
|
|
292
295
|
}
|
|
293
296
|
|
|
@@ -305,9 +308,9 @@ export default class Tree<N extends TreeNode = TreeNode> {
|
|
|
305
308
|
|
|
306
309
|
getNodeByTop(top) {
|
|
307
310
|
const indexes = this.indexes;
|
|
308
|
-
for(const id in indexes) {
|
|
311
|
+
for (const id in indexes) {
|
|
309
312
|
if (Object.prototype.hasOwnProperty.call(indexes, id)) {
|
|
310
|
-
if(indexes[id].top === top) {
|
|
313
|
+
if (indexes[id].top === top) {
|
|
311
314
|
return indexes[id];
|
|
312
315
|
}
|
|
313
316
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export function copySupported
|
|
2
|
-
return
|
|
3
|
-
document.queryCommandSupported("copy")
|
|
1
|
+
export function copySupported() {
|
|
2
|
+
return (
|
|
3
|
+
document.queryCommandSupported && document.queryCommandSupported("copy")
|
|
4
|
+
);
|
|
4
5
|
}
|
|
5
6
|
|
|
6
|
-
export default function copyToClipboard
|
|
7
|
+
export default function copyToClipboard(str: string) {
|
|
7
8
|
const el = document.createElement("textarea");
|
|
8
9
|
el.value = str;
|
|
9
10
|
document.body.appendChild(el);
|
|
@@ -4,18 +4,18 @@ const readyHandlers: ReadyHandlerFunc[] = [];
|
|
|
4
4
|
|
|
5
5
|
const handleState = () => {
|
|
6
6
|
if (["interactive", "complete"].indexOf(document.readyState) > -1) {
|
|
7
|
-
while(readyHandlers.length > 0) {
|
|
8
|
-
|
|
7
|
+
while (readyHandlers.length > 0) {
|
|
8
|
+
readyHandlers.shift()();
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
class ReadyHandler {
|
|
14
|
-
constructor
|
|
14
|
+
constructor() {
|
|
15
15
|
document.onreadystatechange = handleState;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
ready
|
|
18
|
+
ready(handler: ReadyHandlerFunc) {
|
|
19
19
|
readyHandlers.push(handler);
|
|
20
20
|
handleState();
|
|
21
21
|
}
|
|
@@ -9,9 +9,13 @@ export function csrfToken(): string {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function jsonFetchOptions() {
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return {
|
|
13
|
+
method: "POST",
|
|
14
|
+
headers: {
|
|
15
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
16
|
+
"X-CSRF-Token": csrfToken()
|
|
17
|
+
}
|
|
18
|
+
};
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
export async function postJson(url: string, data: Record<string, unknown>) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
2
|
|
|
3
3
|
interface ModalState {
|
|
4
|
-
component: JSX.Element | null
|
|
5
|
-
open: (elem: JSX.Element) => void
|
|
6
|
-
close: () => void
|
|
4
|
+
component: JSX.Element | null;
|
|
5
|
+
open: (elem: JSX.Element) => void;
|
|
6
|
+
close: () => void;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const useModalStore = create<ModalState>((set) => ({
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
2
|
|
|
3
3
|
export interface Toast {
|
|
4
|
-
type: string
|
|
5
|
-
message: string
|
|
4
|
+
type: string;
|
|
5
|
+
message: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
interface ToastState {
|
|
9
|
-
toasts: Toast[]
|
|
10
|
-
error: (msg: string) => void
|
|
11
|
-
notice: (msg: string) => void
|
|
12
|
-
next: () => void
|
|
9
|
+
toasts: Toast[];
|
|
10
|
+
error: (msg: string) => void;
|
|
11
|
+
notice: (msg: string) => void;
|
|
12
|
+
next: () => void;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const useToastStore = create<ToastState>((set) => ({
|
|
16
16
|
toasts: [],
|
|
17
|
-
error: (msg: string) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
error: (msg: string) =>
|
|
18
|
+
set((state) => ({
|
|
19
|
+
toasts: [...state.toasts, { message: msg, type: "error" }]
|
|
20
|
+
})),
|
|
21
|
+
notice: (msg: string) =>
|
|
22
|
+
set((state) => ({
|
|
23
|
+
toasts: [...state.toasts, { message: msg, type: "notice" }]
|
|
24
|
+
})),
|
|
23
25
|
next: () => set((state) => ({ toasts: state.toasts.slice(1) }))
|
|
24
26
|
}));
|
|
25
27
|
|
data/app/javascript/types.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
export interface Locale {
|
|
2
|
-
name: string
|
|
3
|
-
dir: "ltr" | "rtl"
|
|
2
|
+
name: string;
|
|
3
|
+
dir: "ltr" | "rtl";
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export interface AttachmentResource {
|
|
7
|
-
id: number | null
|
|
8
|
-
name: Record<string, string
|
|
9
|
-
description: Record<string, string
|
|
10
|
-
url: string
|
|
7
|
+
id: number | null;
|
|
8
|
+
name: Record<string, string>;
|
|
9
|
+
description: Record<string, string>;
|
|
10
|
+
url: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface ImageResource {
|
|
14
|
-
id: number | null
|
|
15
|
-
alternative: Record<string, string
|
|
16
|
-
caption: Record<string, string
|
|
17
|
-
content_type: string
|
|
18
|
-
filename: string
|
|
19
|
-
crop_start_x: number | null
|
|
20
|
-
crop_start_y: number | null
|
|
21
|
-
crop_width: number | null
|
|
22
|
-
crop_height: number | null
|
|
23
|
-
crop_gravity_x: number
|
|
24
|
-
crop_gravity_y: number
|
|
25
|
-
real_width: number
|
|
26
|
-
real_height: number
|
|
27
|
-
original_url: string
|
|
28
|
-
thumbnail_url: string
|
|
29
|
-
uncropped_url: string
|
|
14
|
+
id: number | null;
|
|
15
|
+
alternative: Record<string, string>;
|
|
16
|
+
caption: Record<string, string>;
|
|
17
|
+
content_type: string;
|
|
18
|
+
filename: string;
|
|
19
|
+
crop_start_x: number | null;
|
|
20
|
+
crop_start_y: number | null;
|
|
21
|
+
crop_width: number | null;
|
|
22
|
+
crop_height: number | null;
|
|
23
|
+
crop_gravity_x: number;
|
|
24
|
+
crop_gravity_y: number;
|
|
25
|
+
real_width: number;
|
|
26
|
+
real_height: number;
|
|
27
|
+
original_url: string;
|
|
28
|
+
thumbnail_url: string;
|
|
29
|
+
uncropped_url: string;
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<% content_for :page_title, "Deleted pages" %>
|
|
2
2
|
|
|
3
3
|
<% content_for :page_description do %>
|
|
4
|
-
<%= link_to("All pages", admin_pages_path(
|
|
4
|
+
<%= link_to("All pages", admin_pages_path(content_locale)) %> /
|
|
5
5
|
Deleted pages
|
|
6
6
|
<% end %>
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<td class="name">
|
|
23
23
|
<%= link_to_if(policy(page).edit?,
|
|
24
24
|
page_name(page),
|
|
25
|
-
edit_admin_page_url(
|
|
25
|
+
edit_admin_page_url(content_locale, page),
|
|
26
26
|
class: 'name_link') %>
|
|
27
27
|
</td>
|
|
28
28
|
<td>
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
Editing
|
|
10
10
|
<% @page.ancestors.reverse.each do |page| %>
|
|
11
11
|
<%= link_to(page.name? ? page.name : tag.i("Untitled"),
|
|
12
|
-
edit_admin_page_path(
|
|
12
|
+
edit_admin_page_path(content_locale, page)) %>
|
|
13
13
|
»
|
|
14
14
|
<% end %>
|
|
15
15
|
<%= link_to(@page.name? ? @page.name : tag.i("Untitled"),
|
|
16
|
-
edit_admin_page_path(
|
|
16
|
+
edit_admin_page_path(content_locale, @page)) %>
|
|
17
17
|
<% end %>
|
|
18
18
|
|
|
19
19
|
<% content_for :page_description_links do %>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
<% content_for :main_wrapper do %>
|
|
24
24
|
<%= form_for(@page,
|
|
25
|
-
url: admin_page_url(
|
|
25
|
+
url: admin_page_url(content_locale, @page),
|
|
26
26
|
builder: PagesCore::Admin::FormBuilder,
|
|
27
27
|
html: {
|
|
28
28
|
class: "edit-page main-wrapper",
|