fae-rails 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/app/assets/javascripts/fae/_deploy.js +198 -0
  4. data/app/assets/javascripts/fae/_modals.js +94 -0
  5. data/app/assets/javascripts/fae/application.js +2 -0
  6. data/app/assets/javascripts/fae/form/_ajax.js +4 -2
  7. data/app/assets/javascripts/fae/form/_filtering.js +34 -0
  8. data/app/assets/javascripts/fae/form/_form.js +1 -0
  9. data/app/assets/javascripts/fae/form/_form_manager.js +295 -0
  10. data/app/assets/javascripts/fae/form/_slugger.js.erb +2 -2
  11. data/app/assets/javascripts/fae/form/inputs/_select.js +5 -2
  12. data/app/assets/stylesheets/fae/base.scss +5 -2
  13. data/app/assets/stylesheets/fae/globals/imports/_variables.scss +1 -0
  14. data/app/assets/stylesheets/fae/globals/layout/_base.scss +7 -2
  15. data/app/assets/stylesheets/fae/globals/layout/_content-header.scss +8 -2
  16. data/app/assets/stylesheets/fae/globals/navigation/_header.scss +2 -2
  17. data/app/assets/stylesheets/fae/globals/navigation/_multi-col-subnav.scss +50 -0
  18. data/app/assets/stylesheets/fae/modules/_buttons.scss +11 -0
  19. data/app/assets/stylesheets/fae/modules/_deploy.scss +25 -0
  20. data/app/assets/stylesheets/fae/modules/_modal.scss +25 -0
  21. data/app/assets/stylesheets/fae/modules/_toggles.scss +39 -23
  22. data/app/assets/stylesheets/fae/modules/forms/_asset-actions.scss +1 -1
  23. data/app/assets/stylesheets/fae/modules/forms/_base.scss +1 -1
  24. data/app/assets/stylesheets/fae/modules/forms/_checkbox.scss +1 -1
  25. data/app/assets/stylesheets/fae/modules/forms/_date.scss +16 -0
  26. data/app/assets/stylesheets/fae/modules/forms/_form-manager.scss +82 -0
  27. data/app/assets/stylesheets/fae/modules/forms/_radio.scss +1 -1
  28. data/app/assets/stylesheets/fae/modules/forms/_select.scss +7 -6
  29. data/app/assets/stylesheets/fae/modules/forms/_simple-mde.scss +1 -1
  30. data/app/assets/stylesheets/fae/modules/forms/_textarea.scss +1 -1
  31. data/app/assets/stylesheets/fae/modules/tables/_filters.scss +4 -0
  32. data/app/assets/stylesheets/fae/pages/_login.scss +4 -0
  33. data/app/controllers/fae/application_controller.rb +7 -0
  34. data/app/controllers/fae/base_controller.rb +5 -1
  35. data/app/controllers/fae/deploy_controller.rb +24 -0
  36. data/app/controllers/fae/deploy_hooks_controller.rb +71 -0
  37. data/app/controllers/fae/form_managers_controller.rb +19 -0
  38. data/app/controllers/fae/options_controller.rb +1 -0
  39. data/app/controllers/fae/static_pages_controller.rb +6 -1
  40. data/app/controllers/fae/users_controller.rb +11 -1
  41. data/app/controllers/fae/utilities_controller.rb +18 -6
  42. data/app/helpers/fae/application_helper.rb +26 -1
  43. data/app/helpers/fae/form_helper.rb +26 -2
  44. data/app/helpers/fae/view_helper.rb +22 -9
  45. data/app/models/concerns/fae/base_model_concern.rb +9 -0
  46. data/app/models/fae/change.rb +19 -6
  47. data/app/models/fae/deploy_hook.rb +12 -0
  48. data/app/models/fae/form_manager.rb +24 -0
  49. data/app/models/fae/user.rb +2 -2
  50. data/app/services/fae/netlify_api.rb +197 -0
  51. data/app/views/devise/unlocks/new.html.slim +5 -9
  52. data/app/views/fae/application/_content_form.html.slim +16 -11
  53. data/app/views/fae/application/_file_uploader.html.slim +7 -2
  54. data/app/views/fae/application/_global_search_results.html.slim +1 -1
  55. data/app/views/fae/application/_header.slim +4 -1
  56. data/app/views/fae/application/_mobilenav.slim +3 -0
  57. data/app/views/fae/deploy/index.html.slim +40 -0
  58. data/app/views/fae/deploy_hooks/_form.html.slim +18 -0
  59. data/app/views/fae/deploy_hooks/_table.html.slim +28 -0
  60. data/app/views/fae/deploy_hooks/edit.html.slim +3 -0
  61. data/app/views/fae/deploy_hooks/new.html.slim +3 -0
  62. data/app/views/fae/images/_image_uploader.html.slim +12 -3
  63. data/app/views/fae/options/_form.html.slim +4 -1
  64. data/app/views/fae/pages/activity_log.html.slim +7 -3
  65. data/app/views/fae/pages/home.html.slim +3 -4
  66. data/app/views/fae/shared/_form_header.html.slim +16 -12
  67. data/app/views/fae/shared/_nested_table.html.slim +4 -2
  68. data/app/views/fae/shared/_recent_changes.html.slim +1 -1
  69. data/app/views/fae/shared/_shared_nested_table.html.slim +4 -1
  70. data/app/views/layouts/fae/application.html.slim +1 -0
  71. data/config/deploy.rb +3 -1
  72. data/config/initializers/devise.rb +6 -6
  73. data/config/locales/fae.en.yml +39 -3
  74. data/config/locales/fae.zh-CN.yml +2 -2
  75. data/config/routes.rb +9 -1
  76. data/db/migrate/20140809222030_add_user_table.rb +1 -1
  77. data/db/migrate/20190925153222_create_fae_form_managers.rb +11 -0
  78. data/db/migrate/20220118192729_create_fae_publish_hooks.rb +10 -0
  79. data/db/migrate/20220128133730_rename_publish_hooks.rb +5 -0
  80. data/db/migrate/20220202153607_add_position_to_deploy_hooks.rb +6 -0
  81. data/lib/fae/options.rb +4 -2
  82. data/lib/fae/version.rb +1 -1
  83. data/lib/generators/fae/base_generator.rb +11 -1
  84. data/lib/generators/fae/nested_scaffold_generator.rb +13 -0
  85. data/lib/generators/fae/templates/assets/fae.js +1 -1
  86. data/lib/generators/fae/templates/controllers/nested_scaffold_controller.rb +14 -0
  87. data/lib/generators/fae/templates/initializers/fae.rb +16 -1
  88. data/lib/generators/fae/templates/views/_form.html.slim +10 -1
  89. data/lib/generators/fae/templates/views/_form_index_nested.html.slim +15 -1
  90. data/lib/generators/fae/templates/views/_form_nested.html.slim +19 -2
  91. data/lib/generators/fae/templates/views/static_page_form.html.slim +13 -1
  92. metadata +28 -8
@@ -207,6 +207,22 @@
207
207
  padding: 12px;
208
208
  font-size: 19px;
209
209
  color: $c-darker-grey;
210
+
211
+ }
212
+
213
+ &.table-filter-group {
214
+ width: 130px;
215
+
216
+ input[type=text] {
217
+ border-radius: 0;
218
+ }
219
+
220
+ label:before {
221
+ right: -5px;
222
+ bottom: -6px;
223
+
224
+ font-size: 15px;
225
+ }
210
226
  }
211
227
  }
212
228
 
@@ -0,0 +1,82 @@
1
+ .form-manager-form {
2
+ z-index: 2;
3
+ background: gray(90);
4
+ display: none;
5
+ position: absolute;
6
+ width: 100%;
7
+ height: 100%;
8
+ overflow: scroll;
9
+ margin-top: 1px;
10
+ padding: 100px 40px 0px 30px;
11
+
12
+ .js-form-manager-submit {
13
+ background: gray(20);
14
+ color: white;
15
+ font-size: 13px;
16
+
17
+ &:hover {
18
+ background: gray(10);
19
+ }
20
+ }
21
+
22
+ .helper {
23
+ color: gray(40);
24
+ font-weight: normal;
25
+ }
26
+
27
+ .inner-content {
28
+ margin-top: 103px;
29
+ }
30
+
31
+ .field-input {
32
+ margin-bottom: 10px;
33
+ }
34
+
35
+ header {
36
+ height: 74px;
37
+
38
+ a {
39
+ margin-right: 5px;
40
+ float: right;
41
+ }
42
+ }
43
+
44
+ .form-section {
45
+ margin-bottom: 30px;
46
+ overflow: auto;
47
+ }
48
+
49
+ .single-field {
50
+ float: left;
51
+ width: 25%;
52
+ margin-right: 20px;
53
+
54
+ input {
55
+ width: 100%;
56
+ }
57
+
58
+ .field_title {
59
+ width: 100%;
60
+ display: inline-block;
61
+
62
+ label {
63
+ float: left;
64
+ margin-right: 10px;
65
+ }
66
+
67
+ input {
68
+ width: auto;
69
+ float: left;
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ .js-form-manager-container {
76
+ display: none;
77
+ z-index: 4;
78
+ }
79
+
80
+ .js-launch-form-manager {
81
+ margin-left: 10px;
82
+ }
@@ -64,6 +64,6 @@
64
64
 
65
65
  .radio_collection.focused {
66
66
  .radio_collection-bullet {
67
- border-color: $c-notice-content;
67
+ border-color: $c-focus-border;
68
68
  }
69
69
  }
@@ -32,7 +32,7 @@
32
32
  top: auto;
33
33
  bottom: 100%;
34
34
  margin-bottom: -1px;
35
- border-top: 1px solid $c-notice-content;
35
+ border-top: 1px solid $c-focus-border;
36
36
  border-bottom: none;
37
37
  box-shadow: none;
38
38
  border-radius: 0;
@@ -41,7 +41,7 @@
41
41
 
42
42
  .chosen-container-active {
43
43
  .chosen-single {
44
- border-color: $c-notice-content;
44
+ border-color: $c-focus-border;
45
45
  background: $c-chosen-gradient-end;
46
46
  }
47
47
  }
@@ -120,7 +120,7 @@
120
120
  .chosen-container-multi.chosen-container-active {
121
121
  .chosen-single,
122
122
  .chosen-choices {
123
- border-color: $c-notice-content;
123
+ border-color: $c-focus-border;
124
124
  }
125
125
  }
126
126
 
@@ -159,7 +159,8 @@
159
159
  }
160
160
 
161
161
  .chosen-search {
162
- display: none;
162
+ position: absolute;
163
+ left: -9999px;
163
164
  }
164
165
  }
165
166
 
@@ -185,7 +186,7 @@
185
186
 
186
187
  .chosen-container {
187
188
  .chosen-drop {
188
- border-color: $c-notice-content;
189
+ border-color: $c-focus-border;
189
190
  }
190
191
  }
191
192
 
@@ -307,7 +308,7 @@
307
308
 
308
309
  &.ms-focus {
309
310
  outline: 0;
310
- border-bottom: 4px solid $c-notice-content;
311
+ border-bottom: 4px solid $c-focus-border;
311
312
  }
312
313
  }
313
314
 
@@ -23,7 +23,7 @@
23
23
  &.mde-focus {
24
24
  .CodeMirror-wrap,
25
25
  .editor-toolbar {
26
- border-color: $c-notice-content;
26
+ border-color: $c-focus-border;
27
27
  }
28
28
  }
29
29
  }
@@ -11,6 +11,6 @@ textarea {
11
11
  border-radius: 2px;
12
12
 
13
13
  &:focus {
14
- border-color: $c-notice-content;
14
+ border-color: $c-focus-border;
15
15
  }
16
16
  }
@@ -58,4 +58,8 @@
58
58
  .table-filter-group {
59
59
  display: inline-block;
60
60
  margin: 0 30px 20px 0;
61
+
62
+ &.no-right-margin {
63
+ margin-right: 0;
64
+ }
61
65
  }
@@ -33,6 +33,10 @@
33
33
  width: 50%;
34
34
  margin: auto;
35
35
 
36
+ h2 {
37
+ margin: 0 0 28px;
38
+ }
39
+
36
40
  @include bp(login_container) {
37
41
  display: inline-block;
38
42
  vertical-align: middle;
@@ -17,9 +17,16 @@ module Fae
17
17
  before_action :detect_cancellation
18
18
  before_action :set_change_user
19
19
  before_action :set_locale
20
+ before_action :setup_form_manager
20
21
 
21
22
  private
22
23
 
24
+ def setup_form_manager
25
+ if Fae.use_form_manager
26
+ @form_manager = FormManager.for_model(params, @item)
27
+ end
28
+ end
29
+
23
30
  # defines the locale used to translate the Fae interface
24
31
  def set_locale
25
32
  if I18n.available_locales.include?(language_from_browser)
@@ -35,7 +35,11 @@ module Fae
35
35
  @item = @klass.new(item_params)
36
36
 
37
37
  if @item.save
38
- redirect_to @index_path, notice: t('fae.save_notice')
38
+ if @item.try(:fae_redirect_to_form_on_create)
39
+ redirect_to send("edit_admin_#{@klass_singular}_path", @item.id), notice: t('fae.save_notice')
40
+ else
41
+ redirect_to @index_path, notice: t('fae.save_notice')
42
+ end
39
43
  else
40
44
  build_assets
41
45
  flash[:alert] = t('fae.save_error')
@@ -0,0 +1,24 @@
1
+ module Fae
2
+ class DeployController < ApplicationController
3
+ before_action :admin_only
4
+
5
+ include Fae::ApplicationHelper
6
+
7
+ def index
8
+ raise 'Fae.netlify configs are missing.' unless netlify_enabled?
9
+ @deploy_hooks = DeployHook.all
10
+ end
11
+
12
+ def deploys_list
13
+ render json: Fae::NetlifyApi.new().get_deploys
14
+ end
15
+
16
+ def deploy_site
17
+ if Fae::NetlifyApi.new().run_deploy(params['deploy_hook_type'], current_user)
18
+ return render json: { success: true }
19
+ end
20
+ render json: {success: false}
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,71 @@
1
+ module Fae
2
+ class DeployHooksController < ApplicationController
3
+
4
+ before_action :super_admin_only
5
+ before_action :set_deploy_hook, only: [:show, :edit, :update, :destroy]
6
+ layout false
7
+
8
+ def index
9
+ @deploy_hooks = DeployHook.all
10
+ end
11
+
12
+ def new
13
+ @deploy_hook = DeployHook.new
14
+ end
15
+
16
+ def edit
17
+ end
18
+
19
+ def create
20
+ @deploy_hook = DeployHook.new(deploy_hook_params)
21
+
22
+ if @deploy_hook.save
23
+ flash[:notice] = t('fae.save_notice')
24
+ @deploy_hooks = DeployHook.all
25
+ render template: table_template_path
26
+ else
27
+ render action: 'new'
28
+ end
29
+ end
30
+
31
+ def update
32
+ if @deploy_hook.update(deploy_hook_params)
33
+ flash[:notice] = t('fae.save_notice')
34
+ @deploy_hooks = DeployHook.all
35
+ render template: table_template_path
36
+ else
37
+ render action: 'edit'
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ if @deploy_hook.destroy
43
+ flash[:notice] = t('fae.delete_notice')
44
+ else
45
+ flash[:alert] = t('fae.delete_error')
46
+ end
47
+ @deploy_hooks = DeployHook.all
48
+ render template: table_template_path
49
+ end
50
+
51
+ private
52
+
53
+ def set_deploy_hook
54
+ @deploy_hook = DeployHook.find(params[:id])
55
+ end
56
+
57
+ def deploy_hook_params
58
+ params.require(:deploy_hook).permit!
59
+ end
60
+
61
+ def set_index_path
62
+ # @index_path determines form's cancel btn path
63
+ @index_path = deploy_hooks_path
64
+ end
65
+
66
+ def table_template_path
67
+ "fae/deploy_hooks/_table.html.slim"
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ module Fae
2
+ class FormManagersController < ApplicationController
3
+
4
+ def update
5
+ if params[:form_manager].present?
6
+ fields_serialized = params[:form_manager][:fields].to_json
7
+ conditions = {
8
+ form_manager_model_name: params[:form_manager][:form_manager_model_name],
9
+ }
10
+ if params[:form_manager][:form_manager_model_name] == 'Fae::StaticPage'
11
+ conditions[:form_manager_model_id] = params[:form_manager][:form_manager_model_id]
12
+ end
13
+ FormManager.where(conditions).first_or_initialize.update_attribute(:fields, fields_serialized)
14
+ end
15
+ render body: nil
16
+ end
17
+
18
+ end
19
+ end
@@ -7,6 +7,7 @@ module Fae
7
7
  @option = Option.first || Option.instance
8
8
  @option.build_logo if @option.logo.blank?
9
9
  @option.build_favicon if @option.favicon.blank?
10
+ @deploy_hooks = DeployHook.all
10
11
  end
11
12
 
12
13
  # PATCH/PUT /options/1
@@ -20,7 +20,8 @@ module Fae
20
20
  redirect_to @index_path, notice: t('fae.save_notice')
21
21
  else
22
22
  build_assocs
23
- render template: "#{fae.root_path.gsub('/', '')}/content_blocks/#{params[:slug]}", error: t('fae.save_error')
23
+ flash[:alert] = t('fae.save_error')
24
+ render template: "#{fae.root_path.gsub('/', '')}/content_blocks/#{params[:slug]}"
24
25
  end
25
26
  end
26
27
 
@@ -29,6 +30,9 @@ module Fae
29
30
  # Use callbacks to share common setup or constraints between actions.
30
31
  def set_item
31
32
  @item = "#{params[:slug]}_page".classify.constantize.instance
33
+ if Fae.use_form_manager
34
+ @form_manager = FormManager.for_model(params, @item)
35
+ end
32
36
  end
33
37
 
34
38
  # set up variables so that fae partial forms work
@@ -50,5 +54,6 @@ module Fae
50
54
  @item.send(:"create_#{assoc.name}", attached_as: assoc.name.to_s) if assoc.macro == :has_one && @item.send(:"#{assoc.name}").blank?
51
55
  end
52
56
  end
57
+
53
58
  end
54
59
  end
@@ -23,6 +23,8 @@ module Fae
23
23
  end
24
24
 
25
25
  def create
26
+ authorize_role
27
+
26
28
  @user = Fae::User.new(user_params)
27
29
 
28
30
  if @user.save
@@ -33,11 +35,13 @@ module Fae
33
35
  end
34
36
 
35
37
  def update
38
+ authorize_role
39
+
36
40
  params[:user].delete(:password) if params[:user][:password].blank?
37
41
  params[:user].delete(:password_confirmation) if params[:user][:password].blank? and params[:user][:password_confirmation].blank?
38
42
 
39
43
  if @user.update(user_params)
40
- path = current_user.super_admin? ? users_path : fae.root_path
44
+ path = current_user.super_admin_or_admin? ? users_path : fae.root_path
41
45
  redirect_to path, notice: t('fae.save_notice')
42
46
  else
43
47
  render action: 'edit', error: t('fae.save_error')
@@ -75,5 +79,11 @@ module Fae
75
79
  # @index_path determines form's cancel btn path
76
80
  @index_path = users_path
77
81
  end
82
+
83
+ def authorize_role
84
+ return if params[:user][:role_id].blank?
85
+ return if @role_collection.map(&:id).include?(params[:user][:role_id].to_i)
86
+ params[:user].delete(:role_id)
87
+ end
78
88
  end
79
89
  end
@@ -2,8 +2,9 @@ module Fae
2
2
  class UtilitiesController < ApplicationController
3
3
 
4
4
  def toggle
5
- klass = params[:object].gsub('__', '/').classify.constantize
6
- if can_toggle(klass)
5
+ klass = params[:object].gsub('__', '/').classify
6
+ if can_toggle(klass, params[:attr])
7
+ klass = klass.constantize
7
8
  klass.find(params[:id]).toggle(params[:attr]).save(validate: false)
8
9
  render body: nil
9
10
  else
@@ -42,10 +43,21 @@ module Fae
42
43
 
43
44
  private
44
45
 
45
- def can_toggle(klass)
46
- # restrict models that non-admins aren't allowed to update
47
- restricted_classes = %w(Fae::User Fae::Role Fae::Option)
48
- return false if restricted_classes.include?(klass.name.to_s) && !current_user.super_admin_or_admin?
46
+ def can_toggle(klass, attribute)
47
+ # check if class exists and convert
48
+ return false unless Object.const_defined?(klass)
49
+ klass = klass.constantize
50
+
51
+ # allow admins to toggle Fae::User#active
52
+ return true if klass == Fae::User && attribute == 'active' && current_user.super_admin_or_admin?
53
+
54
+ # restrict models that only super admins can toggle
55
+ restricted_classes = %w(Fae::User Fae::Role Fae::Option Fae::Change)
56
+ return false if restricted_classes.include?(klass.name.to_s) && !current_user.super_admin?
57
+
58
+ # restrict to only other boolean fields
59
+ return false unless klass.columns_hash[attribute].type == :boolean
60
+
49
61
  true
50
62
  end
51
63
 
@@ -22,6 +22,10 @@ module Fae
22
22
  new_klass
23
23
  end
24
24
 
25
+ def deployments_active_class
26
+ '-parent-current -open' if params[:controller].split('/').last == 'deploy'
27
+ end
28
+
25
29
  def col_name_or_image(item, attribute)
26
30
  value = item.send(attribute)
27
31
  return if value.blank?
@@ -72,7 +76,9 @@ module Fae
72
76
  begin
73
77
  return link_to text, fae.edit_content_block_path(change.changeable.slug) if change.changeable_type == 'Fae::StaticPage'
74
78
  parent = change.changeable.respond_to?(:fae_parent) ? change.changeable.fae_parent : nil
75
- edit_path = edit_polymorphic_path([main_app, fae_scope, parent, change.changeable])
79
+ edit_path = edit_polymorphic_path(
80
+ [main_app, fae_scope.to_sym, parent, change.changeable]
81
+ )
76
82
  return link_to text, edit_path
77
83
  rescue
78
84
  return text
@@ -80,6 +86,15 @@ module Fae
80
86
  end
81
87
  end
82
88
 
89
+ def netlify_enabled?
90
+ Fae.netlify.present? &&
91
+ Fae.netlify[:api_user].present? &&
92
+ Fae.netlify[:api_token].present? &&
93
+ Fae.netlify[:site].present? &&
94
+ Fae.netlify[:site_id].present? &&
95
+ Fae.netlify[:api_base].present?
96
+ end
97
+
83
98
  private
84
99
 
85
100
  def nav_path_current?(path)
@@ -110,5 +125,15 @@ module Fae
110
125
  "#{item.class.name.underscore.gsub('/', '_').pluralize}_#{item.id}"
111
126
  end
112
127
 
128
+ def multi_column_nav_ul_class(item_count)
129
+ num = item_count.length
130
+ if num > 30
131
+ 'multicol-nav four'
132
+ elsif num > 20
133
+ 'multicol-nav three'
134
+ elsif num > 10
135
+ 'multicol-nav'
136
+ end
137
+ end
113
138
  end
114
139
  end
@@ -11,6 +11,8 @@ module Fae
11
11
  add_input_class(options, 'js-markdown-editor') if options[:markdown].present?
12
12
  add_input_class(options, 'js-html-editor') if options[:html].present?
13
13
 
14
+ set_form_manager_container_attr(f, options, attribute) unless options[:show_form_manager] == false
15
+
14
16
  set_maxlength(f, attribute, options)
15
17
 
16
18
  f.input attribute, options
@@ -22,6 +24,8 @@ module Fae
22
24
  list_order f, attribute, options
23
25
  set_prompt f, attribute, options if !options[:include_blank].is_a?(String)
24
26
 
27
+ set_form_manager_container_attr(f, options, attribute) unless options[:show_form_manager] == false
28
+
25
29
  f.association attribute, options
26
30
  end
27
31
 
@@ -46,7 +50,8 @@ module Fae
46
50
 
47
51
  def fae_checkbox(f, attribute, options={})
48
52
  options[:type] ||= 'stacked'
49
- options.update(as: :check_boxes, wrapper_class: "checkbox-wrapper js-checkbox-wrapper #{options[:wrapper_class]} -#{options[:type]}", no_label_div: true)
53
+ options[:input_type] ||= :check_boxes
54
+ options.update(as: options[:input_type], wrapper_class: "input checkbox-wrapper js-checkbox-wrapper #{options[:wrapper_class]} -#{options[:type]}", no_label_div: true)
50
55
  association_or_input f, attribute, options
51
56
  end
52
57
 
@@ -125,7 +130,7 @@ module Fae
125
130
  label = options[:label] || label_translation(attribute) || attribute_name
126
131
  if options[:markdown_supported].present? || options[:helper_text].present?
127
132
  label += content_tag :h6, class: 'helper_text' do
128
- concat(options[:helper_text]) if options[:helper_text].present?
133
+ concat(content_tag(:span, options[:helper_text], class: 'helper_text_text')) if options[:helper_text].present?
129
134
  concat(content_tag(:span, 'Markdown Supported', class: 'markdown-support')) if options[:markdown_supported].present?
130
135
  end
131
136
  end
@@ -188,6 +193,25 @@ module Fae
188
193
  end
189
194
  end
190
195
 
196
+ def add_wrapper_class(options, class_name)
197
+ if options.key?(:wrapper_html)
198
+ options[:wrapper_html].merge!({class: "#{options[:wrapper_html][:class]} #{class_name}"})
199
+ else
200
+ options[:wrapper_html] = { class: class_name }
201
+ end
202
+ end
203
+
204
+ def set_form_manager_container_attr(f, options, attribute)
205
+ form_manager_id = f.object.class.name
206
+ form_manager_id = f.object.attached_as if f.object.try(:attached_as)
207
+ form_manager_id += "_#{attribute}"
208
+ if options.key?(:wrapper_html)
209
+ options[:wrapper_html]['data-form-manager-id'] = form_manager_id
210
+ else
211
+ options[:wrapper_html] = { 'data-form-manager-id' => form_manager_id }
212
+ end
213
+ end
214
+
191
215
  # sets collection to class.for_fae_index if not defined
192
216
  def list_order(f, attribute, options)
193
217
  if is_association?(f, attribute) && !options[:collection]
@@ -13,16 +13,16 @@ module Fae
13
13
  Rails.application.routes.url_helpers.fae_path[1..-1]
14
14
  end
15
15
 
16
- def fae_image_form(f, image_name, label: nil, alt_label: nil, caption_label: nil, show_alt: nil, show_caption: nil, required: nil, helper_text: nil, alt_helper_text: nil, caption_helper_text: nil, attached_as: nil)
17
- render 'fae/images/image_uploader', f: f, image_name: image_name, label: label, alt_label: alt_label, caption_label: caption_label, show_alt: show_alt, show_caption: show_caption, required: required, helper_text: helper_text, alt_helper_text: alt_helper_text, caption_helper_text: caption_helper_text, attached_as: attached_as
16
+ def fae_image_form(f, image_name, label: nil, alt_label: nil, caption_label: nil, show_alt: nil, show_caption: nil, required: nil, helper_text: nil, alt_helper_text: nil, caption_helper_text: nil, attached_as: nil, show_form_manager: true)
17
+ render 'fae/images/image_uploader', f: f, image_name: image_name, label: label, alt_label: alt_label, caption_label: caption_label, show_alt: show_alt, show_caption: show_caption, required: required, helper_text: helper_text, alt_helper_text: alt_helper_text, caption_helper_text: caption_helper_text, attached_as: attached_as, show_form_manager: show_form_manager
18
18
  end
19
19
 
20
- def fae_file_form(f, file_name, label: nil, helper_text: nil, required: nil)
21
- render 'fae/application/file_uploader', f: f, file_name: file_name, label: label, required: required, helper_text: helper_text
20
+ def fae_file_form(f, file_name, label: nil, helper_text: nil, required: nil, show_form_manager: true)
21
+ render 'fae/application/file_uploader', f: f, file_name: file_name, label: label, required: required, helper_text: helper_text, show_form_manager: show_form_manager
22
22
  end
23
23
 
24
- def fae_content_form(f, attribute, label: nil, hint: nil, helper_text: nil, markdown: nil, markdown_supported: nil, input_options: nil)
25
- render 'fae/application/content_form', f: f, attribute: attribute, label: label, hint: hint, helper_text: helper_text, markdown: markdown, markdown_supported: markdown_supported, input_options: input_options
24
+ def fae_content_form(f, attribute, label: nil, hint: nil, helper_text: nil, markdown: nil, markdown_supported: nil, input_options: nil, show_form_manager: true)
25
+ render 'fae/application/content_form', f: f, attribute: attribute, label: label, hint: hint, helper_text: helper_text, markdown: markdown, markdown_supported: markdown_supported, input_options: input_options, show_form_manager: show_form_manager
26
26
  end
27
27
 
28
28
  def fae_index_image(image, path = nil)
@@ -40,9 +40,9 @@ module Fae
40
40
 
41
41
  link_to url, class: "slider-wrapper #{link_class}", method: :post, remote: true do
42
42
  '<div class="slider-options">
43
- <div class="slider-option slider-option-yes">Yes</div>
43
+ <div class="slider-option slider-option-yes" aria-live="polite">Yes</div>
44
44
  <div class="slider-option-selector"></div>
45
- <div class="slider-option slider-option-no">No</div>
45
+ <div class="slider-option slider-option-no" aria-live="polite">No</div>
46
46
  </div>'.html_safe
47
47
  end
48
48
  end
@@ -56,7 +56,11 @@ module Fae
56
56
 
57
57
  def fae_delete_button(item, delete_path = nil, *custom_attrs)
58
58
  return if item.blank?
59
- delete_path ||= polymorphic_path([main_app, fae_scope, item.try(:fae_parent), item])
59
+
60
+ delete_path ||= polymorphic_path(
61
+ [main_app, fae_scope.to_sym, item.try(:fae_parent), item]
62
+ )
63
+
60
64
  attrs = { method: :delete, title: 'Delete', class: 'js-tooltip table-action', data: { confirm: t('fae.delete_confirmation') } }
61
65
  attrs.deep_merge!(custom_attrs[0]) if custom_attrs.present?
62
66
  link_to delete_path, attrs do
@@ -115,6 +119,15 @@ module Fae
115
119
  end
116
120
  end
117
121
 
122
+ def fae_filter_datepicker(attribute, options={})
123
+ options[:label] ||= attribute.to_s.titleize
124
+ options[:placeholder] = options[:label] if options[:placeholder].nil?
125
+ content_tag :div, class: 'table-filter-group text-input datepicker' do
126
+ concat label_tag "filter[#{attribute}]", options[:label]
127
+ concat text_field_tag "filter[#{attribute}]", nil, placeholder: options[:placeholder]
128
+ end
129
+ end
130
+
118
131
  def fae_avatar(user = current_user)
119
132
  hash = Digest::MD5.hexdigest(user.email.downcase)
120
133
  "https://secure.gravatar.com/avatar/#{hash}?s=80&d=mm"
@@ -27,6 +27,15 @@ module Fae
27
27
  "#{fae_nested_parent}_id"
28
28
  end
29
29
 
30
+ def fae_form_manager_model_name
31
+ return 'Fae::StaticPage' if self.class.name.constantize.superclass.name == 'Fae::StaticPage'
32
+ self.class.name
33
+ end
34
+
35
+ def fae_form_manager_model_id
36
+ self.id
37
+ end
38
+
30
39
  module ClassMethods
31
40
  def for_fae_index
32
41
  order(order_method)