decidim-blogs 0.29.2 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/blogs/content_blocks/highlighted_posts_cell.rb +0 -3
  3. data/app/commands/decidim/blogs/create_post.rb +35 -0
  4. data/app/commands/decidim/blogs/update_post.rb +21 -0
  5. data/app/controllers/decidim/blogs/admin/posts_controller.rb +12 -9
  6. data/app/controllers/decidim/blogs/posts_controller.rb +61 -1
  7. data/app/forms/decidim/blogs/post_form.rb +52 -0
  8. data/app/helpers/decidim/blogs/posts_helper.rb +5 -0
  9. data/app/helpers/decidim/blogs/posts_select_helper.rb +32 -0
  10. data/app/models/decidim/blogs/post.rb +2 -1
  11. data/app/packs/stylesheets/blogs.scss +0 -20
  12. data/app/permissions/decidim/blog/permissions.rb +85 -2
  13. data/app/presenters/decidim/blogs/admin_log/post_presenter.rb +1 -1
  14. data/app/presenters/decidim/blogs/post_presenter.rb +25 -1
  15. data/app/views/decidim/blogs/admin/posts/_actions.html.erb +21 -0
  16. data/app/views/decidim/blogs/admin/posts/_post-tr.html.erb +25 -0
  17. data/app/views/decidim/blogs/admin/posts/_posts-thead.html.erb +9 -0
  18. data/app/views/decidim/blogs/admin/posts/index.html.erb +16 -55
  19. data/app/views/decidim/blogs/admin/posts/manage_trash.html.erb +20 -0
  20. data/app/views/decidim/blogs/posts/_actions.html.erb +7 -14
  21. data/app/views/decidim/blogs/posts/_form.html.erb +11 -0
  22. data/app/views/decidim/blogs/posts/_menu_actions.html.erb +21 -0
  23. data/app/views/decidim/blogs/posts/_schema_org_blog_posting_post.html.erb +3 -0
  24. data/app/views/decidim/blogs/posts/edit.html.erb +21 -0
  25. data/app/views/decidim/blogs/posts/index.html.erb +16 -1
  26. data/app/views/decidim/blogs/posts/new.html.erb +21 -0
  27. data/app/views/decidim/blogs/posts/show.html.erb +15 -6
  28. data/config/locales/ar.yml +0 -1
  29. data/config/locales/bg.yml +0 -3
  30. data/config/locales/ca.yml +58 -3
  31. data/config/locales/cs.yml +39 -4
  32. data/config/locales/de.yml +58 -3
  33. data/config/locales/el.yml +0 -3
  34. data/config/locales/en.yml +58 -3
  35. data/config/locales/es-MX.yml +58 -3
  36. data/config/locales/es-PY.yml +58 -3
  37. data/config/locales/es.yml +58 -3
  38. data/config/locales/eu.yml +58 -3
  39. data/config/locales/fi-plain.yml +39 -4
  40. data/config/locales/fi.yml +39 -4
  41. data/config/locales/fr-CA.yml +32 -2
  42. data/config/locales/fr.yml +32 -2
  43. data/config/locales/gl.yml +0 -1
  44. data/config/locales/hu.yml +0 -3
  45. data/config/locales/ja.yml +57 -2
  46. data/config/locales/kaa.yml +0 -1
  47. data/config/locales/ko.yml +0 -2
  48. data/config/locales/lt.yml +0 -3
  49. data/config/locales/nl.yml +0 -1
  50. data/config/locales/no.yml +0 -1
  51. data/config/locales/pl.yml +0 -3
  52. data/config/locales/pt-BR.yml +0 -3
  53. data/config/locales/ro-RO.yml +20 -1
  54. data/config/locales/ru.yml +0 -3
  55. data/config/locales/sq-AL.yml +0 -3
  56. data/config/locales/sv.yml +58 -3
  57. data/config/locales/zh-TW.yml +0 -3
  58. data/db/migrate/20200827153709_add_commentable_counter_cache_to_posts.rb +1 -1
  59. data/db/migrate/20210310120514_add_followable_counter_cache_to_blogs.rb +1 -1
  60. data/db/migrate/20240828103324_add_deleted_at_to_decidim_blogs_posts.rb +8 -0
  61. data/decidim-blogs.gemspec +1 -1
  62. data/lib/decidim/api/blogs_type.rb +4 -5
  63. data/lib/decidim/api/post_type.rb +2 -2
  64. data/lib/decidim/blogs/admin_engine.rb +7 -1
  65. data/lib/decidim/blogs/component.rb +27 -0
  66. data/lib/decidim/blogs/engine.rb +1 -1
  67. data/lib/decidim/blogs/post_serializer.rb +70 -0
  68. data/lib/decidim/blogs/schema_org_blog_posting_post_serializer.rb +81 -0
  69. data/lib/decidim/blogs/test/factories.rb +9 -0
  70. data/lib/decidim/blogs/version.rb +1 -1
  71. data/lib/decidim/blogs.rb +2 -0
  72. metadata +34 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f92b42d662b98c3a74dddec15a232ee1ca834c352ac5562c217275e6d3ce947
4
- data.tar.gz: 4bab2db6af3072e7c38da4558ef6ad33a0f3f1fa910c876d77141c7ce7c1aa45
3
+ metadata.gz: a0d2fde69ea47b9f6ff61d3125320b98a4fabde7e13c80a29f93d0e1e5b53bfd
4
+ data.tar.gz: f6569ec8db96e0e19d3c5006bfee928001b33986534555de4dc4f65c1a1b10f7
5
5
  SHA512:
6
- metadata.gz: 988f66c56ed71effe10777503a231b46bcb3cec74becb62d08a6cecaaf26f4e810b62a8264d27cd31108ebb07cedbd5e81021415a32b54cebc618a8d9ba94643
7
- data.tar.gz: 10efcb379fb47f8e72d282a96e7b4bdbc316d302521c793d417f65733d6ff467939010a22a2da6730dc27f8f17bf8cd1666b3d8468069c69d3a6c2d2b3602d0f
6
+ metadata.gz: 1c740209b1eb84e8bb7995034eee7abe4fdaad87bd908167fb3a4485fb71f5a75f28d0de4cc23b634c3520687bf70934ca1b1f08b499b1bf3c733994a965be7b
7
+ data.tar.gz: 070cd05f488c1dedf3c693678167158e97fecf9e5a2e9b25e326d284bb3ca612142cad01a59ea4c58a4dfdf853ddcfcd174e5e0aaaa888a1d02c1ec25608123b
@@ -4,9 +4,6 @@ module Decidim
4
4
  module Blogs
5
5
  module ContentBlocks
6
6
  class HighlightedPostsCell < Decidim::ContentBlocks::HighlightedElementsCell
7
- include Decidim::ComponentPathHelper
8
- include Decidim::CardHelper
9
-
10
7
  def show
11
8
  render unless posts_count.zero?
12
9
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # This command is executed when the user creates a Post from the frontend
6
+ class CreatePost < Decidim::Commands::CreateResource
7
+ fetch_form_attributes :author
8
+
9
+ private
10
+
11
+ def resource_class = Decidim::Blogs::Post
12
+
13
+ def run_after_hooks
14
+ send_notification
15
+ end
16
+
17
+ def attributes
18
+ super.merge(
19
+ title: { I18n.locale => form.title },
20
+ body: { I18n.locale => form.body },
21
+ component: form.current_component
22
+ )
23
+ end
24
+
25
+ def send_notification
26
+ Decidim::EventsManager.publish(
27
+ event: "decidim.events.blogs.post_created",
28
+ event_class: Decidim::Blogs::CreatePostEvent,
29
+ resource:,
30
+ followers: resource.participatory_space.followers
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # This command is executed when the user updates a Post from the frontend
6
+ class UpdatePost < Decidim::Commands::UpdateResource
7
+ fetch_form_attributes :title, :body
8
+
9
+ private
10
+
11
+ def resource_class = Decidim::Blogs::Post
12
+
13
+ def attributes
14
+ super.merge(
15
+ title: { I18n.locale => form.title },
16
+ body: { I18n.locale => form.body }
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,6 +5,8 @@ module Decidim
5
5
  module Admin
6
6
  # This controller allows the create or update a blog.
7
7
  class PostsController < Admin::ApplicationController
8
+ include Decidim::Admin::HasTrashableResources
9
+
8
10
  helper UserGroupHelper
9
11
  helper PostsHelper
10
12
 
@@ -52,18 +54,19 @@ module Decidim
52
54
  end
53
55
  end
54
56
 
55
- def destroy
56
- enforce_permission_to :destroy, :blogpost, blogpost: post
57
+ private
57
58
 
58
- Decidim::Commands::DestroyResource.call(post, current_user) do
59
- on(:ok) do
60
- flash[:notice] = I18n.t("posts.destroy.success", scope: "decidim.blogs.admin")
61
- redirect_to posts_path
62
- end
63
- end
59
+ def trashable_deleted_resource_type
60
+ :post
64
61
  end
65
62
 
66
- private
63
+ def trashable_deleted_resource
64
+ @trashable_deleted_resource ||= Blogs::Post.with_deleted.find_by(component: current_component, id: params[:id])
65
+ end
66
+
67
+ def trashable_deleted_collection
68
+ @trashable_deleted_collection ||= Post.where(component: current_component).only_deleted.deleted_at_desc.page(params[:page]).per(15)
69
+ end
67
70
 
68
71
  def post
69
72
  @post ||= Blogs::Post.find_by(component: current_component, id: params[:id])
@@ -8,6 +8,10 @@ module Decidim
8
8
  include Paginable
9
9
  include Decidim::IconHelper
10
10
 
11
+ helper Decidim::UserGroupHelper
12
+ helper Decidim::Blogs::PostsSelectHelper
13
+ include Decidim::FormFactory
14
+
11
15
  helper_method :posts, :post, :post_presenter, :paginate_posts, :posts_most_commented, :tabs, :panels
12
16
 
13
17
  def index; end
@@ -16,6 +20,62 @@ module Decidim
16
20
  raise ActionController::RoutingError, "Not Found" unless post
17
21
  end
18
22
 
23
+ def new
24
+ enforce_permission_to :create, :blogpost
25
+ @form = form(Decidim::Blogs::PostForm).instance
26
+ end
27
+
28
+ def create
29
+ enforce_permission_to :create, :blogpost
30
+ @form = form(Decidim::Blogs::PostForm).from_params(params, current_component: current_component)
31
+
32
+ CreatePost.call(@form) do
33
+ on(:ok) do |new_post|
34
+ flash[:notice] = I18n.t("posts.create.success", scope: "decidim.blogs.admin")
35
+ redirect_to post_path(new_post)
36
+ end
37
+
38
+ on(:invalid) do
39
+ flash.now[:alert] = I18n.t("posts.create.invalid", scope: "decidim.blogs.admin")
40
+ render action: "new"
41
+ end
42
+ end
43
+ end
44
+
45
+ def edit
46
+ enforce_permission_to :update, :blogpost, blogpost: post
47
+ @form = form(PostForm).from_model(post)
48
+ end
49
+
50
+ def update
51
+ enforce_permission_to :update, :blogpost, blogpost: post
52
+ @form = form(PostForm).from_params(params, current_component: current_component)
53
+
54
+ UpdatePost.call(@form, post) do
55
+ on(:ok) do |post|
56
+ flash[:notice] = I18n.t("posts.update.success", scope: "decidim.blogs.admin")
57
+ redirect_to post_path(post)
58
+ end
59
+
60
+ on(:invalid) do
61
+ flash.now[:alert] = I18n.t("posts.update.invalid", scope: "decidim.blogs.admin")
62
+ render action: "edit"
63
+ end
64
+ end
65
+ end
66
+
67
+ def destroy
68
+ enforce_permission_to :destroy, :blogpost, blogpost: post
69
+
70
+ Decidim.traceability.perform_action!("delete", post, current_user) do
71
+ post.destroy!
72
+ end
73
+
74
+ flash[:notice] = I18n.t("posts.destroy.success", scope: "decidim.blogs.admin")
75
+
76
+ redirect_to posts_path
77
+ end
78
+
19
79
  private
20
80
 
21
81
  def paginate_posts
@@ -27,7 +87,7 @@ module Decidim
27
87
  end
28
88
 
29
89
  def post_presenter
30
- @post_presenter ||= Decidim::Blogs::PostPresenter.new(post)
90
+ @post_presenter ||= PostPresenter.new(post)
31
91
  end
32
92
 
33
93
  def posts
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # This class holds a Form to update pages from Decidim's admin panel.
6
+ class PostForm < Decidim::Form
7
+ include TranslatableAttributes
8
+
9
+ translatable_attribute :title, String
10
+ translatable_attribute :body, Decidim::Attributes::RichText
11
+
12
+ attribute :decidim_author_id, Integer
13
+
14
+ validates :body, translatable_presence: true
15
+ validates :title, translatable_presence: true
16
+
17
+ validate :can_set_author
18
+
19
+ def map_model(model)
20
+ presenter = PostPresenter.new(model)
21
+
22
+ self.title = presenter.title
23
+ self.body = presenter.body
24
+ end
25
+
26
+ def author
27
+ @author ||= Decidim::UserBaseEntity.find_by(
28
+ organization: current_organization,
29
+ id: decidim_author_id
30
+ )
31
+ end
32
+
33
+ private
34
+
35
+ def can_set_author
36
+ return if author == current_user
37
+ return if user_groups.include? author
38
+ return if author == post&.author
39
+
40
+ errors.add(:decidim_author_id, :invalid)
41
+ end
42
+
43
+ def post
44
+ @post ||= Post.find_by(id: id)
45
+ end
46
+
47
+ def user_groups
48
+ @user_groups ||= Decidim::UserGroups::ManageableUserGroups.for(current_user).verified
49
+ end
50
+ end
51
+ end
52
+ end
@@ -18,6 +18,11 @@ module Decidim
18
18
  body = translated_attribute(post.body)
19
19
  CGI.unescapeHTML html_truncate(body, max_length:)
20
20
  end
21
+
22
+ def render_schema_org_blog_posting_post(post)
23
+ exported_post = Decidim::Exporters::JSON.new([post], SchemaOrgBlogPostingPostSerializer).export.read
24
+ JSON.pretty_generate(JSON.parse(exported_post).first)
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # Custom helpers used in posts views
6
+ module PostsSelectHelper
7
+ include Decidim::ApplicationHelper
8
+ include SanitizeHelper
9
+
10
+ def fo_post_author_select_field(form, name, _options = {})
11
+ select_options = [
12
+ [current_user.name, current_user.id]
13
+ ]
14
+
15
+ select_options += user_groups
16
+ select_options << [form.object.author.name, form.object.author.id] unless !form.object.author || select_options.pluck(1).include?(form.object.author.id)
17
+
18
+ return form.select(name, select_options) if select_options.size > 1
19
+
20
+ form.hidden_field(name, value: select_options.first[1])
21
+ end
22
+
23
+ private
24
+
25
+ def user_groups
26
+ return [] unless current_organization.user_groups_enabled?
27
+
28
+ Decidim::UserGroups::ManageableUserGroups.for(current_user).verified.map { |user_g| [user_g.name, user_g.id] }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -18,6 +18,7 @@ module Decidim
18
18
  include Decidim::TranslatableResource
19
19
  include Traceable
20
20
  include Loggable
21
+ include Decidim::SoftDeletable
21
22
 
22
23
  component_manifest_name "blogs"
23
24
 
@@ -26,7 +27,7 @@ module Decidim
26
27
  validates :title, presence: true
27
28
 
28
29
  scope :created_at_desc, -> { order(arel_table[:created_at].desc) }
29
- scope :published, -> { where("published_at <= ?", Time.current) }
30
+ scope :published, -> { where(published_at: ..Time.current) }
30
31
 
31
32
  searchable_fields({
32
33
  participatory_space: { component: :participatory_space },
@@ -7,26 +7,6 @@
7
7
  }
8
8
  }
9
9
 
10
- &__actions {
11
- @apply flex flex-col md:flex-row justify-between items-center gap-10 pt-10;
12
-
13
- &-left {
14
- @apply flex items-center gap-2;
15
- }
16
-
17
- &-right {
18
- @apply flex items-center gap-4;
19
-
20
- button {
21
- @apply flex items-center gap-1;
22
- }
23
- }
24
-
25
- .is-active span:last-child {
26
- @apply text-white bg-secondary border-secondary;
27
- }
28
- }
29
-
30
10
  &__endorsers {
31
11
  @apply space-y-3;
32
12
 
@@ -4,18 +4,101 @@ module Decidim
4
4
  module Blog
5
5
  class Permissions < Decidim::DefaultPermissions
6
6
  def permissions
7
- return permission_action unless permission_action.subject == :blogpost
7
+ return permission_action unless permission_action.subject == :blogpost || permission_action.subject == :post
8
8
 
9
9
  if permission_action.scope == :public
10
+ if permission_action.action.in?([:update, :destroy])
11
+ toggle_allow(can_manage_post)
12
+ return permission_action
13
+ end
14
+
15
+ if permission_action.action == :create
16
+ toggle_allow(can_create_post)
17
+ return permission_action
18
+ end
19
+
10
20
  allow!
11
21
  return permission_action
12
22
  end
13
23
 
14
- return permission_action if permission_action.scope != :admin
24
+ return permission_action unless permission_action.scope == :admin
25
+
26
+ if permission_action.action.in?([:update, :destroy])
27
+ toggle_allow(admin_can_manage_post)
28
+ return permission_action
29
+ end
15
30
 
16
31
  allow!
17
32
  permission_action
18
33
  end
34
+
35
+ def post
36
+ @post ||= context.fetch(:blogpost, nil)
37
+ end
38
+
39
+ def current_component
40
+ @current_component ||= context.fetch(:current_component, nil)
41
+ end
42
+
43
+ def can_create_post
44
+ current_component&.participatory_space&.published? &&
45
+ current_component&.published? &&
46
+ (creation_enabled_for_participants? || initiative_authorship?)
47
+ end
48
+
49
+ def can_manage_post
50
+ return false unless post&.author
51
+
52
+ can_create_post && post&.author == user
53
+ end
54
+
55
+ def admin_can_manage_post
56
+ return false unless post&.author
57
+
58
+ case post.author
59
+ when Decidim::User
60
+ post.author == user
61
+ when Decidim::UserGroup
62
+ post.author.users.include?(user)
63
+ when Decidim::Organization
64
+ space_admin?
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ def space_admin?
71
+ space_admins.include?(user)
72
+ end
73
+
74
+ def creation_enabled_for_participants?
75
+ component_settings&.creation_enabled_for_participants? &&
76
+ current_component&.participatory_space&.can_participate?(user)
77
+ end
78
+
79
+ def space_admins
80
+ participatory_space = current_component&.participatory_space
81
+
82
+ return [] unless participatory_space
83
+
84
+ @space_admins ||= begin
85
+ space_admins = if participatory_space.respond_to?(:user_roles)
86
+ participatory_space.user_roles(:admin)&.collect(&:user)
87
+ else
88
+ []
89
+ end
90
+ global_admins = current_component.organization.admins
91
+ (global_admins + space_admins).uniq
92
+ end
93
+ end
94
+
95
+ def initiative_authorship?
96
+ return false unless user
97
+
98
+ Decidim.module_installed?("initiatives") &&
99
+ current_component&.participatory_space.is_a?(Decidim::Initiative) &&
100
+ current_component&.participatory_space&.has_authorship?(user)
101
+ end
19
102
  end
20
103
  end
21
104
  end
@@ -17,7 +17,7 @@ module Decidim
17
17
 
18
18
  def action_string
19
19
  case action
20
- when "create", "delete", "update"
20
+ when "create", "delete", "update", "soft_delete", "restore"
21
21
  "decidim.blogs.admin_log.post.#{action}"
22
22
  else
23
23
  super
@@ -5,7 +5,11 @@ module Decidim
5
5
  #
6
6
  # Decorator for posts
7
7
  #
8
- class PostPresenter < SimpleDelegator
8
+ class PostPresenter < Decidim::ResourcePresenter
9
+ include Decidim::ResourceHelper
10
+ include ActionView::Helpers::UrlHelper
11
+ include Decidim::SanitizeHelper
12
+
9
13
  def author
10
14
  @author ||= if official?
11
15
  Decidim::Blogs::OfficialAuthorPresenter.new
@@ -15,6 +19,26 @@ module Decidim
15
19
  Decidim::UserPresenter.new(super)
16
20
  end
17
21
  end
22
+
23
+ def post
24
+ __getobj__
25
+ end
26
+
27
+ def post_path
28
+ Decidim::ResourceLocatorPresenter.new(post).path
29
+ end
30
+
31
+ def title(links: false, html_escape: false, all_locales: false)
32
+ return unless post
33
+
34
+ super(post.title, links, html_escape, all_locales)
35
+ end
36
+
37
+ def body(links: false, extras: true, strip_tags: false, all_locales: false)
38
+ return unless post
39
+
40
+ content_handle_locale(post.body, all_locales, extras, links, strip_tags)
41
+ end
18
42
  end
19
43
  end
20
44
  end
@@ -0,0 +1,21 @@
1
+ <% if view == :deleted %>
2
+ <% if allowed_to? :restore, :blogpost, trashable_deleted_resource: post %>
3
+ <%= icon_link_to "refresh-line", url_for(action: :restore, id: post, controller: "posts"), t("decidim.admin.actions.restore"), method: :patch, class: "action-icon--restore" %>
4
+ <% end %>
5
+ <% else %>
6
+ <% if allowed_to? :update, :blogpost, blogpost: post %>
7
+ <%= icon_link_to "pencil-line", edit_post_path(post), t("actions.edit", scope: "decidim.blogs"), class: "action-icon--edit" %>
8
+ <%= icon_link_to "folder-line", post_attachment_collections_path(post), t("actions.attachment_collections", scope: "decidim.meetings"), class: "action-icon--attachment_collections" %>
9
+ <%= icon_link_to "attachment-line", post_attachments_path(post), t("actions.attachments", scope: "decidim.meetings"), class: "action-icon--attachments" %>
10
+ <% end %>
11
+
12
+ <%= icon_link_to "eye-line", resource_locator(post).path, t("actions.preview", scope: "decidim.admin"), class: "action-icon--preview", target: :blank, data: { "external-link": false } %>
13
+
14
+ <%= resource_permissions_link(post) %>
15
+
16
+ <% if allowed_to? :soft_delete, :blogpost, trashable_deleted_resource: post %>
17
+ <%= icon_link_to "delete-bin-line", soft_delete_post_path(post), t("actions.soft_delete", scope: "decidim.admin"), method: :patch, class: "action-icon--delete", data: { confirm: t("actions.confirm_delete_post", scope: "decidim.blogs") } %>
18
+ <% else %>
19
+ <%= icon "delete-bin-line", class: "action-icon action-icon--disabled", role: "img", aria_label: t("actions.soft_delete", scope: "decidim.admin") %>
20
+ <% end %>
21
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <tr data-id="<%= post.id %>">
2
+ <td>
3
+ <% if allowed_to? :update, :blogpost, blogpost: post %>
4
+ <%= link_to translated_attribute(post.title), edit_post_path(post) %><br>
5
+ <% else %>
6
+ <%= translated_attribute(post.title) %><br>
7
+ <% end %>
8
+ </td>
9
+ <td>
10
+ <%= decidim_sanitize_editor post_description_admin(post) %>
11
+ </td>
12
+ <td>
13
+ <%= translated_attribute(post.try(:author).try(:name)) %>
14
+ </td>
15
+ <% publish_data = publish_data(post.published_at) %>
16
+ <td>
17
+ <%= content_tag :span, class: "padding-3", data: { tooltip: true, disable_hover: false, click_open: false }, title: publish_data[:popup] do
18
+ publish_data[:icon]
19
+ end %>
20
+ <%= l post.published_at, format: :decidim_short %>
21
+ </td>
22
+ <td class="table-list__actions">
23
+ <%= render partial: "decidim/blogs/admin/posts/actions", locals: { post:, view: } %>
24
+ </td>
25
+ </tr>
@@ -0,0 +1,9 @@
1
+ <thead>
2
+ <tr>
3
+ <th><%= t("models.post.fields.title", scope: "decidim.blogs") %></th>
4
+ <th><%= t("models.post.fields.body", scope: "decidim.blogs") %></th>
5
+ <th><%= t("models.post.fields.author", scope: "decidim.blogs") %></th>
6
+ <th><%= t("models.post.fields.published_at", scope: "decidim.blogs") %></th>
7
+ <th><%= t("actions.title", scope: "decidim.blogs") %></th>
8
+ </tr>
9
+ </thead>
@@ -9,64 +9,25 @@
9
9
  </div>
10
10
  <div class="table-scroll">
11
11
  <table class="table-list">
12
- <thead>
13
- <tr>
14
- <th><%= t("models.post.fields.title", scope: "decidim.blogs") %></th>
15
- <th><%= t("models.post.fields.body", scope: "decidim.blogs") %></th>
16
- <th><%= t("models.post.fields.author", scope: "decidim.blogs") %></th>
17
- <th><%= t("models.post.fields.published_at", scope: "decidim.blogs") %></th>
18
- <th><%= t("actions.title", scope: "decidim.blogs") %></th>
19
- </tr>
20
- </thead>
12
+ <%= render partial: "posts-thead" %>
21
13
  <tbody>
22
- <% posts.created_at_desc.each do |post| %>
23
-
24
- <tr data-id="<%= post.id %>">
25
- <td>
26
- <% if allowed_to? :update, :blogpost, blog_post: post %>
27
- <%= link_to translated_attribute(post.title), edit_post_path(post) %><br>
28
- <% else %>
29
- <%= translated_attribute(post.title) %><br>
30
- <% end %>
31
- </td>
32
- <td>
33
- <%= decidim_sanitize_editor post_description_admin(post) %>
34
- </td>
35
- <td>
36
- <%= translated_attribute(post.try(:author).try(:name)) %>
37
- </td>
38
- <% publish_data = publish_data(post.published_at) %>
39
- <td>
40
- <%= content_tag :span, class: "padding-3", data: { tooltip: true, disable_hover: false, click_open: false }, title: publish_data[:popup] do
41
- publish_data[:icon]
42
- end %>
43
- <%= l post.published_at, format: :decidim_short %>
44
- </td>
45
- <td class="table-list__actions">
46
- <% if allowed_to? :update, :blogpost, blog_post: post %>
47
- <%= icon_link_to "pencil-line", edit_post_path(post), t("actions.edit", scope: "decidim.blogs"), class: "action-icon--edit" %>
48
- <% end %>
49
-
50
- <% if allowed_to? :update, :blogpost, blog_post: post %>
51
- <%= icon_link_to "folder-line", post_attachment_collections_path(post), t("actions.attachment_collections", scope: "decidim.meetings"), class: "action-icon--attachment_collections" %>
52
- <% end %>
53
-
54
- <% if allowed_to? :update, :blogpost, blog_post: post %>
55
- <%= icon_link_to "attachment-line", post_attachments_path(post), t("actions.attachments", scope: "decidim.meetings"), class: "action-icon--attachments" %>
56
- <% end %>
57
-
58
- <%= icon_link_to "eye-line", resource_locator(post).path, t("actions.preview", scope: "decidim.admin"), class: "action-icon--preview", target: :blank, data: { "external-link": false } %>
59
-
60
- <%= resource_permissions_link(post) %>
61
-
62
- <% if allowed_to? :destroy, :blogpost, blog_post: post %>
63
- <%= icon_link_to "delete-bin-line", post_path(post), t("actions.destroy", scope: "decidim.blogs"), method: :delete, class: "action-icon--remove", data: { confirm: t("actions.confirm_destroy", scope: "decidim.blogs") } %>
64
- <% end %>
65
- </td>
66
- </tr>
67
- <% end %>
14
+ <%= render partial: "decidim/blogs/admin/posts/post-tr",
15
+ collection: posts,
16
+ as: :post,
17
+ locals: { view: :index } %>
68
18
  </tbody>
69
19
  </table>
70
20
  </div>
21
+ <% if allowed_to? :manage_trash, :post, participatory_space: current_participatory_space %>
22
+ <div class="card mt-4">
23
+ <%= link_to manage_trash_posts_path, class: "flex items-center underline text-secondary" do %>
24
+ <%= icon "delete-bin-2-line", class: "mr-2 fill-current text-secondary", role: "img" %>
25
+ <%= t("actions.view_deleted_posts", scope: "decidim.blogs") %>
26
+ <span class="ml-2">
27
+ <%= icon_with_tooltip("information-line", t("actions.deleted_posts_info", scope: "decidim.blogs")) %>
28
+ </span>
29
+ <% end %>
30
+ </div>
31
+ <% end %>
71
32
  </div>
72
33
  <%= decidim_paginate posts %>
@@ -0,0 +1,20 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="card">
3
+ <div class="item_show__header">
4
+ <h1 class="item_show__header-title">
5
+ <%= t(".title") %>
6
+ </h1>
7
+ </div>
8
+ <div class="table-scroll">
9
+ <table class="table-list">
10
+ <%= render partial: "posts-thead" %>
11
+ <tbody>
12
+ <%= render partial: "decidim/blogs/admin/posts/post-tr",
13
+ collection: trashable_deleted_collection,
14
+ as: :post,
15
+ locals: { view: :deleted } %>
16
+ </tbody>
17
+ </table>
18
+ </div>
19
+ </div>
20
+ <%= decidim_paginate trashable_deleted_collection %>