Add widget cards to homepage
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
class Admin::HomepageController < Admin::BaseController
|
class Admin::HomepageController < Admin::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
load_cards
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -9,4 +10,9 @@ class Admin::HomepageController < Admin::BaseController
|
|||||||
settings = /feature.homepage.widgets/
|
settings = /feature.homepage.widgets/
|
||||||
@settings = Setting.select {|setting| setting.key =~ /#{settings}/ }
|
@settings = Setting.select {|setting| setting.key =~ /#{settings}/ }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_cards
|
||||||
|
@cards = ::Widget::Card.body
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
51
app/controllers/admin/widget/cards_controller.rb
Normal file
51
app/controllers/admin/widget/cards_controller.rb
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
class Admin::Widget::CardsController < Admin::BaseController
|
||||||
|
|
||||||
|
def new
|
||||||
|
@card = ::Widget::Card.new(header: header_card?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@card = ::Widget::Card.new(card_params)
|
||||||
|
if @card.save
|
||||||
|
notice = "Success"
|
||||||
|
redirect_to admin_homepage_url, notice: notice
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@card = ::Widget::Card.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@card = ::Widget::Card.find(params[:id])
|
||||||
|
if @card.update(card_params)
|
||||||
|
notice = "Updated"
|
||||||
|
redirect_to admin_homepage_url, notice: notice
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@card = ::Widget::Card.find(params[:id])
|
||||||
|
@card.destroy
|
||||||
|
|
||||||
|
notice = "Removed"
|
||||||
|
redirect_to admin_homepage_url, notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def card_params
|
||||||
|
params.require(:widget_card).permit(:title, :description, :link_text, :link_url,
|
||||||
|
:button_text, :button_url, :alignment, :header,
|
||||||
|
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy])
|
||||||
|
end
|
||||||
|
|
||||||
|
def header_card?
|
||||||
|
params[:header_card].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -5,6 +5,7 @@ class WelcomeController < ApplicationController
|
|||||||
layout "devise", only: [:welcome, :verification]
|
layout "devise", only: [:welcome, :verification]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@cards = Widget::Card.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def welcome
|
def welcome
|
||||||
|
|||||||
2
app/models/widget.rb
Normal file
2
app/models/widget.rb
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
class Widget
|
||||||
|
end
|
||||||
15
app/models/widget/card.rb
Normal file
15
app/models/widget/card.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class Widget
|
||||||
|
class Card < ActiveRecord::Base
|
||||||
|
include Imageable
|
||||||
|
|
||||||
|
self.table_name = "widget_cards"
|
||||||
|
|
||||||
|
def self.header
|
||||||
|
where(header: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.body
|
||||||
|
where(header: false).order(:created_at)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
22
app/views/admin/homepage/_card.html.erb
Normal file
22
app/views/admin/homepage/_card.html.erb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<tr id="<%= dom_id(card) %>" class="card">
|
||||||
|
<td><%= card.title %></td>
|
||||||
|
<td><%= card.description %></td>
|
||||||
|
<td><%= card.link_text %></td>
|
||||||
|
<td><%= card.link_url %></td>
|
||||||
|
|
||||||
|
<!-- remove conditional once specs have image validations -->
|
||||||
|
<td><% if card.image.present? %>
|
||||||
|
<%= image_tag(card.image_url(:thumb),
|
||||||
|
class: "margin",
|
||||||
|
alt: card.image.title) %>
|
||||||
|
<% end %></td>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<%= link_to "Edit", edit_admin_widget_card_path(card) %>
|
||||||
|
<div>
|
||||||
|
<%= link_to "Remove", admin_widget_card_path(card),
|
||||||
|
method: :delete,
|
||||||
|
data: { confirm: t('admin.actions.confirm') } %>
|
||||||
|
<div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
13
app/views/admin/homepage/_cards.html.erb
Normal file
13
app/views/admin/homepage/_cards.html.erb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>title</th>
|
||||||
|
<th>text</th>
|
||||||
|
<th>link text</th>
|
||||||
|
<th>link</th>
|
||||||
|
<th>image</th>
|
||||||
|
<th>actions</th>
|
||||||
|
</tr>
|
||||||
|
<% cards.each do |card| %>
|
||||||
|
<%= render "card", card: card %>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
@@ -1,6 +1,19 @@
|
|||||||
<h1>Homepage</h1>
|
<h1>Homepage</h1>
|
||||||
|
|
||||||
<p>The active modules appear in the homepage in the same order as here.</p>
|
<p>The active modules appear in the homepage in the same order as here.</p>
|
||||||
|
<h2>Cards</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<%= link_to "Create card", new_admin_widget_card_path %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="cards">
|
||||||
|
<% if @cards.present? %>
|
||||||
|
<%= render "cards", cards: @cards %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<% @settings.each do |setting| %>
|
<% @settings.each do |setting| %>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
11
app/views/admin/widget/cards/_form.html.erb
Normal file
11
app/views/admin/widget/cards/_form.html.erb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<%= form_for [:admin, @card] do |f| %>
|
||||||
|
<%= f.text_field :title %>
|
||||||
|
<%= f.text_area :description %>
|
||||||
|
<%= f.text_field :link_text %>
|
||||||
|
<%= f.text_field :link_url %>
|
||||||
|
<%= f.hidden_field :header, value: @card.header? %>
|
||||||
|
<div class="images small-12 column">
|
||||||
|
<%= render 'images/nested_image', imageable: @card, f: f %>
|
||||||
|
</div>
|
||||||
|
<%= f.submit %>
|
||||||
|
<% end %>
|
||||||
2
app/views/admin/widget/cards/edit.html.erb
Normal file
2
app/views/admin/widget/cards/edit.html.erb
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Edit
|
||||||
|
<%= render "form" %>
|
||||||
2
app/views/admin/widget/cards/new.html.erb
Normal file
2
app/views/admin/widget/cards/new.html.erb
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
New
|
||||||
|
<%= render "form" %>
|
||||||
11
app/views/welcome/_card.html.erb
Normal file
11
app/views/welcome/_card.html.erb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div id="<%= dom_id(card) %>" class="card">
|
||||||
|
<%= card.title %>
|
||||||
|
<%= card.description %>
|
||||||
|
<%= link_to card.link_text, card.link_url %>
|
||||||
|
|
||||||
|
<% if card.image.present? %>
|
||||||
|
<%= image_tag(card.image_url(:large),
|
||||||
|
class: "margin",
|
||||||
|
alt: card.image.title) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
5
app/views/welcome/_cards.html.erb
Normal file
5
app/views/welcome/_cards.html.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<h1>Cards</h1>
|
||||||
|
|
||||||
|
<% @cards.all.each do |card| %>
|
||||||
|
<%= render "card", card: card %>
|
||||||
|
<% end %>
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= render "cards" %>
|
||||||
<% if feature?("user.recommendations") && (@recommended_debates.present? || @recommended_proposals.present?) %>
|
<% if feature?("user.recommendations") && (@recommended_debates.present? || @recommended_proposals.present?) %>
|
||||||
<%= render "recommended",
|
<%= render "recommended",
|
||||||
recommended_debates: @recommended_debates,
|
recommended_debates: @recommended_debates,
|
||||||
|
|||||||
@@ -182,4 +182,7 @@ namespace :admin do
|
|||||||
|
|
||||||
resource :homepage, controller: :homepage
|
resource :homepage, controller: :homepage
|
||||||
|
|
||||||
|
namespace :widget do
|
||||||
|
resources :cards
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
15
db/migrate/20180516091302_create_widget_cards.rb
Normal file
15
db/migrate/20180516091302_create_widget_cards.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class CreateWidgetCards < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :widget_cards do |t|
|
||||||
|
t.string :title
|
||||||
|
t.text :description
|
||||||
|
t.string :link_text
|
||||||
|
t.string :link_url
|
||||||
|
t.string :button_text
|
||||||
|
t.string :button_url
|
||||||
|
t.boolean :header, default: false
|
||||||
|
t.string :alignment
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
db/schema.rb
15
db/schema.rb
@@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20180323190027) do
|
ActiveRecord::Schema.define(version: 20180519132715) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -1223,6 +1223,19 @@ ActiveRecord::Schema.define(version: 20180323190027) do
|
|||||||
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree
|
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree
|
||||||
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
||||||
|
|
||||||
|
create_table "widget_cards", force: :cascade do |t|
|
||||||
|
t.string "title"
|
||||||
|
t.text "description"
|
||||||
|
t.string "link_text"
|
||||||
|
t.string "link_url"
|
||||||
|
t.string "button_text"
|
||||||
|
t.string "button_url"
|
||||||
|
t.boolean "header", default: false
|
||||||
|
t.string "alignment"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
add_foreign_key "administrators", "users"
|
add_foreign_key "administrators", "users"
|
||||||
add_foreign_key "annotations", "legacy_legislations"
|
add_foreign_key "annotations", "legacy_legislations"
|
||||||
add_foreign_key "annotations", "users"
|
add_foreign_key "annotations", "users"
|
||||||
|
|||||||
@@ -962,4 +962,22 @@ LOREM_IPSUM
|
|||||||
sequence(:body) { |n| "Body #{n}" }
|
sequence(:body) { |n| "Body #{n}" }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :widget_card, class: 'Widget::Card' do
|
||||||
|
sequence(:title) { |n| "Title #{n}" }
|
||||||
|
sequence(:description) { |n| "Description #{n}" }
|
||||||
|
sequence(:link_text) { |n| "Link text #{n}" }
|
||||||
|
sequence(:link_url) { |n| "Link url #{n}" }
|
||||||
|
|
||||||
|
trait :header do
|
||||||
|
header true
|
||||||
|
sequence(:button_text) { |n| "Button text #{n}" }
|
||||||
|
sequence(:button_url) { |n| "Button url #{n}" }
|
||||||
|
sequence(:alignment) { |n| "background" }
|
||||||
|
end
|
||||||
|
|
||||||
|
after :create do |widget_card|
|
||||||
|
create(:image, imageable: widget_card)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
38
spec/features/admin/homepage/homepage_spec.rb
Normal file
38
spec/features/admin/homepage/homepage_spec.rb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Homepage' do
|
||||||
|
|
||||||
|
background do
|
||||||
|
admin = create(:administrator).user
|
||||||
|
login_as(admin)
|
||||||
|
|
||||||
|
end
|
||||||
|
scenario "Cards" do
|
||||||
|
card1 = create(:widget_card, title: "Card text",
|
||||||
|
description: "Card description",
|
||||||
|
link_text: "Link text",
|
||||||
|
link_url: "consul.dev")
|
||||||
|
|
||||||
|
card2 = create(:widget_card, title: "Card text2",
|
||||||
|
description: "Card description2",
|
||||||
|
link_text: "Link text2",
|
||||||
|
link_url: "consul.dev2")
|
||||||
|
|
||||||
|
visit root_path
|
||||||
|
|
||||||
|
expect(page).to have_css(".card", count: 2)
|
||||||
|
|
||||||
|
within("#widget_card_#{card1.id}") do
|
||||||
|
expect(page).to have_content("Card text")
|
||||||
|
expect(page).to have_content("Card description")
|
||||||
|
expect(page).to have_link("Link text", href: "consul.dev")
|
||||||
|
expect(page).to have_css("img[alt='#{card1.image.title}']")
|
||||||
|
end
|
||||||
|
|
||||||
|
within("#widget_card_#{card2.id}") do
|
||||||
|
expect(page).to have_content("Card text2")
|
||||||
|
expect(page).to have_content("Card description2")
|
||||||
|
expect(page).to have_link("Link text2", href: "consul.dev2")
|
||||||
|
expect(page).to have_css("img[alt='#{card2.image.title}']")
|
||||||
|
end
|
||||||
|
end
|
||||||
132
spec/features/admin/widgets/cards_spec.rb
Normal file
132
spec/features/admin/widgets/cards_spec.rb
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Cards' do
|
||||||
|
|
||||||
|
background do
|
||||||
|
admin = create(:administrator).user
|
||||||
|
login_as(admin)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Create", :js do
|
||||||
|
visit admin_homepage_path
|
||||||
|
click_link "Create card"
|
||||||
|
|
||||||
|
fill_in "widget_card_title", with: "Card text"
|
||||||
|
fill_in "widget_card_description", with: "Card description"
|
||||||
|
fill_in "widget_card_link_text", with: "Link text"
|
||||||
|
fill_in "widget_card_link_url", with: "consul.dev"
|
||||||
|
attach_image_to_card
|
||||||
|
click_button "Create Card"
|
||||||
|
|
||||||
|
expect(page).to have_content "Success"
|
||||||
|
expect(page).to have_css(".card", count: 1)
|
||||||
|
|
||||||
|
card = Widget::Card.last
|
||||||
|
within("#widget_card_#{card.id}") do
|
||||||
|
expect(page).to have_content "Card text"
|
||||||
|
expect(page).to have_content "Card description"
|
||||||
|
expect(page).to have_content "Link text"
|
||||||
|
expect(page).to have_content "consul.dev"
|
||||||
|
expect(page).to have_css("img[alt='#{card.image.title}']")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Index" do
|
||||||
|
3.times { create(:widget_card) }
|
||||||
|
|
||||||
|
visit admin_homepage_path
|
||||||
|
|
||||||
|
expect(page).to have_css(".card", count: 3)
|
||||||
|
|
||||||
|
cards = Widget::Card.all
|
||||||
|
cards.each do |card|
|
||||||
|
expect(page).to have_content card.title
|
||||||
|
expect(page).to have_content card.description
|
||||||
|
expect(page).to have_content card.link_text
|
||||||
|
expect(page).to have_content card.link_url
|
||||||
|
expect(page).to have_css("img[alt='#{card.image.title}']")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Edit" do
|
||||||
|
card = create(:widget_card)
|
||||||
|
|
||||||
|
visit admin_homepage_path
|
||||||
|
|
||||||
|
within("#widget_card_#{card.id}") do
|
||||||
|
click_link "Edit"
|
||||||
|
end
|
||||||
|
|
||||||
|
fill_in "widget_card_title", with: "Card text updated"
|
||||||
|
fill_in "widget_card_description", with: "Card description updated"
|
||||||
|
fill_in "widget_card_link_text", with: "Link text updated"
|
||||||
|
fill_in "widget_card_link_url", with: "consul.dev updated"
|
||||||
|
click_button "Update Card"
|
||||||
|
|
||||||
|
expect(page).to have_content "Updated"
|
||||||
|
|
||||||
|
expect(page).to have_css(".card", count: 1)
|
||||||
|
within("#widget_card_#{Widget::Card.last.id}") do
|
||||||
|
expect(page).to have_content "Card text updated"
|
||||||
|
expect(page).to have_content "Card description updated"
|
||||||
|
expect(page).to have_content "Link text updated"
|
||||||
|
expect(page).to have_content "consul.dev updated"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Remove", :js do
|
||||||
|
card = create(:widget_card)
|
||||||
|
|
||||||
|
visit admin_homepage_path
|
||||||
|
|
||||||
|
within("#widget_card_#{card.id}") do
|
||||||
|
accept_confirm do
|
||||||
|
click_link "Remove"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content "Removed"
|
||||||
|
expect(page).to have_css(".card", count: 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Header Card" do
|
||||||
|
|
||||||
|
scenario "Create" do
|
||||||
|
visit admin_homepage_path
|
||||||
|
click_link "Create header"
|
||||||
|
|
||||||
|
fill_in "widget_card_title", with: "Card text"
|
||||||
|
fill_in "widget_card_description", with: "Card description"
|
||||||
|
fill_in "widget_card_link_text", with: "Link text"
|
||||||
|
fill_in "widget_card_link_url", with: "consul.dev"
|
||||||
|
click_button "Create Card"
|
||||||
|
|
||||||
|
expect(page).to have_content "Success"
|
||||||
|
|
||||||
|
within("#header") do
|
||||||
|
expect(page).to have_css(".card", count: 1)
|
||||||
|
expect(page).to have_content "Card text"
|
||||||
|
expect(page).to have_content "Card description"
|
||||||
|
expect(page).to have_content "Link text"
|
||||||
|
expect(page).to have_content "consul.dev"
|
||||||
|
end
|
||||||
|
|
||||||
|
within("#cards") do
|
||||||
|
expect(page).to have_css(".card", count: 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
pending "add image expectactions"
|
||||||
|
|
||||||
|
def attach_image_to_card
|
||||||
|
click_link "Add image"
|
||||||
|
image_input = find(".image").find("input[type=file]", visible: false)
|
||||||
|
attach_file(
|
||||||
|
image_input[:id],
|
||||||
|
Rails.root.join('spec/fixtures/files/clippy.jpg'),
|
||||||
|
make_visible: true)
|
||||||
|
expect(page).to have_field('widget_card_image_attributes_title', with: "clippy.jpg")
|
||||||
|
end
|
||||||
|
end
|
||||||
37
spec/models/widget/card_spec.rb
Normal file
37
spec/models/widget/card_spec.rb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Widget::Card do
|
||||||
|
|
||||||
|
let(:card) { build(:widget_card) }
|
||||||
|
|
||||||
|
context "validations" do
|
||||||
|
|
||||||
|
it "is valid" do
|
||||||
|
expect(card).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#header" do
|
||||||
|
|
||||||
|
it "returns the header card" do
|
||||||
|
header = create(:widget_card, header: true)
|
||||||
|
card = create(:widget_card, header: false)
|
||||||
|
|
||||||
|
expect(Widget::Card.header).to eq([header])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#body" do
|
||||||
|
|
||||||
|
it "returns cards for the homepage body" do
|
||||||
|
header = create(:widget_card, header: true)
|
||||||
|
card1 = create(:widget_card, header: false, title: "Card 1")
|
||||||
|
card2 = create(:widget_card, header: false, title: "Card 2")
|
||||||
|
card3 = create(:widget_card, header: false, title: "Card 3")
|
||||||
|
|
||||||
|
expect(Widget::Card.body).to eq([card1, card2, card3])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user