From be6c00f16c1147e89fe9d4433afbd5d3ed9a1aed Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Thu, 10 Mar 2016 09:41:15 +0100 Subject: [PATCH 1/6] Keep separate edited_at timestamp for entries Display instead of updated_at in admin to prevent changing displayed dates during low level events like cache invalidation. --- admins/pageflow/entry.rb | 2 +- app/models/pageflow/revision.rb | 2 +- app/views/admin/entries/_attributes_table.html.arb | 2 +- config/locales/new/entry_edited_at.de.yml | 5 +++++ config/locales/new/entry_edited_at.en.yml | 5 +++++ db/migrate/20160310080213_add_edited_at_to_entries.rb | 9 +++++++++ 6 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 config/locales/new/entry_edited_at.de.yml create mode 100644 config/locales/new/entry_edited_at.en.yml create mode 100644 db/migrate/20160310080213_add_edited_at_to_entries.rb diff --git a/admins/pageflow/entry.rb b/admins/pageflow/entry.rb index 4aec706493..6b162cd813 100644 --- a/admins/pageflow/entry.rb +++ b/admins/pageflow/entry.rb @@ -18,7 +18,7 @@ module Pageflow end end column :created_at - column :updated_at + column :edited_at column :class => 'buttons' do |entry| if authorized?(:edit, Entry) span(link_to(I18n.t('pageflow.admin.entries.editor'), pageflow.edit_entry_path(entry), :class => 'editor button')) diff --git a/app/models/pageflow/revision.rb b/app/models/pageflow/revision.rb index bfcf236ae8..135123500d 100644 --- a/app/models/pageflow/revision.rb +++ b/app/models/pageflow/revision.rb @@ -6,7 +6,7 @@ class Revision < ActiveRecord::Base 'pageflow_pages.position ASC' ].join(',') - belongs_to :entry, :touch => true + belongs_to :entry, touch: :edited_at belongs_to :creator, :class_name => 'User' belongs_to :restored_from, :class_name => 'Pageflow::Revision' diff --git a/app/views/admin/entries/_attributes_table.html.arb b/app/views/admin/entries/_attributes_table.html.arb index 96a2338581..067aaefb58 100644 --- a/app/views/admin/entries/_attributes_table.html.arb +++ b/app/views/admin/entries/_attributes_table.html.arb @@ -4,7 +4,7 @@ attributes_table_for entry do row :account, :class => 'account' end row :created_at - row :updated_at + row :edited_at row :published?, :class => 'published' do span :'data-published' => entry.published? do if entry.published? diff --git a/config/locales/new/entry_edited_at.de.yml b/config/locales/new/entry_edited_at.de.yml new file mode 100644 index 0000000000..698996d829 --- /dev/null +++ b/config/locales/new/entry_edited_at.de.yml @@ -0,0 +1,5 @@ +de: + activerecord: + attributes: + pageflow/entry: + edited_at: "Geändert am" diff --git a/config/locales/new/entry_edited_at.en.yml b/config/locales/new/entry_edited_at.en.yml new file mode 100644 index 0000000000..cf1a2a196e --- /dev/null +++ b/config/locales/new/entry_edited_at.en.yml @@ -0,0 +1,5 @@ +en: + activerecord: + attributes: + pageflow/entry: + edited_at: "Updated at" diff --git a/db/migrate/20160310080213_add_edited_at_to_entries.rb b/db/migrate/20160310080213_add_edited_at_to_entries.rb new file mode 100644 index 0000000000..566f48757f --- /dev/null +++ b/db/migrate/20160310080213_add_edited_at_to_entries.rb @@ -0,0 +1,9 @@ +class AddEditedAtToEntries < ActiveRecord::Migration + def change + add_column :pageflow_entries, :edited_at, :datetime + + execute(<<-SQL) + UPDATE pageflow_entries SET edited_at = updated_at; + SQL + end +end From e5e184354a319fb751261e8c7c4b557a7232276e Mon Sep 17 00:00:00 2001 From: Roman Volkov Date: Wed, 10 Feb 2016 12:41:32 +0100 Subject: [PATCH 2/6] Improve entries table * Display publication state * Add published since column * Use icons instead of buttons in table * Use same icons on buttons on show page --- admins/pageflow/entry.rb | 36 +++++++++++++------ .../stylesheets/pageflow/admin.css.scss | 4 +++ .../pageflow/admin/entries.css.scss | 13 ++----- .../pageflow/admin/entries/index_table.scss | 15 ++++++++ .../pageflow/admin/icon_button.scss | 25 +++++++++++++ .../stylesheets/pageflow/admin/icon_link.scss | 31 ++++++++++++++++ .../admin/publication_state_indicator.scss | 18 ++++++++++ .../pageflow/admin/tooltip_bubble.scss | 30 ++++++++++++++++ app/views/admin/entries/_links.html.arb | 14 ++++++-- .../entry_publication_state_indicator.rb | 26 ++++++++++++++ .../components/pageflow/admin/icon_link_to.rb | 21 +++++++++++ config/locales/new/admin_entry_table.de.yml | 11 ++++++ config/locales/new/admin_entry_table.en.yml | 11 ++++++ 13 files changed, 232 insertions(+), 23 deletions(-) create mode 100644 app/assets/stylesheets/pageflow/admin/entries/index_table.scss create mode 100644 app/assets/stylesheets/pageflow/admin/icon_button.scss create mode 100644 app/assets/stylesheets/pageflow/admin/icon_link.scss create mode 100644 app/assets/stylesheets/pageflow/admin/publication_state_indicator.scss create mode 100644 app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss create mode 100644 app/views/components/pageflow/admin/entry_publication_state_indicator.rb create mode 100644 app/views/components/pageflow/admin/icon_link_to.rb create mode 100644 config/locales/new/admin_entry_table.de.yml create mode 100644 config/locales/new/admin_entry_table.en.yml diff --git a/admins/pageflow/entry.rb b/admins/pageflow/entry.rb index 6b162cd813..5888a6df0b 100644 --- a/admins/pageflow/entry.rb +++ b/admins/pageflow/entry.rb @@ -6,26 +6,41 @@ module Pageflow config.clear_sidebar_sections! index do - column :title, :sortable => 'title' do |entry| - link_to entry.title, admin_entry_path(entry) + column class: 'publication_state' do |entry| + entry_publication_state_indicator(entry) end - column I18n.t('pageflow.admin.entries.members'), :class => 'members' do |entry| + column :title, sortable: 'title' do |entry| + link_to(entry.title, admin_entry_path(entry)) + end + column I18n.t('pageflow.admin.entries.members'), class: 'members' do |entry| entry_user_badge_list(entry) end if authorized?(:read, Account) - column :account, :sortable => 'account_id' do |entry| - link_to(entry.account.name, admin_account_path(entry.account), :data => {:id => entry.account.id}) + column :account, sortable: 'account_id' do |entry| + link_to(entry.account.name, + admin_account_path(entry.account), + data: {id: entry.account.id}) end end column :created_at column :edited_at - column :class => 'buttons' do |entry| + column :published_at, sortable: 'pageflow_revisions.published_at' + + column class: 'buttons' do |entry| if authorized?(:edit, Entry) - span(link_to(I18n.t('pageflow.admin.entries.editor'), pageflow.edit_entry_path(entry), :class => 'editor button')) + icon_link_to(pageflow.edit_entry_path(entry), + tooltip: I18n.t('pageflow.admin.entries.editor_hint'), + class: 'editor') end - span(link_to(I18n.t('pageflow.admin.entries.preview'), preview_admin_entry_path(entry), :class => 'preview button')) + + icon_link_to(preview_admin_entry_path(entry), + tooltip: I18n.t('pageflow.admin.entries.preview'), + class: 'preview') + if entry.published? - span(link_to(I18n.t('pageflow.admin.entries.show_public'), pretty_entry_url(entry), :class => 'show_public button')) + icon_link_to(pretty_entry_url(entry), + tooltip: I18n.t('pageflow.admin.entries.show_public_hint'), + class: 'show_public') end end end @@ -130,7 +145,8 @@ def update end def scoped_collection - params.key?(:folder_id) ? super.where(:folder_id => params[:folder_id]) : super + result = super.includes(:theming, :account, :users, :published_revision) + params.key?(:folder_id) ? result.where(folder_id: params[:folder_id]) : result end def permitted_params diff --git a/app/assets/stylesheets/pageflow/admin.css.scss b/app/assets/stylesheets/pageflow/admin.css.scss index 2afb453dfd..b2377f612d 100644 --- a/app/assets/stylesheets/pageflow/admin.css.scss +++ b/app/assets/stylesheets/pageflow/admin.css.scss @@ -7,6 +7,10 @@ @import "pageflow/admin/features"; @import "pageflow/admin/quotas"; @import "pageflow/admin/tabs_view"; +@import "pageflow/admin/tooltip_bubble"; +@import "pageflow/admin/icon_link"; +@import "pageflow/admin/icon_button"; +@import "pageflow/admin/publication_state_indicator"; #wrapper { overflow: hidden; diff --git a/app/assets/stylesheets/pageflow/admin/entries.css.scss b/app/assets/stylesheets/pageflow/admin/entries.css.scss index ebcd6610df..41eb9c66dc 100644 --- a/app/assets/stylesheets/pageflow/admin/entries.css.scss +++ b/app/assets/stylesheets/pageflow/admin/entries.css.scss @@ -60,14 +60,7 @@ clear: both; } - td.buttons { - padding: 5px; - } - - td.members { - max-width: 130px; - } - - @import './entries/folders'; - @import './entries/user_badge_list'; + @import "./entries/index_table"; + @import "./entries/folders"; + @import "./entries/user_badge_list"; } \ No newline at end of file diff --git a/app/assets/stylesheets/pageflow/admin/entries/index_table.scss b/app/assets/stylesheets/pageflow/admin/entries/index_table.scss new file mode 100644 index 0000000000..1b5d54a484 --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/entries/index_table.scss @@ -0,0 +1,15 @@ +.index_table { + .publication_state { + width: 16px; + padding: 5px; + } + + .buttons { + width: 85px; + padding: 5px; + } + + .members { + max-width: 130px; + } +} diff --git a/app/assets/stylesheets/pageflow/admin/icon_button.scss b/app/assets/stylesheets/pageflow/admin/icon_button.scss new file mode 100644 index 0000000000..1cbf12d0a9 --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/icon_button.scss @@ -0,0 +1,25 @@ +$icon-button-color: #fff; + +a.icon_button:link { + @include background-icon-left($font-size: 15px, + $color: $icon-button-color, + $left: 9px, + $top: 50%); + padding-left: 30px; + + &:before { + font-weight: normal; + } + + &.editor { + @include fa-pencil-icon; + } + + &.preview { + @include fa-eye-icon; + } + + &.show_public { + @include fa-external-link-icon; + } +} diff --git a/app/assets/stylesheets/pageflow/admin/icon_link.scss b/app/assets/stylesheets/pageflow/admin/icon_link.scss new file mode 100644 index 0000000000..adde14486c --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/icon_link.scss @@ -0,0 +1,31 @@ +$icon-link-color: #555; + +$icon-link-acitve-color: #000; + +.icon_link_to { + a { + @include background-icon-center($font-size: 16px, $color: $icon-link-color); + position: relative; + display: inline-block; + width: 25px; + height: 25px; + vertical-align: bottom; + + &:focus, + &:hover { + @include background-icon-color($icon-link-acitve-color); + } + + &.editor { + @include fa-pencil-icon; + } + + &.preview { + @include fa-eye-icon; + } + + &.show_public { + @include fa-external-link-icon; + } + } +} diff --git a/app/assets/stylesheets/pageflow/admin/publication_state_indicator.scss b/app/assets/stylesheets/pageflow/admin/publication_state_indicator.scss new file mode 100644 index 0000000000..074c6bed98 --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/publication_state_indicator.scss @@ -0,0 +1,18 @@ +$publication-state-indicator-color: #5d5d5d; + +.publication_state_indicator { + @include background-icon-center($font-size: 16px, $color: $publication-state-indicator-color); + display: inline-block; + width: 25px; + height: 25px; + vertical-align: bottom; + border-bottom: none; + + &.published_without_password_protection { + @include fa-globe-icon; + } + + &.published_with_password_protection { + @include fa-lock-icon; + } +} diff --git a/app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss b/app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss new file mode 100644 index 0000000000..255a7cc7ac --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss @@ -0,0 +1,30 @@ +$tooltip-bubble-background-color: rgba(0, 0, 0, 0.7); + +$tooltip-bubble-text-color: #fff; + +.tooltip_bubble { + position: absolute; + display: none; + background-color: $tooltip-bubble-background-color; + color: $tooltip-bubble-text-color; + padding: 5px 10px; + top: -30px; + white-space: nowrap; + border-radius: 2px; + pointer-events: none; + + &:before { + content: ""; + position: absolute; + top: 100%; + left: 8px; + @include triangle(10px, $tooltip-bubble-background-color, down); + } +} + +:focus, +:hover { + > .tooltip_bubble { + display: block; + } +} diff --git a/app/views/admin/entries/_links.html.arb b/app/views/admin/entries/_links.html.arb index 7ab8c9cbe2..8fbbcd443d 100644 --- a/app/views/admin/entries/_links.html.arb +++ b/app/views/admin/entries/_links.html.arb @@ -1,9 +1,17 @@ para do if authorized?(:edit, Pageflow::Entry) - span(link_to(I18n.t('pageflow.admin.entries.editor'), pageflow.edit_entry_path(entry), :class => 'editor button')) + span(link_to(I18n.t('pageflow.admin.entries.editor'), + pageflow.edit_entry_path(entry), + class: 'editor icon_button button')) end - span(link_to(I18n.t('pageflow.admin.entries.preview'), preview_admin_entry_path(entry), :class => 'preview button')) + + span(link_to(I18n.t('pageflow.admin.entries.preview'), + preview_admin_entry_path(entry), + class: 'preview icon_button button')) + if entry.published? - span(link_to(I18n.t('pageflow.admin.entries.show_public'), pretty_entry_url(entry), :class => 'show_public button')) + span(link_to(I18n.t('pageflow.admin.entries.show_public'), + pretty_entry_url(entry), + class: 'show_public icon_button button')) end end diff --git a/app/views/components/pageflow/admin/entry_publication_state_indicator.rb b/app/views/components/pageflow/admin/entry_publication_state_indicator.rb new file mode 100644 index 0000000000..28744c1b4b --- /dev/null +++ b/app/views/components/pageflow/admin/entry_publication_state_indicator.rb @@ -0,0 +1,26 @@ +module Pageflow + module Admin + class EntryPublicationStateIndicator < ViewComponent + builder_method :entry_publication_state_indicator + + def build(entry) + if entry.published? + span(class: css_class(entry)) do + span(tooltip_text(entry), class: 'tooltip_bubble') + end + end + end + + private + + def css_class(entry) + ['publication_state_indicator', entry.publication_state] * ' ' + end + + def tooltip_text(entry) + I18n.t(entry.publication_state, + scope: 'activerecord.values.pageflow/entry.publication_states') + end + end + end +end diff --git a/app/views/components/pageflow/admin/icon_link_to.rb b/app/views/components/pageflow/admin/icon_link_to.rb new file mode 100644 index 0000000000..0902c65b28 --- /dev/null +++ b/app/views/components/pageflow/admin/icon_link_to.rb @@ -0,0 +1,21 @@ +module Pageflow + module Admin + class IconLinkTo < ViewComponent + builder_method :icon_link_to + + def build(path, options = {}) + text_node(link_to(tooltip_span(options), path, class: options[:class])) + end + + def tag_name + 'span' + end + + private + + def tooltip_span(options) + content_tag(:span, options[:tooltip], class: 'tooltip_bubble') + end + end + end +end diff --git a/config/locales/new/admin_entry_table.de.yml b/config/locales/new/admin_entry_table.de.yml new file mode 100644 index 0000000000..406b575581 --- /dev/null +++ b/config/locales/new/admin_entry_table.de.yml @@ -0,0 +1,11 @@ +de: + activerecord: + attributes: + pageflow/entry: + published_at: "Veröffentlicht seit" + pageflow: + admin: + entries: + editor_hint: "Editor öffnen" + preview_hint: "Vorschau anzeigen" + show_public_hint: "Öffentliche Seite anzeigen" diff --git a/config/locales/new/admin_entry_table.en.yml b/config/locales/new/admin_entry_table.en.yml new file mode 100644 index 0000000000..d40c1c2f22 --- /dev/null +++ b/config/locales/new/admin_entry_table.en.yml @@ -0,0 +1,11 @@ +en: + activerecord: + attributes: + pageflow/entry: + published_at: "Published since" + pageflow: + admin: + entries: + editor_hint: "Open editor" + preview_hint: "Open preview" + show_public_hint: "Visit public page" From 1a8cd15dd52090ce884301aa278e2f0395a01904 Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Thu, 10 Mar 2016 10:48:04 +0100 Subject: [PATCH 3/6] Extract publication state concern from Entry Add scopes and predicate methods to find entries by there publication state. --- .../pageflow/entry_publication_states.rb | 63 ++++++ app/models/pageflow/entry.rb | 10 +- app/models/pageflow/revision.rb | 3 + .../pageflow/entry_publication_states_spec.rb | 193 ++++++++++++++++++ spec/models/pageflow/revision_spec.rb | 52 +++++ 5 files changed, 312 insertions(+), 9 deletions(-) create mode 100644 app/models/concerns/pageflow/entry_publication_states.rb create mode 100644 spec/models/concerns/pageflow/entry_publication_states_spec.rb diff --git a/app/models/concerns/pageflow/entry_publication_states.rb b/app/models/concerns/pageflow/entry_publication_states.rb new file mode 100644 index 0000000000..8d97709aa4 --- /dev/null +++ b/app/models/concerns/pageflow/entry_publication_states.rb @@ -0,0 +1,63 @@ +module Pageflow + module EntryPublicationStates + extend ActiveSupport::Concern + + included do + scope(:published, -> { joins(:published_revision) }) + + scope(:published_without_password_protection, + -> { published.merge(Revision.without_password_protection) }) + + scope(:published_with_password_protection, + -> { published.merge(Revision.with_password_protection) }) + + scope(:not_published, + lambda do + includes(:published_revision) + .references(:pageflow_revisions) + .where(pageflow_revisions: {id: nil}) + end) + end + + def publication_state + if published_with_password_protection? + 'published_with_password_protection' + elsif published? + 'published_without_password_protection' + else + 'not_published' + end + end + + def published_with_password_protection? + published? && published_revision.password_protected? + end + + def published? + published_revision.present? + end + + def published_at + published? ? published_revision.published_at : nil + end + + def published_until + published? ? published_revision.published_until : nil + end + + module ClassMethods + def with_publication_state(state) + case state + when 'published_with_password_protection' + published_with_password_protection + when 'published_without_password_protection' + published_without_password_protection + when 'not_published' + not_published + else + fail(ArgumentError, "Unknown publication state #{state}") + end + end + end + end +end diff --git a/app/models/pageflow/entry.rb b/app/models/pageflow/entry.rb index 5efde0aaa1..b564d9164e 100644 --- a/app/models/pageflow/entry.rb +++ b/app/models/pageflow/entry.rb @@ -4,6 +4,7 @@ class PasswordMissingError < StandardError end include FeatureTarget + include EntryPublicationStates extend FriendlyId friendly_id :slug_candidates, :use => [:finders, :slugged] @@ -34,7 +35,6 @@ class PasswordMissingError < StandardError validates :account, :theming, :presence => true validate :folder_belongs_to_same_account - scope :published, -> { joins(:published_revision) } scope :editing, -> { joins(:edit_lock).merge(Pageflow::EditLock.active) } attr_accessor :skip_draft_creation @@ -96,14 +96,6 @@ def duplicate EntryDuplicate.of(self).create! end - def published? - published_revision.present? - end - - def published_until - published? ? published_revision.published_until : nil - end - def should_generate_new_friendly_id? slug.blank? || title_changed? end diff --git a/app/models/pageflow/revision.rb b/app/models/pageflow/revision.rb index 135123500d..192c98bed7 100644 --- a/app/models/pageflow/revision.rb +++ b/app/models/pageflow/revision.rb @@ -29,6 +29,9 @@ class Revision < ActiveRecord::Base {:now => Time.now}]) end + scope(:with_password_protection, -> { where('password_protected IS TRUE') }) + scope(:without_password_protection, -> { where('password_protected IS NOT TRUE') }) + scope :editable, -> { where('frozen_at IS NULL') } scope :frozen, -> { where('frozen_at IS NOT NULL') } diff --git a/spec/models/concerns/pageflow/entry_publication_states_spec.rb b/spec/models/concerns/pageflow/entry_publication_states_spec.rb new file mode 100644 index 0000000000..d6de0a317b --- /dev/null +++ b/spec/models/concerns/pageflow/entry_publication_states_spec.rb @@ -0,0 +1,193 @@ +require 'spec_helper' + +module Pageflow + describe 'EntryPublicationStates' do + describe '#publication_state' do + it 'identifies entry published without password protection' do + entry = create(:entry, :published) + + expect(entry.publication_state).to eq('published_without_password_protection') + end + + it 'identifies entry published with password protection' do + entry = create(:entry, :published_with_password) + + expect(entry.publication_state).to eq('published_with_password_protection') + end + + it 'identifies non published entry' do + entry = create(:entry) + + expect(entry.publication_state).to eq('not_published') + end + end + + describe '.published' do + it 'includes published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.published + + expect(result).to include(entry) + end + + it 'does not include non published entries' do + entry = create(:entry) + + result = Entry.published + + expect(result).not_to include(entry) + end + + it 'includes published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.published + + expect(result).to include(entry) + end + end + + describe '.published_without_password_protection' do + it 'includes published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.published_without_password_protection + + expect(result).to include(entry) + end + + it 'does not include non published entries' do + entry = create(:entry) + + result = Entry.published_without_password_protection + + expect(result).not_to include(entry) + end + + it 'does not include published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.published_without_password_protection + + expect(result).not_to include(entry) + end + end + + describe '.published_with_password_protection' do + it 'does not includes published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.published_with_password_protection + + expect(result).not_to include(entry) + end + + it 'does not include non published entries' do + entry = create(:entry) + + result = Entry.published_with_password_protection + + expect(result).not_to include(entry) + end + + it 'includes published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.published_with_password_protection + + expect(result).to include(entry) + end + end + + describe '.not_published' do + it 'does not include published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.not_published + + expect(result).not_to include(entry) + end + + it 'includes non published entries' do + entry = create(:entry) + + result = Entry.not_published + + expect(result).to include(entry) + end + + it 'does not include published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.not_published + + expect(result).not_to include(entry) + end + end + + describe '.with_publication_state' do + describe 'not_published' do + it 'includes non published entries' do + entry = create(:entry) + + result = Entry.with_publication_state('not_published') + + expect(result).to include(entry) + end + + it 'does not include non published entries' do + entry = create(:entry, :published) + + result = Entry.with_publication_state('not_published') + + expect(result).not_to include(entry) + end + end + + describe 'published_with_password_protection' do + it 'includes published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.with_publication_state('published_with_password_protection') + + expect(result).to include(entry) + end + + it 'does not include published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.with_publication_state('published_with_password_protection') + + expect(result).not_to include(entry) + end + end + + describe 'published_without_password_protection' do + it 'includes published entries without password protection' do + entry = create(:entry, :published) + + result = Entry.with_publication_state('published_without_password_protection') + + expect(result).to include(entry) + end + + it 'does not include published entries with password protection' do + entry = create(:entry, :published_with_password) + + result = Entry.with_publication_state('published_without_password_protection') + + expect(result).not_to include(entry) + end + end + + describe 'for unknown publication state' do + it 'raises argument error' do + expect { + Entry.with_publication_state('unknown') + }.to raise_error(ArgumentError) + end + end + end + end +end diff --git a/spec/models/pageflow/revision_spec.rb b/spec/models/pageflow/revision_spec.rb index 1dea10ee46..742fcd3432 100644 --- a/spec/models/pageflow/revision_spec.rb +++ b/spec/models/pageflow/revision_spec.rb @@ -347,6 +347,58 @@ def revision_components end end + describe '.with_password_protection' do + it 'includes revision with password_protected flag set to true' do + revision = create(:revision, password_protected: true) + + result = Revision.with_password_protection + + expect(result).to include(revision) + end + + it 'does not include revision without password_protected flag' do + revision = create(:revision) + + result = Revision.with_password_protection + + expect(result).not_to include(revision) + end + + it 'does not include revision with password_protected flag set to false' do + revision = create(:revision, password_protected: false) + + result = Revision.with_password_protection + + expect(result).not_to include(revision) + end + end + + describe '.without_password_protection' do + it 'includes revision without password_protected flag' do + revision = create(:revision) + + result = Revision.without_password_protection + + expect(result).to include(revision) + end + + it 'does not include revision with password_protected flag set to true' do + revision = create(:revision, password_protected: true) + + result = Revision.without_password_protection + + expect(result).not_to include(revision) + end + + it 'includes revision with password_protected flag set to false' do + revision = create(:revision, password_protected: false) + + result = Revision.without_password_protection + + expect(result).to include(revision) + end + end + describe '#image_files.with_usage_id' do it 'adds file_usage_id to image file record' do revision = create(:revision) From 7107ae4f5c64169b766b2e13660c604676c3c225 Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Thu, 10 Mar 2016 11:16:24 +0100 Subject: [PATCH 4/6] Add entry table filters --- admins/pageflow/entry.rb | 10 +++++++++- app/assets/stylesheets/pageflow/admin.css.scss | 1 + .../stylesheets/pageflow/admin/filters.scss | 3 +++ app/helpers/pageflow/admin/entries_helper.rb | 15 +++++++++++++++ app/models/pageflow/entry.rb | 4 ++++ config/locales/new/admin_entry_filters.de.yml | 13 +++++++++++++ config/locales/new/admin_entry_filters.en.yml | 13 +++++++++++++ 7 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/pageflow/admin/filters.scss create mode 100644 app/helpers/pageflow/admin/entries_helper.rb create mode 100644 config/locales/new/admin_entry_filters.de.yml create mode 100644 config/locales/new/admin_entry_filters.en.yml diff --git a/admins/pageflow/entry.rb b/admins/pageflow/entry.rb index 5888a6df0b..4152f1af87 100644 --- a/admins/pageflow/entry.rb +++ b/admins/pageflow/entry.rb @@ -3,7 +3,6 @@ module Pageflow menu :priority => 1 config.batch_actions = false - config.clear_sidebar_sections! index do column class: 'publication_state' do |entry| @@ -45,6 +44,14 @@ module Pageflow end end + filter :title + filter :account + filter :created_at + filter :edited_at + filter :first_published_at + filter :published_revision_published_at, as: :date_range + filter :with_publication_state, as: :select, collection: -> { collection_for_entry_publication_states } + sidebar :folders, :only => :index do text_node(link_to(I18n.t('pageflow.admin.entries.add_folder'), new_admin_folder_path, :class => 'new')) grouped_folder_list(Folder.accessible_by(Ability.new(current_user), :read), @@ -129,6 +136,7 @@ module Pageflow controller do helper FoldersHelper helper EntriesHelper + helper Pageflow::Admin::EntriesHelper helper Pageflow::Admin::FeaturesHelper helper Pageflow::Admin::RevisionsHelper helper Pageflow::Admin::FormHelper diff --git a/app/assets/stylesheets/pageflow/admin.css.scss b/app/assets/stylesheets/pageflow/admin.css.scss index b2377f612d..4d489c3aa3 100644 --- a/app/assets/stylesheets/pageflow/admin.css.scss +++ b/app/assets/stylesheets/pageflow/admin.css.scss @@ -5,6 +5,7 @@ @import "pageflow/admin/entries"; @import "pageflow/admin/forms"; @import "pageflow/admin/features"; +@import "pageflow/admin/filters"; @import "pageflow/admin/quotas"; @import "pageflow/admin/tabs_view"; @import "pageflow/admin/tooltip_bubble"; diff --git a/app/assets/stylesheets/pageflow/admin/filters.scss b/app/assets/stylesheets/pageflow/admin/filters.scss new file mode 100644 index 0000000000..2be27458c5 --- /dev/null +++ b/app/assets/stylesheets/pageflow/admin/filters.scss @@ -0,0 +1,3 @@ +#filter_sidebar_section { + display: none; +} diff --git a/app/helpers/pageflow/admin/entries_helper.rb b/app/helpers/pageflow/admin/entries_helper.rb new file mode 100644 index 0000000000..8033a8112a --- /dev/null +++ b/app/helpers/pageflow/admin/entries_helper.rb @@ -0,0 +1,15 @@ +module Pageflow + module Admin + module EntriesHelper + def collection_for_entry_publication_states + [ + 'published_without_password_protection', + 'published_with_password_protection', + 'not_published' + ].index_by do |state| + I18n.t(state, scope: 'activerecord.values.pageflow/entry.publication_states') + end + end + end + end +end diff --git a/app/models/pageflow/entry.rb b/app/models/pageflow/entry.rb index b564d9164e..9f3c1af58c 100644 --- a/app/models/pageflow/entry.rb +++ b/app/models/pageflow/entry.rb @@ -104,6 +104,10 @@ def slug_candidates [:title, [:title, :id]] end + def self.ransackable_scopes(_) + [:with_publication_state, :published] + end + private def folder_belongs_to_same_account diff --git a/config/locales/new/admin_entry_filters.de.yml b/config/locales/new/admin_entry_filters.de.yml new file mode 100644 index 0000000000..909d52d452 --- /dev/null +++ b/config/locales/new/admin_entry_filters.de.yml @@ -0,0 +1,13 @@ +de: + activerecord: + attributes: + pageflow/entry: + published_revision_published_at: "Veröffentlicht am" + first_published_at: "Erstmals veröffentlicht am" + with_publication_state: "Veröffentlichungsstatus" + values: + pageflow/entry: + publication_states: + published_without_password_protection: "Ohne Passwortschutz veröffentlicht" + published_with_password_protection: "Mit Passwortschutz veröffentlicht" + not_published: "Nicht veröffentlicht" \ No newline at end of file diff --git a/config/locales/new/admin_entry_filters.en.yml b/config/locales/new/admin_entry_filters.en.yml new file mode 100644 index 0000000000..8dbfa660a7 --- /dev/null +++ b/config/locales/new/admin_entry_filters.en.yml @@ -0,0 +1,13 @@ +en: + activerecord: + attributes: + pageflow/entry: + published_revision_published_at: "Published since" + first_published_at: "First published at" + with_publication_state: "Publication state" + values: + pageflow/entry: + publication_states: + published_without_password_protection: "Published with password protection" + published_with_password_protection: "Published without password protection" + not_published: "Not published" \ No newline at end of file From fc33477e707e20689d9d4a21839a990c8f210eef Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Thu, 10 Mar 2016 11:07:33 +0100 Subject: [PATCH 5/6] Improve eager loading for folder list --- admins/pageflow/entry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admins/pageflow/entry.rb b/admins/pageflow/entry.rb index 4152f1af87..0d3e9a25e2 100644 --- a/admins/pageflow/entry.rb +++ b/admins/pageflow/entry.rb @@ -54,7 +54,7 @@ module Pageflow sidebar :folders, :only => :index do text_node(link_to(I18n.t('pageflow.admin.entries.add_folder'), new_admin_folder_path, :class => 'new')) - grouped_folder_list(Folder.accessible_by(Ability.new(current_user), :read), + grouped_folder_list(Folder.includes(:account).accessible_by(Ability.new(current_user), :read), :class => authorized?(:manage, Folder) ? 'editable' : nil, :active_id => params[:folder_id], :grouped_by_accounts => authorized?(:read, Account)) From 53e03bdd04b5b0155fedd64a11615d4b2291833a Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Mon, 25 Apr 2016 21:50:49 +0200 Subject: [PATCH 6/6] Improve entry admin index query * Add `references` call to fix warning about implicit table dependency * Add index to speed up published revision join --- admins/pageflow/entry.rb | 2 +- ...25192648_add_index_for_revision_publication_timestamps.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160425192648_add_index_for_revision_publication_timestamps.rb diff --git a/admins/pageflow/entry.rb b/admins/pageflow/entry.rb index 0d3e9a25e2..e274cc11b8 100644 --- a/admins/pageflow/entry.rb +++ b/admins/pageflow/entry.rb @@ -153,7 +153,7 @@ def update end def scoped_collection - result = super.includes(:theming, :account, :users, :published_revision) + result = super.includes(:theming, :account, :users, :published_revision).references(:published_revision) params.key?(:folder_id) ? result.where(folder_id: params[:folder_id]) : result end diff --git a/db/migrate/20160425192648_add_index_for_revision_publication_timestamps.rb b/db/migrate/20160425192648_add_index_for_revision_publication_timestamps.rb new file mode 100644 index 0000000000..2823ed109c --- /dev/null +++ b/db/migrate/20160425192648_add_index_for_revision_publication_timestamps.rb @@ -0,0 +1,5 @@ +class AddIndexForRevisionPublicationTimestamps < ActiveRecord::Migration + def change + add_index 'pageflow_revisions', ['entry_id', 'published_at', 'published_until'], name: 'index_pageflow_revisions_on_publication_timestamps', using: :btree + end +end