decidim-assemblies 0.23.3 → 0.24.1

Sign up to get free protection for your applications and to get access to all the features.
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,