[#369] project issues page: in progress

This commit is contained in:
Alexander Machehin 2014-11-20 22:40:50 +05:00
parent a095bf4e61
commit fdf60fb754
15 changed files with 284 additions and 74 deletions

View File

@ -0,0 +1,21 @@
issueService = ($http) ->
{
getIssues: (project, filter) ->
params = {
kind: filter.kind
filter: filter.name
sort: filter.sort
direction: filter.sort_direction
status: filter.status
page: filter.page
}
path = Routes.project_issues_path(project, params)
$http.get(path)
}
angular
.module("RosaABF")
.factory "Issue", issueService
issueService.$inject = ['$http']

View File

@ -0,0 +1,71 @@
IssuesController = (dataservice, $http, $location, Issue) ->
getIssues = ->
promise = Issue.getIssues(vm.project, vm.filter)
promise.then (response) ->
vm.issues = response.data.issues
vm.filter.total_items = response.data.total_items
true
setSortClass = ->
if vm.filter.sort_direction is 'asc'
sort_class = 'fa-chevron-down'
else
sort_class = 'fa-chevron-up'
if vm.filter.sort is 'updated'
vm.updated_class = sort_class
vm.submitted_class = null
else
vm.updated_class = null
vm.submitted_class = sort_class
vm = this
vm.setIssuesFilter = (filter) ->
vm.filter.all = false
vm.filter.assigned = false
vm.filter.created = false
vm.filter[filter] = true
vm.filter.name = filter
vm.getIssues()
vm.setIssuesSort = (issues_sort) ->
if vm.filter.sort_direction is 'desc'
vm.filter.sort_direction = 'asc'
else
vm.filter.sort_direction = 'desc'
vm.filter.sort = issues_sort
setSortClass()
getIssues()
vm.setIssuesStatus = (issues_status) ->
vm.filter.status = issues_status
vm.filter.page = 1
getIssues()
vm.goToPage = (page) ->
getIssues()
init = (dataservice) ->
vm.project = dataservice.project
vm.issues = dataservice.issues
vm.filter = dataservice.filter
if vm.filter.status == "closed"
vm.filter.status_closed = true
else
vm.filter.status_open = true
setSortClass()
init(dataservice)
true
angular
.module("RosaABF")
.controller "IssuesController", IssuesController
IssuesController.$inject = ['IssuesInitializer', '$http', '$location', 'Issue']

View File

@ -10,27 +10,75 @@ class Projects::IssuesController < Projects::BaseController
layout false, only: [:update, :search_collaborators]
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] == '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')}/
@opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged
@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}")
@issues = @issues.preload(:assignee, :user, :pull_request).uniq
.paginate per_page: 20, page: params[:page]
if status == 200
render 'index', layout: request.xhr? ? 'with_sidebar' : 'application'
if params[:kind] == 'pull_requests'
all_issues = @project.issues.joins(:pull_request)
else
render status: status, nothing: true
params[:kind] = 'issues'
all_issues = @project.issues.without_pull_requests
end
@created_issues = all_issues.where(user_id: current_user)
@assigned_issues = all_issues.where(assignee_id: current_user.id)
# TODO: Add search & labels
case params[:filter]
when 'created'
@issues = @created_issues
when 'assigned'
@issues = @assigned_issues
else
params[:filter] = 'all' # default
@issues = all_issues
end
@opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged
params[:status] = params[:status] == 'closed' ? :closed : :open
@issues = @issues.send( params[:status] == :closed ? :closed_or_merged : :not_closed_or_merged )
params[:direction] = params[:direction] == 'asc' ? :asc : :desc
if params[:sort] == 'submitted'
@issues = @issues.order(created_at: params[:direction])
else
params[:sort] = :updated
@issues = @issues.order(updated_at: params[:direction])
end
@issues = @issues.includes(:assignee, :user, :pull_request).uniq
.paginate(page: current_page)
respond_to do |format|
format.html {}
format.json {}
end
# @labels = params[:labels] || []
# @issues = @project.issues.without_pull_requests
# @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')}/
# @opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged
# @status = params[:status] == 'closed' ? :closed : :open
# @issues = @issues.send( (@status == :closed) ? :closed_or_merged : :not_closed_or_merged )
# params[:direction] = params[:direction] == 'asc' ? :asc : :desc
# if params[:sort] == 'submitted'
# @issues = @issues.order(created_at: params[:direction])
# else
# params[:sort] = :updated
# @issues = @issues.order(updated_at: params[:direction])
# end
# @issues = @issues.preload(:assignee, :user, :pull_request).uniq
# .paginate per_page: 20, page: params[:page]
# if status == 200
# render 'index', layout: request.xhr? ? 'with_sidebar' : 'application'
# else
# render status: status, nothing: true
# end
end
def new

View File

@ -0,0 +1,7 @@
json.kind params[:kind]
json.filter params[:filter]
json.sort params[:sort]
json.sort_direction params[:direction]
json.status params[:status]
json.page params[:page]
json.total_items @issues_count

View File

@ -0,0 +1,9 @@
<script>
angular.module('RosaABF').service('IssuesInitializer', function(){
return {
project: '<%= @project.name_with_owner %>',
filter: <%= render('filter.json', all_issues: @all_issues, params: params).html_safe %>,
issues: <%= render('issues.json', issues: @issues).html_safe %>
};
});
</script>

View File

@ -1,27 +0,0 @@
- 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
%span{style: "display: none;"}=issue.serial_id
%td.td1=issue.serial_id
%td
%a{href: path}
%div.issue_title
-prefix = @project ? '' : "<span style=\"color: #999;\">#{issue.project.name}</span>: "
="#{prefix} #{issue.title}".html_safe
.smalltext
= datetime_moment issue.send(@sort == :created ? :created_at : :updated_at)
=t("layout.by") if issue.user
=link_to(issue.user.uname, user_path(issue.user)) if issue.user
-issue.labels.each do |label|
.left.nomargin
.label.selected.tracker.left
.labeltext.selected{style: "background: ##{label.color};"}=label.name
%td.td3{class: (issue.pull_request ? 'td3-pull' : '')}
- if issue.pull_request
%a{href: path}
.code #
= link_to image_tag(avatar_url(issue.assignee), alt: 'avatar', class: 'avatar'), user_path(issue.assignee) if issue.assignee
%a.answers{href: "#{path}#block-list"}
= image_tag 'answers.png', class: 'pic'
.count=issue.comments.where(automatic: false).count

View File

@ -0,0 +1,31 @@
json.(issue, :serial_id, :title)
json.path project_issue_path(issue.project, issue)
json.labels do
json.array!(issue.labels) do |label|
json.name label.name
json.color "##{label.color}"
end
end
json.user do
json.uname issue.user.uname
json.path user_path(issue.user)
end
json.updated_at issue.updated_at
json.updated_at_utc issue.updated_at.strftime('%Y-%m-%d %H:%M:%S UTC')
json.created_at issue.created_at
json.created_at_utc issue.created_at.strftime('%Y-%m-%d %H:%M:%S UTC')
if issue.assignee
json.assignee do
json.path user_path(issue.assignee)
json.image avatar_url(issue.assignee, :micro)
json.fullname issue.assignee.fullname
end
else
json.assignee do
end
end

View File

@ -0,0 +1,3 @@
json.array!(issues) do |issue|
json.partial! 'issue.json', issue: issue
end

View File

@ -1,21 +0,0 @@
#description-top.issues-filter
.project-tabnav
%ul.tabnav-tabs
%li.list-browser-filter-tabs.open{class: ('selected' if @status == :open)}
%a= "#{t('layout.issues.statuses.open')} (#{@opened_issues.count})"
%li.list-browser-filter-tabs.closed{class: ('selected' if @status != :open)}
%a= "#{t('layout.issues.statuses.closed')} (#{@closed_issues.count})"
%li.list-browser-sorts.updated{class: ("selected #{@direction}" if @sort == :updated)}
- if @sort == :updated
%i{class: (@direction == :asc ? 'icon-chevron-up' : 'icon-chevron-down')}
%a= t('layout.issues.sort.updated')
%li.list-browser-sorts.created{class: ("selected #{@direction}" if @sort == :created)}
- if @sort == :created
%i{class: (@direction == :asc ? 'icon-chevron-up' : 'icon-chevron-down')}
%a= t('layout.issues.sort.submitted')
#table1.issues-table
%table#myTable.tablesorter.tracker{cellpadding: "0", cellspacing: "0"}
%tbody
= render partial: 'projects/issues/issue', collection: issues
= will_paginate issues

View File

@ -0,0 +1,57 @@
tabset.boffset10
tab[ heading = "#{t "layout.issues.statuses.open"} (#{@opened_issues.count})"
active = 'issuesCtrl.filter.status_open'
ng-click = "issuesCtrl.setIssuesStatus('open')" ]
tab[ heading = "#{t "layout.issues.statuses.closed"} (#{@closed_issues.count})"
active = 'issuesCtrl.filter.status_closed'
ng-click = "issuesCtrl.setIssuesStatus('closed')" ]
.pull-right.boffset10
button.btn.btn-default.roffset5[ type = 'button'
ng-click = "issuesCtrl.setIssuesSort('updated')" ]
span.fa ng-class = "issuesCtrl.updated_class"
=> t('layout.issues.sort.updated')
button.btn.btn-default[ type = 'button'
ng-click = "issuesCtrl.setIssuesSort('submitted')" ]
span.fa ng-class = "issuesCtrl.submitted_class"
=> t('layout.issues.sort.submitted')
table.table
tr ng-repeat = "issue in issuesCtrl.issues"
td
a ng-href = "{{issue.path}}"
| {{issue.title}}
span.label.small.loffset5[ ng-repeat = "label in issue.labels"
ng-style = "{background: label.color}" ]
| {{label.name}}
.small
= t 'layout.issues.created_by'
a>[ ng-href = "{{issue.user.path}}" ] {{issue.user.uname}}
span.text-muted[ ng-show = 'issuesCtrl.filter.sort == "submitted"'
title = "{{issue.created_at_utc}}" ]
| {{issue.created_at | amDateFormat:'YYYY-MM-DD HH:mm'}} (
span am-time-ago = 'issue.created_at'
| )
span> class = 'text-muted' ng-show = 'issuesCtrl.filter.sort == "updated"'
= t 'layout.issues.updated_at'
span.text-muted[ ng-show = 'issuesCtrl.filter.sort == "updated"'
title = "{{issue.updated_at_utc}}" ]
| {{issue.updated_at | amDateFormat:'YYYY-MM-DD HH:mm'}} (
span am-time-ago = 'issue.updated_at'
| )
td
span.text-muted.roffset5
| {{'#' + issue.serial_id}}
a[ ng-href = '{{issue.assignee.path}}'
title = "#{t('layout.issues.assigned_to')} {{issue.assignee.fullname}}" ]
img ng-src = '{{issue.assignee.image}}'
= angularjs_paginate( per_page: Issue.per_page,
page: 'issuesCtrl.filter.page',
select_page: 'issuesCtrl.goToPage(issuesCtrl.filter.page)',
total_items: 'issuesCtrl.filter.total_items' )
- content_for :additional_scripts do
= render 'init_service.js.erb'

View File

@ -1,5 +0,0 @@
-set_meta_tags title: [title_object(@project), t('.title')]
-render 'submenu'
-render 'index_sidebar'
= render 'issues_table', issues: @issues

View File

@ -0,0 +1,12 @@
-set_meta_tags title: [title_object(@project), t('.title')]
-render 'submenu'
div[ ng-controller = 'IssuesController as issuesCtrl'
ng-cloak = true ]
.row
.col-md-offset-2.col-md-8
= render 'issues_table', issues: @issues
-#render 'index_sidebar'

View File

@ -0,0 +1,4 @@
json.total_items @issues.count
json.issues do
json.partial! 'issues', issues: @issues
end

View File

@ -62,7 +62,7 @@ en:
done: Done
created_by: 'Created by '
updated_at: ' updated'
updated_at: 'updated '
assigned_to: 'Assigned to'
flash:

View File

@ -62,7 +62,7 @@ ru:
done: Обновить
created_by: 'Создано '
updated_at: ' обновлено'
updated_at: 'обновлено '
assigned_to: 'Назначен'
flash: