diff options
-rw-r--r-- | app/assets/javascripts/LabelManager.js.coffee | 79 | ||||
-rw-r--r-- | app/assets/javascripts/dispatcher.js.coffee | 2 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/labels.scss | 12 | ||||
-rw-r--r-- | app/controllers/projects/labels_controller.rb | 22 | ||||
-rw-r--r-- | app/models/label.rb | 2 | ||||
-rw-r--r-- | app/views/projects/labels/_label.html.haml | 12 | ||||
-rw-r--r-- | app/views/projects/labels/index.html.haml | 27 | ||||
-rw-r--r-- | config/routes.rb | 2 |
8 files changed, 146 insertions, 12 deletions
diff --git a/app/assets/javascripts/LabelManager.js.coffee b/app/assets/javascripts/LabelManager.js.coffee new file mode 100644 index 00000000000..056a03651b5 --- /dev/null +++ b/app/assets/javascripts/LabelManager.js.coffee @@ -0,0 +1,79 @@ +class @LabelManager + constructor: (opts = {}) -> + # Defaults + { + @togglePriorityButton = $('.js-toggle-priority') + @prioritizedLabels = $('.js-prioritized-labels') + @otherLabels = $('.js-other-labels') + } = opts + + @prioritizedLabels.sortable( + items: 'li' + update: @onPrioritySortUpdate.bind(@) + ) + + @bindEvents() + + bindEvents: -> + @togglePriorityButton.on 'click', @, @onTogglePriorityClick + + onTogglePriorityClick: (e) -> + e.preventDefault() + _this = e.data + $btn = $(e.currentTarget) + $label = $("##{$btn.data('domId')}") + action = if $btn.parents('.js-prioritized-labels').length then 'remove' else 'add' + _this.toggleLabelPriority($label, action) + + toggleLabelPriority: ($label, action, pasive = false) -> + _this = @ + url = $label.find('.js-toggle-priority').data 'url' + + $target = @prioritizedLabels + $from = @otherLabels + + # Optimistic update + if action is 'remove' + $target = @otherLabels + $from = @prioritizedLabels + + if $from.find('li').length is 1 + $from.find('.empty-message').show() + + if not $target.find('li').length + $target.find('.empty-message').hide() + + $label.detach().appendTo($target) + + # Return if we are not persisting state + return if pasive + + xhr = $.post url + + # If request fails, put label back to Other labels group + xhr.fail -> + _this.toggleLabelPriority($label, 'remove', true) + + # Show a message + new Flash('Unable to update label prioritization at this time' , 'alert') + + onPrioritySortUpdate: -> + @savePrioritySort() + + savePrioritySort: -> + xhr = $.post + url: @prioritizedLabels.data('url') + data: + label_ids: @getSortedLabelsIds() + + xhr.done -> + console.log 'done' + + xhr.fail -> + console.log 'fail' + + getSortedLabelsIds: -> + sortedIds = [] + @prioritizedLabels.find('li').each -> + sortedIds.push $(@).data 'id' + sortedIds
\ No newline at end of file diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index ec540060457..49fc7ef2e12 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -100,6 +100,8 @@ class Dispatcher shortcut_handler = new ShortcutsNavigation() when 'projects:labels:new', 'projects:labels:edit' new Labels() + when 'projects:labels:index' + new LabelManager() when 'projects:network:show' # Ensure we don't create a particular shortcut handler here. This is # already created, where the network graph is created. diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index e179bdf0048..4b0b512db88 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -138,3 +138,15 @@ } } } + +.prioritized-labels { + .add-priority { + display: none; + } +} + +.other-labels { + .remove-priority { + display: none; + } +} diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index ff771ea6d9c..88d745e6bae 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -11,7 +11,8 @@ class Projects::LabelsController < Projects::ApplicationController respond_to :js, :html def index - @labels = @project.labels.page(params[:page]) + @labels = @project.labels.prioritized(false).page(params[:page]) + @prioritized = @project.labels.prioritized respond_to do |format| format.html @@ -71,6 +72,25 @@ class Projects::LabelsController < Projects::ApplicationController end end + def toggle_priority + priority = label.priority + + respond_to do |format| + if label.update_attributes(priority: !priority) + format.json { render json: label } + else + message = label.errors.full_messages.uniq.join('. ') + format.json { render json: { message: message }, status: :unprocessable_entity } + end + end + end + + def set_sorting + respond_to do |format| + format.json { render json: {message: 'success'}} + end + end + protected def module_enabled diff --git a/app/models/label.rb b/app/models/label.rb index e5ad11983be..59e7afe53f3 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -19,6 +19,7 @@ class Label < ActiveRecord::Base validates :color, color: true, allow_blank: false validates :project, presence: true, unless: Proc.new { |service| service.template? } + validates :priority, presence: false, default: false # Don't allow '?', '&', and ',' for label titles validates :title, @@ -29,6 +30,7 @@ class Label < ActiveRecord::Base default_scope { order(title: :asc) } scope :templates, -> { where(template: true) } + scope :prioritized, ->(value = true) { where(priority: value) } alias_attribute :name, :title diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml index 294fec422c5..eda75b64e79 100644 --- a/app/views/projects/labels/_label.html.haml +++ b/app/views/projects/labels/_label.html.haml @@ -1,4 +1,12 @@ -%li{ id: dom_id(label), data: { id: label.id } } +- label_css_id = dom_id(label) +%li{id: label_css_id, :"data-id" => label.id} + %a.js-toggle-priority{:href => "#", + :"data-url" => toggle_priority_namespace_project_label_path(@project.namespace, @project, label), + :"data-dom-id" => "#{label_css_id}" } + %span.add-priority + (+) + %span.remove-priority + (-) = render "shared/label_row", label: label .pull-info-right %span.append-right-20 @@ -24,4 +32,4 @@ - if current_user :javascript - new Subscription('##{dom_id(label)} .label-subscription'); + new Subscription('##{label_css_id} .label-subscription'); diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index 2557d1a4d5b..d71db7545ef 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -10,13 +10,22 @@ New label .labels - - if @labels.present? - %ul.content-list.manage-labels-list - = render @labels - = paginate @labels, theme: 'gitlab' - - else - .nothing-here-block - - if can? current_user, :admin_label, @project - Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}. + .prioritized-labels + %h5 Prioritized Label + %ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_sorting_namespace_project_labels_path(@project.namespace, @project) } + - if @prioritized.present? + = render @prioritized - else - No labels created + %p.empty-message No prioritized labels yet + .other-labels + %h5 Other Labels + - if @labels.present? + %ul.content-list.manage-labels-list.js-other-labels + = render @labels + = paginate @labels, theme: 'gitlab' + - else + .nothing-here-block + - if can? current_user, :admin_label, @project + Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}. + - else + No labels created diff --git a/config/routes.rb b/config/routes.rb index 7e735541f7f..5aa8a0fe8a5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -719,10 +719,12 @@ Rails.application.routes.draw do resources :labels, constraints: { id: /\d+/ } do collection do post :generate + post :set_sorting end member do post :toggle_subscription + post :toggle_priority end end |