pages_core 3.7.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/app/assets/builds/pages_core/admin-dist.js +55 -0
  4. data/app/assets/stylesheets/pages/admin/components/image_editor.scss +1 -0
  5. data/app/assets/stylesheets/pages/admin/components/image_grid.scss +33 -5
  6. data/app/assets/stylesheets/pages/admin/components/layout.scss +2 -1
  7. data/app/assets/stylesheets/pages/admin/components/login.scss +6 -0
  8. data/app/assets/stylesheets/pages/admin/components/tabs.scss +5 -0
  9. data/app/assets/stylesheets/pages/admin/components/tag_editor.scss +13 -7
  10. data/app/assets/stylesheets/pages/admin/controllers/pages.scss +13 -5
  11. data/app/assets/stylesheets/pages/admin.scss +0 -1
  12. data/app/controller_dummies/admin/admin_controller.rb +1 -1
  13. data/app/controller_dummies/application_controller.rb +1 -1
  14. data/app/controller_dummies/attachments_controller.rb +1 -1
  15. data/app/controller_dummies/frontend_controller.rb +1 -1
  16. data/app/controller_dummies/images_controller.rb +1 -1
  17. data/app/controller_dummies/page_files_controller.rb +1 -1
  18. data/app/controller_dummies/pages_controller.rb +1 -1
  19. data/app/controller_dummies/sitemaps_controller.rb +1 -1
  20. data/app/controllers/admin/attachments_controller.rb +1 -1
  21. data/app/controllers/admin/images_controller.rb +10 -7
  22. data/app/controllers/concerns/pages_core/authentication.rb +9 -4
  23. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +5 -0
  24. data/app/controllers/pages_core/frontend/pages_controller.rb +5 -2
  25. data/app/controllers/sessions_controller.rb +1 -1
  26. data/app/formatters/pages_core/link_renderer.rb +2 -2
  27. data/app/helpers/application_helper.rb +1 -1
  28. data/app/helpers/frontend_helper.rb +1 -1
  29. data/app/helpers/pages_core/admin/content_tabs_helper.rb +5 -2
  30. data/app/helpers/pages_core/admin/image_uploads_helper.rb +2 -3
  31. data/app/helpers/pages_core/admin/tag_editor_helper.rb +9 -39
  32. data/app/helpers/pages_core/head_tags_helper.rb +11 -20
  33. data/app/helpers/pages_core/open_graph_tags_helper.rb +1 -1
  34. data/app/javascript/admin-dist.js +2 -0
  35. data/app/javascript/components/Attachments/Attachment.jsx +121 -0
  36. data/app/javascript/components/Attachments/AttachmentEditor.jsx +116 -0
  37. data/app/javascript/components/Attachments/Placeholder.jsx +10 -0
  38. data/app/javascript/components/Attachments.jsx +165 -0
  39. data/app/{assets/javascripts/pages/admin/components/date_range_select.jsx → javascript/components/DateRangeSelect.jsx} +16 -5
  40. data/app/javascript/components/EditableImage.jsx +61 -0
  41. data/app/{assets/javascripts/pages/admin/components/file_upload_button.jsx → javascript/components/FileUploadButton.jsx} +11 -1
  42. data/app/{assets/javascripts/pages/admin/components/focal_point.jsx → javascript/components/ImageCropper/FocalPoint.jsx} +12 -1
  43. data/app/javascript/components/ImageCropper/Image.jsx +65 -0
  44. data/app/javascript/components/ImageCropper/Toolbar.jsx +73 -0
  45. data/app/javascript/components/ImageCropper/useCrop.js +199 -0
  46. data/app/javascript/components/ImageCropper.jsx +90 -0
  47. data/app/javascript/components/ImageEditor/Form.jsx +98 -0
  48. data/app/javascript/components/ImageEditor.jsx +62 -0
  49. data/app/javascript/components/ImageGrid/DragElement.jsx +30 -0
  50. data/app/javascript/components/ImageGrid/FilePlaceholder.jsx +9 -0
  51. data/app/javascript/components/ImageGrid/GridImage.jsx +103 -0
  52. data/app/javascript/components/ImageGrid/Placeholder.jsx +23 -0
  53. data/app/javascript/components/ImageGrid.jsx +257 -0
  54. data/app/javascript/components/ImageUploader.jsx +171 -0
  55. data/app/{assets/javascripts/pages/admin/components/modal.jsx → javascript/components/Modal.jsx} +13 -2
  56. data/app/javascript/components/ModalStore.jsx +12 -0
  57. data/app/{assets/javascripts/pages/admin/components/page_dates.jsx → javascript/components/PageDates.jsx} +11 -1
  58. data/app/{assets/javascripts/pages/admin/components/page_files.jsx → javascript/components/PageFiles.jsx} +11 -2
  59. data/app/{assets/javascripts/pages/admin/components/page_images.jsx → javascript/components/PageImages.jsx} +11 -2
  60. data/app/{assets/javascripts/pages/admin/components/page_tree_store.jsx → javascript/components/PageTree.jsx} +127 -137
  61. data/app/{assets/javascripts/pages/admin/components/page_tree.jsx → javascript/components/PageTreeDraggable.jsx} +35 -29
  62. data/app/{assets/javascripts/pages/admin/components/page_tree_node.jsx → javascript/components/PageTreeNode.jsx} +35 -20
  63. data/app/javascript/components/RichTextArea.jsx +213 -0
  64. data/app/javascript/components/RichTextToolbarButton.jsx +20 -0
  65. data/app/javascript/components/TagEditor/AddTagForm.jsx +42 -0
  66. data/app/javascript/components/TagEditor/Tag.jsx +32 -0
  67. data/app/javascript/components/TagEditor.jsx +61 -0
  68. data/app/javascript/components/Toast.jsx +72 -0
  69. data/app/javascript/components/ToastStore.jsx +14 -0
  70. data/app/javascript/components/drag/draggedOrder.js +51 -0
  71. data/app/javascript/components/drag/useDragCollection.js +84 -0
  72. data/app/javascript/components/drag/useDragUploader.js +112 -0
  73. data/app/javascript/components/drag/useDraggable.js +17 -0
  74. data/app/javascript/components/drag.js +6 -0
  75. data/app/javascript/components.js +14 -0
  76. data/app/javascript/controllers/EditPageController.js +20 -0
  77. data/app/javascript/controllers/LoginController.js +29 -0
  78. data/app/javascript/controllers/MainController.js +65 -0
  79. data/app/javascript/controllers/PageOptionsController.js +62 -0
  80. data/app/javascript/features/RichText.jsx +34 -0
  81. data/app/javascript/hooks.js +2 -0
  82. data/app/javascript/index.js +33 -0
  83. data/app/{assets/javascripts/pages/admin/lib/tree.jsx → javascript/lib/Tree.js} +55 -54
  84. data/app/javascript/lib/copyToClipboard.js +13 -0
  85. data/app/javascript/lib/readyHandler.js +22 -0
  86. data/app/javascript/lib/request.js +36 -0
  87. data/app/models/concerns/pages_core/page_model/images.rb +3 -1
  88. data/app/models/concerns/pages_core/page_model/searchable.rb +19 -0
  89. data/app/models/concerns/pages_core/searchable_document.rb +71 -0
  90. data/app/models/concerns/pages_core/taggable.rb +27 -12
  91. data/app/models/page.rb +2 -0
  92. data/app/models/page_exporter.rb +2 -2
  93. data/app/models/page_image.rb +0 -2
  94. data/app/models/role.rb +1 -1
  95. data/app/models/search_document.rb +72 -0
  96. data/app/models/tag.rb +1 -0
  97. data/app/models/user.rb +1 -1
  98. data/app/{serializers/admin/attachment_serializer.rb → resources/admin/attachment_resource.rb} +6 -5
  99. data/app/{serializers/admin/image_serializer.rb → resources/admin/image_resource.rb} +9 -9
  100. data/app/resources/admin/page_file_resource.rb +10 -0
  101. data/app/{serializers/admin/page_image_serializer.rb → resources/admin/page_image_resource.rb} +4 -2
  102. data/app/resources/export/attachment_resource.rb +10 -0
  103. data/app/resources/export/page_image_resource.rb +45 -0
  104. data/app/resources/export/page_resource.rb +42 -0
  105. data/app/{serializers/page_image_serializer.rb → resources/page_image_resource.rb} +8 -16
  106. data/app/resources/page_resource.rb +33 -0
  107. data/app/services/pages_core/destroy_invite_service.rb +2 -2
  108. data/app/services/pages_core/invite_service.rb +2 -2
  109. data/app/views/admin/pages/_edit_content.html.erb +1 -1
  110. data/app/views/admin/pages/_edit_files.html.erb +1 -5
  111. data/app/views/admin/pages/_edit_images.html.erb +1 -5
  112. data/app/views/admin/pages/_edit_options.html.erb +74 -55
  113. data/app/views/admin/pages/_form.html.erb +19 -0
  114. data/app/views/admin/pages/edit.html.erb +35 -61
  115. data/app/views/admin/pages/index.html.erb +0 -1
  116. data/app/views/admin/pages/new.html.erb +32 -32
  117. data/app/views/admin/users/_access_control.html.erb +5 -1
  118. data/app/views/admin/users/login.html.erb +12 -4
  119. data/app/views/feeds/pages.rss.builder +1 -2
  120. data/app/views/layouts/admin/_header.html.erb +1 -1
  121. data/app/views/layouts/admin/_page_header.html.erb +33 -0
  122. data/app/views/layouts/admin.html.erb +23 -42
  123. data/app/views/pages_core/_google_analytics.html.erb +8 -0
  124. data/db/migrate/20180625154059_enable_search_extensions.rb +10 -0
  125. data/db/migrate/20210209151400_create_search_configurations.rb +35 -0
  126. data/db/migrate/20210210235200_create_search_documents.rb +74 -0
  127. data/lib/pages_core/engine.rb +1 -5
  128. data/lib/pages_core/templates/block_configuration.rb +1 -1
  129. data/lib/pages_core/templates/configuration_handler.rb +1 -1
  130. data/lib/pages_core/version.rb +1 -1
  131. data/lib/pages_core.rb +3 -5
  132. data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +0 -7
  133. data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +2 -2
  134. metadata +101 -115
  135. data/app/assets/javascripts/pages/admin/components/attachment.jsx +0 -130
  136. data/app/assets/javascripts/pages/admin/components/attachment_editor.jsx +0 -131
  137. data/app/assets/javascripts/pages/admin/components/attachments.jsx +0 -211
  138. data/app/assets/javascripts/pages/admin/components/drag_uploader.jsx +0 -174
  139. data/app/assets/javascripts/pages/admin/components/editable_image.jsx +0 -57
  140. data/app/assets/javascripts/pages/admin/components/grid_image.jsx +0 -124
  141. data/app/assets/javascripts/pages/admin/components/image_editor.jsx +0 -496
  142. data/app/assets/javascripts/pages/admin/components/image_grid.jsx +0 -306
  143. data/app/assets/javascripts/pages/admin/components/image_uploader.jsx +0 -176
  144. data/app/assets/javascripts/pages/admin/components/modal_store.jsx +0 -20
  145. data/app/assets/javascripts/pages/admin/components/rich_text_area.jsx +0 -64
  146. data/app/assets/javascripts/pages/admin/components/rich_text_toolbar.jsx +0 -91
  147. data/app/assets/javascripts/pages/admin/components/toast.jsx +0 -34
  148. data/app/assets/javascripts/pages/admin/components/toast_store.jsx +0 -52
  149. data/app/assets/javascripts/pages/admin/components.jsx +0 -2
  150. data/app/assets/javascripts/pages/admin/features/content_tabs.jsx +0 -72
  151. data/app/assets/javascripts/pages/admin/features/edit_page.jsx +0 -97
  152. data/app/assets/javascripts/pages/admin/features/rich_text.jsx +0 -14
  153. data/app/assets/javascripts/pages/admin/features/tag_editor.jsx +0 -160
  154. data/app/assets/javascripts/pages/admin.jsx +0 -17
  155. data/app/assets/javascripts/pages/login_form.jsx +0 -21
  156. data/app/serializers/admin/page_file_serializer.rb +0 -8
  157. data/app/serializers/page_export_serializer.rb +0 -32
  158. data/app/serializers/page_file_export_serializer.rb +0 -6
  159. data/app/serializers/page_image_export_serializer.rb +0 -42
  160. data/app/serializers/page_serializer.rb +0 -23
  161. data/app/views/layouts/admin/_analytics.html.erb +0 -16
  162. data/lib/rails/generators/pages_core/frontend/templates/application.js.erb +0 -15
  163. data/vendor/assets/javascripts/ReactCrop.min.js +0 -1
  164. data/vendor/assets/javascripts/reflux.min.js +0 -1
@@ -1,211 +0,0 @@
1
- class Attachments extends DragUploader {
2
- constructor(props) {
3
- super(props);
4
-
5
- this.state = {
6
- ...this.state,
7
- records: props.records.map(
8
- r => ({ ...r, ref: React.createRef(), handle: this.getHandle() })),
9
- deleted: []
10
- };
11
-
12
- this.container = React.createRef();
13
-
14
- this.deleteRecord = this.deleteRecord.bind(this);
15
- this.receiveFiles = this.receiveFiles.bind(this);
16
- }
17
-
18
- attributeName(record) {
19
- return `${this.props.attribute}[${this.index(record) + 1}]`;
20
- }
21
-
22
- deleteRecord(record) {
23
- let { records, deleted } = this.state;
24
- records = records.filter(i => i != record);
25
- if (record.id) {
26
- deleted = [...deleted, record];
27
- }
28
- this.setState({ records: records, deleted: deleted });
29
- }
30
-
31
- draggables() {
32
- return this.state.records;
33
- }
34
-
35
- getDraggedOrder() {
36
- let dragging = this.state.dragging;
37
- var records = this.state.records;
38
- if (dragging) {
39
- if (this.hovering(this.container)) {
40
- records = [];
41
- this.state.records.filter(r => r !== dragging).forEach(r => {
42
- if (this.hovering(r) && records.indexOf(dragging) === -1) {
43
- records.push(dragging);
44
- }
45
- records.push(r);
46
- });
47
- if (records.indexOf(dragging) === -1) {
48
- records.push(dragging);
49
- }
50
- } else {
51
- records = this.state.records.filter(r => r !== dragging);
52
- if (this.state.y < this.container.current.getBoundingClientRect().top) {
53
- records = [dragging, ...records];
54
- } else {
55
- records.push(dragging);
56
- }
57
- }
58
- }
59
- return records;
60
- }
61
-
62
- index(record) {
63
- let { records, deleted } = this.state;
64
- let ordered = [...records, ...deleted];
65
- return ordered.indexOf(record);
66
- }
67
-
68
- injectUploads(files, records) {
69
- let queue = files.slice();
70
- let source = records;
71
-
72
- if (source.indexOf("Files") === -1) {
73
- return [...source, ...queue];
74
- } else {
75
- records = [];
76
- source.forEach(function (record) {
77
- if (record === "Files") {
78
- records = [...records, ...queue];
79
- } else {
80
- records.push(record);
81
- }
82
- });
83
- }
84
-
85
- return records;
86
- }
87
-
88
- receiveFiles(files, newState) {
89
- this.setState({
90
- ...newState,
91
- records: this.injectUploads(files.map(f => this.uploadAttachment(f)),
92
- this.getDraggedOrder())
93
- });
94
- }
95
-
96
- render() {
97
- let { dragging, deleted } = this.state;
98
- let records = this.getDraggedOrder();
99
- let classes = ["attachments"];
100
- if (dragging) {
101
- classes.push("dragover");
102
- }
103
- return (
104
- <div className={classes.join(" ")}
105
- ref={this.container}
106
- onDragOver={this.drag}
107
- onDrop={this.dragEnd}>
108
- <div className="files">
109
- {records.map(r => this.renderAttachment(r))}
110
- </div>
111
- <div className="deleted">
112
- {deleted.map(r => this.renderDeletedRecord(r))}
113
- </div>
114
- <div className="drop-target">
115
- <FileUploadButton multiple={true}
116
- multiline={true}
117
- callback={this.receiveFiles} />
118
- </div>
119
- </div>
120
- );
121
- }
122
-
123
- renderAttachment(record) {
124
- let dragging = this.state.dragging;
125
-
126
- if (record === "Files") {
127
- return (
128
- <div className="attachment drop-placeholder"
129
- key="file-placeholder">
130
- Upload files here
131
- </div>
132
- );
133
- }
134
-
135
- let onUpdate = (attachment) => {
136
- this.updateAttachment(record, attachment);
137
- };
138
-
139
- return (
140
- <Attachment key={record.handle}
141
- record={record}
142
- locale={this.props.locale}
143
- locales={this.props.locales}
144
- csrf_token={this.props.csrf_token}
145
- showEmbed={this.props.showEmbed}
146
- startDrag={this.startDrag}
147
- position={this.index(record) + 1}
148
- onUpdate={onUpdate}
149
- deleteRecord={this.deleteRecord}
150
- attributeName={this.attributeName(record)}
151
- placeholder={dragging && dragging == record} />
152
- );
153
- }
154
-
155
- renderDeletedRecord(record) {
156
- let attachment = record.attachment;
157
- let attrName = this.attributeName(record);
158
- return (
159
- <span className="deleted-attachment" key={`deleted-${record.id}`}>
160
- <input name={`${attrName}[id]`}
161
- type="hidden" value={record.id} />
162
- <input name={`${attrName}[attachment_id]`}
163
- type="hidden" value={(attachment && attachment.id) || ""} />
164
- <input name={`${attrName}[_destroy]`}
165
- type="hidden" value={true} />
166
- </span>
167
- );
168
- }
169
-
170
- updateAttachment(record, attachment) {
171
- let records = this.state.records.slice();
172
-
173
- records[records.indexOf(record)] = {
174
- ...record,
175
- attachment: { ...record.attachment, ...attachment }
176
- };
177
-
178
- this.setState({ records: records });
179
- }
180
-
181
- filenameToName(str) {
182
- return str.replace(/\.[\w\d]+$/, "").replace(/_/g, " ");
183
- }
184
-
185
- uploadAttachment(file) {
186
- let component = this;
187
- let locale = this.props.locale;
188
- let locales = this.props.locales ? Object.keys(this.props.locales) : [locale];
189
-
190
- let name = {};
191
- locales.forEach((l) => name[l] = file.name);
192
-
193
- let obj = { attachment: { filename: file.name, name: name },
194
- uploading: true,
195
- ref: React.createRef(),
196
- handle: this.getHandle() };
197
- let data = new FormData();
198
-
199
- data.append("attachment[file]", file);
200
- locales.forEach((l) => {
201
- data.append(`attachment[name][${l}]`, this.filenameToName(file.name));
202
- });
203
- this.postFile("/admin/attachments.json", data, function (json) {
204
- obj.attachment = json;
205
- obj.uploading = false;
206
- component.setState({ });
207
- });
208
-
209
- return obj;
210
- }
211
- }
@@ -1,174 +0,0 @@
1
- class DragUploader extends React.Component {
2
- constructor(props) {
3
- super(props);
4
- this.state = { dragging: false,
5
- x: null,
6
- y: null };
7
-
8
- this.cachePositions = this.cachePositions.bind(this);
9
- this.drag = this.drag.bind(this);
10
- this.dragEnd = this.dragEnd.bind(this);
11
- this.dragLeave = this.dragLeave.bind(this);
12
- this.startDrag = this.startDrag.bind(this);
13
- }
14
-
15
- componentDidMount() {
16
- window.addEventListener("mousemove", this.drag);
17
- window.addEventListener("touchmove", this.drag);
18
- window.addEventListener("mouseup", this.dragEnd);
19
- window.addEventListener("touchend", this.dragEnd);
20
- window.addEventListener("mouseout", this.dragLeave);
21
- window.addEventListener("resize", this.cachePositions);
22
- this.cachePositions();
23
- }
24
-
25
- componentWillUnmount() {
26
- window.removeEventListener("mousemove", this.drag);
27
- window.removeEventListener("touchmove", this.drag);
28
- window.removeEventListener("mouseup", this.dragEnd);
29
- window.removeEventListener("touchend", this.dragEnd);
30
- window.removeEventListener("mouseout", this.dragLeave);
31
- window.removeEventListener("resize", this.cachePositions);
32
- }
33
-
34
- draggables() {
35
- // TODO: raise error
36
- return [];
37
- }
38
-
39
- receiveFiles(files, newState) {
40
- this.setState(newState);
41
- }
42
-
43
- cachePositions() {
44
- this.cachedPositions = {};
45
- this.draggables().forEach(d => {
46
- if (d.handle && d.ref && d.ref.current) {
47
- this.cachedPositions[d.handle] = d.ref.current.getBoundingClientRect();
48
- }
49
- });
50
- }
51
-
52
- containsFiles(evt) {
53
- if (!evt.dataTransfer || !evt.dataTransfer.types) {
54
- return false;
55
- }
56
- let types = evt.dataTransfer.types;
57
- for (var i = 0; i < types.length; i++) {
58
- if (types[i] === "Files" || types[i] === "application/x-moz-file") {
59
- return true;
60
- }
61
- }
62
- return false;
63
- }
64
-
65
- drag(evt) {
66
- if (this.state.dragging) {
67
- let position = this.mousePosition(evt);
68
- evt.stopPropagation();
69
- evt.preventDefault();
70
- this.setState({ x: position.x, y: position.y });
71
- } else {
72
- if (this.containsFiles(evt)) {
73
- this.cachePositions();
74
- this.setState({ dragging: "Files" });
75
- }
76
- }
77
- }
78
-
79
- dragEnd(evt) {
80
- if (!this.state.dragging) {
81
- return;
82
- }
83
- evt.preventDefault();
84
- evt.stopPropagation();
85
-
86
- var files = [];
87
- if (this.state.dragging == "Files") {
88
- files = this.getFiles(evt.dataTransfer);
89
- }
90
-
91
- this.receiveFiles(files, { dragging: false, x: null, y: null });
92
- this.cachePositions();
93
- }
94
-
95
- dragLeave(evt) {
96
- if (!this.state.dragging || this.state.dragging !== "Files") {
97
- return;
98
- }
99
- evt.preventDefault();
100
- evt.stopPropagation();
101
- this.setState({ dragging: false, x: null, y: null });
102
- }
103
-
104
- getFiles(dt) {
105
- var files = [];
106
- if (dt.items) {
107
- for (var i = 0; i < dt.items.length; i++) {
108
- if (dt.items[i].kind == "file") {
109
- files.push(dt.items[i].getAsFile());
110
- }
111
- }
112
- } else {
113
- for (var i = 0; i < dt.files.length; i++) {
114
- files.push(dt.files[i]);
115
- }
116
- }
117
- return files.filter(f => (!this.validMimeTypes ||
118
- this.validMimeTypes.indexOf(f.type) !== -1));
119
- }
120
-
121
- getHandle() {
122
- if (!this.handle) {
123
- this.handle = 0;
124
- }
125
- this.handle += 1;
126
- return this.handle;
127
- }
128
-
129
- hovering(target) {
130
- let { x, y } = this.state;
131
- var rect;
132
- if (target.handle && this.cachedPositions[target.handle]) {
133
- rect = this.cachedPositions[target.handle];
134
- } else if (target.current) {
135
- rect = target.current.getBoundingClientRect();
136
- } else {
137
- return false;
138
- }
139
- return (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom);
140
- }
141
-
142
- mousePosition(evt) {
143
- var x, y;
144
- if (evt.type == "touchmove") {
145
- x = evt.touches[0].clientX;
146
- y = evt.touches[0].clientY;
147
- } else {
148
- x = evt.clientX;
149
- y = evt.clientY;
150
- }
151
- return { x: x, y: y };
152
- }
153
-
154
- postFile(url, data, callback) {
155
- let xhr = new XMLHttpRequest();
156
- xhr.open("POST", url);
157
- xhr.setRequestHeader("X-CSRF-Token", this.props.csrf_token);
158
- xhr.addEventListener("load", function () {
159
- if (xhr.readyState == 4 && xhr.status == "200" && callback) {
160
- callback(JSON.parse(xhr.responseText));
161
- }
162
- });
163
- xhr.send(data);
164
- }
165
-
166
- startDrag(evt, record) {
167
- let position = this.mousePosition(evt);
168
- let prevDisplay = record.ref.current.style.display;
169
- record.ref.current.style.display = "none";
170
- this.cachePositions();
171
- record.ref.current.style.display = prevDisplay;
172
- this.setState({ dragging: record, x: position.x, y: position.y });
173
- }
174
- }
@@ -1,57 +0,0 @@
1
- class EditableImage extends React.Component {
2
- constructor(props) {
3
- let image = props.image;
4
- super(props);
5
- this.state = {
6
- image: image,
7
- src: props.src,
8
- width: image.crop_width || image.real_width,
9
- height: image.crop_height || image.real_height
10
- };
11
- this.openEditor = this.openEditor.bind(this);
12
- this.update = this.update.bind(this);
13
- }
14
-
15
- openEditor() {
16
- ModalActions.open(
17
- <ImageEditor image={this.state.image}
18
- caption={this.props.caption}
19
- locale={this.props.locale}
20
- locales={this.props.locales}
21
- csrf_token={this.props.csrf_token}
22
- onUpdate={this.update} />);
23
- }
24
-
25
- height() {
26
- let image = this.state.image;
27
- let width = image.crop_width || image.real_width;
28
- let height = image.crop_height || image.real_height;
29
- return Math.round((height / width) * this.props.width);
30
- }
31
-
32
- update(image, croppedImage) {
33
- let newImage = { ...this.state.image, ...image };
34
- this.setState({image: newImage,
35
- src: croppedImage});
36
- if (this.props.onUpdate) {
37
- this.props.onUpdate(newImage, croppedImage);
38
- }
39
- }
40
-
41
- render() {
42
- let altWarning = !this.state.image.alternative[this.props.locale];
43
-
44
- return (
45
- <div className="editable-image">
46
- {altWarning &&
47
- <span className="alt-warning" title="Alternative text is missing">
48
- <i className="fa fa-exclamation-triangle icon" />
49
- </span>}
50
- <img src={this.state.src}
51
- width={this.props.width}
52
- height={this.height()}
53
- onClick={this.openEditor} />
54
- </div>
55
- );
56
- }
57
- }
@@ -1,124 +0,0 @@
1
- class GridImage extends React.Component {
2
- constructor(props) {
3
- super(props);
4
- this.state = {
5
- src: (props.record.src || null)
6
- };
7
- this.copyEmbed = this.copyEmbed.bind(this);
8
- this.deleteImage = this.deleteImage.bind(this);
9
- this.dragStart = this.dragStart.bind(this);
10
- }
11
-
12
- componentDidMount() {
13
- let file = this.props.record.file;
14
- if (file) {
15
- this.reader = new FileReader();
16
- this.reader.onload = () => this.setState({src: this.reader.result });
17
- this.reader.readAsDataURL(this.props.record.file);
18
- }
19
- }
20
-
21
- copyEmbed(evt) {
22
- let image = this.props.record.image;
23
- evt.preventDefault();
24
- const el = document.createElement("textarea");
25
- el.value = `[image:${image.id}]`;
26
- document.body.appendChild(el);
27
- el.select();
28
- document.execCommand("copy");
29
- document.body.removeChild(el);
30
- ToastActions.notice("Embed code copied to clipboard");
31
- }
32
-
33
- deleteImage(evt) {
34
- evt.preventDefault();
35
- if (this.props.deleteImage) {
36
- this.props.deleteImage(this.props.record);
37
- }
38
- }
39
-
40
- dragStart(evt) {
41
- evt.preventDefault();
42
- evt.stopPropagation();
43
- if (this.props.startDrag) {
44
- this.props.startDrag(evt, this.props.record);
45
- }
46
- }
47
-
48
- renderImage() {
49
- let image = this.props.record.image;
50
- return(
51
- <EditableImage image={image}
52
- src={this.state.src || image.thumbnail_url}
53
- width={250}
54
- caption={true}
55
- locale={this.props.locale}
56
- locales={this.props.locales}
57
- csrf_token={this.props.csrf_token}
58
- onUpdate={this.props.onUpdate} />
59
- );
60
- }
61
-
62
- renderPlaceholder() {
63
- let src = this.state.src;
64
- if (src) {
65
- return (
66
- <div className="temp-image">
67
- <img src={src} />
68
- <span>Uploading...</span>
69
- </div>
70
- );
71
- } else {
72
- return (
73
- <div className="file-placeholder">
74
- <span>Uploading...</span>
75
- </div>
76
- );
77
- }
78
- }
79
-
80
- render() {
81
- let attributeName = this.props.attributeName;
82
- let record = this.props.record;
83
- let image = record.image;
84
- let classes = ["grid-image"];
85
- if (this.props.placeholder) {
86
- classes.push("placeholder");
87
- }
88
- if (this.props.record.file) {
89
- classes.push("uploading");
90
- }
91
- return (
92
- <div className={classes.join(" ")}
93
- onDragStart={this.dragStart}
94
- ref={this.props.record.ref}>
95
- <input name={`${attributeName}[id]`}
96
- type="hidden" value={record.id || ""} />
97
- <input name={`${attributeName}[image_id]`}
98
- type="hidden" value={(image && image.id) || ""} />
99
- <input name={`${attributeName}[position]`}
100
- type="hidden" value={this.props.position} />
101
- {this.props.enablePrimary && (
102
- <input name={`${attributeName}[primary]`}
103
- type="hidden" value={this.props.primary} />
104
- )}
105
- {!image && this.renderPlaceholder()}
106
- {image && this.renderImage()}
107
- {image && (
108
- <div className="actions">
109
- {this.props.showEmbed && (
110
- <button onClick={this.copyEmbed}>
111
- Embed
112
- </button>
113
- )}
114
- {this.props.deleteImage && (
115
- <button onClick={this.deleteImage}>
116
- Remove
117
- </button>
118
- )}
119
- </div>
120
- )}
121
- </div>
122
- );
123
- }
124
- }