[#369] project issues page: in progress
This commit is contained in:
parent
a095bf4e61
commit
fdf60fb754
|
@ -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']
|
|
@ -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']
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
json.array!(issues) do |issue|
|
||||
json.partial! 'issue.json', issue: issue
|
||||
end
|
|
@ -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
|
|
@ -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'
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
-set_meta_tags title: [title_object(@project), t('.title')]
|
||||
-render 'submenu'
|
||||
-render 'index_sidebar'
|
||||
|
||||
= render 'issues_table', issues: @issues
|
|
@ -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'
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
json.total_items @issues.count
|
||||
json.issues do
|
||||
json.partial! 'issues', issues: @issues
|
||||
end
|
|
@ -62,7 +62,7 @@ en:
|
|||
done: Done
|
||||
|
||||
created_by: 'Created by '
|
||||
updated_at: ' updated'
|
||||
updated_at: 'updated '
|
||||
assigned_to: 'Assigned to'
|
||||
|
||||
flash:
|
||||
|
|
|
@ -62,7 +62,7 @@ ru:
|
|||
done: Обновить
|
||||
|
||||
created_by: 'Создано '
|
||||
updated_at: ' обновлено'
|
||||
updated_at: 'обновлено '
|
||||
assigned_to: 'Назначен'
|
||||
|
||||
flash:
|
||||
|
|
Loading…
Reference in New Issue