decidim-meetings 0.10.1 → 0.11.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/config/admin/decidim_meetings_manifest.js +1 -0
  4. data/app/assets/javascripts/decidim/meetings/admin/meetings_form.js.es6 +78 -0
  5. data/app/assets/javascripts/decidim/meetings/admin/registrations_form.js.es6 +9 -7
  6. data/app/cells/decidim/meetings/meeting_cell.rb +71 -0
  7. data/app/cells/decidim/meetings/meeting_list_item/show.erb +14 -0
  8. data/app/cells/decidim/meetings/meeting_list_item_cell.rb +26 -0
  9. data/app/cells/decidim/meetings/meeting_m/header.erb +5 -0
  10. data/app/cells/decidim/meetings/meeting_m/show.erb +21 -0
  11. data/app/cells/decidim/meetings/meeting_m_cell.rb +17 -0
  12. data/app/commands/decidim/meetings/admin/copy_meeting.rb +82 -0
  13. data/app/commands/decidim/meetings/admin/create_meeting.rb +3 -1
  14. data/app/commands/decidim/meetings/admin/export_meeting_registrations.rb +44 -0
  15. data/app/commands/decidim/meetings/admin/update_meeting.rb +1 -0
  16. data/app/commands/decidim/meetings/admin/update_registrations.rb +1 -0
  17. data/app/commands/decidim/meetings/join_meeting.rb +1 -1
  18. data/app/commands/decidim/meetings/leave_meeting.rb +1 -1
  19. data/app/controllers/decidim/meetings/admin/application_controller.rb +3 -3
  20. data/app/controllers/decidim/meetings/admin/attachment_collections_controller.rb +2 -2
  21. data/app/controllers/decidim/meetings/admin/attachments_controller.rb +1 -1
  22. data/app/controllers/decidim/meetings/admin/invites_controller.rb +1 -1
  23. data/app/controllers/decidim/meetings/admin/meeting_closes_controller.rb +1 -1
  24. data/app/controllers/decidim/meetings/admin/meeting_copies_controller.rb +43 -0
  25. data/app/controllers/decidim/meetings/admin/meetings_controller.rb +10 -2
  26. data/app/controllers/decidim/meetings/admin/registrations_controller.rb +6 -5
  27. data/app/controllers/decidim/meetings/application_controller.rb +2 -2
  28. data/app/controllers/decidim/meetings/meeting_widgets_controller.rb +1 -1
  29. data/app/controllers/decidim/meetings/meetings_controller.rb +2 -2
  30. data/app/controllers/decidim/meetings/registrations_controller.rb +1 -1
  31. data/app/forms/decidim/meetings/admin/meeting_copy_form.rb +54 -0
  32. data/app/forms/decidim/meetings/admin/meeting_form.rb +17 -6
  33. data/app/forms/decidim/meetings/admin/meeting_registrations_form.rb +10 -1
  34. data/app/forms/decidim/meetings/admin/meeting_service_form.rb +23 -0
  35. data/app/helpers/decidim/meetings/admin/application_helper.rb +4 -0
  36. data/app/mailers/decidim/meetings/admin/invite_join_meeting_mailer.rb +1 -1
  37. data/app/models/decidim/meetings/abilities/current_user_ability.rb +6 -6
  38. data/app/models/decidim/meetings/meeting.rb +14 -8
  39. data/app/presenters/decidim/meetings/admin_log/meeting_presenter.rb +1 -1
  40. data/app/services/decidim/meetings/meeting_search.rb +2 -2
  41. data/app/types/decidim/meetings/meeting_type.rb +38 -0
  42. data/app/types/decidim/meetings/meetings_type.rb +32 -0
  43. data/app/views/decidim/meetings/admin/invite_join_meeting_mailer/invite.html.erb +1 -1
  44. data/app/views/decidim/meetings/admin/invites/new.html.erb +3 -3
  45. data/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +2 -3
  46. data/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +2 -2
  47. data/app/views/decidim/meetings/admin/meeting_copies/_form.html.erb +42 -0
  48. data/app/views/decidim/meetings/admin/meeting_copies/new.html.erb +7 -0
  49. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +15 -11
  50. data/app/views/decidim/meetings/admin/meetings/_service.html.erb +48 -0
  51. data/app/views/decidim/meetings/admin/meetings/_services.html.erb +25 -0
  52. data/app/views/decidim/meetings/admin/meetings/edit.html.erb +2 -3
  53. data/app/views/decidim/meetings/admin/meetings/index.html.erb +13 -9
  54. data/app/views/decidim/meetings/admin/meetings/new.html.erb +2 -2
  55. data/app/views/decidim/meetings/admin/registrations/_form.html.erb +7 -2
  56. data/app/views/decidim/meetings/admin/registrations/edit.html.erb +2 -3
  57. data/app/views/decidim/meetings/meetings/_filters.html.erb +2 -2
  58. data/app/views/decidim/meetings/meetings/_filters_small_view.html.erb +1 -1
  59. data/app/views/decidim/meetings/meetings/_meetings.html.erb +1 -18
  60. data/app/views/decidim/meetings/meetings/_registration_confirm.html.erb +2 -2
  61. data/app/views/decidim/meetings/meetings/index.html.erb +3 -3
  62. data/app/views/decidim/meetings/meetings/show.html.erb +21 -4
  63. data/app/views/decidim/participatory_processes/participatory_process_groups/_highlighted_meetings.html.erb +2 -2
  64. data/app/views/decidim/participatory_spaces/_highlighted_meetings.html.erb +4 -4
  65. data/app/views/decidim/participatory_spaces/_meeting.html.erb +1 -14
  66. data/app/views/devise/mailer/join_meeting.html.erb +1 -1
  67. data/app/views/devise/mailer/join_meeting.text.erb +1 -1
  68. data/config/locales/ca.yml +35 -12
  69. data/config/locales/en.yml +35 -12
  70. data/config/locales/es.yml +35 -12
  71. data/config/locales/eu.yml +35 -12
  72. data/config/locales/fi.yml +35 -12
  73. data/config/locales/fr.yml +35 -12
  74. data/config/locales/gl.yml +35 -12
  75. data/config/locales/it.yml +35 -12
  76. data/config/locales/nl.yml +73 -50
  77. data/config/locales/pl.yml +35 -12
  78. data/config/locales/pt-BR.yml +35 -12
  79. data/config/locales/pt.yml +35 -12
  80. data/config/locales/ru.yml +0 -3
  81. data/config/locales/sv.yml +35 -12
  82. data/config/locales/uk.yml +0 -3
  83. data/db/migrate/20180305133634_rename_features_to_components_at_meetings.rb +11 -0
  84. data/db/migrate/20180326082611_add_fields_for_registrations.rb +7 -0
  85. data/db/migrate/20180407110934_add_services_to_meetings.rb +7 -0
  86. data/lib/decidim/meetings.rb +2 -1
  87. data/lib/decidim/meetings/admin_engine.rb +1 -0
  88. data/lib/decidim/meetings/{feature.rb → component.rb} +27 -19
  89. data/lib/decidim/meetings/engine.rb +27 -4
  90. data/lib/decidim/meetings/test/factories.rb +10 -3
  91. data/lib/decidim/meetings/version.rb +1 -1
  92. data/lib/decidim/meetings/view_model.rb +12 -0
  93. metadata +65 -15
@@ -26,16 +26,16 @@ module Decidim
26
26
  private
27
27
 
28
28
  def authorized?(action)
29
- return unless feature
29
+ return unless component
30
30
 
31
- ActionAuthorizer.new(user, feature, action).authorize.ok?
31
+ ActionAuthorizer.new(user, component, action).authorize.ok?
32
32
  end
33
33
 
34
- def feature
35
- feature = context.fetch(:current_feature, nil)
36
- return nil unless feature && feature.manifest.name == :meetings
34
+ def component
35
+ component = context.fetch(:current_component, nil)
36
+ return nil unless component && component.manifest.name == :meetings
37
37
 
38
- feature
38
+ component
39
39
  end
40
40
  end
41
41
  end
@@ -8,9 +8,9 @@ module Decidim
8
8
  include Decidim::Resourceable
9
9
  include Decidim::HasAttachments
10
10
  include Decidim::HasAttachmentCollections
11
- include Decidim::HasFeature
11
+ include Decidim::HasComponent
12
12
  include Decidim::HasReference
13
- include Decidim::ScopableFeature
13
+ include Decidim::ScopableComponent
14
14
  include Decidim::HasCategory
15
15
  include Decidim::Followable
16
16
  include Decidim::Comments::Commentable
@@ -19,11 +19,11 @@ module Decidim
19
19
 
20
20
  has_many :registrations, class_name: "Decidim::Meetings::Registration", foreign_key: "decidim_meeting_id", dependent: :destroy
21
21
 
22
- feature_manifest_name "meetings"
22
+ component_manifest_name "meetings"
23
23
 
24
24
  validates :title, presence: true
25
25
 
26
- geocoded_by :address, http_headers: ->(proposal) { { "Referer" => proposal.feature.organization.host } }
26
+ geocoded_by :address, http_headers: ->(proposal) { { "Referer" => proposal.component.organization.host } }
27
27
 
28
28
  scope :past, -> { where(arel_table[:end_time].lteq(Time.current)) }
29
29
  scope :upcoming, -> { where(arel_table[:start_time].gt(Time.current)) }
@@ -38,11 +38,11 @@ module Decidim
38
38
 
39
39
  def has_available_slots?
40
40
  return true if available_slots.zero?
41
- available_slots > registrations.count
41
+ (available_slots - reserved_slots) > registrations.count
42
42
  end
43
43
 
44
44
  def remaining_slots
45
- available_slots - registrations.count
45
+ available_slots - reserved_slots - registrations.count
46
46
  end
47
47
 
48
48
  def has_registration_for?(user)
@@ -51,12 +51,12 @@ module Decidim
51
51
 
52
52
  # Public: Overrides the `commentable?` Commentable concern method.
53
53
  def commentable?
54
- feature.settings.comments_enabled?
54
+ component.settings.comments_enabled?
55
55
  end
56
56
 
57
57
  # Public: Overrides the `accepts_new_comments?` Commentable concern method.
58
58
  def accepts_new_comments?
59
- commentable? && !feature.current_settings.comments_blocked
59
+ commentable? && !component.current_settings.comments_blocked
60
60
  end
61
61
 
62
62
  # Public: Overrides the `comments_have_alignment?` Commentable concern method.
@@ -73,6 +73,12 @@ module Decidim
73
73
  def users_to_notify_on_comment_created
74
74
  followers
75
75
  end
76
+
77
+ def can_participate?(user)
78
+ return true unless participatory_space.try(:private_space?)
79
+ return true if participatory_space.try(:private_space?) && participatory_space.users.include?(user)
80
+ return false if participatory_space.try(:private_space?) && participatory_space.try(:is_transparent?)
81
+ end
76
82
  end
77
83
  end
78
84
  end
@@ -33,7 +33,7 @@ module Decidim
33
33
 
34
34
  def action_string
35
35
  case action
36
- when "close", "create", "delete", "update"
36
+ when "close", "create", "delete", "export_registrations", "update"
37
37
  "decidim.meetings.admin_log.meeting.#{action}"
38
38
  else
39
39
  super
@@ -3,11 +3,11 @@
3
3
  module Decidim
4
4
  module Meetings
5
5
  # This class handles search and filtering of meetings. Needs a
6
- # `current_feature` param with a `Decidim::Feature` in order to
6
+ # `current_component` param with a `Decidim::Component` in order to
7
7
  # find the meetings.
8
8
  class MeetingSearch < ResourceSearch
9
9
  # Public: Initializes the service.
10
- # feature - A Decidim::Feature to get the meetings from.
10
+ # component - A Decidim::Component to get the meetings from.
11
11
  # page - The page number to paginate the results.
12
12
  # per_page - The number of proposals to return per page.
13
13
  def initialize(options = {})
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ MeetingType = GraphQL::ObjectType.define do
6
+ name "Meeting"
7
+ description "A meeting"
8
+
9
+ interfaces [
10
+ Decidim::Comments::CommentableInterface,
11
+ Decidim::Core::CategorizableInterface,
12
+ Decidim::Core::ScopableInterface,
13
+ Decidim::Core::AttachableInterface
14
+ ]
15
+
16
+ field :id, !types.ID
17
+ field :reference, !types.String
18
+ field :title, !Decidim::Core::TranslatedFieldType, "The title of this meeting."
19
+ field :startTime, !Decidim::Core::DateTimeType, "The time this meeting starts", property: :start_time
20
+ field :endTime, !Decidim::Core::DateTimeType, "The time this meeting ends", property: :end_time
21
+
22
+ field :closed, !types.Boolean, "Whether this meeting is closed or not.", property: :closed?
23
+ field :closingReport, Decidim::Core::TranslatedFieldType, "The closing report of this meeting.", property: :closing_report
24
+
25
+ field :registrationsEnabled, !types.Boolean, "Whether the registrations are enabled or not", property: :registrations_enabled
26
+ field :remainingSlots, types.Int, "Amount of slots available for this meeting", property: :remaining_slots
27
+ field :attendeeCount, types.Int, "Amount of attendees to this meeting", property: :attendees_count
28
+ field :contributionCount, types.Int, "Amount of contributions to this meeting", property: :contributions_count
29
+
30
+ field :address, types.String, "The physical address of this meeting"
31
+ field :coordinates, Decidim::Core::CoordinatesType, "Physical coordinates for this meeting" do
32
+ resolve ->(meeting, _args, _ctx) {
33
+ [meeting.latitude, meeting.longitude]
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ MeetingsType = GraphQL::ObjectType.define do
6
+ interfaces [-> { Decidim::Core::ComponentInterface }]
7
+
8
+ name "Meetings"
9
+ description "A meetings component of a participatory space."
10
+
11
+ connection :meetings, MeetingType.connection_type do
12
+ resolve ->(component, _args, _ctx) {
13
+ MeetingsTypeHelper.base_scope(component).includes(:component)
14
+ }
15
+ end
16
+
17
+ field(:meeting, MeetingType) do
18
+ argument :id, !types.ID
19
+
20
+ resolve ->(component, args, _ctx) {
21
+ MeetingsTypeHelper.base_scope(component).find_by(id: args[:id])
22
+ }
23
+ end
24
+ end
25
+
26
+ module MeetingsTypeHelper
27
+ def self.base_scope(component)
28
+ Meeting.where(component: component)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -4,4 +4,4 @@
4
4
  <%= t ".invited_you_to_join_a_meeting", invited_by: @invited_by.name, application: @user.organization.name %>
5
5
  </p>
6
6
 
7
- <p><%= link_to t(".join", meeting_title: translated_attribute(@meeting.title)),routes.meeting_registration_url(meeting_id: @meeting, participatory_space_id: @meeting.feature.participatory_space) %>
7
+ <p><%= link_to t(".join", meeting_title: translated_attribute(@meeting.title)),routes.meeting_registration_url(meeting_id: @meeting, participatory_space_id: @meeting.component.participatory_space) %>
@@ -1,17 +1,17 @@
1
1
  <h2 class="process-title-summary">
2
- <%= t('.new_invite') %>
2
+ <%= t(".new_invite") %>
3
3
  </h2>
4
4
 
5
5
  <div class="section">
6
6
  <div class="callout warning">
7
- <p><%= t('.explanation') %></p>
7
+ <p><%= t(".explanation") %></p>
8
8
  </div>
9
9
  </div>
10
10
 
11
11
  <%= decidim_form_for(@form, url: meeting_registrations_invites_path, method: :post, html: { class: "form new_meeting_registration_invite" }) do |f| %>
12
12
  <div class="card">
13
13
  <div class="card-section">
14
- <%= render partial: 'form', object: f %>
14
+ <%= render partial: "form", object: f %>
15
15
  </div>
16
16
  </div>
17
17
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  <div class="card-section">
7
7
  <div class="row column">
8
- <%= form.translated :text_area, :closing_report, autofocus: true, rows: 15 %>
8
+ <%= form.translated :editor, :closing_report, autofocus: true, rows: 15 %>
9
9
  </div>
10
10
 
11
11
  <div class="row column">
@@ -26,8 +26,7 @@
26
26
  <%= form.select :proposal_ids,
27
27
  @form.proposals.order(title: :asc).pluck(:title, :id),
28
28
  { include_blank: true },
29
- { multiple: true, class: "chosen-select" }
30
- %>
29
+ { multiple: true, class: "chosen-select" } %>
31
30
  <% end %>
32
31
  </div>
33
32
  </div>
@@ -1,5 +1,5 @@
1
- <%= decidim_form_for(@form, url: meeting_meeting_close_path(meeting, @form), html: { class: "form edit_close_meeting" }) do |f| %>
2
- <%= render partial: 'form', object: f, locals: { title: t('.title') } %>
1
+ <%= decidim_form_for(@form, url: meeting_meeting_close_path(meeting, @form), html: { class: "form edit_close_meeting" }) do |f| %>
2
+ <%= render partial: "form", object: f, locals: { title: t(".title") } %>
3
3
 
4
4
  <div class="button--double form-general-submit">
5
5
  <%= f.submit t(".close") %>
@@ -0,0 +1,42 @@
1
+ <div class="card" id="meetings">
2
+ <div class="card-divider">
3
+ <h2 class="card-title"><%= title %></h2>
4
+ </div>
5
+
6
+ <div class="card-section">
7
+ <div class="row column">
8
+ <%= form.translated :text_field, :title, autofocus: true %>
9
+ </div>
10
+
11
+ <div class="row column">
12
+ <%= form.translated :editor, :description %>
13
+ </div>
14
+
15
+ <div class="row column">
16
+ <%= form.text_field :address %>
17
+ </div>
18
+
19
+ <div class="row column">
20
+ <%= form.translated :text_area, :location %>
21
+ </div>
22
+
23
+ <div class="row column">
24
+ <%= form.translated :text_area, :location_hints %>
25
+ </div>
26
+
27
+ <div class="row">
28
+ <div class="columns xlarge-6">
29
+ <%= form.datetime_field :start_time %>
30
+ </div>
31
+
32
+ <div class="columns xlarge-6">
33
+ <%= form.datetime_field :end_time %>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ </div>
39
+
40
+ <%= render "decidim/meetings/admin/meetings/services", form: form %>
41
+
42
+ <%= javascript_include_tag "decidim/meetings/admin/meetings_form" %>
@@ -0,0 +1,7 @@
1
+ <%= decidim_form_for(@form, url: meeting_copies_path(meeting), method: :post, html: { class: "form copy_meetings" }) do |f| %>
2
+ <%= render partial: "form", object: f, locals: { title: t("meeting_copies.new.title", scope: "decidim.admin"), select: t("meeting_copies.new.select", scope: "decidim.admin")} %>
3
+
4
+ <div class="button--double form-general-submit">
5
+ <%= f.submit t("meeting_copies.new.copy", scope: "decidim.admin") %>
6
+ </div>
7
+ <% end %>
@@ -4,45 +4,49 @@
4
4
  </div>
5
5
 
6
6
  <div class="card-section">
7
- <div class="row column" >
7
+ <div class="row column">
8
8
  <%= form.translated :text_field, :title, autofocus: true %>
9
9
  </div>
10
10
 
11
- <div class="row column" >
11
+ <div class="row column">
12
12
  <%= form.translated :editor, :description %>
13
13
  </div>
14
14
 
15
- <div class="row column" >
15
+ <div class="row column">
16
16
  <%= form.text_field :address %>
17
17
  </div>
18
18
 
19
- <div class="row column" >
19
+ <div class="row column">
20
20
  <%= form.translated :text_area, :location %>
21
21
  </div>
22
22
 
23
- <div class="row column" >
23
+ <div class="row column">
24
24
  <%= form.translated :text_area, :location_hints %>
25
25
  </div>
26
26
 
27
- <div class="row" >
28
- <div class="columns xlarge-6" >
27
+ <div class="row">
28
+ <div class="columns xlarge-6">
29
29
  <%= form.datetime_field :start_time %>
30
30
  </div>
31
31
 
32
- <div class="columns xlarge-6" >
32
+ <div class="columns xlarge-6">
33
33
  <%= form.datetime_field :end_time %>
34
34
  </div>
35
35
  </div>
36
- <div class="row" >
36
+ <div class="row">
37
37
  <% if current_participatory_space.has_subscopes? %>
38
- <div class="columns xlarge-6" >
38
+ <div class="columns xlarge-6">
39
39
  <%= scopes_picker_field form, :decidim_scope_id %>
40
40
  </div>
41
41
  <% end %>
42
42
 
43
- <div class="columns xlarge-6" >
43
+ <div class="columns xlarge-6">
44
44
  <%= form.categories_select :decidim_category_id, current_participatory_space.categories, prompt: "", disable_parents: false %>
45
45
  </div>
46
46
  </div>
47
47
  </div>
48
48
  </div>
49
+
50
+ <%= render "services", form: form, id: tabs_id_for_service(blank_service) %>
51
+
52
+ <%= javascript_include_tag "decidim/meetings/admin/meetings_form" %>
@@ -0,0 +1,48 @@
1
+ <% service = form.object %>
2
+
3
+ <div class="card meeting-service" id="<%= id %>-field">
4
+ <div class="card-divider service-divider">
5
+ <h2 class="card-title">
6
+ <span><%= t(".service") %></span>
7
+
8
+ <button class="button small alert hollow move-up-service button--title">
9
+ <%== "#{icon("arrow-top")} #{t(".up")}" %>
10
+ </button>
11
+
12
+ <button class="button small alert hollow move-down-service button--title">
13
+ <%== "#{icon("arrow-bottom")} #{t(".down")}" %>
14
+ </button>
15
+
16
+ <button class="button small alert hollow remove-service button--title">
17
+ <%= t(".remove") %>
18
+ </button>
19
+ </h2>
20
+ </div>
21
+
22
+ <div class="card-section">
23
+ <div class="row column">
24
+ <%=
25
+ form.translated(
26
+ :text_field,
27
+ :title,
28
+ tabs_id: id,
29
+ label: t(".title")
30
+ )
31
+ %>
32
+ </div>
33
+
34
+ <div class="row column">
35
+ <%=
36
+ form.translated(
37
+ :text_area,
38
+ :description,
39
+ rows: 2,
40
+ tabs_id: id,
41
+ label: t(".description")
42
+ )
43
+ %>
44
+ </div>
45
+ </div>
46
+
47
+ <%= form.hidden_field :deleted, value: false %>
48
+ </div>
@@ -0,0 +1,25 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title"><%= t(".services") %></h2>
4
+ </div>
5
+
6
+ <div class="card-section">
7
+ <div class="meeting-services">
8
+ <template>
9
+ <%= fields_for "meeting[services][#{blank_service.to_param}]", blank_service do |service_form| %>
10
+ <%= render "decidim/meetings/admin/meetings/service", form: service_form, id: tabs_id_for_service(blank_service) %>
11
+ <% end %>
12
+ </template>
13
+
14
+ <div class="meeting-services-list">
15
+ <% form.object.services.each do |service| %>
16
+ <%= fields_for "meeting[services][]", service do |service_form| %>
17
+ <%= render "decidim/meetings/admin/meetings/service", form: service_form, id: tabs_id_for_service(service) %>
18
+ <% end %>
19
+ <% end %>
20
+ </div>
21
+
22
+ <button class="button add-service"><%= t(".add_service") %></button>
23
+ </div>
24
+ </div>
25
+ </div>
@@ -1,8 +1,7 @@
1
- <%= decidim_form_for(@form, html: { class: "form edit_meeting" }) do |f| %>
2
- <%= render partial: 'form', object: f %>
1
+ <%= decidim_form_for(@form, html: { class: "form edit_meeting" }) do |f| %>
2
+ <%= render partial: "form", object: f %>
3
3
 
4
4
  <div class="button--double form-general-submit">
5
5
  <%= f.submit t(".update") %>
6
6
  </div>
7
7
  <% end %>
8
-