summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2016-06-07 09:44:01 +0100
committerPhil Hughes <me@iamphill.com>2016-06-14 08:36:07 +0100
commitf67b06ada016915211e84a7d12a063aa25e422f3 (patch)
tree25b94f817c9971c5e347530cce1732f34ffd80f7
parentf34af6b83cc2663bb8a076f4df9c82047e5511ab (diff)
downloadgitlab-ce-f67b06ada016915211e84a7d12a063aa25e422f3.tar.gz
Manually create todo for issuable
Added a button into the sidebar for issues & merge requests to allow users to manually create todo items Closes #15045
-rw-r--r--app/assets/javascripts/right_sidebar.js.coffee41
-rw-r--r--app/assets/stylesheets/pages/issuable.scss12
-rw-r--r--app/controllers/projects/issues_controller.rb14
-rw-r--r--app/controllers/projects/merge_requests_controller.rb14
-rw-r--r--app/finders/todos_finder.rb2
-rw-r--r--app/helpers/issuables_helper.rb14
-rw-r--r--app/models/todo.rb1
-rw-r--r--app/services/todo_service.rb6
-rw-r--r--app/views/layouts/header/_default.html.haml5
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml13
-rw-r--r--config/routes.rb2
11 files changed, 111 insertions, 13 deletions
diff --git a/app/assets/javascripts/right_sidebar.js.coffee b/app/assets/javascripts/right_sidebar.js.coffee
index c9cb0f4bb32..3ee943fe78c 100644
--- a/app/assets/javascripts/right_sidebar.js.coffee
+++ b/app/assets/javascripts/right_sidebar.js.coffee
@@ -43,6 +43,45 @@ class @Sidebar
$('.right-sidebar')
.hasClass('right-sidebar-collapsed'), { path: '/' })
+ $(document)
+ .off 'click', '.js-issuable-todo'
+ .on 'click', '.js-issuable-todo', @toggleTodo
+
+ toggleTodo: (e) ->
+ $this = $(@)
+ $btnText = $this.find('span')
+ data = {
+ todo_id: $this.attr('data-id')
+ }
+
+ $.ajax(
+ url: $this.data('url')
+ type: 'POST'
+ dataType: 'json'
+ data: data
+ beforeSend: ->
+ $this.disable()
+ $('.js-issuable-todo-loading').removeClass 'hidden'
+ ).done (data) ->
+ $todoPendingCount = $('.todos-pending-count')
+ $todoPendingCount.text data.count
+
+ $this.enable()
+ $('.js-issuable-todo-loading').addClass 'hidden'
+
+ if data.count is 0
+ $this.removeAttr 'data-id'
+ $btnText.text $this.data('todo-text')
+
+ $todoPendingCount
+ .addClass 'hidden'
+ else
+ $btnText.text $this.data('mark-text')
+ $todoPendingCount
+ .removeClass 'hidden'
+
+ if data.todo?
+ $this.attr 'data-id', data.todo.id
sidebarDropdownLoading: (e) ->
$sidebarCollapsedIcon = $(@).closest('.block').find('.sidebar-collapsed-icon')
@@ -117,5 +156,3 @@ class @Sidebar
getBlock: (name) ->
@sidebar.find(".block.#{name}")
-
-
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index ea453ce356a..acbb7e7f713 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -34,6 +34,10 @@
color: inherit;
}
+ .issuable-header-text {
+ margin-top: 7px;
+ }
+
.block {
@include clearfix;
padding: $gl-padding 0;
@@ -60,10 +64,6 @@
margin-top: 0;
}
- .issuable-count {
- margin-top: 7px;
- }
-
.gutter-toggle {
margin-left: 20px;
padding-left: 10px;
@@ -250,7 +250,7 @@
}
}
- .issuable-pager {
+ .issuable-header-btn {
background: $gray-normal;
border: 1px solid $border-gray-normal;
&:hover {
@@ -263,7 +263,7 @@
}
}
- a:not(.issuable-pager) {
+ a:not(.issuable-header-btn) {
&:hover {
color: $md-link-color;
text-decoration: none;
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 4e2d3bebb2e..5678d584d4a 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -164,6 +164,20 @@ class Projects::IssuesController < Projects::ApplicationController
end
end
+ def todo
+ json_data = Hash.new
+
+ if params[:todo_id].nil?
+ TodoService.new.mark_todo(issue, current_user)
+
+ json_data[:todo] = current_user.todos.find_by(state: :pending, action: Todo::MARKED, target_id: issue.id)
+ else
+ current_user.todos.find_by_id(params[:todo_id]).update(state: :done)
+ end
+
+ render json: json_data.merge({ count: current_user.todos.pending.count })
+ end
+
protected
def issue
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 67e7187c10d..f0eba453caa 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -260,6 +260,20 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render json: response
end
+ def todo
+ json_data = Hash.new
+
+ if params[:todo_id].nil?
+ TodoService.new.mark_todo(merge_request, current_user)
+
+ json_data[:todo] = current_user.todos.find_by(state: :pending, action: Todo::MARKED, target_id: merge_request.id)
+ else
+ current_user.todos.find_by_id(params[:todo_id]).update(state: :done)
+ end
+
+ render json: json_data.merge({ count: current_user.todos.pending.count })
+ end
+
protected
def selected_target_project
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index 1d88116d7d2..aa47c6c157e 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -36,7 +36,7 @@ class TodosFinder
private
def action_id?
- action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED, Todo::BUILD_FAILED].include?(action_id.to_i)
+ action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED, Todo::BUILD_FAILED, Todo::MARKED].include?(action_id.to_i)
end
def action_id
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 40d8ce8a1d3..88ef1a6468c 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -67,6 +67,20 @@ module IssuablesHelper
end
end
+ def issuable_todo_path(issuable)
+ project = issuable.project
+
+ if issuable.kind_of?(MergeRequest)
+ todo_namespace_project_merge_request_path(project.namespace, project, issuable.iid, :json)
+ else
+ todo_namespace_project_issue_path(project.namespace, project, issuable.iid, :json)
+ end
+ end
+
+ def has_todo(issuable)
+ current_user.todos.find_by(target_id: issuable.id, state: :pending)
+ end
+
private
def sidebar_gutter_collapsed?
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 3a091373329..2792fa9b9a8 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -2,6 +2,7 @@ class Todo < ActiveRecord::Base
ASSIGNED = 1
MENTIONED = 2
BUILD_FAILED = 3
+ MARKED = 4
belongs_to :author, class_name: "User"
belongs_to :note
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index 8e03ff8ddde..5a192e54f25 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -139,6 +139,12 @@ class TodoService
pending_todos(user, attributes).update_all(state: :done)
end
+ # When user marks an issue as todo
+ def mark_todo(issuable, current_user)
+ attributes = attributes_for_todo(issuable.project, issuable, current_user, Todo::MARKED)
+ create_todos(current_user, attributes)
+ end
+
private
def create_todos(users, attributes)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index ad30a367fc5..ebc9f01675a 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -27,9 +27,8 @@
%li
= link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('bell fw')
- - unless todos_pending_count == 0
- %span.badge.todos-pending-count
- = todos_pending_count
+ %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0)}
+ = todos_pending_count
- if current_user.can_create_project?
%li
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index fb906de829a..25d830b6e49 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,9 +1,20 @@
+- todo = has_todo(issuable)
%aside.right-sidebar{ class: sidebar_gutter_collapsed_class }
.issuable-sidebar
- can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.block.issuable-sidebar-header
- %a.gutter-toggle.pull-right.js-sidebar-toggle{href: '#'}
+ %span.issuable-header-text.hide-collapsed.pull-left
+ Todo
+ %button.gutter-toggle.pull-right.js-sidebar-toggle{ type: "button", aria: { label: "Toggle sidebar" } }
= sidebar_gutter_toggle_icon
+ %button.btn.btn-default.issuable-header-btn.pull-right.js-issuable-todo{ type: "button", data: { todo_text: "Add Todo", mark_text: "Mark Done", id: (todo.id unless todo.nil?), url: issuable_todo_path(issuable) } }
+ - if todo.nil?
+ %span
+ Add Todo
+ - else
+ %span
+ Mark Done
+ = icon('spin spinner', class: 'hidden js-issuable-todo-loading')
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, format: :json, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
.block.assignee
diff --git a/config/routes.rb b/config/routes.rb
index 95fbe7dd9df..d018fa742cc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -679,6 +679,7 @@ Rails.application.routes.draw do
post :toggle_subscription
post :toggle_award_emoji
post :remove_wip
+ post :todo
end
collection do
@@ -759,6 +760,7 @@ Rails.application.routes.draw do
get :referenced_merge_requests
get :related_branches
get :can_create_branch
+ post :todo
end
collection do
post :bulk_update