Skip to content

Commit

Permalink
Merge pull request #303 from mumuki/issue-#301-next-button-on-pending…
Browse files Browse the repository at this point in the history
…-exercises

Adding repeat pending button
  • Loading branch information
flbulgarelli committed Sep 11, 2015
2 parents 51c57dc + d3327ff commit 114bd11
Show file tree
Hide file tree
Showing 22 changed files with 264 additions and 72 deletions.
11 changes: 2 additions & 9 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,8 @@ def tab_list(tabs)
'</ul>').html_safe
end

def next_guides_box(guide, options={})
return if guide.path.blank?

suggested = guide.next_guides
if suggested.empty?
t :path_finished, path: link_to_path(guide.path)
else
link_to t(:next_guide, name: suggested.first.name), suggested.first, class: 'btn btn-success'
end
def path_finished(guide)
t :path_finished_html, path: link_to_path(@guide.path) if @guide.path
end

def corollary_box(with_corollary)
Expand Down
10 changes: 3 additions & 7 deletions app/helpers/concerns/with_navigation.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
module WithNavigation
def next_button(navigable)
sibling_button(navigable.next_for(current_user), :next_exercise, 'chevron-right', 'btn btn-success', true)
ContinueNavigation.new(self).button(navigable) || RevisitNavigation.new(self).button(navigable)
end

def next_nav_button(navigable)
sibling_button(navigable.next, :next_exercise, 'chevron-circle-right', 'text-info', true)
ForwardNavigation.new(self).button(navigable)
end

def previous_nav_button(navigable)
sibling_button(navigable.previous, :previous_exercise, 'chevron-circle-left', 'text-info')
end

def sibling_button(sibling, key, icon, clazz, right=false)
link_to fa_icon(icon, text: t(key), right: right), sibling, class: clazz if sibling
BackwardNavigation.new(self).button(navigable)
end
end
7 changes: 7 additions & 0 deletions app/helpers/concerns/with_navigation/anonymous_navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module WithNavigation
module AnonymousNavigation
def clazz
'text-info'
end
end
end
17 changes: 17 additions & 0 deletions app/helpers/concerns/with_navigation/backward_navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module WithNavigation
class BackwardNavigation < Navigation
include AnonymousNavigation

def icon
'chevron-circle-left'
end

def key
:navigation_previous
end

def sibling_for(navigable)
navigable.previous
end
end
end
23 changes: 23 additions & 0 deletions app/helpers/concerns/with_navigation/continue_navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module WithNavigation
class ContinueNavigation < Navigation
def right
true
end

def icon
'chevron-right'
end

def key
:navigation_continue
end

def clazz
'btn btn-success'
end

def sibling_for(navigable)
navigable.next_for(current_user)
end
end
end
21 changes: 21 additions & 0 deletions app/helpers/concerns/with_navigation/forward_navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module WithNavigation
class ForwardNavigation < Navigation
include AnonymousNavigation

def right
true
end

def icon
'chevron-circle-right'
end

def key
:navigation_next
end

def sibling_for(navigable)
navigable.next
end
end
end
24 changes: 24 additions & 0 deletions app/helpers/concerns/with_navigation/navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module WithNavigation
class Navigation
def initialize(template)
@template = template
end

def button(navigable)
sibling = sibling_for(navigable)
link_to link_icon(sibling), sibling, class: clazz if sibling && sibling != navigable
end

def link_icon(sibling)
fa_icon(icon, text: I18n.t(key, sibling: sibling.name), right: right)
end

def right
false
end

def method_missing(name, *args, &block)
@template.send(name, *args, &block)
end
end
end
23 changes: 23 additions & 0 deletions app/helpers/concerns/with_navigation/revisit_navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module WithNavigation
class RevisitNavigation < Navigation
def right
true
end

def icon
'chevron-right'
end

def key
:navigation_revisit
end

def clazz
'btn btn-warning'
end

def sibling_for(navigable)
navigable.first_for(current_user)
end
end
end
1 change: 0 additions & 1 deletion app/models/concerns/with_exercises.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def exercises_count

def pending_exercises(user)
exercises.
at_locale.
joins("left join solutions
on solutions.exercise_id = exercises.id
and solutions.submitter_id = #{user.id}
Expand Down
12 changes: 2 additions & 10 deletions app/models/concerns/with_guide.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,8 @@ module WithGuide
belongs_to :guide
end

def next_for(user)
sibling_for user, 'exercises.position > :position', 'exercises.position asc'
end

def previous_for(user)
sibling_for user, 'exercises.position < :position', 'exercises.position desc'
end

def sibling_for(user, query, order)
guide.pending_exercises(user).where(query, position: position).order(order).first if guide
def siblings_for(user)
guide.pending_exercises(user)
end

def siblings
Expand Down
12 changes: 12 additions & 0 deletions app/models/concerns/with_guides.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ module WithGuides
has_many :guides, -> { order(:position) }
end

def pending_guides(user)
guides.
joins('left join exercises
on exercises.guide_id = guides.id').
joins("left join solutions
on solutions.exercise_id = exercises.id
and solutions.submitter_id = #{user.id}
and solutions.status = #{Status::Passed.to_i}").
where('solutions.id is null').
uniq
end

def first_guide
guides.first
end
Expand Down
5 changes: 2 additions & 3 deletions app/models/concerns/with_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ module WithPath
belongs_to :path
end

def next_guides
path ? siblings.where('guides.position > :position', position: position).order('guides.position asc') : []
def siblings_for(user)
path.pending_guides(user)
end


def siblings
path.guides
end
Expand Down
22 changes: 22 additions & 0 deletions app/models/concerns/with_siblings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ def previous
siblings.where(position: position - 1).first unless orphan?
end

def next_for(user)
sibling_for user, "#{qualified_position} > :position", "#{qualified_position} asc"
end

def previous_for(user)
sibling_for user, "#{qualified_position} < :position", "#{qualified_position} desc"
end

def sibling_for(user, query, order)
siblings_for(user).where(query, position: position).order(order).first if parent
end

def first_for(user)
siblings_for(user).order(position: :asc).first if parent
end

def orphan?
parent.nil?
end
Expand All @@ -24,5 +40,11 @@ def contextualized_name
name
end
end

private

def qualified_position
"#{self.class.table_name}.position"
end
end

3 changes: 0 additions & 3 deletions app/models/exercise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class Exercise < ActiveRecord::Base

acts_as_taggable


enum layout: [:editor_right, :editor_bottom, :no_editor, :scratchy]

after_initialize :defaults, if: :new_record?
Expand All @@ -33,7 +32,6 @@ class Exercise < ActiveRecord::Base

markup_on :description, :hint, :teaser, :corollary


def self.create_or_update_for_import!(guide, original_id, options)
exercise = find_or_initialize_by(original_id: original_id, guide_id: guide.id)
exercise.assign_attributes(options)
Expand Down Expand Up @@ -75,7 +73,6 @@ def guide_expectations
if guide.present? then guide.expectations else [] end
end


def generate_custom_slug
if guide
"#{guide.name}-#{position}-#{name}"
Expand Down
3 changes: 1 addition & 2 deletions app/views/exercise_solutions/_results.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@
fa_icon(:bug, text: t(:notify_problem_to_author)),
subject: t(:problem_with_exercise, title: solution.exercise.name),
class: 'text-warning warning pull-left' %>
<%= next_button(@exercise) %>
<%= next_guides_box(@guide) if @stats.try &:done? %>
<%= next_button(@exercise) || next_button(@guide) %>
</div>

<script>
Expand Down
4 changes: 2 additions & 2 deletions app/views/exercises/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@
</div>
<div class="row">
<div class="col-md-12 text-center">
<%= next_guides_box(@guide) %>
<%= next_button(@guide) || path_finished(@guide) %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<% end if @guide %>
<% end if @guide && current_user? %>
2 changes: 1 addition & 1 deletion app/views/guides/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
<% if @stats.try :done? %>
<%= corollary_box(@guide) %>
<div class="actions">
<%= next_guides_box @guide %>
<%= next_button @guide %>
</div>
<% else %>
<div class="row">
Expand Down
6 changes: 5 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ en:
need_a_hint: "Do you need a hint?"
about: "About"
sending_solution: "Sending solution"
path_finished: "You have finished this path!"
path_finished_html: "You have finished %{path}!"
editor: "Editor"
console: "Console"
type_expressions_here: "You can type expressions here to test your solution"
navigation_continue: 'Next: %{sibling}'
navigation_previous: 'Previous'
navigation_next: 'Next'
navigation_revisit: 'Next pending: %{sibling}'
6 changes: 5 additions & 1 deletion config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,11 @@ es:
recent_activity: "Actividad Reciente"
created_exercises: "Ejercicios Creados"
created_guides: "Guías Creadas"
path_finished: "¡Terminaste esta categoría! ¡Felicitaciones!"
path_finished_html: "¡Terminaste %{path}! ¡Felicitaciones!"
editor: "Editor"
console: "Consola"
type_expressions_here: "Acá podés escribir expresiones para probar tu solución"
navigation_continue: 'Siguiente: %{sibling}'
navigation_previous: 'Anterior'
navigation_next: 'Siguiente'
navigation_revisit: 'Siguiente pendiente: %{sibling}'
24 changes: 0 additions & 24 deletions spec/helpers/application_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,4 @@
it { expect(status_icon(failed_submission)).to eq '<i class="fa fa-times text-danger special-icon"></i>' }
end

describe '#next_guides_box' do
let(:path) { create(:path) }

context 'when guide has no suggestions' do
let(:guide) { create(:guide, position: 1, path: path) }
it { expect(next_guides_box(guide)).to eq 'You have finished this path!' }
end

context 'when guide has one suggestion' do
let!(:suggested_guide) { create(:guide, position: 2, path: path) }
let(:guide) { create(:guide, position: 1, path: path) }

it { expect(next_guides_box(guide)).to include "<a class=\"btn btn-success\" href=\"/guides/#{suggested_guide.slug}\">Next Guide: #{suggested_guide.name}</a>" }
end

context 'when guide has many suggestions' do
let!(:suggested_guide_1) { create(:guide, position: 2, path: path) }
let!(:suggested_guide_2) { create(:guide, position: 2, path: path) }
let(:guide) { create(:guide, position: 1, path: path) }

it { expect(next_guides_box(guide)).to include "<a class=\"btn btn-success\" href=\"/guides/#{suggested_guide_1.slug}\">Next Guide: #{suggested_guide_1.name}</a>" }
it { expect(next_guides_box(guide)).to be_html_safe } end
end

end
Loading

0 comments on commit 114bd11

Please sign in to comment.