decidim-admin 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim-admin might be problematic. Click here for more details.

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