decidim-assemblies 0.23.3 → 0.24.1

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/assemblies/assembly_m_cell.rb +2 -0
  3. data/app/cells/decidim/assemblies/statistic/show.erb +9 -0
  4. data/app/cells/decidim/assemblies/statistic_cell.rb +20 -0
  5. data/app/cells/decidim/assemblies/statistics/show.erb +17 -0
  6. data/app/cells/decidim/assemblies/statistics_cell.rb +18 -0
  7. data/app/commands/decidim/assemblies/admin/create_assembly.rb +1 -0
  8. data/app/commands/decidim/assemblies/admin/create_assembly_admin.rb +12 -72
  9. data/app/commands/decidim/assemblies/admin/update_assembly.rb +2 -1
  10. data/app/controllers/decidim/assemblies/admin/imports_controller.rb +14 -0
  11. data/app/controllers/decidim/assemblies/admin/moderations/reports_controller.rb +14 -0
  12. data/app/controllers/decidim/assemblies/assemblies_controller.rb +1 -1
  13. data/app/events/decidim/role_assigned_to_assembly_event.rb +1 -1
  14. data/app/forms/decidim/assemblies/admin/assembly_form.rb +3 -0
  15. data/app/helpers/decidim/assemblies/admin/assemblies_admin_menu_helper.rb +15 -0
  16. data/app/models/decidim/assembly.rb +3 -3
  17. data/app/presenters/decidim/assemblies/assembly_stats_presenter.rb +35 -25
  18. data/app/queries/decidim/assemblies/organization_assemblies.rb +1 -1
  19. data/app/queries/decidim/assemblies/organization_published_assemblies.rb +1 -1
  20. data/app/serializers/decidim/assemblies/assembly_serializer.rb +1 -0
  21. data/app/views/decidim/assemblies/admin/assemblies/_form.html.erb +4 -0
  22. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +11 -1
  23. data/app/views/decidim/assemblies/assemblies/show.html.erb +1 -1
  24. data/app/views/layouts/decidim/admin/assemblies.html.erb +2 -20
  25. data/app/views/layouts/decidim/admin/assembly.html.erb +2 -1
  26. data/config/locales/ar.yml +2 -1
  27. data/config/locales/ca.yml +9 -3
  28. data/config/locales/cs.yml +9 -3
  29. data/config/locales/de.yml +9 -3
  30. data/config/locales/el.yml +2 -4
  31. data/config/locales/en.yml +9 -3
  32. data/config/locales/es-MX.yml +9 -3
  33. data/config/locales/es-PY.yml +9 -3
  34. data/config/locales/es.yml +9 -3
  35. data/config/locales/eu.yml +2 -1
  36. data/config/locales/fi-plain.yml +9 -3
  37. data/config/locales/fi.yml +9 -3
  38. data/config/locales/fr-CA.yml +9 -3
  39. data/config/locales/fr.yml +9 -3
  40. data/config/locales/gl.yml +59 -1
  41. data/config/locales/hu.yml +2 -4
  42. data/config/locales/id-ID.yml +2 -1
  43. data/config/locales/is-IS.yml +1 -1
  44. data/config/locales/it.yml +2 -4
  45. data/config/locales/ja.yml +2 -4
  46. data/config/locales/lv.yml +2 -4
  47. data/config/locales/nl.yml +12 -3
  48. data/config/locales/no.yml +2 -4
  49. data/config/locales/pl.yml +21 -9
  50. data/config/locales/pt-BR.yml +2 -1
  51. data/config/locales/pt.yml +2 -4
  52. data/config/locales/ro-RO.yml +149 -102
  53. data/config/locales/ru.yml +3 -2
  54. data/config/locales/sk.yml +0 -3
  55. data/config/locales/sl.yml +2 -1
  56. data/config/locales/sr-CS.yml +0 -3
  57. data/config/locales/sv.yml +11 -3
  58. data/config/locales/tr-TR.yml +2 -4
  59. data/config/locales/uk.yml +3 -2
  60. data/config/locales/zh-CN.yml +2 -4
  61. data/db/migrate/20210204152393_add_weight_field_to_assembly.rb +7 -0
  62. data/db/migrate/20210310120444_add_followable_counter_cache_to_assemblies.rb +16 -0
  63. data/lib/decidim/api/assemblies_type_type.rb +16 -0
  64. data/lib/decidim/api/assembly_member_type.rb +28 -0
  65. data/lib/decidim/api/assembly_type.rb +64 -0
  66. data/lib/decidim/assemblies.rb +1 -0
  67. data/lib/decidim/assemblies/admin_engine.rb +31 -1
  68. data/lib/decidim/assemblies/api.rb +9 -0
  69. data/lib/decidim/assemblies/engine.rb +3 -5
  70. data/lib/decidim/assemblies/participatory_space.rb +38 -38
  71. data/lib/decidim/assemblies/query_extensions.rb +39 -20
  72. data/lib/decidim/assemblies/test/factories.rb +5 -4
  73. data/lib/decidim/assemblies/version.rb +1 -1
  74. metadata +23 -14
  75. data/app/types/decidim/assemblies/assemblies_type_type.rb +0 -17
  76. data/app/types/decidim/assemblies/assembly_member_type.rb +0 -29
  77. data/app/types/decidim/assemblies/assembly_type.rb +0 -67
  78. data/app/views/decidim/assemblies/assemblies/_statistics.html.erb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3be7e066b067fe37f9b13c4adb94f7efad0072564bec6a415424274df0dc886
4
- data.tar.gz: 9732152540a243e1c32975a08134c933684e86e905f2575b491888b00842c807
3
+ metadata.gz: 9c71b557033ffeb9218439858746bbd1105dc21a5f1e6bd2a941c3b02bc4c649
4
+ data.tar.gz: 5dd2d134e36807ccd3d7688c443e505a2bbce924b725fd6f11243ffd7350a052
5
5
  SHA512:
6
- metadata.gz: 1fd7989f03ec5d13b09fe660736a45753d52b3a590d7592e7aba4228a65b4cd35c57bd7e7bc4b308251518b8dd1a63aa160afaa6d0c89013248c2b90c9cdeb6a
7
- data.tar.gz: 1234b0b7107a1c19487400477c269c2f39c3866ef74d4a840ba42e781d7bc15663051ab4bd448ae29a388d9b8902282329520b6d015cafcebe2e26edd26f703e
6
+ metadata.gz: 4ea2f39670430ef241cb72476fea3b731b9cf273651e929bf8448d07cb886f862852fb344764fe36403bb374d0499bbe19289c42591d05f456a8da9f0c91d572
7
+ data.tar.gz: 1d36259d39613525824f9cf9af2b3149860620a492b6fa7e312e0cbbf8d511e479943262ae251827f3603c2ff90deeeb25a9fcdf26c8a3aaf574f49ad7ee2244
@@ -41,10 +41,12 @@ module Decidim
41
41
  end
42
42
 
43
43
  def children_count_status
44
+ # rubocop: disable Style/StringConcatenation
44
45
  content_tag(
45
46
  :strong,
46
47
  t("layouts.decidim.assemblies.index.children")
47
48
  ) + " " + children_assemblies_visible_for_user
49
+ # rubocop: enable Style/StringConcatenation
48
50
  end
49
51
 
50
52
  def children_assemblies_visible_for_user
@@ -0,0 +1,9 @@
1
+ <div class="space-stats__data">
2
+ <span class="space-stats__number">
3
+ <%= stat_number %>
4
+ </span>
5
+
6
+ <h4 class="space-stats__title">
7
+ <%= stat_title %>
8
+ </h4>
9
+ </div>
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This cell renders a Statistic of a Assemblies
6
+ class StatisticCell < Decidim::ViewModel
7
+ include ActionView::Helpers::NumberHelper
8
+
9
+ private
10
+
11
+ def stat_number
12
+ number_with_delimiter(model[:stat_number])
13
+ end
14
+
15
+ def stat_title
16
+ t(model[:stat_title], scope: "decidim.assemblies.statistics")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ <section class="row statistics" id="participatory_process-statistics">
2
+ <div class="columns large-8">
3
+ <div class="row column">
4
+ <h3 class="section-heading">
5
+ <%= stats_heading %>
6
+ </h3>
7
+
8
+ <div class="space-stats">
9
+ <% if model.present? %>
10
+ <%= cell("decidim/assemblies/statistic", collection: model) %>
11
+ <% else %>
12
+ <span class="muted"><%= no_stats %></span>
13
+ <% end %>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </section>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This cell renders the Statistics of an Assembly
6
+ class StatisticsCell < Decidim::ViewModel
7
+ private
8
+
9
+ def stats_heading
10
+ t("statistics.headline", scope: "decidim.assemblies")
11
+ end
12
+
13
+ def no_stats
14
+ t("statistics.no_stats", scope: "decidim.assemblies")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -45,6 +45,7 @@ module Decidim
45
45
  organization: form.current_organization,
46
46
  title: form.title,
47
47
  subtitle: form.subtitle,
48
+ weight: form.weight,
48
49
  slug: form.slug,
49
50
  hashtag: form.hashtag,
50
51
  description: form.description,
@@ -6,6 +6,8 @@ module Decidim
6
6
  # A command with all the business logic when creating a new participatory
7
7
  # process admin in the system.
8
8
  class CreateAssemblyAdmin < NotifyRoleAssignedToAssembly
9
+ include ::Decidim::Admin::CreateParticipatorySpaceAdminUserActions
10
+
9
11
  # Public: Initializes the command.
10
12
  #
11
13
  # form - A form object with the params.
@@ -14,34 +16,21 @@ module Decidim
14
16
  def initialize(form, current_user, assembly)
15
17
  @form = form
16
18
  @current_user = current_user
17
- @assembly = assembly
19
+ @participatory_space = assembly
18
20
  end
19
21
 
20
- # Executes the command. Broadcasts these events:
21
- #
22
- # - :ok when everything is valid.
23
- # - :invalid if the form wasn't valid and we couldn't proceed.
24
- #
25
- # Returns nothing.
26
- def call
27
- return broadcast(:invalid) if form.invalid?
22
+ private
28
23
 
29
- ActiveRecord::Base.transaction do
30
- @user = @user ||= existing_user || new_user
31
- create_role
32
- add_admin_as_follower
33
- end
24
+ attr_reader :form, :participatory_space, :current_user, :user
34
25
 
35
- broadcast(:ok)
36
- rescue ActiveRecord::RecordInvalid
37
- form.errors.add(:email, :taken)
38
- broadcast(:invalid)
26
+ def existing_role
27
+ Decidim::AssemblyUserRole.exists?(
28
+ role: form.role.to_sym,
29
+ user: user,
30
+ assembly: @participatory_process
31
+ )
39
32
  end
40
33
 
41
- private
42
-
43
- attr_reader :form, :assembly, :current_user, :user
44
-
45
34
  def create_role
46
35
  Decidim.traceability.perform_action!(
47
36
  :create,
@@ -54,60 +43,11 @@ module Decidim
54
43
  Decidim::AssemblyUserRole.find_or_create_by!(
55
44
  role: form.role.to_sym,
56
45
  user: user,
57
- assembly: @assembly
46
+ assembly: participatory_space
58
47
  )
59
48
  end
60
49
  send_notification user
61
50
  end
62
-
63
- def existing_user
64
- return @existing_user if defined?(@existing_user)
65
-
66
- @existing_user = User.find_by(
67
- email: form.email,
68
- organization: assembly.organization
69
- )
70
-
71
- InviteUserAgain.call(@existing_user, invitation_instructions) if @existing_user && !@existing_user.invitation_accepted?
72
-
73
- @existing_user
74
- end
75
-
76
- def new_user
77
- @new_user ||= InviteUser.call(user_form) do
78
- on(:ok) do |user|
79
- return user
80
- end
81
- end
82
- end
83
-
84
- def user_form
85
- OpenStruct.new(name: form.name,
86
- email: form.email.downcase,
87
- organization: assembly.organization,
88
- admin: false,
89
- invited_by: current_user,
90
- invitation_instructions: invitation_instructions)
91
- end
92
-
93
- def invitation_instructions
94
- return "invite_admin" if form.role == "admin"
95
-
96
- "invite_collaborator"
97
- end
98
-
99
- def add_admin_as_follower
100
- return if user.follows?(assembly)
101
-
102
- form = Decidim::FollowForm
103
- .from_params(followable_gid: assembly.to_signed_global_id.to_s)
104
- .with_context(
105
- current_organization: assembly.organization,
106
- current_user: user
107
- )
108
-
109
- Decidim::CreateFollow.new(form, user).call
110
- end
111
51
  end
112
52
  end
113
53
  end
@@ -94,7 +94,8 @@ module Decidim
94
94
  facebook_handler: form.facebook_handler,
95
95
  instagram_handler: form.instagram_handler,
96
96
  youtube_handler: form.youtube_handler,
97
- github_handler: form.github_handler
97
+ github_handler: form.github_handler,
98
+ weight: form.weight
98
99
  }.merge(uploader_attributes)
99
100
  end
100
101
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module Admin
6
+ # This controller allows importing things.
7
+ # It is targeted for customizations for importing things that lives under
8
+ # an assembly.
9
+ class ImportsController < Decidim::Admin::ImportsController
10
+ include Concerns::AssemblyAdmin
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module Admin
6
+ module Moderations
7
+ # This controller allows admins to manage moderation reports in an assembly.
8
+ class ReportsController < Decidim::Admin::Moderations::ReportsController
9
+ include Concerns::AssemblyAdmin
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -77,7 +77,7 @@ module Decidim
77
77
  end
78
78
 
79
79
  def parent_assemblies
80
- search.results.parent_assemblies.order(promoted: :desc)
80
+ search.results.parent_assemblies.order(weight: :asc, promoted: :desc)
81
81
  end
82
82
 
83
83
  def stats
@@ -10,7 +10,7 @@ module Decidim
10
10
  end
11
11
 
12
12
  def i18n_role
13
- I18n.t(extra["role"], "decidim.admin.models.assembly_user_role.roles", default: extra["role"])
13
+ I18n.t(extra["role"], scope: "decidim.admin.models.assembly_user_role.roles", default: extra["role"])
14
14
  end
15
15
 
16
16
  def i18n_options
@@ -45,6 +45,7 @@ module Decidim
45
45
  attribute :parent_id, Integer
46
46
  attribute :participatory_processes_ids, Array[Integer]
47
47
  attribute :scope_id, Integer
48
+ attribute :weight, Integer, default: 0
48
49
 
49
50
  attribute :is_transparent, Boolean
50
51
  attribute :promoted, Boolean
@@ -79,6 +80,8 @@ module Decidim
79
80
  validates :banner_image, passthru: { to: Decidim::Assembly }
80
81
  validates :hero_image, passthru: { to: Decidim::Assembly }
81
82
 
83
+ validates :weight, presence: true
84
+
82
85
  alias organization current_organization
83
86
 
84
87
  def ensure_parent_cannot_be_child
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module Admin
6
+ module AssembliesAdminMenuHelper
7
+ include Decidim::Admin::SidebarMenuHelper
8
+
9
+ def admin_assemblies_menu
10
+ @admin_assemblies_menu ||= sidebar_menu(:admin_assemblies_menu)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -67,7 +67,7 @@ module Decidim
67
67
  has_many :components, as: :participatory_space, dependent: :destroy
68
68
 
69
69
  has_many :children, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :parent, dependent: :destroy
70
- belongs_to :parent, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :children, optional: true, counter_cache: :children_count
70
+ belongs_to :parent, class_name: "Decidim::Assembly", inverse_of: :children, optional: true, counter_cache: :children_count
71
71
 
72
72
  validates_upload :hero_image
73
73
  mount_uploader :hero_image, Decidim::HeroImageUploader
@@ -215,9 +215,9 @@ module Decidim
215
215
  # rubocop:disable Rails/SkipsModelValidations
216
216
  def update_children_paths
217
217
  self.class.where(
218
- ["#{self.class.table_name}.parents_path <@ :old_path AND #{self.class.table_name}.id != :id", old_path: parents_path_before_last_save, id: id]
218
+ ["#{self.class.table_name}.parents_path <@ :old_path AND #{self.class.table_name}.id != :id", { old_path: parents_path_before_last_save, id: id }]
219
219
  ).update_all(
220
- ["parents_path = :new_path || subpath(parents_path, nlevel(:old_path))", new_path: parents_path, old_path: parents_path_before_last_save]
220
+ ["parents_path = :new_path || subpath(parents_path, nlevel(:old_path))", { new_path: parents_path, old_path: parents_path_before_last_save }]
221
221
  )
222
222
  end
223
223
  # rubocop:enable Rails/SkipsModelValidations
@@ -2,46 +2,56 @@
2
2
 
3
3
  module Decidim
4
4
  module Assemblies
5
- # A presenter to render statistics in the homepage.
5
+ # A presenter to render statistics in an Assembly.
6
6
  class AssemblyStatsPresenter < Rectify::Presenter
7
7
  attribute :assembly, Decidim::Assembly
8
- include IconHelper
8
+ include Decidim::IconHelper
9
9
 
10
- # Public: Render a collection of primary stats.
11
- def highlighted
12
- highlighted_stats = component_stats(priority: StatsRegistry::HIGH_PRIORITY)
13
- highlighted_stats = highlighted_stats.concat(component_stats(priority: StatsRegistry::MEDIUM_PRIORITY))
10
+ # Public: returns a collection of stats (Hash) for the Assembly Home.
11
+ def collection
12
+ highlighted_stats = assembly_participants_stats
13
+ highlighted_stats.concat(assembly_followers_stats(priority: StatsRegistry::HIGH_PRIORITY))
14
+ highlighted_stats.concat(component_stats(priority: StatsRegistry::HIGH_PRIORITY))
15
+ highlighted_stats.concat(component_stats(priority: StatsRegistry::MEDIUM_PRIORITY))
14
16
  highlighted_stats = highlighted_stats.reject(&:empty?)
15
- highlighted_stats = highlighted_stats.reject { |_manifest, _name, data| data.zero? }
16
- grouped_highlighted_stats = highlighted_stats.group_by { |stats| stats.first.name }
17
-
18
- safe_join(
19
- grouped_highlighted_stats.map do |_manifest_name, stats|
20
- content_tag :div, class: "process_stats-item" do
21
- safe_join(
22
- stats.each_with_index.map do |stat, index|
23
- render_stats_data(stat[0], stat[1], stat[2], index)
24
- end
25
- )
17
+ highlighted_stats = highlighted_stats.reject { |_stat_manifest, _stat_title, stat_number| stat_number.zero? }
18
+ grouped_highlighted_stats = highlighted_stats.group_by(&:first)
19
+
20
+ statistics = []
21
+ grouped_highlighted_stats.each do |_manifest_name, stats|
22
+ stats.each_with_index.each do |stat, _index|
23
+ stat.each_with_index.map do |_item, subindex|
24
+ next unless (subindex % 3).zero?
25
+ next if stat[subindex + 2].zero?
26
+
27
+ statistics << { stat_title: stat[subindex + 1], stat_number: stat[subindex + 2] }
26
28
  end
27
29
  end
28
- )
30
+ end
31
+ statistics
29
32
  end
30
33
 
31
34
  private
32
35
 
36
+ def assembly_participants_stats
37
+ Decidim.stats.only([:participants_count]).with_context(assembly)
38
+ .map { |stat_title, stat_number| [assembly.manifest.name, stat_title, stat_number] }
39
+ end
40
+
33
41
  def component_stats(conditions)
34
42
  Decidim.component_manifests.map do |component_manifest|
35
- component_manifest.stats.filter(conditions).with_context(published_components).map { |name, data| [component_manifest, name, data] }.flatten
43
+ component_manifest.stats.except([:proposals_accepted])
44
+ .filter(conditions)
45
+ .with_context(published_components)
46
+ .map { |stat_title, stat_number| [component_manifest.name, stat_title, stat_number] }.flatten
36
47
  end
37
48
  end
38
49
 
39
- def render_stats_data(component_manifest, name, data, index)
40
- safe_join([
41
- index.zero? ? manifest_icon(component_manifest, role: "img", "aria-hidden": true) : " /&nbsp".html_safe,
42
- content_tag(:span, "#{number_with_delimiter(data)} " + I18n.t(name, scope: "decidim.assemblies.statistics"),
43
- class: "#{name} process_stats-text")
44
- ])
50
+ def assembly_followers_stats(conditions)
51
+ Decidim.stats.only([:followers_count])
52
+ .filter(conditions)
53
+ .with_context(assembly)
54
+ .map { |stat_title, stat_number| [assembly.manifest.name, stat_title, stat_number] }
45
55
  end
46
56
 
47
57
  def published_components
@@ -9,7 +9,7 @@ module Decidim
9
9
  end
10
10
 
11
11
  def query
12
- Decidim::Assembly.where(organization: @organization)
12
+ Decidim::Assembly.where(organization: @organization).order(weight: :asc)
13
13
  end
14
14
  end
15
15
  end
@@ -14,7 +14,7 @@ module Decidim
14
14
  OrganizationAssemblies.new(@organization),
15
15
  PublishedAssemblies.new,
16
16
  VisibleAssemblies.new(@user)
17
- ).query
17
+ ).query.order(weight: :asc)
18
18
  end
19
19
  end
20
20
  end
@@ -22,6 +22,7 @@ module Decidim
22
22
  decidim_organization_id: assembly.decidim_organization_id,
23
23
  title: assembly.title,
24
24
  subtitle: assembly.subtitle,
25
+ weight: assembly.weight,
25
26
  short_description: assembly.short_description,
26
27
  description: assembly.description,
27
28
  remote_hero_image_url: Decidim::Assemblies::AssemblyPresenter.new(assembly).hero_image_url,