decidim-admin 0.0.3 → 0.0.5

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +3 -3
  3. data/app/assets/stylesheets/decidim/admin/_email_preview.scss +5 -0
  4. data/app/assets/stylesheets/decidim/admin/application.scss +1 -0
  5. data/app/commands/decidim/admin/create_newsletter.rb +30 -0
  6. data/app/commands/decidim/admin/create_participatory_process_admin.rb +3 -0
  7. data/app/commands/decidim/admin/deliver_newsletter.rb +29 -0
  8. data/app/commands/decidim/admin/destroy_participatory_process_step.rb +9 -0
  9. data/app/commands/decidim/admin/update_feature_permissions.rb +46 -0
  10. data/app/commands/decidim/admin/update_newsletter.rb +33 -0
  11. data/app/commands/decidim/admin/update_organization.rb +17 -2
  12. data/app/commands/decidim/admin/update_participatory_process.rb +4 -2
  13. data/app/constraints/decidim/admin/organization_dashboard_constraint.rb +1 -1
  14. data/app/controllers/decidim/admin/application_controller.rb +3 -0
  15. data/app/controllers/decidim/admin/feature_permissions_controller.rb +59 -0
  16. data/app/controllers/decidim/admin/features_controller.rb +20 -0
  17. data/app/controllers/decidim/admin/newsletters_controller.rb +115 -0
  18. data/app/controllers/decidim/admin/participatory_processes_controller.rb +4 -4
  19. data/app/controllers/decidim/admin/users_controller.rb +3 -1
  20. data/app/forms/decidim/admin/newsletter_form.rb +15 -0
  21. data/app/forms/decidim/admin/organization_form.rb +10 -0
  22. data/app/forms/decidim/admin/participatory_process_form.rb +8 -5
  23. data/app/forms/decidim/admin/permission_form.rb +31 -0
  24. data/app/forms/decidim/admin/permissions_form.rb +16 -0
  25. data/app/helpers/decidim/admin/application_helper.rb +1 -0
  26. data/app/jobs/decidim/admin/newsletter_delivery_job.rb +18 -0
  27. data/app/jobs/decidim/admin/newsletter_job.rb +32 -0
  28. data/app/models/decidim/admin/abilities/admin_user.rb +4 -0
  29. data/app/models/decidim/admin/abilities/base.rb +4 -0
  30. data/app/models/decidim/admin/abilities/collaborator_user.rb +19 -0
  31. data/app/models/decidim/admin/abilities/participatory_process_admin.rb +1 -1
  32. data/app/models/decidim/admin/participatory_process_user_role.rb +1 -1
  33. data/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +1 -1
  34. data/app/views/decidim/admin/attachments/edit.html.erb +1 -1
  35. data/app/views/decidim/admin/attachments/new.html.erb +1 -1
  36. data/app/views/decidim/admin/categories/edit.html.erb +1 -1
  37. data/app/views/decidim/admin/categories/new.html.erb +1 -1
  38. data/app/views/decidim/admin/dashboard/show.html.erb +1 -1
  39. data/app/views/decidim/admin/feature_permissions/edit.html.erb +27 -0
  40. data/app/views/decidim/admin/features/_feature.html.erb +10 -0
  41. data/app/views/decidim/admin/features/edit.html.erb +1 -1
  42. data/app/views/decidim/admin/features/new.html.erb +1 -1
  43. data/app/views/decidim/admin/newsletters/_form.html.erb +5 -0
  44. data/app/views/decidim/admin/newsletters/edit.html.erb +11 -0
  45. data/app/views/decidim/admin/newsletters/index.html.erb +47 -0
  46. data/app/views/decidim/admin/newsletters/new.html.erb +11 -0
  47. data/app/views/decidim/admin/newsletters/show.html.erb +14 -0
  48. data/app/views/decidim/admin/organization/_form.html.erb +34 -0
  49. data/app/views/decidim/admin/organization/edit.html.erb +2 -2
  50. data/app/views/decidim/admin/participatory_process_steps/_form.html.erb +1 -1
  51. data/app/views/decidim/admin/participatory_process_steps/edit.html.erb +1 -1
  52. data/app/views/decidim/admin/participatory_process_steps/new.html.erb +1 -1
  53. data/app/views/decidim/admin/participatory_process_user_roles/index.html.erb +1 -1
  54. data/app/views/decidim/admin/participatory_processes/_form.html.erb +18 -5
  55. data/app/views/decidim/admin/participatory_processes/edit.html.erb +1 -1
  56. data/app/views/decidim/admin/participatory_processes/index.html.erb +1 -1
  57. data/app/views/decidim/admin/participatory_processes/new.html.erb +2 -2
  58. data/app/views/decidim/admin/participatory_processes/show.html.erb +5 -2
  59. data/app/views/decidim/admin/scopes/edit.html.erb +2 -2
  60. data/app/views/decidim/admin/scopes/index.html.erb +1 -1
  61. data/app/views/decidim/admin/scopes/new.html.erb +2 -2
  62. data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  63. data/app/views/decidim/admin/static_pages/edit.html.erb +2 -2
  64. data/app/views/decidim/admin/static_pages/index.html.erb +1 -1
  65. data/app/views/decidim/admin/static_pages/new.html.erb +2 -2
  66. data/app/views/decidim/admin/static_pages/show.html.erb +1 -1
  67. data/app/views/decidim/admin/user_groups/index.html.erb +1 -1
  68. data/app/views/decidim/admin/users/index.html.erb +1 -1
  69. data/app/views/decidim/admin/users/new.html.erb +2 -2
  70. data/app/views/layouts/decidim/admin/_sidebar.html.erb +1 -0
  71. data/app/views/layouts/decidim/admin/participatory_process.html.erb +1 -1
  72. data/config/i18n-tasks.yml +4 -3
  73. data/config/locales/ca.yml +60 -1
  74. data/config/locales/en.yml +59 -0
  75. data/config/locales/es.yml +59 -0
  76. data/config/locales/eu.yml +5 -0
  77. data/config/routes.rb +15 -1
  78. data/db/seeds.rb +3 -1
  79. data/lib/decidim/admin/engine.rb +1 -0
  80. data/lib/decidim/admin/features/base_controller.rb +5 -1
  81. metadata +26 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a558feb308b27b688f8588f74871422a59d3efbc
4
- data.tar.gz: 3300ce4311639a5a14bf6e8fd1c94e1776a5148e
3
+ metadata.gz: ae578c5b5087d3e005a7216cd75b4231041c2572
4
+ data.tar.gz: 43e84e9529896d1a143e33fa1f0d3bb436586cab
5
5
  SHA512:
6
- metadata.gz: 70b3749d2b3fbbaeaa6318b93613d6661f65bd9187b4d1bccab8b872747ff7d0d7ef3c96ea0c5183038671a1d953655773b451e24d531eb1ba9f99cd23b369bf
7
- data.tar.gz: 17f6d2bf2e8966b973a877f83644b8e42e7991782ef242a734a93391c4fda67c1f9f9ae7b56643c9af222742385dbc5bc3b031631962840e7af93cbc8e2f0883
6
+ metadata.gz: 2c505c94e7f607153ce8f8db38e319886393abd5c3460eab9bf111de20f025a78bdd545bbfe8e3d9688c891de4e6f86dd73646379d9b7cee36721a5d8b22ce3b
7
+ data.tar.gz: 4404856289d63a285fc84ba7f7c7f964d44df6909f726a2081728e0c345c57218e0ee0fd373fd113febc3d7cd244bbbe5c7b15ddfa59f67c28457641883f3733
@@ -13,9 +13,9 @@ const sortSteps = () => {
13
13
  sortable('#steps tbody', {
14
14
  placeholder: $('<tr style="border-style: dashed; border-color: #000"><td colspan="4">&nbsp;</td></tr>')[0]
15
15
  })[0].addEventListener('sortupdate', (event) => {
16
- const order = $(event.target).children()
17
- .map((index, child) => $(child).data('id'))
18
- .toArray();
16
+ const order = $(event.target).children().
17
+ map((index, child) => $(child).data('id')).
18
+ toArray();
19
19
 
20
20
  $.ajax({
21
21
  method: 'POST',
@@ -0,0 +1,5 @@
1
+ .email-preview{
2
+ border: 0;
3
+ width: 100%;
4
+ height: 70vh;
5
+ }
@@ -6,6 +6,7 @@
6
6
  @import "actions";
7
7
  @import "forms";
8
8
  @import "icons";
9
+ @import "email_preview";
9
10
 
10
11
  @import "decidim/editor";
11
12
  @import "decidim/utils/fontface";
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Admin
4
+ # Creates a newsletter and assigns the right author and
5
+ # organization.
6
+ class CreateNewsletter < Rectify::Command
7
+ # Initializes the command.
8
+ #
9
+ # form - The source fo data for this newsletter.
10
+ # user - The User that authored this newsletter.
11
+ def initialize(form, user)
12
+ @form = form
13
+ @user = user
14
+ end
15
+
16
+ def call
17
+ return broadcast(:invalid) unless @form.valid?
18
+
19
+ newsletter = Newsletter.create!(
20
+ subject: @form.subject,
21
+ body: @form.body,
22
+ author: @user,
23
+ organization: @user.organization
24
+ )
25
+
26
+ broadcast(:ok, newsletter)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -26,6 +26,9 @@ module Decidim
26
26
 
27
27
  create_participatory_process_admin
28
28
  broadcast(:ok)
29
+ rescue ActiveRecord::RecordInvalid
30
+ form.errors.add(:email, :taken)
31
+ broadcast(:invalid)
29
32
  end
30
33
 
31
34
  private
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Admin
4
+ # Delivers the newsletter to its recipients.
5
+ class DeliverNewsletter < Rectify::Command
6
+ # Initializes the command.
7
+ #
8
+ # newsletter - The newsletter to deliver.
9
+ def initialize(newsletter)
10
+ @newsletter = newsletter
11
+ end
12
+
13
+ def call
14
+ @newsletter.with_lock do
15
+ return broadcast(:invalid) if @newsletter.sent?
16
+ send_newsletter!
17
+ end
18
+
19
+ broadcast(:ok, @newsletter)
20
+ end
21
+
22
+ private
23
+
24
+ def send_newsletter!
25
+ NewsletterJob.perform_later(@newsletter)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -22,8 +22,17 @@ module Decidim
22
22
  return broadcast(:invalid, :active_step) if @step.active?
23
23
 
24
24
  @step.destroy!
25
+ reorder_steps
25
26
  broadcast(:ok)
26
27
  end
28
+
29
+ private
30
+
31
+ def reorder_steps
32
+ ReorderParticipatoryProcessSteps
33
+ .new(@participatory_process.steps, @participatory_process.steps.map(&:id))
34
+ .call
35
+ end
27
36
  end
28
37
  end
29
38
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Admin
4
+ # This command gets called when permissions for a feature are updated
5
+ # in the admin panel.
6
+ class UpdateFeaturePermissions < Rectify::Command
7
+ attr_reader :form, :feature
8
+
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - The form from which the data in this feature comes from.
12
+ # feature - The feature to update.
13
+ def initialize(form, feature)
14
+ @form = form
15
+ @feature = feature
16
+ end
17
+
18
+ # Public: Sets the permissions for a feature.
19
+ #
20
+ # Broadcasts :ok if created, :invalid otherwise.
21
+ def call
22
+ return broadcast(:invalid) unless @form.valid?
23
+
24
+ update_permissions
25
+ broadcast(:ok)
26
+ end
27
+
28
+ private
29
+
30
+ def update_permissions
31
+ permissions = @form.permissions.inject({}) do |result, (key, value)|
32
+ serialized = {
33
+ "authorization_handler_name" => value.authorization_handler_name
34
+ }
35
+
36
+ serialized["options"] = JSON.parse(value.options) if value.options
37
+ result.update(key => serialized)
38
+ end
39
+
40
+ @feature.update_attributes!(
41
+ permissions: permissions
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Admin
4
+ # Updates the newsletter given form data.
5
+ class UpdateNewsletter < Rectify::Command
6
+ # Initializes the command.
7
+ #
8
+ # newsletter - The Newsletter to update.
9
+ # form - The form object containing the data to update.
10
+ # user - The user that updates the newsletter.
11
+ def initialize(newsletter, form, user)
12
+ @newsletter = newsletter
13
+ @form = form
14
+ @user = user
15
+ @organization = user.organization
16
+ end
17
+
18
+ def call
19
+ return broadcast(:invalid) unless @form.valid?
20
+ return broadcast(:invalid) if @newsletter.sent?
21
+ return broadcast(:invalid) unless @organization == @newsletter.organization
22
+
23
+ @newsletter.update_attributes!(
24
+ subject: @form.subject,
25
+ body: @form.body,
26
+ author: @user
27
+ )
28
+
29
+ broadcast(:ok, @newsletter)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -23,7 +23,14 @@ module Decidim
23
23
  return broadcast(:invalid) if form.invalid?
24
24
 
25
25
  update_organization
26
- broadcast(:ok)
26
+
27
+ if @organization.valid?
28
+ broadcast(:ok, @organization)
29
+ else
30
+ form.errors.add(:official_img_header, @organization.errors[:official_img_header]) if @organization.errors.include? :official_img_header
31
+ form.errors.add(:official_img_footer, @organization.errors[:official_img_footer]) if @organization.errors.include? :official_img_footer
32
+ broadcast(:invalid)
33
+ end
27
34
  end
28
35
 
29
36
  private
@@ -31,19 +38,27 @@ module Decidim
31
38
  attr_reader :form, :organization
32
39
 
33
40
  def update_organization
34
- organization.update_attributes!(attributes)
41
+ @organization.assign_attributes(attributes)
42
+ @organization.save! if @organization.valid?
35
43
  end
36
44
 
37
45
  def attributes
38
46
  {
39
47
  name: form.name,
40
48
  twitter_handler: form.twitter_handler,
49
+ facebook_handler: form.facebook_handler,
50
+ instagram_handler: form.instagram_handler,
51
+ youtube_handler: form.youtube_handler,
52
+ github_handler: form.github_handler,
41
53
  description: form.description,
42
54
  welcome_text: form.welcome_text,
43
55
  homepage_image: form.homepage_image || organization.homepage_image,
44
56
  logo: form.logo || organization.logo,
45
57
  favicon: form.favicon || organization.favicon,
46
58
  default_locale: form.default_locale,
59
+ official_img_header: form.official_img_header || organization.official_img_header,
60
+ official_img_footer: form.official_img_footer || organization.official_img_footer,
61
+ official_url: form.official_url,
47
62
  show_statistics: form.show_statistics
48
63
  }
49
64
  end
@@ -32,7 +32,6 @@ module Decidim
32
32
  end
33
33
  end
34
34
 
35
-
36
35
  private
37
36
 
38
37
  attr_reader :form
@@ -53,9 +52,12 @@ module Decidim
53
52
  promoted: form.promoted,
54
53
  description: form.description,
55
54
  short_description: form.short_description,
56
- domain: form.domain,
57
55
  scope: form.scope,
58
56
  developer_group: form.developer_group,
57
+ local_area: form.local_area,
58
+ target: form.target,
59
+ participatory_scope: form.participatory_scope,
60
+ participatory_structure: form.participatory_structure,
59
61
  end_date: form.end_date
60
62
  }.compact
61
63
  end
@@ -15,7 +15,7 @@ module Decidim
15
15
  #
16
16
  # Returns boolean.
17
17
  def matches?
18
- user.organization == organization && ability.can?(:read, :admin_dashboard)
18
+ user && user.organization == organization && ability.can?(:read, :admin_dashboard)
19
19
  end
20
20
 
21
21
  private
@@ -7,6 +7,9 @@ module Decidim
7
7
  include NeedsAuthorization
8
8
  include FormFactory
9
9
  include LocaleSwitcher
10
+ helper Decidim::DecidimFormHelper
11
+
12
+ helper Decidim::LanguageChooserHelper
10
13
 
11
14
  protect_from_forgery with: :exception, prepend: true
12
15
 
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ require_dependency "decidim/admin/application_controller"
3
+
4
+ module Decidim
5
+ module Admin
6
+ # Controller that allows managing all the Admins.
7
+ #
8
+ class FeaturePermissionsController < ApplicationController
9
+ include Concerns::ParticipatoryProcessAdmin
10
+ helper_method :authorizations, :feature
11
+
12
+ def edit
13
+ authorize! :update, feature
14
+ @permissions_form = PermissionsForm.new(
15
+ permissions: permission_forms
16
+ )
17
+ end
18
+
19
+ def update
20
+ authorize! :update, feature
21
+ @permissions_form = PermissionsForm.from_params(params)
22
+
23
+ UpdateFeaturePermissions.call(@permissions_form, feature) do
24
+ on(:ok) do
25
+ flash[:notice] = t("feature_permissions.update.success", scope: "decidim.admin")
26
+ redirect_to participatory_process_features_path(participatory_process)
27
+ end
28
+
29
+ on(:invalid) do
30
+ render action: :edit
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def permission_forms
38
+ permissions = feature.permissions || {}
39
+
40
+ @permission_forms ||= feature.manifest.actions.inject({}) do |result, action|
41
+ form = PermissionForm.new(
42
+ authorization_handler_name: permissions.dig(action, "authorization_handler_name"),
43
+ options: permissions.dig(action, "options").try(:to_json)
44
+ )
45
+
46
+ result.update(action => form)
47
+ end
48
+ end
49
+
50
+ def authorizations
51
+ Decidim.authorization_handlers.map(&:handler_name)
52
+ end
53
+
54
+ def feature
55
+ @feature ||= participatory_process.features.find(params[:feature_id])
56
+ end
57
+ end
58
+ end
59
+ end
@@ -88,6 +88,26 @@ module Decidim
88
88
  end
89
89
  end
90
90
 
91
+ def publish
92
+ @feature = query_scope.find(params[:id])
93
+ authorize! :update, @feature
94
+
95
+ @feature.update_attribute(:published_at, Time.current)
96
+
97
+ flash[:notice] = I18n.t("features.publish.success", scope: "decidim.admin")
98
+ redirect_to action: :index
99
+ end
100
+
101
+ def unpublish
102
+ @feature = query_scope.find(params[:id])
103
+ authorize! :update, @feature
104
+
105
+ @feature.update_attribute(:published_at, nil)
106
+
107
+ flash[:notice] = I18n.t("features.unpublish.success", scope: "decidim.admin")
108
+ redirect_to action: :index
109
+ end
110
+
91
111
  private
92
112
 
93
113
  def query_scope
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # Controller that allows managing user groups at the admin panel.
6
+ #
7
+ class NewslettersController < ApplicationController
8
+ def index
9
+ authorize! :index, Newsletter
10
+ @newsletters = collection.order(Newsletter.arel_table[:created_at].desc)
11
+ end
12
+
13
+ def new
14
+ authorize! :create, Newsletter
15
+ @form = form(NewsletterForm).instance
16
+ end
17
+
18
+ def show
19
+ @newsletter = collection.find(params[:id])
20
+ @email = NewsletterMailer.newsletter(current_user, @newsletter)
21
+ authorize! :read, @newsletter
22
+ end
23
+
24
+ def preview
25
+ @newsletter = collection.find(params[:id])
26
+ authorize! :read, @newsletter
27
+
28
+ email = NewsletterMailer.newsletter(current_user, @newsletter)
29
+ Premailer::Rails::Hook.perform(email)
30
+
31
+ render text: email.html_part.body.decoded
32
+ end
33
+
34
+ def create
35
+ authorize! :create, Newsletter
36
+ @form = form(NewsletterForm).from_params(params)
37
+
38
+ CreateNewsletter.call(@form, current_user) do
39
+ on(:ok) do |newsletter|
40
+ flash.now[:notice] = I18n.t("newsletters.create.success", scope: "decidim.admin")
41
+ redirect_to action: :show, id: newsletter.id
42
+ end
43
+
44
+ on(:invalid) do |newsletter|
45
+ @newsletter = newsletter
46
+ flash.now[:error] = I18n.t("newsletters.create.error", scope: "decidim.admin")
47
+ render action: :new
48
+ end
49
+ end
50
+ end
51
+
52
+ def edit
53
+ @newsletter = collection.find(params[:id])
54
+ authorize! :update, @newsletter
55
+ @form = form(NewsletterForm).from_model(@newsletter)
56
+ end
57
+
58
+ def update
59
+ @newsletter = collection.find(params[:id])
60
+ authorize! :update, Newsletter
61
+ @form = form(NewsletterForm).from_params(params)
62
+
63
+ UpdateNewsletter.call(@newsletter, @form, current_user) do
64
+ on(:ok) do |newsletter|
65
+ flash.now[:notice] = I18n.t("newsletters.update.success", scope: "decidim.admin")
66
+ redirect_to action: :show, id: newsletter.id
67
+ end
68
+
69
+ on(:invalid) do |newsletter|
70
+ @newsletter = newsletter
71
+ flash.now[:error] = I18n.t("newsletters.update.error", scope: "decidim.admin")
72
+ render action: :edit
73
+ end
74
+ end
75
+ end
76
+
77
+ def destroy
78
+ @newsletter = collection.find(params[:id])
79
+ authorize! :destroy, @newsletter
80
+
81
+ if @newsletter.sent?
82
+ flash.now[:error] = I18n.t("newsletters.destroy.error_already_sent", scope: "decidim.admin")
83
+ redirect_to :back
84
+ else
85
+ @newsletter.destroy!
86
+ flash[:notice] = I18n.t("newsletters.destroy.success", scope: "decidim.admin")
87
+ redirect_to action: :index
88
+ end
89
+ end
90
+
91
+ def deliver
92
+ @newsletter = collection.find(params[:id])
93
+ authorize! :update, @newsletter
94
+
95
+ DeliverNewsletter.call(@newsletter) do
96
+ on(:ok) do
97
+ flash[:notice] = I18n.t("newsletters.deliver.success", scope: "decidim.admin")
98
+ redirect_to action: :index
99
+ end
100
+
101
+ on(:invalid) do
102
+ flash[:error] = I18n.t("newsletters.deliver.error", scope: "decidim.admin")
103
+ redirect_to action: :show
104
+ end
105
+ end
106
+ end
107
+
108
+ private
109
+
110
+ def collection
111
+ Newsletter.where(organization: current_organization)
112
+ end
113
+ end
114
+ end
115
+ end