hera_cms 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59772e5b5e2184b62826db82401b6cca00739bdf9bc35388893ae081d4908793
4
- data.tar.gz: bc2eb8324e8fd527e5002f1c23060e863effa81ed341859f06faa884014bee69
3
+ metadata.gz: 5aa9efe0f53f57f3455978481d5b469a58b470f651db6c9b9de10167bdd6910e
4
+ data.tar.gz: b5ed7cb6d61b33f38d40448a12737ccc95aa577f240f2970872edd95de9814e2
5
5
  SHA512:
6
- metadata.gz: cc0bce2b2b970264219687acfe7767fb344513404192811df7366f51ca0c05993ac39e4baad8b6342e6b429b7904308a45880c761e3d95961a1ebc8244e9ae64
7
- data.tar.gz: 3c4608285ef81aec585c542f23755cf7c0f0dc342591077ee394fae576ddbf18038d16d8cf05cb0d4eacde69b880396e328e4357ffbc0f59bf3464a388ff2319
6
+ metadata.gz: 6f1d9b6b41a4e272cb4df3e1a84aba88d10ec26f10458c42206f12af256c7db0451642e0767720d6eb1d5e0ffffc56bf77feef62b9a498526c41102ba568e1ed
7
+ data.tar.gz: '0798a46a9aa7ed5d8dd557e1cd37a82be450d17fbc852cacf89fa4071248a396672376581d3120f1ed12ea84f51c966490a1222f2318f8028c84772037a6687f'
data/README.md CHANGED
@@ -1,13 +1,7 @@
1
- ---- STILL IN DEVELOPMENT ----
2
- ---- If you want to contribute, feel free to open an issue or contact me at rayan@hortatech.com.br ----
3
-
4
1
  # HeraCms
5
2
 
6
3
  Hera aims to enable you to easily add Content Managment to your Rails projects, with a very friendly user interface.
7
4
 
8
- ## Usage
9
- We use some tables to store the editable content of your website, in order for it to be updatable dynamically by the website owner.
10
-
11
5
  ## Installation
12
6
 
13
7
  1. Add this line to your application's Gemfile:
@@ -16,13 +10,13 @@ gem 'hera_cms'
16
10
  ```
17
11
  2. Execute:
18
12
  ```bash
19
- $ bundle
13
+ bundle
20
14
  ```
21
15
 
22
16
  3. The Hera Installer will generate some migrations, that you need to run:
23
17
  ```bash
24
- $ rails hera_cms:install
25
- $ rails db:migrate
18
+ rails g hera_cms:install
19
+ rails db:migrate
26
20
  ```
27
21
 
28
22
  ## Configuration
@@ -60,8 +54,91 @@ Then, you need to add the Hera navbar to your layout. Here is also highly recomm
60
54
 
61
55
  ```
62
56
 
57
+ ## Usage
58
+ We use hera_cms tables to store the editable content of your website, in order for it to be updatable dynamically by the website owner.
59
+
60
+ There are 3 types of editable content you can use: Links, Texts and Images
61
+
62
+ ### Links
63
+
64
+ To add an editable link to the view, you first need to create it in the rails console
65
+
66
+ ```ruby
67
+ # rails console
68
+ pry(main)> HeraCms::Link.create(identifier: 'home-link-main', inner_text: "HortaTech", path: 'https://www.hortatech.com.br')
69
+
70
+ ```
71
+
72
+ Then you can just add it to the view using the Hera Link Helper, passing the correct identifier
73
+
74
+ ```erb
75
+ <!-- app/views/pages/home.html.erb -->
76
+ <!-- ... -->
77
+
78
+ <%= hera_link 'home-link-main' %>
79
+
80
+ <!-- ... -->
81
+
82
+ ```
83
+
84
+ Alternatively, you can create links passing a block, similar to the link_to rails helper
85
+
86
+ ```erb
87
+ <!-- app/views/pages/home.html.erb -->
88
+ <!-- ... -->
89
+
90
+ <%= hera_link 'home-link-main', class: 'main-link' do %>
91
+ <div class="card">
92
+ <p>Lorem ipsum</p>
93
+ </div>
94
+ <% end %>
95
+
96
+ <!-- ... -->
97
+
98
+ ```
99
+
100
+
101
+ ### Texts
102
+
103
+ To add an editable text to the view, it is exactly like addings links. You first need to create it in the rails console
104
+
105
+ ```ruby
106
+ # rails console
107
+ pry(main)> HeraCms::Text.create(identifier: 'home-description', inner_text: "These are not the droids you're looking for")
108
+
109
+ ```
110
+
111
+ Then you can just add it to the view using the Hera Text Helper, passing the correct identifier
112
+
113
+ ```erb
114
+ <!-- app/views/pages/home.html.erb -->
115
+ <!-- ... -->
116
+
117
+ <%= hera_text 'home-description', html_tag: :p %>
118
+
119
+ <!-- ... -->
120
+
121
+ ```
122
+
123
+ ### Images
124
+
125
+ Coming soon...
126
+
127
+ ## Production Database
128
+
129
+ In order to facilitate you not have to duplicate all of your created records from development to production, we use a YAML file to store all record's information from development, located at db/hera_cms/hera_database_seed.yml
130
+
131
+ After you finish developing your application and want to build it in production, you can just run this command in production to replicate your created Hera Links, Texts and Images to your production database
132
+
133
+ ```bash
134
+ rails hera_cms:populate_database
135
+ ```
136
+
63
137
  ## Contributing
64
- Contribution directions go here.
138
+
139
+ ---- GEM STILL IN DEVELOPMENT ----
140
+
141
+ If you want to contribute, feel free to open an issue or contact me at rayan@hortatech.com.br
65
142
 
66
143
  ## License
67
144
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1 +1,310 @@
1
- // Hera edit JS is located at app/views/hera_cms/shared/_hera_edit.js
1
+ // console.log('Loading Hera CMS Javascript');
2
+
3
+ let editables = document.querySelectorAll('.hera-editable')
4
+
5
+ const AUTH_TOKEN = document.querySelector('meta[name=csrf-token]').attributes['content'].value;
6
+
7
+ const allowEdit = () => {
8
+ // Add listeners for all editables [edit mode]
9
+ editables.forEach((editable) => {
10
+ editable.addEventListener('mouseenter', displayEditor);
11
+ editable.addEventListener('mouseleave', hideEditor);
12
+ });
13
+ };
14
+
15
+ const lockEdit = () => {
16
+ // Remove listeners for all editables [view mode]
17
+ editables.forEach((editable) => {
18
+ editable.removeEventListener('mouseenter', displayEditor);
19
+ editable.removeEventListener('mouseleave', hideEditor);
20
+ });
21
+ };
22
+
23
+ const toggleOff = () => {
24
+ // Remove open forms and remove highlights that could be still active [switching from edit to view mode]
25
+ let formBox = document.querySelector(".hera-form-box");
26
+ if(formBox){
27
+ formBox.parentNode.removeChild(formBox);
28
+ };
29
+
30
+ editables.forEach((editable) => {
31
+ if (editable.classList.contains('hera-highlight-layer')){
32
+ editable.classList.remove('hera-highlight-layer');
33
+ }
34
+ });
35
+ // Swap wrapper with editable one (?)
36
+ let wrapper = document.querySelector('.hera-editable-wrapper');
37
+ if(wrapper){
38
+ wrapper.parentNode.replaceChild(wrapper.firstChild, wrapper);
39
+ };
40
+ };
41
+
42
+
43
+ const toggleEditLoader = (e) => {
44
+ // Select all editable elements on the page
45
+ editables = document.querySelectorAll('.hera-editable')
46
+
47
+ // Switches between Edit Mode and View mode
48
+ // In edit mode, all editable links, texts and images need the following:
49
+ // 1. One edit button that appears on hover
50
+ // 2. When you click it, it opens a form that enables you to change the value of the content
51
+ // This events can only exist on edit mode. On view mode nothing happens.
52
+
53
+ const button = e.target;
54
+ if (button.dataset["mode"] === "edit") {
55
+ // console.log('Switching to view mode');
56
+ button.innerText = "Off"
57
+ button.dataset["mode"] = "view"
58
+ button.classList.toggle("hera-edit-button-on");
59
+ toggleOff();
60
+
61
+ const layer = document.querySelector(".hera-background-layer");
62
+ document.body.removeChild(layer);
63
+ // const slickerLayer = document.querySelector(".slicker-layer");
64
+ // const slider = document.querySelector('.slick-track');
65
+ // slider.removeChild(slickerLayer);
66
+ lockEdit();
67
+ }
68
+ else if (button.dataset["mode"] === "view") {
69
+ // console.log('Switching to edit mode');
70
+ button.innerText = "On"
71
+ button.classList.toggle("hera-edit-button-on");
72
+ button.dataset["mode"] = "edit"
73
+ const layer = document.createElement("div");
74
+ layer.classList.add('hera-background-layer');
75
+ // const slickerLayer = document.createElement("div");
76
+ // slickerLayer.classList.add('hera-slicker-layer');
77
+ // const slider = document.querySelector('.slick-track');
78
+ // slider.appendChild(slickerLayer);
79
+ document.body.appendChild(layer);
80
+ allowEdit();
81
+ }
82
+ }
83
+
84
+ const displayEditor = (e) => {
85
+ // Shows the edit button for an element
86
+ // highlith the field to be edited
87
+ e.target.classList.add('hera-highlight-layer');
88
+ e.target.addEventListener('click', createForm);
89
+ }
90
+
91
+ const hideEditor = (e) => {
92
+ // Removes the edit button for an element
93
+ // remove highlighted field
94
+ e.target.classList.remove('hera-highlight-layer');
95
+ e.target.removeEventListener('click', createForm);
96
+ }
97
+
98
+ const sendRequest = (e) => {
99
+ e.preventDefault();
100
+ form = e.target;
101
+
102
+ let url = form.action + "?&authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
103
+
104
+ options = {
105
+ method: "PUT",
106
+ body: new FormData(form)
107
+ };
108
+
109
+ // console.log("fetching");
110
+ fetch(url, options)
111
+ .then(response => response.json())
112
+ .then((data) => {
113
+ window.location.replace(data.redirect);
114
+ });
115
+
116
+ // console.log('end');
117
+ }
118
+
119
+ const createForm = (e) => {
120
+ // Create a form to update the content of element in the database, using its dataset
121
+
122
+ // Prevent the link click when clicks on the form, and the default form behavior
123
+ e.stopImmediatePropagation();
124
+ e.preventDefault();
125
+ e.target.removeEventListener('click', createForm);
126
+ lockEdit();
127
+
128
+ // Selects the element to be edited
129
+ const editable = e.currentTarget
130
+
131
+ // Creates the base form using rails autenthicity token
132
+ let form = document.createElement("form");
133
+
134
+ // Updates the form action to the proper element update route, using the datase
135
+ form.action = `/hera_cms/${editable.dataset['editableType']}/${editable.dataset['editableId']}`;
136
+
137
+ form.enctype = 'multipart/form-data';
138
+
139
+ // Add a hidden input field to properly utilize the PATCH method
140
+
141
+ let i = document.createElement("input");
142
+ i.setAttribute('type', "hidden");
143
+ i.setAttribute('name', "_method");
144
+ i.setAttribute('value', 'patch');
145
+
146
+ form.appendChild(i);
147
+
148
+ // Add the proper inputs for each type of editable
149
+
150
+ switch (editable.dataset['editableType']) {
151
+ case 'links':
152
+ form = linkForm(form, editable);
153
+ break;
154
+ case 'media_index':
155
+ form = imageForm(form, editable);
156
+ break;
157
+ case 'texts':
158
+ form = textForm(form, editable);
159
+ break;
160
+ case 'forms':
161
+ form = formForm(form, editable);
162
+ break;
163
+ default:
164
+ console.log(`Tipo ${editable.dataset['editableType']} não identificado.`)
165
+ }
166
+
167
+ // Add form submit button
168
+ let s = document.createElement("input");
169
+ s.setAttribute('type', "submit");
170
+ s.setAttribute('value', "Atualizar");
171
+
172
+ form.appendChild(s);
173
+
174
+ // Add editable wrapper with form inside
175
+ let wrapper = document.createElement("div");
176
+ wrapper.className = "hera-editable-wrapper " + editable.className;
177
+ editable.parentNode.insertBefore(wrapper ,editable);
178
+
179
+ wrappedEditable = wrapper.appendChild(editable);
180
+
181
+ // Creates and initializes the modal
182
+ let formBox = document.createElement('div');
183
+ formBox.classList.add("hera-form-box");
184
+ formBox.appendChild(form);
185
+ wrapper.appendChild(formBox);
186
+ let boxPositionY = wrapper.getBoundingClientRect().top + 150;
187
+ let boxPositionX = wrapper.getBoundingClientRect().left + 150;
188
+ let screenHeight = window.screen.height;
189
+ let screenWidth = window.screen.width;
190
+ let relativeY = (boxPositionY / screenHeight) * screenHeight;
191
+ let relativeX = boxPositionX / screenWidth * screenWidth;
192
+
193
+ if(relativeX > screenWidth / 2){
194
+ formBox.style.left = "-308px";
195
+ }else{
196
+ formBox.style.right = "-308px";
197
+ };
198
+ if(relativeY > screenHeight / 2){
199
+ formBox.style.top = "-150px";
200
+ }else{
201
+ formBox.style.bottom = "-150px";
202
+ };
203
+ wrappedEditable.removeEventListener('mouseenter', displayEditor);
204
+ wrappedEditable.removeEventListener('mouseleave', hideEditor);
205
+
206
+ // Adds button to destroy wrapper and the form
207
+ let destroyButton = document.createElement("p");
208
+ destroyButton.className = "form-destroy";
209
+ destroyButton.innerHTML = "x";
210
+ destroyButton.addEventListener('click', () => {
211
+ if (wrapper.parentNode) {
212
+ newEditable = wrapper.parentNode.replaceChild(editable, wrapper);
213
+ wrapper.removeChild(formBox);
214
+ editable.classList.remove('hera-highlight-layer');
215
+ bodyLayer.classList.remove('hera-clickable');
216
+ allowEdit();
217
+ }
218
+ });
219
+
220
+
221
+ let bodyLayer = document.querySelector('.hera-background-layer');
222
+ bodyLayer.classList.add('hera-clickable');
223
+ bodyLayer.addEventListener('click', () => {
224
+ destroyButton.click();
225
+ });
226
+
227
+ form.appendChild(destroyButton);
228
+ form.addEventListener('submit', sendRequest);
229
+ }
230
+
231
+ const linkForm = (form, editable) => {
232
+
233
+ // Creates text input for the content of the element and appends it to the form
234
+ pathInput = document.createElement("input");
235
+ pathInput.setAttribute('type', "text");
236
+ pathInput.setAttribute('name', "link[path]");
237
+ pathInput.setAttribute('autocomplete', "off");
238
+ pathInput.setAttribute('value', editable);
239
+
240
+ form.appendChild(pathInput);
241
+
242
+ // Creates text input for the content of the element and appends it to the form
243
+ innerTextInput = document.createElement("input");
244
+ innerTextInput.setAttribute('type', "text");
245
+ innerTextInput.setAttribute('name', "link[inner_text]");
246
+ innerTextInput.setAttribute('autocomplete', "off");
247
+ innerTextInput.innerHTML = editable.innerText;
248
+ innerTextInput.setAttribute('value', editable.innerText);
249
+
250
+ form.appendChild(innerTextInput);
251
+ return form;
252
+ }
253
+
254
+ const imageForm = (form, editable) => {
255
+
256
+ // Creates text input for the content of the element and appends it to the form
257
+ i = document.createElement("input");
258
+ i.setAttribute('type', "file");
259
+ i.setAttribute('name', "media[upload]");
260
+
261
+ form.appendChild(i);
262
+
263
+ i = document.createElement("input");
264
+ i.setAttribute('type', "hidden");
265
+ i.setAttribute('name', "media[upload_cache]");
266
+
267
+ form.appendChild(i);
268
+
269
+ return form;
270
+ }
271
+
272
+ const textForm = (form, editable) => {
273
+
274
+ // Creates text input for the content of the element and appends it to the form
275
+ i = document.createElement("textarea");
276
+ i.setAttribute('type', "text");
277
+ i.setAttribute('name', "text[inner_text]");
278
+ i.setAttribute('autocomplete', "off");
279
+ i.innerHTML = editable.innerText;
280
+ i.setAttribute('value', editable.innerText);
281
+
282
+ form.appendChild(i);
283
+
284
+ return form;
285
+ }
286
+
287
+ const formForm = (form, editable) => {
288
+ i = document.createElement("input");
289
+ i.setAttribute('type', "text");
290
+ i.setAttribute('name', "form[send_to]");
291
+ i.setAttribute('value', editable.getAttribute("data-mail"))
292
+ form.appendChild(i)
293
+ return form
294
+ }
295
+
296
+
297
+ const createElementFromHTML = (htmlString) => {
298
+ // Creates a node element from a HTML string
299
+ const div = document.createElement('div');
300
+ div.innerHTML = htmlString.trim();
301
+
302
+ return div.firstChild;
303
+ }
304
+
305
+
306
+ // Selects the view's edit button and adds listener to toggle between edit and view mode
307
+ const editButton = document.getElementById('hera-edit-button');
308
+ if (editButton) {
309
+ editButton.addEventListener('click', toggleEditLoader)
310
+ }
@@ -1,6 +1,8 @@
1
1
  module HeraCms
2
2
  class ApplicationRecord < ActiveRecord::Base
3
3
  self.abstract_class = true
4
+ before_save :update_seed
5
+
4
6
  def self.identify(identifier)
5
7
  self.find_by(identifier: identifier)
6
8
  end
@@ -2,6 +2,5 @@ module HeraCms
2
2
  class Image < ApplicationRecord
3
3
  validates :identifier, presence: true, uniqueness: true
4
4
 
5
- before_save :update_seed
6
5
  end
7
6
  end
@@ -3,6 +3,5 @@ module HeraCms
3
3
  validates :identifier, presence: true, uniqueness: true
4
4
  validates :path, presence: true
5
5
 
6
- before_save :update_seed
7
6
  end
8
7
  end
@@ -2,6 +2,5 @@ module HeraCms
2
2
  class Text < ApplicationRecord
3
3
  validates :identifier, presence: true, uniqueness: true
4
4
 
5
- before_save :update_seed
6
5
  end
7
6
  end
@@ -3,4 +3,8 @@
3
3
 
4
4
  <h1>Hello Hera CMS Engine</h1>
5
5
 
6
+
7
+
8
+
9
+
6
10
  <%= hera_link "my-link" %>
@@ -8,6 +8,4 @@
8
8
  </div>
9
9
  </div>
10
10
 
11
- <%= javascript_tag do %>
12
- <%= render(partial: 'hera_cms/shared/hera_edit', handlers: [], formats: [:js]) %>
13
- <% end %>
11
+ <%= javascript_include_tag "hera_cms/application" %>
@@ -11,7 +11,7 @@ module HeraCms
11
11
  end
12
12
 
13
13
  def copy_config
14
- template "config.rb", "config/hera.rb"
14
+ template "config.rb", "config/initializers/hera.rb"
15
15
  end
16
16
 
17
17
  def migration_version
@@ -28,11 +28,5 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
28
28
 
29
29
  t.timestamps
30
30
  end
31
-
32
- create_table :hera_cms_forms do |t|
33
- t.string :send_to
34
-
35
- t.timestamps
36
- end
37
31
  end
38
32
  end
data/lib/hera_cms.rb CHANGED
@@ -12,9 +12,10 @@ module HeraCms
12
12
 
13
13
  # mattr_accessor :app_root
14
14
 
15
- # class << self
16
- # attr_accessor :s3_bucket
17
- # end
15
+ class << self
16
+ # attr_accessor :s3_bucket
17
+ attr_accessor :image_upload, :upload_service
18
+ end
18
19
 
19
20
  # Yield self on setup for nice config blocks
20
21
  def self.setup
@@ -1,3 +1,3 @@
1
1
  module HeraCms
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hera_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rayan Castro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-22 00:00:00.000000000 Z
11
+ date: 2021-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -160,7 +160,6 @@ files:
160
160
  - app/models/hera_cms/text.rb
161
161
  - app/views/hera_cms/dashboard/home.html.erb
162
162
  - app/views/hera_cms/layouts/hera_cms/application.html.erb
163
- - app/views/hera_cms/shared/_hera_edit.js
164
163
  - app/views/hera_cms/shared/_navbar.html.erb
165
164
  - app/views/layouts/hera_cms/application.html.erb
166
165
  - config/routes.rb
@@ -1,312 +0,0 @@
1
- console.log('Hera CMS Javascript ON :)');
2
-
3
- let editables = document.querySelectorAll('.hera-editable')
4
-
5
- const AUTH_TOKEN = document.querySelector('meta[name=csrf-token]').attributes['content'].value;
6
-
7
- const allowEdit = () => {
8
- // Add listeners for all editables [edit mode]
9
- editables.forEach((editable) => {
10
- editable.addEventListener('mouseenter', displayEditor);
11
- editable.addEventListener('mouseleave', hideEditor);
12
- });
13
- };
14
-
15
- const lockEdit = () => {
16
- // Remove listeners for all editables [view mode]
17
- editables.forEach((editable) => {
18
- editable.removeEventListener('mouseenter', displayEditor);
19
- editable.removeEventListener('mouseleave', hideEditor);
20
- });
21
- };
22
-
23
- const toggleOff = () => {
24
- // Remove open forms and remove highlights that could be still active [switching from edit to view mode]
25
- let formBox = document.querySelector(".hera-form-box");
26
- if(formBox){
27
- formBox.parentNode.removeChild(formBox);
28
- };
29
-
30
- editables.forEach((editable) => {
31
- if (editable.classList.contains('hera-highlight-layer')){
32
- editable.classList.remove('hera-highlight-layer');
33
- }
34
- });
35
- // Swap wrapper with editable one (?)
36
- let wrapper = document.querySelector('.hera-editable-wrapper');
37
- if(wrapper){
38
- wrapper.parentNode.replaceChild(wrapper.firstChild, wrapper);
39
- };
40
- };
41
-
42
-
43
- const toggleEditLoader = (e) => {
44
- // Select all editable elements on the page
45
- editables = document.querySelectorAll('.hera-editable')
46
-
47
- // Switches between Edit Mode and View mode
48
- // In edit mode, all editable links, texts and images need the following:
49
- // 1. One edit button that appears on hover
50
- // 2. When you click it, it opens a form that enables you to change the value of the content
51
- // This events can only exist on edit mode. On view mode nothing happens.
52
-
53
- const button = e.target;
54
- if (button.dataset["mode"] === "edit") {
55
- console.log('Switching to view mode');
56
- button.innerText = "Off"
57
- button.dataset["mode"] = "view"
58
- button.classList.toggle("hera-edit-button-on");
59
- toggleOff();
60
-
61
- const layer = document.querySelector(".hera-background-layer");
62
- document.body.removeChild(layer);
63
- // const slickerLayer = document.querySelector(".slicker-layer");
64
- // const slider = document.querySelector('.slick-track');
65
- // slider.removeChild(slickerLayer);
66
- lockEdit();
67
- }
68
- else if (button.dataset["mode"] === "view") {
69
- console.log('Switching to edit mode');
70
- button.innerText = "On"
71
- button.classList.toggle("hera-edit-button-on");
72
- button.dataset["mode"] = "edit"
73
- const layer = document.createElement("div");
74
- layer.classList.add('hera-background-layer');
75
- // const slickerLayer = document.createElement("div");
76
- // slickerLayer.classList.add('hera-slicker-layer');
77
- // const slider = document.querySelector('.slick-track');
78
- // slider.appendChild(slickerLayer);
79
- document.body.appendChild(layer);
80
- allowEdit();
81
- }
82
- }
83
-
84
- const displayEditor = (e) => {
85
- // Shows the edit button for an element
86
- // highlith the field to be edited
87
- e.target.classList.add('hera-highlight-layer');
88
- e.target.addEventListener('click', createForm);
89
- }
90
-
91
- const hideEditor = (e) => {
92
- // Removes the edit button for an element
93
- // remove highlighted field
94
- e.target.classList.remove('hera-highlight-layer');
95
- e.target.removeEventListener('click', createForm);
96
- }
97
-
98
- const sendRequest = (e) => {
99
- e.preventDefault();
100
- form = e.target;
101
-
102
- let url = form.action + "?&authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
103
-
104
- options = {
105
- method: "PUT",
106
- body: new FormData(form)
107
- };
108
-
109
- console.log("fetching");
110
- fetch(url, options)
111
- .then(response => response.json())
112
- .then((data) => {
113
- window.location.replace(data.redirect);
114
- });
115
-
116
- console.log('end');
117
- }
118
-
119
- const createForm = (e) => {
120
- // Create a form to update the content of element in the database, using its dataset
121
-
122
- // Prevent the link click when clicks on the form, and the default form behavior
123
- e.stopImmediatePropagation();
124
- e.preventDefault();
125
- e.target.removeEventListener('click', createForm);
126
- lockEdit();
127
-
128
- // Selects the element to be edited
129
- const editable = e.currentTarget
130
-
131
- // Creates the base form using rails autenthicity token
132
- let form = document.createElement("form");
133
-
134
- // Updates the form action to the proper element update route, using the datase
135
- form.action = `/hera_cms/${editable.dataset['editableType']}/${editable.dataset['editableId']}`;
136
-
137
- form.enctype = 'multipart/form-data';
138
-
139
- // Add a hidden input field to properly utilize the PATCH method
140
-
141
- let i = document.createElement("input");
142
- i.setAttribute('type', "hidden");
143
- i.setAttribute('name', "_method");
144
- i.setAttribute('value', 'patch');
145
-
146
- form.appendChild(i);
147
-
148
- // Add the proper inputs for each type of editable
149
-
150
- switch (editable.dataset['editableType']) {
151
- case 'links':
152
- form = linkForm(form, editable);
153
- break;
154
- case 'media_index':
155
- form = imageForm(form, editable);
156
- break;
157
- case 'texts':
158
- form = textForm(form, editable);
159
- break;
160
- case 'forms':
161
- form = formForm(form, editable);
162
- break;
163
- default:
164
- console.log(`Tipo ${editable.dataset['editableType']} não identificado.`)
165
- }
166
-
167
- // Add form submit button
168
- let s = document.createElement("input");
169
- s.setAttribute('type', "submit");
170
- s.setAttribute('value', "Atualizar");
171
-
172
- form.appendChild(s);
173
-
174
- // Add editable wrapper with form inside
175
- let wrapper = document.createElement("div");
176
- wrapper.className = "hera-editable-wrapper " + editable.className;
177
- editable.parentNode.insertBefore(wrapper ,editable);
178
-
179
- wrappedEditable = wrapper.appendChild(editable);
180
-
181
- // Creates and initializes the modal
182
- let formBox = document.createElement('div');
183
- formBox.classList.add("hera-form-box");
184
- formBox.appendChild(form);
185
- wrapper.appendChild(formBox);
186
- let boxPositionY = wrapper.getBoundingClientRect().top + 150;
187
- let boxPositionX = wrapper.getBoundingClientRect().left + 150;
188
- let screenHeight = window.screen.height;
189
- let screenWidth = window.screen.width;
190
- let relativeY = (boxPositionY / screenHeight) * screenHeight;
191
- let relativeX = boxPositionX / screenWidth * screenWidth;
192
-
193
- if(relativeX > screenWidth / 2){
194
- formBox.style.left = "-308px";
195
- }else{
196
- formBox.style.right = "-308px";
197
- };
198
- if(relativeY > screenHeight / 2){
199
- formBox.style.top = "-150px";
200
- }else{
201
- formBox.style.bottom = "-150px";
202
- };
203
- wrappedEditable.removeEventListener('mouseenter', displayEditor);
204
- wrappedEditable.removeEventListener('mouseleave', hideEditor);
205
-
206
- // Adds button to destroy wrapper and the form
207
- let destroyButton = document.createElement("p");
208
- destroyButton.className = "form-destroy";
209
- destroyButton.innerHTML = "x";
210
- destroyButton.addEventListener('click', () => {
211
- if (wrapper.parentNode) {
212
- newEditable = wrapper.parentNode.replaceChild(editable, wrapper);
213
- wrapper.removeChild(formBox);
214
- editable.classList.remove('hera-highlight-layer');
215
- bodyLayer.classList.remove('hera-clickable');
216
- allowEdit();
217
- }
218
- });
219
-
220
-
221
- let bodyLayer = document.querySelector('.hera-background-layer');
222
- bodyLayer.classList.add('hera-clickable');
223
- bodyLayer.addEventListener('click', () => {
224
- destroyButton.click();
225
- });
226
-
227
- form.appendChild(destroyButton);
228
- form.addEventListener('submit', sendRequest);
229
- }
230
-
231
- const linkForm = (form, editable) => {
232
-
233
- // Creates text input for the content of the element and appends it to the form
234
- pathInput = document.createElement("input");
235
- pathInput.setAttribute('type', "text");
236
- pathInput.setAttribute('name', "link[path]");
237
- pathInput.setAttribute('autocomplete', "off");
238
- pathInput.setAttribute('value', editable);
239
-
240
- form.appendChild(pathInput);
241
-
242
- // Creates text input for the content of the element and appends it to the form
243
- innerTextInput = document.createElement("input");
244
- innerTextInput.setAttribute('type', "text");
245
- innerTextInput.setAttribute('name', "link[inner_text]");
246
- innerTextInput.setAttribute('autocomplete', "off");
247
- innerTextInput.innerHTML = editable.innerText;
248
- innerTextInput.setAttribute('value', editable.innerText);
249
-
250
- form.appendChild(innerTextInput);
251
- return form;
252
- }
253
-
254
- const imageForm = (form, editable) => {
255
-
256
- // Creates text input for the content of the element and appends it to the form
257
- i = document.createElement("input");
258
- i.setAttribute('type', "file");
259
- i.setAttribute('name', "media[upload]");
260
-
261
- form.appendChild(i);
262
-
263
- i = document.createElement("input");
264
- i.setAttribute('type', "hidden");
265
- i.setAttribute('name', "media[upload_cache]");
266
-
267
- form.appendChild(i);
268
-
269
- return form;
270
- }
271
-
272
- const textForm = (form, editable) => {
273
-
274
- // Creates text input for the content of the element and appends it to the form
275
- i = document.createElement("textarea");
276
- i.setAttribute('type', "text");
277
- i.setAttribute('name', "text[inner_text]");
278
- i.setAttribute('autocomplete', "off");
279
- i.innerHTML = editable.innerText;
280
- i.setAttribute('value', editable.innerText);
281
-
282
- form.appendChild(i);
283
-
284
- return form;
285
- }
286
-
287
- const formForm = (form, editable) => {
288
- console.log(editable)
289
- console.log(form)
290
- i = document.createElement("input");
291
- i.setAttribute('type', "text");
292
- i.setAttribute('name', "form[send_to]");
293
- i.setAttribute('value', editable.getAttribute("data-mail"))
294
- form.appendChild(i)
295
- return form
296
- }
297
-
298
-
299
- const createElementFromHTML = (htmlString) => {
300
- // Creates a node element from a HTML string
301
- const div = document.createElement('div');
302
- div.innerHTML = htmlString.trim();
303
-
304
- return div.firstChild;
305
- }
306
-
307
-
308
- // Selects the view's edit button and adds listener to toggle between edit and view mode
309
- const editButton = document.getElementById('hera-edit-button');
310
- if (editButton) {
311
- editButton.addEventListener('click', toggleEditLoader)
312
- }