Skip to content
This repository has been archived by the owner on Mar 27, 2023. It is now read-only.

Commit

Permalink
Add ability to archive pages (#588)
Browse files Browse the repository at this point in the history
* Add ability to archive pages

* Refactored Page#active boolean flag to be a Page#publish_status,
which is an enum with 3 possible statuses.

* Add ability to archive and unarchive pages.

* Add ability to search pages filtering by `publish_status

* Add confirm pop-up to archive link

* Use new enum on page service class
  • Loading branch information
rodrei authored and osahyoun committed Jul 25, 2016
1 parent 7b68dbc commit 679f1b4
Show file tree
Hide file tree
Showing 36 changed files with 298 additions and 164 deletions.
6 changes: 3 additions & 3 deletions app/assets/javascripts/plugins_toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ const setupOnce = require('setup_once');
initialize: function(){
this.$stateInput = this.$('.activation-toggle-field');
this.$checkbox = this.$('.onoffswitch__checkbox');
this.state = JSON.parse(this.$stateInput.val());
this.state = this.$stateInput.val();
},

handleClick: function(e){
if (this.state == true && this.$stateInput.data('confirm-turning-off')){
if (this.state == 'published' && this.$stateInput.data('confirm-turning-off')){
if (!window.confirm(this.$stateInput.data('confirm-turning-off'))) {
this.toggleButton();
return false;
Expand All @@ -40,7 +40,7 @@ const setupOnce = require('setup_once');
},

toggleState: function(){
this.state = !this.state;
this.state = this.state === 'published' ? 'unpublished' : 'published';
this.$stateInput.val(this.state);
},
});
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/page_archives_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class PageArchivesController < ApplicationController
before_action :authenticate_user!
def create
@page = Page.find(params[:page_id])
@page.archived!
redirect_to pages_path, notice: 'Page was successfully archived.'
end

def destroy
@page = Page.find(params[:page_id])
@page.unpublished!
redirect_to pages_path, notice: 'Page was successfully unarchived.'
end
end
14 changes: 10 additions & 4 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ class PagesController < ApplicationController
before_action :get_page_or_homepage, only: [:show]

def index
# Filter the desired pages by search parameters, and sort them descending by their date of update.
@pages = Search::PageSearcher.new(params).search.sort_by(&:updated_at).reverse!
@search_params = params[:search].present? ? params[:search] : {}
@search_params = search_params
@pages = Search::PageSearcher.new(@search_params).search.sort_by(&:updated_at).reverse!
end

def analytics
Expand Down Expand Up @@ -59,7 +58,7 @@ def update
private

def render_liquid(layout, view)
return redirect_to(Settings.homepage_url) unless @page.active? || user_signed_in?
return redirect_to(Settings.homepage_url) unless @page.published? || user_signed_in?
localize_by_page_language(@page)

@rendered = renderer(layout).render
Expand Down Expand Up @@ -105,5 +104,12 @@ def page_params
:follow_up_liquid_layout_id,
{:tag_ids => []} )
end

def search_params
default_params = { publish_status: Page.publish_statuses.values_at(:published, :unpublished) }
params[:search] ||= {}
params[:search].reverse_merge default_params
end

end

8 changes: 8 additions & 0 deletions app/helpers/pages_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,12 @@ def share_card(page)
image: Image.find_by(id: share.image_id).try(:content).try(:url)
}
end

def archive_confirm_message(page)
msg = "Are you sure you want to archive this page?"
if page.published?
msg += " It will also be unpublished making it inaccessible except to logged-in campaigners."
end
msg
end
end
3 changes: 2 additions & 1 deletion app/models/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class Page < ActiveRecord::Base
has_paper_trail

enum follow_up_plan: [:with_liquid, :with_page] # todo - :with_link
enum publish_status: [:published, :unpublished, :archived]

belongs_to :language
belongs_to :campaign # Note that some pages do not necessarily belong to campaigns
Expand All @@ -18,11 +19,11 @@ class Page < ActiveRecord::Base
has_many :links, dependent: :destroy

scope :language, -> (code) { code ? joins(:language).where(languages: { code: code }) : all }
scope :published, -> { where(active: true) }
scope :featured, -> { where(featured: true) }

validates :title, presence: true
validates :liquid_layout, presence: true
validates :publish_status, presence: true
validate :primary_image_is_owned

after_save :switch_plugins
Expand Down
8 changes: 7 additions & 1 deletion app/services/search/page_searcher.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Search::PageSearcher

def initialize(params)
@queries = params[:search]
@queries = params
@collection = Page.all
end

Expand All @@ -23,6 +23,8 @@ def search
search_by_campaign(query)
when 'plugin_type'
search_by_plugin_type(query)
when 'publish_status'
search_by_publish_status(query)
when 'order_by'
order_by(query)
end
Expand Down Expand Up @@ -109,6 +111,10 @@ def search_by_plugin_type(query)
@collection = @collection.where(id: matches_by_plugins)
end

def search_by_publish_status(query)
@collection = @collection.where(publish_status: query)
end

def order_by(query)
if validate_order_by(query)
if query.is_a? Array
Expand Down
2 changes: 1 addition & 1 deletion app/views/api/pages/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
json.array! @pages do |page|
json.extract! page, :id, :title, :slug, :content, :created_at, :updated_at, :active, :featured, :action_count
json.extract! page, :id, :title, :slug, :content, :created_at, :updated_at, :publish_status, :featured, :action_count
json.language page.language.code
end
4 changes: 2 additions & 2 deletions app/views/api/pages/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
json.extract! @page, :id, :title, :slug, :content, :created_at, :updated_at, :active, :featured, :action_count
json.language @page.language.code
json.extract! @page, :id, :title, :slug, :content, :created_at, :updated_at, :publish_status, :featured, :action_count
json.language @page.language.code
4 changes: 2 additions & 2 deletions app/views/pages/_campaigner_overlay.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- if user_signed_in? && page.present?
.campaigner-overlay.mobile-hide class="#{page.active? ? 'campaigner-overlay--active' : 'campaigner-overlay--inactive'}" data-status="#{page.active? ? 'active' : 'inactive'}"
.campaigner-overlay.mobile-hide class="#{page.published? ? 'campaigner-overlay--active' : 'campaigner-overlay--inactive'}" data-status="#{page.published? ? 'active' : 'inactive'}"
.campaigner-overlay__close.fa.fa-close
.campaigner-overlay__status.campaigner-overlay__info--active
| Published
Expand All @@ -13,7 +13,7 @@
= form_for page, url: api_page_path(page), remote: true do |ff|
/ we have nested page[page][active] to match the massive nested form submitted with the one-form
= ff.fields_for :page do |f|
= f.hidden_field :active, class: 'campaigner-overlay__publish-field', value: !page.active?
= f.hidden_field :publish_status, class: 'campaigner-overlay__publish-field', value: page.published? ? "unpublished" : "published"
= f.submit "Publish", class: 'campaigner-overlay__toggle-publish campaigner-overlay__info--inactive'
= f.submit "Unpublish", class: 'campaigner-overlay__toggle-publish campaigner-overlay__info--active', 'data-confirm' => "Are you sure you want to unpublish this page? It will become inaccessible except to logged-in campaigners."
= link_to 'Edit', edit_page_path(page), class: 'campaigner-overlay__edit-link'
Expand Down
8 changes: 4 additions & 4 deletions app/views/pages/_edit_sidebar.slim
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
.page-edit-bar__save-box
.page-edit-bar__toggle
.page-edit-bar__toggle-title Autosave
.page-edit-bar__toggle-btns.page-edit-bar__toggle-autosave data-autosave="#{!page.active?}"
= render 'shared/binary_switch', checked: !page.active?
.page-edit-bar__toggle-btns.page-edit-bar__toggle-autosave data-autosave="#{!page.published?}"
= render 'shared/binary_switch', checked: !page.published?
.page-edit-bar__toggle
= form_for page, url: api_page_path(page), remote: true, html: {class: 'activation-toggle'} do |ff|
/ we have nested page[page][active] to match the massive nested form submitted with the one-form
= ff.fields_for :page do |f|
= f.hidden_field :active, class: 'activation-toggle-field', value: page.active?, "data-confirm-turning-off" => "Are you sure you want to unpublish this page? It will become inaccessible except to logged-in campaigners."
= f.hidden_field :publish_status, class: 'activation-toggle-field', value: page.publish_status, "data-confirm-turning-off" => "Are you sure you want to unpublish this page? It will become inaccessible except to logged-in campaigners."
.page-edit-bar__toggle-title Publish
.page-edit-bar__toggle-btns
= render 'shared/binary_switch', checked: page.active?
= render 'shared/binary_switch', checked: page.published?
.page-edit-bar__last-saved
.page-edit-bar__error-message
.page-edit-bar__btn-holder.page-edit-bar__btn-holder--hidden
Expand Down
6 changes: 6 additions & 0 deletions app/views/pages/_search.slim
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
@search_params[:plugin_type]),
html_options= {class: 'selectize-container', multiple: true}

.page-filter__row
= label_tag 'search[publish_status]', 'Publish status:', class: 'control-label col-lg-3'
.col-lg-3
= select_tag 'search[publish_status]', options_for_select(Page.publish_statuses.to_a, @search_params[:publish_status]),
html_options= {class: 'selectize-container', multiple: true}

.col-md-12
= submit_tag 'Filter by these criteria', class: 'btn btn-primary page-filter__submit', id: 'search_button'
= button_tag 'Reset filters', type: 'button', class: 'btn btn-danger page-filter__reset', id: 'filter_reset_button'
Expand Down
14 changes: 11 additions & 3 deletions app/views/pages/index.slim
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,26 @@
th
th
th
th
tbody
- @pages.each do |page|
tr
td = page.title
td = page.active? ? t('.published') : t('.unpublished')
td = t('.' + page.publish_status)
td = page.created_at.strftime('%Y-%b-%d')
td = page.updated_at.strftime('%Y-%b-%d')
td = page.action_count
td = link_to t('pages.edit.view'), member_facing_page_path(page)
td = link_to t('common.edit'), edit_page_path(page)
td = link_to_if !page.archived?, t('common.edit'), edit_page_path(page)
td = link_to t('.stats'), analytics_page_path(page)
td = link_to t('menu.clone'), new_clone_page_path(id: page.id)
td = link_to_if !page.archived?, t('menu.clone'), new_clone_page_path(id: page.id)
td
- if page.archived?
= link_to t('pages.index.unarchive'), page_archive_path(page), method: :delete
- else
= link_to t('pages.index.archive'), page_archive_path(page), method: :post, 'data-confirm' => archive_confirm_message(page)


#search-filter
= render partial: 'search'

5 changes: 4 additions & 1 deletion config/locales/champaign.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,15 @@ en:
title: "Pages"
filter: "Advanced Search"
stats: "Stats"
publish_status: "Published?"
publish_status: "Publish status"
published: 'Published'
unpublished: 'Private'
archived: 'Archived'
action_count: 'Actions'
table:
featured: "Featured"
archive: "Archive"
unarchive: "Unarchive"
new:
title: "Let's Get Started!"
title_label: "Page Title"
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
resources :images
get 'plugins', to: 'plugins#index'
get 'plugins/:type/:id', to: 'plugins#show', as: 'plugin'

resource :archive, only: [:create, :destroy], controller: 'page_archives'
end

resources :pages, path: 'a', as: 'member_facing_page', only: [:edit, :show] do
Expand Down
19 changes: 19 additions & 0 deletions db/migrate/20160720045351_add_publish_status_to_pages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class AddPublishStatusToPages < ActiveRecord::Migration
class Page < ActiveRecord::Base
end

def up
add_column :pages, :publish_status, :integer, default: 1, null: false
add_index :pages, :publish_status
Page.where(active: true).update_all(publish_status: 0)
Page.where(active: false).update_all(publish_status: 1)
remove_column :pages, :active
end

def down
add_column :pages, :active, :boolean, default: false
add_index :pages, :active
remove_column :pages, :publish_status
end
end

3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@
t.text "messages"
t.text "content", default: ""
t.boolean "featured", default: false
t.boolean "active", default: false
t.integer "liquid_layout_id"
t.integer "follow_up_liquid_layout_id"
t.integer "action_count", default: 0
Expand All @@ -199,12 +198,14 @@
t.integer "follow_up_plan", default: 0, null: false
t.integer "follow_up_page_id"
t.text "javascript"
t.integer "publish_status", default: 1, null: false
end

add_index "pages", ["follow_up_liquid_layout_id"], name: "index_pages_on_follow_up_liquid_layout_id", using: :btree
add_index "pages", ["follow_up_page_id"], name: "index_pages_on_follow_up_page_id", using: :btree
add_index "pages", ["liquid_layout_id"], name: "index_pages_on_liquid_layout_id", using: :btree
add_index "pages", ["primary_image_id"], name: "index_pages_on_primary_image_id", using: :btree
add_index "pages", ["publish_status"], name: "index_pages_on_publish_status", using: :btree

create_table "pages_tags", force: :cascade do |t|
t.integer "page_id"
Expand Down
22 changes: 11 additions & 11 deletions spec/controllers/pages_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
let(:user) { instance_double('User', id: '1') }
let(:default_language) { instance_double(Language, code: :en) }
let(:language) { instance_double(Language, code: :fr) }
let(:page) { instance_double('Page', active?: true, featured?: true, id: '1', liquid_layout: '3', follow_up_liquid_layout: '4', language: default_language) }
let(:page) { instance_double('Page', published?: true, featured?: true, id: '1', liquid_layout: '3', follow_up_liquid_layout: '4', language: default_language) }
let(:renderer) { instance_double('LiquidRenderer', render: 'my rendered html', personalization_data: { some: 'data'}) }

before do
Expand Down Expand Up @@ -142,25 +142,25 @@

it 'redirects to homepage if user not logged in and page unpublished' do
allow(controller).to receive(:user_signed_in?) { false }
allow(page).to receive(:active?){ false }
allow(page).to receive(:published?){ false }
expect( get :show, id: '1' ).to redirect_to(Settings.homepage_url)
end

it 'does not redirect to homepage if user not logged in and page published' do
allow(controller).to receive(:user_signed_in?) { false }
allow(page).to receive(:active?){ true }
allow(page).to receive(:published?){ true }
expect( get :show, id: '1' ).not_to be_redirect
end

it 'does not redirect to homepage if user logged in and page unpublished' do
allow(controller).to receive(:user_signed_in?) { true }
allow(page).to receive(:active?){ false }
allow(page).to receive(:published?){ false }
expect( get :show, id: '1' ).not_to be_redirect
end

it 'does not redirect to homepage if user logged in and page published' do
allow(controller).to receive(:user_signed_in?) { true }
allow(page).to receive(:active?){ true }
allow(page).to receive(:published?){ true }
expect( get :show, id: '1' ).not_to be_redirect
end

Expand All @@ -170,8 +170,8 @@
end

context 'on pages with localization' do
let(:french_page) { instance_double(Page, valid?: true, active?: true, language: language, id: '42', liquid_layout: '5') }
let(:english_page) { instance_double(Page, valid?: true, active?: true, language: default_language, id: '66', liquid_layout: '5') }
let(:french_page) { instance_double(Page, valid?: true, published?: true, language: language, id: '42', liquid_layout: '5') }
let(:english_page) { instance_double(Page, valid?: true, published?: true, language: default_language, id: '66', liquid_layout: '5') }

context 'with french' do
subject { french_page }
Expand Down Expand Up @@ -250,28 +250,28 @@
it 'redirects to homepage if user not logged in and page unpublished' do
subject
allow(controller).to receive(:user_signed_in?) { false }
allow(page).to receive(:active?){ false }
allow(page).to receive(:published?){ false }
expect( get :follow_up, id: '1' ).to redirect_to(Settings.homepage_url)
end

it 'does not redirect to homepage if user not logged in and page published' do
subject
allow(controller).to receive(:user_signed_in?) { false }
allow(page).to receive(:active?){ true }
allow(page).to receive(:published?){ true }
expect( get :follow_up, id: '1' ).not_to be_redirect
end

it 'does not redirect to homepage if user logged in and page unpublished' do
subject
allow(controller).to receive(:user_signed_in?) { true }
allow(page).to receive(:active?){ false }
allow(page).to receive(:published?){ false }
expect( get :follow_up, id: '1' ).not_to be_redirect
end

it 'does not redirect to homepage if user logged in and page published' do
subject
allow(controller).to receive(:user_signed_in?) { true }
allow(page).to receive(:active?){ true }
allow(page).to receive(:published?){ true }
expect( get :follow_up, id: '1' ).not_to be_redirect
end

Expand Down

0 comments on commit 679f1b4

Please sign in to comment.