Commit 04cdb2ec8738b2aa542b0cadaee273dd18c7ad3d

Authored by damau
1 parent 7fd532c9
Exists in master and in 1 other branch production

adds a search bar to issues closes issue #367

app/controllers/problems_controller.rb
@@ -7,8 +7,8 @@ class ProblemsController < ApplicationController @@ -7,8 +7,8 @@ class ProblemsController < ApplicationController
7 7
8 def index 8 def index
9 app_scope = current_user.admin? ? App.all : current_user.apps 9 app_scope = current_user.admin? ? App.all : current_user.apps
10 -  
11 - @problems = Problem.for_apps(app_scope).in_env(params[:environment]).unresolved.ordered_by(@sort, @order) 10 + @all_errs = params[:all_errs]
  11 + @problems = Problem.for_apps(app_scope).in_env(params[:environment]).all_else_unresolved(@all_errs).ordered_by(@sort, @order)
12 @selected_problems = params[:problems] || [] 12 @selected_problems = params[:problems] || []
13 respond_to do |format| 13 respond_to do |format|
14 format.html do 14 format.html do
@@ -18,11 +18,11 @@ class ProblemsController < ApplicationController @@ -18,11 +18,11 @@ class ProblemsController < ApplicationController
18 end 18 end
19 end 19 end
20 20
21 - def all  
22 - app_scope = current_user.admin? ? App.all : current_user.apps  
23 - @problems = Problem.for_apps(app_scope).ordered_by(@sort, @order).page(params[:page]).per(current_user.per_page)  
24 - @selected_problems = params[:problems] || []  
25 - end 21 +# def all
  22 +# app_scope = current_user.admin? ? App.all : current_user.apps
  23 +# @problems = Problem.for_apps(app_scope).ordered_by(@sort, @order).page(params[:page]).per(current_user.per_page)
  24 +# @selected_problems = params[:problems] || []
  25 +# end
26 26
27 def show 27 def show
28 @notices = @problem.notices.reverse_ordered.page(params[:notice]).per(1) 28 @notices = @problem.notices.reverse_ordered.page(params[:notice]).per(1)
@@ -92,9 +92,12 @@ class ProblemsController < ApplicationController @@ -92,9 +92,12 @@ class ProblemsController < ApplicationController
92 end 92 end
93 93
94 def search 94 def search
95 - app_scope = current_user.admin? ? App.all : current_user.apps  
96 -  
97 - @problems = Problem.for_apps(app_scope).in_env(params[:environment]).unresolved.ordered_by(@sort, @order) 95 + if params[:app_id]
  96 + app_scope = App.where(:_id => params[:app_id])
  97 + else
  98 + app_scope = current_user.admin? ? App.all : current_user.apps
  99 + end
  100 + @problems = Problem.search(params[:search]).for_apps(app_scope).in_env(params[:environment]).all_else_unresolved(params[:all_errs]).ordered_by(@sort, @order)
98 @selected_problems = params[:problems] || [] 101 @selected_problems = params[:problems] || []
99 @problems = @problems.page(params[:page]).per(current_user.per_page) 102 @problems = @problems.page(params[:page]).per(current_user.per_page)
100 render :content_type => 'text/javascript' 103 render :content_type => 'text/javascript'
app/models/problem.rb
@@ -40,19 +40,27 @@ class Problem @@ -40,19 +40,27 @@ class Problem
40 has_many :comments, :inverse_of => :err, :dependent => :destroy 40 has_many :comments, :inverse_of => :err, :dependent => :destroy
41 41
42 before_create :cache_app_attributes 42 before_create :cache_app_attributes
43 - 43 +
44 scope :resolved, where(:resolved => true) 44 scope :resolved, where(:resolved => true)
45 scope :unresolved, where(:resolved => false) 45 scope :unresolved, where(:resolved => false)
46 scope :ordered, order_by(:last_notice_at.desc) 46 scope :ordered, order_by(:last_notice_at.desc)
47 scope :for_apps, lambda {|apps| where(:app_id.in => apps.all.map(&:id))} 47 scope :for_apps, lambda {|apps| where(:app_id.in => apps.all.map(&:id))}
48 48
49 validates_presence_of :last_notice_at, :first_notice_at 49 validates_presence_of :last_notice_at, :first_notice_at
50 -  
51 - 50 +
  51 +
  52 + def self.all_else_unresolved all
  53 + if all
  54 + find(:all)
  55 + else
  56 + where(:resolved => false)
  57 + end
  58 + end
  59 +
52 def self.in_env(env) 60 def self.in_env(env)
53 env.present? ? where(:environment => env) : scoped 61 env.present? ? where(:environment => env) : scoped
54 end 62 end
55 - 63 +
56 def notices 64 def notices
57 Notice.for_errs(errs).ordered 65 Notice.for_errs(errs).ordered
58 end 66 end
@@ -60,20 +68,20 @@ class Problem @@ -60,20 +68,20 @@ class Problem
60 def comments_allowed? 68 def comments_allowed?
61 Errbit::Config.allow_comments_with_issue_tracker || !app.issue_tracker_configured? 69 Errbit::Config.allow_comments_with_issue_tracker || !app.issue_tracker_configured?
62 end 70 end
63 - 71 +
64 def resolve! 72 def resolve!
65 self.update_attributes!(:resolved => true, :resolved_at => Time.now) 73 self.update_attributes!(:resolved => true, :resolved_at => Time.now)
66 end 74 end
67 - 75 +
68 def unresolve! 76 def unresolve!
69 self.update_attributes!(:resolved => false, :resolved_at => nil) 77 self.update_attributes!(:resolved => false, :resolved_at => nil)
70 end 78 end
71 - 79 +
72 def unresolved? 80 def unresolved?
73 !resolved? 81 !resolved?
74 end 82 end
75 -  
76 - 83 +
  84 +
77 def self.merge!(*problems) 85 def self.merge!(*problems)
78 problems = problems.flatten.uniq 86 problems = problems.flatten.uniq
79 merged_problem = problems.shift 87 merged_problem = problems.shift
@@ -85,11 +93,11 @@ class Problem @@ -85,11 +93,11 @@ class Problem
85 merged_problem.reset_cached_attributes 93 merged_problem.reset_cached_attributes
86 merged_problem 94 merged_problem
87 end 95 end
88 - 96 +
89 def merged? 97 def merged?
90 errs.length > 1 98 errs.length > 1
91 end 99 end
92 - 100 +
93 def unmerge! 101 def unmerge!
94 problem_errs = errs.to_a 102 problem_errs = errs.to_a
95 problem_errs.shift 103 problem_errs.shift
@@ -102,7 +110,7 @@ class Problem @@ -102,7 +110,7 @@ class Problem
102 end 110 end
103 end 111 end
104 112
105 - 113 +
106 def self.ordered_by(sort, order) 114 def self.ordered_by(sort, order)
107 case sort 115 case sort
108 when "app"; order_by(["app_name", order]) 116 when "app"; order_by(["app_name", order])
@@ -171,6 +179,10 @@ class Problem @@ -171,6 +179,10 @@ class Problem
171 (app.issue_tracker_configured? && app.issue_tracker.label) || nil 179 (app.issue_tracker_configured? && app.issue_tracker.label) || nil
172 end 180 end
173 181
  182 + def self.search(value)
  183 + where.or(error_class: /#{value}/i).or(where: /#{value}/i).or(message: /#{value}/i).or(app_name: /#{value}/i).or(environment: /#{value}/i)
  184 + end
  185 +
174 private 186 private
175 def attribute_count_increase(name, value) 187 def attribute_count_increase(name, value)
176 counter, index = send(name), attribute_index(value) 188 counter, index = send(name), attribute_index(value)
@@ -195,6 +207,5 @@ class Problem @@ -195,6 +207,5 @@ class Problem
195 def attribute_index(value) 207 def attribute_index(value)
196 Digest::MD5.hexdigest(value.to_s) 208 Digest::MD5.hexdigest(value.to_s)
197 end 209 end
198 -  
199 end 210 end
200 211
app/views/apps/show.html.haml
@@ -82,7 +82,13 @@ @@ -82,7 +82,13 @@
82 82
83 - if @app.problems.any? 83 - if @app.problems.any?
84 %h3.clear Errors 84 %h3.clear Errors
85 - = render 'problems/table', :problems => @problems 85 + %section
  86 + = form_tag search_problems_path(:all_errs => @all_errs, :app_id => @app.id), :method => :get, :remote => true do
  87 + = text_field_tag :search, params[:search], :placeholder => 'Search for issues'
  88 + %br
  89 + %section
  90 + .problem_table{:id => 'problem_table'}
  91 + = render 'problems/table', :problems => @problems
86 - else 92 - else
87 %h3.clear No errs have been caught yet, make sure you setup your app 93 %h3.clear No errs have been caught yet, make sure you setup your app
88 = render 'configuration_instructions', :app => @app 94 = render 'configuration_instructions', :app => @app
app/views/problems/index.html.haml
1 -- content_for :title, 'Unresolved Errors' 1 +- content_for :title, @all_errs ? 'All Errors' : 'Unresolved Errors'
2 - content_for :head do 2 - content_for :head do
3 = auto_discovery_link_tag :atom, problems_path(User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices at #{request.host}" 3 = auto_discovery_link_tag :atom, problems_path(User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices at #{request.host}"
4 - content_for :action_bar do 4 - content_for :action_bar do
5 - = link_to 'show resolved', all_problems_path, :class => 'button'  
6 -= render 'table', :problems => @problems 5 + - if @all_errs
  6 + = link_to 'hide resolved', problems_path, :class => 'button'
  7 + - else
  8 + = link_to 'show resolved', problems_path(:all_errs => true), :class => 'button'
  9 +%section
  10 + = form_tag search_problems_path(:all_errs => @all_errs), :method => :get, :remote => true do
  11 + = text_field_tag :search, params[:search], :placeholder => 'Search for issues'
  12 +%br
  13 +%section
  14 + .problem_table{:id => 'problem_table'}
  15 + = render 'problems/table', :problems => @problems
app/views/problems/search.js.haml 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +$("#problem_table").empty().append("#{escape_javascript(render('problems/table', :problems => @problems))}");
  2 +$.getScript('/assets/errbit.js')
  3 +$("#flash-messages").empty()
  4 +
  5 +
config/routes.rb
@@ -22,6 +22,7 @@ Errbit::Application.routes.draw do @@ -22,6 +22,7 @@ Errbit::Application.routes.draw do
22 post :merge_several 22 post :merge_several
23 post :unmerge_several 23 post :unmerge_several
24 get :all 24 get :all
  25 + get :search, :format => [:js]
25 end 26 end
26 end 27 end
27 28
spec/models/problem_spec.rb
@@ -185,9 +185,20 @@ describe Problem do @@ -185,9 +185,20 @@ describe Problem do
185 Problem.unresolved.all.should include(unresolved) 185 Problem.unresolved.all.should include(unresolved)
186 end 186 end
187 end 187 end
188 - end  
189 -  
190 188
  189 + context "searching" do
  190 + it 'finds the correct record' do
  191 + find = Fabricate(:problem, :resolved => false, :error_class => 'theErrorclass::other',
  192 + :message => "other", :where => 'errorclass', :environment => 'development', :app_name => 'other')
  193 + dont_find = Fabricate(:problem, :resolved => false, :error_class => "Batman",
  194 + :message => 'todo', :where => 'classerror', :environment => 'development', :app_name => 'other')
  195 + Problem.search("theErrorClass").unresolved.should include(find)
  196 + Problem.search("theErrorClass").unresolved.should_not include(dont_find)
  197 + end
  198 + end
  199 + end
  200 +
  201 +
191 context "notice counter cache" do 202 context "notice counter cache" do
192 before do 203 before do
193 @app = Fabricate(:app) 204 @app = Fabricate(:app)