in app/assets/javascripts/labels_select.js [103:210]
saveLabelData = function() {
var data, selected;
selected = $dropdown
.closest('.selectbox')
.find("input[name='" + fieldName + "']")
.map(function() {
return this.value;
})
.get();
if (_.isEqual(initialSelected, selected)) return;
initialSelected = selected;
data = {};
data[abilityName] = {};
data[abilityName].label_ids = selected;
if (!selected.length) {
data[abilityName].label_ids = [''];
}
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
axios
.put(issueUpdateURL, data)
.then(({ data }) => {
var labelCount, template, labelTooltipTitle, labelTitles, formattedLabels;
$loading.fadeOut();
$dropdown.trigger('loaded.gl.dropdown');
$selectbox.hide();
data.issueUpdateURL = issueUpdateURL;
labelCount = 0;
if (data.labels.length && issueUpdateURL) {
template = LabelsSelect.getLabelTemplate({
labels: data.labels,
issueUpdateURL,
enableScopedLabels: scopedLabels,
scopedLabelsDocumentationLink,
});
labelCount = data.labels.length;
// EE Specific
if (isEE) {
/**
* For Scoped labels, the last label selected with the
* same key will be applied to the current issueable.
*
* If these are the labels - priority::1, priority::2; and if
* we apply them in the same order, only priority::2 will stick
* with the issuable.
*
* In the current dropdown implementation, we keep track of all
* the labels selected via a hidden DOM element. Since a User
* can select priority::1 and priority::2 at the same time, the
* DOM will have 2 hidden input and the dropdown will show both
* the items selected but in reality server only applied
* priority::2.
*
* We find all the labels then find all the labels server accepted
* and then remove the excess ones.
*/
const toRemoveIds = Array.from(
$form.find(`input[type="hidden"][name="${fieldName}"]`),
)
.map(el => el.value)
.map(Number);
data.labels.forEach(label => {
const index = toRemoveIds.indexOf(label.id);
toRemoveIds.splice(index, 1);
});
toRemoveIds.forEach(id => {
$form
.find(`input[type="hidden"][name="${fieldName}"][value="${id}"]`)
.last()
.remove();
});
}
} else {
template = `<span class="no-value">${__('None')}</span>`;
}
$value.removeAttr('style').html(template);
$sidebarCollapsedValue.text(labelCount);
if (data.labels.length) {
labelTitles = data.labels.map(function(label) {
return label.title;
});
if (labelTitles.length > 5) {
labelTitles = labelTitles.slice(0, 5);
labelTitles.push(
sprintf(s__('Labels|and %{count} more'), { count: data.labels.length - 5 }),
);
}
labelTooltipTitle = labelTitles.join(', ');
} else {
labelTooltipTitle = __('Labels');
}
$sidebarLabelTooltip.attr('title', labelTooltipTitle).tooltip('_fixTitle');
$('.has-tooltip', $value).tooltip({
container: 'body',
});
})
.catch(() => flash(__('Error saving label update.')));
};