decidim-assemblies 0.20.1 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>