From 9dcd42425d263089fdbc026829a068bbebd4abf6 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Fri, 21 Nov 2014 16:26:21 +0500 Subject: [PATCH] [#369] project issues index page: labels filter --- .../angular-new/issues/issue.js.coffee | 1 + .../issues/issues_controller.js.coffee | 22 ++++++++-- .../stylesheets/custom_bootstrap.css.sass | 5 +++ app/controllers/projects/issues_controller.rb | 9 +++- .../projects/issues/_filter.json.jbuilder | 16 ++++--- .../projects/issues/_filter_labels.html.slim | 10 +++++ .../projects/issues/_index_sidebar.html.haml | 22 ---------- .../projects/issues/_index_sidebar.html.slim | 14 ++++++ .../projects/issues/_init_service.js.erb | 2 + app/views/projects/issues/_labels.html.haml | 44 ------------------- .../projects/issues/_labels.json.jbuilder | 25 +++++++++++ app/views/projects/issues/index.html.slim | 8 +--- 12 files changed, 93 insertions(+), 85 deletions(-) create mode 100644 app/views/projects/issues/_filter_labels.html.slim delete mode 100644 app/views/projects/issues/_index_sidebar.html.haml create mode 100644 app/views/projects/issues/_index_sidebar.html.slim delete mode 100644 app/views/projects/issues/_labels.html.haml create mode 100644 app/views/projects/issues/_labels.json.jbuilder diff --git a/app/assets/javascripts/angular-new/issues/issue.js.coffee b/app/assets/javascripts/angular-new/issues/issue.js.coffee index eface3344..45e3203f1 100644 --- a/app/assets/javascripts/angular-new/issues/issue.js.coffee +++ b/app/assets/javascripts/angular-new/issues/issue.js.coffee @@ -7,6 +7,7 @@ issueService = ($http) -> sort: filter.sort direction: filter.sort_direction status: filter.status + labels: filter.labels page: filter.page } diff --git a/app/assets/javascripts/angular-new/issues/issues_controller.js.coffee b/app/assets/javascripts/angular-new/issues/issues_controller.js.coffee index 41b577622..3862646f6 100644 --- a/app/assets/javascripts/angular-new/issues/issues_controller.js.coffee +++ b/app/assets/javascripts/angular-new/issues/issues_controller.js.coffee @@ -1,6 +1,7 @@ IssuesController = (dataservice, $http, $location, Issue) -> getIssues = -> + prepareLabelsFilter() promise = Issue.getIssues(vm.project, vm.filter) promise.then (response) -> vm.issues = response.data.issues @@ -28,6 +29,12 @@ IssuesController = (dataservice, $http, $location, Issue) -> vm.updated_class = null vm.submitted_class = sort_class + prepareLabelsFilter = -> + vm.filter.labels = [] + _.each(vm.labels, (l) -> + vm.filter.labels.push(l.name) if l.selected + ) + vm = this vm.setIssuesFilter = (filter) -> @@ -57,10 +64,19 @@ IssuesController = (dataservice, $http, $location, Issue) -> vm.goToPage = (page) -> getIssues() + vm.toggleLabelFilter = (label) -> + label.selected = !label.selected + if label.selected + label.style = label.default_style + else + label.style = {} + getIssues() + init = (dataservice) -> - vm.project = dataservice.project - vm.issues = dataservice.issues - vm.filter = dataservice.filter + vm.project = dataservice.project + vm.issues = dataservice.issues + vm.filter = dataservice.filter + vm.labels = dataservice.labels vm.filter[dataservice.filter.filter] = true diff --git a/app/assets/stylesheets/custom_bootstrap.css.sass b/app/assets/stylesheets/custom_bootstrap.css.sass index 834c91133..8a5003d2e 100644 --- a/app/assets/stylesheets/custom_bootstrap.css.sass +++ b/app/assets/stylesheets/custom_bootstrap.css.sass @@ -197,3 +197,8 @@ table.highlighttable textarea.resize-vertical resize: vertical +.label-flag + float: left + margin: 1px 2px + border: 1px solid + diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index b09e7b33d..576f20278 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -21,8 +21,6 @@ class Projects::IssuesController < Projects::BaseController @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 @@ -32,6 +30,13 @@ class Projects::IssuesController < Projects::BaseController params[:filter] = 'all' # default @issues = all_issues end + + if params[:labels].is_a?(Array) && params[:labels].present? + @issues = @issues.joins(:labels).where(labels: {name: params[:labels]}) + else + params[:labels] = [] + end + @opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged params[:status] = params[:status] == 'closed' ? :closed : :open diff --git a/app/views/projects/issues/_filter.json.jbuilder b/app/views/projects/issues/_filter.json.jbuilder index 829a2a737..0d88746a8 100644 --- a/app/views/projects/issues/_filter.json.jbuilder +++ b/app/views/projects/issues/_filter.json.jbuilder @@ -4,10 +4,12 @@ json.sort params[:sort] json.sort_direction params[:direction] json.status params[:status] -json.all_count @all_issues.not_closed_or_merged.count -json.assigned_count @assigned_issues.not_closed_or_merged.count -json.created_count @created_issues.not_closed_or_merged.count -json.opened_count @opened_issues.count -json.closed_count @closed_issues.count -json.page params[:page] -json.filtered_count @issues.count +json.labels params[:labels] + +json.all_count @all_issues.not_closed_or_merged.count +json.assigned_count @assigned_issues.not_closed_or_merged.count +json.created_count @created_issues.not_closed_or_merged.count +json.opened_count @opened_issues.count +json.closed_count @closed_issues.count +json.page params[:page] +json.filtered_count @issues.count diff --git a/app/views/projects/issues/_filter_labels.html.slim b/app/views/projects/issues/_filter_labels.html.slim new file mode 100644 index 000000000..0a218f33f --- /dev/null +++ b/app/views/projects/issues/_filter_labels.html.slim @@ -0,0 +1,10 @@ +ul.nav.nav-pills.nav-stacked + li[ role = 'presentation' ng-repeat = 'label in issuesCtrl.labels' ] + a[ href = '#' + ng-click = 'issuesCtrl.toggleLabelFilter(label)' + ng-style = 'label.style' ] + .label-flag[ ng-style = 'label.default_style' + ng-show = '!label.selected' ]   + | {{label.name}} + span.pull-right + | {{label.count}} diff --git a/app/views/projects/issues/_index_sidebar.html.haml b/app/views/projects/issues/_index_sidebar.html.haml deleted file mode 100644 index 2568a9e5e..000000000 --- a/app/views/projects/issues/_index_sidebar.html.haml +++ /dev/null @@ -1,22 +0,0 @@ --content_for :sidebar do - - if current_user - =form_tag project_issues_path(@project), id: 'filter_issues', method: :get do - .bordered - %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.width30.right=@project.issues.without_pull_requests.not_closed_or_merged.count - %tr - %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).not_closed_or_merged.count - =form_tag project_issues_path(@project), id: 'search_issue', class: 'ajax_search_form', method: :get do - .bordered.bpadding20 - - search = params[:search_issue].present? ? params[:search_issue] : t('layout.issues.search') - =tracker_search_field(:search_issue, search) - - if can? :new, @project.issues.new - .bordered.nopadding - %h3.bmargin10=t('layout.issues.new') - = link_to t("layout.add"), new_project_issue_path(@project), class: 'button' - =render 'labels' diff --git a/app/views/projects/issues/_index_sidebar.html.slim b/app/views/projects/issues/_index_sidebar.html.slim new file mode 100644 index 000000000..1dc5319cc --- /dev/null +++ b/app/views/projects/issues/_index_sidebar.html.slim @@ -0,0 +1,14 @@ +ul.nav.nav-pills.nav-stacked + - %w(all assigned created).each do |kind_filter| + li ng-class = "{ active: issuesCtrl.filter.#{kind_filter} }" + a ng-click = "issuesCtrl.setIssuesFilter('#{kind_filter}')" + span.badge.pull-right= "{{ issuesCtrl.filter.#{kind_filter}_count }}" + - kind = params[:kind] == 'issues' ? 'tracker' : 'pull_requests' + = "{{'#{kind}.filter.#{kind_filter}' | i18n}}" + +- if can? :new, @project.issues.new + hr + = link_to t('layout.issues.new'), new_project_issue_path(@project), class: 'btn btn-primary' +hr + += render 'filter_labels', project: @project diff --git a/app/views/projects/issues/_init_service.js.erb b/app/views/projects/issues/_init_service.js.erb index 2006e5ca9..a2c18f12b 100644 --- a/app/views/projects/issues/_init_service.js.erb +++ b/app/views/projects/issues/_init_service.js.erb @@ -2,6 +2,8 @@ angular.module('RosaABF').service('IssuesInitializer', function(){ return { project: '<%= @project.name_with_owner %>', + <% all_issue_ids = @all_issues.not_closed_or_merged.ids %> + labels: <%= render('labels.json', project: @project, all_issue_ids: all_issue_ids).html_safe %>, filter: <%= render('filter.json', all_issues: @all_issues, params: params).html_safe %>, issues: <%= render('issues.json', issues: @issues).html_safe %> }; diff --git a/app/views/projects/issues/_labels.html.haml b/app/views/projects/issues/_labels.html.haml deleted file mode 100644 index c114f7205..000000000 --- a/app/views/projects/issues/_labels.html.haml +++ /dev/null @@ -1,44 +0,0 @@ -.block - %h3=t('layout.issues.labels') - #labels-stock - =form_tag project_issues_path(@project), id: 'filter_labels', method: :get do - - @project.labels.each_with_index do |label, index| - =render 'projects/shared/filter_label', - id: label.name.parameterize, - selected: @labels.include?(label.name), - extra_classes: 'div-tracker-labels', - color: label.color, - check_box_name: 'labels', - check_box_value: label.name, - name: label.name, - count: Labeling.joins(:label).where(labels: {name: label.name, project_id: @project.id}).count - - if can? :write, @project - %a#manage-labels.button.tmargin10{href: "#labels-stock"}=t('layout.issues.label_manage') - #labels-edit{style: "display: none;"} - - @project.labels.each_with_index do |label, index| - .label.edit{id: "label-#{index}"} - .labeltext.edit{style: "background: ##{label.color};"} - .text=link_to(label.name, project_issues_update_label_path(@project, label.id), class: 'edit_label') - .delete{id: "delete#{index}"} - %a{href: project_issues_delete_label_path(@project, label.id), class: 'delete_label'}= image_tag 'x-label.png' - .both - .edit_label_form{style: 'display:none'} - =form_tag project_issues_update_label_path(@project, label.id), id: 'update_label', method: :post do - %input.gray{name: 'name', type: "text", value: label.name} - =render 'colors_chooser', current_color: label.color - .lefter - %a{href: "#custom_color-#{label.name}", id: "custom_color-#{label.name}", class: 'custom_color'}=t('layout.issues.label_custom_color') - =text_field_tag :color, label.color, id: 'label_color', class: 'gray', style: 'display:none', maxlength: 6 - .righter - =link_to t('layout.update'), project_issues_update_label_path(@project, label.id), id: 'update_label', class: 'button' - .both - - =form_tag create_label_project_issues_path(@project), id: 'new_label', method: :post do - =tracker_search_field(:name, t('layout.issues.new_label')) - =render 'colors_chooser' - .lefter - %a{href: "#custom_color", id: 'custom_color', class: 'custom_color'}=t('layout.issues.label_custom_color') - =text_field_tag :color, '0054a6', id: 'label_color', class: 'gray', style: 'display:none', maxlength: 6 - .righter - =link_to t('layout.add'), create_label_project_issues_path(@project), id: 'add_label', class: 'button' - .both diff --git a/app/views/projects/issues/_labels.json.jbuilder b/app/views/projects/issues/_labels.json.jbuilder new file mode 100644 index 000000000..03d1e62bf --- /dev/null +++ b/app/views/projects/issues/_labels.json.jbuilder @@ -0,0 +1,25 @@ +json.array!(project.labels) do |label| + json.id label.id + json.name label.name + json.color label.color + + selected = params[:labels].include?(label.name) + json.selected selected + json.style do + json.set! 'background-color', "##{label.color}" + json.color '#FFF' + end if selected + + json.default_style do + json.set! 'background-color', "##{label.color}" + json.color '#FFF' + end + + json.count Labeling.joins(:label).where( + issue_id: all_issue_ids, + labels: { + name: label.name, + project_id: project.id + } + ).count +end diff --git a/app/views/projects/issues/index.html.slim b/app/views/projects/issues/index.html.slim index e112dc48a..8b82b7d16 100644 --- a/app/views/projects/issues/index.html.slim +++ b/app/views/projects/issues/index.html.slim @@ -4,13 +4,7 @@ .container ng-controller = 'IssuesController as issuesCtrl' ng-cloak = true .row .col-md-3.col-sm-4.offset20 - ul.nav.nav-pills.nav-stacked - - %w(all assigned created).each do |kind_filter| - li ng-class = "{ active: issuesCtrl.filter.#{kind_filter} }" - a ng-click = "issuesCtrl.setIssuesFilter('#{kind_filter}')" - span.badge.pull-right= "{{ issuesCtrl.filter.#{kind_filter}_count }}" - - kind = params[:kind] == 'issues' ? 'tracker' : 'pull_requests' - = "{{'#{kind}.filter.#{kind_filter}' | i18n}}" + = render 'index_sidebar', project: @project .col-md-9.col-sm-8.offset20 tabset.boffset10 tab[ heading = "#{t "layout.issues.statuses.open"} ({{issuesCtrl.filter.opened_count}})"