alchemy_cms 6.0.0.b1 → 6.0.0.pre.b5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/README.md +14 -2
  4. data/Rakefile +37 -23
  5. data/alchemy_cms.gemspec +1 -1
  6. data/app/assets/stylesheets/alchemy/_extends.scss +15 -2
  7. data/app/assets/stylesheets/alchemy/archive.scss +16 -1
  8. data/app/assets/stylesheets/alchemy/fonts.scss +0 -0
  9. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.svg +0 -0
  10. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.ttf +0 -0
  11. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.woff +0 -0
  12. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.svg +0 -0
  13. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.ttf +0 -0
  14. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.woff +0 -0
  15. data/app/assets/stylesheets/tinymce/skins/alchemy/img/anchor.gif +0 -0
  16. data/app/assets/stylesheets/tinymce/skins/alchemy/img/loader.gif +0 -0
  17. data/app/assets/stylesheets/tinymce/skins/alchemy/img/object.gif +0 -0
  18. data/app/assets/stylesheets/tinymce/skins/alchemy/img/trans.gif +0 -0
  19. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +0 -0
  20. data/app/controllers/alchemy/admin/attachments_controller.rb +3 -3
  21. data/app/controllers/alchemy/admin/elements_controller.rb +1 -0
  22. data/app/controllers/alchemy/admin/pages_controller.rb +1 -9
  23. data/app/controllers/alchemy/admin/pictures_controller.rb +21 -8
  24. data/app/controllers/alchemy/admin/resources_controller.rb +84 -10
  25. data/app/controllers/alchemy/api/elements_controller.rb +12 -8
  26. data/app/controllers/alchemy/api/pages_controller.rb +4 -2
  27. data/app/decorators/alchemy/element_editor.rb +7 -4
  28. data/app/decorators/alchemy/ingredient_editor.rb +5 -1
  29. data/app/helpers/alchemy/elements_block_helper.rb +14 -6
  30. data/app/models/alchemy/attachment.rb +24 -7
  31. data/app/models/alchemy/element/element_essences.rb +14 -3
  32. data/app/models/alchemy/element/element_ingredients.rb +11 -3
  33. data/app/models/alchemy/element/presenters.rb +18 -1
  34. data/app/models/alchemy/element.rb +0 -14
  35. data/app/models/alchemy/ingredient.rb +21 -62
  36. data/app/models/alchemy/page/page_natures.rb +1 -10
  37. data/app/models/alchemy/page/page_scopes.rb +4 -0
  38. data/app/models/alchemy/page.rb +13 -4
  39. data/app/models/alchemy/page_version.rb +1 -1
  40. data/app/models/alchemy/picture.rb +14 -38
  41. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -1
  42. data/app/views/alchemy/admin/attachments/index.html.erb +2 -3
  43. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  44. data/app/views/alchemy/admin/elements/destroy.js.erb +1 -3
  45. data/app/views/alchemy/admin/elements/fold.js.erb +2 -2
  46. data/app/views/alchemy/admin/elements/update.js.erb +1 -1
  47. data/app/views/alchemy/admin/pages/_toolbar.html.erb +1 -1
  48. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  49. data/app/views/alchemy/admin/pages/index.html.erb +2 -9
  50. data/app/views/alchemy/admin/partials/_search_form.html.erb +9 -0
  51. data/app/views/alchemy/admin/pictures/_archive.html.erb +1 -1
  52. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
  53. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +4 -2
  54. data/app/views/alchemy/admin/pictures/index.html.erb +8 -3
  55. data/app/views/alchemy/admin/resources/_filter.html.erb +12 -0
  56. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +14 -17
  57. data/app/views/alchemy/admin/resources/_form.html.erb +2 -0
  58. data/app/views/alchemy/admin/resources/_table_header.html.erb +15 -0
  59. data/app/views/alchemy/admin/resources/index.html.erb +3 -11
  60. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
  61. data/app/views/alchemy/ingredients/_file_editor.html.erb +3 -1
  62. data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
  63. data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
  64. data/app/views/alchemy/ingredients/_link_editor.html.erb +8 -8
  65. data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -0
  66. data/app/views/alchemy/ingredients/_page_editor.html.erb +1 -0
  67. data/app/views/alchemy/ingredients/_picture_editor.html.erb +7 -6
  68. data/app/views/alchemy/ingredients/_select_editor.html.erb +1 -0
  69. data/app/views/alchemy/ingredients/_text_editor.html.erb +5 -4
  70. data/config/locales/alchemy.en.yml +85 -49
  71. data/lib/alchemy/forms/builder.rb +21 -1
  72. data/lib/alchemy/resource_filter.rb +40 -0
  73. data/lib/alchemy/resources_helper.rb +1 -16
  74. data/lib/alchemy/test_support/shared_ingredient_examples.rb +21 -4
  75. data/lib/alchemy/tinymce.rb +4 -0
  76. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +18 -7
  77. data/lib/alchemy/version.rb +1 -1
  78. data/lib/alchemy_cms.rb +1 -0
  79. data/lib/generators/alchemy/menus/templates/node.html.erb +1 -1
  80. data/lib/generators/alchemy/menus/templates/node.html.haml +1 -1
  81. data/lib/generators/alchemy/menus/templates/node.html.slim +1 -1
  82. data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
  83. data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
  84. data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
  85. data/package.json +1 -1
  86. metadata +7 -7
  87. data/app/views/alchemy/admin/attachments/_filter_bar.html.erb +0 -29
  88. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +0 -30
@@ -110,22 +110,13 @@ module Alchemy
110
110
  # If the page is the current preview it uses the updated_at value as cache key.
111
111
  #
112
112
  def cache_key
113
- if Page.current_preview == self
113
+ if Page.current_preview == id
114
114
  "alchemy/pages/#{id}-#{updated_at}"
115
115
  else
116
116
  "alchemy/pages/#{id}-#{published_at}"
117
117
  end
118
118
  end
119
119
 
120
- # We use the published_at value for the cache_key.
121
- #
122
- # If no published_at value is set yet, i.e. because it was never published,
123
- # we return the updated_at value.
124
- #
125
- def published_at
126
- read_attribute(:published_at) || updated_at
127
- end
128
-
129
120
  # Returns true if the page cache control headers should be set.
130
121
  #
131
122
  # == Disable Alchemy's page caching globally
@@ -8,6 +8,10 @@ module Alchemy
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
+ # All pages of given page layout
12
+ #
13
+ scope :by_page_layout, ->(page_layout) { where(page_layout: page_layout) }
14
+
11
15
  # All language root pages
12
16
  #
13
17
  scope :language_roots, -> { where(language_root: true) }
@@ -182,20 +182,29 @@ module Alchemy
182
182
  end
183
183
 
184
184
  def alchemy_resource_filters
185
- %w[published not_public restricted]
185
+ [
186
+ {
187
+ name: :by_page_layout,
188
+ values: PageLayout.all.map { |p| [Alchemy.t(p["name"], scope: "page_layout_names"), p["name"]] },
189
+ },
190
+ {
191
+ name: :status,
192
+ values: %w[published not_public restricted],
193
+ },
194
+ ]
186
195
  end
187
196
 
188
197
  def searchable_alchemy_resource_attributes
189
198
  %w[name urlname title]
190
199
  end
191
200
 
192
- # Used to store the current page previewed in the edit page template.
201
+ # Used to store the current page id previewed in the edit page template.
193
202
  #
194
203
  def current_preview=(page)
195
- RequestStore.store[:alchemy_current_preview] = page
204
+ RequestStore.store[:alchemy_current_preview] = page&.id
196
205
  end
197
206
 
198
- # Returns the current page previewed in the edit page template.
207
+ # Returns the current page id previewed in the edit page template.
199
208
  #
200
209
  def current_preview
201
210
  RequestStore.store[:alchemy_current_preview]
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Alchemy
4
4
  class PageVersion < BaseRecord
5
- belongs_to :page, class_name: "Alchemy::Page", inverse_of: :versions
5
+ belongs_to :page, class_name: "Alchemy::Page", inverse_of: :versions, touch: true
6
6
 
7
7
  has_many :elements, -> { order(:position) },
8
8
  class_name: "Alchemy::Element",
@@ -116,6 +116,7 @@ module Alchemy
116
116
  scope :recent, -> { where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at) }
117
117
  scope :deletable, -> { where("#{table_name}.id NOT IN (SELECT picture_id FROM #{EssencePicture.table_name})") }
118
118
  scope :without_tag, -> { left_outer_joins(:taggings).where(gutentag_taggings: { id: nil }) }
119
+ scope :by_file_format, ->(format) { where(image_file_format: format) }
119
120
 
120
121
  # Class methods
121
122
 
@@ -134,6 +135,19 @@ module Alchemy
134
135
  @_url_class = klass
135
136
  end
136
137
 
138
+ def alchemy_resource_filters
139
+ [
140
+ {
141
+ name: :by_file_format,
142
+ values: distinct.pluck(:image_file_format),
143
+ },
144
+ {
145
+ name: :misc,
146
+ values: %w(recent last_upload without_tag),
147
+ },
148
+ ]
149
+ end
150
+
137
151
  def searchable_alchemy_resource_attributes
138
152
  %w(name image_file_name)
139
153
  end
@@ -144,34 +158,6 @@ module Alchemy
144
158
 
145
159
  Picture.where(upload_hash: last_picture.upload_hash)
146
160
  end
147
-
148
- def search_by(params, query, per_page = nil)
149
- pictures = query.result
150
-
151
- if params[:tagged_with].present?
152
- pictures = pictures.tagged_with(params[:tagged_with])
153
- end
154
-
155
- if params[:filter].present?
156
- pictures = pictures.filtered_by(params[:filter])
157
- end
158
-
159
- if per_page
160
- pictures = pictures.page(params[:page] || 1).per(per_page)
161
- end
162
-
163
- pictures.order(:name)
164
- end
165
-
166
- def filtered_by(filter = "")
167
- case filter
168
- when "recent" then recent
169
- when "last_upload" then last_upload
170
- when "without_tag" then without_tag
171
- else
172
- all
173
- end
174
- end
175
161
  end
176
162
 
177
163
  # Instance methods
@@ -203,16 +189,6 @@ module Alchemy
203
189
  nil
204
190
  end
205
191
 
206
- def previous(params = {})
207
- query = Picture.ransack(params[:q])
208
- Picture.search_by(params, query).where("name < ?", name).last
209
- end
210
-
211
- def next(params = {})
212
- query = Picture.ransack(params[:q])
213
- Picture.search_by(params, query).where("name > ?", name).first
214
- end
215
-
216
192
  # Updates name and tag_list attributes.
217
193
  #
218
194
  # Used by +Admin::PicturesController#update_multiple+
@@ -14,7 +14,7 @@
14
14
 
15
15
  <div id="assign_file_list" class="with_padding<%= search_filter_params[:tagged_with].present? ? ' filtered' : '' %>">
16
16
  <div id="library_sidebar">
17
- <%= render 'filter_bar' %>
17
+ <%= render 'filter_bar' if resource_has_filters %>
18
18
 
19
19
  <% if Alchemy::Attachment.tag_counts.any? %>
20
20
  <div class="tag-list">
@@ -7,8 +7,7 @@
7
7
  file_attribute: 'file' %>
8
8
  <% end %>
9
9
  </div>
10
- <%= render 'alchemy/admin/partials/search_form',
11
- additional_params: [:file_type, :tagged_with] %>
10
+ <%= render 'alchemy/admin/partials/search_form' %>
12
11
  <% end %>
13
12
 
14
13
  <div id="archive_all" class="with_tag_filter resources-table-wrapper">
@@ -16,7 +15,7 @@
16
15
  <%= render 'files_list' %>
17
16
 
18
17
  <div id="library_sidebar">
19
- <%= render 'filter_bar' %>
18
+ <%= render 'filter_bar' if resource_has_filters %>
20
19
 
21
20
  <% if Alchemy::Attachment.tag_counts.any? %>
22
21
  <div class="tag-list with_filter_bar<%= ' filtered' if search_filter_params[:tagged_with].present? %>">
@@ -34,7 +34,7 @@
34
34
 
35
35
  Alchemy.growl('<%= Alchemy.t(:successfully_added_element) %>');
36
36
  Alchemy.closeCurrentDialog();
37
- Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
37
+ Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
38
38
  Alchemy.PreviewWindow.refresh(function() {
39
39
  Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>);
40
40
  });
@@ -3,9 +3,7 @@ $('#element_<%= @element.id %>').hide(200, function() {
3
3
  Alchemy.growl('<%= j @notice %>');
4
4
  $('#element_area .sortable-elements').sortable('refresh');
5
5
  Alchemy.PreviewWindow.refresh();
6
- <% @element.richtext_contents_ids.each do |id| %>
7
- tinymce.get('tinymce_<%= id %>').remove();
8
- <% end %>
6
+ Alchemy.Tinymce.remove(<%= @richtext_ids.to_json %>);
9
7
  <% if @element.fixed? %>
10
8
  Alchemy.FixedElements.removeTab(<%= @element.id %>);
11
9
  <% end %>
@@ -14,12 +14,12 @@
14
14
 
15
15
  <% if @element.folded? -%>
16
16
 
17
- Alchemy.Tinymce.remove(<%= @element.richtext_contents_ids.to_json %>);
17
+ Alchemy.Tinymce.remove(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
18
18
 
19
19
  <% else -%>
20
20
 
21
21
  $el.trigger('FocusElementEditor.Alchemy');
22
- Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
22
+ Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
23
23
  Alchemy.GUI.initElement($el);
24
24
  Alchemy.SortableElements(
25
25
  <%= @page.id %>,
@@ -1,7 +1,7 @@
1
1
  (function() {
2
2
  var $el = $('#element_<%= @element.id %>');
3
3
  var $errors = $('#element_<%= @element.id %>_errors');
4
- $('> .element-content .content_editor, > .element-content .ingredient_editor', $el).removeClass('validation_failed');
4
+ $('> .element-content .content_editor, > .element-content .ingredient-editor', $el).removeClass('validation_failed');
5
5
 
6
6
  <%- if @element_validated -%>
7
7
 
@@ -74,4 +74,4 @@
74
74
  <% search_filter_params[:view] = "list" %>
75
75
  <%= render "alchemy/admin/partials/search_form",
76
76
  url: alchemy.admin_pages_path(search_filter_params.except(:q, :page)),
77
- additional_params: [:view, :page_layout, :tagged_with, :filter] %>
77
+ additional_params: [:view] %>
@@ -138,7 +138,7 @@
138
138
  <% end %>
139
139
 
140
140
  <% content_for :javascripts do %>
141
- <% if Alchemy::Tinymce.custom_config_contents(@page).present? %>
141
+ <% if Alchemy::Tinymce.custom_configs_present?(@page) %>
142
142
  <%= render 'tinymce_custom_config' %>
143
143
  <% end %>
144
144
 
@@ -24,15 +24,8 @@
24
24
  <%= paginate @pages, scope: alchemy, theme: "alchemy" %>
25
25
 
26
26
  <div id="library_sidebar">
27
- <%= render "page_layout_filter" %>
28
-
29
- <%= render "filter_bar",
30
- label: Alchemy::Page.human_attribute_name(:status),
31
- url: alchemy.admin_pages_path(search_filter_params.except(:filter, :page).merge(view: "list")) %>
32
-
33
- <% if resource_has_tags %>
34
- <%= render "tag_list" %>
35
- <% end %>
27
+ <%= render "filter_bar" if resource_has_filters %>
28
+ <%= render "tag_list" if resource_has_tags %>
36
29
  </div>
37
30
  <% else %>
38
31
  <% if @page_root %>
@@ -16,6 +16,15 @@
16
16
  id: 'search_field_clear',
17
17
  title: Alchemy.t(:click_to_show_all),
18
18
  style: search_filter_params.fetch(:q, {}).fetch(resource_handler.search_field_name, '').present? ? 'display: block' : 'display: none' %>
19
+
20
+ <% search_filter_params.fetch(:filter, []).each do |filter_param| %>
21
+ <%= hidden_field_tag "filter[#{filter_param[0]}]", filter_param[1], id: nil %>
22
+ <% end %>
23
+
24
+ <% if search_filter_params.fetch(:tagged_with, nil) %>
25
+ <%= hidden_field_tag :tagged_with, search_filter_params.fetch(:tagged_with), id: nil %>
26
+ <% end %>
27
+
19
28
  <% local_assigns.fetch(:additional_params, []).each do |additional_param| %>
20
29
  <%= hidden_field_tag additional_param, search_filter_params[additional_param], id: nil %>
21
30
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <div id="library_sidebar">
2
- <%= render 'filter_bar' %>
2
+ <%= render 'filter_bar' if resource_has_filters %>
3
3
 
4
4
  <% if Alchemy::Picture.tag_counts.any? %>
5
5
  <div class="tag-list with_filter_bar<%= ' filtered' if search_filter_params[:tagged_with].present? %>">
@@ -3,7 +3,7 @@
3
3
  </div>
4
4
  <div id="assign_image_list" class="with_padding<%= search_filter_params[:tagged_with].present? ? ' filtered' : '' %>">
5
5
  <div id="library_sidebar">
6
- <%= render 'filter_bar' %>
6
+ <%= render 'filter_bar' if resource_has_filters %>
7
7
  <div class="tag-list">
8
8
  <%= render 'tag_list' %>
9
9
  </div>
@@ -7,8 +7,10 @@
7
7
  in_dialog: true,
8
8
  redirect_url: alchemy.admin_pictures_path(
9
9
  size: search_filter_params[:size],
10
- filter: 'last_upload',
11
- form_field_id: @form_field_id
10
+ filter: { misc: 'last_upload' },
11
+ form_field_id: @form_field_id,
12
+ content_id: @content.try(:id),
13
+ element_id: @element.try(:id)
12
14
  ) %>
13
15
  <div class="toolbar_spacer"></div>
14
16
  <% end %>
@@ -6,7 +6,7 @@
6
6
  file_attribute: 'image_file',
7
7
  redirect_url: alchemy.admin_pictures_path(
8
8
  size: @size,
9
- filter: 'last_upload'
9
+ filter: { misc: 'last_upload' }
10
10
  ) %>
11
11
  <div class="toolbar_spacer"></div>
12
12
  <% end %>
@@ -67,7 +67,7 @@
67
67
  </div>
68
68
 
69
69
  <%= render 'alchemy/admin/partials/search_form',
70
- additional_params: [:filter, :tagged_with, :size] %>
70
+ additional_params: [:size] %>
71
71
  <% end %>
72
72
 
73
73
  <div id="picture_archive" class="resources-table-wrapper with_tag_filter">
@@ -75,7 +75,12 @@
75
75
  <h2>
76
76
  <%= @pictures.total_count %>
77
77
  <%= Alchemy::Picture.model_name.human(count: @pictures.total_count) %>
78
- <%= Alchemy.t("picture_library.filter.#{search_filter_params[:filter]}") if search_filter_params[:filter].present? %>
78
+ <% if search_filter_params[:filter].present? %>
79
+ <%= Alchemy.t("filtered_by") %>
80
+ <% search_filter_params[:filter].each do |k, v| %>
81
+ <span class="applied-filter"><%= Alchemy.t("filters.picture.#{k}.values.#{v}") %></span>
82
+ <% end %>
83
+ <% end %>
79
84
  </h2>
80
85
  </div>
81
86
  <%= render 'archive' %>
@@ -0,0 +1,12 @@
1
+ <label>
2
+ <h3><%= Alchemy.t("name", scope: ["filters", resource_name, filter.name]) || Alchemy.t('Filter') %></h3>
3
+ <%= select_tag(
4
+ filter.name,
5
+ options_for_select(
6
+ filter.options_for_select, params[:filter].try(:[], filter.name)
7
+ ),
8
+ include_blank: Alchemy.t(:all, scope: ['resources', resource_name, 'filters']),
9
+ data: { remote: !!request.xhr? },
10
+ class: 'alchemy_selectbox'
11
+ ) %>
12
+ </label>
@@ -1,28 +1,25 @@
1
1
  <div id="filter_bar">
2
- <label>
3
- <h3><%= local_assigns[:label] || Alchemy.t('Filter') %></h3>
4
- <%= select_tag(
5
- 'resource_filter',
6
- options_for_select(
7
- resource_filter_select, search_filter_params[:filter]
8
- ),
9
- include_blank: Alchemy.t(:all, scope: ['resources', resource_name, 'filters']),
10
- data: { remote: !!request.xhr? },
11
- class: 'alchemy_selectbox'
12
- ) %>
13
- </label>
2
+ <%= render partial: "filter", collection: resource_filters_for_select %>
14
3
  </div>
15
4
 
16
5
  <script type="text/javascript">
17
6
  $(function() {
18
- $('#resource_filter').on('change', function(e) {
7
+ $('select', '#filter_bar').on('change', function(e) {
19
8
  var $this = $(this);
20
- var url = '<%= local_assigns[:url] || resources_path(resource_handler.namespaced_resources_name, search_filter_params.except(:filter).to_h) %>';
9
+ var filter_param = 'filter['+$this.attr('name')+']';
10
+ var path = '<%= resources_path(resource_handler.namespaced_resources_name) %>';
11
+ var params = new URLSearchParams('<%= raw search_filter_params.to_query %>');
12
+
13
+ if ($this.val() === "") {
14
+ params.delete(filter_param);
15
+ } else {
16
+ params.set(filter_param, $this.val());
17
+ }
18
+
21
19
  if ($this.data('remote') === true) {
22
- $.get(url, {filter: $this.val()}, null, 'script');
20
+ $.get(path, params.toString(), null, 'script');
23
21
  } else {
24
- delimiter = url.match(/\?/) ? '&' : '?';
25
- Turbolinks.visit(url + delimiter + 'filter=' + encodeURIComponent($this.val()));
22
+ Turbolinks.visit(path + '?' + params.toString());
26
23
  }
27
24
  return false;
28
25
  });
@@ -6,6 +6,8 @@
6
6
  label_method: relation[:attr_method],
7
7
  include_blank: Alchemy.t(:blank, scope: 'resources.relation_select'),
8
8
  input_html: {class: 'alchemy_selectbox'} %>
9
+ <% elsif attribute[:type].in? %i[date time datetime] %>
10
+ <%= f.datepicker attribute[:name], resource_attribute_field_options(attribute) %>
9
11
  <% else %>
10
12
  <%= f.input attribute[:name], resource_attribute_field_options(attribute) %>
11
13
  <% end %>
@@ -1,4 +1,19 @@
1
1
  <div class="resources-header">
2
+ <% if search_filter_params[:filter].present? %>
3
+ <b><%= Alchemy.t("filtered_by") %></b>
4
+ <% search_filter_params[:filter].each do |k, v| %>
5
+ <%- tmp_params = search_filter_params.dup -%>
6
+ <%- tmp_params[:filter] = tmp_params[:filter].except(k) -%>
7
+ <%- dismiss_filter_url = resource_url_proxy.url_for(
8
+ { action: 'index' }.merge(tmp_params.except(:page))
9
+ ) -%>
10
+ <div class="applied-filter">
11
+ <%= Alchemy.t("filters.#{resource_handler.resource_name}.#{k}.values.#{v}", default: v) %>
12
+ <%= link_to render_icon(:times, size: 'xs'), dismiss_filter_url, class: 'dismiss-filter' %>
13
+ </div>
14
+ <% end %>
15
+ <% end %>
16
+
2
17
  <h2>
3
18
  <%= resources_instance_variable.total_count %>
4
19
  <%= resource_model.model_name.human(count: resources_instance_variable.total_count) %>