Skip to content

Commit

Permalink
Add organization show page & download subscriptions button for org le…
Browse files Browse the repository at this point in the history
…aders

- Move chapters table into a partial for use on org show page
  • Loading branch information
lilliealbert committed Jul 18, 2016
1 parent 2443b77 commit 6ad1f46
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 33 deletions.
14 changes: 13 additions & 1 deletion app/assets/stylesheets/utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@
margin-bottom: 20px;
}

.mt20 {
margin-top: 20px;
}

.mt10 {
margin-top: 10px;
}

.p20 {
padding: 20px;
}

.inline-block {
display: inline-block;
}

.whitespace-nowrap {
white-space: nowrap;
}
}
18 changes: 18 additions & 0 deletions app/controllers/organizations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class OrganizationsController < ApplicationController
before_action :authenticate_user!, only: [:download_subscriptions]

def index
skip_authorization
@organizations = Organization.all
Expand All @@ -13,6 +15,22 @@ def index
.map { |e| ChapterEventLocation.new(e) }
end

def show
skip_authorization
@organization = Organization.find(params[:id])
end

def download_subscriptions
@organization = Organization.find(params[:organization_id])
authorize @organization, :manage_organization?

filename = "#{@organization.name.downcase.sub(' ', '_')}_subscribed_users_#{Date.today.strftime("%Y_%m_%d")}"

respond_to do |format|
format.csv { send_data @organization.subscription_csv, filename: filename }
end
end

private

class ChapterEventLocation
Expand Down
11 changes: 11 additions & 0 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'csv'

class Organization < ActiveRecord::Base
has_many :chapters, dependent: :destroy, inverse_of: :organization
has_many :leaders, through: :organization_leaderships, source: :user
Expand All @@ -12,4 +14,13 @@ def has_leader?(user)

user.organization_leaderships.map(&:organization_id).include?(id)
end

def subscription_csv
CSV.generate do |csv|
csv << ["email", "first_name", "last_name"]
users.each do |user|
csv << [user.email, user.first_name, user.last_name]
end
end
end
end
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ def event_role(event)
def event_checkiner?(event)
event_attendance(event)[:checkiner]
end

def organization_leader?(organization)
organization.leaders.include?(self)
end
end
7 changes: 6 additions & 1 deletion app/policies/organization_policy.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
class OrganizationPolicy < ApplicationPolicy

def manage_organization?
user.organization_leader?(record) || user.admin?
end

class Scope < Scope
def resolve
if user.admin?
Expand All @@ -8,4 +13,4 @@ def resolve
end
end
end
end
end
28 changes: 28 additions & 0 deletions app/views/chapters/_table.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<table class="table table-striped table-bordered table-condensed responsive-table datatable-sorted">
<thead>
<tr>
<th data-default-sort="asc">Name</th>
<th>Events</th>
<% if current_user.try(:admin?) %>
<th></th>
<% end %>
</tr>
</thead>

<tbody>
<% chapters.each do |chapter| %>
<tr>
<td><%= link_to chapter.name, chapter %></td>
<td data-label="Events:"><%= chapter.events_count + chapter.external_events_count %></td>
<td>
<% if policy(chapter).update? %>
<%= link_to 'Edit', edit_chapter_path(chapter), class: 'btn fa-before fa-edit' %>
<% end %>
<% if current_user.try(:admin?) && chapter.destroyable? %>
<%= link_to 'Destroy', chapter, data: {confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-danger' %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
31 changes: 2 additions & 29 deletions app/views/chapters/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,32 +1,5 @@
<%= content_for(:header_text, 'Listing chapters') %>
<table class="table table-striped table-bordered table-condensed responsive-table datatable-sorted">
<thead>
<tr>
<th data-default-sort="asc">Name</th>
<th>Events</th>
<% if current_user.try(:admin?) %>
<th></th>
<% end %>
</tr>
</thead>
<%= render 'table', chapters: @chapters %>
<tbody>
<% @chapters.each do |chapter| %>
<tr>
<td><%= link_to chapter.name, chapter %></td>
<td data-label="Events:"><%= chapter.events_count + chapter.external_events_count %></td>
<td>
<% if policy(chapter).update? %>
<%= link_to 'Edit', edit_chapter_path(chapter), class: 'btn fa-before fa-edit' %>
<% end %>
<% if current_user.try(:admin?) && chapter.destroyable? %>
<%= link_to 'Destroy', chapter, data: {confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-danger' %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>

<%= render 'shared/actions', links: crud_object_nav_links(:chapter, policy(Chapter).new? ? ['New Chapter', new_chapter_path] : nil) %>
<%= render 'shared/actions', links: crud_object_nav_links(:chapter, policy(Chapter).new? ? ['New Chapter', new_chapter_path] : nil) %>
2 changes: 1 addition & 1 deletion app/views/organizations/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<% @organizations.sort_by(&:name).each do |org| %>
<% if org.chapters.count > 0 %>
<h2><%= org.name %></h2>
<h2><%= link_to org.name, organization_path(org) %></h2>
<div><% org.chapters.count %><%= pluralize(org.chapters.count, 'chapter') %></div>
<% if org.leaders.length > 0 %>
<div>Leaders:</div>
Expand Down
25 changes: 25 additions & 0 deletions app/views/organizations/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h1><%= @organization.name %></h1>

<% if @organization.leaders.present? %>
<h2>Organization Leaders</h2>
<i>These are people who can approve Bridge Troll postings for any <%= @organization.name %> event.</i>
<ul>
<% @organization.leaders.each do |leader| %>
<li><%= link_to leader.full_name, user_profile_path(leader) %></li>
<% end %>
</ul>
<% end %>
<% if policy(@organization).manage_organization? %>
<div class="org-leader-tools bg-info p20">
<h2>Organization Leader Tools</h2>
<i>This section is only visible to admins & organization leaders.</i>
<p>
<%= link_to "Download subscribed user email addresses", organization_download_subscriptions_path(@organization, format: :csv), class: "btn mt10" %>
</p>
</div>
<% end %>

<h2 class="mt20">Chapters</h2>

<%= render 'chapters/table', chapters: @organization.chapters %>
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
end
end

resources :organizations, only: [:index]
resources :organizations, only: [:index, :show] do
get :download_subscriptions
end

resources :events do
resources :organizers, only: [:index, :create, :destroy] do
Expand Down
44 changes: 44 additions & 0 deletions spec/controllers/organizations_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'rails_helper'

describe OrganizationsController do
let(:organization) { create :organization, name: "RailsBridge" }

describe "permissions" do
context "a user that is not logged in" do
it "can not download a subscription list" do
expect(
get :download_subscriptions, organization_id: organization.id
).to redirect_to(new_user_session_path)
end
end
end

describe '#download_subscriptions' do
context "logged in as an organization leader" do
let(:organization_leader) { create :user }
let(:subscriber) { create :user, email: "seven_lemurs@example.com" }

before do
sign_in organization_leader
organization.leaders << organization_leader
OrganizationSubscription.create(subscribed_organization: organization, user: subscriber)
end

it "should return the subscribed users" do
expect(
get :download_subscriptions, organization_id: organization.id, format: :csv
).to be_success
expect(response.headers["Content-Disposition"]).to include "railsbridge_subscribed_users"
expect(response.body).to include "seven_lemurs@example.com"
end
end

context "logged in as a regular user" do
it "should redirect" do
expect(
get :download_subscriptions, organization_id: organization.id
).to be_redirect
end
end
end
end
18 changes: 18 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,22 @@
expect(@user.profile_path).to eq(Rails.application.routes.url_helpers.user_profile_path(@user))
end
end
``
describe "#organization_leader?" do
let(:org) { create :organization }

subject { @user.organization_leader?(org) }

context "when they're an org leader" do
before do
org.leaders << @user
end

it { is_expected.to be true }
end

context "when they're not an org leader" do
it { is_expected.to be false }
end
end
end

0 comments on commit 6ad1f46

Please sign in to comment.