Skip to content

Commit

Permalink
Merge pull request #113 from openjournals/collections
Browse files Browse the repository at this point in the history
User-curated collections
  • Loading branch information
arfon committed Jun 1, 2015
2 parents 9c25bb0 + c64aa5d commit 8b7b024
Show file tree
Hide file tree
Showing 41 changed files with 566 additions and 26 deletions.
7 changes: 7 additions & 0 deletions app/assets/javascripts/collections.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$ ->
$(".collection-idea-button").click ->
this.remove()
2 changes: 2 additions & 0 deletions app/assets/javascripts/ideas.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

$ ->
$("[data-toggle='tooltip']").tooltip()
$('.collect-toggle').dropdown()
$('.dropdown-toggle').dropdown()

counter = ->
value = $("#idea-body").val()
Expand Down
6 changes: 5 additions & 1 deletion app/assets/stylesheets/ideas.css.sass
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ button
&.tag-link
margin-bottom: 5px

&.vote
&.vote, &.hide-it
margin-right: 5px

&.dismiss:hover
Expand Down Expand Up @@ -143,3 +143,7 @@ ul.similar

input.email-address
width: 230px

button.collection-idea-button
display: block
margin-bottom: 5px
17 changes: 11 additions & 6 deletions app/assets/stylesheets/jquery.textcomplete.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* Sample */

.dropdown-menu {
ul.dropdown-menu {
border: 1px solid #ddd;
background-color: white;
padding: 0px;
}

.dropdown-menu li {
Expand All @@ -14,9 +13,15 @@
border-top: none;
}

.dropdown-menu li:hover,
.dropdown-menu .active {
background-color: rgb(110, 183, 219);
ul.dropdown-menu li a,
ul.dropdown-menu li a:hover {
background-color: white;
padding: 5px
}

.dropdown-menu li.new-collection a,
.dropdown-menu li.new-collection a:hover {
font-weight: bold;
}


Expand Down
84 changes: 84 additions & 0 deletions app/controllers/collections_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
class CollectionsController < ApplicationController
before_filter :require_user, :except => [ :show ]

def new
@collection = Collection.new

if @idea = Idea.find_by_sha(params[:idea_id])
@collection.ideas << @idea
end
end

def show
@collection = Collection.find_by_sha(params[:id])

respond_to do |format|
format.atom { render :atom => @collection, :include => [ :ideas ] }
format.json { render :json => @collection, :include => [ :ideas ] }
format.html
end
end

def create
@collection = Collection.new(collection_params)
@collection.user = current_user

if @collection.save
set_ideas
redirect_to collection_path(@collection), :notice => "Collection created"
end
end

def edit
@collection = Collection.find_by_sha(params[:id])
redirect_to collections_path, :warning => "Collection not found" unless @collection

# Redirect if not owner
redirect_to collection_path(@collection) unless @collection.owner == current_user
end

def update
@collection = Collection.find_by_sha(params[:id])
redirect_to collections_path, :warning => "Collection not found" unless @collection
redirect_to collection_path(@collection) unless @collection.owner == current_user

set_ideas

redirect_to collection_path(@collection), :notice => "Collection updated"
end

def add_idea
@collection = Collection.find_by_sha(params[:id])
@idea = Idea.find_by_sha(params[:idea_id])
@collection.ideas << @idea unless @collection.ideas.include?(@idea)
redirect_to collection_path(@collection), :notice => "Idea added"
end

def destroy
@collection = Collection.find_by_sha(params[:id])
redirect_to collections_path, :warning => "Collection not found" unless @collection
redirect_to collection_path(@collection) unless @collection.owner == current_user

if @collection.destroy
redirect_to collections_path, :warning => "Collection deleted"
end
end

private

def set_ideas
@collection.collection_ideas.destroy_all

# This will be empty if there are no ideas
return true unless params['collection']['ideas']

params['collection']['ideas'].each do |_, idea_sha|
@idea = Idea.find_by_sha(idea_sha)
@collection.ideas << @idea if @idea
end
end

def collection_params
params.require(:collection).permit(:name, :description)
end
end
5 changes: 3 additions & 2 deletions app/controllers/ideas_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ class IdeasController < ApplicationController
respond_to :json, :html, :atom

def index
@ideas = Idea.by_date.recent.visible.for_user(current_user).paginate(:page => params[:page], :per_page => 10)

@ideas = Idea.by_date.visible.for_user(current_user).limit(10)
@recent = true

respond_to do |format|
format.atom
format.json { render :json => @ideas }
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
class UsersController < ApplicationController
respond_to :json, :html

def collections
@user = User.find_by_sha(params[:id])
@collections = @user.collections.paginate(:page => params[:page], :per_page => 10)
end

def show
@user = User.find_by_sha(params[:id])
@ideas = @user.ideas.paginate(:page => params[:page], :per_page => 10)
Expand Down
2 changes: 0 additions & 2 deletions app/helpers/search_helper.rb

This file was deleted.

2 changes: 0 additions & 2 deletions app/helpers/sessions_helper.rb

This file was deleted.

2 changes: 0 additions & 2 deletions app/helpers/users_helper.rb

This file was deleted.

2 changes: 0 additions & 2 deletions app/helpers/votes_helper.rb

This file was deleted.

21 changes: 21 additions & 0 deletions app/models/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Collection < ActiveRecord::Base
belongs_to :user
has_many :collection_ideas, :dependent => :destroy
has_many :ideas, :through => :collection_ideas

before_create :set_sha

def to_param
sha
end

def owner
user
end

private

def set_sha
self.sha = SecureRandom.hex
end
end
5 changes: 5 additions & 0 deletions app/models/collection_idea.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class CollectionIdea < ActiveRecord::Base
belongs_to :collection
belongs_to :idea

end
3 changes: 3 additions & 0 deletions app/models/idea.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class Idea < ActiveRecord::Base
has_many :votes
has_many :audit_logs

has_many :collection_ideas
has_many :collections, :through => :collection_ideas

# Citations/references
has_many :idea_references
has_many :references, :through => :idea_references, :source => 'referenced'
Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class User < ActiveRecord::Base
has_many :ideas
has_many :votes
has_many :audit_logs
has_many :collections

before_create :set_sha

Expand Down
15 changes: 15 additions & 0 deletions app/views/collections/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<%= render 'layouts/errors', :object => @collection %>

<%= form_for @collection, :html => {:data => {:toggle => "validator"}} do |f| %>
<div class="form-group">
<%= f.label :name, :class => "control-label" %>
<%= f.text_field :name, :class => "form-control", "placeholder" => "Enter your collection name", :required => "" %>
<div class="help-block with-errors"></div>
</div>

<%= render :partial => "ideas", :locals => { :form => f } %>

<%= f.button :class => 'btn btn-default' %>
<% end %>

<%= button_to "Delete Collection", collection_path(:id => @collection.to_param), :method => :delete, :class => 'btn btn-danger', :style => "width:140px;margin-top:5px", :data => {:confirm => 'Are you sure?'} unless @collection.new_record? %>
16 changes: 16 additions & 0 deletions app/views/collections/_ideas.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="form-group">
<%= form.label :ideas, :class => "control-label" %>

<% if @collection.ideas.any? %>
<div class="collection-ideas">
<% @collection.ideas.each_with_index do |idea, index| %>
<button type="button" class="btn btn-default btn-sm collection-idea-button">
<%= idea.title %> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
<%= form.hidden_field "ideas[#{index}]", :value => idea.sha %>
</button>
<% end %>
</div>
<% else %>
<p>This collection has no ideas</p>
<% end %>
</div>
26 changes: 26 additions & 0 deletions app/views/collections/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div class="page-header">
<h1>Edit Collection</h1>
</div>

<div class="row form">
<div class="col-sm-8">
<%= render :partial => 'shared/flashes', :locals => { :flash => flash } %>
<%= render :partial => "users/email" unless current_user.email? %>
<%= render :partial => "form" %>
</div>
<div class="col-sm-3 col-sm-offset-1">
<div class="login-block">
<p class="name"><%= current_user.name %> &middot; <%= link_to "Sign out", signout_path %></p>
</div>

<div class="helper-block">
<h5>About Collections</h5>
<p>Collections are a way for you to group ideas and share these curated collections with others.</p>
</div>

<div class="helper-block">
<h5>Formatting</h5>
<p>You can use Markdown to format your ideas. Read more about the supported syntax <a href="https://help.github.com/articles/github-flavored-markdown/" target="_blank">here</a>.</p>
</div>
</div>
</div>
27 changes: 27 additions & 0 deletions app/views/collections/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="page-header">
<h1>Create a new collection</h1>
</div>

<div class="row form">
<div class="col-sm-8">
<%= render :partial => 'shared/flashes', :locals => { :flash => flash } %>
<%= render :partial => "users/email" unless current_user.email? %>
<%= render :partial => "form" %>
</div>
<div class="col-sm-3 col-sm-offset-1">
<div class="login-block">
<p class="name"><%= current_user.name %> &middot; <%= link_to "Sign out", signout_path %></p>
</div>

<div class="helper-block">
<h5>About Collections</h5>
<p>Collections are a way for you to group ideas and share these curated collections with others.</p>
</div>

<div class="helper-block">
<h5>Formatting</h5>
<p>You can use Markdown to format your ideas. Read more about the supported syntax <a href="https://help.github.com/articles/github-flavored-markdown/" target="_blank">here</a>.</p>
</div>

</div>
</div>
16 changes: 16 additions & 0 deletions app/views/collections/show.atom.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
atom_feed do |feed|
feed.title("Journal of Brief Ideas: Collection #{@collection.name}")
feed.updated(@collection.collection_ideas.last.created_at) if @collection.ideas.length > 0

@collection.ideas.each do |idea|
feed.entry(idea) do |entry|
entry.title(idea.title)
entry.doi(idea.doi)
entry.content(idea.body, type: 'html')

entry.author do |author|
author.name(idea.user.name)
end
end
end
end
30 changes: 30 additions & 0 deletions app/views/collections/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div class="page-header">
<h1><%= @collection.name %></h1>
</div>

<div class="row form">
<div class="col-sm-8">
<%= render :partial => 'shared/flashes', :locals => { :flash => flash } %>
<p class="lead"><em>Curated by <%= link_to @collection.user.nice_name, user_path(@collection.user) %></em></p>

<% if @collection.ideas.any? %>
<%= render :partial => "ideas/idea", :collection => @collection.ideas.visible %>
<% else %>
<p>This collection doesn't have any ideas.</p>
<% end %>

</div>
<div class="col-sm-3 col-sm-offset-1">
<%= render :partial => 'sessions/login' %>

<div class="help-block">
<% if current_user && @collection.owner == current_user %>
<h5>Manage collection</h5>
<p><%= link_to "Edit collection", edit_collection_path(@collection) %></p>
<% end %>

<h5>Subscribe</h5>
<p><%= image_tag "feed-icon-14x14.png" %> &middot; <%= link_to "Subscribe to this collection", collection_path(@collection, :format => :atom) %></p>
</div>
</div>
</div>
4 changes: 2 additions & 2 deletions app/views/ideas/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<% elsif @all %>
<h1>All ideas</h1>
<% else %>
<h1>Ideas from the last week</h1>
<h1>Recent ideas</h1>
<% end %>
</div>

Expand All @@ -20,7 +20,7 @@
<% end %>

<div class="text-center">
<%= will_paginate @ideas, renderer: BootstrapPagination::Rails %>
<%= will_paginate @ideas, renderer: BootstrapPagination::Rails unless @recent %>
</div>
</div>

Expand Down
1 change: 0 additions & 1 deletion app/views/ideas/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
</div>
<div class="col-sm-3 col-sm-offset-1">
<div class="login-block">
<%= image_tag current_user.avatar_url, :class => "avatar" %>
<p class="name"><%= current_user.name %> &middot; <%= link_to "Sign out", signout_path %></p>
</div>

Expand Down
Loading

0 comments on commit 8b7b024

Please sign in to comment.