summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-11-04 22:37:44 +0800
committerLin Jen-Shin <godfat@godfat.org>2016-11-04 22:37:44 +0800
commitfb9a0e5277f9825d7faf991c0600a7247b268fe8 (patch)
tree35000cd71ebf5de840c2c931d2f1c7a9b7357dad /app
parentce1dc4c25d3464b7a9a1b21d93157c9fed98f705 (diff)
parent5368b9f249485e254a90fe7daa551d61412bee26 (diff)
downloadgitlab-ce-fb9a0e5277f9825d7faf991c0600a7247b268fe8.tar.gz
Merge remote-tracking branch 'upstream/master' into show-status-from-branch
* upstream/master: (35 commits) Only skip group when it's actually a group in the "Share with group" select Fix: Todos Filter Shows All Users Fix: Guest sees some repository details and gets 404 Move shared params to a helper GrapeDSL for project hooks Update commits.scss updated styling commit SHA on branches page + added to changelog change build list height to show 6,5 builds + improve padding of list, with first/last child selectors Ignore builds directory from eslint Add changelog entry Document multiple repository storage paths Allow multiple repository storage shards to be enabled, and automatically round-robin between them Cleaned up global namespace JS Add tip for using Chrome to run and debug teaspoon tests. Add CHANGELOG entry file Add jquery.timeago.js to application.js Update match-regex to fix filename convention Move jquery.timeago to vendor directory Change a bunch of doc links to either relative or https://docs.gitlab.com. Show log corresponding to env in admin/logs ...
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/api.js12
-rw-r--r--app/assets/javascripts/application.js178
-rw-r--r--app/assets/javascripts/awards_handler.js2
-rw-r--r--app/assets/javascripts/confirm_danger_modal.js2
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js.es614
-rw-r--r--app/assets/javascripts/gl_form.js2
-rw-r--r--app/assets/javascripts/groups_select.js7
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js75
-rw-r--r--app/assets/javascripts/lib/utils/jquery.timeago.js182
-rw-r--r--app/assets/javascripts/members.js.es62
-rw-r--r--app/assets/javascripts/project_new.js13
-rw-r--r--app/assets/javascripts/project_select.js4
-rw-r--r--app/assets/javascripts/search.js2
-rw-r--r--app/assets/javascripts/users_select.js4
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss8
-rw-r--r--app/assets/stylesheets/framework/selects.scss6
-rw-r--r--app/assets/stylesheets/pages/commits.scss17
-rw-r--r--app/assets/stylesheets/pages/editor.scss4
-rw-r--r--app/assets/stylesheets/pages/icons.scss12
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss15
-rw-r--r--app/assets/stylesheets/pages/status.scss3
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/controllers/autocomplete_controller.rb6
-rw-r--r--app/controllers/projects/group_links_controller.rb2
-rw-r--r--app/helpers/application_settings_helper.rb4
-rw-r--r--app/helpers/ci_status_helper.rb4
-rw-r--r--app/helpers/dropdowns_helper.rb2
-rw-r--r--app/models/application_setting.rb39
-rw-r--r--app/models/merge_request.rb4
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/user.rb1
-rw-r--r--app/views/admin/application_settings/_form.html.haml4
-rw-r--r--app/views/admin/logs/show.html.haml2
-rw-r--r--app/views/dashboard/issues.atom.builder2
-rw-r--r--app/views/dashboard/issues.html.haml4
-rw-r--r--app/views/dashboard/todos/index.html.haml2
-rw-r--r--app/views/groups/issues.atom.builder2
-rw-r--r--app/views/groups/issues.html.haml4
-rw-r--r--app/views/layouts/devise.html.haml4
-rw-r--r--app/views/projects/blob/_editor.html.haml8
-rw-r--r--app/views/projects/blob/_upload.html.haml2
-rw-r--r--app/views/projects/branches/_commit.html.haml2
-rw-r--r--app/views/projects/ci/pipelines/_pipeline.html.haml2
-rw-r--r--app/views/projects/edit.html.haml4
-rw-r--r--app/views/projects/issues/index.atom.builder2
-rw-r--r--app/views/projects/issues/index.html.haml4
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/projects/tree/_tree_content.html.haml2
-rw-r--r--app/views/shared/icons/_icon_status_canceled.svg (renamed from app/views/shared/icons/_icon_status_cancel.svg)2
-rw-r--r--app/views/shared/icons/_icon_status_created.svg2
-rw-r--r--app/views/shared/icons/_icon_status_skipped.svg1
-rw-r--r--app/views/shared/issuable/_form.html.haml1
-rw-r--r--app/views/shared/issuable/_label_dropdown.html.haml2
53 files changed, 304 insertions, 386 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 7ebe1599fca..1cab66e109e 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -22,16 +22,14 @@
});
},
// Return groups list. Filtered by query
- // Only active groups retrieved
- groups: function(query, skip_ldap, skip_groups, callback) {
+ groups: function(query, options, callback) {
var url = Api.buildUrl(Api.groupsPath);
return $.ajax({
url: url,
- data: {
- search: query,
- skip_groups: skip_groups,
- per_page: 20
- },
+ data: $.extend({
+ search: query,
+ per_page: 20
+ }, options),
dataType: "json"
}).done(function(groups) {
return callback(groups);
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 7dd9adac736..7d942de0184 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -13,6 +13,7 @@
/*= require jquery-ui/sortable */
/*= require jquery_ujs */
/*= require jquery.endless-scroll */
+/*= require jquery.timeago */
/*= require jquery.highlight */
/*= require jquery.waitforimages */
/*= require jquery.atwho */
@@ -54,125 +55,53 @@
/*= require_directory . */
/*= require fuzzaldrin-plus */
-(function() {
- window.slugify = function(text) {
- return text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase();
- };
-
- window.ajaxGet = function(url) {
- return $.ajax({
- type: "GET",
- url: url,
- dataType: "script"
- });
- };
-
- window.split = function(val) {
- return val.split(/,\s*/);
- };
-
- window.extractLast = function(term) {
- return split(term).pop();
- };
-
- window.rstrip = function(val) {
- if (val) {
- return val.replace(/\s+$/, '');
- } else {
- return val;
- }
- };
-
- // Disable button if text field is empty
- window.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
- event_name = event_name || 'input';
- var closest_submit, field;
- field = $(field_selector);
- closest_submit = field.closest('form').find(button_selector);
- if (rstrip(field.val()) === "") {
- closest_submit.disable();
- }
- return field.on(event_name, function() {
- if (rstrip($(this).val()) === "") {
- return closest_submit.disable();
- } else {
- return closest_submit.enable();
- }
- });
- };
+(function () {
+ document.addEventListener('page:fetch', gl.utils.cleanupBeforeFetch);
+ window.addEventListener('hashchange', gl.utils.shiftWindow);
- // Disable button if any input field with given selector is empty
- window.disableButtonIfAnyEmptyField = function(form, form_selector, button_selector) {
- var closest_submit, updateButtons;
- closest_submit = form.find(button_selector);
- updateButtons = function() {
- var filled;
- filled = true;
- form.find('input').filter(form_selector).each(function() {
- return filled = rstrip($(this).val()) !== "" || !$(this).attr('required');
- });
- if (filled) {
- return closest_submit.enable();
- } else {
- return closest_submit.disable();
- }
- };
- updateButtons();
- return form.keyup(updateButtons);
- };
-
- window.sanitize = function(str) {
- return str.replace(/<(?:.|\n)*?>/gm, '');
- };
-
- window.shiftWindow = function() {
- return scrollBy(0, -100);
- };
-
- document.addEventListener("page:fetch", gl.utils.cleanupBeforeFetch);
-
- window.addEventListener("hashchange", shiftWindow);
-
- window.onload = function() {
+ window.onload = function () {
// Scroll the window to avoid the topnav bar
// https://github.com/twitter/bootstrap/issues/1768
if (location.hash) {
- return setTimeout(shiftWindow, 100);
+ return setTimeout(gl.utils.shiftWindow, 100);
}
};
- $(function() {
- var $body, $document, $sidebarGutterToggle, $window, bootstrapBreakpoint, checkInitialSidebarSize, fitSidebarForSize, flash;
- $document = $(document);
- $window = $(window);
- $body = $('body');
+ $(function () {
+ var $body = $('body');
+ var $document = $(document);
+ var $window = $(window);
+ var $sidebarGutterToggle = $('.js-sidebar-toggle');
+ var $flash = $('.flash-container');
+ var bootstrapBreakpoint = bp.getBreakpointSize();
+ var checkInitialSidebarSize;
+ var fitSidebarForSize;
// Set the default path for all cookies to GitLab's root directory
Cookies.defaults.path = gon.relative_url_root || '/';
gl.utils.preventDisabledButtons();
- bootstrapBreakpoint = bp.getBreakpointSize();
- $(".nav-sidebar").niceScroll({
+ $('.nav-sidebar').niceScroll({
cursoropacitymax: '0.4',
cursorcolor: '#FFF',
- cursorborder: "1px solid #FFF"
+ cursorborder: '1px solid #FFF'
});
- $(".js-select-on-focus").on("focusin", function() {
- return $(this).select().one('mouseup', function(e) {
+ $('.js-select-on-focus').on('focusin', function () {
+ return $(this).select().one('mouseup', function (e) {
return e.preventDefault();
});
// Click a .js-select-on-focus field, select the contents
// Prevent a mouseup event from deselecting the input
});
- $('.remove-row').bind('ajax:success', function() {
+ $('.remove-row').bind('ajax:success', function () {
$(this).tooltip('destroy')
.closest('li')
.fadeOut();
});
- $('.js-remove-tr').bind('ajax:before', function() {
+ $('.js-remove-tr').bind('ajax:before', function () {
return $(this).hide();
});
- $('.js-remove-tr').bind('ajax:success', function() {
+ $('.js-remove-tr').bind('ajax:success', function () {
return $(this).closest('tr').fadeOut();
});
$('select.select2').select2({
@@ -180,8 +109,8 @@
// Initialize select2 selects
dropdownAutoWidth: true
});
- $('.js-select2').bind('select2-close', function() {
- return setTimeout((function() {
+ $('.js-select2').bind('select2-close', function () {
+ return setTimeout((function () {
$('.select2-container-active').removeClass('select2-container-active');
return $(':focus').blur();
}), 1);
@@ -191,24 +120,24 @@
$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover';
$body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]',
- placement: function(_, el) {
+ placement: function (_, el) {
return $(el).data('placement') || 'bottom';
}
});
- $('.trigger-submit').on('change', function() {
+ $('.trigger-submit').on('change', function () {
return $(this).parents('form').submit();
// Form submitter
});
gl.utils.localTimeAgo($('abbr.timeago, .js-timeago'), true);
// Flash
- if ((flash = $(".flash-container")).length > 0) {
- flash.click(function() {
+ if ($flash.length > 0) {
+ $flash.click(function () {
return $(this).fadeOut();
});
- flash.show();
+ $flash.show();
}
// Disable form buttons while a form is submitting
- $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function(e) {
+ $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function (e) {
var buttons;
buttons = $('[type="submit"]', this);
switch (e.type) {
@@ -219,36 +148,36 @@
return buttons.enable();
}
});
- $(document).ajaxError(function(e, xhrObj, xhrSetting, xhrErrorText) {
- var ref;
+ $(document).ajaxError(function (e, xhrObj) {
+ var ref = xhrObj.status;
if (xhrObj.status === 401) {
return new Flash('You need to be logged in.', 'alert');
- } else if ((ref = xhrObj.status) === 404 || ref === 500) {
+ } else if (ref === 404 || ref === 500) {
return new Flash('Something went wrong on our end.', 'alert');
}
});
- $('.account-box').hover(function() {
+ $('.account-box').hover(function () {
// Show/Hide the profile menu when hovering the account box
return $(this).toggleClass('hover');
});
- $document.on('click', '.diff-content .js-show-suppressed-diff', function() {
+ $document.on('click', '.diff-content .js-show-suppressed-diff', function () {
var $container;
$container = $(this).parent();
$container.next('table').show();
return $container.remove();
// Commit show suppressed diff
});
- $('.navbar-toggle').on('click', function() {
+ $('.navbar-toggle').on('click', function () {
$('.header-content .title').toggle();
$('.header-content .header-logo').toggle();
$('.header-content .navbar-collapse').toggle();
return $('.navbar-toggle').toggleClass('active');
});
// Show/hide comments on diff
- $body.on("click", ".js-toggle-diff-comments", function(e) {
+ $body.on('click', '.js-toggle-diff-comments', function (e) {
var $this = $(this);
- $this.toggleClass('active');
var notesHolders = $this.closest('.diff-file').find('.notes_holder');
+ $this.toggleClass('active');
if ($this.hasClass('active')) {
notesHolders.show().find('.hide').show();
} else {
@@ -257,30 +186,27 @@
$this.trigger('blur');
return e.preventDefault();
});
- $document.off("click", '.js-confirm-danger');
- $document.on("click", '.js-confirm-danger', function(e) {
- var btn, form, text;
+ $document.off('click', '.js-confirm-danger');
+ $document.on('click', '.js-confirm-danger', function (e) {
+ var btn = $(e.target);
+ var form = btn.closest('form');
+ var text = btn.data('confirm-danger-message');
e.preventDefault();
- btn = $(e.target);
- text = btn.data("confirm-danger-message");
- form = btn.closest("form");
return new ConfirmDangerModal(form, text);
});
- $document.on('click', 'button', function() {
+ $document.on('click', 'button', function () {
return $(this).blur();
});
- $('input[type="search"]').each(function() {
- var $this;
- $this = $(this);
+ $('input[type="search"]').each(function () {
+ var $this = $(this);
$this.attr('value', $this.val());
});
- $document.off('keyup', 'input[type="search"]').on('keyup', 'input[type="search"]', function(e) {
+ $document.off('keyup', 'input[type="search"]').on('keyup', 'input[type="search"]', function () {
var $this;
$this = $(this);
return $this.attr('value', $this.val());
});
- $sidebarGutterToggle = $('.js-sidebar-toggle');
- $document.off('breakpoint:change').on('breakpoint:change', function(e, breakpoint) {
+ $document.off('breakpoint:change').on('breakpoint:change', function (e, breakpoint) {
var $gutterIcon;
if (breakpoint === 'sm' || breakpoint === 'xs') {
$gutterIcon = $sidebarGutterToggle.find('i');
@@ -289,7 +215,7 @@
}
}
});
- fitSidebarForSize = function() {
+ fitSidebarForSize = function () {
var oldBootstrapBreakpoint;
oldBootstrapBreakpoint = bootstrapBreakpoint;
bootstrapBreakpoint = bp.getBreakpointSize();
@@ -297,13 +223,13 @@
return $document.trigger('breakpoint:change', [bootstrapBreakpoint]);
}
};
- checkInitialSidebarSize = function() {
+ checkInitialSidebarSize = function () {
bootstrapBreakpoint = bp.getBreakpointSize();
- if (bootstrapBreakpoint === "xs" || "sm") {
+ if (bootstrapBreakpoint === 'xs' || 'sm') {
return $document.trigger('breakpoint:change', [bootstrapBreakpoint]);
}
};
- $window.off("resize.app").on("resize.app", function(e) {
+ $window.off('resize.app').on('resize.app', function () {
return fitSidebarForSize();
});
gl.awardsHandler = new AwardsHandler();
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 8bdb0965f99..d7cda977845 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -1,7 +1,7 @@
/* eslint-disable */
(function() {
this.AwardsHandler = (function() {
- const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; //For separating lists produced by ruby's Array#toSentence
+ var FROM_SENTENCE_REGEX = /(?:, and | and |, )/; //For separating lists produced by ruby's Array#toSentence
function AwardsHandler() {
this.aliases = gl.emojiAliases();
$(document).off('click', '.js-add-award').on('click', '.js-add-award', (function(_this) {
diff --git a/app/assets/javascripts/confirm_danger_modal.js b/app/assets/javascripts/confirm_danger_modal.js
index 230a1b95c52..143d21adb37 100644
--- a/app/assets/javascripts/confirm_danger_modal.js
+++ b/app/assets/javascripts/confirm_danger_modal.js
@@ -12,7 +12,7 @@
submit.disable();
$('.js-confirm-danger-input').off('input');
$('.js-confirm-danger-input').on('input', function() {
- if (rstrip($(this).val()) === project_path) {
+ if (gl.utils.rstrip($(this).val()) === project_path) {
return submit.enable();
} else {
return submit.disable();
diff --git a/app/assets/javascripts/gfm_auto_complete.js.es6 b/app/assets/javascripts/gfm_auto_complete.js.es6
index 31df51ac03a..824413bf20f 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.es6
+++ b/app/assets/javascripts/gfm_auto_complete.js.es6
@@ -126,8 +126,8 @@
}
return {
username: m.username,
- title: sanitize(title),
- search: sanitize(m.username + " " + m.name)
+ title: gl.utils.sanitize(title),
+ search: gl.utils.sanitize(m.username + " " + m.name)
};
});
}
@@ -159,7 +159,7 @@
}
return {
id: i.iid,
- title: sanitize(i.title),
+ title: gl.utils.sanitize(i.title),
search: i.iid + " " + i.title
};
});
@@ -189,7 +189,7 @@
}
return {
id: m.iid,
- title: sanitize(m.title),
+ title: gl.utils.sanitize(m.title),
search: "" + m.title
};
});
@@ -222,7 +222,7 @@
}
return {
id: m.iid,
- title: sanitize(m.title),
+ title: gl.utils.sanitize(m.title),
search: m.iid + " " + m.title
};
});
@@ -240,9 +240,9 @@
var sanitizeLabelTitle;
sanitizeLabelTitle = function(title) {
if (/[\w\?&]+\s+[\w\?&]+/g.test(title)) {
- return "\"" + (sanitize(title)) + "\"";
+ return "\"" + (gl.utils.sanitize(title)) + "\"";
} else {
- return sanitize(title);
+ return gl.utils.sanitize(title);
}
};
return $.map(merges, function(m) {
diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js
index 742807d93ad..ce54c34492d 100644
--- a/app/assets/javascripts/gl_form.js
+++ b/app/assets/javascripts/gl_form.js
@@ -24,8 +24,8 @@
if (isNewForm) {
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
- disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
// remove notify commit author checkbox for non-commit notes
+ gl.utils.disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
GitLab.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
new DropzoneInput(this.form);
autosize(this.textarea);
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js
index b275620c799..e3c39c895ba 100644
--- a/app/assets/javascripts/groups_select.js
+++ b/app/assets/javascripts/groups_select.js
@@ -6,15 +6,16 @@
function GroupsSelect() {
$('.ajax-groups-select').each((function(_this) {
return function(i, select) {
- var skip_ldap, skip_groups;
- skip_ldap = $(select).hasClass('skip_ldap');
+ var all_available, skip_groups;
+ all_available = $(select).data('all-available');
skip_groups = $(select).data('skip-groups') || [];
return $(select).select2({
placeholder: "Search for a group",
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query: function(query) {
- return Api.groups(query.term, skip_ldap, skip_groups, function(groups) {
+ options = { all_available: all_available, skip_groups: skip_groups };
+ return Api.groups(query.term, options, function(groups) {
var data;
data = {
results: groups
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 21efe2d76dd..8447421195d 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -24,6 +24,81 @@
return null;
}
};
+
+ w.gl.utils.ajaxGet = function(url) {
+ return $.ajax({
+ type: "GET",
+ url: url,
+ dataType: "script"
+ });
+ };
+
+ w.gl.utils.split = function(val) {
+ return val.split(/,\s*/);
+ };
+
+ w.gl.utils.extractLast = function(term) {
+ return this.split(term).pop();
+ };
+
+ w.gl.utils.rstrip = function rstrip(val) {
+ if (val) {
+ return val.replace(/\s+$/, '');
+ } else {
+ return val;
+ }
+ };
+
+ w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
+ event_name = event_name || 'input';
+ var closest_submit, field, that;
+ that = this;
+ field = $(field_selector);
+ closest_submit = field.closest('form').find(button_selector);
+ if (this.rstrip(field.val()) === "") {
+ closest_submit.disable();
+ }
+ return field.on(event_name, function() {
+ if (that.rstrip($(this).val()) === "") {
+ return closest_submit.disable();
+ } else {
+ return closest_submit.enable();
+ }
+ });
+ };
+
+ w.gl.utils.disableButtonIfAnyEmptyField = function(form, form_selector, button_selector) {
+ var closest_submit, updateButtons;
+ closest_submit = form.find(button_selector);
+ updateButtons = function() {
+ var filled;
+ filled = true;
+ form.find('input').filter(form_selector).each(function() {
+ return filled = this.rstrip($(this).val()) !== "" || !$(this).attr('required');
+ });
+ if (filled) {
+ return closest_submit.enable();
+ } else {
+ return closest_submit.disable();
+ }
+ };
+ updateButtons();
+ return form.keyup(updateButtons);
+ };
+
+ w.gl.utils.sanitize = function(str) {
+ return str.replace(/<(?:.|\n)*?>/gm, '');
+ };
+
+ w.gl.utils.unbindEvents = function() {
+ return $(document).off('scroll');
+ };
+
+ w.gl.utils.shiftWindow = function() {
+ return w.scrollBy(0, -100);
+ };
+
+
gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
return $tooltipEl.tooltip('destroy').attr('title', newTitle).tooltip('fixTitle');
};
diff --git a/app/assets/javascripts/lib/utils/jquery.timeago.js b/app/assets/javascripts/lib/utils/jquery.timeago.js
deleted file mode 100644
index de76cdd2ea7..00000000000
--- a/app/assets/javascripts/lib/utils/jquery.timeago.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* eslint-disable */
-/**
- * Timeago is a jQuery plugin that makes it easy to support automatically
- * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
- *
- * @name timeago
- * @version 1.1.0
- * @requires jQuery v1.2.3+
- * @author Ryan McGeary
- * @license MIT License - http://www.opensource.org/licenses/mit-license.php
- *
- * For usage and examples, visit:
- * http://timeago.yarp.com/
- *
- * Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
- */
-
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function ($) {
- $.timeago = function(timestamp) {
- if (timestamp instanceof Date) {
- return inWords(timestamp);
- } else if (typeof timestamp === "string") {
- return inWords($.timeago.parse(timestamp));
- } else if (typeof timestamp === "number") {
- return inWords(new Date(timestamp));
- } else {
- return inWords($.timeago.datetime(timestamp));
- }
- };
- var $t = $.timeago;
-
- $.extend($.timeago, {
- settings: {
- refreshMillis: 60000,
- allowFuture: false,
- strings: {
- prefixAgo: null,
- prefixFromNow: null,
- suffixAgo: "ago",
- suffixFromNow: "from now",
- seconds: "less than a minute",
- minute: "about a minute",
- minutes: "%d minutes",
- hour: "about an hour",
- hours: "about %d hours",
- day: "a day",
- days: "%d days",
- month: "about a month",
- months: "%d months",
- year: "about a year",
- years: "%d years",
- wordSeparator: " ",
- numbers: []
- }
- },
- inWords: function(distanceMillis) {
- var $l = this.settings.strings;
- var prefix = $l.prefixAgo;
- var suffix = $l.suffixAgo;
- if (this.settings.allowFuture) {
- if (distanceMillis < 0) {
- prefix = $l.prefixFromNow;
- suffix = $l.suffixFromNow;
- }
- }
-
- var seconds = Math.abs(distanceMillis) / 1000;
- var minutes = seconds / 60;
- var hours = minutes / 60;
- var days = hours / 24;
- var years = days / 365;
-
- function substitute(stringOrFunction, number) {
- var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
- var value = ($l.numbers && $l.numbers[number]) || number;
- return string.replace(/%d/i, value);
- }
-
- var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
- seconds < 90 && substitute($l.minute, 1) ||
- minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
- minutes < 90 && substitute($l.hour, 1) ||
- hours < 24 && substitute($l.hours, Math.round(hours)) ||
- hours < 42 && substitute($l.day, 1) ||
- days < 30 && substitute($l.days, Math.round(days)) ||
- days < 45 && substitute($l.month, 1) ||
- days < 365 && substitute($l.months, Math.round(days / 30)) ||
- years < 1.5 && substitute($l.year, 1) ||
- substitute($l.years, Math.round(years));
-
- var separator = $l.wordSeparator || "";
- if ($l.wordSeparator === undefined) { separator = " "; }
- return $.trim([prefix, words, suffix].join(separator));
- },
- parse: function(iso8601) {
- var s = $.trim(iso8601);
- s = s.replace(/\.\d+/,""); // remove milliseconds
- s = s.replace(/-/,"/").replace(/-/,"/");
- s = s.replace(/T/," ").replace(/Z/," UTC");
- s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
- return new Date(s);
- },
- datetime: function(elem) {
- var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
- return $t.parse(iso8601);
- },
- isTime: function(elem) {
- // jQuery's `is()` doesn't play well with HTML5 in IE
- return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
- }
- });
-
- // functions that can be called via $(el).timeago('action')
- // init is default when no action is given
- // functions are called with context of a single element
- var functions = {
- init: function(){
- var refresh_el = $.proxy(refresh, this);
- refresh_el();
- var $s = $t.settings;
- if ($s.refreshMillis > 0) {
- setInterval(refresh_el, $s.refreshMillis);
- }
- },
- update: function(time){
- $(this).data('timeago', { datetime: $t.parse(time) });
- refresh.apply(this);
- }
- };
-
- $.fn.timeago = function(action, options) {
- var fn = action ? functions[action] : functions.init;
- if(!fn){
- throw new Error("Unknown function name '"+ action +"' for timeago");
- }
- // each over objects here and call the requested function
- this.each(function(){
- fn.call(this, options);
- });
- return this;
- };
-
- function refresh() {
- var data = prepareData(this);
- if (!isNaN(data.datetime)) {
- $(this).text(inWords(data.datetime));
- }
- return this;
- }
-
- function prepareData(element) {
- element = $(element);
- if (!element.data("timeago")) {
- element.data("timeago", { datetime: $t.datetime(element) });
- var text = $.trim(element.text());
- if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
- element.attr("title", text);
- }
- }
- return element.data("timeago");
- }
-
- function inWords(date) {
- return $t.inWords(distance(date));
- }
-
- function distance(date) {
- return (new Date().getTime() - date.getTime());
- }
-
- // fix for IE6 suckage
- document.createElement("abbr");
- document.createElement("time");
-}));
diff --git a/app/assets/javascripts/members.js.es6 b/app/assets/javascripts/members.js.es6
index 371abd09e78..895bc10784f 100644
--- a/app/assets/javascripts/members.js.es6
+++ b/app/assets/javascripts/members.js.es6
@@ -11,7 +11,7 @@
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
$('.js-member-update-control').off('change').on('change', this.formSubmit);
$('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
- disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
+ gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
}
removeRow(e) {
diff --git a/app/assets/javascripts/project_new.js b/app/assets/javascripts/project_new.js
index 40575caa57f..0d3fb31a9cf 100644
--- a/app/assets/javascripts/project_new.js
+++ b/app/assets/javascripts/project_new.js
@@ -45,7 +45,9 @@
};
ProjectNew.prototype.toggleRepoVisibility = function () {
- var $repoAccessLevel = $('.js-repo-access-level select');
+ var $repoAccessLevel = $('.js-repo-access-level select'),
+ containerRegistry = document.querySelectorAll('.js-container-registry')[0],
+ containerRegistryCheckbox = document.getElementById('project_container_registry_enabled');
this.$repoSelects.find("option[value='" + $repoAccessLevel.val() + "']")
.nextAll()
@@ -70,8 +72,17 @@
if (selectedVal) {
this.$repoSelects.removeClass('disabled');
+
+ if (containerRegistry) {
+ containerRegistry.style.display = '';
+ }
} else {
this.$repoSelects.addClass('disabled');
+
+ if (containerRegistry) {
+ containerRegistry.style.display = 'none';
+ containerRegistryCheckbox.checked = false;
+ }
}
}.bind(this));
};
diff --git a/app/assets/javascripts/project_select.js b/app/assets/javascripts/project_select.js
index b74b4ae68ff..e1acf3c8232 100644
--- a/app/assets/javascripts/project_select.js
+++ b/app/assets/javascripts/project_select.js
@@ -24,7 +24,7 @@
data = groups.concat(projects);
return finalCallback(data);
};
- return Api.groups(term, false, false, groupsCallback);
+ return Api.groups(term, {}, groupsCallback);
};
} else {
projectsCallback = finalCallback;
@@ -73,7 +73,7 @@
data = groups.concat(projects);
return finalCallback(data);
};
- return Api.groups(query.term, false, false, groupsCallback);
+ return Api.groups(query.term, {}, groupsCallback);
};
} else {
projectsCallback = finalCallback;
diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js
index 6c2389f202f..d79e6f014f6 100644
--- a/app/assets/javascripts/search.js
+++ b/app/assets/javascripts/search.js
@@ -11,7 +11,7 @@
filterable: true,
fieldName: 'group_id',
data: function(term, callback) {
- return Api.groups(term, false, false, function(data) {
+ return Api.groups(term, {}, function(data) {
data.unshift({
name: 'Any'
});
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 3847278e80a..7a2221dbaf5 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -23,6 +23,8 @@
$dropdown = $(dropdown);
options.projectId = $dropdown.data('project-id');
options.showCurrentUser = $dropdown.data('current-user');
+ options.todoFilter = $dropdown.data('todo-filter');
+ options.todoStateFilter = $dropdown.data('todo-state-filter');
showNullUser = $dropdown.data('null-user');
showMenuAbove = $dropdown.data('showMenuAbove');
showAnyUser = $dropdown.data('any-user');
@@ -394,6 +396,8 @@
project_id: options.projectId || null,
group_id: options.groupId || null,
skip_ldap: options.skipLdap || null,
+ todo_filter: options.todoFilter || null,
+ todo_state_filter: options.todoStateFilter || null,
current_user: options.showCurrentUser || null,
push_code_to_protected_branches: options.pushCodeToProtectedBranches || null,
author_id: options.authorId || null,
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index baa38ab60c8..3e34ec98427 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -36,7 +36,7 @@
color: $dropdown-toggle-color;
font-size: 15px;
text-align: left;
- border: 1px solid $dropdown-toggle-border-color;
+ border: 1px solid $border-color;
border-radius: $border-radius-base;
outline: 0;
text-overflow: ellipsis;
@@ -45,11 +45,9 @@
.fa {
position: absolute;
- top: 50%;
- right: 6px;
- margin-top: -6px;
+ top: 10px;
+ right: 8px;
color: $dropdown-toggle-icon-color;
- font-size: 10px;
&.fa-spinner {
font-size: 16px;
diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss
index ecdf0be1a05..13749f1b7bd 100644
--- a/app/assets/stylesheets/framework/selects.scss
+++ b/app/assets/stylesheets/framework/selects.scss
@@ -27,9 +27,9 @@
height: 0;
margin-left: 2px;
vertical-align: middle;
- border-top: $caret-width-base dashed;
- border-right: $caret-width-base solid transparent;
- border-left: $caret-width-base solid transparent;
+ border-top: 5px dashed;
+ border-right: 5px solid transparent;
+ border-left: 5px solid transparent;
color: $gray-darkest;
}
}
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 52d6a39bd59..98a84351a3d 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -164,7 +164,22 @@
.branch-commit {
color: $gl-gray;
- .commit-id,
+ .commit-icon {
+ text-align: center;
+ display: inline-block;
+
+ svg {
+ height: 14px;
+ width: 14px;
+ vertical-align: middle;
+ fill: $table-text-gray;
+ }
+ }
+
+ .commit-id {
+ color: $gl-link-color;
+ }
+
.commit-row-message {
color: $gl-gray;
}
diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss
index cb8cefaca97..778126bcfb7 100644
--- a/app/assets/stylesheets/pages/editor.scss
+++ b/app/assets/stylesheets/pages/editor.scss
@@ -55,6 +55,10 @@
float: left;
}
+ .file-buttons {
+ font-size: 0;
+ }
+
.select2 {
float: right;
}
diff --git a/app/assets/stylesheets/pages/icons.scss b/app/assets/stylesheets/pages/icons.scss
new file mode 100644
index 00000000000..407c8db211d
--- /dev/null
+++ b/app/assets/stylesheets/pages/icons.scss
@@ -0,0 +1,12 @@
+// CI icon colors
+
+.ci-status-icon {
+ &-created {
+ fill: $gray-darkest;
+ }
+
+ &-skipped,
+ &-canceled {
+ fill: $gl-text-color;
+ }
+}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index a8e8bbcb208..bf3cb6e7ad9 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -85,6 +85,11 @@
}
.commit-link {
+ a {
+ &:focus {
+ text-decoration: none;
+ }
+ }
.ci-status {
@@ -439,7 +444,7 @@
}
.grouped-pipeline-dropdown {
- padding: 8px 0;
+ padding: 0;
width: 186px;
left: auto;
right: -197px;
@@ -448,6 +453,14 @@
ul {
max-height: 245px;
overflow: auto;
+
+ li:first-child {
+ padding-top: 8px;
+ }
+
+ li:last-child {
+ padding-bottom: 8px;
+ }
}
a {
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index 01426e28e92..92997eae8b9 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -6,7 +6,8 @@
white-space: nowrap;
border-radius: 4px;
- &:hover {
+ &:hover,
+ &:focus {
text-decoration: none;
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 6ef7cf0bae6..86e808314f4 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -116,8 +116,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_packet_size,
:send_user_confirmation_email,
:container_registry_token_expire_delay,
- :repository_storage,
:enabled_git_access_protocol,
+ repository_storages: [],
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index b48668eea87..daa82336208 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -11,9 +11,13 @@ class AutocompleteController < ApplicationController
@users = @users.reorder(:name)
@users = @users.page(params[:page])
+ if params[:todo_filter].present?
+ @users = @users.todo_authors(current_user.id, params[:todo_state_filter])
+ end
+
if params[:search].blank?
# Include current user if available to filter by "Me"
- if params[:current_user] && current_user
+ if params[:current_user].present? && current_user
@users = [*@users, current_user]
end
diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb
index ae060abee5c..9eaf26a0dbf 100644
--- a/app/controllers/projects/group_links_controller.rb
+++ b/app/controllers/projects/group_links_controller.rb
@@ -7,7 +7,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
@group_links = project.project_group_links.all
@skip_groups = @group_links.pluck(:group_id)
- @skip_groups << project.group.try(:id)
+ @skip_groups << project.namespace_id unless project.personal?
end
def create
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 6229384817b..45a567a1eba 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -93,11 +93,11 @@ module ApplicationSettingsHelper
end
end
- def repository_storage_options_for_select
+ def repository_storages_options_for_select
options = Gitlab.config.repositories.storages.map do |name, path|
["#{name} - #{path}", name]
end
- options_for_select(options, @application_setting.repository_storage)
+ options_for_select(options, @application_setting.repository_storages)
end
end
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index 3decedace4f..895c3d728ad 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -47,8 +47,10 @@ module CiStatusHelper
'icon_play'
when 'created'
'icon_status_created'
+ when 'skipped'
+ 'icon_status_skipped'
else
- 'icon_status_cancel'
+ 'icon_status_canceled'
end
custom_icon(icon_name)
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index 81e0b6bb5ae..cbab1fd5967 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -43,7 +43,7 @@ module DropdownsHelper
default_label = data_attr[:default_label]
content_tag(:button, class: "dropdown-menu-toggle #{options[:toggle_class] if options.has_key?(:toggle_class)}", id: (options[:id] if options.has_key?(:id)), type: "button", data: data_attr) do
output = content_tag(:span, toggle_text, class: "dropdown-toggle-text #{'is-default' if toggle_text == default_label}")
- output << icon('chevron-down')
+ output << icon('caret-down')
output.html_safe
end
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index c99aa7772bb..6e7a90e7d9c 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -18,6 +18,7 @@ class ApplicationSetting < ActiveRecord::Base
serialize :disabled_oauth_sign_in_sources, Array
serialize :domain_whitelist, Array
serialize :domain_blacklist, Array
+ serialize :repository_storages
cache_markdown_field :sign_in_text
cache_markdown_field :help_page_text
@@ -74,9 +75,8 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
- validates :repository_storage,
- presence: true,
- inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
+ validates :repository_storages, presence: true
+ validate :check_repository_storages
validates :enabled_git_access_protocol,
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
@@ -166,7 +166,7 @@ class ApplicationSetting < ActiveRecord::Base
disabled_oauth_sign_in_sources: [],
send_user_confirmation_email: false,
container_registry_token_expire_delay: 5,
- repository_storage: 'default',
+ repository_storages: ['default'],
user_default_external: false,
)
end
@@ -201,6 +201,29 @@ class ApplicationSetting < ActiveRecord::Base
self.domain_blacklist_raw = file.read
end
+ def repository_storages
+ value = read_attribute(:repository_storages)
+ value = [value] if value.is_a?(String)
+ value = [] if value.nil?
+
+ value
+ end
+
+ # repository_storage is still required in the API. Remove in 9.0
+ def repository_storage
+ repository_storages.first
+ end
+
+ def repository_storage=(value)
+ self.repository_storages = [value]
+ end
+
+ # Choose one of the available repository storage options. Currently all have
+ # equal weighting.
+ def pick_repository_storage
+ repository_storages.sample
+ end
+
def runners_registration_token
ensure_runners_registration_token!
end
@@ -208,4 +231,12 @@ class ApplicationSetting < ActiveRecord::Base
def health_check_access_token
ensure_health_check_access_token!
end
+
+ private
+
+ def check_repository_storages
+ invalid = repository_storages - Gitlab.config.repositories.storages.keys
+ errors.add(:repository_storages, "can't include: #{invalid.join(", ")}") unless
+ invalid.empty?
+ end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 0397c57f935..6b8ac3fb48b 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -441,11 +441,11 @@ class MergeRequest < ActiveRecord::Base
end
def should_remove_source_branch?
- merge_params['should_remove_source_branch'].present?
+ Gitlab::Utils.to_boolean(merge_params['should_remove_source_branch'])
end
def force_remove_source_branch?
- merge_params['force_remove_source_branch'].present?
+ Gitlab::Utils.to_boolean(merge_params['force_remove_source_branch'])
end
def remove_source_branch?
diff --git a/app/models/project.rb b/app/models/project.rb
index d5512dfaf9c..cf931f64c03 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -28,7 +28,7 @@ class Project < ActiveRecord::Base
default_value_for :archived, false
default_value_for :visibility_level, gitlab_config_features.visibility_level
default_value_for :container_registry_enabled, gitlab_config_features.container_registry
- default_value_for(:repository_storage) { current_application_settings.repository_storage }
+ default_value_for(:repository_storage) { current_application_settings.pick_repository_storage }
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
default_value_for :issues_enabled, gitlab_config_features.issues
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
diff --git a/app/models/user.rb b/app/models/user.rb
index af3c0b7dc02..65e96ee6b2e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -173,6 +173,7 @@ class User < ActiveRecord::Base
scope :active, -> { with_state(:active) }
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
+ scope :todo_authors, ->(user_id, state) { where(id: Todo.where(user_id: user_id, state: state).select(:author_id)) }
def self.with_two_factor
joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id").
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index c4c68cd7891..28003e5f509 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -353,9 +353,9 @@
%fieldset
%legend Repository Storage
.form-group
- = f.label :repository_storage, 'Storage path for new projects', class: 'control-label col-sm-2'
+ = f.label :repository_storages, 'Storage paths for new projects', class: 'control-label col-sm-2'
.col-sm-10
- = f.select :repository_storage, repository_storage_options_for_select, {}, class: 'form-control'
+ = f.select :repository_storages, repository_storages_options_for_select, {include_hidden: false}, multiple: true, class: 'form-control'
.help-block
Manage repository storage paths. Learn more in the
= succeed "." do
diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml
index 676812121d7..824edd171f3 100644
--- a/app/views/admin/logs/show.html.haml
+++ b/app/views/admin/logs/show.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
- page_title "Logs"
- loggers = [Gitlab::GitLogger, Gitlab::AppLogger,
- Gitlab::ProductionLogger, Gitlab::SidekiqLogger,
+ Gitlab::EnvironmentLogger, Gitlab::SidekiqLogger,
Gitlab::RepositoryCheckLogger]
= render 'admin/background_jobs/head'
diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder
index 0404d0728ea..bdea1064096 100644
--- a/app/views/dashboard/issues.atom.builder
+++ b/app/views/dashboard/issues.atom.builder
@@ -1,7 +1,7 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{current_user.name} issues"
- xml.link href: issues_dashboard_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
+ xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
xml.id issues_dashboard_url
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index 1eec4db45a0..3caaf827ff5 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -2,13 +2,13 @@
- header_title "Issues", issues_dashboard_path(assignee_id: current_user.id)
= content_for :meta_tags do
- if current_user
- = auto_discovery_link_tag(:atom, issues_dashboard_url(format: :atom, private_token: current_user.private_token), title: "#{current_user.name} issues")
+ = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{current_user.name} issues")
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
- = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do
+ = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do
= icon('rss')
%span.icon-label
Subscribe
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index 2411cc45724..e247eebc3fc 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -37,7 +37,7 @@
- if params[:author_id].present?
= hidden_field_tag(:author_id, params[:author_id])
= dropdown_tag(user_dropdown_label(params[:author_id], 'Author'), options: { toggle_class: 'js-user-search js-filter-submit js-author-search', title: 'Filter by author', filter: true, filterInput: 'input#author-search', dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit',
- placeholder: 'Search authors', data: { any_user: 'Any Author', first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: 'author_id', default_label: 'Author' } })
+ placeholder: 'Search authors', data: { any_user: 'Any Author', first_user: (current_user.username if current_user), project_id: (@project.id if @project), selected: params[:author_id], field_name: 'author_id', default_label: 'Author', todo_filter: true, todo_state_filter: params[:state] || 'pending' } })
.filter-item.inline
- if params[:type].present?
= hidden_field_tag(:type, params[:type])
diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder
index b1628040325..0cc6466d34e 100644
--- a/app/views/groups/issues.atom.builder
+++ b/app/views/groups/issues.atom.builder
@@ -1,7 +1,7 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@group.name} issues"
- xml.link href: issues_group_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
+ xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: issues_group_url, rel: "alternate", type: "text/html"
xml.id issues_group_url
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 4434f1cbd35..dc6c1bb69de 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -1,13 +1,13 @@
- page_title "Issues"
= content_for :meta_tags do
- if current_user
- = auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues")
+ = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues")
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
- = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do
+ = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do
= icon('rss')
%span.icon-label
Subscribe
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 6922f1e153f..afd9958f073 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -26,8 +26,8 @@
Perform code reviews and enhance collaboration with merge requests.
Each project can also have an issue tracker and a wiki.
- - if current_application_settings.sign_in_text.present?
- = markdown_field(current_application_settings, :sign_in_text)
+ - if current_application_settings.sign_in_text.present?
+ = markdown_field(current_application_settings, :sign_in_text)
%hr.footer-fixed
.container.footer-container
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index d4f59764a70..4a6aa92e3f3 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -14,13 +14,13 @@
= text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name'
- .pull-right
+ .pull-right.file-buttons
.license-selector.js-license-selector-wrap.hidden
- = dropdown_tag("Choose a License template", options: { toggle_class: 'js-license-selector', title: "Choose a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } )
+ = dropdown_tag("Choose a License template", options: { toggle_class: 'btn js-license-selector', title: "Choose a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } )
.gitignore-selector.js-gitignore-selector-wrap.hidden
- = dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } )
+ = dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'btn js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } )
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.hidden
- = dropdown_tag("Choose a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } )
+ = dropdown_tag("Choose a GitLab CI Yaml template", options: { toggle_class: 'btn js-gitlab-ci-yml-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } )
= button_tag class: 'soft-wrap-toggle btn', type: 'button' do
%span.no-wrap
= custom_icon('icon_no_wrap')
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index b1f50eb5f34..57a27ec904e 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -26,6 +26,6 @@
:javascript
- disableButtonIfEmptyField($('.js-upload-blob-form').find('.js-commit-message'), '.btn-upload-file');
+ gl.utils.disableButtonIfEmptyField($('.js-upload-blob-form').find('.js-commit-message'), '.btn-upload-file');
new BlobFileDropzone($('.js-upload-blob-form'), '#{method}');
new NewCommitForm($('.js-upload-blob-form'))
diff --git a/app/views/projects/branches/_commit.html.haml b/app/views/projects/branches/_commit.html.haml
index d54c76ff9c8..de607772df6 100644
--- a/app/views/projects/branches/_commit.html.haml
+++ b/app/views/projects/branches/_commit.html.haml
@@ -1,4 +1,6 @@
.branch-commit
+ .icon-container.commit-icon
+ = custom_icon("icon_commit")
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-id monospace"
&middot;
%span.str-truncated
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 840f468dc05..1f748d73d06 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -41,7 +41,7 @@
- else
Cant find HEAD commit for this branch
- - stages_status = pipeline.statuses.relevant.latest.stages_status
+ - stages_status = pipeline.statuses.latest.stages_status
%td.stage-cell
- stages.each do |stage|
- status = stages_status[stage]
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index c40ad06969e..a5422966617 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -102,7 +102,7 @@
= link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
- if Gitlab.config.registry.enabled
- .form-group
+ .form-group.js-container-registry{ style: ("display: none;" if @project.project_feature.send(:repository_access_level) == 0) }
.checkbox
= f.label :container_registry_enabled do
= f.check_box :container_registry_enabled
@@ -290,4 +290,4 @@
Saving project.
%p Please wait a moment, this page will automatically refresh when ready.
-= render 'shared/confirm_modal', phrase: @project.path \ No newline at end of file
+= render 'shared/confirm_modal', phrase: @project.path
diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder
index 36957560de0..a0df0db77c5 100644
--- a/app/views/projects/issues/index.atom.builder
+++ b/app/views/projects/issues/index.atom.builder
@@ -1,7 +1,7 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name} issues"
- xml.link href: namespace_project_issues_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
+ xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_issues_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_issues_url(@project.namespace, @project)
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index cc57cfdb342..c493ff3585b 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -8,7 +8,7 @@
= content_for :meta_tags do
- if current_user
- = auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
+ = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues")
%div{ class: (container_class) }
- if @project.issues.any?
@@ -16,7 +16,7 @@
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
- = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
+ = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn append-right-10' do
= icon('rss')
%span.icon-label
Subscribe
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 69a3bc5f046..4de95036eef 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -12,7 +12,7 @@
= render 'projects/last_push'
= render "home_panel"
-- if @project.feature_available?(:repository, current_user)
+- if current_user && can?(current_user, :download_code, @project)
%nav.project-stats{ class: container_class }
%ul.nav
%li
diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml
index 0f7d629ab98..21e378b8735 100644
--- a/app/views/projects/tree/_tree_content.html.haml
+++ b/app/views/projects/tree/_tree_content.html.haml
@@ -37,5 +37,5 @@
:javascript
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
- ajaxGet("#{escape_javascript(@logs_path)}");
+ gl.utils.ajaxGet("#{escape_javascript(@logs_path)}");
});
diff --git a/app/views/shared/icons/_icon_status_cancel.svg b/app/views/shared/icons/_icon_status_canceled.svg
index fd1ebbcbabd..1b2d0891244 100644
--- a/app/views/shared/icons/_icon_status_cancel.svg
+++ b/app/views/shared/icons/_icon_status_canceled.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-canceled" viewBox="0 0 14 14">
<g fill="#5C5C5C" fill-rule="evenodd">
<path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
<rect width="8" height="2" x="3" y="6" transform="rotate(45 7 7)" rx=".5"/>
diff --git a/app/views/shared/icons/_icon_status_created.svg b/app/views/shared/icons/_icon_status_created.svg
index 1f5c3b51b03..dca5d289767 100644
--- a/app/views/shared/icons/_icon_status_created.svg
+++ b/app/views/shared/icons/_icon_status_created.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-created" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
diff --git a/app/views/shared/icons/_icon_status_skipped.svg b/app/views/shared/icons/_icon_status_skipped.svg
new file mode 100644
index 00000000000..014ca86b61b
--- /dev/null
+++ b/app/views/shared/icons/_icon_status_skipped.svg
@@ -0,0 +1 @@
+<svg width="20" height="20" class="ci-status-icon-skipped" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Group Copy 31</title><g fill="#5C5C5C" fill-rule="evenodd"><path d="M10 17.857c4.286 0 7.857-3.571 7.857-7.857S14.286 2.143 10 2.143 2.143 5.714 2.143 10 5.714 17.857 10 17.857M10 0c5.571 0 10 4.429 10 10s-4.429 10-10 10S0 15.571 0 10 4.429 0 10 0"/><path d="M10.986 11l-1.293 1.293a1 1 0 0 0 1.414 1.414l2.644-2.644a1.505 1.505 0 0 0 0-2.126l-2.644-2.644a1 1 0 0 0-1.414 1.414L10.986 9H6.4a1 1 0 0 0 0 2h4.586z"/></g></svg>
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index d410755cad1..0ace6be8f4e 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -142,6 +142,7 @@
.col-sm-10.col-sm-offset-2
.checkbox
= label_tag 'merge_request[force_remove_source_branch]' do
+ = hidden_field_tag 'merge_request[force_remove_source_branch]', '0'
= check_box_tag 'merge_request[force_remove_source_branch]', '1', @merge_request.force_remove_source_branch?
Remove source branch when merge request is accepted.
diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml
index 22b5a6aa11b..1d778bc88de 100644
--- a/app/views/shared/issuable/_label_dropdown.html.haml
+++ b/app/views/shared/issuable/_label_dropdown.html.haml
@@ -22,7 +22,7 @@
%button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data}
%span.dropdown-toggle-text{ class: ("is-default" if selected.nil? || selected.empty?) }
= multi_label_name(selected, "Labels")
- = icon('chevron-down')
+ = icon('caret-down')
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
= render partial: "shared/issuable/label_page_default", locals: { title: dropdown_title, show_footer: show_footer, show_create: show_create }
- if show_create && project && can?(current_user, :admin_label, project)