diff --git a/app/controllers/admin_posts_controller.rb b/app/controllers/admin_posts_controller.rb index 426c71b3d3e..092b876a56e 100644 --- a/app/controllers/admin_posts_controller.rb +++ b/app/controllers/admin_posts_controller.rb @@ -1,37 +1,37 @@ class AdminPostsController < Admin::BaseController - before_action :admin_only, except: [:index, :show] before_action :load_languages, except: [:show, :destroy] + before_action :load_admin_posts, only: [:index, :drafts] # GET /admin_posts def index - if params[:tag] - @tag = AdminPostTag.find_by(id: params[:tag]) - if @tag - @admin_posts = @tag.admin_posts - end - end - @admin_posts ||= AdminPost - if params[:language_id].present? && (@language = Language.find_by(short: params[:language_id])) - @admin_posts = @admin_posts.where(language_id: @language.id) - @tags = AdminPostTag.distinct.joins(:admin_posts).where(admin_posts: { language_id: @language.id }).order(:name) - else - @admin_posts = @admin_posts.non_translated - @tags = AdminPostTag.order(:name) - end - @admin_posts = @admin_posts.order('created_at DESC').page(params[:page]) + @page_subtitle = t(".page_title") + @pagy, @admin_posts = pagy(@admin_posts.posted.order(published_at: :desc)) + end + + # GET /admin_posts/drafts + def drafts + authorize AdminPost + + @page_subtitle = t(".page_title") + @pagy, @admin_posts = pagy(@admin_posts.unposted.order(created_at: :desc)) end # GET /admin_posts/1 def show + @admin_post = AdminPost.find(params[:id]) + authorize(@admin_post) unless @admin_post.posted? + admin_posts = AdminPost.non_translated - @admin_post = AdminPost.find_by(id: params[:id]) - unless @admin_post - raise ActiveRecord::RecordNotFound, "Couldn't find admin post '#{params[:id]}'" + if @admin_post.posted? + @admin_posts = admin_posts.posted.order(published_at: :desc).limit(8) + @previous_admin_post = admin_posts.posted.order(published_at: :desc).where("published_at < ?", @admin_post.published_at).first + @next_admin_post = admin_posts.posted.order(published_at: :asc).where("published_at > ?", @admin_post.published_at).first + else + @admin_posts = admin_posts.unposted.order(created_at: :desc).limit(8) + @previous_admin_post = admin_posts.unposted.order(created_at: :desc).where("created_at < ?", @admin_post.created_at).first + @next_admin_post = admin_posts.unposted.order(created_at: :asc).where("created_at > ?", @admin_post.created_at).first end - @admin_posts = admin_posts.order('created_at DESC').limit(8) - @previous_admin_post = admin_posts.order('created_at DESC').where('created_at < ?', @admin_post.created_at).first - @next_admin_post = admin_posts.order('created_at ASC').where('created_at > ?', @admin_post.created_at).first @page_subtitle = @admin_post.title.html_safe respond_to do |format| format.html # show.html.erb @@ -39,6 +39,13 @@ def show end end + # GET /admin_posts/1/preview + def preview + @preview_mode = true + @admin_post = AdminPost.find(params[:id]) + authorize(@admin_post) + end + # GET /admin_posts/new # GET /admin_posts/new.xml def new @@ -55,24 +62,55 @@ def edit # POST /admin_posts def create @admin_post = AdminPost.new(admin_post_params) + @admin_post.posted = true if params[:post_button] && !@admin_post&.translated_post&.draft? + authorize @admin_post - if @admin_post.save - flash[:notice] = ts("Admin Post was successfully created.") - redirect_to(@admin_post) - else - render action: "new" + if !params[:edit_button] && @admin_post.valid? + if params[:preview_button] + @preview_mode = true + render action: "preview" and return + elsif !params[:edit_button] && @admin_post.save + flash[:notice] = t(".success") + redirect_to(admin_post_path(@admin_post)) and return + end end + + render action: "new" end # PUT /admin_posts/1 def update + @admin_post = AdminPost.find(params[:id]) + @admin_post.attributes = admin_post_params + @admin_post.posted = true if params[:post_button] && !@admin_post&.translated_post&.draft? + authorize @admin_post + + if !params[:edit_button] && @admin_post.valid? + if params[:preview_button] + @preview_mode = true + render :preview and return + elsif @admin_post.save + flash[:notice] = t(".success") + redirect_to(@admin_post) and return + end + end + + render action: "edit" + end + + # PUT /admin_posts/1/post + def post @admin_post = AdminPost.find(params[:id]) authorize @admin_post - if @admin_post.update(admin_post_params) - flash[:notice] = ts("Admin Post was successfully updated.") - redirect_to(@admin_post) + + @admin_post.posted = true + + if @admin_post.save + flash[:notice] = t(".success") + redirect_to @admin_post else - render action: "edit" + flash[:error] = t(".error") + redirect_to(edit_admin_post_path(@admin_post)) end end @@ -81,7 +119,8 @@ def destroy @admin_post = AdminPost.find(params[:id]) authorize @admin_post @admin_post.destroy - redirect_to(admin_posts_path) + + redirect_to(@admin_post.posted? ? admin_posts_path : drafts_admin_posts_path) end protected @@ -90,6 +129,19 @@ def load_languages @news_languages = Language.where(id: Locale.all.map(&:language_id)).default_order end + def load_admin_posts + @tag = AdminPostTag.find_by(id: params[:tag]) if params[:tag] + @admin_posts = @tag&.admin_posts || AdminPost + + if params[:language_id].present? && (@language = Language.find_by(short: params[:language_id])) + @admin_posts = @admin_posts.where(language_id: @language.id) + @tags = AdminPostTag.distinct.joins(:admin_posts).where(admin_posts: { language_id: @language.id }).order(:name) + else + @admin_posts = @admin_posts.non_translated + @tags = AdminPostTag.order(:name) + end + end + private def admin_post_params diff --git a/app/helpers/admin_post_helper.rb b/app/helpers/admin_post_helper.rb index e167de609f7..94e30b2c5d5 100644 --- a/app/helpers/admin_post_helper.rb +++ b/app/helpers/admin_post_helper.rb @@ -1,6 +1,9 @@ module AdminPostHelper def sorted_translations(admin_post) - admin_post.translations.sort_by do |translation| + translations = admin_post.translations + translations = translations.posted if admin_post.posted? + + translations.sort_by do |translation| language = translation.language language.sortable_name.blank? ? language.short : language.sortable_name end diff --git a/app/models/admin_post.rb b/app/models/admin_post.rb index 47ed4a87587..e2910cb5203 100644 --- a/app/models/admin_post.rb +++ b/app/models/admin_post.rb @@ -33,19 +33,26 @@ class AdminPost < ApplicationRecord validate :translated_post_must_exist validate :translated_post_language_must_differ + validate :translated_post_must_be_posted_first scope :non_translated, -> { where("translated_post_id IS NULL") } - scope :for_homepage, -> { order("created_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) } + scope :for_homepage, -> { posted.order(published_at: :desc).limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) } + + scope :unposted, -> { where(posted: false) } + scope :posted, -> { where(posted: true) } before_save :inherit_translated_post_comment_permissions, :inherit_translated_post_tags - after_save :expire_cached_home_admin_posts, :update_translation_comment_permissions, :update_translation_tags + before_save :set_published_at, if: :posted_changed? after_destroy :expire_cached_home_admin_posts + after_save :expire_cached_home_admin_posts, :update_translation_comment_permissions, :update_translation_tags + after_save :post_translations, if: :saved_change_to_posted? # Return the name to link comments to for this object def commentable_name self.title end + def commentable_owners begin [Admin.find(self.admin_id)] @@ -54,6 +61,10 @@ def commentable_owners end end + def draft? + !self.posted? + end + def tag_list tags.map{ |t| t.name }.join(", ") end @@ -75,10 +86,16 @@ def translated_post_must_exist def translated_post_language_must_differ return if translated_post.blank? return unless translated_post.language == language - + errors.add(:translated_post_id, "cannot be same language as original post") end + def translated_post_must_be_posted_first + return if translated_post.blank? + + errors.add(:translated_post_id, :must_be_posted_first) if translated_post.draft? && self.posted? + end + #################### # DELAYED JOBS #################### @@ -137,4 +154,18 @@ def update_translation_tags end end end + + def set_published_at + self.published_at = Time.current if self.posted && !self.published_at + end + + def post_translations + return if translations.blank? || !self.posted + + transaction do + translations.find_each do |post| + post.update(posted: true, published_at: self.published_at) + end + end + end end diff --git a/app/policies/admin_post_policy.rb b/app/policies/admin_post_policy.rb index 957e1c46e53..97f5a46ad88 100644 --- a/app/policies/admin_post_policy.rb +++ b/app/policies/admin_post_policy.rb @@ -1,13 +1,25 @@ class AdminPostPolicy < ApplicationPolicy POSTING_ROLES = %w[superadmin board board_assistants_team communications support translation].freeze + DRAFTING_ROLES = %w[policy_and_abuse].freeze def can_post? user_has_roles?(POSTING_ROLES) end - alias new? can_post? - alias edit? can_post? - alias create? can_post? - alias update? can_post? - alias destroy? can_post? + def can_draft? + user_has_roles?(DRAFTING_ROLES) || can_post? + end + + def edit? + can_post? || (@record&.draft? && can_draft?) + end + + alias new? can_draft? + alias show? can_draft? + alias create? edit? + alias update? edit? + alias destroy? edit? + alias post? can_post? + alias drafts? can_draft? + alias preview? edit? end diff --git a/app/views/admin/_admin_nav.html.erb b/app/views/admin/_admin_nav.html.erb index e705ea49bb8..7475c61cc40 100644 --- a/app/views/admin/_admin_nav.html.erb +++ b/app/views/admin/_admin_nav.html.erb @@ -3,10 +3,19 @@
  • <%= span_if_current t(".ao3_news"), admin_posts_path %>
  • + <% if policy(AdminPost).can_draft? %> +
  • + <%= span_if_current t(".ao3_news_drafts"), drafts_admin_posts_path %> +
  • + <% end %> <% if policy(AdminPost).can_post? %>
  • <%= span_if_current t(".post_ao3_news"), new_admin_post_path %>
  • + <% elsif policy(AdminPost).can_draft? %> +
  • + <%= span_if_current t(".draft_ao3_news"), new_admin_post_path %> +
  • <% end %> <% if params[:controller] == "admin_posts" && params[:action] == "edit" %>
  • diff --git a/app/views/admin/_header.html.erb b/app/views/admin/_header.html.erb index 7fdbb92101b..8c4e3fc15d5 100644 --- a/app/views/admin/_header.html.erb +++ b/app/views/admin/_header.html.erb @@ -26,8 +26,13 @@ <%= link_to t(".nav.posts.admin_posts"), admin_posts_path %>