pages_core 3.12.3 → 3.12.5
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/pages_core/admin-dist.js +1 -44
- data/app/assets/builds/pages_core/admin-dist.js.map +3 -3
- data/app/assets/builds/pages_core/admin.css +79 -46
- 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 +17 -16
- 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
@@ -8,22 +8,22 @@ import { AttachmentResource, Locale } from "../../types";
|
|
8
8
|
import { useDraggable, Draggable } from "../drag";
|
9
9
|
|
10
10
|
interface Record {
|
11
|
-
id: number | null
|
12
|
-
attachment: AttachmentResource
|
13
|
-
uploading: boolean
|
11
|
+
id: number | null;
|
12
|
+
attachment: AttachmentResource;
|
13
|
+
uploading: boolean;
|
14
14
|
}
|
15
15
|
|
16
16
|
interface AttachmentProps {
|
17
|
-
attributeName: string
|
18
|
-
placeholder: boolean
|
19
|
-
draggable: { record: Record }
|
20
|
-
locale: string
|
21
|
-
locales: { [index: string]: Locale }
|
22
|
-
deleteRecord: () => void
|
23
|
-
showEmbed: boolean
|
24
|
-
position: number
|
25
|
-
onUpdate: (localizations: Record<string, Record<string, string>>) => void
|
26
|
-
startDrag: (evt: Event, draggable: Draggable) => void
|
17
|
+
attributeName: string;
|
18
|
+
placeholder: boolean;
|
19
|
+
draggable: { record: Record };
|
20
|
+
locale: string;
|
21
|
+
locales: { [index: string]: Locale };
|
22
|
+
deleteRecord: () => void;
|
23
|
+
showEmbed: boolean;
|
24
|
+
position: number;
|
25
|
+
onUpdate: (localizations: Record<string, Record<string, string>>) => void;
|
26
|
+
startDrag: (evt: Event, draggable: Draggable) => void;
|
27
27
|
}
|
28
28
|
|
29
29
|
export default function Attachment(props: AttachmentProps) {
|
@@ -70,7 +70,8 @@ export default function Attachment(props: AttachmentProps) {
|
|
70
70
|
attachment={attachment}
|
71
71
|
locale={locale}
|
72
72
|
locales={locales}
|
73
|
-
onUpdate={props.onUpdate}
|
73
|
+
onUpdate={props.onUpdate}
|
74
|
+
/>
|
74
75
|
);
|
75
76
|
};
|
76
77
|
|
@@ -90,44 +91,46 @@ export default function Attachment(props: AttachmentProps) {
|
|
90
91
|
}
|
91
92
|
|
92
93
|
return (
|
93
|
-
<div className={classes.join(" ")}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
<input
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
94
|
+
<div className={classes.join(" ")} {...listeners}>
|
95
|
+
<input
|
96
|
+
name={`${attributeName}[id]`}
|
97
|
+
type="hidden"
|
98
|
+
value={record.id || ""}
|
99
|
+
/>
|
100
|
+
<input
|
101
|
+
name={`${attributeName}[attachment_id]`}
|
102
|
+
type="hidden"
|
103
|
+
value={(attachment && attachment.id) || ""}
|
104
|
+
/>
|
105
|
+
<input
|
106
|
+
name={`${attributeName}[position]`}
|
107
|
+
type="hidden"
|
108
|
+
value={props.position}
|
109
|
+
/>
|
110
|
+
{!uploading && (
|
111
|
+
<div className="actions">
|
112
|
+
<button onClick={editAttachment}>Edit</button>
|
113
|
+
{props.showEmbed && <button onClick={copyEmbed}>Embed</button>}
|
114
|
+
{props.deleteRecord && <button onClick={deleteRecord}>Remove</button>}
|
115
|
+
</div>
|
116
|
+
)}
|
117
|
+
{attachment && (
|
118
|
+
<div className="attachment-info">
|
119
|
+
<h3>
|
120
|
+
<i className={`fa-solid fa-${icon} icon`} />
|
121
|
+
{name() || <em>Untitled</em>}
|
122
|
+
<br />
|
123
|
+
</h3>
|
124
|
+
{!uploading && (
|
125
|
+
<a href={attachment.url} rel="noreferrer" target="_blank">
|
126
|
+
{attachment.filename}
|
127
|
+
</a>
|
128
|
+
)}
|
129
|
+
{!uploading && description() && (
|
130
|
+
<p dir={localeDir}>{description()}</p>
|
131
|
+
)}
|
132
|
+
</div>
|
133
|
+
)}
|
131
134
|
</div>
|
132
135
|
);
|
133
136
|
}
|
@@ -6,10 +6,10 @@ import { AttachmentResource, Locale } from "../../types";
|
|
6
6
|
import { putJson } from "../../lib/request";
|
7
7
|
|
8
8
|
interface AttachmentEditorProps {
|
9
|
-
attachment: AttachmentResource
|
10
|
-
locale: string
|
11
|
-
locales: { [index: string]: Locale }
|
12
|
-
onUpdate: (localizations: Record<string, Record<string, string>>) => void
|
9
|
+
attachment: AttachmentResource;
|
10
|
+
locale: string;
|
11
|
+
locales: { [index: string]: Locale };
|
12
|
+
onUpdate: (localizations: Record<string, Record<string, string>>) => void;
|
13
13
|
}
|
14
14
|
|
15
15
|
export default function AttachmentEditor(props: AttachmentEditorProps) {
|
@@ -18,19 +18,19 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
|
|
18
18
|
const [locale, setLocale] = useState(props.locale);
|
19
19
|
const [localizations, setLocalizations] = useState({
|
20
20
|
name: attachment.name || {},
|
21
|
-
description: attachment.description || {}
|
21
|
+
description: attachment.description || {}
|
22
22
|
});
|
23
23
|
|
24
24
|
const notice = useToastStore((state) => state.notice);
|
25
25
|
const closeModal = useModalStore((state) => state.close);
|
26
26
|
|
27
|
-
const updateLocalization =
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
const updateLocalization =
|
28
|
+
(name: "name" | "description") => (evt: ChangeEvent<HTMLInputElement>) => {
|
29
|
+
setLocalizations({
|
30
|
+
...localizations,
|
31
|
+
[name]: { ...localizations[name], [locale]: evt.target.value }
|
32
|
+
});
|
33
|
+
};
|
34
34
|
|
35
35
|
const copyEmbedCode = (evt: Event) => {
|
36
36
|
evt.preventDefault();
|
@@ -59,13 +59,12 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
|
|
59
59
|
<form>
|
60
60
|
{props.locales && Object.keys(locales).length > 1 && (
|
61
61
|
<div className="field">
|
62
|
-
<label>
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
{Object.keys(locales).map(key => (
|
62
|
+
<label>Locale</label>
|
63
|
+
<select
|
64
|
+
name="locale"
|
65
|
+
value={locale}
|
66
|
+
onChange={(e) => setLocale(e.target.value)}>
|
67
|
+
{Object.keys(locales).map((key) => (
|
69
68
|
<option key={`locale-${key}`} value={key}>
|
70
69
|
{locales[key].name}
|
71
70
|
</option>
|
@@ -75,47 +74,43 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
|
|
75
74
|
)}
|
76
75
|
<div className="field">
|
77
76
|
<label>Name</label>
|
78
|
-
<input
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
<input
|
78
|
+
type="text"
|
79
|
+
className="name"
|
80
|
+
lang={locale}
|
81
|
+
dir={inputDir}
|
82
|
+
value={localizations.name[locale] || ""}
|
83
|
+
onChange={updateLocalization("name")}
|
84
|
+
/>
|
84
85
|
</div>
|
85
86
|
<div className="field">
|
86
87
|
<label>Description</label>
|
87
|
-
<textarea
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
88
|
+
<textarea
|
89
|
+
className="description"
|
90
|
+
value={localizations.description[locale] || ""}
|
91
|
+
lang={locale}
|
92
|
+
dir={inputDir}
|
93
|
+
onChange={updateLocalization("description")}
|
94
|
+
/>
|
92
95
|
</div>
|
93
96
|
<div className="field embed-code">
|
94
|
-
<label>
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
{copySupported() &&
|
101
|
-
<button onClick={copyEmbedCode}>
|
102
|
-
Copy
|
103
|
-
</button>
|
104
|
-
)}
|
97
|
+
<label>Embed code</label>
|
98
|
+
<input
|
99
|
+
type="text"
|
100
|
+
value={`[attachment:${attachment.id}]`}
|
101
|
+
disabled={true}
|
102
|
+
/>
|
103
|
+
{copySupported() && <button onClick={copyEmbedCode}>Copy</button>}
|
105
104
|
</div>
|
106
105
|
<div className="field">
|
107
106
|
<label>File</label>
|
108
|
-
<a href={attachment.url}
|
109
|
-
|
110
|
-
|
107
|
+
<a href={attachment.url} rel="noreferrer" target="_blank">
|
108
|
+
{attachment.filename}
|
109
|
+
</a>
|
111
110
|
</div>
|
112
111
|
<div className="buttons">
|
113
|
-
<button onClick={save}>
|
114
|
-
|
115
|
-
</button>
|
116
|
-
<button onClick={closeModal}>
|
117
|
-
Cancel
|
118
|
-
</button>
|
112
|
+
<button onClick={save}>Save</button>
|
113
|
+
<button onClick={closeModal}>Cancel</button>
|
119
114
|
</div>
|
120
115
|
</form>
|
121
116
|
</div>
|
@@ -5,10 +5,12 @@ import Placeholder from "./Attachments/Placeholder";
|
|
5
5
|
import FileUploadButton from "./FileUploadButton";
|
6
6
|
import { post } from "../lib/request";
|
7
7
|
|
8
|
-
import {
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
import {
|
9
|
+
createDraggable,
|
10
|
+
draggedOrder,
|
11
|
+
useDragCollection,
|
12
|
+
useDragUploader
|
13
|
+
} from "./drag";
|
12
14
|
|
13
15
|
function filenameToName(str) {
|
14
16
|
return str.replace(/\.[\w\d]+$/, "").replace(/_/g, " ");
|
@@ -16,18 +18,20 @@ function filenameToName(str) {
|
|
16
18
|
|
17
19
|
export default function Attachments(props) {
|
18
20
|
const collection = useDragCollection(props.records);
|
19
|
-
const locales =
|
20
|
-
|
21
|
+
const locales =
|
22
|
+
props.locales && props.locales.length > 0
|
23
|
+
? Object.keys(props.locales)
|
24
|
+
: [props.locale];
|
21
25
|
const [deleted, setDeleted] = useState([]);
|
22
26
|
|
23
27
|
const uploadAttachment = (file) => {
|
24
28
|
let name = {};
|
25
|
-
locales.forEach((l) => name[l] = file.name);
|
29
|
+
locales.forEach((l) => (name[l] = file.name));
|
26
30
|
|
27
|
-
const draggable = createDraggable(
|
28
|
-
|
29
|
-
|
30
|
-
);
|
31
|
+
const draggable = createDraggable({
|
32
|
+
attachment: { filename: file.name, name: name },
|
33
|
+
uploading: true
|
34
|
+
});
|
31
35
|
|
32
36
|
let data = new FormData();
|
33
37
|
|
@@ -36,14 +40,15 @@ export default function Attachments(props) {
|
|
36
40
|
data.append(`attachment[name][${l}]`, filenameToName(file.name));
|
37
41
|
});
|
38
42
|
|
39
|
-
post("/admin/attachments.json", data)
|
40
|
-
.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
}
|
43
|
+
post("/admin/attachments.json", data).then((json) => {
|
44
|
+
collection.dispatch({
|
45
|
+
type: "update",
|
46
|
+
payload: {
|
47
|
+
...draggable,
|
48
|
+
record: { attachment: json, uploading: false }
|
49
|
+
}
|
46
50
|
});
|
51
|
+
});
|
47
52
|
|
48
53
|
return draggable;
|
49
54
|
};
|
@@ -51,7 +56,7 @@ export default function Attachments(props) {
|
|
51
56
|
const receiveFiles = (files) => {
|
52
57
|
collection.dispatch({
|
53
58
|
type: "append",
|
54
|
-
payload: files.map(f => uploadAttachment(f))
|
59
|
+
payload: files.map((f) => uploadAttachment(f))
|
55
60
|
});
|
56
61
|
};
|
57
62
|
|
@@ -62,17 +67,21 @@ export default function Attachments(props) {
|
|
62
67
|
});
|
63
68
|
collection.dispatch({
|
64
69
|
type: "insertFiles",
|
65
|
-
payload: files.map(f => uploadAttachment(f))
|
70
|
+
payload: files.map((f) => uploadAttachment(f))
|
66
71
|
});
|
67
72
|
};
|
68
73
|
|
69
|
-
const [dragState,
|
70
|
-
|
71
|
-
|
74
|
+
const [dragState, dragStart, listeners] = useDragUploader(
|
75
|
+
[collection],
|
76
|
+
dragEnd
|
77
|
+
);
|
72
78
|
|
73
79
|
const position = (record) => {
|
74
|
-
return
|
75
|
-
|
80
|
+
return (
|
81
|
+
[...collection.draggables.map((d) => d.record), ...deleted].indexOf(
|
82
|
+
record
|
83
|
+
) + 1
|
84
|
+
);
|
76
85
|
};
|
77
86
|
|
78
87
|
const attrName = (record) => {
|
@@ -102,21 +111,23 @@ export default function Attachments(props) {
|
|
102
111
|
const { dragging } = dragState;
|
103
112
|
|
104
113
|
if (draggable === "Files") {
|
105
|
-
return
|
114
|
+
return <Placeholder key="placeholder" />;
|
106
115
|
}
|
107
116
|
|
108
117
|
return (
|
109
|
-
<Attachment
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
<Attachment
|
119
|
+
key={draggable.handle}
|
120
|
+
draggable={draggable}
|
121
|
+
locale={props.locale}
|
122
|
+
locales={props.locales}
|
123
|
+
showEmbed={props.showEmbed}
|
124
|
+
startDrag={dragStart}
|
125
|
+
position={position(draggable.record)}
|
126
|
+
onUpdate={update(draggable)}
|
127
|
+
deleteRecord={remove(draggable)}
|
128
|
+
attributeName={attrName(draggable.record)}
|
129
|
+
placeholder={dragging && dragging == draggable}
|
130
|
+
/>
|
120
131
|
);
|
121
132
|
};
|
122
133
|
|
@@ -128,30 +139,31 @@ export default function Attachments(props) {
|
|
128
139
|
}
|
129
140
|
|
130
141
|
return (
|
131
|
-
<div className={classes.join(" ")}
|
132
|
-
|
133
|
-
{...listeners}>
|
134
|
-
<div className="files">
|
135
|
-
{dragOrder.map(d => attachment(d))}
|
136
|
-
</div>
|
142
|
+
<div className={classes.join(" ")} ref={collection.ref} {...listeners}>
|
143
|
+
<div className="files">{dragOrder.map((d) => attachment(d))}</div>
|
137
144
|
<div className="deleted">
|
138
|
-
{deleted.map(r =>
|
145
|
+
{deleted.map((r) => (
|
139
146
|
<span className="deleted-attachment" key={r.id}>
|
140
|
-
<input name={`${attrName(r)}[id]`}
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
<input
|
147
|
-
|
148
|
-
|
149
|
-
|
147
|
+
<input name={`${attrName(r)}[id]`} type="hidden" value={r.id} />
|
148
|
+
<input
|
149
|
+
name={`${attrName(r)}[attachment_id]`}
|
150
|
+
type="hidden"
|
151
|
+
value={(r.attachment && r.attachment.id) || ""}
|
152
|
+
/>
|
153
|
+
<input
|
154
|
+
name={`${attrName(r)}[_destroy]`}
|
155
|
+
type="hidden"
|
156
|
+
value={true}
|
157
|
+
/>
|
158
|
+
</span>
|
159
|
+
))}
|
150
160
|
</div>
|
151
161
|
<div className="drop-target">
|
152
|
-
<FileUploadButton
|
153
|
-
|
154
|
-
|
162
|
+
<FileUploadButton
|
163
|
+
multiple={true}
|
164
|
+
multiline={true}
|
165
|
+
callback={receiveFiles}
|
166
|
+
/>
|
155
167
|
</div>
|
156
168
|
</div>
|
157
169
|
);
|