Skip to content
Snippets Groups Projects
Commit 244134f9 authored by Paco Guzman's avatar Paco Guzman
Browse files

Cache todos pending/done dashboard query counts

parent 97999fd4
No related branches found
No related tags found
No related merge requests found
Loading
@@ -49,6 +49,7 @@ v 8.10.0 (unreleased)
Loading
@@ -49,6 +49,7 @@ v 8.10.0 (unreleased)
- Collapse large diffs by default (!4990) - Collapse large diffs by default (!4990)
- Check for conflicts with existing Project's wiki path when creating a new project. - Check for conflicts with existing Project's wiki path when creating a new project.
- Show last push widget in upstream after push to fork - Show last push widget in upstream after push to fork
- Cache todos pending/done dashboard query counts.
- Don't instantiate a git tree on Projects show default view - Don't instantiate a git tree on Projects show default view
- Bump Rinku to 2.0.0 - Bump Rinku to 2.0.0
- Remove unused front-end variable -> default_issues_tracker - Remove unused front-end variable -> default_issues_tracker
Loading
Loading
class Dashboard::TodosController < Dashboard::ApplicationController class Dashboard::TodosController < Dashboard::ApplicationController
include TodosHelper
before_action :find_todos, only: [:index, :destroy_all] before_action :find_todos, only: [:index, :destroy_all]
   
def index def index
Loading
@@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
Loading
@@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' } format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' }
format.js { head :ok } format.js { head :ok }
format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } format.json { render json: todos_counts }
end end
end end
   
Loading
@@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
Loading
@@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' }
format.js { head :ok } format.js { head :ok }
format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } format.json { render json: todos_counts }
end end
end end
   
Loading
@@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController
Loading
@@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def find_todos def find_todos
@todos ||= TodosFinder.new(current_user, params).execute @todos ||= TodosFinder.new(current_user, params).execute
end end
def todos_counts
{
count: TodosFinder.new(current_user, state: :pending).execute.count,
done_count: TodosFinder.new(current_user, state: :done).execute.count
}
end
end end
Loading
@@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController
Loading
@@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController
todo = TodoService.new.mark_todo(issuable, current_user) todo = TodoService.new.mark_todo(issuable, current_user)
   
render json: { render json: {
count: current_user.todos_pending_count, count: TodosFinder.new(current_user, state: :pending).execute.count,
delete_path: dashboard_todo_path(todo) delete_path: dashboard_todo_path(todo)
} }
end end
Loading
Loading
Loading
@@ -8,7 +8,7 @@
Loading
@@ -8,7 +8,7 @@
# action_id: integer # action_id: integer
# author_id: integer # author_id: integer
# project_id; integer # project_id; integer
# state: 'pending' or 'done' # state: 'pending' (default) or 'done'
# type: 'Issue' or 'MergeRequest' # type: 'Issue' or 'MergeRequest'
# #
   
Loading
Loading
module TodosHelper module TodosHelper
def todos_pending_count def todos_pending_count
TodosFinder.new(current_user, state: :pending).execute.count @todos_pending_count ||= TodosFinder.new(current_user, state: :pending).execute.count
end end
   
def todos_done_count def todos_done_count
TodosFinder.new(current_user, state: :done).execute.count @todos_done_count ||= TodosFinder.new(current_user, state: :done).execute.count
end end
   
def todo_action_name(todo) def todo_action_name(todo)
Loading
Loading
require('spec_helper') require('spec_helper')
   
describe Projects::TodosController do describe Projects::TodosController do
include ApiHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) } let(:issue) { create(:issue, project: project) }
Loading
@@ -8,43 +10,51 @@ describe Projects::TodosController do
Loading
@@ -8,43 +10,51 @@ describe Projects::TodosController do
   
context 'Issues' do context 'Issues' do
describe 'POST create' do describe 'POST create' do
def go
post :create,
namespace_id: project.namespace.path,
project_id: project.path,
issuable_id: issue.id,
issuable_type: 'issue',
format: 'html'
end
context 'when authorized' do context 'when authorized' do
before do before do
sign_in(user) sign_in(user)
project.team << [user, :developer] project.team << [user, :developer]
end end
   
it 'should create todo for issue' do it 'creates todo for issue' do
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: issue.id,
issuable_type: 'issue')
end.to change { user.todos.count }.by(1) end.to change { user.todos.count }.by(1)
   
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
it 'returns todo path and pending count' do
go
expect(response).to have_http_status(200)
expect(json_response['count']).to eq 1
expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
end
end end
   
context 'when not authorized' do context 'when not authorized' do
it 'should not create todo for issue that user has no access to' do it 'does not create todo for issue that user has no access to' do
sign_in(user) sign_in(user)
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: issue.id,
issuable_type: 'issue')
end.to change { user.todos.count }.by(0) end.to change { user.todos.count }.by(0)
   
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
   
it 'should not create todo for issue when user not logged in' do it 'does not create todo for issue when user not logged in' do
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: issue.id,
issuable_type: 'issue')
end.to change { user.todos.count }.by(0) end.to change { user.todos.count }.by(0)
   
expect(response).to have_http_status(302) expect(response).to have_http_status(302)
Loading
@@ -55,43 +65,51 @@ describe Projects::TodosController do
Loading
@@ -55,43 +65,51 @@ describe Projects::TodosController do
   
context 'Merge Requests' do context 'Merge Requests' do
describe 'POST create' do describe 'POST create' do
def go
post :create,
namespace_id: project.namespace.path,
project_id: project.path,
issuable_id: merge_request.id,
issuable_type: 'merge_request',
format: 'html'
end
context 'when authorized' do context 'when authorized' do
before do before do
sign_in(user) sign_in(user)
project.team << [user, :developer] project.team << [user, :developer]
end end
   
it 'should create todo for merge request' do it 'creates todo for merge request' do
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: merge_request.id,
issuable_type: 'merge_request')
end.to change { user.todos.count }.by(1) end.to change { user.todos.count }.by(1)
   
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
it 'returns todo path and pending count' do
go
expect(response).to have_http_status(200)
expect(json_response['count']).to eq 1
expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
end
end end
   
context 'when not authorized' do context 'when not authorized' do
it 'should not create todo for merge request user has no access to' do it 'does not create todo for merge request user has no access to' do
sign_in(user) sign_in(user)
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: merge_request.id,
issuable_type: 'merge_request')
end.to change { user.todos.count }.by(0) end.to change { user.todos.count }.by(0)
   
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
   
it 'should not create todo for merge request user has no access to' do it 'does not create todo for merge request user has no access to' do
expect do expect do
post(:create, namespace_id: project.namespace.path, go
project_id: project.path,
issuable_id: merge_request.id,
issuable_type: 'merge_request')
end.to change { user.todos.count }.by(0) end.to change { user.todos.count }.by(0)
   
expect(response).to have_http_status(302) expect(response).to have_http_status(302)
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment