Commit c559bcca authored by Mike Greiling's avatar Mike Greiling

Prettify additional modules (I through Z)

parent aeaf6686
......@@ -26,14 +26,17 @@ export default class IssuableIndex {
static resetIncomingEmailToken() {
const $resetToken = $('.incoming-email-token-reset');
$resetToken.on('click', (e) => {
$resetToken.on('click', e => {
e.preventDefault();
$resetToken.text('resetting...');
axios.put($resetToken.attr('href'))
axios
.put($resetToken.attr('href'))
.then(({ data }) => {
$('#issuable_email').val(data.new_address).focus();
$('#issuable_email')
.val(data.new_address)
.focus();
$resetToken.text('reset it');
})
......
......@@ -28,7 +28,7 @@ export default class Issue {
}
// Listen to state changes in the Vue app
document.addEventListener('issuable_vue_app:change', (event) => {
document.addEventListener('issuable_vue_app:change', event => {
this.updateTopState(event.detail.isClosed, event.detail.data);
});
}
......@@ -55,7 +55,13 @@ export default class Issue {
$(document).trigger('issuable:change', isClosed);
this.toggleCloseReopenButton(isClosed);
let numProjectIssues = Number(projectIssuesCounter.first().text().trim().replace(/[^\d]/, ''));
let numProjectIssues = Number(
projectIssuesCounter
.first()
.text()
.trim()
.replace(/[^\d]/, ''),
);
numProjectIssues = isClosed ? numProjectIssues - 1 : numProjectIssues + 1;
projectIssuesCounter.text(addDelimiter(numProjectIssues));
......@@ -76,29 +82,34 @@ export default class Issue {
initIssueBtnEventListeners() {
const issueFailMessage = 'Unable to update this issue at this time.';
return $(document).on('click', '.js-issuable-actions a.btn-close, .js-issuable-actions a.btn-reopen', (e) => {
var $button, shouldSubmit, url;
e.preventDefault();
e.stopImmediatePropagation();
$button = $(e.currentTarget);
shouldSubmit = $button.hasClass('btn-comment');
if (shouldSubmit) {
Issue.submitNoteForm($button.closest('form'));
}
this.disableCloseReopenButton($button);
return $(document).on(
'click',
'.js-issuable-actions a.btn-close, .js-issuable-actions a.btn-reopen',
e => {
var $button, shouldSubmit, url;
e.preventDefault();
e.stopImmediatePropagation();
$button = $(e.currentTarget);
shouldSubmit = $button.hasClass('btn-comment');
if (shouldSubmit) {
Issue.submitNoteForm($button.closest('form'));
}
url = $button.attr('href');
return axios.put(url)
.then(({ data }) => {
const isClosed = $button.hasClass('btn-close');
this.updateTopState(isClosed, data);
})
.catch(() => flash(issueFailMessage))
.then(() => {
this.disableCloseReopenButton($button, false);
});
});
this.disableCloseReopenButton($button);
url = $button.attr('href');
return axios
.put(url)
.then(({ data }) => {
const isClosed = $button.hasClass('btn-close');
this.updateTopState(isClosed, data);
})
.catch(() => flash(issueFailMessage))
.then(() => {
this.disableCloseReopenButton($button, false);
});
},
);
}
initCloseReopenReport() {
......@@ -124,7 +135,7 @@ export default class Issue {
static submitNoteForm(form) {
var noteText;
noteText = form.find("textarea.js-note-text").val();
noteText = form.find('textarea.js-note-text').val();
if (noteText && noteText.trim().length > 0) {
return form.submit();
}
......@@ -133,22 +144,26 @@ export default class Issue {
static initMergeRequests() {
var $container;
$container = $('#merge-requests');
return axios.get($container.data('url'))
return axios
.get($container.data('url'))
.then(({ data }) => {
if ('html' in data) {
$container.html(data.html);
}
}).catch(() => flash('Failed to load referenced merge requests'));
})
.catch(() => flash('Failed to load referenced merge requests'));
}
static initRelatedBranches() {
var $container;
$container = $('#related-branches');
return axios.get($container.data('url'))
return axios
.get($container.data('url'))
.then(({ data }) => {
if ('html' in data) {
$container.html(data.html);
}
}).catch(() => flash('Failed to load related branches'));
})
.catch(() => flash('Failed to load related branches'));
}
}
......@@ -42,16 +42,14 @@ export default class Job extends LogOutputBehaviours {
this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100);
this.$window
.off('scroll')
.on('scroll', () => {
if (!isScrolledToBottom()) {
this.toggleScrollAnimation(false);
} else if (isScrolledToBottom() && !this.isLogComplete) {
this.toggleScrollAnimation(true);
}
this.scrollThrottled();
});
this.$window.off('scroll').on('scroll', () => {
if (!isScrolledToBottom()) {
this.toggleScrollAnimation(false);
} else if (isScrolledToBottom() && !this.isLogComplete) {
this.toggleScrollAnimation(true);
}
this.scrollThrottled();
});
this.$window
.off('resize.build')
......@@ -87,10 +85,11 @@ export default class Job extends LogOutputBehaviours {
}
getBuildTrace() {
return axios.get(`${this.pagePath}/trace.json`, {
params: { state: this.state },
})
.then((res) => {
return axios
.get(`${this.pagePath}/trace.json`, {
params: { state: this.state },
})
.then(res => {
const log = res.data;
if (!this.fetchingStatusFavicon) {
......@@ -186,5 +185,4 @@ export default class Job extends LogOutputBehaviours {
sidebarOnClick() {
if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
}
}
......@@ -47,7 +47,10 @@ export default class LabelManager {
}
toggleEmptyState($label, $btn, action) {
this.emptyState.classList.toggle('hidden', !!this.prioritizedLabels[0].querySelector(':scope > li'));
this.emptyState.classList.toggle(
'hidden',
!!this.prioritizedLabels[0].querySelector(':scope > li'),
);
}
toggleLabelPriority($label, action, persistState) {
......@@ -80,16 +83,14 @@ export default class LabelManager {
return;
}
if (action === 'remove') {
axios.delete(url)
.catch(rollbackLabelPosition);
axios.delete(url).catch(rollbackLabelPosition);
// Restore empty message
if (!$from.find('li').length) {
$from.find('.empty-message').removeClass('hidden');
}
} else {
this.savePrioritySort($label, action)
.catch(rollbackLabelPosition);
this.savePrioritySort($label, action).catch(rollbackLabelPosition);
}
}
......@@ -102,8 +103,7 @@ export default class LabelManager {
}
onPrioritySortUpdate() {
this.savePrioritySort()
.catch(() => flash(this.errorMessage));
this.savePrioritySort().catch(() => flash(this.errorMessage));
}
savePrioritySort() {
......
......@@ -22,7 +22,7 @@ export default class Labels {
updateColorPreview() {
const previewColor = $('input#label_color').val();
return $('div.label-color-preview').css('background-color', previewColor);
// Updates the the preview color with the hex-color input
// Updates the the preview color with the hex-color input
}
// Updates the preview color with a click on a suggested color
......
......@@ -5,7 +5,9 @@ import initFlyOutNav from './fly_out_nav';
function hideEndFade($scrollingTabs) {
$scrollingTabs.each(function scrollTabsLoop() {
const $this = $(this);
$this.siblings('.fade-right').toggleClass('scrolling', Math.round($this.width()) < $this.prop('scrollWidth'));
$this
.siblings('.fade-right')
.toggleClass('scrolling', Math.round($this.width()) < $this.prop('scrollWidth'));
});
}
......@@ -15,38 +17,42 @@ export default function initLayoutNav() {
initFlyOutNav();
$(document).on('init.scrolling-tabs', () => {
const $scrollingTabs = $('.scrolling-tabs').not('.is-initialized');
$scrollingTabs.addClass('is-initialized');
$(document)
.on('init.scrolling-tabs', () => {
const $scrollingTabs = $('.scrolling-tabs').not('.is-initialized');
$scrollingTabs.addClass('is-initialized');
$(window).on('resize.nav', () => {
hideEndFade($scrollingTabs);
}).trigger('resize.nav');
$(window)
.on('resize.nav', () => {
hideEndFade($scrollingTabs);
})
.trigger('resize.nav');
$scrollingTabs.on('scroll', function tabsScrollEvent() {
const $this = $(this);
const currentPosition = $this.scrollLeft();
const maxPosition = $this.prop('scrollWidth') - $this.outerWidth();
$scrollingTabs.on('scroll', function tabsScrollEvent() {
const $this = $(this);
const currentPosition = $this.scrollLeft();
const maxPosition = $this.prop('scrollWidth') - $this.outerWidth();
$this.siblings('.fade-left').toggleClass('scrolling', currentPosition > 0);
$this.siblings('.fade-right').toggleClass('scrolling', currentPosition < maxPosition - 1);
});
$this.siblings('.fade-left').toggleClass('scrolling', currentPosition > 0);
$this.siblings('.fade-right').toggleClass('scrolling', currentPosition < maxPosition - 1);
});
$scrollingTabs.each(function scrollTabsEachLoop() {
const $this = $(this);
const scrollingTabWidth = $this.width();
const $active = $this.find('.active');
const activeWidth = $active.width();
$scrollingTabs.each(function scrollTabsEachLoop() {
const $this = $(this);
const scrollingTabWidth = $this.width();
const $active = $this.find('.active');
const activeWidth = $active.width();
if ($active.length) {
const offset = $active.offset().left + activeWidth;
if ($active.length) {
const offset = $active.offset().left + activeWidth;
if (offset > scrollingTabWidth - 30) {
const scrollLeft = (offset - (scrollingTabWidth / 2)) - (activeWidth / 2);
if (offset > scrollingTabWidth - 30) {
const scrollLeft = offset - scrollingTabWidth / 2 - activeWidth / 2;
$this.scrollLeft(scrollLeft);
$this.scrollLeft(scrollLeft);
}
}
}
});
}).trigger('init.scrolling-tabs');
});
})
.trigger('init.scrolling-tabs');
}
......@@ -70,7 +70,7 @@ LineHighlighter.prototype.highlightHash = function(newHash) {
const scrollOptions = {
// Scroll to the first highlighted line on initial load
// Offset -50 for the sticky top bar, and another -100 for some context
offset: -150
offset: -150,
};
if (this.options.scrollFileHolder) {
$(this.options.fileHolderSelector).scrollTo(lineSelector, scrollOptions);
......@@ -85,7 +85,9 @@ LineHighlighter.prototype.clickHandler = function(event) {
var current, lineNumber, range;
event.preventDefault();
this.clearHighlight();
lineNumber = $(event.target).closest('a').data('lineNumber');
lineNumber = $(event.target)
.closest('a')
.data('lineNumber');
current = this.hashToRange(this._hash);
if (!(current[0] && event.shiftKey)) {
// If there's no current selection, or there is but Shift wasn't held,
......@@ -104,7 +106,7 @@ LineHighlighter.prototype.clickHandler = function(event) {
};
LineHighlighter.prototype.clearHighlight = function() {
return $("." + this.highlightLineClass).removeClass(this.highlightLineClass);
return $('.' + this.highlightLineClass).removeClass(this.highlightLineClass);
};
// Convert a URL hash String into line numbers
......@@ -135,7 +137,7 @@ LineHighlighter.prototype.hashToRange = function(hash) {
//
// lineNumber - Line number to highlight
LineHighlighter.prototype.highlightLine = function(lineNumber) {
return $("#LC" + lineNumber).addClass(this.highlightLineClass);
return $('#LC' + lineNumber).addClass(this.highlightLineClass);
};
// Highlight all lines within a range
......@@ -160,9 +162,9 @@ LineHighlighter.prototype.highlightRange = function(range) {
LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
var hash;
if (lastLineNumber) {
hash = "#L" + firstLineNumber + "-" + lastLineNumber;
hash = '#L' + firstLineNumber + '-' + lastLineNumber;
} else {
hash = "#L" + firstLineNumber;
hash = '#L' + firstLineNumber;
}
this._hash = hash;
return this.__setLocationHash__(hash);
......@@ -172,11 +174,15 @@ LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
//
// This method is stubbed in tests.
LineHighlighter.prototype.__setLocationHash__ = function(value) {
return window.history.pushState({
url: value
// We're using pushState instead of assigning location.hash directly to
// prevent the page from scrolling on the hashchange event
}, document.title, value);
return window.history.pushState(
{
url: value,
// We're using pushState instead of assigning location.hash directly to
// prevent the page from scrolling on the hashchange event
},
document.title,
value,
);
};
export default LineHighlighter;
......@@ -15,7 +15,7 @@ export default (input, parameters, escapeParameters = true) => {
let output = input;
if (parameters) {
Object.keys(parameters).forEach((parameterName) => {
Object.keys(parameters).forEach(parameterName => {
const parameterValue = parameters[parameterName];
const escapedParameterValue = escapeParameters ? _.escape(parameterValue) : parameterValue;
output = output.replace(new RegExp(`%{${parameterName}}`, 'g'), escapedParameterValue);
......
......@@ -9,7 +9,9 @@ import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
//
export default function memberExpirationDate(selector = '.js-access-expiration-date') {
function toggleClearInput() {
$(this).closest('.clearable-input').toggleClass('has-value', $(this).val() !== '');
$(this)
.closest('.clearable-input')
.toggleClass('has-value', $(this).val() !== '');
}
const inputs = $(selector);
......@@ -40,7 +42,9 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d
inputs.next('.js-clear-input').on('click', function clicked(event) {
event.preventDefault();
const input = $(this).closest('.clearable-input').find(selector);
const input = $(this)
.closest('.clearable-input')
.find(selector);
const calendar = input.data('pikaday');
calendar.setDate(null);
......
......@@ -16,26 +16,29 @@ function MergeRequest(opts) {
this.opts = opts != null ? opts : {};
this.submitNoteForm = this.submitNoteForm.bind(this);
this.$el = $('.merge-request');
this.$('.show-all-commits').on('click', (function(_this) {
return function() {
return _this.showAllCommits();
};
})(this));
this.$('.show-all-commits').on(
'click',
(function(_this) {
return function() {
return _this.showAllCommits();
};
})(this),
);
this.initTabs();
this.initMRBtnListeners();
this.initCommitMessageListeners();
this.closeReopenReportToggle = IssuablesHelper.initCloseReopenReport();
if ($("a.btn-close").length) {
if ($('a.btn-close').length) {
this.taskList = new TaskList({
dataType: 'merge_request',
fieldName: 'description',
selector: '.detail-page-description',
onSuccess: (result) => {
onSuccess: result => {
document.querySelector('#task_status').innerText = result.task_status;
document.querySelector('#task_status_short').innerText = result.task_status_short;
}
},
});
}
}
......@@ -84,7 +87,7 @@ MergeRequest.prototype.initMRBtnListeners = function() {
MergeRequest.prototype.submitNoteForm = function(form, $button) {
var noteText;
noteText = form.find("textarea.js-note-text").val();
noteText = form.find('textarea.js-note-text').val();
if (noteText.trim().length > 0) {
form.submit();
$button.data('submitted', true);
......@@ -122,7 +125,7 @@ MergeRequest.setStatusBoxToMerged = function() {
MergeRequest.decreaseCounter = function(by = 1) {
const $el = $('.js-merge-counter');
const count = Math.max((parseInt($el.text().replace(/[^\d]/, ''), 10) - by), 0);
const count = Math.max(parseInt($el.text().replace(/[^\d]/, ''), 10) - by, 0);
$el.text(addDelimiter(count));
};
......
......@@ -15,7 +15,7 @@ export default class Milestone {
}
bindTabsSwitching() {
return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => {
return $('a[data-toggle="tab"]').on('show.bs.tab', e => {
const $target = $(e.target);
window.location.hash = $target.attr('href');
......@@ -36,7 +36,8 @@ export default class Milestone {
const tabElId = $target.attr('href');
if (endpoint && !$target.hasClass('is-loaded')) {
axios.get(endpoint)
axios
.get(endpoint)
.then(({ data }) => {
$(tabElId).html(data.html);
$target.addClass('is-loaded');
......@@ -46,23 +47,28 @@ export default class Milestone {
}
static initDeprecationMessage() {
const deprecationMesssageContainer = document.querySelector('.js-milestone-deprecation-message');
const deprecationMesssageContainer = document.querySelector(
'.js-milestone-deprecation-message',
);
if (!deprecationMesssageContainer) return;
const deprecationMessage = deprecationMesssageContainer.querySelector('.js-milestone-deprecation-message-template').innerHTML;
const deprecationMessage = deprecationMesssageContainer.querySelector(
'.js-milestone-deprecation-message-template',
).innerHTML;
const $popover = $('.js-popover-link', deprecationMesssageContainer);
const hideOnScroll = togglePopover.bind($popover, false);
$popover.popover({
content: deprecationMessage,
html: true,
placement: 'bottom',
})
.on('mouseenter', mouseenter)
.on('mouseleave', debouncedMouseleave())
.on('show.bs.popover', () => {
window.addEventListener('scroll', hideOnScroll, { once: true });
});
$popover
.popover({
content: deprecationMessage,
html: true,
placement: 'bottom',
})
.on('mouseenter', mouseenter)
.on('mouseleave', debouncedMouseleave())
.on('show.bs.popover', () => {
window.addEventListener('scroll', hideOnScroll, { once: true });
});
}
}
......@@ -46,7 +46,7 @@ export default class MiniPipelineGraph {
$(document).on(
'click',
`${this.container} .js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item`,
(e) => {
e => {
e.stopPropagation();
},
);
......@@ -82,7 +82,8 @@ export default class MiniPipelineGraph {
this.renderBuildsList(button, '');
this.toggleLoading(button);
axios.get(endpoint)
axios
.get(endpoint)
.then(({ data }) => {
this.toggleLoading(button);
this.renderBuildsList(button, data.html);
......@@ -90,7 +91,11 @@ export default class MiniPipelineGraph {
})
.catch(() => {
this.toggleLoading(button);
if ($(button).parent().hasClass('open')) {
if (
$(button)
.parent()
.hasClass('open')
) {
$(button).dropdown('toggle');
}
flash('An error occurred while fetching the builds.', 'alert');
......@@ -104,8 +109,8 @@ export default class MiniPipelineGraph {
* @return {type}
*/
toggleLoading(stageContainer) {
stageContainer.parentElement.querySelector(
`${this.dropdownListSelector} .js-builds-dropdown-loading`,
).classList.toggle('hidden');
stageContainer.parentElement
.querySelector(`${this.dropdownListSelector} .js-builds-dropdown-loading`)
.classList.toggle('hidden');
}
}
......@@ -14,14 +14,14 @@ export default class NamespaceSelect {
selectable: true,
filterRemote: true,
search: {
fields: ['path']
fields: ['path'],
},
fieldName: fieldName,
toggleLabel: function(selected) {
if (selected.id == null) {
return selected.text;
} else {
return selected.kind + ": " + selected.full_path;
return selected.kind + ': ' + selected.full_path;
}
},
data: function(term, dataCallback) {
......@@ -29,7 +29,7 @@ export default class NamespaceSelect {
if (isFilter) {
const anyNamespace = {
text: 'Any namespace',
id: null
id: null,
};
namespaces.unshift(anyNamespace);
namespaces.splice(1, 0, 'divider');
......@@ -41,7 +41,7 @@ export default class NamespaceSelect {
if (namespace.id == null) {
return namespace.text;
} else {
return namespace.kind + ": " + namespace.full_path;
return namespace.kind + ': ' + namespace.full_path;
}
},
renderRow: this.renderRow,
......
......@@ -20,7 +20,7 @@ export default (function() {
this.mtime = 0;
this.mspace = 0;
this.parents = {};
this.colors = ["#000"];
this.colors = ['#000'];
this.offsetX = 150;
this.offsetY = 20;
this.unitTime = 30;
......@@ -30,9 +30,10 @@ export default (function() {
}
BranchGraph.prototype.load = function() {
axios.get(this.options.url)
axios
.get(this.options.url)
.then(({ data }) => {
$(".loading", this.element).hide();
$('.loading', this.element).hide();
this.prepareData(data.days, data.commits);
this.buildGraph();
})
......@@ -71,17 +72,19 @@ export default (function() {
c = ref[j];
this.mtime = Math.max(this.mtime, c.time);
this.mspace = Math.max(this.mspace, c.space);
results.push((function() {
var l, len1, ref1, results1;
ref1 = c.parents;
results1 = [];
for (l = 0, len1 = ref1.length; l < len1; l += 1) {
p = ref1[l];
this.parents[p[0]] = true;
results1.push(this.mspace = Math.max(this.mspace, p[1]));
}
return results1;
}).call(this));
results.push(
function() {
var l, len1, ref1, results1;
ref1 = c.parents;
results1 = [];
for (l = 0, len1 = ref1.length; l < len1; l += 1) {
p = ref1[l];
this.parents[p[0]] = true;
results1.push((this.mspace = Math.max(this.mspace, p[1])));
}
return results1;
}.call(this),
);
}
return results;
};
......@@ -91,11 +94,11 @@ export default (function() {
k = 0;
results = [];
while (k < this.mspace) {
this.colors.push(Raphael.getColor(.8));
this.colors.push(Raphael.getColor(0.8));
// Skipping a few colors in the spectrum to get more contrast between colors
Raphael.getColor();
Raphael.getColor();
results.push(k += 1);
results.push((k += 1));
}
return results;
};
......@@ -104,12 +107,12 @@ export default (function() {
var cuday, cumonth, day, j, len, mm, ref;
const { r } = this;
cuday = 0;
cumonth = "";
cumonth = '';
r.rect(0, 0, 40, this.barHeight).attr({
fill: "#222"
fill: '#222',
});
r.rect(40, 0, 30, this.barHeight).attr({
fill: "#444"
fill: '#444',
});
ref = this.days;
......@@ -118,16 +121,16 @@ export default (function() {
if (cuday !== day[0] || cumonth !== day[1]) {
// Dates
r.text(55, this.offsetY + this.unitTime * mm, day[0]).attr({
font: "12px Monaco, monospace",
fill: "#BBB"
font: '12px Monaco, monospace',
fill: '#BBB',
});
[cuday] = day;
}
if (cumonth !== day[1]) {
// Months
r.text(20, this.offsetY + this.unitTime * mm, day[1]).attr({
font: "12px Monaco, monospace",
fill: "#EEE"
font: '12px Monaco, monospace',
fill: '#EEE',
});
// eslint-disable-next-line prefer-destructuring
......@@ -173,11 +176,13 @@ export default (function() {
BranchGraph.prototype.bindEvents = function() {
const { element } = this;
return $(element).scroll((function(_this) {
return function(event) {
return _this.renderPartialGraph();
};
})(this));
return $(element).scroll(
(function(_this) {
return function(event) {
return _this.renderPartialGraph();
};
})(this),
);
};
BranchGraph.prototype.scrollDown = function() {
......@@ -219,46 +224,53 @@ export default (function() {
shortrefs = commit.refs;
// Truncate if longer than 15 chars
if (shortrefs.length > 17) {
shortrefs = shortrefs.substr(0, 15) + "";
shortrefs = shortrefs.substr(0, 15) + '';
}
text = r.text(x + 4, y, shortrefs).attr({
"text-anchor": "start",
font: "10px Monaco, monospace",
fill: "#FFF",
title: commit.refs
'text-anchor': 'start',
font: '10px Monaco, monospace',
fill: '#FFF',
title: commit.refs,
});
textbox = text.getBBox();
// Create rectangle based on the size of the textbox
rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr({
fill: "#000",
"fill-opacity": .5,
stroke: "none"
fill: '#000',
'fill-opacity': 0.5,
stroke: 'none',
});
triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr({
fill: "#000",
"fill-opacity": .5,
stroke: "none"
triangle = r.path(['M', x - 5, y, 'L', x - 15, y - 4, 'L', x - 15, y + 4, 'Z']).attr({
fill: '#000',
'fill-opacity': 0.5,
stroke: 'none',
});
label = r.set(rect, text);
label.transform(["t", -rect.getBBox().width - 15, 0]);
label.transform(['t', -rect.getBBox().width - 15, 0]);
// Set text to front
return text.toFront();
};
BranchGraph.prototype.appendAnchor = function(x, y, commit) {
const { r, top, options } = this;
const anchor = r.circle(x, y, 10).attr({
fill: "#000",
opacity: 0,
cursor: "pointer"
}).click(function() {
return window.open(options.commit_url.replace("%s", commit.id), "_blank");
}).hover(function() {
this.tooltip = r.commitTooltip(x + 5, y, commit);
return top.push(this.tooltip.insertBefore(this));
}, function() {
return this.tooltip && this.tooltip.remove() && delete this.tooltip;
});
const anchor = r
.circle(x, y, 10)
.attr({
fill: '#000',
opacity: 0,
cursor: 'pointer',
})
.click(function() {
return window.open(options.commit_url.replace('%s', commit.id), '_blank');
})
.hover(
function() {
this.tooltip = r.commitTooltip(x + 5, y, commit);
return top.push(this.tooltip.insertBefore(this));
},
function() {
return this.tooltip && this.tooltip.remove() && delete this.tooltip;
},
);
return top.push(anchor);
};
......@@ -266,7 +278,7 @@ export default (function() {
const { r } = this;
r.circle(x, y, 3).attr({
fill: this.colors[commit.space],
stroke: "none"
stroke: 'none',
});
const avatar_box_x = this.offsetX + this.unitSpace * this.mspace + 10;
......@@ -274,13 +286,15 @@ export default (function() {
r.rect(avatar_box_x, avatar_box_y, 20, 20).attr({
stroke: this.colors[commit.space],
"stroke-width": 2
'stroke-width': 2,
});
r.image(commit.author.icon, avatar_box_x, avatar_box_y, 20, 20);
return r.text(this.offsetX + this.unitSpace * this.mspace + 35, y, commit.message.split("\n")[0]).attr({
"text-anchor": "start",
font: "14px Monaco, monospace"
});
return r
.text(this.offsetX + this.unitSpace * this.mspace + 35, y, commit.message.split('\n')[0])
.attr({
'text-anchor': 'start',
font: '14px Monaco, monospace',
});
};
BranchGraph.prototype.drawLines = function(x, y, commit) {
......@@ -304,30 +318,32 @@ export default (function() {
// Build line shape
if (parent[1] === commit.space) {
offset = [0, 5];
arrow = "l-2,5,4,0,-2,-5,0,5";
arrow = 'l-2,5,4,0,-2,-5,0,5';
} else if (parent[1] < commit.space) {
offset = [3, 3];
arrow = "l5,0,-2,4,-3,-4,4,2";
arrow = 'l5,0,-2,4,-3,-4,4,2';
} else {
offset = [-3, 3];
arrow = "l-5,0,2,4,3,-4,-4,2";
arrow = 'l-5,0,2,4,3,-4,-4,2';
}
// Start point
route = ["M", x + offset[0], y + offset[1]];
route = ['M', x + offset[0], y + offset[1]];
// Add arrow if not first parent
if (i > 0) {
route.push(arrow);
}
// Circumvent if overlap
if (commit.space !== parentCommit.space || commit.space !== parent[1]) {
route.push("L", parentX2, y + 10, "L", parentX2, parentY - 5);
route.push('L', parentX2, y + 10, 'L', parentX2, parentY - 5);
}
// End point
route.push("L", parentX1, parentY);
results.push(r.path(route).attr({
stroke: color,
"stroke-width": 2
}));
route.push('L', parentX1, parentY);
results.push(
r.path(route).attr({
stroke: color,
'stroke-width': 2,
}),
);
}
return results;
};
......@@ -337,10 +353,10 @@ export default (function() {
const { r } = this;
const x = this.offsetX + this.unitSpace * (this.mspace - commit.space);
const y = this.offsetY + this.unitTime * commit.time;
r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr({
fill: "#000",
"fill-opacity": .5,
stroke: "none"
r.path(['M', x + 5, y, 'L', x + 15, y + 4, 'L', x + 15, y - 4, 'Z']).attr({
fill: '#000',
'fill-opacity': 0.5,
stroke: 'none',
});
// Displayed in the center
return this.element.scrollTop(y - this.graphHeight / 2);
......
......@@ -49,7 +49,7 @@ Raphael.prototype.textWrap = function testWrap(t, width) {
const s = [];
for (let j = 0, len = words.length; j < len; j += 1) {
const word = words[j];
if (x + (word.length * letterWidth) > width) {
if (x + word.length * letterWidth > width) {
s.push('\n');
x = 0;
}
......
......@@ -30,24 +30,24 @@ export default class NewBranchForm {
startsWith = {
pattern: /^(\/|\.)/g,
prefix: "can't start with",
conjunction: "or"
conjunction: 'or',
};
endsWith = {
pattern: /(\/|\.|\.lock)$/g,
prefix: "can't end in",
conjunction: "or"
conjunction: 'or',
};
invalid = {
pattern: /(\s|~|\^|:|\?|\*|\[|\\|\.\.|@\{|\/{2,}){1}/g,
prefix: "can't contain",
conjunction: ", "
conjunction: ', ',
};
single = {
pattern: /^@+$/g,
prefix: "can't be",
conjunction: "or"
conjunction: 'or',
};
return this.restrictions = [startsWith, invalid, endsWith, single];
return (this.restrictions = [startsWith, invalid, endsWith, single]);
}
validate() {
......@@ -73,7 +73,7 @@ export default class NewBranchForm {
return "'" + value + "'";
}
});
return restriction.prefix + " " + (formatted.join(restriction.conjunction));
return restriction.prefix + ' ' + formatted.join(restriction.conjunction);
};
validator = (function(_this) {
return function(errors, restriction) {
......@@ -88,7 +88,7 @@ export default class NewBranchForm {
})(this);
errors = this.restrictions.reduce(validator, []);
if (errors.length > 0) {
errorMessage = $("<span/>").text(errors.join(', '));
errorMessage = $('<span/>').text(errors.join(', '));
return this.branchNameError.append(errorMessage);
}
}
......
......@@ -6,9 +6,7 @@ export default class NewCommitForm {
this.branchName = form.find('.js-branch-name');
this.originalBranch = form.find('.js-original-branch');
this.createMergeRequest = form.find('.js-create-merge-request');
this.createMergeRequestContainer = form.find(
'.js-create-merge-request-container',
);
this.createMergeRequestContainer = form.find('.js-create-merge-request-container');
this.branchName.keyup(this.renderDestination);
this.renderDestination();
}
......
......@@ -18,7 +18,9 @@ export default function notificationsDropdown() {
$(document).on('ajax:success', '.notification-form', (e, data) => {
if (data.saved) {
$(e.currentTarget).closest('.js-notification-dropdown').replaceWith(data.html);
$(e.currentTarget)
.closest('.js-notification-dropdown')
.replaceWith(data.html);
} else {
Flash('Failed to save new settings', 'alert');
}
......
......@@ -22,7 +22,8 @@ export default class NotificationsForm {
// eslint-disable-next-line class-methods-use-this
showCheckboxLoadingSpinner($parent) {
$parent.addClass('is-loading')
$parent
.addClass('is-loading')
.find('.custom-notification-event-loading')
.removeClass('fa-check')
.addClass('fa-spin fa-spinner')
......@@ -38,9 +39,12 @@ export default class NotificationsForm {
.then(({ data }) => {
$checkbox.enable();
if (data.saved) {
$parent.find('.custom-notification-event-loading').toggleClass('fa-spin fa-spinner fa-check is-done');
$parent
.find('.custom-notification-event-loading')
.toggleClass('fa-spin fa-spinner fa-check is-done');
setTimeout(() => {
$parent.removeClass('is-loading')
$parent
.removeClass('is-loading')
.find('.custom-notification-event-loading')
.toggleClass('fa-spin fa-spinner fa-check is-done');
}, 2000);
......
......@@ -24,22 +24,25 @@ export default {
getOld() {
this.loading.show();
axios.get(this.url, {
params: {
limit: this.limit,
offset: this.offset,
},
}).then(({ data }) => {
this.append(data.count, this.prepareData(data.html));
this.callback();
axios
.get(this.url, {
params: {
limit: this.limit,
offset: this.offset,
},
})
.then(({ data }) => {
this.append(data.count, this.prepareData(data.html));
this.callback();
// keep loading until we've filled the viewport height
if (!this.disable && !this.isScrollable()) {
this.getOld();
} else {
this.loading.hide();
}
}).catch(() => this.loading.hide());
// keep loading until we've filled the viewport height
if (!this.disable && !this.isScrollable()) {
this.getOld();
} else {
this.loading.hide();
}
})
.catch(() => this.loading.hide());
},
append(count, html) {
......
<script>
import pdfjsLib from 'vendor/pdf';
import workerSrc from 'vendor/pdf.worker.min';
import pdfjsLib from 'vendor/pdf';
import workerSrc from 'vendor/pdf.worker.min';
import page from './page/index.vue';
import page from './page/index.vue';
export default {
components: { page },
props: {
pdf: {
type: [String, Uint8Array],
required: true,
},
export default {
components: { page },
props: {
pdf: {
type: [String, Uint8Array],
required: true,
},
data() {
return {
loading: false,
pages: [],
};
},
data() {
return {
loading: false,
pages: [],
};
},
computed: {
document() {
return typeof this.pdf === 'string' ? this.pdf : { data: this.pdf };
},
computed: {
document() {
return typeof this.pdf === 'string' ? this.pdf : { data: this.pdf };
},
hasPDF() {
return this.pdf && this.pdf.length > 0;
},
hasPDF() {
return this.pdf && this.pdf.length > 0;
},
watch: { pdf: 'load' },
mounted() {
pdfjsLib.PDFJS.workerSrc = workerSrc;
if (this.hasPDF) this.load();
},
watch: { pdf: 'load' },
mounted() {
pdfjsLib.PDFJS.workerSrc = workerSrc;
if (this.hasPDF) this.load();
},
methods: {
load() {
this.pages = [];
return pdfjsLib
.getDocument(this.document)
.then(this.renderPages)
.then(() => this.$emit('pdflabload'))
.catch(error => this.$emit('pdflaberror', error))
.then(() => {
this.loading = false;
});
},
methods: {
load() {
this.pages = [];
return pdfjsLib.getDocument(this.document)
.then(this.renderPages)
.then(() => this.$emit('pdflabload'))
.catch(error => this.$emit('pdflaberror', error))
.then(() => { this.loading = false; });
},
renderPages(pdf) {
const pagePromises = [];
this.loading = true;
for (let num = 1; num <= pdf.numPages; num += 1) {
pagePromises.push(
pdf.getPage(num).then(p => this.pages.push(p)),
);
}
return Promise.all(pagePromises);
},
renderPages(pdf) {
const pagePromises = [];
this.loading = true;
for (let num = 1; num <= pdf.numPages; num += 1) {
pagePromises.push(pdf.getPage(num).then(p => this.pages.push(p)));
}
return Promise.all(pagePromises);
},
};
},
};
</script>
<template>
......@@ -69,9 +70,9 @@
</template>
<style>
.pdf-viewer {
background: url('./assets/img/bg.gif');
display: flex;
flex-flow: column nowrap;
}
.pdf-viewer {
background: url('./assets/img/bg.gif');
display: flex;
flex-flow: column nowrap;
}
</style>
<script>
export default {
props: {
page: {
type: Object,
required: true,
},
number: {
type: Number,
required: true,
},
export default {
props: {
page: {
type: Object,
required: true,
},
data() {
return {
scale: 4,
rendering: false,
};
number: {
type: Number,
required: true,
},
},
data() {
return {
scale: 4,
rendering: false,
};
},
computed: {
viewport() {
return this.page.getViewport(this.scale);
},
computed: {
viewport() {
return this.page.getViewport(this.scale);
},
context() {
return this.$refs.canvas.getContext('2d');
},
renderContext() {
return {
canvasContext: this.context,
viewport: this.viewport,
};
},
context() {
return this.$refs.canvas.getContext('2d');
},
mounted() {
this.$refs.canvas.height = this.viewport.height;
this.$refs.canvas.width = this.viewport.width;
this.rendering = true;
this.page.render(this.renderContext)
.then(() => { this.rendering = false; })
.catch(error => this.$emit('pdflaberror', error));
renderContext() {
return {
canvasContext: this.context,
viewport: this.viewport,
};
},
};
},
mounted() {
this.$refs.canvas.height = this.viewport.height;
this.$refs.canvas.width = this.viewport.width;
this.rendering = true;
this.page
.render(this.renderContext)
.then(() => {
this.rendering = false;
})
.catch(error => this.$emit('pdflaberror', error));
},
};
</script>
<template>
......@@ -51,20 +54,20 @@
</template>
<style>
.pdf-page {
margin: 8px auto 0 auto;
border-top: 1px #ddd solid;
border-bottom: 1px #ddd solid;
width: 100%;
}
.pdf-page {
margin: 8px auto 0 auto;
border-top: 1px #ddd solid;
border-bottom: 1px #ddd solid;
width: 100%;
}
.pdf-page:first-child {
margin-top: 0px;
border-top: 0px;
}
.pdf-page:first-child {
margin-top: 0px;
border-top: 0px;
}
.pdf-page:last-child {
margin-bottom: 0px;
border-bottom: 0px;
}
.pdf-page:last-child {
margin-bottom: 0px;
border-bottom: 0px;
}
</style>
......@@ -64,10 +64,7 @@ export default {
return [];
}
const { details } = this.pipeline;
return [
...(details.manual_actions || []),
...(details.scheduled_actions || []),
];
return [...(details.manual_actions || []), ...(details.scheduled_actions || [])];
},
/**
* If provided, returns the commit tag.
......
......@@ -10,14 +10,14 @@ import { __ } from '~/locale';
const highlighter = function(element, text, matches) {
var highlightText, j, lastIndex, len, matchIndex, matchedChars, unmatched;
lastIndex = 0;
highlightText = "";
highlightText = '';
matchedChars = [];
for (j = 0, len = matches.length; j < len; j += 1) {
matchIndex = matches[j];
unmatched = text.substring(lastIndex, matchIndex);
if (unmatched) {
if (matchedChars.length) {
element.append(matchedChars.join("").bold());
element.append(matchedChars.join('').bold());
}
matchedChars = [];
element.append(document.createTextNode(unmatched));
......@@ -26,7 +26,7 @@ const highlighter = function(element, text, matches) {
lastIndex = matchIndex + 1;
}
if (matchedChars.length) {
element.append(matchedChars.join("").bold());
element.append(matchedChars.join('').bold());
}
return element.append(document.createTextNode(text.substring(lastIndex)));
};
......@@ -40,7 +40,7 @@ export default class ProjectFindFile {
this.selectRowDown = this.selectRowDown.bind(this);
this.selectRowUp = this.selectRowUp.bind(this);
this.filePaths = {};
this.inputElement = this.element.find(".file-finder-input");
this.inputElement = this.element.find('.file-finder-input');
// init event
this.initEvent();
// focus text input box
......@@ -50,38 +50,51 @@ export default class ProjectFindFile {
}
initEvent() {
this.inputElement.off("keyup");
this.inputElement.on("keyup", (function(_this) {
return function(event) {
var oldValue, ref, target, value;
target = $(event.target);
value = target.val();
oldValue = (ref = target.data("oldValue")) != null ? ref : "";
if (value !== oldValue) {
target.data("oldValue", value);
_this.findFile();
return _this.element.find("tr.tree-item").eq(0).addClass("selected").focus();
}
};
})(this));
this.inputElement.off('keyup');
this.inputElement.on(
'keyup',
(function(_this) {
return function(event) {
var oldValue, ref, target, value;
target = $(event.target);
value = target.val();
oldValue = (ref = target.data('oldValue')) != null ? ref : '';
if (value !== oldValue) {
target.data('oldValue', value);
_this.findFile();
return _this.element
.find('tr.tree-item')
.eq(0)
.addClass('selected')
.focus();
}
};
})(this),
);
}
findFile() {
var result, searchText;
searchText = this.inputElement.val();
result = searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
result =
searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
return this.renderList(result, searchText);
// find file
// find file
}
// files pathes load
load(url) {
axios.get(url)
axios
.get(url)
.then(({ data }) => {
this.element.find('.loading').hide();
this.filePaths = data;
this.findFile();
this.element.find('.files-slider tr.tree-item').eq(0).addClass('selected').focus();
this.element
.find('.files-slider tr.tree-item')
.eq(0)
.addClass('selected')
.focus();
})
.catch(() => flash(__('An error occurred while loading filenames')));
}
......@@ -89,7 +102,7 @@ export default class ProjectFindFile {
// render result
renderList(filePaths, searchText) {
var blobItemUrl, filePath, html, i, len, matches, results;
this.element.find(".tree-table > tbody").empty();
this.element.find('.tree-table > tbody').empty();
results = [];
for (i = 0, len = filePaths.length; i < len; i += 1) {
......@@ -100,9 +113,9 @@ export default class ProjectFindFile {
if (searchText) {
matches = fuzzaldrinPlus.match(filePath, searchText);
}
blobItemUrl = this.options.blobUrlTemplate + "/" + filePath;
blobItemUrl = this.options.blobUrlTemplate + '/' + filePath;
html = ProjectFindFile.makeHtml(filePath, matches, blobItemUrl);
results.push(this.element.find(".tree-table > tbody").append(html));
results.push(this.element.find('.tree-table > tbody').append(html));
}
return results;
}
......@@ -110,52 +123,56 @@ export default class ProjectFindFile {
// make tbody row html
static makeHtml(filePath, matches, blobItemUrl) {
var $tr;
$tr = $("<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>");
$tr = $(
"<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>",
);
if (matches) {
$tr.find("a").replaceWith(highlighter($tr.find("a"), filePath, matches).attr("href", blobItemUrl));
$tr
.find('a')
.replaceWith(highlighter($tr.find('a'), filePath, matches).attr('href', blobItemUrl));
} else {
$tr.find("a").attr("href", blobItemUrl);
$tr.find(".str-truncated").text(filePath);
$tr.find('a').attr('href', blobItemUrl);
$tr.find('.str-truncated').text(filePath);
}
return $tr;
}
selectRow(type) {
var next, rows, selectedRow;
rows = this.element.find(".files-slider tr.tree-item");
selectedRow = this.element.find(".files-slider tr.tree-item.selected");
rows = this.element.find('.files-slider tr.tree-item');
selectedRow = this.element.find('.files-slider tr.tree-item.selected');
if (rows && rows.length > 0) {
if (selectedRow && selectedRow.length > 0) {
if (type === "UP") {
if (type === 'UP') {
next = selectedRow.prev();
} else if (type === "DOWN") {
} else if (type === 'DOWN') {
next = selectedRow.next();
}
if (next.length > 0) {
selectedRow.removeClass("selected");
selectedRow.removeClass('selected');
selectedRow = next;
}
} else {
selectedRow = rows.eq(0);
}
return selectedRow.addClass("selected").focus();
return selectedRow.addClass('selected').focus();
}
}
selectRowUp() {
return this.selectRow("UP");
return this.selectRow('UP');
}
selectRowDown() {
return this.selectRow("DOWN");
return this.selectRow('DOWN');
}
goToTree() {
return window.location.href = this.options.treeUrl;
return (window.location.href = this.options.treeUrl);
}
goToBlob() {
var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
var $link = this.element.find('.tree-item.selected .tree-item-file-name a');
if ($link.length) {
$link.get(0).click();
......
......@@ -5,4 +5,3 @@ export default function projectImport() {
visitUrl(window.location.href);
}, 5000);
}
......@@ -31,32 +31,35 @@ export default class ProjectLabelSubscription {
$btn.addClass('disabled');
axios.post(url).then(() => {
let newStatus;
let newAction;
axios
.post(url)
.then(() => {
let newStatus;
let newAction;
if (oldStatus === 'unsubscribed') {
[newStatus, newAction] = ['subscribed', 'Unsubscribe'];
} else {
[newStatus, newAction] = ['unsubscribed', 'Subscribe'];
}
if (oldStatus === 'unsubscribed') {
[newStatus, newAction] = ['subscribed', 'Unsubscribe'];
} else {
[newStatus, newAction] = ['unsubscribed', 'Subscribe'];
}
$btn.removeClass('disabled');
$btn.removeClass('disabled');
this.$buttons.attr('data-status', newStatus);
this.$buttons.find('> span').text(newAction);
this.$buttons.attr('data-status', newStatus);
this.$buttons.find('> span').text(newAction);
this.$buttons.map((i, button) => {
const $button = $(button);
const originalTitle = $button.attr('data-original-title');
this.$buttons.map((i, button) => {
const $button = $(button);
const originalTitle = $button.attr('data-original-title');
if (originalTitle) {
ProjectLabelSubscription.setNewTitle($button, originalTitle, newStatus, newAction);
}
if (originalTitle) {
ProjectLabelSubscription.setNewTitle($button, originalTitle, newStatus, newAction);
}
return button;
});
}).catch(() => flash(__('There was an error subscribing to this label.')));
return button;
});
})
.catch(() => flash(__('There was an error subscribing to this label.')));
}
static setNewTitle($button, originalTitle, newStatus) {
......
......@@ -16,28 +16,28 @@ export default function projectSelect() {
this.withMergeRequestsEnabled = $(select).data('withMergeRequestsEnabled');
this.allowClear = $(select).data('allowClear') || false;
placeholder = "Search for project";
placeholder = 'Search for project';
if (this.includeGroups) {
placeholder += " or group";
placeholder += ' or group';
}
$(select).select2({
placeholder: placeholder,
minimumInputLength: 0,
query: (function (_this) {
return function (query) {
query: (function(_this) {
return function(query) {
var finalCallback, projectsCallback;
finalCallback = function (projects) {
finalCallback = function(projects) {
var data;
data = {
results: projects
results: projects,
};
return query.callback(data);
};
if (_this.includeGroups) {
projectsCallback = function (projects) {
projectsCallback = function(projects) {
var groupsCallback;
groupsCallback = function (groups) {
groupsCallback = function(groups) {
var data;
data = groups.concat(projects);
return finalCallback(data);
......@@ -48,17 +48,26 @@ export default function projectSelect() {
projectsCallback = finalCallback;
}
if (_this.groupId) {
return Api.groupProjects(_this.groupId, query.term, {
with_issues_enabled: _this.withIssuesEnabled,
with_merge_requests_enabled: _this.withMergeRequestsEnabled,
}, projectsCallback);
return Api.groupProjects(
_this.groupId,
query.term,
{
with_issues_enabled: _this.withIssuesEnabled,
with_merge_requests_enabled: _this.withMergeRequestsEnabled,
},
projectsCallback,
);
} else {
return Api.projects(query.term, {
order_by: _this.orderBy,
with_issues_enabled: _this.withIssuesEnabled,
with_merge_requests_enabled: _this.withMergeRequestsEnabled,
membership: !_this.allProjects,
}, projectsCallback);
return Api.projects(
query.term,
{
order_by: _this.orderBy,
with_issues_enabled: _this.withIssuesEnabled,
with_merge_requests_enabled: _this.withMergeRequestsEnabled,
membership: !_this.allProjects,
},
projectsCallback,
);
}
};
})(this),
......@@ -69,7 +78,7 @@ export default function projectSelect() {
url: project.web_url,
});
},
text: function (project) {
text: function(project) {
return project.name_with_namespace || project.name;
},
......@@ -79,7 +88,7 @@ export default function projectSelect() {
allowClear: this.allowClear,
dropdownCssClass: "ajax-project-dropdown"
dropdownCssClass: 'ajax-project-dropdown',
});
if (simpleFilter) return select;
return new ProjectSelectComboButton(select);
......
......@@ -14,10 +14,11 @@ export default class ProjectSelectComboButton {
}
bindEvents() {
this.projectSelectInput.siblings('.new-project-item-select-button')
this.projectSelectInput
.siblings('.new-project-item-select-button')
.on('click', e => this.openDropdown(e));
this.newItemBtn.on('click', (e) => {
this.newItemBtn.on('click', e => {
if (!this.getProjectFromLocalStorage()) {
e.preventDefault();
this.openDropdown(e);
......@@ -31,14 +32,21 @@ export default class ProjectSelectComboButton {
const localStorageIsSafe = AccessorUtilities.isLocalStorageAccessSafe();
if (localStorageIsSafe) {
this.localStorageKey = ['group', this.groupId, this.formattedText.localStorageItemType, 'recent-project'].join('-');
this.localStorageKey = [
'group',
this.groupId,
this.formattedText.localStorageItemType,
'recent-project',
].join('-');
this.setBtnTextFromLocalStorage();
}
}
// eslint-disable-next-line class-methods-use-this
openDropdown(event) {
$(event.currentTarget).siblings('.project-item-select').select2('open');
$(event.currentTarget)
.siblings('.project-item-select')
.select2('open');
}
selectProject() {
......@@ -86,8 +94,14 @@ export default class ProjectSelectComboButton {
const defaultTextPrefix = this.resourceLabel;
// the trailing slice call depluralizes each of these strings (e.g. new-issues -> new-issue)
const localStorageItemType = `new-${this.resourceType.split('_').join('-').slice(0, -1)}`;
const presetTextSuffix = this.resourceType.split('_').join(' ').slice(0, -1);
const localStorageItemType = `new-${this.resourceType
.split('_')
.join('-')
.slice(0, -1)}`;
const presetTextSuffix = this.resourceType
.split('_')
.join(' ')
.slice(0, -1);
return {
localStorageItemType, // new-issue / new-merge-request
......@@ -96,4 +110,3 @@ export default class ProjectSelectComboButton {
};
}
}
......@@ -7,7 +7,7 @@ function setVisibilityOptions(namespaceSelector) {
const selectedNamespace = namespaceSelector.options[namespaceSelector.selectedIndex];
const { name, visibility, visibilityLevel, showPath, editPath } = selectedNamespace.dataset;
document.querySelectorAll('.visibility-level-setting .form-check').forEach((option) => {
document.querySelectorAll('.visibility-level-setting .form-check').forEach(option => {
const optionInput = option.querySelector('input[type=radio]');
const optionValue = optionInput ? optionInput.value : 0;
const optionTitle = option.querySelector('.option-title');
......@@ -20,8 +20,7 @@ function setVisibilityOptions(namespaceSelector) {
optionInput.disabled = true;
const reason = option.querySelector('.option-disabled-reason');
if (reason) {
reason.innerHTML =
`This project cannot be ${optionName} because the visibility of
reason.innerHTML = `This project cannot be ${optionName} because the visibility of
<a href="${showPath}">${name}</a> is ${visibility}. To make this project
${optionName}, you must first <a href="${editPath}">change the visibility</a>
of the parent group.`;
......
......@@ -65,10 +65,14 @@ export default class PrometheusMetrics {
let totalMissingEnvVarMetrics = 0;
let totalExporters = 0;
metrics.forEach((metric) => {
metrics.forEach(metric => {
if (metric.active_metrics > 0) {
totalExporters += 1;
this.$monitoredMetricsList.append(`<li>${_.escape(metric.group)}<span class="badge">${_.escape(metric.active_metrics)}</span></li>`);
this.$monitoredMetricsList.append(
`<li>${_.escape(metric.group)}<span class="badge">${_.escape(
metric.active_metrics,
)}</span></li>`,
);
totalMonitoredMetrics += metric.active_metrics;
if (metric.metrics_missing_requirements > 0) {
this.$missingEnvVarMetricsList.append(`<li>${_.escape(metric.group)}</li>`);
......@@ -78,17 +82,26 @@ export default class PrometheusMetrics {
});
if (totalMonitoredMetrics === 0) {
const emptyCommonMetricsText = sprintf(s__('PrometheusService|<p class="text-tertiary">No <a href="%{docsUrl}">common metrics</a> were found</p>'), {
docsUrl: this.helpMetricsPath,
}, false);
const emptyCommonMetricsText = sprintf(
s__(
'PrometheusService|<p class="text-tertiary">No <a href="%{docsUrl}">common metrics</a> were found</p>',
),
{
docsUrl: this.helpMetricsPath,
},
false,
);
this.$monitoredMetricsEmpty.empty();
this.$monitoredMetricsEmpty.append(emptyCommonMetricsText);
this.showMonitoringMetricsPanelState(PANEL_STATE.EMPTY);
} else {
const metricsCountText = sprintf(s__('PrometheusService|%{exporters} with %{metrics} were found'), {
exporters: n__('%d exporter', '%d exporters', totalExporters),
metrics: n__('%d metric', '%d metrics', totalMonitoredMetrics),
});
const metricsCountText = sprintf(
s__('PrometheusService|%{exporters} with %{metrics} were found'),
{
exporters: n__('%d exporter', '%d exporters', totalExporters),
metrics: n__('%d metric', '%d metrics', totalMonitoredMetrics),
},
);
this.$monitoredMetricsCount.text(metricsCountText);
this.showMonitoringMetricsPanelState(PANEL_STATE.LIST);
......@@ -102,7 +115,8 @@ export default class PrometheusMetrics {
loadActiveMetrics() {
this.showMonitoringMetricsPanelState(PANEL_STATE.LOADING);
backOff((next, stop) => {
axios.get(this.activeMetricsEndpoint)
axios
.get(this.activeMetricsEndpoint)
.then(({ data }) => {
if (data && data.success) {
stop(data);
......@@ -117,7 +131,7 @@ export default class PrometheusMetrics {
})
.catch(stop);
})
.then((res) => {
.then(res => {
if (res && res.data && res.data.length) {
this.populateActiveMetrics(res.data);
} else {
......
......@@ -9,7 +9,7 @@ const IGNORE_ERRORS = [
'canvas.contentDocument',
'MyApp_RemoveAllHighlights',
'http://tt.epicplay.com',
'Can\'t find variable: ZiteReader',
"Can't find variable: ZiteReader",
'jigsaw is not defined',
'ComboSearch is not defined',
'http://loading.retry.widdit.com/',
......
......@@ -2,7 +2,8 @@ import $ from 'jquery';
class RefSelectDropdown {
constructor($dropdownButton, availableRefs) {
const availableRefsValue = availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
const availableRefsValue =
availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
$dropdownButton.glDropdown({
data: availableRefsValue,
filterable: true,
......@@ -29,7 +30,7 @@ class RefSelectDropdown {
const $fieldInput = $(`input[name="${$dropdownButton.data('fieldName')}"]`, $dropdownContainer);
const $filterInput = $('input[type="search"]', $dropdownContainer);
$filterInput.on('keyup', (e) => {
$filterInput.on('keyup', e => {
const keyCode = e.keyCode || e.which;
if (keyCode !== 13) return;
......
......@@ -3,10 +3,14 @@ import { __ } from './locale';
function expandSection($section) {
$section.find('.js-settings-toggle:not(.js-settings-toggle-trigger-only)').text(__('Collapse'));
$section.find('.settings-content').off('scroll.expandSection').scrollTop(0);
$section
.find('.settings-content')
.off('scroll.expandSection')
.scrollTop(0);
$section.addClass('expanded');
if (!$section.hasClass('no-animate')) {
$section.addClass('animating')
$section
.addClass('animating')
.one('animationend.animateSection', () => $section.removeClass('animating'));
}
}
......@@ -16,7 +20,8 @@ function closeSection($section) {
$section.find('.settings-content').on('scroll.expandSection', () => expandSection($section));
$section.removeClass('expanded');
if (!$section.hasClass('no-animate')) {
$section.addClass('animating')
$section
.addClass('animating')
.one('animationend.animateSection', () => $section.removeClass('animating'));
}
}
......
......@@ -10,8 +10,10 @@ import syntaxHighlight from './syntax_highlight';
const WRAPPER = '<div class="diff-content"></div>';
const LOADING_HTML = '<i class="fa fa-spinner fa-spin"></i>';
const ERROR_HTML = '<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>';
const COLLAPSED_HTML = '<div class="nothing-here-block diff-collapsed">This diff is collapsed. <button class="click-to-expand btn btn-link">Click to expand it.</button></div>';
const ERROR_HTML =
'<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>';
const COLLAPSED_HTML =
'<div class="nothing-here-block diff-collapsed">This diff is collapsed. <button class="click-to-expand btn btn-link">Click to expand it.</button></div>';
export default class SingleFileDiff {
constructor(file) {
......@@ -23,23 +25,36 @@ export default class SingleFileDiff {
this.isOpen = !this.diffForPath;
if (this.diffForPath) {
this.collapsedContent = this.content;
this.loadingContent = $(WRAPPER).addClass('loading').html(LOADING_HTML).hide();
this.loadingContent = $(WRAPPER)
.addClass('loading')
.html(LOADING_HTML)
.hide();
this.content = null;
this.collapsedContent.after(this.loadingContent);
this.$toggleIcon.addClass('fa-caret-right');
} else {
this.collapsedContent = $(WRAPPER).html(COLLAPSED_HTML).hide();
this.collapsedContent = $(WRAPPER)
.html(COLLAPSED_HTML)
.hide();
this.content.after(this.collapsedContent);
this.$toggleIcon.addClass('fa-caret-down');
}
$('.js-file-title, .click-to-expand', this.file).on('click', (function (e) {
this.toggleDiff($(e.target));
}).bind(this));
$('.js-file-title, .click-to-expand', this.file).on(
'click',
function(e) {
this.toggleDiff($(e.target));
}.bind(this),
);
}
toggleDiff($target, cb) {
if (!$target.hasClass('js-file-title') && !$target.hasClass('click-to-expand') && !$target.hasClass('diff-toggle-caret')) return;
if (
!$target.hasClass('js-file-title') &&
!$target.hasClass('click-to-expand') &&
!$target.hasClass('diff-toggle-caret')
)
return;
this.isOpen = !this.isOpen;
if (!this.isOpen && !this.hasError) {
this.content.hide();
......@@ -65,7 +80,8 @@ export default class SingleFileDiff {
this.collapsedContent.hide();
this.loadingContent.show();
axios.get(this.diffForPath)
axios
.get(this.diffForPath)
.then(({ data }) => {
this.loadingContent.hide();
if (data.html) {
......
......@@ -93,7 +93,9 @@ export default class SmartInterval {
destroy() {
this.cancel();
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
$(document).off('visibilitychange').off('beforeunload');
$(document)
.off('visibilitychange')
.off('beforeunload');
}
/* private */
......@@ -111,11 +113,12 @@ export default class SmartInterval {
triggerCallback() {
this.isLoading = true;
this.cfg.callback()
this.cfg
.callback()
.then(() => {
this.isLoading = false;
})
.catch((err) => {
.catch(err => {
this.isLoading = false;
throw err;
});
......@@ -134,9 +137,9 @@ export default class SmartInterval {
handleVisibilityChange(e) {
this.state.pageVisibility = e.target.visibilityState;
const intervalAction = this.isPageVisible() ?
this.onVisibilityVisible :
this.onVisibilityHidden;
const intervalAction = this.isPageVisible()
? this.onVisibilityVisible
: this.onVisibilityHidden;
intervalAction.apply(this);
}
......@@ -162,7 +165,9 @@ export default class SmartInterval {
this.setCurrentInterval(nextInterval);
}
isPageVisible() { return this.state.pageVisibility === 'visible'; }
isPageVisible() {
return this.state.pageVisibility === 'visible';
}
stopTimer() {
const { state } = this;
......@@ -170,4 +175,3 @@ export default class SmartInterval {
state.intervalId = window.clearInterval(state.intervalId);
}
}
......@@ -11,10 +11,14 @@ export default class Star {
const $starSpan = $this.find('span');
const $startIcon = $this.find('svg');
axios.post($this.data('endpoint'))
axios
.post($this.data('endpoint'))
.then(({ data }) => {
const isStarred = $starSpan.hasClass('starred');
$this.parent().find('.star-count').text(data.star_count);
$this
.parent()
.find('.star-count')
.text(data.star_count);
if (isStarred) {
$starSpan.removeClass('starred').text(s__('StarProject|Star'));
......
......@@ -26,7 +26,11 @@ export default class TaskList {
// Prevent duplicate event bindings
this.disable();
$(`${this.selector} .js-task-list-container`).taskList('enable');
$(document).on('tasklist:changed', `${this.selector} .js-task-list-container`, this.update.bind(this));
$(document).on(
'tasklist:changed',
`${this.selector} .js-task-list-container`,
this.update.bind(this),
);
}
disable() {
......@@ -41,7 +45,8 @@ export default class TaskList {
[this.fieldName]: $target.val(),
};
return axios.patch($target.data('updateUrl') || $('form.js-issuable-update').attr('action'), patchData)
return axios
.patch($target.data('updateUrl') || $('form.js-issuable-update').attr('action'), patchData)
.then(({ data }) => this.onSuccess(data))
.catch(err => this.onError(err));
}
......
......@@ -31,12 +31,18 @@ export default class IssuableTemplateSelector extends TemplateSelector {
requestFile(query) {
this.startLoadingSpinner();
Api.issueTemplate(this.namespacePath, this.projectPath, query.name, this.issuableType, (err, currentTemplate) => {
this.currentTemplate = currentTemplate;
this.stopLoadingSpinner();
if (err) return; // Error handled by global AJAX error handler
this.setInputValueToTemplateContent();
});
Api.issueTemplate(
this.namespacePath,
this.projectPath,
query.name,
this.issuableType,
(err, currentTemplate) => {
this.currentTemplate = currentTemplate;
this.stopLoadingSpinner();
if (err) return; // Error handled by global AJAX error handler
this.setInputValueToTemplateContent();
},
);
return;
}
......
......@@ -4,10 +4,14 @@ import * as fit from 'xterm/lib/addons/fit/fit';
export default class GLTerminal {
constructor(options = {}) {
this.options = Object.assign({}, {
cursorBlink: true,
screenKeys: true,
}, options);
this.options = Object.assign(
{},
{
cursorBlink: true,
screenKeys: true,
},
options,
);
this.container = document.querySelector(options.selector);
......
......@@ -4,15 +4,43 @@ function simulateEvent(el, type, options = {}) {
if (/^mouse/.test(type)) {
event = el.ownerDocument.createEvent('MouseEvents');
event.initMouseEvent(type, true, true, el.ownerDocument.defaultView,
options.button, options.screenX, options.screenY, options.clientX, options.clientY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
event.initMouseEvent(
type,
true,
true,
el.ownerDocument.defaultView,
options.button,
options.screenX,
options.screenY,
options.clientX,
options.clientY,
options.ctrlKey,
options.altKey,
options.shiftKey,
options.metaKey,
options.button,
el,
);
} else {
event = el.ownerDocument.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, el.ownerDocument.defaultView,
options.button, options.screenX, options.screenY, options.clientX, options.clientY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
event.initCustomEvent(
type,
true,
true,
el.ownerDocument.defaultView,
options.button,
options.screenX,
options.screenY,
options.clientX,
options.clientY,
options.ctrlKey,
options.altKey,
options.shiftKey,
options.metaKey,
options.button,
el,
);
event.dataTransfer = {
data: {},
......@@ -37,14 +65,16 @@ function simulateEvent(el, type, options = {}) {
}
function isLast(target) {
const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
const el =
typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
const { children } = el;
return children.length - 1 === target.index;
}
function getTarget(target) {
const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
const el =
typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
const { children } = el;
return (
......@@ -58,13 +88,13 @@ function getTarget(target) {
function getRect(el) {
const rect = el.getBoundingClientRect();
const width = rect.right - rect.left;
const height = (rect.bottom - rect.top) + 10;
const height = rect.bottom - rect.top + 10;
return {
x: rect.left,
y: rect.top,
cx: rect.left + (width / 2),
cy: rect.top + (height / 2),
cx: rect.left + width / 2,
cy: rect.top + height / 2,
w: width,
h: height,
hw: width / 2,
......@@ -112,8 +142,8 @@ export default function simulateDrag(options) {
const dragInterval = setInterval(() => {
const progress = (new Date().getTime() - startTime) / duration;
const x = (fromRect.cx + ((toRect.cx - fromRect.cx) * progress));
const y = (fromRect.cy + ((toRect.cy - fromRect.cy) * progress));
const x = fromRect.cx + (toRect.cx - fromRect.cx) * progress;
const y = fromRect.cy + (toRect.cy - fromRect.cy) * progress;
const overEl = fromEl.ownerDocument.elementFromPoint(x, y);
simulateEvent(overEl, 'mousemove', {
......
......@@ -12,7 +12,7 @@ export default function simulateInput(target, text) {
}
if (text.length > 0) {
Array.prototype.forEach.call(text, (char) => {
Array.prototype.forEach.call(text, char => {
input.value += char;
triggerEvents(input);
});
......
......@@ -49,7 +49,7 @@ function onToggleClicked(toggle, input, clickCallback) {
export default function setupToggleButtons(container, clickCallback = () => {}) {
const toggles = container.querySelectorAll('.js-project-feature-toggle');
toggles.forEach((toggle) => {
toggles.forEach(toggle => {
const input = toggle.querySelector('.js-project-feature-toggle-input');
const isOn = convertPermissionToBoolean(input.value);
......
......@@ -8,7 +8,7 @@ export default class TreeView {
this.initKeyNav();
// Code browser tree slider
// Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$(".tree-content-holder .tree-item").on('click', function(e) {
$('.tree-content-holder .tree-item').on('click', function(e) {
var $clickedEl, path;
$clickedEl = $(e.target);
path = $('.tree-item-file-name a', this).attr('href');
......@@ -27,33 +27,33 @@ export default class TreeView {
initKeyNav() {
var li, liSelected;
li = $("tr.tree-item");
li = $('tr.tree-item');
liSelected = null;
return $('body').keydown(function(e) {
var next, path;
if ($("input:focus").length > 0 && (e.which === 38 || e.which === 40)) {
if ($('input:focus').length > 0 && (e.which === 38 || e.which === 40)) {
return false;
}
if (e.which === 40) {
if (liSelected) {
next = liSelected.next();
if (next.length > 0) {
liSelected.removeClass("selected");
liSelected = next.addClass("selected");
liSelected.removeClass('selected');
liSelected = next.addClass('selected');
}
} else {
liSelected = li.eq(0).addClass("selected");
liSelected = li.eq(0).addClass('selected');
}
return $(liSelected).focus();
} else if (e.which === 38) {
if (liSelected) {
next = liSelected.prev();
if (next.length > 0) {
liSelected.removeClass("selected");
liSelected = next.addClass("selected");
liSelected.removeClass('selected');
liSelected = next.addClass('selected');
}
} else {
liSelected = li.last().addClass("selected");
liSelected = li.last().addClass('selected');
}
return $(liSelected).focus();
} else if (e.which === 13) {
......
......@@ -49,7 +49,7 @@ export default class U2FAuthenticate {
start() {
return importU2FLibrary()
.then((utils) => {
.then(utils => {
this.u2fUtils = utils;
this.renderInProgress();
})
......@@ -57,14 +57,19 @@ export default class U2FAuthenticate {
}
authenticate() {
return this.u2fUtils.sign(this.appId, this.challenge, this.signRequests,
(response) => {
return this.u2fUtils.sign(
this.appId,
this.challenge,
this.signRequests,
response => {
if (response.errorCode) {
const error = new U2FError(response.errorCode, 'authenticate');
return this.renderError(error);
}
return this.renderAuthenticated(JSON.stringify(response));
}, 10);
},
10,
);
}
renderTemplate(name, params) {
......@@ -99,5 +104,4 @@ export default class U2FAuthenticate {
this.container[0].classList.add('hidden');
this.fallbackUI.classList.remove('hidden');
}
}
......@@ -34,7 +34,7 @@ export default class U2FRegister {
start() {
return importU2FLibrary()
.then((utils) => {
.then(utils => {
this.u2fUtils = utils;
this.renderSetup();
})
......@@ -42,14 +42,19 @@ export default class U2FRegister {
}
register() {
return this.u2fUtils.register(this.appId, this.registerRequests, this.signRequests,
(response) => {
return this.u2fUtils.register(
this.appId,
this.registerRequests,
this.signRequests,
response => {
if (response.errorCode) {
const error = new U2FError(response.errorCode, 'register');
return this.renderError(error);
}
return this.renderRegistered(JSON.stringify(response));
}, 10);
},
10,
);
}
renderTemplate(name, params) {
......
......@@ -19,11 +19,10 @@ function getChromeVersion(userAgent) {
export function canInjectU2fApi(userAgent) {
const isSupportedChrome = isChrome(userAgent) && getChromeVersion(userAgent) >= 41;
const isSupportedOpera = isOpera(userAgent) && getOperaVersion(userAgent) >= 40;
const isMobile = (
const isMobile =
userAgent.indexOf('droid') >= 0 ||
userAgent.indexOf('CriOS') >= 0 ||
/\b(iPad|iPhone|iPod)(?=;)/.test(userAgent)
);
/\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
return (isSupportedChrome || isSupportedOpera) && !isMobile;
}
......
......@@ -4,13 +4,17 @@ import Api from './api';
export default () => {
$('#js-project-dropdown').glDropdown({
data: (term, callback) => {
Api.projects(term, {
order_by: 'last_activity_at',
}, (data) => {
callback(data);
});
Api.projects(
term,
{
order_by: 'last_activity_at',
},
data => {
callback(data);
},
);
},
text: project => (project.name_with_namespace || project.name),
text: project => project.name_with_namespace || project.name,
selectable: true,
fieldName: 'author_id',
filterable: true,
......@@ -18,6 +22,6 @@ export default () => {
fields: ['name_with_namespace'],
},
id: data => data.id,
isSelected: data => (data.id === 2),
isSelected: data => data.id === 2,
});
};
......@@ -4,7 +4,7 @@ import Flash, { hideFlash } from './flash';
import { convertPermissionToBoolean } from './lib/utils/common_utils';
export default () => {
$('body').on('click', '.js-usage-consent-action', (e) => {
$('body').on('click', '.js-usage-consent-action', e => {
e.preventDefault();
e.stopImmediatePropagation(); // overwrite rails listener
......@@ -18,7 +18,8 @@ export default () => {
const hideConsentMessage = () => hideFlash(document.querySelector('.ping-consent-message'));
axios.put(url, data)
axios
.put(url, data)
.then(() => {
hideConsentMessage();
})
......
......@@ -15,8 +15,8 @@ function UsersSelect(currentUser, els, options = {}) {
var $els;
this.users = this.users.bind(this);
this.user = this.user.bind(this);
this.usersPath = "/autocomplete/users.json";
this.userPath = "/autocomplete/users/:id.json";
this.usersPath = '/autocomplete/users.json';
this.userPath = '/autocomplete/users/:id.json';
if (currentUser != null) {
if (typeof currentUser === 'object') {
this.currentUser = currentUser;
......@@ -33,156 +33,180 @@ function UsersSelect(currentUser, els, options = {}) {
$els = $('.js-user-search');
}
$els.each((function(_this) {
return function(i, dropdown) {
var options = {};
var $block, $collapsedSidebar, $dropdown, $loading, $selectbox, $value, abilityName, assignTo, assigneeTemplate, collapsedAssigneeTemplate, defaultLabel, defaultNullUser, firstUser, issueURL, selectedId, selectedIdDefault, showAnyUser, showNullUser, showMenuAbove;
$dropdown = $(dropdown);
options.projectId = $dropdown.data('projectId');
options.groupId = $dropdown.data('groupId');
options.showCurrentUser = $dropdown.data('currentUser');
options.todoFilter = $dropdown.data('todoFilter');
options.todoStateFilter = $dropdown.data('todoStateFilter');
showNullUser = $dropdown.data('nullUser');
defaultNullUser = $dropdown.data('nullUserDefault');
showMenuAbove = $dropdown.data('showMenuAbove');
showAnyUser = $dropdown.data('anyUser');
firstUser = $dropdown.data('firstUser');
options.authorId = $dropdown.data('authorId');
defaultLabel = $dropdown.data('defaultLabel');
issueURL = $dropdown.data('issueUpdate');
$selectbox = $dropdown.closest('.selectbox');
$block = $selectbox.closest('.block');
abilityName = $dropdown.data('abilityName');
$value = $block.find('.value');
$collapsedSidebar = $block.find('.sidebar-collapsed-user');
$loading = $block.find('.block-loading').fadeOut();
selectedIdDefault = (defaultNullUser && showNullUser) ? 0 : null;
selectedId = $dropdown.data('selected');
if (selectedId === undefined) {
selectedId = selectedIdDefault;
}
const assignYourself = function () {
const unassignedSelected = $dropdown.closest('.selectbox')
.find(`input[name='${$dropdown.data('fieldName')}'][value=0]`);
if (unassignedSelected) {
unassignedSelected.remove();
$els.each(
(function(_this) {
return function(i, dropdown) {
var options = {};
var $block,
$collapsedSidebar,
$dropdown,
$loading,
$selectbox,
$value,
abilityName,
assignTo,
assigneeTemplate,
collapsedAssigneeTemplate,
defaultLabel,
defaultNullUser,
firstUser,
issueURL,
selectedId,
selectedIdDefault,
showAnyUser,
showNullUser,
showMenuAbove;
$dropdown = $(dropdown);
options.projectId = $dropdown.data('projectId');
options.groupId = $dropdown.data('groupId');
options.showCurrentUser = $dropdown.data('currentUser');
options.todoFilter = $dropdown.data('todoFilter');
options.todoStateFilter = $dropdown.data('todoStateFilter');
showNullUser = $dropdown.data('nullUser');
defaultNullUser = $dropdown.data('nullUserDefault');
showMenuAbove = $dropdown.data('showMenuAbove');
showAnyUser = $dropdown.data('anyUser');
firstUser = $dropdown.data('firstUser');
options.authorId = $dropdown.data('authorId');
defaultLabel = $dropdown.data('defaultLabel');
issueURL = $dropdown.data('issueUpdate');
$selectbox = $dropdown.closest('.selectbox');
$block = $selectbox.closest('.block');
abilityName = $dropdown.data('abilityName');
$value = $block.find('.value');
$collapsedSidebar = $block.find('.sidebar-collapsed-user');
$loading = $block.find('.block-loading').fadeOut();
selectedIdDefault = defaultNullUser && showNullUser ? 0 : null;
selectedId = $dropdown.data('selected');
if (selectedId === undefined) {
selectedId = selectedIdDefault;
}
// Save current selected user to the DOM
const input = document.createElement('input');
input.type = 'hidden';
input.name = $dropdown.data('fieldName');
const assignYourself = function() {
const unassignedSelected = $dropdown
.closest('.selectbox')
.find(`input[name='${$dropdown.data('fieldName')}'][value=0]`);
const currentUserInfo = $dropdown.data('currentUserInfo');
if (currentUserInfo) {
input.value = currentUserInfo.id;
input.dataset.meta = _.escape(currentUserInfo.name);
} else if (_this.currentUser) {
input.value = _this.currentUser.id;
}
if ($selectbox) {
$dropdown.parent().before(input);
} else {
$dropdown.after(input);
}
};
if ($block[0]) {
$block[0].addEventListener('assignYourself', assignYourself);
}
const getSelectedUserInputs = function() {
return $selectbox
.find(`input[name="${$dropdown.data('fieldName')}"]`);
};
if (unassignedSelected) {
unassignedSelected.remove();
}
const getSelected = function() {
return getSelectedUserInputs()
.map((index, input) => parseInt(input.value, 10))
.get();
};
// Save current selected user to the DOM
const input = document.createElement('input');
input.type = 'hidden';
input.name = $dropdown.data('fieldName');
const checkMaxSelect = function() {
const maxSelect = $dropdown.data('maxSelect');
if (maxSelect) {
const selected = getSelected();
const currentUserInfo = $dropdown.data('currentUserInfo');
if (selected.length > maxSelect) {
const firstSelectedId = selected[0];
const firstSelected = $dropdown.closest('.selectbox')
.find(`input[name='${$dropdown.data('fieldName')}'][value=${firstSelectedId}]`);
if (currentUserInfo) {
input.value = currentUserInfo.id;
input.dataset.meta = _.escape(currentUserInfo.name);
} else if (_this.currentUser) {
input.value = _this.currentUser.id;
}
firstSelected.remove();
emitSidebarEvent('sidebar.removeAssignee', {
id: firstSelectedId,
});
if ($selectbox) {
$dropdown.parent().before(input);
} else {
$dropdown.after(input);
}
}
};
};
const getMultiSelectDropdownTitle = function(selectedUser, isSelected) {
const selectedUsers = getSelected()
.filter(u => u !== 0);
const firstUser = getSelectedUserInputs()
.map((index, input) => ({
name: input.dataset.meta,
value: parseInt(input.value, 10),
}))
.filter(u => u.id !== 0)
.get(0);
if (selectedUsers.length === 0) {
return 'Unassigned';
} else if (selectedUsers.length === 1) {
return firstUser.name;
} else if (isSelected) {
const otherSelected = selectedUsers.filter(s => s !== selectedUser.id);
return `${selectedUser.name} + ${otherSelected.length} more`;
} else {
return `${firstUser.name} + ${selectedUsers.length - 1} more`;
if ($block[0]) {
$block[0].addEventListener('assignYourself', assignYourself);
}
};
$('.assign-to-me-link').on('click', (e) => {
e.preventDefault();
$(e.currentTarget).hide();
const getSelectedUserInputs = function() {
return $selectbox.find(`input[name="${$dropdown.data('fieldName')}"]`);
};
const getSelected = function() {
return getSelectedUserInputs()
.map((index, input) => parseInt(input.value, 10))
.get();
};
const checkMaxSelect = function() {
const maxSelect = $dropdown.data('maxSelect');
if (maxSelect) {
const selected = getSelected();
if (selected.length > maxSelect) {
const firstSelectedId = selected[0];
const firstSelected = $dropdown
.closest('.selectbox')
.find(`input[name='${$dropdown.data('fieldName')}'][value=${firstSelectedId}]`);
firstSelected.remove();
emitSidebarEvent('sidebar.removeAssignee', {
id: firstSelectedId,
});
}
}
};
const getMultiSelectDropdownTitle = function(selectedUser, isSelected) {
const selectedUsers = getSelected().filter(u => u !== 0);
const firstUser = getSelectedUserInputs()
.map((index, input) => ({
name: input.dataset.meta,
value: parseInt(input.value, 10),
}))
.filter(u => u.id !== 0)
.get(0);
if (selectedUsers.length === 0) {
return 'Unassigned';
} else if (selectedUsers.length === 1) {
return firstUser.name;
} else if (isSelected) {
const otherSelected = selectedUsers.filter(s => s !== selectedUser.id);
return `${selectedUser.name} + ${otherSelected.length} more`;
} else {
return `${firstUser.name} + ${selectedUsers.length - 1} more`;
}
};
if ($dropdown.data('multiSelect')) {
assignYourself();
checkMaxSelect();
$('.assign-to-me-link').on('click', e => {
e.preventDefault();
$(e.currentTarget).hide();
const currentUserInfo = $dropdown.data('currentUserInfo');
$dropdown.find('.dropdown-toggle-text').text(getMultiSelectDropdownTitle(currentUserInfo)).removeClass('is-default');
} else {
const $input = $(`input[name="${$dropdown.data('fieldName')}"]`);
$input.val(gon.current_user_id);
selectedId = $input.val();
$dropdown.find('.dropdown-toggle-text').text(gon.current_user_fullname).removeClass('is-default');
}
});
$block.on('click', '.js-assign-yourself', (e) => {
e.preventDefault();
return assignTo(_this.currentUser.id);
});
assignTo = function(selected) {
var data;
data = {};
data[abilityName] = {};
data[abilityName].assignee_id = selected != null ? selected : null;
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
return axios.put(issueURL, data)
.then(({ data }) => {
if ($dropdown.data('multiSelect')) {
assignYourself();
checkMaxSelect();
const currentUserInfo = $dropdown.data('currentUserInfo');
$dropdown
.find('.dropdown-toggle-text')
.text(getMultiSelectDropdownTitle(currentUserInfo))
.removeClass('is-default');
} else {
const $input = $(`input[name="${$dropdown.data('fieldName')}"]`);
$input.val(gon.current_user_id);
selectedId = $input.val();
$dropdown
.find('.dropdown-toggle-text')
.text(gon.current_user_fullname)
.removeClass('is-default');
}
});
$block.on('click', '.js-assign-yourself', e => {
e.preventDefault();
return assignTo(_this.currentUser.id);
});
assignTo = function(selected) {
var data;
data = {};
data[abilityName] = {};
data[abilityName].assignee_id = selected != null ? selected : null;
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
return axios.put(issueURL, data).then(({ data }) => {
var user, tooltipTitle;
$dropdown.trigger('loaded.gl.dropdown');
$loading.fadeOut();
......@@ -190,14 +214,14 @@ function UsersSelect(currentUser, els, options = {}) {
user = {
name: data.assignee.name,
username: data.assignee.username,
avatar: data.assignee.avatar_url
avatar: data.assignee.avatar_url,
};
tooltipTitle = _.escape(user.name);
} else {
user = {
name: 'Unassigned',
username: '',
avatar: ''
avatar: '',
};
tooltipTitle = __('Assignee');
}
......@@ -205,319 +229,341 @@ function UsersSelect(currentUser, els, options = {}) {
$collapsedSidebar.attr('title', tooltipTitle).tooltip('_fixTitle');
return $collapsedSidebar.html(collapsedAssigneeTemplate(user));
});
};
collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>');
assigneeTemplate = _.template('<% if (username) { %> <a class="author-link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>');
return $dropdown.glDropdown({
showMenuAbove: showMenuAbove,
data: function(term, callback) {
return _this.users(term, options, function(users) {
// GitLabDropdownFilter returns this.instance
// GitLabDropdownRemote returns this.options.instance
const glDropdown = this.instance || this.options.instance;
glDropdown.options.processData(term, users, callback);
}.bind(this));
},
processData: function(term, data, callback) {
let users = data;
// Only show assigned user list when there is no search term
if ($dropdown.hasClass('js-multiselect') && term.length === 0) {
const selectedInputs = getSelectedUserInputs();
// Potential duplicate entries when dealing with issue board
// because issue board is also managed by vue
const selectedUsers = _.uniq(selectedInputs, false, a => a.value)
.filter((input) => {
const userId = parseInt(input.value, 10);
const inUsersArray = users.find(u => u.id === userId);
return !inUsersArray && userId !== 0;
})
.map((input) => {
const userId = parseInt(input.value, 10);
const { avatarUrl, avatar_url, name, username } = input.dataset;
return {
avatar_url: avatarUrl || avatar_url,
id: userId,
name,
username,
};
});
};
collapsedAssigneeTemplate = _.template(
'<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>',
);
assigneeTemplate = _.template(
'<% if (username) { %> <a class="author-link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>',
);
return $dropdown.glDropdown({
showMenuAbove: showMenuAbove,
data: function(term, callback) {
return _this.users(
term,
options,
function(users) {
// GitLabDropdownFilter returns this.instance
// GitLabDropdownRemote returns this.options.instance
const glDropdown = this.instance || this.options.instance;
glDropdown.options.processData(term, users, callback);
}.bind(this),
);
},
processData: function(term, data, callback) {
let users = data;
// Only show assigned user list when there is no search term
if ($dropdown.hasClass('js-multiselect') && term.length === 0) {
const selectedInputs = getSelectedUserInputs();
// Potential duplicate entries when dealing with issue board
// because issue board is also managed by vue
const selectedUsers = _.uniq(selectedInputs, false, a => a.value)
.filter(input => {
const userId = parseInt(input.value, 10);
const inUsersArray = users.find(u => u.id === userId);
return !inUsersArray && userId !== 0;
})
.map(input => {
const userId = parseInt(input.value, 10);
const { avatarUrl, avatar_url, name, username } = input.dataset;
return {
avatar_url: avatarUrl || avatar_url,
id: userId,
name,
username,
};
});
users = data.concat(selectedUsers);
}
users = data.concat(selectedUsers);
}
let anyUser;
let index;
let len;
let name;
let obj;
let showDivider;
if (term.length === 0) {
showDivider = 0;
if (firstUser) {
// Move current user to the front of the list
for (index = 0, len = users.length; index < len; index += 1) {
obj = users[index];
if (obj.username === firstUser) {
users.splice(index, 1);
users.unshift(obj);
break;
let anyUser;
let index;
let len;
let name;
let obj;
let showDivider;
if (term.length === 0) {
showDivider = 0;
if (firstUser) {
// Move current user to the front of the list
for (index = 0, len = users.length; index < len; index += 1) {
obj = users[index];
if (obj.username === firstUser) {
users.splice(index, 1);
users.unshift(obj);
break;
}
}
}
}
if (showNullUser) {
showDivider += 1;
users.unshift({
beforeDivider: true,
name: 'Unassigned',
id: 0
});
}
if (showAnyUser) {
showDivider += 1;
name = showAnyUser;
if (name === true) {
name = 'Any User';
if (showNullUser) {
showDivider += 1;
users.unshift({
beforeDivider: true,
name: 'Unassigned',
id: 0,
});
}
if (showAnyUser) {
showDivider += 1;
name = showAnyUser;
if (name === true) {
name = 'Any User';
}
anyUser = {
beforeDivider: true,
name: name,
id: null,
};
users.unshift(anyUser);
}
anyUser = {
beforeDivider: true,
name: name,
id: null
};
users.unshift(anyUser);
}
if (showDivider) {
users.splice(showDivider, 0, 'divider');
}
if (showDivider) {
users.splice(showDivider, 0, 'divider');
}
if ($dropdown.hasClass('js-multiselect')) {
const selected = getSelected().filter(i => i !== 0);
if ($dropdown.hasClass('js-multiselect')) {
const selected = getSelected().filter(i => i !== 0);
if (selected.length > 0) {
if ($dropdown.data('dropdownHeader')) {
showDivider += 1;
users.splice(showDivider, 0, {
header: $dropdown.data('dropdownHeader'),
});
}
if (selected.length > 0) {
if ($dropdown.data('dropdownHeader')) {
showDivider += 1;
users.splice(showDivider, 0, {
header: $dropdown.data('dropdownHeader'),
});
}
const selectedUsers = users
.filter(u => selected.indexOf(u.id) !== -1)
.sort((a, b) => a.name > b.name);
const selectedUsers = users
.filter(u => selected.indexOf(u.id) !== -1)
.sort((a, b) => a.name > b.name);
users = users.filter(u => selected.indexOf(u.id) === -1);
users = users.filter(u => selected.indexOf(u.id) === -1);
selectedUsers.forEach((selectedUser) => {
showDivider += 1;
users.splice(showDivider, 0, selectedUser);
});
selectedUsers.forEach(selectedUser => {
showDivider += 1;
users.splice(showDivider, 0, selectedUser);
});
users.splice(showDivider + 1, 0, 'divider');
users.splice(showDivider + 1, 0, 'divider');
}
}
}
}
callback(users);
if (showMenuAbove) {
$dropdown.data('glDropdown').positionMenuAbove();
}
},
filterable: true,
filterRemote: true,
search: {
fields: ['name', 'username']
},
selectable: true,
fieldName: $dropdown.data('fieldName'),
toggleLabel: function(selected, el, glDropdown) {
const inputValue = glDropdown.filterInput.val();
if (this.multiSelect && inputValue === '') {
// Remove non-users from the fullData array
const users = glDropdown.filteredFullData();
const callback = glDropdown.parseData.bind(glDropdown);
// Update the data model
this.processData(inputValue, users, callback);
}
callback(users);
if (showMenuAbove) {
$dropdown.data('glDropdown').positionMenuAbove();
}
},
filterable: true,
filterRemote: true,
search: {
fields: ['name', 'username'],
},
selectable: true,
fieldName: $dropdown.data('fieldName'),
toggleLabel: function(selected, el, glDropdown) {
const inputValue = glDropdown.filterInput.val();
if (this.multiSelect && inputValue === '') {
// Remove non-users from the fullData array
const users = glDropdown.filteredFullData();
const callback = glDropdown.parseData.bind(glDropdown);
// Update the data model
this.processData(inputValue, users, callback);
}
if (this.multiSelect) {
return getMultiSelectDropdownTitle(selected, $(el).hasClass('is-active'));
}
if (this.multiSelect) {
return getMultiSelectDropdownTitle(selected, $(el).hasClass('is-active'));
}
if (selected && 'id' in selected && $(el).hasClass('is-active')) {
$dropdown.find('.dropdown-toggle-text').removeClass('is-default');
if (selected.text) {
return selected.text;
if (selected && 'id' in selected && $(el).hasClass('is-active')) {
$dropdown.find('.dropdown-toggle-text').removeClass('is-default');
if (selected.text) {
return selected.text;
} else {
return selected.name;
}
} else {
return selected.name;
$dropdown.find('.dropdown-toggle-text').addClass('is-default');
return defaultLabel;
}
},
defaultLabel: defaultLabel,
hidden: function(e) {
if ($dropdown.hasClass('js-multiselect')) {
emitSidebarEvent('sidebar.saveAssignees');
}
} else {
$dropdown.find('.dropdown-toggle-text').addClass('is-default');
return defaultLabel;
}
},
defaultLabel: defaultLabel,
hidden: function(e) {
if ($dropdown.hasClass('js-multiselect')) {
emitSidebarEvent('sidebar.saveAssignees');
}
if (!$dropdown.data('alwaysShowSelectbox')) {
$selectbox.hide();
// Recalculate where .value is because vue might have changed it
$block = $selectbox.closest('.block');
$value = $block.find('.value');
// display:block overrides the hide-collapse rule
$value.css('display', '');
}
},
multiSelect: $dropdown.hasClass('js-multiselect'),
inputMeta: $dropdown.data('inputMeta'),
clicked: function(options) {
const { $el, e, isMarking } = options;
const user = options.selectedObj;
if ($dropdown.hasClass('js-multiselect')) {
const isActive = $el.hasClass('is-active');
const previouslySelected = $dropdown.closest('.selectbox')
.find("input[name='" + ($dropdown.data('fieldName')) + "'][value!=0]");
// Enables support for limiting the number of users selected
// Automatically removes the first on the list if more users are selected
checkMaxSelect();
if (!$dropdown.data('alwaysShowSelectbox')) {
$selectbox.hide();
if (user.beforeDivider && user.name.toLowerCase() === 'unassigned') {
// Unassigned selected
previouslySelected.each((index, element) => {
const id = parseInt(element.value, 10);
element.remove();
});
emitSidebarEvent('sidebar.removeAllAssignees');
} else if (isActive) {
// user selected
emitSidebarEvent('sidebar.addAssignee', user);
// Recalculate where .value is because vue might have changed it
$block = $selectbox.closest('.block');
$value = $block.find('.value');
// display:block overrides the hide-collapse rule
$value.css('display', '');
}
},
multiSelect: $dropdown.hasClass('js-multiselect'),
inputMeta: $dropdown.data('inputMeta'),
clicked: function(options) {
const { $el, e, isMarking } = options;
const user = options.selectedObj;
// Remove unassigned selection (if it was previously selected)
const unassignedSelected = $dropdown.closest('.selectbox')
.find("input[name='" + ($dropdown.data('fieldName')) + "'][value=0]");
if ($dropdown.hasClass('js-multiselect')) {
const isActive = $el.hasClass('is-active');
const previouslySelected = $dropdown
.closest('.selectbox')
.find("input[name='" + $dropdown.data('fieldName') + "'][value!=0]");
// Enables support for limiting the number of users selected
// Automatically removes the first on the list if more users are selected
checkMaxSelect();
if (user.beforeDivider && user.name.toLowerCase() === 'unassigned') {
// Unassigned selected
previouslySelected.each((index, element) => {
const id = parseInt(element.value, 10);
element.remove();
});
emitSidebarEvent('sidebar.removeAllAssignees');
} else if (isActive) {
// user selected
emitSidebarEvent('sidebar.addAssignee', user);
// Remove unassigned selection (if it was previously selected)
const unassignedSelected = $dropdown
.closest('.selectbox')
.find("input[name='" + $dropdown.data('fieldName') + "'][value=0]");
if (unassignedSelected) {
unassignedSelected.remove();
}
} else {
if (previouslySelected.length === 0) {
// Select unassigned because there is no more selected users
this.addInput($dropdown.data('fieldName'), 0, {});
}
if (unassignedSelected) {
unassignedSelected.remove();
}
} else {
if (previouslySelected.length === 0) {
// Select unassigned because there is no more selected users
this.addInput($dropdown.data('fieldName'), 0, {});
// User unselected
emitSidebarEvent('sidebar.removeAssignee', user);
}
// User unselected
emitSidebarEvent('sidebar.removeAssignee', user);
if (getSelected().find(u => u === gon.current_user_id)) {
$('.assign-to-me-link').hide();
} else {
$('.assign-to-me-link').show();
}
}
if (getSelected().find(u => u === gon.current_user_id)) {
$('.assign-to-me-link').hide();
} else {
$('.assign-to-me-link').show();
var isIssueIndex, isMRIndex, page, selected;
page = $('body').attr('data-page');
isIssueIndex = page === 'projects:issues:index';
isMRIndex = page === page && page === 'projects:merge_requests:index';
if (
$dropdown.hasClass('js-filter-bulk-update') ||
$dropdown.hasClass('js-issuable-form-dropdown')
) {
e.preventDefault();
const isSelecting = user.id !== selectedId;
selectedId = isSelecting ? user.id : selectedIdDefault;
if (selectedId === gon.current_user_id) {
$('.assign-to-me-link').hide();
} else {
$('.assign-to-me-link').show();
}
return;
}
if ($el.closest('.add-issues-modal').length) {
ModalStore.store.filter[$dropdown.data('fieldName')] = user.id;
} else if (handleClick) {
e.preventDefault();
handleClick(user, isMarking);
} else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
} else if (!$dropdown.hasClass('js-multiselect')) {
selected = $dropdown
.closest('.selectbox')
.find("input[name='" + $dropdown.data('fieldName') + "']")
.val();
return assignTo(selected);
}
}
var isIssueIndex, isMRIndex, page, selected;
page = $('body').attr('data-page');
isIssueIndex = page === 'projects:issues:index';
isMRIndex = (page === page && page === 'projects:merge_requests:index');
if ($dropdown.hasClass('js-filter-bulk-update') || $dropdown.hasClass('js-issuable-form-dropdown')) {
e.preventDefault();
// Automatically close dropdown after assignee is selected
// since CE has no multiple assignees
// EE does not have a max-select
if (
$dropdown.data('maxSelect') &&
getSelected().length === $dropdown.data('maxSelect')
) {
// Close the dropdown
$dropdown.dropdown('toggle');
}
},
id: function(user) {
return user.id;
},
opened: function(e) {
const $el = $(e.currentTarget);
const selected = getSelected();
if ($dropdown.hasClass('js-issue-board-sidebar') && selected.length === 0) {
this.addInput($dropdown.data('fieldName'), 0, {});
}
$el.find('.is-active').removeClass('is-active');
const isSelecting = (user.id !== selectedId);
selectedId = isSelecting ? user.id : selectedIdDefault;
function highlightSelected(id) {
$el.find(`li[data-user-id="${id}"] .dropdown-menu-user-link`).addClass('is-active');
}
if (selectedId === gon.current_user_id) {
$('.assign-to-me-link').hide();
if (selected.length > 0) {
getSelected().forEach(selectedId => highlightSelected(selectedId));
} else if ($dropdown.hasClass('js-issue-board-sidebar')) {
highlightSelected(0);
} else {
$('.assign-to-me-link').show();
highlightSelected(selectedId);
}
return;
}
if ($el.closest('.add-issues-modal').length) {
ModalStore.store.filter[$dropdown.data('fieldName')] = user.id;
} else if (handleClick) {
e.preventDefault();
handleClick(user, isMarking);
} else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
} else if (!$dropdown.hasClass('js-multiselect')) {
selected = $dropdown.closest('.selectbox').find("input[name='" + ($dropdown.data('fieldName')) + "']").val();
return assignTo(selected);
}
// Automatically close dropdown after assignee is selected
// since CE has no multiple assignees
// EE does not have a max-select
if ($dropdown.data('maxSelect') &&
getSelected().length === $dropdown.data('maxSelect')) {
// Close the dropdown
$dropdown.dropdown('toggle');
}
},
id: function (user) {
return user.id;
},
opened: function(e) {
const $el = $(e.currentTarget);
const selected = getSelected();
if ($dropdown.hasClass('js-issue-board-sidebar') && selected.length === 0) {
this.addInput($dropdown.data('fieldName'), 0, {});
}
$el.find('.is-active').removeClass('is-active');
function highlightSelected(id) {
$el.find(`li[data-user-id="${id}"] .dropdown-menu-user-link`).addClass('is-active');
}
},
updateLabel: $dropdown.data('dropdownTitle'),
renderRow: function(user) {
var avatar, img, listClosingTags, listWithName, listWithUserName, username;
username = user.username ? '@' + user.username : '';
avatar = user.avatar_url ? user.avatar_url : gon.default_avatar_url;
if (selected.length > 0) {
getSelected().forEach(selectedId => highlightSelected(selectedId));
} else if ($dropdown.hasClass('js-issue-board-sidebar')) {
highlightSelected(0);
} else {
highlightSelected(selectedId);
}
},
updateLabel: $dropdown.data('dropdownTitle'),
renderRow: function(user) {
var avatar, img, listClosingTags, listWithName, listWithUserName, username;
username = user.username ? "@" + user.username : "";
avatar = user.avatar_url ? user.avatar_url : gon.default_avatar_url;
let selected = false;
let selected = false;
if (this.multiSelect) {
selected = getSelected().find(u => user.id === u);
if (this.multiSelect) {
selected = getSelected().find(u => user.id === u);
const { fieldName } = this;
const field = $dropdown
.closest('.selectbox')
.find("input[name='" + fieldName + "'][value='" + user.id + "']");
const { fieldName } = this;
const field = $dropdown.closest('.selectbox').find("input[name='" + fieldName + "'][value='" + user.id + "']");
if (field.length) {
selected = true;
if (field.length) {
selected = true;
}
} else {
selected = user.id === selectedId;
}
} else {
selected = user.id === selectedId;
}
img = "";
if (user.beforeDivider != null) {
`<li><a href='#' class='${selected === true ? 'is-active' : ''}'>${_.escape(user.name)}</a></li>`;
} else {
img = "<img src='" + avatar + "' class='avatar avatar-inline' width='32' />";
}
img = '';
if (user.beforeDivider != null) {
`<li><a href='#' class='${selected === true ? 'is-active' : ''}'>${_.escape(
user.name,
)}</a></li>`;
} else {
img = "<img src='" + avatar + "' class='avatar avatar-inline' width='32' />";
}
return `
return `
<li data-user-id=${user.id}>
<a href='#' class='dropdown-menu-user-link ${selected === true ? 'is-active' : ''}'>
${img}
......@@ -528,114 +574,117 @@ function UsersSelect(currentUser, els, options = {}) {
</a>
</li>
`;
}
});
};
})(this));
$('.ajax-users-select').each((function(_this) {
return function(i, select) {
var firstUser, showAnyUser, showEmailUser, showNullUser;
var options = {};
options.skipLdap = $(select).hasClass('skip_ldap');
options.projectId = $(select).data('projectId');
options.groupId = $(select).data('groupId');
options.showCurrentUser = $(select).data('currentUser');
options.authorId = $(select).data('authorId');
options.skipUsers = $(select).data('skipUsers');
showNullUser = $(select).data('nullUser');
showAnyUser = $(select).data('anyUser');
showEmailUser = $(select).data('emailUser');
firstUser = $(select).data('firstUser');
return $(select).select2({
placeholder: "Search for a user",
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query: function(query) {
return _this.users(query.term, options, function(users) {
var anyUser, data, emailUser, index, len, name, nullUser, obj, ref;
data = {
results: users
};
if (query.term.length === 0) {
if (firstUser) {
// Move current user to the front of the list
ref = data.results;
for (index = 0, len = ref.length; index < len; index += 1) {
obj = ref[index];
if (obj.username === firstUser) {
data.results.splice(index, 1);
data.results.unshift(obj);
break;
},
});
};
})(this),
);
$('.ajax-users-select').each(
(function(_this) {
return function(i, select) {
var firstUser, showAnyUser, showEmailUser, showNullUser;
var options = {};
options.skipLdap = $(select).hasClass('skip_ldap');
options.projectId = $(select).data('projectId');
options.groupId = $(select).data('groupId');
options.showCurrentUser = $(select).data('currentUser');
options.authorId = $(select).data('authorId');
options.skipUsers = $(select).data('skipUsers');
showNullUser = $(select).data('nullUser');
showAnyUser = $(select).data('anyUser');
showEmailUser = $(select).data('emailUser');
firstUser = $(select).data('firstUser');
return $(select).select2({
placeholder: 'Search for a user',
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query: function(query) {
return _this.users(query.term, options, function(users) {
var anyUser, data, emailUser, index, len, name, nullUser, obj, ref;
data = {
results: users,
};
if (query.term.length === 0) {
if (firstUser) {
// Move current user to the front of the list
ref = data.results;
for (index = 0, len = ref.length; index < len; index += 1) {
obj = ref[index];
if (obj.username === firstUser) {
data.results.splice(index, 1);
data.results.unshift(obj);
break;
}
}
}
}
if (showNullUser) {
nullUser = {
name: 'Unassigned',
id: 0
};
data.results.unshift(nullUser);
}
if (showAnyUser) {
name = showAnyUser;
if (name === true) {
name = 'Any User';
if (showNullUser) {
nullUser = {
name: 'Unassigned',
id: 0,
};
data.results.unshift(nullUser);
}
anyUser = {
name: name,
id: null
if (showAnyUser) {
name = showAnyUser;
if (name === true) {
name = 'Any User';
}
anyUser = {
name: name,
id: null,
};
data.results.unshift(anyUser);
}
}
if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) {
var trimmed = query.term.trim();
emailUser = {
name: 'Invite "' + trimmed + '" by email',
username: trimmed,
id: trimmed,
invite: true,
};
data.results.unshift(anyUser);
data.results.unshift(emailUser);
}
}
if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) {
var trimmed = query.term.trim();
emailUser = {
name: "Invite \"" + trimmed + "\" by email",
username: trimmed,
id: trimmed,
invite: true
};
data.results.unshift(emailUser);
}
return query.callback(data);
});
},
initSelection: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.initSelection.apply(_this, args);
},
formatResult: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.formatResult.apply(_this, args);
},
formatSelection: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.formatSelection.apply(_this, args);
},
dropdownCssClass: "ajax-users-dropdown",
// we do not want to escape markup since we are displaying html in results
escapeMarkup: function(m) {
return m;
}
});
};
})(this));
return query.callback(data);
});
},
initSelection: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.initSelection.apply(_this, args);
},
formatResult: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.formatResult.apply(_this, args);
},
formatSelection: function() {
var args;
args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return _this.formatSelection.apply(_this, args);
},
dropdownCssClass: 'ajax-users-dropdown',
// we do not want to escape markup since we are displaying html in results
escapeMarkup: function(m) {
return m;
},
});
};
})(this),
);
}
UsersSelect.prototype.initSelection = function(element, callback) {
var id, nullUser;
id = $(element).val();
if (id === "0") {
if (id === '0') {
nullUser = {
name: 'Unassigned'
name: 'Unassigned',
};
return callback(nullUser);
} else if (id !== "") {
} else if (id !== '') {
return this.user(id, callback);
}
};
......@@ -647,7 +696,17 @@ UsersSelect.prototype.formatResult = function(user) {
} else {
avatar = gon.default_avatar_url;
}
return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar avatar-inline s32' src='" + avatar + "'></div> <div class='user-name dropdown-menu-user-full-name'>" + _.escape(user.name) + "</div> <div class='user-username dropdown-menu-user-username'>" + (!user.invite ? "@" + _.escape(user.username) : "") + "</div> </div>";
return (
"<div class='user-result " +
(!user.username ? 'no-username' : void 0) +
"'> <div class='user-image'><img class='avatar avatar-inline s32' src='" +
avatar +
"'></div> <div class='user-name dropdown-menu-user-full-name'>" +
_.escape(user.name) +
"</div> <div class='user-username dropdown-menu-user-username'>" +
(!user.invite ? '@' + _.escape(user.username) : '') +
'</div> </div>'
);
};
UsersSelect.prototype.formatSelection = function(user) {
......@@ -662,10 +721,9 @@ UsersSelect.prototype.user = function(user_id, callback) {
var url;
url = this.buildUrl(this.userPath);
url = url.replace(':id', user_id);
return axios.get(url)
.then(({ data }) => {
callback(data);
});
return axios.get(url).then(({ data }) => {
callback(data);
});
};
// Return users list. Filtered by query
......@@ -682,12 +740,11 @@ UsersSelect.prototype.users = function(query, options, callback) {
todo_state_filter: options.todoStateFilter || null,
current_user: options.showCurrentUser || null,
author_id: options.authorId || null,
skip_users: options.skipUsers || null
skip_users: options.skipUsers || null,
};
return axios.get(url, { params })
.then(({ data }) => {
callback(data);
});
return axios.get(url, { params }).then(({ data }) => {
callback(data);
});
};
UsersSelect.prototype.buildUrl = function(url) {
......
......@@ -47,16 +47,26 @@ export default class ZenMode {
e.preventDefault();
return $(e.currentTarget).trigger('zen_mode:leave');
});
$(document).on('zen_mode:enter', (function(_this) {
return function(e) {
return _this.enter($(e.target).closest('.md-area').find('.zen-backdrop'));
};
})(this));
$(document).on('zen_mode:leave', (function(_this) {
return function(e) {
return _this.exit();
};
})(this));
$(document).on(
'zen_mode:enter',
(function(_this) {
return function(e) {
return _this.enter(
$(e.target)
.closest('.md-area')
.find('.zen-backdrop'),
);
};
})(this),
);
$(document).on(
'zen_mode:leave',
(function(_this) {
return function(e) {
return _this.exit();
};
})(this),
);
$(document).on('keydown', function(e) {
// Esc
if (e.keyCode === 27) {
......@@ -93,7 +103,7 @@ export default class ZenMode {
scrollTo(zen_area) {
return $.scrollTo(zen_area, 0, {
offset: -150
offset: -150,
});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment