diff --git a/app/assets/javascripts/alchemy/templates/page.hbs b/app/assets/javascripts/alchemy/templates/page.hbs
index 81748efe20..8eb772da82 100644
--- a/app/assets/javascripts/alchemy/templates/page.hbs
+++ b/app/assets/javascripts/alchemy/templates/page.hbs
@@ -1,9 +1,19 @@
-
-
- {{ page.name }}
-
-
- {{ page.url_path }}
-
+
+
+
+ {{ page.name }}
+
+
+ {{ page.url_path }}
+
+
+
+
+ {{ page.site.name }}
+
+
+ {{ page.language.name }}
+
+
diff --git a/app/assets/stylesheets/alchemy/page-select.scss b/app/assets/stylesheets/alchemy/page-select.scss
index c6fe0760be..c944cd3c72 100644
--- a/app/assets/stylesheets/alchemy/page-select.scss
+++ b/app/assets/stylesheets/alchemy/page-select.scss
@@ -8,24 +8,49 @@
.page-select--page {
display: flex;
- align-items: center;
+ flex-direction: column;
.icon {
margin: 0 8px 0 4px;
.select2-highlighted & {
- color: $white
+ color: $white;
}
}
}
+.page-select--top,
+.page-select--bottom {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+
+.page-select--bottom {
+ font-size: $small-font-size;
+ padding-left: 6 * $default-padding;
+}
+
+.page-select--language-code {
+ display: inline-block;
+ background-color: $medium-gray;
+ margin-left: auto;
+ border-radius: $default-border-radius;
+ padding: $default-padding / 2 $default-padding;
+
+ .select2-highlighted & {
+ color: $select-hover-bg-color;
+ background-color: white;
+ }
+}
+
.page-select--page-urlname {
margin-left: auto;
- padding: $default-padding 2*$default-padding;
+ padding: $default-padding 2 * $default-padding;
color: $dark-gray;
font-size: $small-font-size;
.select2-highlighted & {
- color: $white
+ color: $white;
}
}
diff --git a/app/controllers/alchemy/api/pages_controller.rb b/app/controllers/alchemy/api/pages_controller.rb
index 48af2ee2ad..7a914fc41c 100644
--- a/app/controllers/alchemy/api/pages_controller.rb
+++ b/app/controllers/alchemy/api/pages_controller.rb
@@ -2,19 +2,19 @@
module Alchemy
class Api::PagesController < Api::BaseController
+ serialization_scope :current_ability
before_action :load_page, only: [:show]
# Returns all pages as json object
#
def index
- language = Alchemy::Language.find_by(id: params[:language_id]) || Alchemy::Language.current
-
# Fix for cancancan not able to merge multiple AR scopes for logged in users
- if cannot? :edit_content, Alchemy::Page
+ if can? :edit_content, Alchemy::Page
+ @pages = Alchemy::Page.all
+ else
+ language = Alchemy::Language.find_by(id: params[:language_id]) || Alchemy::Language.current
@pages = Alchemy::Page.accessible_by(current_ability, :index)
@pages = @pages.where(language: language)
- else
- @pages = language&.pages.presence || Alchemy::Page.none
end
@pages = @pages.includes(*page_includes)
@pages = @pages.ransack(params[:q]).result
diff --git a/app/serializers/alchemy/page_serializer.rb b/app/serializers/alchemy/page_serializer.rb
index 34d68bd500..59c16a773a 100644
--- a/app/serializers/alchemy/page_serializer.rb
+++ b/app/serializers/alchemy/page_serializer.rb
@@ -18,5 +18,10 @@ class PageSerializer < ActiveModel::Serializer
:parent_id
has_many :elements
+
+ with_options if: -> { scope.can?(:edit_content, object) } do
+ belongs_to :site
+ belongs_to :language
+ end
end
end
diff --git a/spec/controllers/alchemy/api/pages_controller_spec.rb b/spec/controllers/alchemy/api/pages_controller_spec.rb
index 4db2105b10..45502e2722 100644
--- a/spec/controllers/alchemy/api/pages_controller_spec.rb
+++ b/spec/controllers/alchemy/api/pages_controller_spec.rb
@@ -10,7 +10,6 @@ module Alchemy
let(:result) { JSON.parse(response.body) }
context "without a default language present" do
-
it "returns JSON" do
get :index, params: { format: :json }
expect(result["pages"]).to eq([])
@@ -87,10 +86,27 @@ module Alchemy
let(:language_2) { create(:alchemy_language, site: site_2) }
let!(:site_2_page) { create(:alchemy_page, :public, language: language_2) }
- it "only returns pages for current site" do
- get :index, format: :json
+ context "as guest user" do
+ it "only returns pages for current site" do
+ get :index, format: :json
+ expect(result["pages"].map { |r| r["id"] }).to eq([page.parent_id, page.id])
+ end
+ end
+
+ context "as author user" do
+ before do
+ authorize_user(build(:alchemy_dummy_user, :as_author))
+ end
- expect(result["pages"].map { |r| r["id"] }).to_not include(site_2_page.id)
+ it "returns all pages" do
+ get :index, format: :json
+ expect(result["pages"].map { |r| r["id"] }).to eq([
+ page.parent_id,
+ page.id,
+ site_2_page.parent_id,
+ site_2_page.id,
+ ])
+ end
end
end
diff --git a/spec/serializers/alchemy/page_serializer_spec.rb b/spec/serializers/alchemy/page_serializer_spec.rb
new file mode 100644
index 0000000000..2345f21091
--- /dev/null
+++ b/spec/serializers/alchemy/page_serializer_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+RSpec.describe Alchemy::PageSerializer do
+ subject do
+ described_class.new(page, scope: Alchemy::Permissions.new(user)).to_json
+ end
+
+ let(:page) { build_stubbed(:alchemy_page) }
+
+ context "for guest user" do
+ let(:user) { nil }
+
+ it "includes public attributes" do
+ json = JSON.parse(subject)
+ expect(json).to match(
+ "id" => page.id,
+ "name" => page.name,
+ "urlname" => page.urlname,
+ "page_layout" => page.page_layout,
+ "title" => page.title,
+ "language_code" => page.language_code,
+ "meta_keywords" => page.meta_keywords,
+ "meta_description" => page.meta_description,
+ "tag_list" => page.tag_list,
+ "created_at" => an_instance_of(String),
+ "updated_at" => an_instance_of(String),
+ "status" => page.status.transform_keys(&:to_s),
+ "url_path" => page.url_path,
+ "parent_id" => page.parent_id,
+ "elements" => [],
+ )
+ end
+ end
+
+ context "for admin user" do
+ let(:user) { build_stubbed(:alchemy_dummy_user, :as_author) }
+
+ it "includes all attributes" do
+ json = JSON.parse(subject)
+ expect(json).to match(
+ "id" => page.id,
+ "name" => page.name,
+ "urlname" => page.urlname,
+ "page_layout" => page.page_layout,
+ "title" => page.title,
+ "language_code" => page.language_code,
+ "meta_keywords" => page.meta_keywords,
+ "meta_description" => page.meta_description,
+ "tag_list" => page.tag_list,
+ "created_at" => an_instance_of(String),
+ "updated_at" => an_instance_of(String),
+ "status" => page.status.transform_keys(&:to_s),
+ "url_path" => page.url_path,
+ "parent_id" => page.parent_id,
+ "elements" => [],
+ "site" => {
+ "id" => page.site.id,
+ "aliases" => nil,
+ "created_at" => an_instance_of(String),
+ "host" => "*",
+ "name" => "Default Site",
+ "public" => true,
+ "redirect_to_primary_host" => false,
+ "updated_at" => an_instance_of(String),
+ },
+ "language" => {
+ "country_code" => "",
+ "created_at" => an_instance_of(String),
+ "creator_id" => nil,
+ "default" => true,
+ "frontpage_name" => "Intro",
+ "id" => page.language_id,
+ "language_code" => "en",
+ "locale" => "en",
+ "name" => "Your Language",
+ "page_layout" => "index",
+ "public" => true,
+ "site_id" => page.site.id,
+ "updated_at" => an_instance_of(String),
+ "updater_id" => nil,
+ },
+ )
+ end
+ end
+end