Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions app/controllers/admin/chapters_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
class Admin::ChaptersController < Admin::ApplicationController
before_action :set_chapter, only: [:show, :edit, :update]
before_action :set_chapter, only: %i[show edit update update_active]
after_action :verify_authorized

def index
authorize Chapter
@chapters = Chapter.all.order(:name)

@chapters = @chapters.where(chapter_index_params) if chapter_index_params.present?
end

def new
@chapter = Chapter.new
authorize @chapter
Expand Down Expand Up @@ -36,12 +43,21 @@ def edit
def update
authorize(@chapter)

if @chapter.update(chapter_params)
flash[:notice] = "Chapter #{@chapter.name} has been successfully updated"
redirect_to [:admin, @chapter]
else
flash[:notice] = @chapter.errors.full_messages
render 'edit'
respond_to do |format|
format.json do
@chapter.update(chapter_params)

head :ok
end
format.html do
if @chapter.update(chapter_params)
flash[:notice] = "Chapter #{@chapter.name} has been successfully updated"
return redirect_to [:admin, @chapter]
end

flash[:notice] = @chapter.errors.full_messages
render 'edit'
end
end
end

Expand All @@ -61,6 +77,10 @@ def members

private

def chapter_index_params
@chapter_index_params ||= params.permit(:active)
end

def chapter_params
params.require(:chapter).permit(:name, :email, :city, :time_zone, :twitter, :description, :image)
end
Expand Down
4 changes: 4 additions & 0 deletions app/policies/chapter_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ def index?
show?
end

def update_active?
is_admin_or_organiser?
end

def create?
is_admin_or_organiser?
end
Expand Down
60 changes: 60 additions & 0 deletions app/views/admin/chapters/index.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
%section#banner
.row
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a .row in foundation should contain column elements, so here there should be a large-12.columns to achieve correct alignment.

.large-12.columns
%h1 Chapters
= link_to t('.view_all_chapters'), admin_chapters_path
&nbsp;
= link_to t('.view_active_chapters'), admin_chapters_path(active: true)
&nbsp;
= link_to t('.view_inactive_chapters'), admin_chapters_path(active: false)
.row
.large-12.columns
%hr
.large-4.columns
Name / City / Slug
.large-4.columns
Email / Twitter
.large-1.columns
Active?

- @chapters.each do |chapter|
.row
%hr
.large-4.columns
= link_to admin_chapter_path(chapter) do
%p= chapter.name
%p= chapter.city
%p= chapter.slug
.large-4.columns
%p= chapter.email
%p= chapter.twitter
.large-1.columns
= check_box_tag :chapter_active, 'true', chapter.active?, class: 'chapter_active', data: { 'chapter-id': chapter.id, }

- content_for :page_footer do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind having javascript available as well, however it should be optional and not the default. Also, a confirmation button to verify disabling chapters before any actions take place.

:javascript
$('input.chapter_active').on('click', function() {
let active = $(this).is(':checked');
let message = "#{t('.change_chapter_to_inactive_confirmation')}";

if (active) {
message = "#{t('.change_chapter_to_active_confirmation')}";
}

if (!confirm(message)) {
return false;
}
});

$('input.chapter_active').on('change', function() {
let element = $(this);
let chapterId = element.data('chapter-id');
let active = element.is(':checked');
let url = '/admin/chapters/' + chapterId;

$.ajax({
type: "PUT",
url: url,
data: { chapter: { active: active } }
})
});
12 changes: 12 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,18 @@ en:
admin:
dashboard:
title: 'Admin'
chapters:
index:
'yes': 'Yes'
'no': 'No'
change_chapter_to_active_confirmation: 'Are you sure you want to make this chapter active?'
change_chapter_to_inactive_confirmation: 'Are you sure you want to make this chapter inactive?'
toggle_link: 'Toggle Active Status'
view_all_chapters: 'View All Chapters'
view_active_chapters: 'View Active Chapters'
view_inactive_chapters: 'View Inactive Chapters'
toggle_active:
message: 'Successfully toggled active status for %{name}'
jobs:
title: Manage jobs
info:
Expand Down
12 changes: 11 additions & 1 deletion spec/fabricators/chapter_fabricator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

Fabricator(:chapter) do
name { Fabricate.sequence(:name) }
city { Faker::Lorem.word }
city { Faker::Address.city }
email { Faker::Internet.email }
slug { Faker::Internet.slug }
twitter { Faker::Internet.url }
time_zone { 'London' }

after_save do |chapter|
Expand All @@ -30,3 +32,11 @@
email { Faker::Internet.email }
time_zone { 'London' }
end

Fabricator(:active_chapter, from: :chapter) do
active true
end

Fabricator(:inactive_chapter, from: :chapter) do
active false
end
94 changes: 94 additions & 0 deletions spec/features/admin/chapters_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,74 @@
end
end

context '#index' do
let!(:active_chapters) { Fabricate.times(3, :active_chapter) }
let!(:inactive_chapters) { Fabricate.times(3, :inactive_chapter) }

background { login_as_admin(member) }

scenario "an admin can view all chapters and their information" do
visit admin_chapters_path

assert_chapters_exist_on_page(active_chapters)
assert_chapters_exist_on_page(inactive_chapters)
end

scenario 'an admin can filter to view only active chapters' do
visit admin_chapters_path
click_link 'View Active Chapters'

assert_chapters_exist_on_page(active_chapters)
assert_chapters_not_exist_on_page(inactive_chapters)
end

scenario 'an admin can filter to view only inactive chapters' do
visit admin_chapters_path
click_link 'View Inactive Chapters'

assert_chapters_exist_on_page(inactive_chapters)
assert_chapters_not_exist_on_page(active_chapters)
end

scenario 'an admin can filter to view all chapters' do
visit admin_chapters_path
click_link 'View All Chapters'

assert_chapters_exist_on_page(inactive_chapters)
assert_chapters_exist_on_page(active_chapters)
end

scenario 'an admin can update the status of the active chapter', js: true do
visit admin_chapters_path
first_active_chapter = active_chapters.first

within(all('.row', text: first_active_chapter.email)[0]) do
set_chapter_active_checkbox(first_active_chapter.id, false)
end

page.accept_alert

wait_for_ajax

expect(first_active_chapter.reload).not_to be_active
end

scenario 'an admin can update the status of the inactive chapter', js: true do
visit admin_chapters_path
first_inactive_chapter = inactive_chapters.first

within(all('.row', text: first_inactive_chapter.email)[0]) do
set_chapter_active_checkbox(first_inactive_chapter.id, true)
end

page.accept_alert

wait_for_ajax

expect(first_inactive_chapter.reload).to be_active
end
end

context '#creating a new chapter' do
before do
login_as_admin(member)
Expand Down Expand Up @@ -122,4 +190,30 @@
expect(page).not_to have_content(coach_email)
end
end

private

def assert_chapters_exist_on_page(chapters)
chapters.each do |chapter|
expect(page).to have_link(chapter.name)
expect(page).to have_content(chapter.city)
expect(page).to have_content(chapter.slug)
expect(page).to have_content(chapter.email)
expect(page).to have_content(chapter.twitter)
end
end

def assert_chapters_not_exist_on_page(chapters)
chapters.each do |chapter|
expect(page).not_to have_link(chapter.name)
expect(page).not_to have_content(chapter.city)
expect(page).not_to have_content(chapter.slug)
expect(page).not_to have_content(chapter.email)
expect(page).not_to have_content(chapter.twitter)
end
end

def set_chapter_active_checkbox(id, value)
find("input[data-chapter-id='#{id}']").set(value)
end
end
15 changes: 15 additions & 0 deletions spec/support/wait_for_ajax.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module WaitForAjax
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def wait_for_ajax
Timeout.timeout(Capybara.default_max_wait_time) do
loop until finished_all_ajax_requests?
end
end

def finished_all_ajax_requests?
page.evaluate_script('jQuery.active').zero?
end
end

RSpec.configure do |config|
config.include WaitForAjax, type: :feature
end