From d3ac9d1a2c9a2eace766b4a00707e9afc9b6cdd2 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 30 Apr 2013 00:13:45 +0600 Subject: [PATCH] [#98] Add common issues tracker --- app/assets/images/menu-delimiter.png | Bin 0 -> 2823 bytes app/controllers/projects/issues_controller.rb | 2 +- app/controllers/users/users_controller.rb | 31 +++++++++++++++++- app/models/user.rb | 1 + app/views/activity_feeds/_feed_tabs.html.haml | 5 ++- .../projects/issues/_index_sidebar.html.haml | 6 ++-- app/views/projects/issues/_issue.html.haml | 6 ++-- app/views/users/users/issues_index.html.haml | 12 +++++++ config/locales/models/issue.en.yml | 3 +- config/locales/models/issue.ru.yml | 3 +- config/locales/title.en.yml | 3 ++ config/locales/title.ru.yml | 3 ++ config/routes.rb | 2 ++ 13 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 app/assets/images/menu-delimiter.png create mode 100644 app/views/users/users/issues_index.html.haml diff --git a/app/assets/images/menu-delimiter.png b/app/assets/images/menu-delimiter.png new file mode 100644 index 0000000000000000000000000000000000000000..642e391cb213a33e98b5970a6176ee671c1df1b5 GIT binary patch literal 2823 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 Z09ehZJM@PX4wnD`002ovPDHLkV1k%8K0E*b literal 0 HcmV?d00001 diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 0e11f2c38..b4d98901e 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -13,7 +13,7 @@ class Projects::IssuesController < Projects::BaseController def index(status = 200) @labels = params[:labels] || [] @issues = @project.issues.without_pull_requests - @issues = @issues.where(:assignee_id => current_user.id) if @is_assigned_to_me = params[:filter] == 'to_me' + @issues = @issues.where(:assignee_id => current_user.id) if @is_assigned_to_me = params[:filter] == 'assigned' @issues = @issues.joins(:labels).where(:labels => {:name => @labels}) unless @labels == [] # Using mb_chars for correct transform to lowercase ('Русский Текст'.downcase => "Русский Текст") @issues = @issues.search(params[:search_issue]) if params[:search_issue] !~ /#{t('layout.issues.search')}/ diff --git a/app/controllers/users/users_controller.rb b/app/controllers/users/users_controller.rb index e3fe08a13..7ffbcb99b 100644 --- a/app/controllers/users/users_controller.rb +++ b/app/controllers/users/users_controller.rb @@ -1,6 +1,6 @@ # -*- encoding : utf-8 -*- class Users::UsersController < Users::BaseController - skip_before_filter :authenticate_user! + skip_before_filter :authenticate_user!, :only => [:allowed, :check, :discover] before_filter :find_user_by_key, :only => [:allowed, :discover] def allowed @@ -23,6 +23,35 @@ class Users::UsersController < Users::BaseController render :json => {:name => @user.name}.to_json end + def issues + @created_issues = current_user.issues.without_pull_requests + @assigned_issues = Issue.where(:assignee_id => current_user.id).without_pull_requests + pr_ids = Project.accessible_by(current_ability, :membered).uniq.pluck(:id) + @all_issues = Issue.where(:project_id => pr_ids).without_pull_requests + + case params[:filter] + when 'created' + @issues = @created_issues + when 'assigned' + @issues = @assigned_issues + else + params[:filter] = 'all' # default + @issues = @all_issues + end + @filter = params[:filter] + @opened_issues, @closed_issues = @issues.not_closed_or_merged.count, @issues.closed_or_merged.count + + @status = params[:status] == 'closed' ? :closed : :open + @issues = @issues.send( (@status == :closed) ? :closed_or_merged : :not_closed_or_merged ) + + @sort = params[:sort] == 'updated' ? :updated : :created + @direction = params[:direction] == 'asc' ? :asc : :desc + @issues = @issues.order("issues.#{@sort}_at #{@direction}") + .includes(:assignee, :user, :pull_request).uniq + .paginate :per_page => 20, :page => params[:page] + render 'issues_index', :layout => request.xhr? ? 'with_sidebar' : 'application' + end + protected def find_user_by_key diff --git a/app/models/user.rb b/app/models/user.rb index b7d9a498b..9b29dc37f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,6 +28,7 @@ class User < Avatar has_many :own_projects, :as => :owner, :class_name => 'Project', :dependent => :destroy has_many :own_groups, :foreign_key => :owner_id, :class_name => 'Group', :dependent => :destroy has_many :own_platforms, :as => :owner, :class_name => 'Platform', :dependent => :destroy + has_many :issues has_many :assigned_issues, :foreign_key => :assignee_id, :class_name => 'Issue', :dependent => :nullify has_many :key_pairs diff --git a/app/views/activity_feeds/_feed_tabs.html.haml b/app/views/activity_feeds/_feed_tabs.html.haml index e8b731174..606900a84 100644 --- a/app/views/activity_feeds/_feed_tabs.html.haml +++ b/app/views/activity_feeds/_feed_tabs.html.haml @@ -2,4 +2,7 @@ %nav %ul - (collection = t 'feed_menu').each do |base, title| - %li= link_to title, root_path(:filter => base), :class => @filter == base ? 'active' : '' + %li= link_to title, root_path(:filter => base), :class => controller_name == 'activity_feeds' && @filter == base ? 'active' : '' + %li + = image_tag 'menu-delimiter.png', :style => 'margin-bottom: -7px;' + %li=link_to t('users.users.issues_index.title'), issues_path, :class => controller_name== 'users' && action_name == 'issues' ? 'active' : '' diff --git a/app/views/projects/issues/_index_sidebar.html.haml b/app/views/projects/issues/_index_sidebar.html.haml index 51e7e8e18..98aa865f4 100644 --- a/app/views/projects/issues/_index_sidebar.html.haml +++ b/app/views/projects/issues/_index_sidebar.html.haml @@ -5,11 +5,11 @@ %table %tr %td.width18=radio_button_tag :myradio, 'all', !@is_assigned_to_me, {:id => 'myradio1', :class => 'niceRadio', :name => 'filter'} - %td.width135=t("layout.issues.all") + %td.width135=t('layout.issues.all') %td.width30.right=@project.issues.without_pull_requests.count %tr - %td=radio_button_tag :myradio, 'to_me', @is_assigned_to_me, {:id => 'myradio1', :class => 'niceRadio', :name => 'filter'} - %td=t("layout.issues.to_me") + %td=radio_button_tag :myradio, 'assigned', @is_assigned_to_me, {:id => 'myradio1', :class => 'niceRadio', :name => 'filter'} + %td=t('layout.issues.assigned') %td.width30.right=@project.issues.without_pull_requests.where(:assignee_id => current_user.id).count =form_tag project_issues_path(@project), :id => 'search_issue', :class => 'ajax_search_form', :method => :get do .bordered.bpadding20 diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 0154d5aa3..b454491cf 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -1,4 +1,4 @@ -- path = polymorphic_path [@project, issue.pull_request ? issue.pull_request : issue] +- path = polymorphic_path [@project || issue.project, issue.pull_request ? issue.pull_request : issue] %tr#row1{:name => "row", :class => issue.labels.map(&:name).compact} %td.td0 @@ -6,7 +6,9 @@ %td.td1=issue.serial_id %td %a{:href => path} - %div.issue_title=issue.title + %div.issue_title + -prefix = @project ? '' : "#{issue.project.name}: " + ="#{prefix} #{issue.title}".html_safe .smalltext =issue.send(@sort == :created ? :created_at : :updated_at).to_s(:long) =t("layout.by") if issue.user diff --git a/app/views/users/users/issues_index.html.haml b/app/views/users/users/issues_index.html.haml new file mode 100644 index 000000000..0f15c918d --- /dev/null +++ b/app/views/users/users/issues_index.html.haml @@ -0,0 +1,12 @@ +-set_meta_tags :title => t('.title') +-content_for :feed_tabs, render('activity_feeds/feed_tabs') +-content_for :sidebar do + =form_tag issues_path, :id => 'filter_issues', :method => :get do + .bordered + %table + -%w[all assigned created].each do |filter| + %tr + %td.width18=radio_button_tag :myradio, filter, filter == @filter, {:id => 'myradio1', :class => 'niceRadio', :name => 'filter'} + %td.width135=t("layout.issues.#{filter}") + %td.width30.right=instance_variable_get("@#{filter}_issues").count +=render 'projects/issues/issues_table', :issues => @issues diff --git a/config/locales/models/issue.en.yml b/config/locales/models/issue.en.yml index b9930d4e2..c6ed5d582 100644 --- a/config/locales/models/issue.en.yml +++ b/config/locales/models/issue.en.yml @@ -20,7 +20,8 @@ en: assign_someone: Assign someone to this issue list: List all: All issues - to_me: Assigned to me + assigned: Assigned to me + created: Created by you edit: Edit search: Find issue... comments_header: Comments diff --git a/config/locales/models/issue.ru.yml b/config/locales/models/issue.ru.yml index 51bd8db5e..427f95510 100644 --- a/config/locales/models/issue.ru.yml +++ b/config/locales/models/issue.ru.yml @@ -20,7 +20,8 @@ ru: assign_someone: Назначить кого-либо на задачу list: Список all: Все задачи - to_me: Назначенные мне + assigned: Назначенные мне + created: Созданные мной edit: Редактировать search: Найти задачу... comments_header: Комментарии diff --git a/config/locales/title.en.yml b/config/locales/title.en.yml index 01c37f6b7..a7cc0675a 100644 --- a/config/locales/title.en.yml +++ b/config/locales/title.en.yml @@ -6,6 +6,9 @@ en: settings: profile: title: 'Your Profile' + users: + issues_index: + title: 'Your Issues' projects: build_lists: index: diff --git a/config/locales/title.ru.yml b/config/locales/title.ru.yml index 736eb83c9..354fa68ea 100644 --- a/config/locales/title.ru.yml +++ b/config/locales/title.ru.yml @@ -6,6 +6,9 @@ ru: settings: profile: title: 'Ваш профиль' + users: + issues_index: + title: 'Ваши задачи' projects: build_lists: index: diff --git a/config/routes.rb b/config/routes.rb index aa52742d1..81c297a57 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -209,6 +209,8 @@ Rosa::Application.routes.draw do get '/allowed' => 'users#allowed' get '/check' => 'users#check' get '/discover' => 'users#discover' + get '/issues' => 'users#issues' + get '/pull_requests' => 'users#pull_requests' end scope :module => 'groups' do