Add SDG phases cards management
These cards will be displayed in the SDG homepage. Note there seems to be a strange behavior in cancancan. If we define these rules: can :manage, Widget::Card, page_type: "SDG::Phase" can :manage, Widget::Card The expected behavior is the first rule will always be ignored because the second one overwrites it. However, when creating a new card with `load_and_authorize_resource` will automatically add `page_type: "SDG::Phase"`. Similarly, if we do something like: can :manage, Widget::Card, id: 3 can :manage, Widget::Card Then the new card will have `3` as an ID. Maybe upgrading cancancan solves the issue; we haven't tried it. For now we're defining a different rule when creating widget cards.
This commit is contained in:
@@ -31,4 +31,5 @@
|
|||||||
@import "admin/*";
|
@import "admin/*";
|
||||||
@import "sdg/**/*";
|
@import "sdg/**/*";
|
||||||
@import "sdg_management/*";
|
@import "sdg_management/*";
|
||||||
|
@import "sdg_management/**/*";
|
||||||
@import "widgets/**/*";
|
@import "widgets/**/*";
|
||||||
|
|||||||
@@ -208,6 +208,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin regular-button($color: $brand) {
|
||||||
|
@include button($background: $color);
|
||||||
|
@extend %button;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin hollow-button($color: $link) {
|
@mixin hollow-button($color: $link) {
|
||||||
@include button($style: hollow, $background: $color);
|
@include button($style: hollow, $background: $color);
|
||||||
@extend %button;
|
@extend %button;
|
||||||
|
|||||||
11
app/assets/stylesheets/sdg_management/homepage/show.scss
Normal file
11
app/assets/stylesheets/sdg_management/homepage/show.scss
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
.phase-cards {
|
||||||
|
> header {
|
||||||
|
align-items: flex-start;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include regular-button;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,15 @@
|
|||||||
<%= header %>
|
<%= header %>
|
||||||
|
|
||||||
|
<% phases.each do |phase| %>
|
||||||
|
<section class="phase-cards <%= phase.kind %>-cards">
|
||||||
|
<header>
|
||||||
|
<h3><%= phase.title %></h3>
|
||||||
|
<%= link_to create_card_text(phase), new_sdg_management_sdg_phase_widget_card_path(phase) %>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<%= render Admin::Widget::Cards::TableComponent.new(
|
||||||
|
phase.cards,
|
||||||
|
no_cards_message: no_cards_message
|
||||||
|
) %>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
|
|||||||
@@ -12,4 +12,12 @@ class SDGManagement::Homepage::ShowComponent < ApplicationComponent
|
|||||||
def title
|
def title
|
||||||
t("sdg_management.homepage.title")
|
t("sdg_management.homepage.title")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_card_text(phase)
|
||||||
|
t("sdg_management.homepage.create_card", phase: phase.title.downcase)
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_cards_message
|
||||||
|
t("sdg_management.homepage.no_cards")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
13
app/controllers/sdg_management/cards_controller.rb
Normal file
13
app/controllers/sdg_management/cards_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class SDGManagement::CardsController < SDGManagement::BaseController
|
||||||
|
include Admin::Widget::CardsActions
|
||||||
|
helper_method :index_path
|
||||||
|
|
||||||
|
load_and_authorize_resource :phase, class: "SDG::Phase", id_param: "sdg_phase_id"
|
||||||
|
load_and_authorize_resource :card, through: :phase, class: "Widget::Card"
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def index_path
|
||||||
|
sdg_management_homepage_path
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -6,5 +6,7 @@ class Abilities::SDG::Manager
|
|||||||
|
|
||||||
can :read, ::SDG::Target
|
can :read, ::SDG::Target
|
||||||
can :manage, ::SDG::LocalTarget
|
can :manage, ::SDG::LocalTarget
|
||||||
|
can [:read, :update, :destroy], Widget::Card, cardable_type: "SDG::Phase"
|
||||||
|
can(:create, Widget::Card) { |card| card.cardable_type == "SDG::Phase" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
class SDG::Phase < ApplicationRecord
|
class SDG::Phase < ApplicationRecord
|
||||||
|
include Cardable
|
||||||
enum kind: %w[sensitization planning monitoring]
|
enum kind: %w[sensitization planning monitoring]
|
||||||
validates :kind, presence: true, uniqueness: true
|
validates :kind, presence: true, uniqueness: true
|
||||||
|
|
||||||
def self.[](kind)
|
def self.[](kind)
|
||||||
find_by!(kind: kind)
|
find_by!(kind: kind)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
self.class.human_attribute_name("kind.#{kind}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -336,6 +336,10 @@ en:
|
|||||||
sdg/local_target/translation:
|
sdg/local_target/translation:
|
||||||
title: "Title"
|
title: "Title"
|
||||||
description: "Description"
|
description: "Description"
|
||||||
|
sdg/phase/kind:
|
||||||
|
sensitization: "Sensitization"
|
||||||
|
planning: "Planning"
|
||||||
|
monitoring: "Monitoring"
|
||||||
sdg/target:
|
sdg/target:
|
||||||
code: "Code"
|
code: "Code"
|
||||||
title: "Title"
|
title: "Title"
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ en:
|
|||||||
title: "SDG content"
|
title: "SDG content"
|
||||||
homepage:
|
homepage:
|
||||||
title: "Homepage configuration"
|
title: "Homepage configuration"
|
||||||
|
create_card: "Create %{phase} card"
|
||||||
|
no_cards: "There are no cards for this phase"
|
||||||
menu:
|
menu:
|
||||||
budget_investments: "Participatory budgets"
|
budget_investments: "Participatory budgets"
|
||||||
debates: "Debates"
|
debates: "Debates"
|
||||||
|
|||||||
@@ -331,6 +331,10 @@ es:
|
|||||||
sdg/local_target/translation:
|
sdg/local_target/translation:
|
||||||
title: "Título"
|
title: "Título"
|
||||||
description: "Descripción"
|
description: "Descripción"
|
||||||
|
sdg/phase/kind:
|
||||||
|
sensitization: "Sensibilización"
|
||||||
|
planning: "Planificación"
|
||||||
|
monitoring: "Seguimiento"
|
||||||
sdg/target:
|
sdg/target:
|
||||||
code: "Código"
|
code: "Código"
|
||||||
title: "Título"
|
title: "Título"
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ es:
|
|||||||
title: "Contenido ODS"
|
title: "Contenido ODS"
|
||||||
homepage:
|
homepage:
|
||||||
title: "Configuración de la página de inicio"
|
title: "Configuración de la página de inicio"
|
||||||
|
create_card: "Crear tarjeta de %{phase}"
|
||||||
|
no_cards: "No hay tarjetas para esta fase"
|
||||||
menu:
|
menu:
|
||||||
budget_investments: "Presupuestos participativos"
|
budget_investments: "Presupuestos participativos"
|
||||||
debates: "Debates"
|
debates: "Debates"
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ namespace :sdg_management do
|
|||||||
resources :local_targets, except: [:show]
|
resources :local_targets, except: [:show]
|
||||||
resource :homepage, controller: :homepage, only: [:show]
|
resource :homepage, controller: :homepage, only: [:show]
|
||||||
|
|
||||||
|
resources :phases, only: [], as: :sdg_phases do
|
||||||
|
resources :cards, except: [:index, :show], as: :widget_cards
|
||||||
|
end
|
||||||
|
|
||||||
types = SDG::Related::RELATABLE_TYPES.map(&:tableize)
|
types = SDG::Related::RELATABLE_TYPES.map(&:tableize)
|
||||||
types_constraint = /#{types.join("|")}/
|
types_constraint = /#{types.join("|")}/
|
||||||
|
|
||||||
|
|||||||
@@ -30,3 +30,9 @@ section "Creating Sustainable Development Goals" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
section "Creating SDG homepage cards" do
|
||||||
|
SDG::Phase.all.each do |phase|
|
||||||
|
Widget::Card.create!(cardable: phase, title: "#{phase.title} card")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -13,4 +13,9 @@ describe "Abilities::SDG::Manager" do
|
|||||||
it { should_not be_able_to(:read, SDG::Manager) }
|
it { should_not be_able_to(:read, SDG::Manager) }
|
||||||
it { should_not be_able_to(:create, SDG::Manager) }
|
it { should_not be_able_to(:create, SDG::Manager) }
|
||||||
it { should_not be_able_to(:delete, SDG::Manager) }
|
it { should_not be_able_to(:delete, SDG::Manager) }
|
||||||
|
|
||||||
|
it { should_not be_able_to(:update, create(:widget_card)) }
|
||||||
|
it { should be_able_to(:update, create(:widget_card, cardable: SDG::Phase.sample)) }
|
||||||
|
it { should_not be_able_to(:create, build(:widget_card)) }
|
||||||
|
it { should be_able_to(:create, build(:widget_card, cardable: SDG::Phase.sample)) }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -195,6 +195,15 @@ describe "Polymorphic routes" do
|
|||||||
|
|
||||||
expect(sdg_management_polymorphic_path(target)).to eq sdg_management_local_target_path(target)
|
expect(sdg_management_polymorphic_path(target)).to eq sdg_management_local_target_path(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "routes SDG phases widget cards" do
|
||||||
|
phase = SDG::Phase.sample
|
||||||
|
card = create(:widget_card, cardable: phase)
|
||||||
|
|
||||||
|
expect(sdg_management_polymorphic_path(card)).to eq(
|
||||||
|
sdg_management_sdg_phase_widget_card_path(phase, card)
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -16,5 +16,37 @@ describe "SDG homepage configuration", :js do
|
|||||||
|
|
||||||
expect(page).to have_title "SDG content - Homepage configuration"
|
expect(page).to have_title "SDG content - Homepage configuration"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "Create card" do
|
||||||
|
visit sdg_management_homepage_path
|
||||||
|
click_link "Create planning card"
|
||||||
|
|
||||||
|
within(".translatable-fields") { fill_in "Title", with: "My planning card" }
|
||||||
|
click_button "Create card"
|
||||||
|
|
||||||
|
within(".planning-cards") do
|
||||||
|
expect(page).to have_content "My planning card"
|
||||||
|
end
|
||||||
|
|
||||||
|
within(".sensitization-cards") do
|
||||||
|
expect(page).to have_content "There are no cards for this phase"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Update card" do
|
||||||
|
create(:widget_card, cardable: SDG::Phase["monitoring"], title: "My monitoring card")
|
||||||
|
|
||||||
|
visit sdg_management_homepage_path
|
||||||
|
within(".monitoring-cards") { click_link "Edit" }
|
||||||
|
|
||||||
|
within(".translatable-fields") { fill_in "Title", with: "Updated monitoring card" }
|
||||||
|
click_button "Save card"
|
||||||
|
|
||||||
|
within(".monitoring-cards") do
|
||||||
|
expect(page).to have_css "tbody tr", count: 1
|
||||||
|
expect(page).to have_content "Updated monitoring card"
|
||||||
|
expect(page).not_to have_content "My monitoring card"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user