slash_admin 0.1.0 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -12
  3. data/app/assets/images/slash_admin/favicon.png +0 -0
  4. data/app/assets/images/slash_admin/logo.png +0 -0
  5. data/app/assets/javascripts/slash_admin/application.js +33 -25
  6. data/app/assets/stylesheets/slash_admin/application.scss +271 -146
  7. data/app/assets/stylesheets/slash_admin/colors.scss +16 -13
  8. data/app/controllers/slash_admin/models_controller.rb +166 -32
  9. data/app/controllers/slash_admin/security/sessions_controller.rb +1 -1
  10. data/app/controllers/slash_admin/selectize_controller.rb +21 -1
  11. data/app/helpers/slash_admin/application_helper.rb +45 -4
  12. data/app/helpers/slash_admin/widgets_helper.rb +1 -0
  13. data/app/views/layouts/slash_admin/application.html.erb +1 -1
  14. data/app/views/slash_admin/base/_data_belongs_to.html.erb +14 -16
  15. data/app/views/slash_admin/base/_data_list.html.erb +118 -121
  16. data/app/views/slash_admin/base/_data_nestable.html.erb +2 -2
  17. data/app/views/slash_admin/base/_data_new.html.erb +4 -1
  18. data/app/views/slash_admin/base/_filters.html.erb +63 -55
  19. data/app/views/slash_admin/base/index.html.erb +3 -3
  20. data/app/views/slash_admin/custom_fields/_google_map.html.erb +14 -11
  21. data/app/views/slash_admin/custom_fields/_select.html.erb +5 -1
  22. data/app/views/slash_admin/custom_fields/_timezone.html.erb +2 -0
  23. data/app/views/slash_admin/dashboard/widgets/_statistic_progress_tile.html.erb +1 -1
  24. data/app/views/slash_admin/fields/_belongs_to.html.erb +2 -2
  25. data/app/views/slash_admin/fields/_carrierwave.html.erb +107 -10
  26. data/app/views/slash_admin/fields/_has_many.html.erb +2 -2
  27. data/app/views/slash_admin/fields/_has_one.html.erb +9 -24
  28. data/app/views/slash_admin/fields/_json.html.erb +1 -1
  29. data/app/views/slash_admin/fields/_jsonb.html.erb +14 -0
  30. data/app/views/slash_admin/{custom_fields → fields}/_nested_belongs_to.html.erb +11 -10
  31. data/app/views/slash_admin/fields/_nested_has_one.html.erb +23 -0
  32. data/app/views/slash_admin/security/sessions/new.html.erb +6 -3
  33. data/app/views/slash_admin/shared/_batch_actions.html.erb +1 -1
  34. data/app/views/slash_admin/shared/_header.html.erb +2 -3
  35. data/app/views/slash_admin/shared/_menu.html.erb +33 -30
  36. data/app/views/slash_admin/shared/_new_form_buttons.html.erb +2 -2
  37. data/config/initializers/validators.rb +4 -0
  38. data/config/locales/{slash_admin.en.yml → en.yml} +3 -0
  39. data/config/locales/{slash_admin.fr.yml → fr.yml} +4 -1
  40. data/lib/batch_translation.rb +1 -1
  41. data/lib/generators/slash_admin/override_admin/override_admin_generator.rb +1 -0
  42. data/lib/generators/slash_admin/override_session/templates/session.erb +2 -2
  43. data/lib/slash_admin.rb +1 -3
  44. data/lib/slash_admin/version.rb +1 -1
  45. data/vendor/assets/javascripts/bootstrap-datepicker.fr.min.js +1 -0
  46. data/vendor/assets/javascripts/bootstrap-datepicker.min.js +8 -0
  47. data/vendor/assets/stylesheets/bootstrap-datepicker.min.css +7 -0
  48. metadata +19 -69
@@ -3,7 +3,7 @@
3
3
 
4
4
  <div class="row">
5
5
  <div class="col-sm-12">
6
- <div class="portlet">
6
+ <div class="portlet" id="portlet-<%= @model_class.model_name.human(count: 2).parameterize.underscore.downcase %>">
7
7
  <div class="portlet-title">
8
8
  <div class="caption">
9
9
  <% if @is_nestable %>
@@ -27,8 +27,8 @@
27
27
  <i class="fa fa-angle-down fix-dropdown"></i>
28
28
  </a>
29
29
  <div class="dropdown-menu">
30
- <a class="dropdown-item" href="<%= polymorphic_url([:slash_admin, @model_class], format: 'csv') %>"><%= t('slash_admin.view.export_csv') %></a>
31
- <a class="dropdown-item" href="<%= polymorphic_url([:slash_admin, @model_class], format: 'xls') %>"><%= t('slash_admin.view.export_xls') %></a>
30
+ <a class="dropdown-item" href="<%= polymorphic_url([:slash_admin, @model_class], filters: params[:filters].present? ? params[:filters].permit! : [], format: 'csv') %>"><%= t('slash_admin.view.export_csv') %></a>
31
+ <!-- <a class="dropdown-item" href="<%= polymorphic_url([:slash_admin, @model_class], format: 'xls') %>"><%= t('slash_admin.view.export_xls') %></a> -->
32
32
  </div>
33
33
  </div>
34
34
  </div>
@@ -1,24 +1,27 @@
1
1
  <%= f.label a.keys.first, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
2
  <input type="text" class="form-control" id="<%= f.options[:html][:id] %>_search" />
3
3
  <script async defer
4
- src="https://maps.googleapis.com/maps/api/js?key=<%= a[a.keys.first.to_sym][:google_api_key] %>&libraries=places&callback=initMap">
4
+ src="https://maps.googleapis.com/maps/api/js?key=<%= a[a.keys.first.to_sym][:google_api_key] %>&libraries=places&callback=initMap&language=<%= I18n.locale %>">
5
5
  </script>
6
6
  <div class="google-map-container" id="<%= f.options[:html][:id] %>_map" style="width:100%; min-height:350px"></div>
7
- <%= f.hidden_field a.keys.first, class: 'form-control', id: f.options[:html][:id] + '_' + a.keys.first.to_s, required: required?(f.object, a) %>
8
-
7
+ <%= f.hidden_field a.keys.first, class: 'form-control', id: f.options[:html][:id] + '_' + a.keys.first.to_s, required: required?(f.object, a), value: f.object.send(a.keys.first.to_s).to_json %>
9
8
  <script type="text/javascript">
10
9
  var map = {};
11
10
  var markers;
12
11
  function initMap() {
13
12
  markers = [];
14
13
  var myOptions = {
15
- zoom: <%= a[a.keys.first.to_sym][:default_zoom_level] %>,
14
+ zoom: <%= a[a.keys.first.to_sym][:default_zoom] %>,
16
15
  center: new google.maps.LatLng(<%= a[a.keys.first.to_sym][:default_latitude] %>, <%= a[a.keys.first.to_sym][:default_longitude] %>),
17
16
  mapTypeId: google.maps.MapTypeId.ROADMAP,
18
17
  scrollwheel: false
19
18
  };
20
19
  map = new google.maps.Map(document.getElementById("<%= f.options[:html][:id] %>_map"), myOptions);
21
- document.getElementById("<%= f.options[:html][:id] %>_search").value = '';
20
+ <% if f.object.send(a.keys.first.to_s).present? %>
21
+ document.getElementById("<%= f.options[:html][:id] %>_search").value = "<%= f.object.send(a.keys.first.to_s)['formatted_address'] %>";
22
+ <% else %>
23
+ document.getElementById("<%= f.options[:html][:id] %>_search").value = '';
24
+ <% end %>
22
25
  initializeAutocomplete('<%= f.options[:html][:id] %>_search');
23
26
  function initializeAutocomplete(id) {
24
27
  var element = document.getElementById(id);
@@ -31,15 +34,15 @@
31
34
  }
32
35
  function onPlaceChanged() {
33
36
  cleanAllMarkers();
34
- var final_datas = {}
37
+ var final_datas = {};
35
38
  var place = this.getPlace();
36
- if (place.length == 0) {
39
+ if (place.length === 0) {
37
40
  return;
38
41
  }
39
42
  var location = place.geometry.location;
40
43
  final_datas.location = {
41
- latitude: location.lat(),
42
- longitude: location.lng()
44
+ lat: location.lat(),
45
+ lng: location.lng()
43
46
  };
44
47
  final_datas.formatted_address = place.formatted_address;
45
48
  for (var i in place.address_components) {
@@ -56,11 +59,11 @@
56
59
  var json = JSON.parse(document.getElementById("<%= f.options[:html][:id] + '_' + a.keys.first.to_s %>").value);
57
60
  if (json.location) {
58
61
  var marker = new google.maps.Marker({
59
- position: new google.maps.LatLng(json.location.latitude, json.location.longitude),
62
+ position: new google.maps.LatLng(json.location.lat, json.location.lng),
60
63
  map: map
61
64
  });
62
65
  markers.push(marker);
63
- map.setCenter(new google.maps.LatLng(json.location.latitude, json.location.longitude));
66
+ map.setCenter(new google.maps.LatLng(json.location.lat, json.location.lng));
64
67
  }
65
68
  }
66
69
  }
@@ -1,2 +1,6 @@
1
1
  <%= f.label a.keys.first, class: "form-control-label #{required?(f.object, a) ? 'required' : ''}" %>
2
- <%= f.select(a.keys.first, a[a.keys.first][:choices], { include_blank: a[a.keys.first][:include_blank], required: required?(f.object, a) }, class: 'selectize-single') %>
2
+ <% if a[a.keys.first][:multiple].present? && a[a.keys.first][:multiple] == true %>
3
+ <%= f.select(a.keys.first, a[a.keys.first][:choices], { include_blank: a[a.keys.first][:include_blank], required: required?(f.object, a) }, class: 'selectize-multiple', multiple: true) %>
4
+ <% else %>
5
+ <%= f.select(a.keys.first, a[a.keys.first][:choices], { include_blank: a[a.keys.first][:include_blank], required: required?(f.object, a) }, class: 'selectize-single') %>
6
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= f.label a.keys.first, class: "form-control-label #{required?(f.object, a) ? 'required' : ''}" %>
2
+ <%= f.select(a.keys.first, ActiveSupport::TimeZone::MAPPING.values, { include_blank: true, required: required?(f.object, a) }, class: 'selectize-single') %>
@@ -2,7 +2,7 @@
2
2
  <div class="display">
3
3
  <div class="number">
4
4
  <h3 class="font-green-sharp">
5
- <span data-counter="counterup" data-value="<%= options[:number] %>"></span><!--
5
+ <span><%= options[:number] %></span><!--
6
6
  --><% if options[:currency].present? %><small><%= options[:currency] %></small><% end %>
7
7
  </h3>
8
8
  <small><%= options[:title] %></small>
@@ -1,9 +1,9 @@
1
1
  <%= f.label a, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
2
  <%= f.collection_select a.to_s + '_id',
3
- class_name_from_association(f.object, a).constantize.all.limit(20), :id, object_label(class_name_from_association(f.object, a)),
3
+ class_name_from_association(f.object, a).constantize.all.order(f.object.send(a).present? ? "CASE WHEN id = #{f.object.send(a).try(:id)} THEN 1 ELSE 0 END DESC" : "id DESC").limit(20), :id, object_label(class_name_from_association(f.object, a)),
4
4
  {
5
5
  prompt: t('slash_admin.view.select_model', model_name: class_name_from_association(f.object, a).constantize.model_name.human.downcase),
6
6
  },
7
7
  'data-model': class_name_from_association(f.object, a).constantize.model_name.to_s.underscore,
8
8
  'data-fields': "SlashAdmin::Models::#{class_name_from_association(f.object, a).classify.pluralize}Controller".constantize.new.autocomplete_params.join(' '),
9
- class: 'selectize-model-single', required: required?(f.object, a).present? %>
9
+ class: 'selectize-model-single', required: required?(f.object, a).present? %>
@@ -1,15 +1,112 @@
1
1
  <%= f.label a.to_sym, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
2
 
3
- <div class="image-field">
4
- <%# TODO handle file that are not image eg pdf %>
5
- <% if f.object.send(a).try(:url).present? %>
6
- <img src="<%= f.object.send(a) %>" class="image"/>
7
- <% end %>
8
- <%= f.hidden_field (a.to_s + '_cache').to_sym %>
9
- <%= f.file_field a %>
3
+ <% if f.object.send(a).is_a? Array %>
4
+ <% multiple_files = true %>
5
+ <% else %>
6
+ <% multiple_files = false %>
7
+ <% end %>
8
+
9
+ <div class="row row-end">
10
+ <div class="col-3">
11
+ <% if multiple_files %>
12
+ <% f.object.send(a).each_with_index do |file, i| %>
13
+ <% extension = file.try(:extension).try(:downcase) || file.try(:format).try(:downcase) || file.try(:file).try(:extension) %>
14
+ <% if extension.present? %>
15
+ <% if %w{jpg png jpeg gif bmp}.include?(extension) %>
16
+ <% if file.try(:url).present? %>
17
+ <a href="#" class="image-link-modal" data-toggle="modal" data-target="#imageModal_<%= f.object.class.name + '_' + a + '_' + i.to_s %>" data-src="<%= file.url %>">
18
+ <div class="block cover-image" style="background: url(<%= file.url %>) no-repeat center center;">
19
+ <div class="image-overlay">
20
+ <i class="fa-2x icon-magnifier icon-zoom-image"></i>
21
+ </div>
22
+ </div>
23
+ </a>
24
+ <div id="imageModal_<%= f.object.class.name + '_' + a + '_' + i.to_s %>" class="modal">
25
+ <div class="modal-dialog modal-xl">
26
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
27
+ <span aria-hidden="true">&times;</span>
28
+ </button>
29
+ <img class="modal-content img-fluid" id="image_container_<%= f.object.class.name + '_' + a + '_' + i.to_s %>"/>
30
+ </div>
31
+ </div>
32
+ <script type="text/javascript">
33
+ var excluder_<%= f.object.class.name + '_' + a + '_' + i.to_s %> = "<%= f.object.class.name + '_' + a + '_' + i.to_s %>";
34
+ var target_<%= f.object.class.name + '_' + a + '_' + i.to_s %> = "imageModal_" + excluder_<%= f.object.class.name + '_' + a + '_' + i.to_s %>;
35
+ $('a[data-target="#'+ target_<%= f.object.class.name + '_' + a + '_' + i.to_s %> +'"]').on('click', function(e) {
36
+ e.preventDefault();
37
+
38
+ var container = $('#image_container_' + excluder_<%= f.object.class.name + '_' + a + '_' + i.to_s %>);
39
+ container.attr('src', '');
40
+
41
+ var src = $(this).attr('data-src');
42
+
43
+ container.attr('src', src);
44
+ });
45
+ </script>
46
+ <% else %>
47
+ <a href="<%= file %>" target="_blank" class="remote-asset-link"><%= file.url %></a>
48
+ <% end %>
49
+ <% end %>
50
+ <% else %>
51
+ <%= t('slash_admin.view.no_image') %>
52
+ <% end %>
53
+ <% end %>
54
+ <% else %>
55
+ <% extension = f.object.send(a).file.try(:extension).try(:downcase) || f.object.send(a).file.try(:format).try(:downcase) || f.object.send(a).file.try(:file).try(:extension) %>
56
+ <% if extension.present? %>
57
+ <% if %w{jpg png jpeg gif bmp}.include?(extension) %>
58
+ <% if f.object.send(a).try(:url).present? %>
59
+ <a href="#" class="image-link-modal" data-toggle="modal" data-target="#imageModal_<%= f.object.class.name + '_' + a.to_s %>" data-src="<%= f.object.send(a) %>">
60
+ <div class="block cover-image" style="background: url(<%= f.object.send(a) %>) no-repeat center center;">
61
+ <div class="image-overlay">
62
+ <i class="fa-2x icon-magnifier icon-zoom-image"></i>
63
+ </div>
64
+ </div>
65
+ </a>
66
+ <div id="imageModal_<%= f.object.class.name + '_' + a.to_s %>" class="modal">
67
+ <div class="modal-dialog modal-xl">
68
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
69
+ <span aria-hidden="true">&times;</span>
70
+ </button>
71
+ <img class="modal-content img-fluid" id="image_container_<%= f.object.class.name + '_' + a.to_s %>"/>
72
+ </div>
73
+ </div>
74
+ <script type="text/javascript">
75
+ var excluder_<%= f.object.class.name + '_' + a.to_s %> = "<%= f.object.class.name + '_' + a.to_s %>";
76
+ var target_<%= f.object.class.name + '_' + a.to_s %> = "imageModal_" + excluder_<%= f.object.class.name + '_' + a.to_s %>;
77
+ $('a[data-target="#'+ target_<%= f.object.class.name + '_' + a.to_s %> +'"]').on('click', function(e) {
78
+ e.preventDefault();
79
+
80
+ var container = $('#image_container_' + excluder_<%= f.object.class.name + '_' + a.to_s %>);
81
+ container.attr('src', '');
82
+
83
+ var src = $(this).attr('data-src');
84
+
85
+ container.attr('src', src);
86
+ });
87
+ </script>
88
+ <% end %>
89
+ <% else %>
90
+ <a href="<%= f.object.send(a) %>" target="_blank" class="remote-asset-link"><%= f.object.send(a) %></a>
91
+ <% end %>
92
+ <% else %>
93
+ <%= t('slash_admin.view.no_image') %>
94
+ <% end %>
95
+ <% end %>
96
+ </div>
97
+ <div class="col-9">
98
+ <%= f.hidden_field (a.to_s + '_cache').to_sym %>
99
+ <%= f.file_field a, multiple: multiple_files %>
100
+ </div>
10
101
  </div>
11
102
 
12
- <% if f.object.send(a).try(:url).present? && required?(f.object, a).blank? %>
13
- <%= f.check_box ('remove_' + a.to_s).to_sym %>
14
- Supprimer l'image
103
+ <% unless multiple_files %>
104
+ <% if f.object.send(a).try(:url).present? && required?(f.object, a).blank? %>
105
+ <div class="form-check image-delete">
106
+ <%= f.check_box ('remove_' + a.to_s).to_sym, class: 'form-check-input' %>
107
+ <label class="form-check-label" for="<%= f.object.model_name.param_key + '_remove_' + a.to_s %>">
108
+ <%= t('slash_admin.view.delete_image') %>
109
+ </label>
110
+ </div>
111
+ <% end %>
15
112
  <% end %>
@@ -1,11 +1,11 @@
1
1
  <%= f.label a, class: "form-control-label #{required?(f.object, a) ? 'required' : ''}" %>
2
2
  <%= f.collection_select "#{a.to_s.singularize}_ids",
3
- class_name_from_association(f.object, a).classify.constantize.all.limit(20), :id,
3
+ class_name_from_association(f.object, a).constantize.all.order(f.object.send(a).present? ? "CASE WHEN id IN(#{f.object.send(a).pluck(:id).join(',')}) THEN 1 ELSE 0 END DESC" : "id DESC").limit(20), :id,
4
4
  object_label(class_name_from_association(f.object, a)),
5
5
  {include_blank: true},
6
6
  {
7
7
  class: 'selectize-model-multiple',
8
- multiple: 'multiple',
8
+ multiple: true,
9
9
  'data-model': class_name_from_association(f.object, a).constantize.model_name.to_s.underscore,
10
10
  'data-fields': "SlashAdmin::Models::#{class_name_from_association(f.object, a).classify.pluralize}Controller".constantize.new.autocomplete_params.join(' '),
11
11
  required: required?(f.object, a)
@@ -1,24 +1,9 @@
1
- <%= f.label a, class: 'form-control-label label-has-one' %>
2
-
3
- <% if @model.send(a).blank? %>
4
- <% @model.send("#{a.to_s}=", a.to_s.classify.constantize.new) %>
5
- <% end %>
6
-
7
- <%= f.fields_for a do |association_form| %>
8
- <% if @model.id.blank? %>
9
- <% if a.is_a?(Hash) %>
10
- <% params_assoc = "SlashAdmin::Models::#{class_name_from_association(f.object, a).pluralize}Controller".constantize.new.create_params(from: @model_class).each %>
11
- <% else %>
12
- <% params_assoc = "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.create_params(from: @model_class).each %>
13
- <% end %>
14
- <% else %>
15
- <% if a.is_a?(Hash) %>
16
- <% params_assoc = "SlashAdmin::Models::#{class_name_from_association(f.object, a).pluralize}Controller".constantize.new.update_params(from: @model_class).each %>
17
- <% else %>
18
- <% params_assoc = "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.update_params(from: @model_class).each %>
19
- <% end %>
20
- <% end %>
21
- <% params_assoc.each do |attribute| %>
22
- <%= render 'slash_admin/fields/form_group', f: association_form, a: attribute %>
23
- <% end %>
24
- <% end %>
1
+ <%= f.label a, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
+ <%= f.select a.to_s,
3
+ class_name_from_association(f.object, a).constantize.all.order(f.object.send(a).present? ? "CASE WHEN id = #{f.object.send(a).try(:id)} THEN 1 ELSE 0 END DESC" : "id DESC").limit(20).collect { |assoc| [assoc.send(object_label(class_name_from_association(f.object, a))), assoc.id] },
4
+ {
5
+ prompt: t('slash_admin.view.select_model', model_name: class_name_from_association(f.object, a).constantize.model_name.human.downcase),
6
+ },
7
+ 'data-model': class_name_from_association(f.object, a).constantize.model_name.to_s.underscore,
8
+ 'data-fields': "SlashAdmin::Models::#{class_name_from_association(f.object, a).classify.pluralize}Controller".constantize.new.autocomplete_params.join(' '),
9
+ class: 'selectize-model-single', required: required?(f.object, a).present? %>
@@ -1,5 +1,5 @@
1
1
  <%= f.label a, class: "form-control-label #{required?(f.object, a) ? 'required' : ''}"%>
2
- <%= f.text_area a, class: "form-control #{'jsonarea_' + f.object.class.to_s + '_' + a.to_s}", required: required?(f.object, a) %>
2
+ <%= f.text_area a, class: "form-control #{'jsonarea_' + f.object.class.to_s + '_' + a.to_s}", required: required?(f.object, a), value: f.object.send(a).to_json %>
3
3
 
4
4
  <script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
5
5
  <script type="text/javascript">
@@ -0,0 +1,14 @@
1
+ <%= f.label a, class: "form-control-label #{required?(f.object, a) ? 'required' : ''}"%>
2
+ <%= f.text_area a, class: "form-control #{'jsonarea_' + f.object.class.to_s + '_' + a.to_s}", required: required?(f.object, a) %>
3
+
4
+ <script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
5
+ <script type="text/javascript">
6
+ var jsonarea_<%= f.object.class.to_s + '_' + a.to_s %> = document.getElementsByClassName("jsonarea_<%= f.object.class.to_s + '_' + a.to_s %>")[0];
7
+ var editor_jsonarea_<%= f.object.class.to_s + '_' + a.to_s %> = CodeMirror.fromTextArea(jsonarea_<%= f.object.class.to_s + '_' + a.to_s %>, {
8
+ lineNumbers: true,
9
+ theme: 'relax-seti',
10
+ mode: "application/json",
11
+ gutters: ["CodeMirror-lint-markers"],
12
+ lint: true
13
+ });
14
+ </script>
@@ -1,24 +1,24 @@
1
- <%= f.label a.keys.first, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
- <%= f.collection_select a.keys.first.to_s + '_id',
3
- class_name_from_association(f.object, a).constantize.all.limit(20), :id, object_label(a),
1
+ <%= f.label a, class: "form-control-label #{required?(f.object, a).present? ? 'required' : ''}" %>
2
+ <%= f.collection_select a.to_s + '_id',
3
+ class_name_from_association(f.object, a).constantize.all.order(f.object.send(a).present? ? "CASE WHEN id = #{f.object.send(a).try(:id)} THEN 1 ELSE 0 END DESC" : "id DESC").limit(20), :id, object_label(a),
4
4
  {
5
5
  prompt: t('slash_admin.view.select_model', model_name: class_name_from_association(f.object, a).constantize.model_name.human.downcase),
6
6
  },
7
7
  'data-model': class_name_from_association(f.object, a).constantize.model_name.to_s.underscore,
8
- 'data-fields': "SlashAdmin::Models::#{a.keys.first.to_s.classify.pluralize}Controller".constantize.new.autocomplete_params.join(' '),
9
- class: "selectize-model-single #{a.keys.first.to_s}_id", required: required?(f.object, a).present? %>
8
+ 'data-fields': "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.autocomplete_params.join(' '),
9
+ class: "selectize-model-single #{a.to_s}_id", required: required?(f.object, a).present? %>
10
10
 
11
- <a href="#" class="add-belongs-to" style="font-size: .9em;"><%= t('slash_admin.view.add', class_name_from_association(f.object, a).constantize.model_name.human.downcase) %></a>
11
+ <a href="#" class="add-belongs-to" style="font-size: .9em;"><%= t('slash_admin.view.add', model_name: class_name_from_association(f.object, a).constantize.model_name.human.downcase) %></a>
12
12
 
13
13
  <script type="text/javascript">
14
14
  $(function() {
15
15
  $('.add-belongs-to').on('click', function(e) {
16
16
  e.preventDefault();
17
17
  $('.modal-belongs-to').html();
18
- $('.modal-belongs-to').html("<%= escape_javascript(render 'slash_admin/base/data_belongs_to', a: a) %>");
18
+ $('.modal-belongs-to').html("<%= escape_javascript(render 'slash_admin/base/data_belongs_to', f: f, a: a) %>");
19
19
  $('.modal-belongs-to').modal('show');
20
20
 
21
- var id = "form#new_<%= a.keys.first.to_s.singularize %>";
21
+ var id = "form#new_<%= a.to_s.singularize %>";
22
22
 
23
23
  function closeModals() {
24
24
  $(".modal").modal("hide");
@@ -45,8 +45,9 @@ class: "selectize-model-single #{a.keys.first.to_s}_id", required: required?(f.o
45
45
  toastr.success("<%= t('slash_admin.view.create_success', model_name: class_name_from_association(f.object, a).constantize.model_name.human) %>");
46
46
  $(id).trigger("reset");
47
47
  closeModals();
48
- var select = $('.<%= a.keys.first.to_s + '_id' %>')[0].selectize;
49
- select.addOption({value: data.id, text: data.title});
48
+ var select = $('.<%= a.to_s + '_id' %>')[0].selectize;
49
+ select.addOption({value: data.id, text: data.name});
50
+ select.refreshOption();
50
51
  select.addItem(data.id);
51
52
  }
52
53
  });
@@ -0,0 +1,23 @@
1
+ <%= f.label a, class: 'form-control-label label-has-one' %>
2
+
3
+ <% if f.object.send(a).blank? %>
4
+ <% f.object.send("#{a.to_s}=", a.to_s.classify.constantize.new) %>
5
+ <% end %>
6
+
7
+ <%= f.fields_for a do |association_form| %>
8
+ <% if f.object.id.blank? %>
9
+ <% method = 'create_params' %>
10
+ <% else %>
11
+ <% method = 'update_params' %>
12
+ <% end %>
13
+
14
+ <% if a.is_a?(Hash) %>
15
+ <% params_assoc = "SlashAdmin::Models::#{class_name_from_association(f.object, a).pluralize}Controller".constantize.new.send(method, from: @model_class) %>
16
+ <% else %>
17
+ <% params_assoc = "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.send(method, from: @model_class) %>
18
+ <% end %>
19
+
20
+ <% params_assoc.each do |attribute| %>
21
+ <%= render 'slash_admin/fields/form_group', f: association_form, a: attribute %>
22
+ <% end %>
23
+ <% end %>
@@ -1,20 +1,23 @@
1
1
  <div class="container-fluid container-fluid-admin bckg-dark">
2
- <div class="login-form centered">
2
+ <div class="login-form">
3
3
  <div class="row">
4
4
  <div class="col-sm-12 content bckg-dark-light">
5
5
  <h2 class="text-center title-login"><%= t('slash_admin.view.administration') %></h2>
6
+ <div align="center">
7
+ <img src="<%= asset_path('slash_admin/logo.png') %>" class="img-fluid" style="max-width: 250px;"/>
8
+ </div>
6
9
  <%= form_for(:admin, url: '') do |f| %>
7
10
  <span class="failed-login">
8
11
  <%= @error_messages %>
9
12
  </span>
10
13
  <div class="input-group">
11
- <span class="input-group-addon">
14
+ <span class="input-group-prepend">
12
15
  <i class="fa fa-user"></i>
13
16
  </span>
14
17
  <%= f.text_field :login, required: false, autofocus: true, label: false, placeholder: t('slash_admin.view.username'), class: 'form-control' %>
15
18
  </div>
16
19
  <div class="input-group">
17
- <span class="input-group-addon">
20
+ <span class="input-group-prepend">
18
21
  <i class="fa fa-lock"></i>
19
22
  </span>
20
23
  <%= f.password_field :password, required: false, label: false, placeholder: t('slash_admin.view.password'), class: 'form-control' %>
@@ -1,4 +1,4 @@
1
- <div class="block-batch pull-right">
1
+ <div class="block-batch float-right">
2
2
  <div class="dropdown">
3
3
  <a class="btn btn-circle btn-info btn-sm dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
4
4
  <i class="fa fa-share"></i>
@@ -18,18 +18,17 @@
18
18
  <img src="data:image/png;base64,<%= current_admin.identicon %>" class="rounded-circle"/>
19
19
  <% end %>
20
20
  <span class=""><%= current_admin.login %></span>
21
- <!--<i class="fa fa-angle-down"></i>-->
22
21
  </a>
23
22
  </li>
24
23
 
25
24
  <li class="nav-item">
26
- <a class="nav-link" href="/" title="Accueil du site" target="_blank">
25
+ <a class="nav-link" href="/" title="<%= t('slash_admin.view.website_homepage') %>" target="_blank">
27
26
  <i class="icon-screen-desktop"></i>
28
27
  </a>
29
28
  </li>
30
29
 
31
30
  <li class="nav-item">
32
- <a class="nav-link" href="<%= slash_admin.logout_url %>" title="Se déconnecter">
31
+ <a class="nav-link" href="<%= slash_admin.logout_url %>" title="<%= t('slash_admin.view.sign_out') %>">
33
32
  <i class="icon-logout"></i>
34
33
  </a>
35
34
  </li>