decidim-admin 0.13.1 → 0.14.1

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/admin/application.js.es6 +3 -0
  3. data/app/assets/javascripts/decidim/admin/bundle.js +5 -5
  4. data/app/assets/javascripts/decidim/admin/bundle.js.map +1 -1
  5. data/app/assets/javascripts/decidim/admin/draggable-list.js.es6 +30 -0
  6. data/app/assets/stylesheets/decidim/admin/components/_autocomplete_select.component.scss +6 -0
  7. data/app/assets/stylesheets/decidim/admin/extra/_action-icon.scss +5 -0
  8. data/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +4 -0
  9. data/app/assets/stylesheets/decidim/admin/modules/_card-grid.scss +25 -0
  10. data/app/assets/stylesheets/decidim/admin/modules/_draggable-list.scss +27 -0
  11. data/app/assets/stylesheets/decidim/admin/modules/_forms.scss +8 -1
  12. data/app/assets/stylesheets/decidim/admin/modules/_modules.scss +8 -0
  13. data/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +2 -0
  14. data/app/cells/decidim/admin/content_block/show.erb +13 -0
  15. data/app/cells/decidim/admin/content_block_cell.rb +19 -0
  16. data/app/commands/decidim/admin/reorder_content_blocks.rb +97 -0
  17. data/app/commands/decidim/admin/update_component_permissions.rb +31 -11
  18. data/app/commands/decidim/admin/update_content_block.rb +55 -0
  19. data/app/commands/decidim/admin/update_organization_appearance.rb +0 -3
  20. data/app/controllers/decidim/admin/component_permissions_controller.rb +32 -5
  21. data/app/controllers/decidim/admin/components/base_controller.rb +2 -1
  22. data/app/controllers/decidim/admin/concerns/has_attachment_collections.rb +0 -8
  23. data/app/controllers/decidim/admin/concerns/has_private_users.rb +6 -10
  24. data/app/controllers/decidim/admin/impersonations_controller.rb +1 -0
  25. data/app/controllers/decidim/admin/officializations_controller.rb +1 -0
  26. data/app/controllers/decidim/admin/organization_homepage_content_blocks_controller.rb +64 -0
  27. data/app/controllers/decidim/admin/organization_homepage_controller.rb +52 -0
  28. data/app/forms/decidim/admin/content_block_form.rb +24 -0
  29. data/app/forms/decidim/admin/organization_appearance_form.rb +0 -4
  30. data/app/helpers/decidim/admin/resource_permissions_helper.rb +24 -0
  31. data/app/views/decidim/admin/component_permissions/edit.html.erb +8 -3
  32. data/app/views/decidim/admin/components/edit.html.erb +1 -1
  33. data/app/views/decidim/admin/components/new.html.erb +1 -1
  34. data/app/views/decidim/admin/officializations/index.html.erb +3 -2
  35. data/app/views/decidim/admin/organization_appearance/_form.html.erb +0 -10
  36. data/app/views/decidim/admin/organization_homepage/edit.html.erb +43 -0
  37. data/app/views/decidim/admin/organization_homepage_content_blocks/edit.html.erb +13 -0
  38. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +3 -2
  39. data/app/views/layouts/decidim/admin/newsletters.erb +1 -1
  40. data/app/views/layouts/decidim/admin/settings.html.erb +3 -0
  41. data/config/locales/ca.yml +8 -30
  42. data/config/locales/en.yml +8 -30
  43. data/config/locales/es-PY.yml +8 -30
  44. data/config/locales/es.yml +8 -30
  45. data/config/locales/eu.yml +8 -30
  46. data/config/locales/fi.yml +128 -150
  47. data/config/locales/fr.yml +8 -30
  48. data/config/locales/gl.yml +8 -30
  49. data/config/locales/hu.yml +660 -0
  50. data/config/locales/it.yml +8 -30
  51. data/config/locales/nl.yml +8 -30
  52. data/config/locales/pl.yml +8 -30
  53. data/config/locales/pt-BR.yml +41 -63
  54. data/config/locales/pt.yml +8 -30
  55. data/config/locales/ru.yml +18 -43
  56. data/config/locales/sv.yml +38 -60
  57. data/config/locales/uk.yml +19 -44
  58. data/config/routes.rb +3 -0
  59. data/lib/decidim/admin/engine.rb +8 -0
  60. data/lib/decidim/admin/form_builder.rb +2 -1
  61. data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +1 -1
  62. data/lib/decidim/admin/test/manage_attachments_examples.rb +4 -4
  63. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +192 -0
  64. data/lib/decidim/admin/version.rb +1 -1
  65. metadata +31 -11
@@ -0,0 +1,30 @@
1
+ ((exports) => {
2
+ const { createSortList } = exports.DecidimAdmin;
3
+
4
+ const createSortableList = (lists) => {
5
+ createSortList(lists, {
6
+ handle: "li",
7
+ forcePlaceholderSize: true,
8
+ connectWith: ".js-connect"
9
+ })
10
+ };
11
+
12
+ // Once in DOM
13
+ $(() => {
14
+ const $draggables = $(".draggable-list")
15
+ let draggablesClassNames = []
16
+ $draggables.each((index, elem) => {
17
+ draggablesClassNames = [...draggablesClassNames, `.${elem.className.split(" ").filter((name) => (/js-list.*/).test(name))[0]}`]
18
+ })
19
+
20
+ document.addEventListener("drag", function (event) {
21
+ $draggables.not(event.target.parentElement).addClass("dragging")
22
+ })
23
+
24
+ document.addEventListener("dragend", function() {
25
+ $draggables.removeClass("dragging")
26
+ })
27
+
28
+ createSortableList(draggablesClassNames.join(", "))
29
+ })
30
+ })(window)
@@ -11,3 +11,9 @@
11
11
  }
12
12
  }
13
13
  }
14
+
15
+ .autocomplete-field--results-inline{
16
+ .Select-menu-outer{
17
+ position: relative;
18
+ }
19
+ }
@@ -4,5 +4,10 @@
4
4
  color: rgba($muted, .3);
5
5
  vertical-align: bottom;
6
6
  }
7
+
8
+ &.action-icon--highlighted{
9
+ color: $warning-color;
10
+ vertical-align: bottom;
11
+ }
7
12
  }
8
13
  }
@@ -18,6 +18,10 @@
18
18
  position: initial;
19
19
  }
20
20
 
21
+ .is-dropdown-submenu{
22
+ z-index: 2;
23
+ }
24
+
21
25
  .user-login{
22
26
  vertical-align: middle;
23
27
  position: initial;
@@ -0,0 +1,25 @@
1
+ $card-grid-margin-bottom: map-get($grid-column-gutter, medium);
2
+
3
+ .card-grid{
4
+ display: flex;
5
+ flex-wrap: wrap;
6
+
7
+ &::before{
8
+ width: 0; //fixes a flexbox bug in Safari with the clearfix element
9
+ }
10
+
11
+ .column{
12
+ margin-bottom: $card-grid-margin-bottom;
13
+ }
14
+
15
+ .card{
16
+ margin-bottom: 0;
17
+ display: flex;
18
+ flex-direction: column;
19
+ height: 100%;
20
+ }
21
+
22
+ .card__content{
23
+ flex-grow: 1;
24
+ }
25
+ }
@@ -0,0 +1,27 @@
1
+ .draggable-list{
2
+ margin: 0;
3
+ padding: 0;
4
+ list-style-type: none;
5
+ min-height: ($global-padding * 2) + $global-lineheight;
6
+
7
+ &.dragging{
8
+ border-top: 2px dashed $medium-gray;
9
+ border-bottom: 2px dashed $medium-gray;
10
+ background-color: $body-background;
11
+ }
12
+
13
+ li{
14
+ cursor: move;
15
+ padding: $global-padding / 2 0;
16
+ }
17
+
18
+ .draggable-content{
19
+ @include flex;
20
+ @include flex-align(justify, middle);
21
+
22
+ font-weight: $global-weight-bold;
23
+ border: $border;
24
+ background-color: $light-gray;
25
+ padding: $global-padding / 2 $global-padding;
26
+ }
27
+ }
@@ -63,13 +63,20 @@ textarea{
63
63
  justify-content: center;
64
64
  }
65
65
 
66
- .check-radio{
66
+ .check-radio,
67
+ .check-radio-collection{
67
68
  label{
68
69
  font-weight: normal;
69
70
  display: inline-flex;
70
71
  align-items: center;
71
72
  }
72
73
 
74
+ legend{
75
+ font-weight: 600;
76
+ }
77
+ }
78
+
79
+ .check-radio{
73
80
  input{
74
81
  margin-bottom: 0;
75
82
  }
@@ -18,6 +18,7 @@
18
18
  //Contents
19
19
  @import "callouts";
20
20
  @import "cards";
21
+ @import "card-grid";
21
22
  @import "table-list";
22
23
  @import "action-icon";
23
24
  @import "char-counter";
@@ -26,3 +27,10 @@
26
27
  @import "filters";
27
28
  @import "dropdown";
28
29
  @import "agenda";
30
+ @import "draggable-list";
31
+
32
+ // mentions__container
33
+ @import "decidim/modules/tags";
34
+ @import "decidim/modules/input-tags";
35
+ @import "decidim/modules/input-mentions";
36
+ @import "decidim/modules/input-hashtags";
@@ -36,6 +36,7 @@ $palette: $foundation-palette;
36
36
  }
37
37
 
38
38
  // helpers
39
+ $margin-xs: .5rem;
39
40
  $margin-s: 1rem;
40
41
  $margin-sm: 2rem;
41
42
  $margin-m: 3rem;
@@ -43,6 +44,7 @@ $margin-l: 5rem;
43
44
 
44
45
  $size:(
45
46
  none: 0,
47
+ xs: $margin-xs,
46
48
  s: $margin-s,
47
49
  sm: $margin-sm,
48
50
  m: $margin-m,
@@ -0,0 +1,13 @@
1
+ <li draggable="true" data-content-block-manifest-name="<%= manifest_name %>">
2
+ <div class="draggable-content">
3
+ <%= t(public_name_key) %>
4
+ <div>
5
+ <% if has_settings? %>
6
+ <%= link_to decidim_admin.edit_organization_homepage_content_block_path(manifest_name), class: "mr-s text-muted" do %>
7
+ <%= icon "pencil" %>
8
+ <% end %>
9
+ <% end %>
10
+ <%= icon "menu" %>
11
+ </div>
12
+ </div>
13
+ </li>
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ class ContentBlockCell < Decidim::ViewModel
6
+ include Decidim::IconHelper
7
+
8
+ delegate :public_name_key, :has_settings?, to: :model
9
+
10
+ def manifest_name
11
+ model.try(:manifest_name) || model.name
12
+ end
13
+
14
+ def decidim_admin
15
+ Decidim::Admin::Engine.routes.url_helpers
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # A command that reorders a collection of content blocks. It also creates
6
+ # the ones that might be missing.
7
+ class ReorderContentBlocks < Rectify::Command
8
+ # Public: Initializes the command.
9
+ #
10
+ # organization - the Organization where the content blocks reside
11
+ # scope - the scope applied to the content blocks
12
+ # order - an Array holding the order of IDs of published content blocks.
13
+ def initialize(organization, scope, order)
14
+ @organization = organization
15
+ @scope = scope
16
+ @order = order
17
+ end
18
+
19
+ # Executes the command. Broadcasts these events:
20
+ #
21
+ # - :ok when everything is valid.
22
+ # - :invalid if the data wasn't valid and we couldn't proceed.
23
+ #
24
+ # Returns nothing.
25
+ def call
26
+ return broadcast(:invalid) if order.blank?
27
+
28
+ reorder_steps
29
+ broadcast(:ok)
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :organization, :scope
35
+
36
+ def reorder_steps
37
+ transaction do
38
+ reset_weights
39
+ collection.reload
40
+ set_new_weights
41
+ unpublish_removed_content_blocks
42
+ publish_appearing_content_blocks
43
+ end
44
+ end
45
+
46
+ def reset_weights
47
+ # rubocop:disable Rails/SkipsModelValidations
48
+ collection.where.not(weight: nil).update_all(weight: nil)
49
+ # rubocop:enable Rails/SkipsModelValidations
50
+ end
51
+
52
+ def set_new_weights
53
+ data = order.each_with_index.inject({}) do |hash, (manifest_name, index)|
54
+ hash.update(manifest_name => index + 1)
55
+ end
56
+
57
+ data.each do |manifest_name, weight|
58
+ content_block = collection.find { |block| block.manifest_name == manifest_name }
59
+ if content_block.present?
60
+ content_block.update!(weight: weight)
61
+ else
62
+ create_content_block(manifest_name, weight)
63
+ end
64
+ end
65
+ end
66
+
67
+ # rubocop:disable Rails/SkipsModelValidations
68
+ def unpublish_removed_content_blocks
69
+ collection.where(weight: nil).update_all(published_at: nil)
70
+ end
71
+
72
+ def publish_appearing_content_blocks
73
+ collection.where(published_at: nil).where.not(weight: nil).update_all(published_at: Time.current)
74
+ end
75
+ # rubocop:enable Rails/SkipsModelValidations
76
+
77
+ def create_content_block(manifest_name, weight)
78
+ Decidim::ContentBlock.create!(
79
+ organization: organization,
80
+ scope: scope,
81
+ weight: weight,
82
+ manifest_name: manifest_name
83
+ )
84
+ end
85
+
86
+ def order
87
+ return nil unless @order.is_a?(Array) && @order.present?
88
+
89
+ @order
90
+ end
91
+
92
+ def collection
93
+ @collection ||= Decidim::ContentBlock.for_scope(scope, organization: organization)
94
+ end
95
+ end
96
+ end
97
+ end
@@ -5,22 +5,22 @@ module Decidim
5
5
  # This command gets called when permissions for a component are updated
6
6
  # in the admin panel.
7
7
  class UpdateComponentPermissions < Rectify::Command
8
- attr_reader :form, :component
9
-
10
8
  # Public: Initializes the command.
11
9
  #
12
10
  # form - The form from which the data in this component comes from.
13
11
  # component - The component to update.
14
- def initialize(form, component)
12
+ # resource - The resource to update.
13
+ def initialize(form, component, resource)
15
14
  @form = form
16
15
  @component = component
16
+ @resource = resource
17
17
  end
18
18
 
19
19
  # Public: Sets the permissions for a component.
20
20
  #
21
21
  # Broadcasts :ok if created, :invalid otherwise.
22
22
  def call
23
- return broadcast(:invalid) unless @form.valid?
23
+ return broadcast(:invalid) unless form.valid?
24
24
 
25
25
  transaction do
26
26
  update_permissions
@@ -32,9 +32,11 @@ module Decidim
32
32
 
33
33
  private
34
34
 
35
+ attr_reader :form, :component, :resource
36
+
35
37
  def configured_permissions
36
- @form.permissions.select do |_action, permission|
37
- permission.authorization_handler_name.present?
38
+ form.permissions.select do |action, permission|
39
+ permission.authorization_handler_name.present? || overriding_component_permissions?(action)
38
40
  end
39
41
  end
40
42
 
@@ -45,16 +47,34 @@ module Decidim
45
47
  "options" => value.options
46
48
  }
47
49
 
48
- result.update(key => serialized)
50
+ result.update(key => value.authorization_handler_name.present? ? serialized : {})
49
51
  end
50
52
 
51
- @component.update!(
52
- permissions: permissions
53
- )
53
+ if resource
54
+ resource_permissions.update!(permissions: different_from_component_permissions(permissions))
55
+ else
56
+ component.update!(permissions: permissions)
57
+ end
54
58
  end
55
59
 
56
60
  def run_hooks
57
- @component.manifest.run_hooks(:permission_update, @component)
61
+ component.manifest.run_hooks(:permission_update, component: component, resource: resource)
62
+ end
63
+
64
+ def resource_permissions
65
+ @resource_permissions ||= resource.resource_permission || resource.build_resource_permission
66
+ end
67
+
68
+ def different_from_component_permissions(permissions)
69
+ return permissions unless component.permissions
70
+
71
+ permissions.deep_stringify_keys.reject do |action, config|
72
+ HashDiff.diff(config, component.permissions[action]).empty?
73
+ end
74
+ end
75
+
76
+ def overriding_component_permissions?(action)
77
+ resource && component&.permissions&.fetch(action, nil)
58
78
  end
59
79
  end
60
80
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # This command gets called when a content block is updated from the admin
6
+ # panel.
7
+ class UpdateContentBlock < Rectify::Command
8
+ attr_reader :form, :content_block, :scope
9
+
10
+ # Public: Initializes the command.
11
+ #
12
+ # form - The form from which the data in this component comes from.
13
+ # component - The component to update.
14
+ # scope - the scope where the content block belongs to.
15
+ def initialize(form, content_block, scope)
16
+ @form = form
17
+ @content_block = content_block
18
+ @scope = scope
19
+ end
20
+
21
+ # Public: Updates the content block settings and its attachments.
22
+ #
23
+ # Broadcasts :ok if created, :invalid otherwise.
24
+ def call
25
+ return broadcast(:invalid) if form.invalid?
26
+
27
+ transaction do
28
+ update_content_block_settings
29
+ update_content_block_images
30
+ content_block.save!
31
+ end
32
+
33
+ broadcast(:ok)
34
+ end
35
+
36
+ private
37
+
38
+ def update_content_block_settings
39
+ content_block.settings = form.settings
40
+ end
41
+
42
+ def update_content_block_images
43
+ content_block.manifest.images.each do |image_config|
44
+ image_name = image_config[:name]
45
+
46
+ if form.images["remove_#{image_name}".to_sym]
47
+ content_block.images_container.send("remove_#{image_name}=", true)
48
+ elsif form.images[image_name]
49
+ content_block.images_container.send("#{image_name}=", form.images[image_name])
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -59,9 +59,6 @@ module Decidim
59
59
  cta_button_path: form.cta_button_path,
60
60
  cta_button_text: form.cta_button_text,
61
61
  description: form.description,
62
- welcome_text: form.welcome_text,
63
- homepage_image: form.homepage_image,
64
- remove_homepage_image: form.remove_homepage_image,
65
62
  logo: form.logo,
66
63
  remove_logo: form.remove_logo,
67
64
  favicon: form.favicon,
@@ -5,7 +5,11 @@ module Decidim
5
5
  # Controller that allows managing component permissions.
6
6
  #
7
7
  class ComponentPermissionsController < Decidim::Admin::ApplicationController
8
- helper_method :authorizations, :other_authorizations_for, :component
8
+ include Decidim::ComponentPathHelper
9
+
10
+ helper Decidim::ResourceHelper
11
+
12
+ helper_method :authorizations, :other_authorizations_for, :component, :resource_params, :resource
9
13
 
10
14
  def edit
11
15
  enforce_permission_to :update, :component, component: component
@@ -18,10 +22,10 @@ module Decidim
18
22
  enforce_permission_to :update, :component, component: component
19
23
  @permissions_form = PermissionsForm.from_params(params)
20
24
 
21
- UpdateComponentPermissions.call(@permissions_form, component) do
25
+ UpdateComponentPermissions.call(@permissions_form, component, resource) do
22
26
  on(:ok) do
23
27
  flash[:notice] = t("component_permissions.update.success", scope: "decidim.admin")
24
- redirect_to components_path(current_participatory_space)
28
+ redirect_to return_path
25
29
  end
26
30
 
27
31
  on(:invalid) do
@@ -32,8 +36,20 @@ module Decidim
32
36
 
33
37
  private
34
38
 
39
+ def return_path
40
+ if resource
41
+ manage_component_path(component)
42
+ else
43
+ components_path(current_participatory_space)
44
+ end
45
+ end
46
+
47
+ def resource_params
48
+ params.permit(:resource_id, :resource_name).to_h.symbolize_keys
49
+ end
50
+
35
51
  def permission_forms
36
- component.manifest.actions.inject({}) do |result, action|
52
+ actions.inject({}) do |result, action|
37
53
  form = PermissionForm.new(
38
54
  authorization_handler_name: authorization_for(action),
39
55
  options: permissions.dig(action, "options")
@@ -43,6 +59,10 @@ module Decidim
43
59
  end
44
60
  end
45
61
 
62
+ def actions
63
+ @actions ||= (resource&.resource_manifest || component.manifest).actions
64
+ end
65
+
46
66
  def authorizations
47
67
  Verifications::Adapter.from_collection(
48
68
  current_organization.available_authorizations
@@ -55,12 +75,19 @@ module Decidim
55
75
  )
56
76
  end
57
77
 
78
+ def resource
79
+ @resource ||= if params[:resource_id] && params[:resource_name]
80
+ res = Decidim.find_resource_manifest(params[:resource_name])&.resource_scope(component)&.find_by(id: params[:resource_id])
81
+ res if res&.allow_resource_permissions?
82
+ end
83
+ end
84
+
58
85
  def component
59
86
  @component ||= current_participatory_space.components.find(params[:component_id])
60
87
  end
61
88
 
62
89
  def permissions
63
- @permissions ||= component.permissions || {}
90
+ @permissions ||= (component.permissions || {}).merge(resource&.permissions || {})
64
91
  end
65
92
 
66
93
  def authorization_for(action)
@@ -15,6 +15,7 @@ module Decidim
15
15
  helper Decidim::ResourceHelper
16
16
  helper Decidim::Admin::ExportsHelper
17
17
  helper Decidim::Admin::BulkActionsHelper
18
+ helper Decidim::Admin::ResourcePermissionsHelper
18
19
 
19
20
  helper_method :current_component,
20
21
  :current_participatory_space,
@@ -53,7 +54,7 @@ module Decidim
53
54
  end
54
55
 
55
56
  def parent_path
56
- @parent_path ||= EngineRouter.admin_proxy(current_participatory_space).components_path
57
+ @parent_path ||= ::Decidim::EngineRouter.admin_proxy(current_participatory_space).components_path
57
58
  end
58
59
  end
59
60
  end
@@ -100,14 +100,6 @@ module Decidim
100
100
  raise NotImplementedError
101
101
  end
102
102
 
103
- # Public: The Class or Object to be used with the authorization layer to
104
- # verify the user can manage the attachment collection
105
- #
106
- # By default is the same as the collection_for.
107
- def authorization_object
108
- collection_for
109
- end
110
-
111
103
  def collection
112
104
  @collection ||= collection_for.attachment_collections
113
105
  end
@@ -13,7 +13,8 @@ module Decidim
13
13
  extend ActiveSupport::Concern
14
14
 
15
15
  included do
16
- helper_method :privatable_to, :authorization_object, :collection
16
+ helper PaginateHelper
17
+ helper_method :privatable_to, :collection
17
18
 
18
19
  def index
19
20
  enforce_permission_to :read, :space_private_user
@@ -84,16 +85,11 @@ module Decidim
84
85
  raise NotImplementedError
85
86
  end
86
87
 
87
- # Public: The Class or Object to be used with the authorization layer to
88
- # verify the user can manage the private users
89
- #
90
- # By default is the same as the privatable_to.
91
- def authorization_object
92
- privatable_to
93
- end
94
-
95
88
  def collection
96
- @collection ||= privatable_to.participatory_space_private_users
89
+ @collection ||= privatable_to
90
+ .participatory_space_private_users
91
+ .page(params[:page])
92
+ .per(20)
97
93
  end
98
94
  end
99
95
  end
@@ -80,6 +80,7 @@ module Decidim
80
80
  managed: true,
81
81
  name: params.dig(:impersonate_user, :name)
82
82
  ) do |u|
83
+ u.nickname = User.nicknamize(u.name, organization: current_organization)
83
84
  u.admin = false
84
85
  u.tos_agreement = true
85
86
  end
@@ -8,6 +8,7 @@ module Decidim
8
8
  layout "decidim/admin/users"
9
9
 
10
10
  helper_method :user
11
+ helper Decidim::Messaging::ConversationHelper
11
12
 
12
13
  def index
13
14
  enforce_permission_to :read, :officialization
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # Controller that allows managing the organization homepage content blocks
6
+ class OrganizationHomepageContentBlocksController < Decidim::Admin::ApplicationController
7
+ layout "decidim/admin/settings"
8
+
9
+ helper_method :content_block
10
+
11
+ def edit
12
+ enforce_permission_to :update, :organization, organization: current_organization
13
+ @form = form(ContentBlockForm).from_model(content_block)
14
+ end
15
+
16
+ def update
17
+ enforce_permission_to :update, :organization, organization: current_organization
18
+ @form = form(ContentBlockForm).from_params(params)
19
+
20
+ UpdateContentBlock.call(@form, content_block, :homepage) do
21
+ on(:ok) do
22
+ redirect_to edit_organization_homepage_path
23
+ end
24
+ on(:invalid) do
25
+ render :edit
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def content_block
33
+ @content_block ||= content_blocks.find_by(manifest_name: params[:id]) ||
34
+ content_block_from_manifest
35
+ end
36
+
37
+ def content_block_manifest
38
+ @content_block_manifest = unused_content_block_manifests.find { |manifest| manifest.name.to_s == params[:id] }
39
+ end
40
+
41
+ def content_blocks
42
+ @content_blocks ||= Decidim::ContentBlock.for_scope(:homepage, organization: current_organization)
43
+ end
44
+
45
+ def used_content_block_manifests
46
+ @used_content_block_manifests ||= content_blocks.map(&:manifest_name)
47
+ end
48
+
49
+ def unused_content_block_manifests
50
+ @unused_content_block_manifests ||= Decidim.content_blocks.for(:homepage).reject do |manifest|
51
+ used_content_block_manifests.include?(manifest.name.to_s)
52
+ end
53
+ end
54
+
55
+ def content_block_from_manifest
56
+ Decidim::ContentBlock.create!(
57
+ organization: current_organization,
58
+ scope: :homepage,
59
+ manifest_name: params[:id]
60
+ )
61
+ end
62
+ end
63
+ end
64
+ end