decidim-action_delegator 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +225 -0
  4. data/Rakefile +41 -0
  5. data/app/assets/config/admin/decidim_action_delegator_manifest.css +0 -0
  6. data/app/assets/config/admin/decidim_action_delegator_manifest.js +1 -0
  7. data/app/assets/config/decidim_action_delegator_manifest.css +3 -0
  8. data/app/assets/config/decidim_action_delegator_manifest.js +2 -0
  9. data/app/assets/images/decidim/action_delegator/icon.svg +1 -0
  10. data/app/assets/javascripts/decidim/action_delegator/admin/action_delegator.js.es6 +3 -0
  11. data/app/assets/javascripts/decidim/action_delegator/questions.js.es6 +26 -0
  12. data/app/assets/stylesheets/decidim/action_delegator/questions.scss +25 -0
  13. data/app/commands/decidim/action_delegator/admin/create_delegation.rb +62 -0
  14. data/app/commands/decidim/action_delegator/consultations/multiple_vote_question_override.rb +31 -0
  15. data/app/commands/decidim/action_delegator/consultations/vote_question_override.rb +36 -0
  16. data/app/commands/decidim/action_delegator/vote_delegation.rb +28 -0
  17. data/app/controllers/concerns/decidim/action_delegator/admin/filterable.rb +23 -0
  18. data/app/controllers/decidim/action_delegator/admin/application_controller.rb +19 -0
  19. data/app/controllers/decidim/action_delegator/admin/consultations/exports_controller.rb +27 -0
  20. data/app/controllers/decidim/action_delegator/admin/consultations_controller.rb +33 -0
  21. data/app/controllers/decidim/action_delegator/admin/delegations_controller.rb +79 -0
  22. data/app/controllers/decidim/action_delegator/admin/exports/sum_of_weights_controller.rb +15 -0
  23. data/app/controllers/decidim/action_delegator/admin/results/sum_of_weights_controller.rb +37 -0
  24. data/app/controllers/decidim/action_delegator/admin/settings_controller.rb +71 -0
  25. data/app/controllers/decidim/action_delegator/application_controller.rb +14 -0
  26. data/app/controllers/decidim/action_delegator/consultations/question_multiple_votes_controller_override.rb +28 -0
  27. data/app/controllers/decidim/action_delegator/consultations/question_votes_controller_override.rb +55 -0
  28. data/app/controllers/decidim/action_delegator/user_delegations_controller.rb +22 -0
  29. data/app/controllers/decidim/action_delegator/verifications/sms/authorizations_controller_override.rb +38 -0
  30. data/app/forms/decidim/action_delegator/admin/delegation_form.rb +25 -0
  31. data/app/forms/decidim/action_delegator/consultations/vote_form_override.rb +15 -0
  32. data/app/helpers/decidim/action_delegator/admin/delegation_helper.rb +27 -0
  33. data/app/helpers/decidim/action_delegator/application_helper.rb +10 -0
  34. data/app/jobs/decidim/action_delegator/export_consultation_results_job.rb +51 -0
  35. data/app/jobs/decidim/action_delegator/send_sms_job.rb +60 -0
  36. data/app/jobs/decidim/action_delegator/twilio_send_sms_job.rb +43 -0
  37. data/app/models/decidim/action_delegator/application_record.rb +10 -0
  38. data/app/models/decidim/action_delegator/consultations/vote_override.rb +15 -0
  39. data/app/models/decidim/action_delegator/delegation.rb +26 -0
  40. data/app/models/decidim/action_delegator/setting.rb +22 -0
  41. data/app/models/decidim/action_delegator/unversioned_vote.rb +19 -0
  42. data/app/models/decidim/action_delegator/whodunnit_vote.rb +28 -0
  43. data/app/permissions/decidim/action_delegator/consultations_permissions_extension.rb +27 -0
  44. data/app/permissions/decidim/action_delegator/permissions.rb +74 -0
  45. data/app/presenters/decidim/action_delegator/admin/consultation_presenter.rb +15 -0
  46. data/app/presenters/decidim/action_delegator/admin/setting_presenter.rb +13 -0
  47. data/app/presenters/decidim/action_delegator/question_with_totals.rb +24 -0
  48. data/app/queries/decidim/action_delegator/consultation_delegations.rb +25 -0
  49. data/app/queries/decidim/action_delegator/decrypted_authorizations.rb +112 -0
  50. data/app/queries/decidim/action_delegator/delegated_votes_versions.rb +31 -0
  51. data/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb +24 -0
  52. data/app/queries/decidim/action_delegator/delegates_votes_by_question.rb +26 -0
  53. data/app/queries/decidim/action_delegator/delegation_votes.rb +30 -0
  54. data/app/queries/decidim/action_delegator/grantee_delegations.rb +24 -0
  55. data/app/queries/decidim/action_delegator/json_build_object_query.rb +45 -0
  56. data/app/queries/decidim/action_delegator/organization_delegations.rb +26 -0
  57. data/app/queries/decidim/action_delegator/organization_settings.rb +25 -0
  58. data/app/queries/decidim/action_delegator/published_responses.rb +25 -0
  59. data/app/queries/decidim/action_delegator/responses_by_membership.rb +75 -0
  60. data/app/queries/decidim/action_delegator/scrutiny.rb +87 -0
  61. data/app/queries/decidim/action_delegator/setting_delegations.rb +19 -0
  62. data/app/queries/decidim/action_delegator/sum_of_membership_weight.rb +48 -0
  63. data/app/queries/decidim/action_delegator/sum_of_weights.rb +25 -0
  64. data/app/queries/decidim/action_delegator/type_and_weight.rb +26 -0
  65. data/app/queries/decidim/action_delegator/voted_with_direct_verification.rb +53 -0
  66. data/app/queries/decidim/action_delegator/votes_count_aggregation.rb +34 -0
  67. data/app/serializers/decidim/action_delegator/consultation_results_serializer.rb +19 -0
  68. data/app/serializers/decidim/action_delegator/sum_of_weights_serializer.rb +17 -0
  69. data/app/services/decidim/action_delegator/sms_gateway.rb +51 -0
  70. data/app/views/decidim/action_delegator/_callout.html.erb +5 -0
  71. data/app/views/decidim/action_delegator/_delegations_modal.html.erb +93 -0
  72. data/app/views/decidim/action_delegator/_link_to_delegations.html.erb +5 -0
  73. data/app/views/decidim/action_delegator/_link_to_question.html.erb +5 -0
  74. data/app/views/decidim/action_delegator/admin/consultations/results.html.erb +62 -0
  75. data/app/views/decidim/action_delegator/admin/delegations/index.html.erb +36 -0
  76. data/app/views/decidim/action_delegator/admin/delegations/new.html.erb +30 -0
  77. data/app/views/decidim/action_delegator/admin/results/sum_of_weights/index.html.erb +63 -0
  78. data/app/views/decidim/action_delegator/admin/settings/index.html.erb +39 -0
  79. data/app/views/decidim/action_delegator/admin/settings/new.html.erb +30 -0
  80. data/app/views/decidim/action_delegator/user_delegations/index.html.erb +19 -0
  81. data/app/views/decidim/consultations/consultations/_question.html.erb +41 -0
  82. data/app/views/decidim/consultations/consultations/show.html.erb +14 -0
  83. data/app/views/decidim/consultations/question_multiple_votes/_form.html.erb +25 -0
  84. data/app/views/decidim/consultations/question_votes/update_vote_button.js.erb +32 -0
  85. data/app/views/decidim/consultations/questions/_vote_button.html.erb +107 -0
  86. data/app/views/decidim/consultations/questions/_vote_modal.html.erb +30 -0
  87. data/app/views/decidim/consultations/questions/_vote_modal_confirm.html.erb +38 -0
  88. data/app/views/decidim/verifications/sms/authorizations/new.html.erb +33 -0
  89. data/app/views/layouts/decidim/action_delegator/admin/_users_sidebar.html.erb +56 -0
  90. data/app/views/layouts/decidim/action_delegator/admin/delegations.html.erb +13 -0
  91. data/app/views/layouts/decidim/admin/consultation.html.erb +56 -0
  92. data/app/views/layouts/decidim/admin/question.html.erb +98 -0
  93. data/app/views/layouts/decidim/admin/users.html.erb +7 -0
  94. data/config/i18n-tasks.yml +10 -0
  95. data/config/locales/ca.yml +101 -0
  96. data/config/locales/cs.yml +101 -0
  97. data/config/locales/en.yml +109 -0
  98. data/config/locales/es.yml +101 -0
  99. data/db/migrate/20200729194540_create_decidim_action_delegator_delegations.rb +12 -0
  100. data/db/migrate/20200824113801_create_settings.rb +13 -0
  101. data/db/migrate/20200828113755_add_setting_id_to_delegations.rb +11 -0
  102. data/db/migrate/20200831141540_make_granter_id_and_grantee_id_non_nullable.rb +8 -0
  103. data/db/migrate/20201001172345_remove_expires_at_from_delegations.rb +7 -0
  104. data/db/migrate/20201005203554_add_setting_granter_unique_index_to_delegations.rb +10 -0
  105. data/db/migrate/20201006084522_remove_setting_id_index_from_delegations.rb +7 -0
  106. data/db/migrate/20201030164808_add_delegation_id_to_versions.rb +8 -0
  107. data/db/seeds.rb +7 -0
  108. data/lib/decidim/action_delegator/admin.rb +10 -0
  109. data/lib/decidim/action_delegator/admin_engine.rb +42 -0
  110. data/lib/decidim/action_delegator/engine.rb +53 -0
  111. data/lib/decidim/action_delegator/test/factories.rb +25 -0
  112. data/lib/decidim/action_delegator/version.rb +10 -0
  113. data/lib/decidim/action_delegator.rb +29 -0
  114. data/lib/json_key.rb +10 -0
  115. metadata +267 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class SettingDelegations < Rectify::Query
6
+ def initialize(setting)
7
+ @setting = setting
8
+ end
9
+
10
+ def query
11
+ Delegation.where(setting: setting)
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :setting
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class SumOfMembershipWeight < Rectify::Query
6
+ def initialize(relation)
7
+ @relation = relation
8
+ end
9
+
10
+ def query
11
+ relation
12
+ .select(
13
+ questions[:id].as("question_id"),
14
+ questions[:title].as("question_title"),
15
+ responses[:title],
16
+ votes_count
17
+ )
18
+ .group(
19
+ questions[:id],
20
+ questions[:title],
21
+ responses[:title]
22
+ )
23
+ .order(responses[:title])
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :relation
29
+
30
+ def questions
31
+ Decidim::Consultations::Question.arel_table
32
+ end
33
+
34
+ def responses
35
+ Decidim::Consultations::Response.arel_table
36
+ end
37
+
38
+ def authorizations
39
+ Decidim::Authorization.arel_table
40
+ end
41
+
42
+ def votes_count
43
+ field = Arel.sql("membership_weight")
44
+ VotesCountAggregation.new(field, "votes_count").to_sql
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class SumOfWeights < Rectify::Query
6
+ def initialize(consultation)
7
+ @consultation = consultation
8
+ end
9
+
10
+ def query
11
+ SumOfMembershipWeight.new(published_questions_responses).query
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :consultation
17
+
18
+ def published_questions_responses
19
+ VotedWithDirectVerification.new(
20
+ PublishedResponses.new(consultation).query
21
+ ).query
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class TypeAndWeight < Rectify::Query
6
+ def initialize(consultation)
7
+ @consultation = consultation
8
+ end
9
+
10
+ def query
11
+ relation = VotedWithDirectVerification.new(published_questions_responses).query
12
+ ResponsesByMembership.new(relation).query
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :consultation
18
+
19
+ # Returns the published questions' responses of the given consultation as an ActiveRecord
20
+ # Relation. Note this enables us to the chain it with other AR Relation objects.
21
+ def published_questions_responses
22
+ PublishedResponses.new(consultation).query
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class VotedWithDirectVerification < Rectify::Query
6
+ def initialize(relation)
7
+ @relation = relation
8
+ end
9
+
10
+ def query
11
+ relation
12
+ .joins(:votes)
13
+ .joins(join_on_votes_author(decrypted_authorizations))
14
+ .where(direct_verification.or(no_authorization))
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :relation
20
+
21
+ def join_on_votes_author(arel_table)
22
+ join_on = votes.create_on(arel_table[:decidim_user_id].eq(votes[:decidim_author_id]))
23
+ arel_table.create_join(arel_table, join_on, Arel::Nodes::OuterJoin)
24
+ end
25
+
26
+ def votes
27
+ Decidim::Consultations::Vote.arel_table
28
+ end
29
+
30
+ def decrypted_authorizations
31
+ @decrypted_authorizations ||= DecryptedAuthorizations.new(subquery).query.as("decrypted_authorizations")
32
+ end
33
+
34
+ def subquery
35
+ relation
36
+ .joins(:votes)
37
+ .joins(join_on_votes_author(authorizations))
38
+ end
39
+
40
+ def authorizations
41
+ Decidim::Authorization.arel_table
42
+ end
43
+
44
+ def direct_verification
45
+ decrypted_authorizations[:name].eq("direct_verifications")
46
+ end
47
+
48
+ def no_authorization
49
+ decrypted_authorizations[:id].eq(nil)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class VotesCountAggregation
6
+ def initialize(field, aliaz)
7
+ @field = field
8
+ @aliaz = aliaz
9
+ end
10
+
11
+ def to_sql
12
+ int_field = cast(field, :integer)
13
+ int_field = coalesce(int_field, 1)
14
+ Arel::Nodes::Sum.new([int_field], aliaz).to_sql
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :field, :aliaz
20
+
21
+ # Returns the equivalent of `CAST ((<exprs>) AS <type>)` in Arel
22
+ def cast(*exprs, type)
23
+ Arel::Nodes::NamedFunction.new(
24
+ "CAST",
25
+ [Arel::Nodes::As.new(Arel::Nodes::Grouping.new(exprs), Arel.sql(type.to_s.upcase))]
26
+ )
27
+ end
28
+
29
+ def coalesce(*exprs)
30
+ Arel::Nodes::NamedFunction.new("COALESCE", exprs)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class ConsultationResultsSerializer < Decidim::Exporters::Serializer
6
+ include Decidim::TranslationsHelper
7
+
8
+ def serialize
9
+ {
10
+ question: translated_attribute(resource.question.title),
11
+ response: translated_attribute(resource.title),
12
+ membership_type: resource.membership_type,
13
+ membership_weight: resource.membership_weight,
14
+ votes_count: resource.votes_count
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class SumOfWeightsSerializer < Decidim::Exporters::Serializer
6
+ include Decidim::TranslationsHelper
7
+
8
+ def serialize
9
+ {
10
+ question: translated_attribute(resource.question_title),
11
+ response: translated_attribute(resource.title),
12
+ votes_count: resource.votes_count
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ActionDelegator
5
+ class SmsGateway
6
+ attr_reader :mobile_phone_number, :code, :response
7
+
8
+ SMS_GATEWAY_PROVIDER_JOBS = {
9
+ som_connexio: SendSmsJob,
10
+ twilio: TwilioSendSmsJob
11
+ }.freeze
12
+
13
+ def initialize(mobile_phone_number, code)
14
+ @mobile_phone_number = mobile_phone_number
15
+ @code = code
16
+ end
17
+
18
+ def deliver_code
19
+ return false unless sms_gateway_provider_valid?
20
+
21
+ sms_gateway_job.perform_later(sender, mobile_phone_number, message)
22
+
23
+ true
24
+ end
25
+
26
+ private
27
+
28
+ def sms_gateway_job
29
+ SMS_GATEWAY_PROVIDER_JOBS[sms_gateway_provider.to_sym]
30
+ end
31
+
32
+ def sender
33
+ ENV["SMS_SENDER"]
34
+ end
35
+
36
+ def sms_gateway_provider
37
+ ENV["SMS_GATEWAY_PROVIDER"]
38
+ end
39
+
40
+ def sms_gateway_provider_valid?
41
+ return false unless sms_gateway_provider
42
+
43
+ SMS_GATEWAY_PROVIDER_JOBS.keys.include? sms_gateway_provider.to_sym
44
+ end
45
+
46
+ def message
47
+ I18n.t("decidim.action_delegator.sms_message", code: code)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ <% if signed_in? && Decidim::ActionDelegator::Delegation.granted_to?(current_user, consultation) %>
2
+ <div class="delegation-callout callout warning is-hidden">
3
+ <p><%= t "action_delegator.delegations_modal.callout", scope: "decidim" %> <span class="delegation-callout-message"></span></p>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,93 @@
1
+ <div class="reveal" data-reveal id="delegations-modal">
2
+ <div class="reveal__header">
3
+ <h3 class="reveal__title">
4
+ <%= t "action_delegator.delegations_modal.title", scope: "decidim" %>
5
+ </h3>
6
+ <button class="close-button" data-close aria-label="Close modal" type="button">
7
+ <span aria-hidden="true">&times;</span>
8
+ </button>
9
+ </div>
10
+
11
+ <p><%= t "action_delegator.delegations_modal.contextual_help", scope: "decidim" %></p>
12
+ <div class="card card--secondary">
13
+ <div class="card__content">
14
+
15
+ <% signed_in? && Decidim::ActionDelegator::GranteeDelegations.for(question.consultation, current_user).each do |delegation| %>
16
+ <div class="row">
17
+ <div class="columns medium-5 medium-offset-1">
18
+ <%= delegation.granter.name %>
19
+ </div>
20
+ <div class="columns medium-5 medium-offset-1">
21
+
22
+ <%# Copied from decidim-consultation's _vote_button.html.erb %>
23
+ <% if question.consultation.upcoming? %>
24
+ <div class="button expanded disabled">
25
+ <div class="vote-button-caption"><%= t("questions.vote_button.vote", scope: "decidim") %></div>
26
+ <div>
27
+ <%= t "questions.vote_button.starting_from",
28
+ scope: "decidim",
29
+ date: l(question.start_voting_date) %>
30
+ </div>
31
+ </div>
32
+ <% elsif question.consultation.finished? && signed_in? && question.voted_by?(delegation.granter) %>
33
+ <%= button_to decidim_consultations.question_question_votes_path(question),
34
+ method: :delete,
35
+ remote: true,
36
+ data: { disable: true },
37
+ class: "button expanded success disabled delegation_unvote_button" do %>
38
+ <div class="vote-button-caption">
39
+ <%= t("questions.vote_button.already_voted", scope: "decidim") %>
40
+ </div>
41
+ <% end %>
42
+ <% elsif signed_in? && question.consultation.active? %>
43
+ <% if allowed_to? :unvote_delegation, :question, { question: question, delegation: delegation }, [Decidim::ActionDelegator::Permissions, Decidim::Admin::Permissions, Decidim::Permissions] %>
44
+ <%= button_to decidim_consultations.question_question_votes_path(question),
45
+ method: :delete,
46
+ remote: true,
47
+ data: { disable: true },
48
+ class: "button expanded success delegation_unvote_button" do %>
49
+ <%= hidden_field_tag "decidim_consultations_delegation_id", delegation.id, id: "decidim_consultations_delegation_id_delete_#{delegation.id}" %>
50
+ <div class="vote-button-caption"
51
+ data-original="<%= t("questions.vote_button.already_voted", scope: "decidim") %>"
52
+ data-replace="<%= t("questions.vote_button.already_voted_hover", scope: "decidim") %>">
53
+ <%= t("questions.vote_button.already_voted", scope: "decidim") %>
54
+ </div>
55
+ <% end %>
56
+ <% elsif allowed_to? :vote_delegation, :question, { question: question, delegation: delegation }, [Decidim::ActionDelegator::Permissions, Decidim::Admin::Permissions, Decidim::Permissions] %>
57
+ <% if question.multiple? %>
58
+ <%= link_to decidim_consultations.question_question_multiple_votes_path(question, delegation: delegation.id),
59
+ class: "button expanded",
60
+ id: "multivote_button" do %>
61
+ <div class="vote-button-caption"><%= t "questions.vote_button.vote", scope: "decidim" %></div>
62
+ <% end %>
63
+ <% else %>
64
+
65
+ <%# This link is slightly modified from _vote_button to add stuff needed by delegations %>
66
+ <%= link_to "#", class: "button expanded delegation-vote-button", data: { "delegation-id" => delegation.id, "delegation-granter-name" => delegation.granter.name } do %>
67
+ <div class="vote-button-caption"><%= t "questions.vote_button.vote", scope: "decidim" %></div>
68
+ <% end %>
69
+
70
+ <% end %>
71
+ <% else %>
72
+ <%= authorized_vote_modal_button(question, remote: true, class: "button expanded light button--sc") do %>
73
+ <%= t("questions.vote_button.verification_required", scope: "decidim") %>
74
+ <% end %>
75
+ <% end %>
76
+ <% elsif question.consultation.active? %>
77
+ <%= logged_button_to decidim_consultations.question_question_votes_path(question),
78
+ class: "button expanded",
79
+ data: { disable: true },
80
+ id: "vote_button" do %>
81
+ <div class="vote-button-caption">
82
+ <%= t("questions.vote_button.vote", scope: "decidim") %>
83
+ </div>
84
+ <% end %>
85
+ <% end %>
86
+
87
+ </div>
88
+ </div>
89
+ <% end %>
90
+
91
+ </div>
92
+ </div>
93
+ </div>
@@ -0,0 +1,5 @@
1
+ <% if Decidim::ActionDelegator::Delegation.granted_to?(current_user, consultation) %>
2
+ <div class="delegations-notice flex--cc">
3
+ <%= link_to t("action_delegator.delegations.link", scope: "decidim"), "#", id: "delegations-button" %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% if signed_in? && Decidim::ActionDelegator::Delegation.granted_to?(current_user, question.consultation) %>
2
+ <div class="delegations-notice flex--cc">
3
+ <%= link_to t("action_delegator.delegations.link", scope: "decidim"), decidim_consultations.question_path(question) %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,62 @@
1
+ <div class="card" id="consultations">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t ".title" %>
5
+ <span class="label button--title">
6
+ <%= t "decidim.admin.consultations.results.total_votes", count: current_consultation.total_votes %>
7
+ /
8
+ <%= t "decidim.admin.consultations.results.total_delegates", count: @total_delegates %>
9
+ /
10
+ <%= t "decidim.admin.consultations.results.participants", count: current_consultation.total_participants %>
11
+ </span>
12
+ <span id="export-consultation-results" class="button--title">
13
+ <% if allowed_to?(:export_consultation_results, :consultation, consultation: current_consultation) %>
14
+ <%= link_to t("decidim.admin.consultations.results.export"), decidim_admin_action_delegator.consultation_exports_path(current_consultation), method: :post, class: "button tiny button--title" %>
15
+ <% else %>
16
+ <span class="button tiny button--title disabled"><%= t("decidim.admin.consultations.results.export") %></span>
17
+ <% end %>
18
+ </span>
19
+ </h2>
20
+ </div>
21
+ <div class="card-section">
22
+ <table class="table-list">
23
+ <% @questions.each do |question| %>
24
+ <% unless question.external_voting %>
25
+ <thead>
26
+ <tr>
27
+ <th><%= strip_tags translated_attribute question.title %></th>
28
+ <th><%= I18n.t("decidim.admin.consultations.results.membership_type") %></th>
29
+ <th><%= I18n.t("decidim.admin.consultations.results.membership_weight") %></th>
30
+ <th class="table-list__actions">
31
+ <%= t "decidim.admin.consultations.results.total_votes", count: question.total_votes %>
32
+ /
33
+ <%= t "decidim.admin.consultations.results.total_delegates", count: question.total_delegates %>
34
+ /
35
+ <%= t "decidim.admin.consultations.results.participants", count: question.total_participants %>
36
+ </th>
37
+ </tr>
38
+ </thead>
39
+ <tbody>
40
+ <% if question.publishable_results? %>
41
+ <% @responses.fetch(question.id, []).each do |row| %>
42
+ <tr>
43
+ <td class="response-title"><%= strip_tags translated_attribute row.title %></td>
44
+ <td class="membership-type"><%= row.membership_type %></td>
45
+ <td class="membership-weight"><%= row.membership_weight %></td>
46
+ <td class="votes-count"><%= row.votes_count %></td>
47
+ </tr>
48
+ <% end %>
49
+ <% else %>
50
+ <tr>
51
+ <td><em><%= t "decidim.admin.consultations.results.not_visible" %></em></td>
52
+ <td>&nbsp;</td>
53
+ <td>&nbsp;</td>
54
+ <td>&nbsp;</td>
55
+ </tr>
56
+ <% end %>
57
+ </tbody>
58
+ <% end %>
59
+ <% end %>
60
+ </table>
61
+ </div>
62
+ </div>
@@ -0,0 +1,36 @@
1
+ <div class="card with-overflow" id='user-groups'>
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t ".title" %>
5
+ <%= link_to t(".actions.new_delegation"), decidim_admin_action_delegator.new_setting_delegation_path(current_setting), class: "button tiny button--title" %>
6
+ </h2>
7
+ </div>
8
+ <div class="card-section">
9
+ <div class="table-scroll">
10
+ <table class="table-list">
11
+ <thead>
12
+ <tr>
13
+ <th><%= t(".granter") %></th>
14
+ <th><%= t(".grantee") %></th>
15
+ <th><%= t(".created_at") %></th>
16
+ <th>&nbsp;</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <% @delegations.each do |delegation| %>
21
+ <tr data-delegation-id="<%= delegation.id %>">
22
+ <td><%= delegation.granter.name %></td>
23
+ <td><%= delegation.grantee.name %></td>
24
+ <td><%= l delegation.created_at, format: :short %></td>
25
+
26
+ <td class="table-list__actions">
27
+ <%= icon_link_to "circle-x", decidim_admin_action_delegator.setting_delegation_path(delegation.setting, delegation), t("actions.destroy", scope: "decidim.admin"), class: "action-icon--remove", method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") } %>
28
+ </td>
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ </table>
33
+ </div>
34
+ <%= decidim_paginate @delegations %>
35
+ </div>
36
+ </div>
@@ -0,0 +1,30 @@
1
+ <h2 class="card-title process-title-summary">
2
+ <%= t ".title" %>
3
+ </h2>
4
+
5
+ <%= decidim_form_for @form, url: { action: "create" }, html: { class: "form new_delegation" } do |f| %>
6
+ <div class="card">
7
+ <div class="card-divider">
8
+ <h2 class="card-title"><%= t ".form.title" %></h2>
9
+ </div>
10
+
11
+ <div class="card-section">
12
+ <% prompt_options = { url: decidim_admin.users_organization_url, placeholder: t(".select_member") } %>
13
+
14
+ <div class="row column">
15
+ <%= f.autocomplete_select(:granter_id, @form.granter, { multiple: false, label: t(".granter") }, prompt_options) do |user|
16
+ { value: user.id, label: "#{user.name} (@#{user.nickname})" }
17
+ end %>
18
+ </div>
19
+ <div class="row column">
20
+ <%= f.autocomplete_select(:grantee_id, @form.grantee, { multiple: false, label: t(".grantee") }, prompt_options) do |user|
21
+ { value: user.id, label: "#{user.name} (@#{user.nickname})" }
22
+ end %>
23
+ </div>
24
+ </div>
25
+ </div>
26
+
27
+ <div class="button--double form-general-submit">
28
+ <%= f.submit t(".save") %>
29
+ </div>
30
+ <% end %>
@@ -0,0 +1,63 @@
1
+ <div class="card" id="consultations">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t ".title" %>
5
+ <span class="label button--title">
6
+ <%= t "decidim.admin.consultations.results.total_votes", count: current_consultation.total_votes %>
7
+ /
8
+ <%= t "decidim.admin.consultations.results.total_delegates", count: @total_delegates %>
9
+ /
10
+ <%= t "decidim.admin.consultations.results.participants", count: current_consultation.total_participants %>
11
+ </span>
12
+ <span id="export-consultation-results" class="button--title">
13
+ <% if allowed_to?(:export_consultation_results, :consultation, consultation: current_consultation) %>
14
+ <%= link_to(
15
+ t("decidim.admin.consultations.results.export"),
16
+ decidim_admin_action_delegator.consultation_exports_sum_of_weights_path(current_consultation),
17
+ method: :post,
18
+ class: "button tiny button--title"
19
+ ) %>
20
+ <% else %>
21
+ <span class="button tiny button--title disabled"><%= t("decidim.admin.consultations.results.export") %></span>
22
+ <% end %>
23
+ </span>
24
+ </h2>
25
+ </div>
26
+ <div class="card-section">
27
+ <table id="results" class="table-list">
28
+ <% @questions.each do |question| %>
29
+ <% unless question.external_voting %>
30
+ <thead>
31
+ <tr>
32
+ <th><%= strip_tags translated_attribute question.title %></th>
33
+ <th class="table-list__actions">
34
+ <%= t "decidim.admin.consultations.results.total_votes", count: question.total_votes %>
35
+ /
36
+ <%= t "decidim.admin.consultations.results.total_delegates", count: question.total_delegates %>
37
+ /
38
+ <%= t "decidim.admin.consultations.results.participants", count: question.total_participants %>
39
+ </th>
40
+ </tr>
41
+ </thead>
42
+ <tbody>
43
+ <% if question.publishable_results? %>
44
+ <% @responses.fetch(question.id, []).each do |row| %>
45
+ <tr>
46
+ <td class="response-title"><%= strip_tags translated_attribute row.title %></td>
47
+ <td class="votes-count"><%= row.votes_count %></td>
48
+ </tr>
49
+ <% end %>
50
+ <% else %>
51
+ <tr>
52
+ <td><em><%= t "decidim.admin.consultations.results.not_visible" %></em></td>
53
+ <td>&nbsp;</td>
54
+ <td>&nbsp;</td>
55
+ <td>&nbsp;</td>
56
+ </tr>
57
+ <% end %>
58
+ </tbody>
59
+ <% end %>
60
+ <% end %>
61
+ </table>
62
+ </div>
63
+ </div>
@@ -0,0 +1,39 @@
1
+ <div class="card with-overflow" id='user-groups'>
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t ".title" %>
5
+ <%= link_to t(".actions.new_setting"), decidim_admin_action_delegator.new_setting_path, class: "button tiny button--title" %>
6
+ </h2>
7
+ </div>
8
+ <div class="card-section">
9
+ <div class="table-scroll">
10
+ <table class="table-list">
11
+ <thead>
12
+ <tr>
13
+ <th><%= t(".consultation") %></th>
14
+ <th><%= t(".max_grants") %></th>
15
+ <th><%= t(".delegations") %></th>
16
+ <th><%= t(".created_at") %></th>
17
+ <th>&nbsp;</th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% @settings.each do |setting| %>
22
+ <tr data-setting-id="<%= setting.id %>">
23
+ <td><%= link_to translated_attribute(setting.consultation.title), decidim_admin_action_delegator.setting_delegations_path(setting) %></td>
24
+ <td><%= setting.max_grants %></td>
25
+ <td><%= setting.delegations.count %></td>
26
+ <td><%= l setting.created_at, format: :short %></td>
27
+
28
+ <td class="table-list__actions">
29
+ <%= icon_link_to "people", decidim_admin_action_delegator.setting_delegations_path(setting), t("actions.manage", scope: "decidim.admin"), class: "action-icon--edit" %>
30
+ <%= icon_link_to "circle-x", decidim_admin_action_delegator.setting_path(setting), t("actions.destroy", scope: "decidim.admin"), class: "action-icon--remove", method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") } %>
31
+ <%= icon_link_to "eye", decidim_consultations.consultation_path(setting.consultation), t("actions.preview", scope: "decidim.admin"), class: "action-icon--edit" %>
32
+ </td>
33
+ </tr>
34
+ <% end %>
35
+ </tbody>
36
+ </table>
37
+ </div>
38
+ </div>
39
+ </div>