fae-rails 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -2
  3. data/app/assets/config/fae/manifest.js +2 -0
  4. data/app/assets/javascripts/fae/_contrast.js +50 -0
  5. data/app/assets/javascripts/fae/_deploy.js +198 -0
  6. data/app/assets/javascripts/fae/_modals.js +94 -0
  7. data/app/assets/javascripts/fae/application.js +7 -1
  8. data/app/assets/javascripts/fae/form/_ajax.js +17 -5
  9. data/app/assets/javascripts/fae/form/_filtering.js +34 -0
  10. data/app/assets/javascripts/fae/form/_form.js +5 -2
  11. data/app/assets/javascripts/fae/form/_form_manager.js +295 -0
  12. data/app/assets/javascripts/fae/form/_slugger.js.erb +2 -2
  13. data/app/assets/javascripts/fae/form/_validator.js +224 -55
  14. data/app/assets/javascripts/fae/form/drag_drop.js +109 -0
  15. data/app/assets/javascripts/fae/form/inputs/_select.js +10 -4
  16. data/app/assets/javascripts/fae/form/inputs/_text.js +23 -9
  17. data/app/assets/javascripts/fae/vendor/simplemde/codemirror-4.inline-attachment.js +95 -0
  18. data/app/assets/javascripts/fae/vendor/simplemde/inline-attachment.js +405 -0
  19. data/app/assets/stylesheets/fae/application.css +1 -0
  20. data/app/assets/stylesheets/fae/base.scss +7 -3
  21. data/app/assets/stylesheets/fae/globals/_tags.scss +1 -1
  22. data/app/assets/stylesheets/fae/globals/imports/_variables.scss +1 -0
  23. data/app/assets/stylesheets/fae/globals/layout/_base.scss +9 -4
  24. data/app/assets/stylesheets/fae/globals/layout/_content-header.scss +14 -4
  25. data/app/assets/stylesheets/fae/globals/legacy/_pre-1.3.scss +1 -1
  26. data/app/assets/stylesheets/fae/globals/navigation/_footer.scss +1 -1
  27. data/app/assets/stylesheets/fae/globals/navigation/_header.scss +3 -3
  28. data/app/assets/stylesheets/fae/globals/navigation/_multi-col-subnav.scss +50 -0
  29. data/app/assets/stylesheets/fae/globals/navigation/_sidenav.scss +2 -2
  30. data/app/assets/stylesheets/fae/globals/navigation/_utility.scss +1 -1
  31. data/app/assets/stylesheets/fae/modules/_buttons.scss +11 -0
  32. data/app/assets/stylesheets/fae/modules/_deploy.scss +25 -0
  33. data/app/assets/stylesheets/fae/modules/_errors-bar.scss +19 -0
  34. data/app/assets/stylesheets/fae/modules/_modal.scss +25 -0
  35. data/app/assets/stylesheets/fae/modules/_toggles.scss +39 -23
  36. data/app/assets/stylesheets/fae/modules/forms/_asset-actions.scss +1 -1
  37. data/app/assets/stylesheets/fae/modules/forms/_base.scss +14 -1
  38. data/app/assets/stylesheets/fae/modules/forms/_checkbox.scss +1 -1
  39. data/app/assets/stylesheets/fae/modules/forms/_date.scss +20 -4
  40. data/app/assets/stylesheets/fae/modules/forms/_form-manager.scss +82 -0
  41. data/app/assets/stylesheets/fae/modules/forms/_hints.scss +1 -1
  42. data/app/assets/stylesheets/fae/modules/forms/_label.scss +1 -1
  43. data/app/assets/stylesheets/fae/modules/forms/_radio.scss +1 -1
  44. data/app/assets/stylesheets/fae/modules/forms/_select.scss +9 -8
  45. data/app/assets/stylesheets/fae/modules/forms/_simple-mde.scss +72 -1
  46. data/app/assets/stylesheets/fae/modules/forms/_textarea.scss +1 -1
  47. data/app/assets/stylesheets/fae/modules/tables/_base.scss +1 -1
  48. data/app/assets/stylesheets/fae/modules/tables/_filters.scss +4 -0
  49. data/app/assets/stylesheets/fae/modules/tables/_pagination.scss +2 -2
  50. data/app/assets/stylesheets/fae/pages/_error.scss +1 -1
  51. data/app/assets/stylesheets/fae/pages/_login.scss +5 -1
  52. data/app/assets/stylesheets/fae/simplemde_override.scss +32 -0
  53. data/app/controllers/fae/application_controller.rb +9 -2
  54. data/app/controllers/fae/base_controller.rb +6 -2
  55. data/app/controllers/fae/deploy_controller.rb +24 -0
  56. data/app/controllers/fae/deploy_hooks_controller.rb +71 -0
  57. data/app/controllers/fae/form_managers_controller.rb +19 -0
  58. data/app/controllers/fae/options_controller.rb +1 -0
  59. data/app/controllers/fae/setup_controller.rb +2 -2
  60. data/app/controllers/fae/static_pages_controller.rb +6 -1
  61. data/app/controllers/fae/users_controller.rb +11 -1
  62. data/app/controllers/fae/utilities_controller.rb +18 -6
  63. data/app/helpers/fae/application_helper.rb +36 -2
  64. data/app/helpers/fae/form_helper.rb +26 -2
  65. data/app/helpers/fae/view_helper.rb +26 -9
  66. data/app/models/concerns/fae/base_model_concern.rb +17 -0
  67. data/app/models/concerns/fae/seo_set_concern.rb +1 -0
  68. data/app/models/fae/change.rb +20 -6
  69. data/app/models/fae/deploy_hook.rb +12 -0
  70. data/app/models/fae/form_manager.rb +24 -0
  71. data/app/models/fae/option.rb +1 -0
  72. data/app/models/fae/seo_set.rb +14 -0
  73. data/app/models/fae/user.rb +2 -2
  74. data/app/services/fae/netlify_api.rb +213 -0
  75. data/app/uploaders/fae/file_uploader.rb +1 -1
  76. data/app/uploaders/fae/image_uploader.rb +2 -2
  77. data/app/views/devise/unlocks/new.html.slim +5 -9
  78. data/app/views/fae/application/_content_form.html.slim +16 -11
  79. data/app/views/fae/application/_file_uploader.html.slim +7 -2
  80. data/app/views/fae/application/_global_search_results.html.slim +1 -1
  81. data/app/views/fae/application/_header.slim +4 -1
  82. data/app/views/fae/application/_mobilenav.slim +3 -0
  83. data/app/views/fae/application/_seo_set_form.html.slim +12 -0
  84. data/app/views/fae/deploy/index.html.slim +40 -0
  85. data/app/views/fae/deploy_hooks/_form.html.slim +18 -0
  86. data/app/views/fae/deploy_hooks/_table.html.slim +28 -0
  87. data/app/views/fae/deploy_hooks/edit.html.slim +3 -0
  88. data/app/views/fae/deploy_hooks/new.html.slim +3 -0
  89. data/app/views/fae/images/_image_uploader.html.slim +12 -3
  90. data/app/views/fae/options/_form.html.slim +6 -2
  91. data/app/views/fae/pages/activity_log.html.slim +7 -3
  92. data/app/views/fae/pages/home.html.slim +3 -4
  93. data/app/views/fae/shared/_errors.slim +0 -3
  94. data/app/views/fae/shared/_form_header.html.slim +20 -12
  95. data/app/views/fae/shared/_nested_table.html.slim +5 -2
  96. data/app/views/fae/shared/_recent_changes.html.slim +1 -1
  97. data/app/views/fae/shared/_shared_nested_table.html.slim +9 -3
  98. data/app/views/layouts/fae/application.html.slim +2 -1
  99. data/config/deploy.rb +3 -1
  100. data/config/initializers/carrierwave.rb +41 -2
  101. data/config/initializers/devise.rb +6 -6
  102. data/config/initializers/fae_judge.rb +4 -2
  103. data/config/locales/fae.en.yml +49 -4
  104. data/config/locales/fae.zh-CN.yml +2 -2
  105. data/config/puma.rb +82 -0
  106. data/config/routes.rb +9 -1
  107. data/db/migrate/20140809222030_add_user_table.rb +1 -1
  108. data/db/migrate/20190925153222_create_fae_form_managers.rb +11 -0
  109. data/db/migrate/20220118192729_create_fae_publish_hooks.rb +10 -0
  110. data/db/migrate/20220128133730_rename_publish_hooks.rb +5 -0
  111. data/db/migrate/20220202153607_add_position_to_deploy_hooks.rb +6 -0
  112. data/db/migrate/20221118161833_create_fae_seo_sets.rb +13 -0
  113. data/lib/fae/concerns/models/base.rb +2 -0
  114. data/lib/fae/engine.rb +3 -3
  115. data/lib/fae/options.rb +18 -18
  116. data/lib/fae/version.rb +1 -1
  117. data/lib/generators/fae/base_generator.rb +28 -5
  118. data/lib/generators/fae/controller_generator.rb +0 -1
  119. data/lib/generators/fae/install_generator.rb +1 -1
  120. data/lib/generators/fae/model_generator.rb +1 -2
  121. data/lib/generators/fae/nested_index_scaffold_generator.rb +1 -2
  122. data/lib/generators/fae/nested_scaffold_generator.rb +23 -2
  123. data/lib/generators/fae/page_generator.rb +1 -2
  124. data/lib/generators/fae/scaffold_generator.rb +1 -1
  125. data/lib/generators/fae/templates/assets/fae.js +1 -1
  126. data/lib/generators/fae/templates/controllers/nested_scaffold_controller.rb +13 -1
  127. data/lib/generators/fae/templates/controllers/scaffold_controller.rb +7 -0
  128. data/lib/generators/fae/templates/initializers/fae.rb +16 -1
  129. data/lib/generators/fae/templates/views/_form.html.slim +12 -1
  130. data/lib/generators/fae/templates/views/_form_index_nested.html.slim +15 -1
  131. data/lib/generators/fae/templates/views/_form_nested.html.slim +22 -2
  132. data/lib/generators/fae/templates/views/static_page_form.html.slim +13 -1
  133. metadata +53 -24
  134. data/config/deploy/dev.rb +0 -19
  135. data/config/deploy/prod.rb +0 -19
  136. data/config/deploy/stage.rb +0 -19
  137. /data/app/assets/javascripts/fae/vendor/{simplemde.min.js → simplemde/simplemde.min.js} +0 -0
@@ -0,0 +1,295 @@
1
+ /* global Fae */
2
+
3
+ /**
4
+ * Fae form manager
5
+ * @namespace form
6
+ * @memberof Fae
7
+ */
8
+ Fae.form.formManager = {
9
+
10
+ $theForm: null,
11
+ $managerForm: null,
12
+ savedFieldSettings: null,
13
+ mainContentClass: 'main-content',
14
+ fmContainerClass: 'js-form-manager-container',
15
+ formManagerFormClass: 'form-manager-form',
16
+ launchManagerClass: 'js-launch-form-manager',
17
+ cancelManagerClass: 'js-form-manager-cancel',
18
+ saveAndCloseManagerClass: 'js-form-manager-submit',
19
+ helperTextTextElClass: 'helper_text_text',
20
+ infoAttr: 'data-form-manager-info',
21
+ languageAttr: 'data-language',
22
+ requiredEl: '<abbr title="required">*</abbr> ',
23
+ containerManagerDataId: 'data-form-manager-id',
24
+ ignoredFields: [
25
+ 'seo_title',
26
+ 'seo_description',
27
+ 'social_media_title',
28
+ 'social_media_description',
29
+ 'social_media_image'
30
+ ],
31
+
32
+ init: function(formSelector) {
33
+ var _this = this;
34
+ formSelector = formSelector || 'form:first';
35
+ _this.$theForm = $(formSelector);
36
+
37
+ // Draw initial label/helper overrides
38
+ _this.setupAllFields(_this.$theForm);
39
+
40
+ $('body').on('click', '.'+_this.launchManagerClass, function(e) {
41
+ e.preventDefault();
42
+ _this.$theForm = $(this).parents('form');
43
+ _this._launchManager($(this));
44
+ });
45
+
46
+ $('body').on('click', '.'+_this.saveAndCloseManagerClass, function(e) {
47
+ e.preventDefault();
48
+ _this._saveAndCloseManager($(this));
49
+ });
50
+
51
+ $('body').on('click', '.'+_this.cancelManagerClass, function(e) {
52
+ e.preventDefault();
53
+ _this._closeManager($(this));
54
+ });
55
+
56
+ },
57
+
58
+ setupAllFields: function($theForm) {
59
+ _this = this;
60
+ if ($theForm.length && $theForm.attr(_this.infoAttr)) {
61
+ this.savedFieldSettings = JSON.parse($theForm.attr(_this.infoAttr));
62
+
63
+ $.each(JSON.parse(this.savedFieldSettings.fields), function(i, fieldSettings) {
64
+ _this._determineFieldSetup(fieldSettings);
65
+ });
66
+ }
67
+ },
68
+
69
+ _determineFieldSetup: function(fieldSettings) {
70
+ var $container = $('[data-form-manager-id="'+fieldSettings.formManagerId+'"]');
71
+ _this._setupField($container, fieldSettings.label, fieldSettings.helper);
72
+
73
+ if ($container.hasClass('image')) {
74
+ var $captionContainer = $('.' + fieldSettings.formManagerId + '_caption_container');
75
+ var $altContainer = $('.' + fieldSettings.formManagerId + '_alt_container');
76
+
77
+ if ($captionContainer) {
78
+ var captionLabel = fieldSettings.label + ' Caption';
79
+ _this._setupField($captionContainer, captionLabel, '');
80
+ }
81
+ if ($altContainer) {
82
+ var altLabel = fieldSettings.label + ' Alt Text';
83
+ _this._setupField($altContainer, altLabel, '');
84
+ }
85
+ }
86
+ },
87
+
88
+ _setupField: function($container, overriddenLabel, overriddenHelper) {
89
+ var _this = this;
90
+ if ($container.length) {
91
+ var $label = $container.find('label:first');
92
+ var $helperTextContainerEl = $container.find('h6');
93
+ var $labelInner = $label.find('.label_inner');
94
+ var $labelTextEl = $label;
95
+ if ($labelInner.length) {
96
+ $labelTextEl = $labelInner;
97
+ }
98
+ var $labelsCheckbox = $labelTextEl.find('input');
99
+
100
+ var newLabelText = '';
101
+ if ($container.hasClass('required') || $label.hasClass('required') || $labelInner.text().indexOf('*') !== -1) {
102
+ newLabelText = _this.requiredEl;
103
+ }
104
+
105
+ newLabelText += overriddenLabel;
106
+ $labelTextEl.html(newLabelText);
107
+
108
+ if($labelsCheckbox.length) {
109
+ $labelTextEl.append($labelsCheckbox);
110
+ }
111
+
112
+ // Don't mess with image alt text or caption helpers
113
+ if ($container.attr('class').indexOf('alt_container') !== -1
114
+ || $container.attr('class').indexOf('caption_container') !== -1
115
+ ) {
116
+ return;
117
+ }
118
+
119
+ // Just do the helper thing no matter what, aka allow empty
120
+ $label.removeClass('has_no_helper_text');
121
+
122
+ // Main form and nested form markup differs, deal with it
123
+ if ($container.find('h6').length) {
124
+ $label.find('.'+_this.helperTextTextElClass).text(overriddenHelper);
125
+ } else {
126
+ if ($helperTextContainerEl.length) {
127
+ $helperTextContainerEl.find('.'+_this.helperTextTextElClass).text(overriddenHelper);
128
+ } else {
129
+ $helperTextContainerEl = $('<h6 />', {class: 'helper_text'}).append($('<span />', {class: 'helper_text_text', text: overriddenHelper}));
130
+ }
131
+ $label.append($helperTextContainerEl);
132
+ }
133
+ }
134
+ },
135
+
136
+ _launchManager: function() {
137
+ var _this = this;
138
+
139
+ // Show all language inputs so we can manage them
140
+ _this.$theForm.find('['+_this.languageAttr+']').show();
141
+
142
+ _this.$managerForm =
143
+ $('<form />', {action: '#', class: _this.formManagerFormClass})
144
+ .append($('<header />', {class: 'content-header js-content-header js-will-be-sticky'})
145
+ .append($('<a />', {href: '#', text: 'Cancel', class: 'button '+_this.cancelManagerClass}))
146
+ .append($('<a />', {href: '#', text: 'Submit', class: 'button js-form-manager-submit'}))
147
+ );
148
+
149
+ // Insert a bunch of inputs for label/helper text
150
+ _this._gatherAndInjectManagerEls();
151
+
152
+ $('.'+_this.fmContainerClass).append(_this.$managerForm);
153
+ _this._revealManagerForm();
154
+
155
+ },
156
+
157
+ _gatherAndInjectManagerEls: function() {
158
+ $(_this.$theForm.find('['+_this.containerManagerDataId+']')).each(function(i) {
159
+ var $container = $(this);
160
+
161
+ if ($container.hasClass('hidden') || !_this._shouldDisplayInManager($container)) { return; }
162
+
163
+ var $label = $container.find('label:first');
164
+ var $labelTextEl = $label;
165
+ var $labelInner = $label.find('.label_inner');
166
+ if ($labelInner.length) {
167
+ $labelTextEl = $labelInner;
168
+ }
169
+ var $helperTextTextEl = $label.find('.'+_this.helperTextTextElClass);
170
+ var containerManagerId = $container.attr(_this.containerManagerDataId);
171
+ var iDParts = containerManagerId.split('_');
172
+ iDParts.shift();
173
+ var fMLabelText = _this._titleize(iDParts.join(' '));
174
+ var labelInputValue = $labelTextEl.clone().children().remove().end().text().replace('*','').trim();
175
+ var helperInputValue = $helperTextTextEl.text();
176
+
177
+ var $fmFieldContainer = $('<div />', {class: "form-section", 'data-form-manager-id': $container.attr('data-form-manager-id')});
178
+ var $fmSingleFieldContainer = $('<div />', {class: "single-field"});
179
+ var $fmSingleHelperFieldContainer = $('<div />', {class: "single-field"});
180
+ var $fmFieldTitle = $('<div />', {class: "field_title"});
181
+ var $fmHelperFieldTitle = $('<div />', {class: "field_title"});
182
+ var $fMLabel = $('<label />', {text: fMLabelText, class: 'fm_label'});
183
+ var $fMHelper = $('<label />', {text: 'Helper', class: 'fm_label'});
184
+ var $labelInput = $('<input />', {type: 'text', id: $container.attr('data-form-manager-id')+'_label_input', class: 'label_input', value: labelInputValue});
185
+ var $helperInput = $('<input />', {type: 'text', id: $container.attr('data-form-manager-id')+'_helper_input', class: 'helper_input', value: helperInputValue});
186
+
187
+ _this.$managerForm.append(
188
+ $fmFieldContainer.append(
189
+ $fmSingleFieldContainer.append(
190
+ $fmFieldTitle.append(
191
+ $fMLabel
192
+ ),
193
+ $labelInput
194
+ ),
195
+ $fmSingleHelperFieldContainer.append(
196
+ $fmHelperFieldTitle.append(
197
+ $fMHelper
198
+ ),
199
+ $helperInput
200
+ )
201
+ )
202
+ );
203
+
204
+ });
205
+ },
206
+
207
+ _revealManagerForm: function() {
208
+ var _this = this;
209
+ $('.'+_this.mainContentClass).hide();
210
+ $('.'+_this.fmContainerClass).show();
211
+ $('.'+_this.formManagerFormClass).fadeIn('fast');
212
+ },
213
+
214
+ _saveAndCloseManager: function() {
215
+ _this = this;
216
+ _this._submitManager();
217
+ _this._closeManager();
218
+ },
219
+
220
+ _closeManager: function() {
221
+ var _this = this;
222
+ $('.'+_this.fmContainerClass).children().remove();
223
+ $('.'+_this.mainContentClass).show();
224
+ },
225
+
226
+ _submitManager: function() {
227
+ var _this = this;
228
+ var payload = {
229
+ form_manager: {
230
+ form_manager_model_name: _this.$theForm.data('form-manager-model'),
231
+ form_manager_model_id: _this.$theForm.data('form-manager-model-id'),
232
+ fields: {}
233
+ }
234
+ };
235
+
236
+ // Gather everything in the inputs for a POST
237
+ $.each(_this.$managerForm.find('['+_this.containerManagerDataId+']'), function(i) {
238
+ var $container = $(this);
239
+ var formManagerId = $container.attr(_this.containerManagerDataId);
240
+ var requiredValue = $container.hasClass('required') ? 1 : 0;
241
+
242
+ payload.form_manager.fields[formManagerId] = {
243
+ formManagerId: formManagerId,
244
+ label: $container.find('.label_input').val(),
245
+ helper: $container.find('.helper_input').val(),
246
+ required: requiredValue
247
+ };
248
+ });
249
+
250
+ // Reset the labels/helpers to the custom ones just made
251
+ $.each(payload.form_manager.fields, function(i, fieldSettings) {
252
+ _this._determineFieldSetup(fieldSettings);
253
+ });
254
+
255
+ $.ajax({
256
+ url: Fae.path+'/form_managers/update',
257
+ type: 'post',
258
+ data: payload,
259
+ headers: {
260
+ 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
261
+ },
262
+ dataType: 'json',
263
+ success: function (data) {
264
+ // do something?
265
+ }
266
+ });
267
+
268
+ },
269
+
270
+ _shouldDisplayInManager: function($container) {
271
+ var _this = this;
272
+ var should = true;
273
+ $(_this.ignoredFields).each(function(i, fuzzyClass) {
274
+ if ($container.attr('class').indexOf(fuzzyClass) > -1) {
275
+ should = false;
276
+ return false;
277
+ }
278
+ });
279
+ return should;
280
+ },
281
+
282
+ _capitalize: function(str) {
283
+ return str.charAt(0).toUpperCase() + str.slice(1);
284
+ },
285
+
286
+ _titleize: function(str) {
287
+ var _this = this;
288
+ var string_array = str.split(' ');
289
+ string_array = string_array.map(function(str) {
290
+ return _this._capitalize(str);
291
+ });
292
+ return string_array.join(' ');
293
+ }
294
+
295
+ };
@@ -74,8 +74,8 @@ Fae.form.slugger = {
74
74
  slug_text = slug_text.join(' ');
75
75
 
76
76
  // Strip accented characters
77
- var from = 'àáâãäæåçèéêëęēėìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ';
78
- var to = 'aaaaaaaceeeeeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY';
77
+ var from = 'âàáâãäæåçèéêëęēėìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ';
78
+ var to = 'aaaaaaaaceeeeeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY';
79
79
 
80
80
  // Loop through all accented characters and replace with non-accents
81
81
  for (var i = 0; i < from.length; i++) {