decidim-assemblies 0.20.1 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/assemblies/assembly_m_cell.rb +1 -5
  3. data/app/commands/decidim/assemblies/admin/create_assemblies_type.rb +45 -0
  4. data/app/commands/decidim/assemblies/admin/create_assembly.rb +1 -2
  5. data/app/commands/decidim/assemblies/admin/destroy_assemblies_type.rb +45 -0
  6. data/app/commands/decidim/assemblies/admin/update_assemblies_type.rb +46 -0
  7. data/app/commands/decidim/assemblies/admin/update_assembly.rb +1 -2
  8. data/app/controllers/concerns/decidim/assemblies/admin/filterable.rb +30 -0
  9. data/app/controllers/decidim/assemblies/admin/assemblies_controller.rb +8 -23
  10. data/app/controllers/decidim/assemblies/admin/assemblies_types_controller.rb +107 -0
  11. data/app/controllers/decidim/assemblies/assemblies_controller.rb +1 -1
  12. data/app/forms/decidim/assemblies/admin/assemblies_type_form.rb +17 -0
  13. data/app/forms/decidim/assemblies/admin/assembly_form.rb +19 -10
  14. data/app/helpers/decidim/assemblies/admin/assemblies_helper.rb +6 -0
  15. data/app/helpers/decidim/assemblies/filter_assemblies_helper.rb +10 -7
  16. data/app/models/decidim/assemblies_type.rb +24 -0
  17. data/app/models/decidim/assembly.rb +12 -2
  18. data/app/models/decidim/assembly_user_role.rb +1 -1
  19. data/app/permissions/decidim/assemblies/permissions.rb +25 -0
  20. data/app/presenters/decidim/assemblies/admin_log/assemblies_type_presenter.rb +43 -0
  21. data/app/presenters/decidim/assemblies/admin_log/assembly_presenter.rb +1 -2
  22. data/app/presenters/decidim/log/value_types/assembly_type_presenter.rb +29 -0
  23. data/app/queries/decidim/assemblies/filtered_assemblies.rb +2 -2
  24. data/app/queries/decidim/assemblies/parent_assemblies_for_select.rb +23 -0
  25. data/app/services/decidim/assemblies/assembly_search.rb +3 -3
  26. data/app/types/decidim/assemblies/assemblies_type_type.rb +17 -0
  27. data/app/types/decidim/assemblies/assembly_member_type.rb +29 -0
  28. data/app/types/decidim/assemblies/assembly_type.rb +67 -0
  29. data/app/views/decidim/assemblies/_filter_by_type.html.erb +14 -12
  30. data/app/views/decidim/assemblies/admin/assemblies/_form.html.erb +2 -6
  31. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +5 -2
  32. data/app/views/decidim/assemblies/admin/assemblies_types/_form.html.erb +11 -0
  33. data/app/views/decidim/assemblies/admin/assemblies_types/edit.html.erb +6 -0
  34. data/app/views/decidim/assemblies/admin/assemblies_types/index.html.erb +43 -0
  35. data/app/views/decidim/assemblies/admin/assemblies_types/new.html.erb +7 -0
  36. data/app/views/decidim/assemblies/admin/assembly_members/index.html.erb +30 -30
  37. data/app/views/decidim/assemblies/assemblies/show.html.erb +1 -5
  38. data/app/views/layouts/decidim/admin/assemblies.html.erb +17 -0
  39. data/app/views/layouts/decidim/admin/assembly.html.erb +2 -2
  40. data/config/locales/ar.yml +24 -0
  41. data/config/locales/ca.yml +32 -0
  42. data/config/locales/cs.yml +33 -1
  43. data/config/locales/de.yml +11 -0
  44. data/config/locales/el.yml +1 -0
  45. data/config/locales/en.yml +32 -0
  46. data/config/locales/es-MX.yml +32 -0
  47. data/config/locales/es-PY.yml +32 -0
  48. data/config/locales/es.yml +32 -0
  49. data/config/locales/eu.yml +11 -0
  50. data/config/locales/fi-plain.yml +32 -0
  51. data/config/locales/fi.yml +32 -0
  52. data/config/locales/fr.yml +11 -0
  53. data/config/locales/gl.yml +11 -0
  54. data/config/locales/hu.yml +32 -0
  55. data/config/locales/id-ID.yml +11 -0
  56. data/config/locales/is-IS.yml +11 -0
  57. data/config/locales/it.yml +20 -0
  58. data/config/locales/nl.yml +20 -0
  59. data/config/locales/no.yml +31 -0
  60. data/config/locales/pl.yml +11 -0
  61. data/config/locales/pt-BR.yml +11 -0
  62. data/config/locales/pt.yml +11 -0
  63. data/config/locales/ru.yml +11 -0
  64. data/config/locales/sv.yml +11 -0
  65. data/config/locales/tr-TR.yml +11 -0
  66. data/config/locales/uk.yml +11 -0
  67. data/db/migrate/20200108113855_create_decidim_assembly_types.rb +19 -0
  68. data/db/migrate/20200108123050_migrate_decidim_assembly_types.rb +83 -0
  69. data/lib/decidim/assemblies/admin_engine.rb +2 -0
  70. data/lib/decidim/assemblies/engine.rb +7 -0
  71. data/lib/decidim/assemblies/participatory_space.rb +3 -2
  72. data/lib/decidim/assemblies/query_extensions.rb +40 -0
  73. data/lib/decidim/assemblies/test/factories.rb +24 -2
  74. data/lib/decidim/assemblies/version.rb +1 -1
  75. metadata +29 -9
  76. data/app/views/decidim/assemblies/assembly_widgets/show.html.erb +0 -11
@@ -14,6 +14,12 @@ module Decidim
14
14
  @processes_selected ||= current_assembly.linked_participatory_space_resources(:participatory_processes, "included_participatory_processes").pluck(:id)
15
15
  end
16
16
  end
17
+
18
+ # Public: A collection of Assemblies that can be selected as parent
19
+ # assemblies for another assembly; to be used in forms.
20
+ def parent_assemblies_for_select
21
+ @parent_assemblies_for_select ||= ParentAssembliesForSelect.for(current_organization, current_assembly)
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -7,10 +7,10 @@ module Decidim
7
7
  # `filter` returns a Filter object from Decidim::FilterResource
8
8
  module FilterAssembliesHelper
9
9
  def available_filters
10
- %w(all) + Assembly::ASSEMBLY_TYPES
10
+ @available_filters ||= [t("all", scope: "decidim.assemblies.filter")] + organization_assembly_types
11
11
  end
12
12
 
13
- def filter_link(filter_name)
13
+ def filter_link(type_id)
14
14
  Decidim::Assemblies::Engine
15
15
  .routes
16
16
  .url_helpers
@@ -18,7 +18,7 @@ module Decidim
18
18
  filter: {
19
19
  scope_id: filter.scope_id,
20
20
  area_id: filter.area_id,
21
- assembly_type: filter_name
21
+ type_id: type_id
22
22
  }
23
23
  )
24
24
  end
@@ -27,12 +27,15 @@ module Decidim
27
27
  t("help", scope: "decidim.assemblies.filter")
28
28
  end
29
29
 
30
- def filter_name(filter_key)
31
- t(filter_key, scope: "decidim.assemblies.filter")
30
+ def current_filter_name
31
+ type = AssembliesType.find_by(id: filter.type_id)
32
+ return translated_attribute type.title if type
33
+
34
+ t("all", scope: "decidim.assemblies.filter")
32
35
  end
33
36
 
34
- def current_filter_name
35
- filter_name(filter.assembly_type)
37
+ def organization_assembly_types
38
+ AssembliesType.where(organization: current_organization)&.map { |type| [translated_attribute(type.title), type.id] }
36
39
  end
37
40
  end
38
41
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Assembly type.
5
+ class AssembliesType < ApplicationRecord
6
+ include Decidim::Traceable
7
+ include Decidim::Loggable
8
+
9
+ belongs_to :organization,
10
+ foreign_key: "decidim_organization_id",
11
+ class_name: "Decidim::Organization"
12
+
13
+ has_many :assemblies,
14
+ foreign_key: "decidim_assemblies_type_id",
15
+ class_name: "Decidim::Assembly",
16
+ dependent: :nullify
17
+
18
+ validates :title, presence: true
19
+
20
+ def self.log_presenter_class_for(_log)
21
+ Decidim::Assemblies::AdminLog::AssembliesTypePresenter
22
+ end
23
+ end
24
+ end
@@ -34,7 +34,6 @@ module Decidim
34
34
  include Decidim::Searchable
35
35
 
36
36
  SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
37
- ASSEMBLY_TYPES = %w(government executive consultative_advisory participatory working_group commission others).freeze
38
37
  CREATED_BY = %w(city_council public others).freeze
39
38
 
40
39
  belongs_to :organization,
@@ -44,6 +43,10 @@ module Decidim
44
43
  foreign_key: "decidim_area_id",
45
44
  class_name: "Decidim::Area",
46
45
  optional: true
46
+ belongs_to :assembly_type,
47
+ foreign_key: "decidim_assemblies_type_id",
48
+ class_name: "Decidim::AssembliesType",
49
+ optional: true
47
50
  has_many :categories,
48
51
  foreign_key: "decidim_participatory_space_id",
49
52
  foreign_type: "decidim_participatory_space_type",
@@ -148,6 +151,13 @@ module Decidim
148
151
  closing_date < Date.current
149
152
  end
150
153
 
154
+ def user_roles(role_name = nil)
155
+ roles = Decidim::AssemblyUserRole.where(assembly: self)
156
+ return roles if role_name.blank?
157
+
158
+ roles.where(role: role_name)
159
+ end
160
+
151
161
  private
152
162
 
153
163
  # When an assembly changes their parent, we need to update the parents_path attribute
@@ -201,7 +211,7 @@ module Decidim
201
211
 
202
212
  # Allow ransacker to search for a key in a hstore column (`title`.`en`)
203
213
  ransacker :title do |parent|
204
- Arel::Nodes::InfixOperation.new("->", parent.table[:title], Arel::Nodes.build_quoted(I18n.locale.to_s))
214
+ Arel::Nodes::InfixOperation.new("->>", parent.table[:title], Arel::Nodes.build_quoted(I18n.locale.to_s))
205
215
  end
206
216
  end
207
217
  end
@@ -11,7 +11,7 @@ module Decidim
11
11
  belongs_to :assembly, foreign_key: "decidim_assembly_id", class_name: "Decidim::Assembly", optional: true
12
12
  alias participatory_space assembly
13
13
 
14
- ROLES = %w(admin collaborator moderator).freeze
14
+ ROLES = %w(admin collaborator moderator valuator).freeze
15
15
  validates :role, inclusion: { in: ROLES }, uniqueness: { scope: [:user, :assembly] }
16
16
  validate :user_and_assembly_same_organization
17
17
 
@@ -35,11 +35,13 @@ module Decidim
35
35
 
36
36
  # org admins and space admins can do everything in the admin section
37
37
  org_admin_action?
38
+ assemblies_type_action?
38
39
 
39
40
  return permission_action unless assembly
40
41
 
41
42
  moderator_action?
42
43
  collaborator_action?
44
+ valuator_action?
43
45
  assembly_admin_action?
44
46
 
45
47
  permission_action
@@ -47,6 +49,21 @@ module Decidim
47
49
 
48
50
  private
49
51
 
52
+ def assemblies_type_action?
53
+ return unless [:assembly_type, :assemblies_type].include? permission_action.subject
54
+ return disallow! unless user.admin?
55
+
56
+ assembly_type = context.fetch(:assembly_type, nil)
57
+ case permission_action.action
58
+ when :destroy
59
+ assemblies_is_empty = assembly_type && assembly_type.assemblies.empty?
60
+
61
+ toggle_allow(assemblies_is_empty)
62
+ else
63
+ allow!
64
+ end
65
+ end
66
+
50
67
  # It's an admin user if it's an organization admin or is a space admin
51
68
  # for the current `assembly`.
52
69
  def admin_user?
@@ -177,6 +194,14 @@ module Decidim
177
194
  allow! if permission_action.action == :read || permission_action.action == :preview
178
195
  end
179
196
 
197
+ # Valuators can only read the assembly components
198
+ def valuator_action?
199
+ return unless can_manage_assembly?(role: :valuator)
200
+
201
+ allow! if permission_action.action == :read && permission_action.subject == :component
202
+ allow! if permission_action.action == :export && permission_action.subject == :component_data
203
+ end
204
+
180
205
  # Process admins can perform everything *inside* that assembly. They cannot
181
206
  # create a assembly or perform actions on assembly groups or other
182
207
  # assemblies.
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::AssembliesType`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # AssembliesTypePresenter.new(action_log, view_helpers).present
15
+ class AssembliesTypePresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def diff_fields_mapping
19
+ {
20
+ title: :i18n
21
+ }
22
+ end
23
+
24
+ def i18n_labels_scope
25
+ "activemodel.attributes.assemblies_type"
26
+ end
27
+
28
+ def action_string
29
+ case action
30
+ when "create", "delete", "update"
31
+ "decidim.admin_log.assembly_type.#{action}"
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ def has_diff?
38
+ action == "delete" || super
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -37,8 +37,7 @@ module Decidim
37
37
  target: :i18n,
38
38
  title: :i18n,
39
39
  purpose_of_action: :i18n,
40
- assembly_type: :string,
41
- assembly_type_other: :i8n,
40
+ decidim_assemblies_type_id: :assembly_type,
42
41
  creation_date: :date,
43
42
  created_by: :string,
44
43
  created_by_other: :i18n,
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Log
5
+ module ValueTypes
6
+ # This class presents the given value as a Decidim::AssembliesType. Check
7
+ # the `DefaultPresenter` for more info on how value
8
+ # presenters work.
9
+ class AssemblyTypePresenter < DefaultPresenter
10
+ # Public: Presents the value as a Decidim::AssembliesType. If the type can
11
+ # be found, it shows its title. Otherwise it shows its ID.
12
+ #
13
+ # Returns an HTML-safe String.
14
+ def present
15
+ return unless value
16
+ return h.translated_attribute(type.title) if type
17
+
18
+ I18n.t("not_found", id: value, scope: "decidim.log.value_types.assembly_type_presenter")
19
+ end
20
+
21
+ private
22
+
23
+ def type
24
+ @type ||= Decidim::AssembliesType.find_by(id: value)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -13,9 +13,9 @@ module Decidim
13
13
  end
14
14
 
15
15
  def query
16
- return assemblies.all if @filter == "all"
16
+ return assemblies.all if @filter.blank?
17
17
 
18
- assemblies.where(assembly_type: @filter)
18
+ assemblies.where(decidim_assemblies_type_id: @filter)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This query filters assemblies that can be assigned as parents for an assembly.
6
+ class ParentAssembliesForSelect < Rectify::Query
7
+ # Syntactic sugar to initialize the class and return the queried objects.
8
+ def self.for(organization, assembly)
9
+ new(organization, assembly).query
10
+ end
11
+
12
+ # Initializes the class.
13
+ def initialize(organization, assembly)
14
+ @organization = organization
15
+ @assembly = assembly
16
+ end
17
+
18
+ def query
19
+ Assembly.where(organization: @organization).where.not(id: @assembly)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,10 +8,10 @@ module Decidim
8
8
  super(Assembly.all, options)
9
9
  end
10
10
 
11
- def search_assembly_type
12
- return query if assembly_type == "all"
11
+ def search_type_id
12
+ return query if type_id.blank?
13
13
 
14
- query.where(assembly_type: assembly_type)
14
+ query.where(decidim_assemblies_type_id: type_id)
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This type represents an AssembliesType.
6
+ AssembliesTypeType = GraphQL::ObjectType.define do
7
+ name "AssembliesType"
8
+ description "An assemblies type"
9
+
10
+ field :id, !types.ID, "The assemblies type's unique ID"
11
+ field :title, !Decidim::Core::TranslatedFieldType, "The title of this assemblies type."
12
+ field :createdAt, !Decidim::Core::DateTimeType, "The time this assemblies type was created", property: :created_at
13
+ field :updatedAt, !Decidim::Core::DateTimeType, "The time this assemblies type was updated", property: :updated_at
14
+ field :assemblies, !types[Decidim::Assemblies::AssemblyType], "Assemblies with this assemblies type"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This type represents a assembly.
6
+ AssemblyMemberType = GraphQL::ObjectType.define do
7
+ name "AssemblyMember"
8
+ description "An assembly member"
9
+
10
+ field :id, !types.ID, "Internal ID of the member"
11
+ field :fullName, types.String, "Full name of the member", property: :full_name
12
+ field :position, types.String, "Position of the member in the assembly"
13
+
14
+ field :user, Decidim::Core::UserType, "The corresponding decidim user", property: :user
15
+
16
+ field :createdAt, Decidim::Core::DateTimeType, "The time this member was created", property: :created_at
17
+ field :updatedAt, Decidim::Core::DateTimeType, "The time this member was updated", property: :updated_at
18
+
19
+ field :weight, types.Int, "Order of appearance in which it should be represented"
20
+ field :gender, types.String, "Gender of the member"
21
+ # field :birthday, Decidim::Core::DateType, "Birthday date of the member" # non-public currently
22
+ field :birthplace, types.String, "Birthplace of the member"
23
+ field :designationDate, Decidim::Core::DateType, "Date of designation of the member", property: :designation_date
24
+ # field :designationMode, types.String, "Mode in which the member was designated", property: :designation_mode # non-public currently
25
+ field :positionOther, types.String, "Custom position name", property: :position_other
26
+ field :ceasedDate, Decidim::Core::DateType, "Date of cease for the member", property: :ceased_date
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This type represents a assembly.
6
+ AssemblyType = GraphQL::ObjectType.define do
7
+ interfaces [
8
+ -> { Decidim::Core::ParticipatorySpaceInterface },
9
+ -> { Decidim::Core::AttachableInterface },
10
+ -> { Decidim::Core::ParticipatorySpaceResourceableInterface }
11
+ ]
12
+
13
+ name "Assembly"
14
+ description "An assembly"
15
+
16
+ field :id, !types.ID, "The internal ID for this assembly"
17
+ field :subtitle, Decidim::Core::TranslatedFieldType, "The subtitle of this assembly"
18
+ field :shortDescription, Decidim::Core::TranslatedFieldType, "The sort description of this assembly", property: :short_description
19
+ field :description, Decidim::Core::TranslatedFieldType, "The description of this assembly"
20
+ field :slug, !types.String, "The slug of this assembly"
21
+ field :hashtag, types.String, "The hashtag for this assembly"
22
+ field :createdAt, !Decidim::Core::DateTimeType, "The time this assembly was created", property: :created_at
23
+ field :updatedAt, !Decidim::Core::DateTimeType, "The time this assembly was updated", property: :updated_at
24
+ field :publishedAt, !Decidim::Core::DateTimeType, "The time this assembly was published", property: :published_at
25
+ field :reference, !types.String, "Reference for this assembly"
26
+ field :categories, !types[Decidim::Core::CategoryType], "Categories for this assembly"
27
+
28
+ field :heroImage, types.String, "The hero image for this assembly", property: :hero_image
29
+ field :bannerImage, types.String, "The banner image for this assembly", property: :banner_image
30
+ field :promoted, types.Boolean, "If this assembly is promoted (therefore in the homepage)"
31
+ field :developerGroup, Decidim::Core::TranslatedFieldType, "The promoter group of this assembly", property: :developer_group
32
+ field :metaScope, Decidim::Core::TranslatedFieldType, "The scope metadata of this assembly", property: :meta_scope
33
+ field :localArea, Decidim::Core::TranslatedFieldType, "The organization area of this assembly", property: :local_area
34
+ field :target, Decidim::Core::TranslatedFieldType, "Who participates in this assembly"
35
+ field :participatoryScope, Decidim::Core::TranslatedFieldType, "What is decided on this assembly", property: :participatory_scope
36
+ field :participatoryStructure, Decidim::Core::TranslatedFieldType, "How it is decided on this assembly", property: :participatory_structure
37
+ field :showStatistics, types.Boolean, "If this assembly should show statistics", property: :show_statistics
38
+ field :scopesEnabled, types.Boolean, "If this assembly has scopes enabled", property: :scopes_enabled
39
+ field :privateSpace, types.Boolean, "If this assembly is a private space", property: :private_space
40
+ field :area, Decidim::Core::AreaApiType, "Area of this assembly"
41
+ field :parent, Decidim::Assemblies::AssemblyType, "The parent assembly of this assembly"
42
+ field :parentsPath, types.String, "Assembly hierarchy representation", property: :parents_path
43
+ field :childrenCount, types.Int, "Number of children assemblies", property: :children_count
44
+ field :purposeOfAction, Decidim::Core::TranslatedFieldType, "Purpose of action", property: :purpose_of_action
45
+ field :composition, Decidim::Core::TranslatedFieldType, "Composition of this assembly"
46
+ field :assemblyType, Decidim::Assemblies::AssembliesTypeType, "Type of the assembly", property: :assembly_type
47
+ field :creationDate, Decidim::Core::DateType, "Creation date of this assembly", property: :creation_date
48
+ field :createdBy, types.String, "The creator of this assembly", property: :created_by
49
+ field :createdByOther, Decidim::Core::TranslatedFieldType, "Custom creator", property: :created_by_other
50
+ field :duration, Decidim::Core::DateType, "Duration of this assembly"
51
+ field :includedAt, Decidim::Core::DateType, "Included at", property: :included_at
52
+ field :closingDate, Decidim::Core::DateType, "Closing date of the assembly", property: :closing_date
53
+ field :closingDateReason, Decidim::Core::TranslatedFieldType, "Closing date reason of this assembly", property: :closing_date_reason
54
+ field :internalOrganisation, Decidim::Core::TranslatedFieldType, "Internal organisation of this assembly", property: :internal_organisation
55
+ field :isTransparent, types.Boolean, "If this assembly is transparent", property: :is_transparent
56
+ field :specialFeatures, Decidim::Core::TranslatedFieldType, "Special features of this assembly", property: :special_features
57
+ field :twitterHandler, types.String, "Twitter handler", property: :twitter_handler
58
+ field :instagramHandler, types.String, "Instagram handler", property: :instagram_handler
59
+ field :facebookHandler, types.String, "Facebook handler", property: :facebook_handler
60
+ field :youtubeHandler, types.String, "Youtube handler", property: :youtube_handler
61
+ field :githubHandler, types.String, "Github handler", property: :github_handler
62
+
63
+ field :members, !types[Decidim::Assemblies::AssemblyMemberType], "Members of this assembly"
64
+ field :children, !types[Decidim::Assemblies::AssemblyType], "Childrens of this assembly"
65
+ end
66
+ end
67
+ end
@@ -1,15 +1,17 @@
1
1
  <div id="assemblies-filter" class="inline-filters">
2
- <label>
3
- <span><%= help_text %></span>
4
- <button id="button-text" data-toggle="inline-filter-sort"><%= current_filter_name %></button>
5
- <div id="inline-filter-sort" class="dropdown-pane" data-position="bottom" data-alignment="right" data-dropdown data-auto-focus="true">
6
- <ul class="list-reset">
7
- <% available_filters.each do |filter| %>
8
- <%= link_to filter_link(filter), remote: true do %>
9
- <li><%= filter_name(filter) %></li>
2
+ <% if available_filters.any? %>
3
+ <label>
4
+ <span><%= help_text %></span>
5
+ <button id="button-text" data-toggle="inline-filter-sort"><%= current_filter_name %></button>
6
+ <div id="inline-filter-sort" class="dropdown-pane" data-position="bottom" data-alignment="right" data-dropdown data-auto-focus="true">
7
+ <ul class="list-reset">
8
+ <% available_filters.each do |title, id| %>
9
+ <%= link_to filter_link(id), remote: true do %>
10
+ <li><%= title %></li>
11
+ <% end %>
10
12
  <% end %>
11
- <% end %>
12
- </ul>
13
- </div>
14
- </label>
13
+ </ul>
14
+ </div>
15
+ </label>
16
+ <% end %>
15
17
  </div>