Skip to content
Snippets Groups Projects
Commit fec2e27f authored by Jan Provaznik's avatar Jan Provaznik
Browse files

[backend] backport of scoped labels

Scoped labels in EE require additional changes in CE code.
parent 97ab8539
No related branches found
No related tags found
No related merge requests found
Showing
with 78 additions and 31 deletions
Loading
Loading
@@ -7,6 +7,9 @@ module IssuableActions
included do
before_action :authorize_destroy_issuable!, only: :destroy
before_action :authorize_admin_issuable!, only: :bulk_update
before_action only: :show do
push_frontend_feature_flag(:scoped_labels, default_enabled: true)
end
end
 
def permitted_keys
Loading
Loading
Loading
Loading
@@ -46,7 +46,7 @@ module LabelsHelper
if block_given?
link_to link, class: css_class, &block
else
link_to render_colored_label(label, tooltip: tooltip), link, class: css_class
render_label(label, tooltip: tooltip, link: link, css: css_class)
end
end
 
Loading
Loading
@@ -78,19 +78,33 @@ module LabelsHelper
end
end
 
def render_colored_label(label, label_suffix = '', tooltip: true)
def render_label(label, tooltip: true, link: nil, css: nil)
# if scoped label is used then EE wraps label tag with scoped label
# doc link
html = render_colored_label(label, tooltip: tooltip)
html = link_to(html, link, class: css) if link
html
end
def render_colored_label(label, label_suffix: '', tooltip: true, title: nil)
text_color = text_color_for_bg(label.color)
title ||= label_tooltip_title(label)
 
# Intentionally not using content_tag here so that this method can be called
# by LabelReferenceFilter
span = %(<span class="badge color-label #{"has-tooltip" if tooltip}" ) +
%(style="background-color: #{label.color}; color: #{text_color}" ) +
%(title="#{escape_once(label.description)}" data-container="body">) +
%(data-html="true" style="background-color: #{label.color}; color: #{text_color}" ) +
%(title="#{escape_once(title)}" data-container="body">) +
%(#{escape_once(label.name)}#{label_suffix}</span>)
 
span.html_safe
end
 
def label_tooltip_title(label)
label.description
end
def suggested_colors
[
'#0033CC',
Loading
Loading
@@ -231,6 +245,31 @@ module LabelsHelper
labels.sort_by(&:title)
end
 
def label_dropdown_data(project, opts = {})
{
toggle: "dropdown",
field_name: opts[:field_name] || "label_name[]",
show_no: "true",
show_any: "true",
project_id: project&.try(:id),
namespace_path: project&.try(:namespace)&.try(:full_path),
project_path: project&.try(:path)
}.merge(opts)
end
def sidebar_label_dropdown_data(issuable_type, issuable_sidebar)
label_dropdown_data(nil, {
default_label: "Labels",
field_name: "#{issuable_type}[label_names][]",
ability_name: issuable_type,
namespace_path: issuable_sidebar[:namespace_path],
project_path: issuable_sidebar[:project_path],
issue_update: issuable_sidebar[:issuable_json_path],
labels: issuable_sidebar[:project_labels_path],
display: 'static'
})
end
# Required for Banzai::Filter::LabelReferenceFilter
module_function :render_colored_label, :text_color_for_bg, :escape_once
module_function :render_colored_label, :text_color_for_bg, :escape_once, :label_tooltip_title
end
Loading
Loading
@@ -4,7 +4,7 @@ class GlobalLabel
attr_accessor :title, :labels
alias_attribute :name, :title
 
delegate :color, :text_color, :description, to: :@first_label
delegate :color, :text_color, :description, :scoped_label?, to: :@first_label
 
def for_display
@first_label
Loading
Loading
Loading
Loading
@@ -107,12 +107,13 @@ class IssuableBaseService < BaseService
@labels_service ||= ::Labels::AvailableLabelsService.new(current_user, parent, params)
end
 
def process_label_ids(attributes, existing_label_ids: nil)
def process_label_ids(attributes, existing_label_ids: nil, extra_label_ids: [])
label_ids = attributes.delete(:label_ids)
add_label_ids = attributes.delete(:add_label_ids)
remove_label_ids = attributes.delete(:remove_label_ids)
 
new_label_ids = existing_label_ids || label_ids || []
new_label_ids |= extra_label_ids
 
if add_label_ids.blank? && remove_label_ids.blank?
new_label_ids = label_ids if label_ids
Loading
Loading
@@ -147,7 +148,7 @@ class IssuableBaseService < BaseService
 
params.delete(:state_event)
params[:author] ||= current_user
params[:label_ids] = issuable.label_ids.to_a + process_label_ids(params)
params[:label_ids] = process_label_ids(params, extra_label_ids: issuable.label_ids.to_a)
 
issuable.assign_attributes(params)
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
.modal-dialog
.modal-content
.modal-header
%h3.page-title Delete #{render_colored_label(label, tooltip: false)} ?
%h3.page-title Delete #{render_label(label, tooltip: false)} ?
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true } &times;
 
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@
- if defined?(@project)
= link_to_label(label, subject: @project, tooltip: false)
- else
= render_colored_label(label, tooltip: false)
= render_label(label, tooltip: false)
.label-description
.append-right-default.prepend-left-default
- if label.description.present?
Loading
Loading
Loading
Loading
@@ -21,13 +21,7 @@
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-issue-board-sidebar{ type: "button",
":data-selected" => "selectedLabels",
":data-labels" => "issue.assignableLabelsEndpoint",
data: { toggle: "dropdown",
field_name: "issue[label_names][]",
show_no: "true",
show_any: "true",
project_id: @project&.try(:id),
namespace_path: @namespace_path,
project_path: @project.try(:path) } }
data: label_dropdown_data(@project, namespace_path: @namespace_path, field_name: "issue[label_names][]") }
%span.dropdown-toggle-text
{{ labelDropdownTitle }}
= icon('chevron-down')
Loading
Loading
Loading
Loading
@@ -8,7 +8,7 @@
- classes = local_assigns.fetch(:classes, [])
- selected = local_assigns.fetch(:selected, nil)
- dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by label")
- dropdown_data = {toggle: 'dropdown', field_name: "label_name[]", show_no: "true", show_any: "true", namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path), labels: labels_filter_path_with_defaults, default_label: "Labels"}
- dropdown_data = label_dropdown_data(@project, labels: labels_filter_path_with_defaults, default_label: "Labels")
- dropdown_data.merge!(data_options)
- label_name = local_assigns.fetch(:label_name, "Labels")
- no_default_styles = local_assigns.fetch(:no_default_styles, false)
Loading
Loading
Loading
Loading
@@ -105,10 +105,9 @@
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right'
.value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
- if selected_labels.any?
- selected_labels.each do |label|
= link_to sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label[:title]) do
%span.badge.color-label.has-tooltip{ style: "background-color: #{label[:color]}; color: #{label[:text_color]}", title: label[:description], data: { container: "body" } }
= label[:title]
- selected_labels.each do |label_hash|
- label = Label.new(label_hash.slice(:color, :description, :title))
= render_label(label, link: sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label[:title]))
- else
%span.no-value
= _('None')
Loading
Loading
@@ -116,7 +115,7 @@
- selected_labels.each do |label|
= hidden_field_tag "#{issuable_type}[label_names][]", label[:id], id: nil
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: {toggle: "dropdown", default_label: "Labels", field_name: "#{issuable_type}[label_names][]", ability_name: issuable_type, show_no: "true", show_any: "true", namespace_path: issuable_sidebar[:namespace_path], project_path: issuable_sidebar[:project_path], issue_update: issuable_sidebar[:issuable_json_path], labels: issuable_sidebar[:project_labels_path], display: 'static' } }
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: sidebar_label_dropdown_data(issuable_type, issuable_sidebar) }
%span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) }
= multi_label_name(selected_labels, "Labels")
= icon('chevron-down', 'aria-hidden': 'true')
Loading
Loading
Loading
Loading
@@ -4,7 +4,9 @@
.form-group.row
= f.label :title, class: 'col-form-label col-sm-2'
.col-sm-10
= f.text_field :title, class: "form-control qa-label-title", required: true, autofocus: true
= f.text_field :title, class: "form-control js-label-title qa-label-title", required: true, autofocus: true
= render_if_exists 'shared/labels/create_label_help_text'
.form-group.row
= f.label :description, class: 'col-form-label col-sm-2'
.col-sm-10
Loading
Loading
Loading
Loading
@@ -22,7 +22,7 @@
 
- labels.each do |label|
= link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, label_name: label.title, state: 'all' }) do
- render_colored_label(label)
- render_label(label)
 
%span.assignee-icon
- assignees.each do |assignee|
Loading
Loading
Loading
Loading
@@ -5,8 +5,7 @@
%li.is-not-draggable
%span.label-row
%span.label-name
= link_to milestones_label_path(options) do
- render_colored_label(label, tooltip: false)
= render_label(label, tooltip: false, link: milestones_label_path(options))
%span.prepend-description-left
= markdown_field(label, :description)
 
Loading
Loading
Loading
Loading
@@ -195,15 +195,21 @@ module Banzai
 
content = link_content || object_link_text(object, matches)
 
%(<a href="#{url}" #{data}
title="#{escape_once(title)}"
class="#{klass}">#{content}</a>)
link = %(<a href="#{url}" #{data}
title="#{escape_once(title)}"
class="#{klass}">#{content}</a>)
wrap_link(link, object)
else
match
end
end
end
 
def wrap_link(link, object)
link
end
def data_attributes_for(text, parent, object, link_content: false, link_reference: false)
object_parent_type = parent.is_a?(Group) ? :group : :project
 
Loading
Loading
Loading
Loading
@@ -91,7 +91,11 @@ module Banzai
label_suffix = " <i>in #{reference}</i>" if reference.present?
end
 
LabelsHelper.render_colored_label(object, label_suffix)
LabelsHelper.render_colored_label(object, label_suffix: label_suffix, title: tooltip_title(object))
end
def tooltip_title(label)
nil
end
 
def full_path_ref?(matches)
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment